Mercurial > hg > CbC > CbC_gcc
comparison gcc/go/go-gcc.cc @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 // go-gcc.cc -- Go frontend to gcc IR. | 1 // go-gcc.cc -- Go frontend to gcc IR. |
2 // Copyright (C) 2011-2017 Free Software Foundation, Inc. | 2 // Copyright (C) 2011-2018 Free Software Foundation, Inc. |
3 // Contributed by Ian Lance Taylor, Google. | 3 // Contributed by Ian Lance Taylor, Google. |
4 | 4 |
5 // This file is part of GCC. | 5 // This file is part of GCC. |
6 | 6 |
7 // GCC is free software; you can redistribute it and/or modify it under | 7 // GCC is free software; you can redistribute it and/or modify it under |
274 Bexpression* | 274 Bexpression* |
275 nil_pointer_expression() | 275 nil_pointer_expression() |
276 { return this->make_expression(null_pointer_node); } | 276 { return this->make_expression(null_pointer_node); } |
277 | 277 |
278 Bexpression* | 278 Bexpression* |
279 var_expression(Bvariable* var, Varexpr_context, Location); | 279 var_expression(Bvariable* var, Location); |
280 | 280 |
281 Bexpression* | 281 Bexpression* |
282 indirect_expression(Btype*, Bexpression* expr, bool known_valid, Location); | 282 indirect_expression(Btype*, Bexpression* expr, bool known_valid, Location); |
283 | 283 |
284 Bexpression* | 284 Bexpression* |
349 | 349 |
350 Bexpression* | 350 Bexpression* |
351 call_expression(Bfunction* caller, Bexpression* fn, | 351 call_expression(Bfunction* caller, Bexpression* fn, |
352 const std::vector<Bexpression*>& args, | 352 const std::vector<Bexpression*>& args, |
353 Bexpression* static_chain, Location); | 353 Bexpression* static_chain, Location); |
354 | |
355 Bexpression* | |
356 stack_allocation_expression(int64_t size, Location); | |
357 | 354 |
358 // Statements. | 355 // Statements. |
359 | 356 |
360 Bstatement* | 357 Bstatement* |
361 error_statement() | 358 error_statement() |
424 | 421 |
425 void | 422 void |
426 global_variable_set_init(Bvariable*, Bexpression*); | 423 global_variable_set_init(Bvariable*, Bexpression*); |
427 | 424 |
428 Bvariable* | 425 Bvariable* |
429 local_variable(Bfunction*, const std::string&, Btype*, bool, | 426 local_variable(Bfunction*, const std::string&, Btype*, Bvariable*, bool, |
430 Location); | 427 Location); |
431 | 428 |
432 Bvariable* | 429 Bvariable* |
433 parameter_variable(Bfunction*, const std::string&, Btype*, bool, | 430 parameter_variable(Bfunction*, const std::string&, Btype*, bool, |
434 Location); | 431 Location); |
484 { return this->make_function(error_mark_node); } | 481 { return this->make_function(error_mark_node); } |
485 | 482 |
486 Bfunction* | 483 Bfunction* |
487 function(Btype* fntype, const std::string& name, const std::string& asm_name, | 484 function(Btype* fntype, const std::string& name, const std::string& asm_name, |
488 bool is_visible, bool is_declaration, bool is_inlinable, | 485 bool is_visible, bool is_declaration, bool is_inlinable, |
489 bool disable_split_stack, bool in_unique_section, Location); | 486 bool disable_split_stack, bool does_not_return, |
487 bool in_unique_section, Location); | |
490 | 488 |
491 Bstatement* | 489 Bstatement* |
492 function_defer_statement(Bfunction* function, Bexpression* undefer, | 490 function_defer_statement(Bfunction* function, Bexpression* undefer, |
493 Bexpression* defer, Location); | 491 Bexpression* defer, Location); |
494 | 492 |
537 Btype* | 535 Btype* |
538 fill_in_array(Btype*, Btype*, Bexpression*); | 536 fill_in_array(Btype*, Btype*, Bexpression*); |
539 | 537 |
540 tree | 538 tree |
541 non_zero_size_type(tree); | 539 non_zero_size_type(tree); |
540 | |
541 tree | |
542 convert_tree(tree, tree, Location); | |
542 | 543 |
543 private: | 544 private: |
544 void | 545 void |
545 define_builtin(built_in_function bcode, const char* name, const char* libname, | 546 define_builtin(built_in_function bcode, const char* name, const char* libname, |
546 tree fntype, bool const_p, bool noreturn_p); | 547 tree fntype, bool const_p, bool noreturn_p); |
630 tree math_function_type = build_function_type_list(double_type_node, | 631 tree math_function_type = build_function_type_list(double_type_node, |
631 double_type_node, | 632 double_type_node, |
632 NULL_TREE); | 633 NULL_TREE); |
633 tree math_function_type_long = | 634 tree math_function_type_long = |
634 build_function_type_list(long_double_type_node, long_double_type_node, | 635 build_function_type_list(long_double_type_node, long_double_type_node, |
635 long_double_type_node, NULL_TREE); | 636 NULL_TREE); |
636 tree math_function_type_two = build_function_type_list(double_type_node, | 637 tree math_function_type_two = build_function_type_list(double_type_node, |
637 double_type_node, | 638 double_type_node, |
638 double_type_node, | 639 double_type_node, |
639 NULL_TREE); | 640 NULL_TREE); |
640 tree math_function_type_long_two = | 641 tree math_function_type_long_two = |
758 this->define_builtin(BUILT_IN_PREFETCH, "__builtin_prefetch", NULL, | 759 this->define_builtin(BUILT_IN_PREFETCH, "__builtin_prefetch", NULL, |
759 build_varargs_function_type_list(void_type_node, | 760 build_varargs_function_type_list(void_type_node, |
760 const_ptr_type_node, | 761 const_ptr_type_node, |
761 NULL_TREE), | 762 NULL_TREE), |
762 false, false); | 763 false, false); |
764 | |
765 // The compiler uses __builtin_unreachable for cases that can not | |
766 // occur. | |
767 this->define_builtin(BUILT_IN_UNREACHABLE, "__builtin_unreachable", NULL, | |
768 build_function_type(void_type_node, void_list_node), | |
769 true, true); | |
763 } | 770 } |
764 | 771 |
765 // Get an unnamed integer type. | 772 // Get an unnamed integer type. |
766 | 773 |
767 Btype* | 774 Btype* |
950 *pp = field; | 957 *pp = field; |
951 pp = &DECL_CHAIN(field); | 958 pp = &DECL_CHAIN(field); |
952 } | 959 } |
953 TYPE_FIELDS(fill_tree) = field_trees; | 960 TYPE_FIELDS(fill_tree) = field_trees; |
954 layout_type(fill_tree); | 961 layout_type(fill_tree); |
962 | |
963 // Because Go permits converting between named struct types and | |
964 // equivalent struct types, for which we use VIEW_CONVERT_EXPR, and | |
965 // because we don't try to maintain TYPE_CANONICAL for struct types, | |
966 // we need to tell the middle-end to use structural equality. | |
967 SET_TYPE_STRUCTURAL_EQUALITY(fill_tree); | |
968 | |
955 return fill; | 969 return fill; |
956 } | 970 } |
957 | 971 |
958 // Make an array type. | 972 // Make an array type. |
959 | 973 |
1084 Btype* r = this->fill_in_struct(placeholder, fields); | 1098 Btype* r = this->fill_in_struct(placeholder, fields); |
1085 | 1099 |
1086 if (TYPE_NAME(t) != NULL_TREE) | 1100 if (TYPE_NAME(t) != NULL_TREE) |
1087 { | 1101 { |
1088 // Build the data structure gcc wants to see for a typedef. | 1102 // Build the data structure gcc wants to see for a typedef. |
1089 tree copy = build_distinct_type_copy(t); | 1103 tree copy = build_variant_type_copy(t); |
1090 TYPE_NAME(copy) = NULL_TREE; | 1104 TYPE_NAME(copy) = NULL_TREE; |
1091 DECL_ORIGINAL_TYPE(TYPE_NAME(t)) = copy; | 1105 DECL_ORIGINAL_TYPE(TYPE_NAME(t)) = copy; |
1092 } | 1106 } |
1093 | 1107 |
1094 return r->get_tree() != error_mark_node; | 1108 return r->get_tree() != error_mark_node; |
1185 Gcc_backend::type_size(Btype* btype) | 1199 Gcc_backend::type_size(Btype* btype) |
1186 { | 1200 { |
1187 tree t = btype->get_tree(); | 1201 tree t = btype->get_tree(); |
1188 if (t == error_mark_node) | 1202 if (t == error_mark_node) |
1189 return 1; | 1203 return 1; |
1204 if (t == void_type_node) | |
1205 return 0; | |
1190 t = TYPE_SIZE_UNIT(t); | 1206 t = TYPE_SIZE_UNIT(t); |
1191 gcc_assert(tree_fits_uhwi_p (t)); | 1207 gcc_assert(tree_fits_uhwi_p (t)); |
1192 unsigned HOST_WIDE_INT val_wide = TREE_INT_CST_LOW(t); | 1208 unsigned HOST_WIDE_INT val_wide = TREE_INT_CST_LOW(t); |
1193 int64_t ret = static_cast<int64_t>(val_wide); | 1209 int64_t ret = static_cast<int64_t>(val_wide); |
1194 if (ret < 0 || static_cast<unsigned HOST_WIDE_INT>(ret) != val_wide) | 1210 if (ret < 0 || static_cast<unsigned HOST_WIDE_INT>(ret) != val_wide) |
1254 } | 1270 } |
1255 | 1271 |
1256 // An expression that references a variable. | 1272 // An expression that references a variable. |
1257 | 1273 |
1258 Bexpression* | 1274 Bexpression* |
1259 Gcc_backend::var_expression(Bvariable* var, Varexpr_context, Location location) | 1275 Gcc_backend::var_expression(Bvariable* var, Location location) |
1260 { | 1276 { |
1261 tree ret = var->get_tree(location); | 1277 tree ret = var->get_tree(location); |
1262 if (ret == error_mark_node) | 1278 if (ret == error_mark_node) |
1263 return this->error_expression(); | 1279 return this->error_expression(); |
1264 return this->make_expression(ret); | 1280 return this->make_expression(ret); |
1454 || expr_tree == error_mark_node | 1470 || expr_tree == error_mark_node |
1455 || TREE_TYPE(expr_tree) == error_mark_node) | 1471 || TREE_TYPE(expr_tree) == error_mark_node) |
1456 return this->error_expression(); | 1472 return this->error_expression(); |
1457 | 1473 |
1458 tree ret; | 1474 tree ret; |
1459 if (this->type_size(type) == 0) | 1475 if (this->type_size(type) == 0 |
1476 || TREE_TYPE(expr_tree) == void_type_node) | |
1460 { | 1477 { |
1461 // Do not convert zero-sized types. | 1478 // Do not convert zero-sized types. |
1462 ret = expr_tree; | 1479 ret = expr_tree; |
1463 } | 1480 } |
1464 else if (TREE_CODE(type_tree) == INTEGER_TYPE) | 1481 else if (TREE_CODE(type_tree) == INTEGER_TYPE) |
1776 } | 1793 } |
1777 | 1794 |
1778 constructor_elt empty = {NULL, NULL}; | 1795 constructor_elt empty = {NULL, NULL}; |
1779 constructor_elt* elt = init->quick_push(empty); | 1796 constructor_elt* elt = init->quick_push(empty); |
1780 elt->index = field; | 1797 elt->index = field; |
1781 elt->value = fold_convert_loc(location.gcc_location(), TREE_TYPE(field), | 1798 elt->value = this->convert_tree(TREE_TYPE(field), val, location); |
1782 val); | |
1783 if (!TREE_CONSTANT(elt->value)) | 1799 if (!TREE_CONSTANT(elt->value)) |
1784 is_constant = false; | 1800 is_constant = false; |
1785 } | 1801 } |
1786 gcc_assert(field == NULL_TREE); | 1802 gcc_assert(field == NULL_TREE); |
1787 tree ret = build_constructor(type_tree, init); | 1803 tree ret = build_constructor(type_tree, init); |
1883 if (array_tree == error_mark_node | 1899 if (array_tree == error_mark_node |
1884 || TREE_TYPE(array_tree) == error_mark_node | 1900 || TREE_TYPE(array_tree) == error_mark_node |
1885 || index_tree == error_mark_node) | 1901 || index_tree == error_mark_node) |
1886 return this->error_expression(); | 1902 return this->error_expression(); |
1887 | 1903 |
1888 tree ret = build4_loc(location.gcc_location(), ARRAY_REF, | 1904 // A function call that returns a zero sized object will have been |
1889 TREE_TYPE(TREE_TYPE(array_tree)), array_tree, | 1905 // changed to return void. If we see void here, assume we are |
1890 index_tree, NULL_TREE, NULL_TREE); | 1906 // dealing with a zero sized type and just evaluate the operands. |
1907 tree ret; | |
1908 if (TREE_TYPE(array_tree) != void_type_node) | |
1909 ret = build4_loc(location.gcc_location(), ARRAY_REF, | |
1910 TREE_TYPE(TREE_TYPE(array_tree)), array_tree, | |
1911 index_tree, NULL_TREE, NULL_TREE); | |
1912 else | |
1913 ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR, | |
1914 void_type_node, array_tree, index_tree); | |
1915 | |
1891 return this->make_expression(ret); | 1916 return this->make_expression(ret); |
1892 } | 1917 } |
1893 | 1918 |
1894 // Create an expression for a call to FN_EXPR with FN_ARGS. | 1919 // Create an expression for a call to FN_EXPR with FN_ARGS. |
1895 Bexpression* | 1920 Bexpression* |
1921 | 1946 |
1922 // This is to support builtin math functions when using 80387 math. | 1947 // This is to support builtin math functions when using 80387 math. |
1923 tree excess_type = NULL_TREE; | 1948 tree excess_type = NULL_TREE; |
1924 if (optimize | 1949 if (optimize |
1925 && TREE_CODE(fndecl) == FUNCTION_DECL | 1950 && TREE_CODE(fndecl) == FUNCTION_DECL |
1926 && DECL_IS_BUILTIN(fndecl) | 1951 && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL) |
1927 && DECL_BUILT_IN_CLASS(fndecl) == BUILT_IN_NORMAL | 1952 && DECL_IS_BUILTIN (fndecl) |
1928 && nargs > 0 | 1953 && nargs > 0 |
1929 && ((SCALAR_FLOAT_TYPE_P(rettype) | 1954 && ((SCALAR_FLOAT_TYPE_P(rettype) |
1930 && SCALAR_FLOAT_TYPE_P(TREE_TYPE(args[0]))) | 1955 && SCALAR_FLOAT_TYPE_P(TREE_TYPE(args[0]))) |
1931 || (COMPLEX_FLOAT_TYPE_P(rettype) | 1956 || (COMPLEX_FLOAT_TYPE_P(rettype) |
1932 && COMPLEX_FLOAT_TYPE_P(TREE_TYPE(args[0]))))) | 1957 && COMPLEX_FLOAT_TYPE_P(TREE_TYPE(args[0]))))) |
1969 | 1994 |
1970 delete[] args; | 1995 delete[] args; |
1971 return this->make_expression(ret); | 1996 return this->make_expression(ret); |
1972 } | 1997 } |
1973 | 1998 |
1974 // Return an expression that allocates SIZE bytes on the stack. | |
1975 | |
1976 Bexpression* | |
1977 Gcc_backend::stack_allocation_expression(int64_t size, Location location) | |
1978 { | |
1979 tree alloca = builtin_decl_explicit(BUILT_IN_ALLOCA); | |
1980 tree size_tree = build_int_cst(integer_type_node, size); | |
1981 tree ret = build_call_expr_loc(location.gcc_location(), alloca, 1, size_tree); | |
1982 tree memset = builtin_decl_explicit(BUILT_IN_MEMSET); | |
1983 ret = build_call_expr_loc(location.gcc_location(), memset, 3, | |
1984 ret, integer_zero_node, size_tree); | |
1985 return this->make_expression(ret); | |
1986 } | |
1987 | |
1988 // An expression as a statement. | 1999 // An expression as a statement. |
1989 | 2000 |
1990 Bstatement* | 2001 Bstatement* |
1991 Gcc_backend::expression_statement(Bfunction*, Bexpression* expr) | 2002 Gcc_backend::expression_statement(Bfunction*, Bexpression* expr) |
1992 { | 2003 { |
2009 // initialization of a zero-sized expression to a non-zero sized | 2020 // initialization of a zero-sized expression to a non-zero sized |
2010 // variable, or vice-versa. Avoid crashes by omitting the | 2021 // variable, or vice-versa. Avoid crashes by omitting the |
2011 // initializer. Such initializations don't mean anything anyhow. | 2022 // initializer. Such initializations don't mean anything anyhow. |
2012 if (int_size_in_bytes(TREE_TYPE(var_tree)) != 0 | 2023 if (int_size_in_bytes(TREE_TYPE(var_tree)) != 0 |
2013 && init_tree != NULL_TREE | 2024 && init_tree != NULL_TREE |
2025 && TREE_TYPE(init_tree) != void_type_node | |
2014 && int_size_in_bytes(TREE_TYPE(init_tree)) != 0) | 2026 && int_size_in_bytes(TREE_TYPE(init_tree)) != 0) |
2015 { | 2027 { |
2016 DECL_INITIAL(var_tree) = init_tree; | 2028 DECL_INITIAL(var_tree) = init_tree; |
2017 init_tree = NULL_TREE; | 2029 init_tree = NULL_TREE; |
2018 } | 2030 } |
2041 // externally visible variables. That might lead us to doing an | 2053 // externally visible variables. That might lead us to doing an |
2042 // assignment of a zero-sized expression to a non-zero sized | 2054 // assignment of a zero-sized expression to a non-zero sized |
2043 // expression; avoid crashes here by avoiding assignments of | 2055 // expression; avoid crashes here by avoiding assignments of |
2044 // zero-sized expressions. Such assignments don't really mean | 2056 // zero-sized expressions. Such assignments don't really mean |
2045 // anything anyhow. | 2057 // anything anyhow. |
2046 if (int_size_in_bytes(TREE_TYPE(lhs_tree)) == 0 | 2058 if (TREE_TYPE(lhs_tree) == void_type_node |
2059 || int_size_in_bytes(TREE_TYPE(lhs_tree)) == 0 | |
2060 || TREE_TYPE(rhs_tree) == void_type_node | |
2047 || int_size_in_bytes(TREE_TYPE(rhs_tree)) == 0) | 2061 || int_size_in_bytes(TREE_TYPE(rhs_tree)) == 0) |
2048 return this->compound_statement(this->expression_statement(bfn, lhs), | 2062 return this->compound_statement(this->expression_statement(bfn, lhs), |
2049 this->expression_statement(bfn, rhs)); | 2063 this->expression_statement(bfn, rhs)); |
2050 | 2064 |
2051 // Sometimes the same unnamed Go type can be created multiple times | 2065 rhs_tree = this->convert_tree(TREE_TYPE(lhs_tree), rhs_tree, location); |
2052 // and thus have multiple tree representations. Make sure this does | |
2053 // not confuse the middle-end. | |
2054 if (TREE_TYPE(lhs_tree) != TREE_TYPE(rhs_tree)) | |
2055 { | |
2056 tree lhs_type_tree = TREE_TYPE(lhs_tree); | |
2057 gcc_assert(TREE_CODE(lhs_type_tree) == TREE_CODE(TREE_TYPE(rhs_tree))); | |
2058 if (POINTER_TYPE_P(lhs_type_tree) | |
2059 || INTEGRAL_TYPE_P(lhs_type_tree) | |
2060 || SCALAR_FLOAT_TYPE_P(lhs_type_tree) | |
2061 || COMPLEX_FLOAT_TYPE_P(lhs_type_tree)) | |
2062 rhs_tree = fold_convert_loc(location.gcc_location(), lhs_type_tree, | |
2063 rhs_tree); | |
2064 else if (TREE_CODE(lhs_type_tree) == RECORD_TYPE | |
2065 || TREE_CODE(lhs_type_tree) == ARRAY_TYPE) | |
2066 { | |
2067 gcc_assert(int_size_in_bytes(lhs_type_tree) | |
2068 == int_size_in_bytes(TREE_TYPE(rhs_tree))); | |
2069 rhs_tree = fold_build1_loc(location.gcc_location(), | |
2070 VIEW_CONVERT_EXPR, | |
2071 lhs_type_tree, rhs_tree); | |
2072 } | |
2073 } | |
2074 | 2066 |
2075 return this->make_statement(fold_build2_loc(location.gcc_location(), | 2067 return this->make_statement(fold_build2_loc(location.gcc_location(), |
2076 MODIFY_EXPR, | 2068 MODIFY_EXPR, |
2077 void_type_node, | 2069 void_type_node, |
2078 lhs_tree, rhs_tree)); | 2070 lhs_tree, rhs_tree)); |
2287 pop_cfun(); | 2279 pop_cfun(); |
2288 | 2280 |
2289 tree tv = value->get_tree(); | 2281 tree tv = value->get_tree(); |
2290 if (tv == error_mark_node) | 2282 if (tv == error_mark_node) |
2291 return this->error_statement(); | 2283 return this->error_statement(); |
2292 tree t = build3_loc(switch_location.gcc_location(), SWITCH_EXPR, | 2284 tree t = build2_loc(switch_location.gcc_location(), SWITCH_EXPR, |
2293 NULL_TREE, tv, stmt_list, NULL_TREE); | 2285 NULL_TREE, tv, stmt_list); |
2294 return this->make_statement(t); | 2286 return this->make_statement(t); |
2295 } | 2287 } |
2296 | 2288 |
2297 // Pair of statements. | 2289 // Pair of statements. |
2298 | 2290 |
2498 } | 2490 } |
2499 | 2491 |
2500 gcc_unreachable(); | 2492 gcc_unreachable(); |
2501 } | 2493 } |
2502 | 2494 |
2495 // Convert EXPR_TREE to TYPE_TREE. Sometimes the same unnamed Go type | |
2496 // can be created multiple times and thus have multiple tree | |
2497 // representations. Make sure this does not confuse the middle-end. | |
2498 | |
2499 tree | |
2500 Gcc_backend::convert_tree(tree type_tree, tree expr_tree, Location location) | |
2501 { | |
2502 if (type_tree == TREE_TYPE(expr_tree)) | |
2503 return expr_tree; | |
2504 | |
2505 if (type_tree == error_mark_node | |
2506 || expr_tree == error_mark_node | |
2507 || TREE_TYPE(expr_tree) == error_mark_node) | |
2508 return error_mark_node; | |
2509 | |
2510 gcc_assert(TREE_CODE(type_tree) == TREE_CODE(TREE_TYPE(expr_tree))); | |
2511 if (POINTER_TYPE_P(type_tree) | |
2512 || INTEGRAL_TYPE_P(type_tree) | |
2513 || SCALAR_FLOAT_TYPE_P(type_tree) | |
2514 || COMPLEX_FLOAT_TYPE_P(type_tree)) | |
2515 return fold_convert_loc(location.gcc_location(), type_tree, expr_tree); | |
2516 else if (TREE_CODE(type_tree) == RECORD_TYPE | |
2517 || TREE_CODE(type_tree) == ARRAY_TYPE) | |
2518 { | |
2519 gcc_assert(int_size_in_bytes(type_tree) | |
2520 == int_size_in_bytes(TREE_TYPE(expr_tree))); | |
2521 if (TYPE_MAIN_VARIANT(type_tree) | |
2522 == TYPE_MAIN_VARIANT(TREE_TYPE(expr_tree))) | |
2523 return fold_build1_loc(location.gcc_location(), NOP_EXPR, | |
2524 type_tree, expr_tree); | |
2525 return fold_build1_loc(location.gcc_location(), VIEW_CONVERT_EXPR, | |
2526 type_tree, expr_tree); | |
2527 } | |
2528 | |
2529 gcc_unreachable(); | |
2530 } | |
2531 | |
2503 // Make a global variable. | 2532 // Make a global variable. |
2504 | 2533 |
2505 Bvariable* | 2534 Bvariable* |
2506 Gcc_backend::global_variable(const std::string& var_name, | 2535 Gcc_backend::global_variable(const std::string& var_name, |
2507 const std::string& asm_name, | 2536 const std::string& asm_name, |
2575 | 2604 |
2576 // Make a local variable. | 2605 // Make a local variable. |
2577 | 2606 |
2578 Bvariable* | 2607 Bvariable* |
2579 Gcc_backend::local_variable(Bfunction* function, const std::string& name, | 2608 Gcc_backend::local_variable(Bfunction* function, const std::string& name, |
2580 Btype* btype, bool is_address_taken, | 2609 Btype* btype, Bvariable* decl_var, |
2581 Location location) | 2610 bool is_address_taken, Location location) |
2582 { | 2611 { |
2583 tree type_tree = btype->get_tree(); | 2612 tree type_tree = btype->get_tree(); |
2584 if (type_tree == error_mark_node) | 2613 if (type_tree == error_mark_node) |
2585 return this->error_variable(); | 2614 return this->error_variable(); |
2586 tree decl = build_decl(location.gcc_location(), VAR_DECL, | 2615 tree decl = build_decl(location.gcc_location(), VAR_DECL, |
2588 type_tree); | 2617 type_tree); |
2589 DECL_CONTEXT(decl) = function->get_tree(); | 2618 DECL_CONTEXT(decl) = function->get_tree(); |
2590 TREE_USED(decl) = 1; | 2619 TREE_USED(decl) = 1; |
2591 if (is_address_taken) | 2620 if (is_address_taken) |
2592 TREE_ADDRESSABLE(decl) = 1; | 2621 TREE_ADDRESSABLE(decl) = 1; |
2622 if (decl_var != NULL) | |
2623 { | |
2624 DECL_HAS_VALUE_EXPR_P(decl) = 1; | |
2625 SET_DECL_VALUE_EXPR(decl, decl_var->get_decl()); | |
2626 } | |
2593 go_preserve_from_gc(decl); | 2627 go_preserve_from_gc(decl); |
2594 return new Bvariable(decl); | 2628 return new Bvariable(decl); |
2595 } | 2629 } |
2596 | 2630 |
2597 // Make a function parameter variable. | 2631 // Make a function parameter variable. |
2702 DECL_CHAIN(var) = BLOCK_VARS(block_tree); | 2736 DECL_CHAIN(var) = BLOCK_VARS(block_tree); |
2703 BLOCK_VARS(block_tree) = var; | 2737 BLOCK_VARS(block_tree) = var; |
2704 BIND_EXPR_VARS(bind_tree) = BLOCK_VARS(block_tree); | 2738 BIND_EXPR_VARS(bind_tree) = BLOCK_VARS(block_tree); |
2705 } | 2739 } |
2706 | 2740 |
2707 if (this->type_size(btype) != 0 && init_tree != NULL_TREE) | 2741 if (this->type_size(btype) != 0 |
2708 DECL_INITIAL(var) = fold_convert_loc(location.gcc_location(), type_tree, | 2742 && init_tree != NULL_TREE |
2709 init_tree); | 2743 && TREE_TYPE(init_tree) != void_type_node) |
2744 DECL_INITIAL(var) = this->convert_tree(type_tree, init_tree, location); | |
2710 | 2745 |
2711 if (is_address_taken) | 2746 if (is_address_taken) |
2712 TREE_ADDRESSABLE(var) = 1; | 2747 TREE_ADDRESSABLE(var) = 1; |
2713 | 2748 |
2714 *pstatement = this->make_statement(build1_loc(location.gcc_location(), | 2749 *pstatement = this->make_statement(build1_loc(location.gcc_location(), |
2715 DECL_EXPR, | 2750 DECL_EXPR, |
2716 void_type_node, var)); | 2751 void_type_node, var)); |
2717 | 2752 |
2718 // Don't initialize VAR with BINIT, but still evaluate BINIT for | 2753 // For a zero sized type, don't initialize VAR with BINIT, but still |
2719 // its side effects. | 2754 // evaluate BINIT for its side effects. |
2720 if (this->type_size(btype) == 0 && init_tree != NULL_TREE) | 2755 if (init_tree != NULL_TREE |
2756 && (this->type_size(btype) == 0 | |
2757 || TREE_TYPE(init_tree) == void_type_node)) | |
2721 *pstatement = | 2758 *pstatement = |
2722 this->compound_statement(this->expression_statement(function, binit), | 2759 this->compound_statement(this->expression_statement(function, binit), |
2723 *pstatement); | 2760 *pstatement); |
2724 | 2761 |
2725 return new Bvariable(var); | 2762 return new Bvariable(var); |
3010 | 3047 |
3011 Bfunction* | 3048 Bfunction* |
3012 Gcc_backend::function(Btype* fntype, const std::string& name, | 3049 Gcc_backend::function(Btype* fntype, const std::string& name, |
3013 const std::string& asm_name, bool is_visible, | 3050 const std::string& asm_name, bool is_visible, |
3014 bool is_declaration, bool is_inlinable, | 3051 bool is_declaration, bool is_inlinable, |
3015 bool disable_split_stack, bool in_unique_section, | 3052 bool disable_split_stack, bool does_not_return, |
3016 Location location) | 3053 bool in_unique_section, Location location) |
3017 { | 3054 { |
3018 tree functype = fntype->get_tree(); | 3055 tree functype = fntype->get_tree(); |
3019 if (functype != error_mark_node) | 3056 if (functype != error_mark_node) |
3020 { | 3057 { |
3021 gcc_assert(FUNCTION_POINTER_TYPE_P(functype)); | 3058 gcc_assert(FUNCTION_POINTER_TYPE_P(functype)); |
3047 if (disable_split_stack) | 3084 if (disable_split_stack) |
3048 { | 3085 { |
3049 tree attr = get_identifier ("no_split_stack"); | 3086 tree attr = get_identifier ("no_split_stack"); |
3050 DECL_ATTRIBUTES(decl) = tree_cons(attr, NULL_TREE, NULL_TREE); | 3087 DECL_ATTRIBUTES(decl) = tree_cons(attr, NULL_TREE, NULL_TREE); |
3051 } | 3088 } |
3089 if (does_not_return) | |
3090 TREE_THIS_VOLATILE(decl) = 1; | |
3052 if (in_unique_section) | 3091 if (in_unique_section) |
3053 resolve_unique_section(decl, 0, 1); | 3092 resolve_unique_section(decl, 0, 1); |
3054 | 3093 |
3055 go_preserve_from_gc(decl); | 3094 go_preserve_from_gc(decl); |
3056 return new Bfunction(decl); | 3095 return new Bfunction(decl); |