diff options
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r-- | gcc/cp/class.c | 177 |
1 files changed, 78 insertions, 99 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 12192e6..4668c68 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -151,8 +151,6 @@ static void check_bases_and_members (tree); static tree create_vtable_ptr (tree, tree *); static void include_empty_classes (record_layout_info); static void layout_class_type (tree, tree *); -static void fixup_pending_inline (tree); -static void fixup_inline_methods (tree); static void propagate_binfo_offsets (tree, tree); static void layout_virtual_bases (record_layout_info, splay_tree); static void build_vbase_offset_vtbl_entries (tree, vtbl_init_data *); @@ -3799,12 +3797,27 @@ build_clone (tree fn, tree name) /* Copy the function. */ clone = copy_decl (fn); - /* Remember where this function came from. */ - DECL_CLONED_FUNCTION (clone) = fn; - DECL_ABSTRACT_ORIGIN (clone) = fn; /* Reset the function name. */ DECL_NAME (clone) = name; SET_DECL_ASSEMBLER_NAME (clone, NULL_TREE); + /* Remember where this function came from. */ + DECL_ABSTRACT_ORIGIN (clone) = fn; + /* Make it easy to find the CLONE given the FN. */ + TREE_CHAIN (clone) = TREE_CHAIN (fn); + TREE_CHAIN (fn) = clone; + + /* If this is a template, do the rest on the DECL_TEMPLATE_RESULT. */ + if (TREE_CODE (clone) == TEMPLATE_DECL) + { + tree result = build_clone (DECL_TEMPLATE_RESULT (clone), name); + DECL_TEMPLATE_RESULT (clone) = result; + DECL_TEMPLATE_INFO (result) = copy_node (DECL_TEMPLATE_INFO (result)); + DECL_TI_TEMPLATE (result) = clone; + TREE_TYPE (clone) = TREE_TYPE (result); + return clone; + } + + DECL_CLONED_FUNCTION (clone) = fn; /* There's no pending inline data for this function. */ DECL_PENDING_INLINE_INFO (clone) = NULL; DECL_PENDING_INLINE_P (clone) = 0; @@ -3852,61 +3865,79 @@ build_clone (tree fn, tree name) TYPE_ATTRIBUTES (TREE_TYPE (fn))); } - /* Copy the function parameters. But, DECL_ARGUMENTS on a TEMPLATE_DECL - aren't function parameters; those are the template parameters. */ - if (TREE_CODE (clone) != TEMPLATE_DECL) + /* Copy the function parameters. */ + DECL_ARGUMENTS (clone) = copy_list (DECL_ARGUMENTS (clone)); + /* Remove the in-charge parameter. */ + if (DECL_HAS_IN_CHARGE_PARM_P (clone)) + { + TREE_CHAIN (DECL_ARGUMENTS (clone)) + = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone))); + DECL_HAS_IN_CHARGE_PARM_P (clone) = 0; + } + /* And the VTT parm, in a complete [cd]tor. */ + if (DECL_HAS_VTT_PARM_P (fn)) { - DECL_ARGUMENTS (clone) = copy_list (DECL_ARGUMENTS (clone)); - /* Remove the in-charge parameter. */ - if (DECL_HAS_IN_CHARGE_PARM_P (clone)) + if (DECL_NEEDS_VTT_PARM_P (clone)) + DECL_HAS_VTT_PARM_P (clone) = 1; + else { TREE_CHAIN (DECL_ARGUMENTS (clone)) = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone))); - DECL_HAS_IN_CHARGE_PARM_P (clone) = 0; - } - /* And the VTT parm, in a complete [cd]tor. */ - if (DECL_HAS_VTT_PARM_P (fn)) - { - if (DECL_NEEDS_VTT_PARM_P (clone)) - DECL_HAS_VTT_PARM_P (clone) = 1; - else - { - TREE_CHAIN (DECL_ARGUMENTS (clone)) - = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone))); - DECL_HAS_VTT_PARM_P (clone) = 0; - } + DECL_HAS_VTT_PARM_P (clone) = 0; } + } - for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms)) - { - DECL_CONTEXT (parms) = clone; - cxx_dup_lang_specific_decl (parms); - } + for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms)) + { + DECL_CONTEXT (parms) = clone; + cxx_dup_lang_specific_decl (parms); } /* Create the RTL for this function. */ SET_DECL_RTL (clone, NULL_RTX); rest_of_decl_compilation (clone, /*top_level=*/1, at_eof); - /* Make it easy to find the CLONE given the FN. */ - TREE_CHAIN (clone) = TREE_CHAIN (fn); - TREE_CHAIN (fn) = clone; + if (pch_file) + note_decl_for_pch (clone); - /* If this is a template, handle the DECL_TEMPLATE_RESULT as well. */ - if (TREE_CODE (clone) == TEMPLATE_DECL) - { - tree result; + return clone; +} - DECL_TEMPLATE_RESULT (clone) - = build_clone (DECL_TEMPLATE_RESULT (clone), name); - result = DECL_TEMPLATE_RESULT (clone); - DECL_TEMPLATE_INFO (result) = copy_node (DECL_TEMPLATE_INFO (result)); - DECL_TI_TEMPLATE (result) = clone; +/* Implementation of DECL_CLONED_FUNCTION and DECL_CLONED_FUNCTION_P, do + not invoke this function directly. + + For a non-thunk function, returns the address of the slot for storing + the function it is a clone of. Otherwise returns NULL_TREE. + + If JUST_TESTING, looks through TEMPLATE_DECL and returns NULL if + cloned_function is unset. This is to support the separate + DECL_CLONED_FUNCTION and DECL_CLONED_FUNCTION_P modes; using the latter + on a template makes sense, but not the former. */ + +tree * +decl_cloned_function_p (const_tree decl, bool just_testing) +{ + tree *ptr; + if (just_testing) + decl = STRIP_TEMPLATE (decl); + + if (TREE_CODE (decl) != FUNCTION_DECL + || !DECL_LANG_SPECIFIC (decl) + || DECL_LANG_SPECIFIC (decl)->u.fn.thunk_p) + { +#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) + if (!just_testing) + lang_check_failed (__FILE__, __LINE__, __FUNCTION__); + else +#endif + return NULL; } - else if (pch_file) - note_decl_for_pch (clone); - return clone; + ptr = &DECL_LANG_SPECIFIC (decl)->u.fn.u5.cloned_function; + if (just_testing && *ptr == NULL_TREE) + return NULL; + else + return ptr; } /* Produce declarations for all appropriate clones of FN. If @@ -3920,7 +3951,7 @@ clone_function_decl (tree fn, int update_method_vec_p) /* Avoid inappropriate cloning. */ if (TREE_CHAIN (fn) - && DECL_CLONED_FUNCTION (TREE_CHAIN (fn))) + && DECL_CLONED_FUNCTION_P (TREE_CHAIN (fn))) return; if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)) @@ -3977,7 +4008,7 @@ adjust_clone_args (tree decl) { tree clone; - for (clone = TREE_CHAIN (decl); clone && DECL_CLONED_FUNCTION (clone); + for (clone = TREE_CHAIN (decl); clone && DECL_CLONED_FUNCTION_P (clone); clone = TREE_CHAIN (clone)) { tree orig_clone_parms = TYPE_ARG_TYPES (TREE_TYPE (clone)); @@ -4447,54 +4478,6 @@ create_vtable_ptr (tree t, tree* virtuals_p) return NULL_TREE; } -/* Fixup the inline function given by INFO now that the class is - complete. */ - -static void -fixup_pending_inline (tree fn) -{ - if (DECL_PENDING_INLINE_INFO (fn)) - { - tree args = DECL_ARGUMENTS (fn); - while (args) - { - DECL_CONTEXT (args) = fn; - args = TREE_CHAIN (args); - } - } -} - -/* Fixup the inline methods and friends in TYPE now that TYPE is - complete. */ - -static void -fixup_inline_methods (tree type) -{ - tree method = TYPE_METHODS (type); - VEC(tree,gc) *friends; - unsigned ix; - - if (method && TREE_CODE (method) == TREE_VEC) - { - if (TREE_VEC_ELT (method, 1)) - method = TREE_VEC_ELT (method, 1); - else if (TREE_VEC_ELT (method, 0)) - method = TREE_VEC_ELT (method, 0); - else - method = TREE_VEC_ELT (method, 2); - } - - /* Do inline member functions. */ - for (; method; method = TREE_CHAIN (method)) - fixup_pending_inline (method); - - /* Do friends. */ - for (friends = CLASSTYPE_INLINE_FRIENDS (type), ix = 0; - VEC_iterate (tree, friends, ix, method); ix++) - fixup_pending_inline (method); - CLASSTYPE_INLINE_FRIENDS (type) = NULL; -} - /* Add OFFSET to all base types of BINFO which is a base in the hierarchy dominated by T. @@ -5219,8 +5202,6 @@ finish_struct_1 (tree t) TYPE_SIZE (t) = NULL_TREE; CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE; - fixup_inline_methods (t); - /* Make assumptions about the class; we'll reset the flags if necessary. */ CLASSTYPE_EMPTY_P (t) = 1; @@ -5332,9 +5313,7 @@ finish_struct_1 (tree t) add_fields_to_record_type (TYPE_FIELDS (t), field_vec, 0); qsort (field_vec->elts, n_fields, sizeof (tree), field_decl_cmp); - if (! DECL_LANG_SPECIFIC (TYPE_MAIN_DECL (t))) - retrofit_lang_decl (TYPE_MAIN_DECL (t)); - DECL_SORTED_FIELDS (TYPE_MAIN_DECL (t)) = field_vec; + CLASSTYPE_SORTED_FIELDS (t) = field_vec; } /* Complain if one of the field types requires lower visibility. */ |