diff options
Diffstat (limited to 'contrib/gcc/cp/semantics.c')
-rw-r--r-- | contrib/gcc/cp/semantics.c | 512 |
1 files changed, 250 insertions, 262 deletions
diff --git a/contrib/gcc/cp/semantics.c b/contrib/gcc/cp/semantics.c index a6f9afb..110eb3a 100644 --- a/contrib/gcc/cp/semantics.c +++ b/contrib/gcc/cp/semantics.c @@ -56,8 +56,6 @@ static void emit_associated_thunks PARAMS ((tree)); static void genrtl_try_block PARAMS ((tree)); static void genrtl_eh_spec_block PARAMS ((tree)); static void genrtl_handler PARAMS ((tree)); -static void genrtl_ctor_stmt PARAMS ((tree)); -static void genrtl_subobject PARAMS ((tree)); static void genrtl_named_return_value PARAMS ((void)); static void cp_expand_stmt PARAMS ((tree)); static void genrtl_start_function PARAMS ((tree)); @@ -81,7 +79,7 @@ static tree clear_decl_rtl PARAMS ((tree *, int *, void *)); (SUBSTMT) = (COND); \ } while (0) -/* Returns non-zero if the current statement is a full expression, +/* Returns nonzero if the current statement is a full expression, i.e. temporaries created during that statement should be destroyed at the end of the statement. */ @@ -99,7 +97,7 @@ stmt_tree current_stmt_tree () { return (cfun - ? &cfun->language->x_stmt_tree + ? &cfun->language->base.x_stmt_tree : &scope_chain->x_stmt_tree); } @@ -111,7 +109,7 @@ int anon_aggr_type_p (node) tree node; { - return (CLASS_TYPE_P (node) && TYPE_LANG_SPECIFIC(node)->anon_aggr); + return ANON_AGGR_TYPE_P (node); } /* Finish a scope. */ @@ -268,7 +266,6 @@ finish_then_clause (if_stmt) tree if_stmt; { RECHAIN_STMTS (if_stmt, THEN_CLAUSE (if_stmt)); - last_tree = if_stmt; return if_stmt; } @@ -294,21 +291,8 @@ finish_else_clause (if_stmt) void finish_if_stmt () { - do_poplevel (); finish_stmt (); -} - -void -clear_out_block () -{ - /* If COND wasn't a declaration, clear out the - block we made for it and start a new one here so the - optimization in expand_end_loop will work. */ - if (getdecls () == NULL_TREE) - { - do_poplevel (); - do_pushlevel (); - } + do_poplevel (); } /* Begin a while-statement. Returns a newly created WHILE_STMT if @@ -333,8 +317,29 @@ finish_while_stmt_cond (cond, while_stmt) tree while_stmt; { cond = maybe_convert_cond (cond); - FINISH_COND (cond, while_stmt, WHILE_COND (while_stmt)); - clear_out_block (); + if (processing_template_decl) + /* Don't mess with condition decls in a template. */ + FINISH_COND (cond, while_stmt, WHILE_COND (while_stmt)); + else if (getdecls () == NULL_TREE) + /* It was a simple condition; install it. */ + WHILE_COND (while_stmt) = cond; + else + { + /* If there was a declaration in the condition, we can't leave it + there; transform + while (A x = 42) { } + to + while (true) { A x = 42; if (!x) break; } */ + tree if_stmt; + WHILE_COND (while_stmt) = boolean_true_node; + + if_stmt = begin_if_stmt (); + cond = build_unary_op (TRUTH_NOT_EXPR, cond, 0); + finish_if_stmt_cond (cond, if_stmt); + finish_break_stmt (); + finish_then_clause (if_stmt); + finish_if_stmt (); + } } /* Finish a while-statement, which may be given by WHILE_STMT. */ @@ -419,12 +424,12 @@ begin_for_stmt () r = build_stmt (FOR_STMT, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE); NEW_FOR_SCOPE_P (r) = flag_new_for_scope > 0; - add_stmt (r); if (NEW_FOR_SCOPE_P (r)) { do_pushlevel (); note_level_for_for (); } + add_stmt (r); return r; } @@ -450,8 +455,29 @@ finish_for_cond (cond, for_stmt) tree for_stmt; { cond = maybe_convert_cond (cond); - FINISH_COND (cond, for_stmt, FOR_COND (for_stmt)); - clear_out_block (); + if (processing_template_decl) + /* Don't mess with condition decls in a template. */ + FINISH_COND (cond, for_stmt, FOR_COND (for_stmt)); + else if (getdecls () == NULL_TREE) + /* It was a simple condition; install it. */ + FOR_COND (for_stmt) = cond; + else + { + /* If there was a declaration in the condition, we can't leave it + there; transform + for (; A x = 42;) { } + to + for (;;) { A x = 42; if (!x) break; } */ + tree if_stmt; + FOR_COND (for_stmt) = NULL_TREE; + + if_stmt = begin_if_stmt (); + cond = build_unary_op (TRUTH_NOT_EXPR, cond, 0); + finish_if_stmt_cond (cond, if_stmt); + finish_break_stmt (); + finish_then_clause (if_stmt); + finish_if_stmt (); + } } /* Finish the increment-EXPRESSION in a for-statement, which may be @@ -504,9 +530,9 @@ tree begin_switch_stmt () { tree r; + do_pushlevel (); r = build_stmt (SWITCH_STMT, NULL_TREE, NULL_TREE, NULL_TREE); add_stmt (r); - do_pushlevel (); return r; } @@ -562,11 +588,11 @@ finish_switch_stmt (switch_stmt) { RECHAIN_STMTS (switch_stmt, SWITCH_BODY (switch_stmt)); pop_switch (); - do_poplevel (); finish_stmt (); + do_poplevel (); } -/* Generate the RTL for T, which is a TRY_BLOCK. */ +/* Generate the RTL for T, which is a TRY_BLOCK. */ static void genrtl_try_block (t) @@ -603,7 +629,7 @@ genrtl_try_block (t) } } -/* Generate the RTL for T, which is an EH_SPEC_BLOCK. */ +/* Generate the RTL for T, which is an EH_SPEC_BLOCK. */ static void genrtl_eh_spec_block (t) @@ -712,7 +738,7 @@ finish_function_handler_sequence (try_block) check_handlers (TRY_HANDLERS (try_block)); } -/* Generate the RTL for T, which is a HANDLER. */ +/* Generate the RTL for T, which is a HANDLER. */ static void genrtl_handler (t) @@ -781,22 +807,7 @@ finish_handler (handler) RECHAIN_STMTS (handler, HANDLER_BODY (handler)); } -/* Generate the RTL for T, which is a CTOR_STMT. */ - -static void -genrtl_ctor_stmt (t) - tree t; -{ - if (CTOR_BEGIN_P (t)) - begin_protect_partials (); - else - /* After this point, any exceptions will cause the - destructor to be executed, so we no longer need to worry - about destroying the various subobjects ourselves. */ - end_protect_partials (); -} - -/* Begin a compound-statement. If HAS_NO_SCOPE is non-zero, the +/* Begin a compound-statement. If HAS_NO_SCOPE is nonzero, the compound-statement does not define a scope. Returns a new COMPOUND_STMT if appropriate. */ @@ -835,7 +846,7 @@ begin_compound_stmt (has_no_scope) } /* Finish a compound-statement, which may be given by COMPOUND_STMT. - If HAS_NO_SCOPE is non-zero, the compound statement does not define + If HAS_NO_SCOPE is nonzero, the compound statement does not define a scope. */ tree @@ -880,9 +891,6 @@ finish_asm_stmt (cv_qualifier, string, output_operands, tree r; tree t; - if (TREE_CHAIN (string)) - string = combine_strings (string); - if (cv_qualifier != NULL_TREE && cv_qualifier != ridpointers[(int) RID_VOLATILE]) { @@ -927,7 +935,7 @@ finish_asm_stmt (cv_qualifier, string, output_operands, tree operand; constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t))); - operand = TREE_VALUE (output_operands); + operand = TREE_VALUE (t); if (!parse_output_constraint (&constraint, i, ninputs, noutputs, @@ -948,7 +956,7 @@ finish_asm_stmt (cv_qualifier, string, output_operands, DECL_RTL for the OPERAND -- which we don't have at this point. */ if (!allows_reg && DECL_P (operand)) - mark_addressable (operand); + cxx_mark_addressable (operand); } } @@ -980,38 +988,28 @@ finish_label_decl (name) add_decl_stmt (decl); } -/* Generate the RTL for a SUBOBJECT. */ - -static void -genrtl_subobject (cleanup) - tree cleanup; -{ - add_partial_entry (cleanup); -} - -/* We're in a constructor, and have just constructed a a subobject of - *THIS. CLEANUP is code to run if an exception is thrown before the - end of the current function is reached. */ +/* When DECL goes out of scope, make sure that CLEANUP is executed. */ void -finish_subobject (cleanup) +finish_decl_cleanup (decl, cleanup) + tree decl; tree cleanup; { - tree r = build_stmt (SUBOBJECT, cleanup); - add_stmt (r); + add_stmt (build_stmt (CLEANUP_STMT, decl, cleanup)); } -/* When DECL goes out of scope, make sure that CLEANUP is executed. */ +/* If the current scope exits with an exception, run CLEANUP. */ -void -finish_decl_cleanup (decl, cleanup) - tree decl; +void +finish_eh_cleanup (cleanup) tree cleanup; { - add_stmt (build_stmt (CLEANUP_STMT, decl, cleanup)); + tree r = build_stmt (CLEANUP_STMT, NULL_TREE, cleanup); + CLEANUP_EH_ONLY (r) = 1; + add_stmt (r); } -/* Generate the RTL for a RETURN_INIT. */ +/* Generate the RTL for a RETURN_INIT. */ static void genrtl_named_return_value () @@ -1031,7 +1029,7 @@ genrtl_named_return_value () the return value. */ SET_DECL_RTL (decl, gen_reg_rtx (GET_MODE (DECL_RTL (decl)))); if (TREE_ADDRESSABLE (decl)) - put_var_into_stack (decl); + put_var_into_stack (decl, /*rescan=*/true); } emit_local_var (decl); @@ -1093,67 +1091,30 @@ finish_named_return_value (return_id, init) DECL_UNINLINABLE (current_function_decl) = 1; } -/* The INIT_LIST is a list of mem-initializers, in the order they were - written by the user. The TREE_VALUE of each node is a list of - initializers for a particular subobject. The TREE_PURPOSE is a - FIELD_DECL is the initializer is for a non-static data member, and - a class type if the initializer is for a base class. */ +/* Begin processing a mem-initializer-list. */ void -finish_mem_initializers (init_list) - tree init_list; +begin_mem_initializers () { - tree member_init_list; - tree base_init_list; - tree last_base_warned_about; - tree next; - tree init; + if (! DECL_CONSTRUCTOR_P (current_function_decl)) + error ("only constructors take base initializers"); +} - member_init_list = NULL_TREE; - base_init_list = NULL_TREE; - last_base_warned_about = NULL_TREE; +/* The MEM_INITS is a list of mem-initializers, in reverse of the + order they were written by the user. Each node is as for + emit_mem_initializers. */ - for (init = init_list; init; init = next) - { - next = TREE_CHAIN (init); - if (TREE_CODE (TREE_PURPOSE (init)) == FIELD_DECL) - { - TREE_CHAIN (init) = member_init_list; - member_init_list = init; - - /* We're running through the initializers from right to left - as we process them here. So, if we see a data member - initializer after we see a base initializer, that - actually means that the base initializer preceded the - data member initializer. */ - if (warn_reorder && last_base_warned_about != base_init_list) - { - tree base; - - for (base = base_init_list; - base != last_base_warned_about; - base = TREE_CHAIN (base)) - { - warning ("base initializer for `%T'", - TREE_PURPOSE (base)); - warning (" will be re-ordered to precede member initializations"); - } - - last_base_warned_about = base_init_list; - } - } - else - { - TREE_CHAIN (init) = base_init_list; - base_init_list = init; - } - } +void +finish_mem_initializers (tree mem_inits) +{ + /* Reorder the MEM_INITS so that they are in the order they appeared + in the source program. */ + mem_inits = nreverse (mem_inits); if (processing_template_decl) - add_stmt (build_min_nt (CTOR_INITIALIZER, - member_init_list, base_init_list)); + add_stmt (build_min_nt (CTOR_INITIALIZER, mem_inits)); else - emit_base_init (member_init_list, base_init_list); + emit_mem_initializers (mem_inits); } /* Returns the stack of SCOPE_STMTs for the current function. */ @@ -1161,7 +1122,7 @@ finish_mem_initializers (init_list) tree * current_scope_stmt_stack () { - return &cfun->language->x_scope_stmt_stack; + return &cfun->language->base.x_scope_stmt_stack; } /* Finish a parenthesized expression EXPR. */ @@ -1171,7 +1132,7 @@ finish_parenthesized_expr (expr) tree expr; { if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expr)))) - /* This inhibits warnings in truthvalue_conversion. */ + /* This inhibits warnings in c_common_truthvalue_conversion. */ C_SET_EXP_ORIGINAL_CODE (expr, ERROR_MARK); if (TREE_CODE (expr) == OFFSET_REF) @@ -1263,32 +1224,87 @@ finish_stmt_expr (rtl_expr) return result; } -/* Finish a call to FN with ARGS. Returns a representation of the - call. */ +/* Generate an expression for `FN (ARGS)'. + + If DISALLOW_VIRTUAL is true, the call to FN will be not generated + as a virtual call, even if FN is virtual. (This flag is set when + encountering an expression where the function name is explicitly + qualified. For example a call to `X::f' never generates a virtual + call.) + + Returns code for the call. */ tree -finish_call_expr (fn, args, koenig) - tree fn; - tree args; - int koenig; +finish_call_expr (tree fn, tree args, bool disallow_virtual) { - tree result; + if (fn == error_mark_node || args == error_mark_node) + return error_mark_node; + + if (processing_template_decl) + return build_nt (CALL_EXPR, fn, args, NULL_TREE); - if (koenig) + /* ARGS should be a list of arguments. */ + my_friendly_assert (!args || TREE_CODE (args) == TREE_LIST, + 20020712); + + if (BASELINK_P (fn)) { - if (TREE_CODE (fn) == BIT_NOT_EXPR) - fn = build_x_unary_op (BIT_NOT_EXPR, TREE_OPERAND (fn, 0)); - else if (TREE_CODE (fn) != TEMPLATE_ID_EXPR) - fn = do_identifier (fn, 2, args); - } - result = build_x_function_call (fn, args, current_class_ref); + tree object; + + /* A call to a member function. From [over.call.func]: + + If the keyword this is in scope and refers to the class of + that member function, or a derived class thereof, then the + function call is transformed into a qualified function call + using (*this) as the postfix-expression to the left of the + . operator.... [Otherwise] a contrived object of type T + becomes the implied object argument. + + This paragraph is unclear about this situation: + + struct A { void f(); }; + struct B : public A {}; + struct C : public A { void g() { B::f(); }}; + + In particular, for `B::f', this paragraph does not make clear + whether "the class of that member function" refers to `A' or + to `B'. We believe it refers to `B'. */ + if (current_class_type + && DERIVED_FROM_P (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)), + current_class_type) + && current_class_ref) + object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)), + NULL); + else + { + tree representative_fn; - if (TREE_CODE (result) == CALL_EXPR - && (! TREE_TYPE (result) - || TREE_CODE (TREE_TYPE (result)) != VOID_TYPE)) - result = require_complete_type (result); + representative_fn = BASELINK_FUNCTIONS (fn); + if (TREE_CODE (representative_fn) == TEMPLATE_ID_EXPR) + representative_fn = TREE_OPERAND (representative_fn, 0); + representative_fn = get_first_fn (representative_fn); + object = build_dummy_object (DECL_CONTEXT (representative_fn)); + } - return result; + return build_new_method_call (object, fn, args, NULL_TREE, + (disallow_virtual + ? LOOKUP_NONVIRTUAL : 0)); + } + else if (is_overloaded_fn (fn)) + /* A call to a namespace-scope function. */ + return build_new_function_call (fn, args); + else if (CLASS_TYPE_P (TREE_TYPE (fn))) + { + /* If the "function" is really an object of class type, it might + have an overloaded `operator ()'. */ + tree result; + result = build_opfncall (CALL_EXPR, LOOKUP_NORMAL, fn, args, NULL_TREE); + if (result) + return result; + } + + /* A call where the function is unknown. */ + return build_function_call (fn, args); } /* Finish a call to a postfix increment or decrement or EXPR. (Which @@ -1348,14 +1364,6 @@ finish_object_call_expr (fn, object, args) tree object; tree args; { -#if 0 - /* This is a future direction of this code, but because - build_x_function_call cannot always undo what is done in - build_component_ref entirely yet, we cannot do this. */ - - tree real_fn = build_component_ref (object, fn, NULL_TREE, 1); - return finish_call_expr (real_fn, args); -#else if (DECL_DECLARES_TYPE_P (fn)) { if (processing_template_decl) @@ -1374,9 +1382,11 @@ finish_object_call_expr (fn, object, args) return error_mark_node; } } - - return build_method_call (object, fn, args, NULL_TREE, LOOKUP_NORMAL); -#endif + + if (processing_template_decl || name_p (fn)) + return build_method_call (object, fn, args, NULL_TREE, LOOKUP_NORMAL); + else + return build_new_method_call (object, fn, args, NULL_TREE, LOOKUP_NORMAL); } /* Finish a qualified member function call using OBJECT and ARGS as @@ -1417,22 +1427,6 @@ finish_pseudo_destructor_call_expr (object, scope, destructor) return cp_convert (void_type_node, object); } -/* Finish a call to a globally qualified member function FN using - ARGS. Returns an expression for the call. */ - -tree -finish_qualified_call_expr (fn, args) - tree fn; - tree args; -{ - if (processing_template_decl) - return build_min_nt (CALL_EXPR, fn, args, NULL_TREE); - else - return build_member_call (TREE_OPERAND (fn, 0), - TREE_OPERAND (fn, 1), - args); -} - /* Finish an expression of the form CODE EXPR. */ tree @@ -1467,6 +1461,20 @@ finish_id_expr (expr) return expr; } +/* Return the declaration for the function-name variable indicated by + ID. */ + +tree +finish_fname (tree id) +{ + tree decl; + + decl = fname_decl (C_RID_CODE (id), id); + if (processing_template_decl) + decl = build_min_nt (LOOKUP_EXPR, DECL_NAME (decl)); + return decl; +} + static tree current_type_lookups; /* Perform deferred access control for types used in the type of a @@ -1524,20 +1532,17 @@ reset_type_access_control () current_type_lookups = NULL_TREE; } -/* Begin a function definition declared with DECL_SPECS and - DECLARATOR. Returns non-zero if the function-declaration is - legal. */ +/* Begin a function definition declared with DECL_SPECS, ATTRIBUTES, + and DECLARATOR. Returns nonzero if the function-declaration is + valid. */ int -begin_function_definition (decl_specs, declarator) +begin_function_definition (decl_specs, attributes, declarator) tree decl_specs; + tree attributes; tree declarator; { - tree specs; - tree attrs; - - split_specs_attrs (decl_specs, &specs, &attrs); - if (!start_function (specs, declarator, attrs, SF_DEFAULT)) + if (!start_function (decl_specs, declarator, attributes, SF_DEFAULT)) return 0; deferred_type_access_control (); @@ -1589,7 +1594,7 @@ finish_translation_unit () while (current_namespace != global_namespace) pop_namespace (); - /* Do file scope __FUNCTION__ et al. */ + /* Do file scope __FUNCTION__ et al. */ finish_fname_decls (); finish_file (); @@ -1632,8 +1637,27 @@ finish_template_template_parm (aggr, identifier) return finish_template_type_parm (aggr, tmpl); } +/* ARGUMENT is the default-argument value for a template template + parameter. If ARGUMENT is invalid, issue error messages and return + the ERROR_MARK_NODE. Otherwise, ARGUMENT itself is returned. */ + +tree +check_template_template_default_arg (tree argument) +{ + if (TREE_CODE (argument) != TEMPLATE_DECL + && TREE_CODE (argument) != TEMPLATE_TEMPLATE_PARM + && TREE_CODE (argument) != TYPE_DECL + && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE) + { + error ("invalid default template argument"); + return error_mark_node; + } + + return argument; +} + /* Finish a parameter list, indicated by PARMS. If ELLIPSIS is - non-zero, the parameter list was terminated by a `...'. */ + nonzero, the parameter list was terminated by a `...'. */ tree finish_parmlist (parms, ellipsis) @@ -1661,7 +1685,7 @@ begin_class_definition (t) if (t == error_mark_node) return error_mark_node; - /* Check the bases are accessible. */ + /* Check the bases are accessible. */ decl_type_access_control (TYPE_NAME (t)); reset_type_access_control (); @@ -1731,7 +1755,8 @@ begin_class_definition (t) TYPE_BINFO_BASETYPES (t) = NULL_TREE; TYPE_FIELDS (t) = NULL_TREE; TYPE_METHODS (t) = NULL_TREE; - CLASSTYPE_TAGS (t) = NULL_TREE; + CLASSTYPE_DECL_LIST (t) = NULL_TREE; + CLASSTYPE_NESTED_UDTS (t) = NULL; CLASSTYPE_VBASECLASSES (t) = NULL_TREE; TYPE_SIZE (t) = NULL_TREE; } @@ -1824,8 +1849,12 @@ finish_member_declaration (decl) TREE_CHAIN (decl) = TYPE_METHODS (current_class_type); TYPE_METHODS (current_class_type) = decl; + + maybe_add_class_template_decl_list (current_class_type, decl, + /*friend_p=*/0); } - else + /* Enter the DECL into the scope of the class. */ + else if (TREE_CODE (decl) == USING_DECL || pushdecl_class_level (decl)) { /* All TYPE_DECLs go at the end of TYPE_FIELDS. Ordinary fields go at the beginning. The reason is that lookup_field_1 @@ -1836,7 +1865,7 @@ finish_member_declaration (decl) struct S { enum E { }; int E } s; s.E = 3; - is legal. In addition, the FIELD_DECLs must be maintained in + is valid. In addition, the FIELD_DECLs must be maintained in declaration order so that class layout works as expected. However, we don't need that order until class layout, so we save a little time by putting FIELD_DECLs on in reverse order @@ -1853,9 +1882,8 @@ finish_member_declaration (decl) TYPE_FIELDS (current_class_type) = decl; } - /* Enter the DECL into the scope of the class. */ - if (TREE_CODE (decl) != USING_DECL) - pushdecl_class_level (decl); + maybe_add_class_template_decl_list (current_class_type, decl, + /*friend_p=*/0); } } @@ -1912,16 +1940,6 @@ begin_inline_definitions () do_pending_inlines (); } -/* Finish processing the inline function definitions cached during the - processing of a class definition. */ - -void -finish_inline_definitions () -{ - if (current_class_type == NULL_TREE) - clear_inline_text_obstack (); -} - /* Finish processing the declaration of a member class template TYPES whose template parameters are given by PARMS. */ @@ -1969,7 +1987,7 @@ finish_template_decl (parms) /* Finish processing a template-id (which names a type) of the form NAME < ARGS >. Return the TYPE_DECL for the type named by the - template-id. If ENTERING_SCOPE is non-zero we are about to enter + template-id. If ENTERING_SCOPE is nonzero we are about to enter the scope of template-id indicated. */ tree @@ -2030,7 +2048,12 @@ finish_base_specifier (access_specifier, base_class) { tree result; - if (! is_aggr_type (base_class, 1)) + if (base_class == error_mark_node) + { + error ("invalid base-class specification"); + result = NULL_TREE; + } + else if (! is_aggr_type (base_class, 1)) result = NULL_TREE; else { @@ -2058,11 +2081,9 @@ check_multiple_declarators () contain at most one declarator. We don't just use PROCESSING_TEMPLATE_DECL for the first - condition since that would disallow the perfectly legal code, + condition since that would disallow the perfectly valid code, like `template <class T> struct S { int i, j; };'. */ - tree scope = current_scope (); - - if (scope && TREE_CODE (scope) == FUNCTION_DECL) + if (at_function_scope_p ()) /* It's OK to write `template <class T> void f() { int i, j;}'. */ return; @@ -2112,7 +2133,7 @@ finish_sizeof (t) if (processing_template_decl) return build_min_nt (SIZEOF_EXPR, t); - return TYPE_P (t) ? c_sizeof (t) : expr_sizeof (t); + return TYPE_P (t) ? cxx_sizeof (t) : expr_sizeof (t); } /* Implement the __alignof keyword: Return the minimum required @@ -2125,7 +2146,7 @@ finish_alignof (t) if (processing_template_decl) return build_min_nt (ALIGNOF_EXPR, t); - return TYPE_P (t) ? c_alignof (complete_type (t)) : c_alignof_expr (t); + return TYPE_P (t) ? cxx_alignof (t) : c_alignof_expr (t); } /* Generate RTL for the statement T, and its substatements, and any @@ -2137,10 +2158,6 @@ cp_expand_stmt (t) { switch (TREE_CODE (t)) { - case CTOR_STMT: - genrtl_ctor_stmt (t); - break; - case TRY_BLOCK: genrtl_try_block (t); break; @@ -2153,10 +2170,6 @@ cp_expand_stmt (t) genrtl_handler (t); break; - case SUBOBJECT: - genrtl_subobject (SUBOBJECT_CLEANUP (t)); - break; - case RETURN_INIT: genrtl_named_return_value (); break; @@ -2211,7 +2224,7 @@ simplify_aggr_init_exprs_r (tp, walk_subtrees, data) { /* Replace the first argument with the address of the third argument to the AGGR_INIT_EXPR. */ - mark_addressable (slot); + cxx_mark_addressable (slot); args = tree_cons (NULL_TREE, build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (slot)), @@ -2271,35 +2284,9 @@ emit_associated_thunks (fn) enabling you to output all the thunks with the function itself. */ if (DECL_VIRTUAL_P (fn)) { - tree binfo; - tree v; - - for (binfo = TYPE_BINFO (DECL_CONTEXT (fn)); - binfo; - binfo = TREE_CHAIN (binfo)) - for (v = BINFO_VIRTUALS (binfo); v; v = TREE_CHAIN (v)) - if (BV_FN (v) == fn - && (!integer_zerop (BV_DELTA (v)) - || BV_USE_VCALL_INDEX_P (v))) - { - tree thunk; - tree vcall_index; - - if (BV_USE_VCALL_INDEX_P (v)) - { - vcall_index = BV_VCALL_INDEX (v); - my_friendly_assert (vcall_index != NULL_TREE, 20000621); - } - else - vcall_index = NULL_TREE; - - thunk = make_thunk (build1 (ADDR_EXPR, - vfunc_ptr_type_node, - fn), - BV_DELTA (v), - vcall_index); - use_thunk (thunk, /*emit_p=*/1); - } + tree thunk; + for (thunk = DECL_THUNKS (fn); thunk; thunk = TREE_CHAIN (thunk)) + use_thunk (thunk, /*emit_p=*/1); } } @@ -2311,6 +2298,7 @@ expand_body (fn) { int saved_lineno; const char *saved_input_filename; + tree saved_function; /* When the parser calls us after finishing the body of a template function, we don't really want to expand the body. When we're @@ -2388,21 +2376,23 @@ expand_body (fn) if (DECL_EXTERNAL (fn)) return; - timevar_push (TV_INTEGRATION); - - /* Optimize the body of the function before expanding it. */ - optimize_function (fn); - - timevar_pop (TV_INTEGRATION); - timevar_push (TV_EXPAND); - /* Save the current file name and line number. When we expand the body of the function, we'll set LINENO and INPUT_FILENAME so that error-mesages come out in the right places. */ saved_lineno = lineno; saved_input_filename = input_filename; + saved_function = current_function_decl; lineno = DECL_SOURCE_LINE (fn); input_filename = DECL_SOURCE_FILE (fn); + current_function_decl = fn; + + timevar_push (TV_INTEGRATION); + + /* Optimize the body of the function before expanding it. */ + optimize_function (fn); + + timevar_pop (TV_INTEGRATION); + timevar_push (TV_EXPAND); genrtl_start_function (fn); current_function_is_thunk = DECL_THUNK_P (fn); @@ -2435,6 +2425,7 @@ expand_body (fn) DECL_SAVED_TREE (fn) = NULL_TREE; /* And restore the current source position. */ + current_function_decl = saved_function; lineno = saved_lineno; input_filename = saved_input_filename; extract_interface_info (); @@ -2462,7 +2453,7 @@ nullify_returns_r (tp, walk_subtrees, data) if (TYPE_P (*tp)) *walk_subtrees = 0; else if (TREE_CODE (*tp) == RETURN_STMT) - RETURN_EXPR (*tp) = NULL_TREE; + RETURN_STMT_EXPR (*tp) = NULL_TREE; else if (TREE_CODE (*tp) == CLEANUP_STMT && CLEANUP_DECL (*tp) == nrv) CLEANUP_EH_ONLY (*tp) = 1; @@ -2516,10 +2507,7 @@ genrtl_start_function (fn) function; we need the named return value info for cp_copy_res_decl_for_inlining. */ if (! DECL_INLINE (fn)) - { - free (DECL_SAVED_FUNCTION_DATA (fn)); - DECL_SAVED_FUNCTION_DATA (fn) = NULL; - } + DECL_SAVED_FUNCTION_DATA (fn) = NULL; } /* Keep track of how many functions we're presently expanding. */ |