diff options
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r-- | gcc/cp/class.c | 79 |
1 files changed, 64 insertions, 15 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 1a37934..c6b4ed6 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1016,7 +1016,6 @@ add_method (tree type, tree method, tree using_decl) bool complete_p; bool insert_p = false; tree current_fns; - tree fns; if (method == error_mark_node) return false; @@ -1083,8 +1082,9 @@ add_method (tree type, tree method, tree using_decl) current_fns = insert_p ? NULL_TREE : (*method_vec)[slot]; /* Check to see if we've already got this method. */ - for (fns = current_fns; fns; fns = OVL_NEXT (fns)) + for (tree *p = ¤t_fns; *p; ) { + tree fns = *p; tree fn = OVL_CURRENT (fns); tree fn_type; tree method_type; @@ -1092,12 +1092,14 @@ add_method (tree type, tree method, tree using_decl) tree parms2; if (TREE_CODE (fn) != TREE_CODE (method)) - continue; + goto cont; /* Two using-declarations can coexist, we'll complain about ambiguity in overload resolution. */ - if (using_decl && TREE_CODE (fns) == OVERLOAD && OVL_USED (fns)) - continue; + if (using_decl && TREE_CODE (fns) == OVERLOAD && OVL_USED (fns) + /* Except handle inherited constructors specially. */ + && ! DECL_CONSTRUCTOR_P (fn)) + goto cont; /* [over.load] Member function declarations with the same name and the same parameter types cannot be @@ -1131,7 +1133,7 @@ add_method (tree type, tree method, tree using_decl) == FUNCTION_REF_QUALIFIED (method_type)) && (type_memfn_quals (fn_type) != type_memfn_quals (method_type) || type_memfn_rqual (fn_type) != type_memfn_rqual (method_type))) - continue; + goto cont; /* For templates, the return type and template parameters must be identical. */ @@ -1140,7 +1142,7 @@ add_method (tree type, tree method, tree using_decl) TREE_TYPE (method_type)) || !comp_template_parms (DECL_TEMPLATE_PARMS (fn), DECL_TEMPLATE_PARMS (method)))) - continue; + goto cont; if (! DECL_STATIC_FUNCTION_P (fn)) parms1 = TREE_CHAIN (parms1); @@ -1178,18 +1180,38 @@ add_method (tree type, tree method, tree using_decl) mangle_decl (method); } cgraph_node::record_function_versions (fn, method); - continue; + goto cont; } - if (DECL_INHERITED_CTOR_BASE (method)) + if (DECL_INHERITED_CTOR (method)) { - if (DECL_INHERITED_CTOR_BASE (fn)) + if (DECL_INHERITED_CTOR (fn)) { + tree basem = DECL_INHERITED_CTOR_BASE (method); + tree basef = DECL_INHERITED_CTOR_BASE (fn); + if (flag_new_inheriting_ctors) + { + if (basem == basef) + { + /* Inheriting the same constructor along different + paths, combine them. */ + SET_DECL_INHERITED_CTOR + (fn, ovl_cons (DECL_INHERITED_CTOR (method), + DECL_INHERITED_CTOR (fn))); + /* Adjust deletedness and such. */ + deduce_inheriting_ctor (fn); + /* And discard the new one. */ + return false; + } + else + /* Inherited ctors can coexist until overload + resolution. */ + goto cont; + } error_at (DECL_SOURCE_LOCATION (method), - "%q#D inherited from %qT", method, - DECL_INHERITED_CTOR_BASE (method)); + "%q#D", method); error_at (DECL_SOURCE_LOCATION (fn), "conflicts with version inherited from %qT", - DECL_INHERITED_CTOR_BASE (fn)); + basef); } /* Otherwise defer to the other function. */ return false; @@ -1200,6 +1222,13 @@ add_method (tree type, tree method, tree using_decl) /* Defer to the local function. */ return false; } + else if (flag_new_inheriting_ctors + && DECL_INHERITED_CTOR (fn)) + { + /* Hide the inherited constructor. */ + *p = OVL_NEXT (fns); + continue; + } else { error ("%q+#D cannot be overloaded", method); @@ -1212,6 +1241,12 @@ add_method (tree type, tree method, tree using_decl) will crash while processing the definitions. */ return false; } + + cont: + if (TREE_CODE (fns) == OVERLOAD) + p = &OVL_CHAIN (fns); + else + break; } /* A class should never have more than one destructor. */ @@ -3308,10 +3343,19 @@ one_inheriting_sig (tree t, tree ctor, tree *parms, int nparms) constructor CTOR. */ static void -one_inherited_ctor (tree ctor, tree t) +one_inherited_ctor (tree ctor, tree t, tree using_decl) { tree parms = FUNCTION_FIRST_USER_PARMTYPE (ctor); + if (flag_new_inheriting_ctors) + { + ctor = implicitly_declare_fn (sfk_inheriting_constructor, + t, /*const*/false, ctor, parms); + add_method (t, ctor, using_decl); + TYPE_HAS_USER_CONSTRUCTOR (t) = true; + return; + } + tree *new_parms = XALLOCAVEC (tree, list_length (parms)); int i = 0; for (; parms && parms != void_list_node; parms = TREE_CHAIN (parms)) @@ -3412,7 +3456,7 @@ add_implicitly_declared_members (tree t, tree* access_decls, input_location = DECL_SOURCE_LOCATION (using_decl); if (ctor_list) for (; ctor_list; ctor_list = OVL_NEXT (ctor_list)) - one_inherited_ctor (OVL_CURRENT (ctor_list), t); + one_inherited_ctor (OVL_CURRENT (ctor_list), t, using_decl); *access_decls = TREE_CHAIN (*access_decls); input_location = loc; } @@ -4772,6 +4816,11 @@ build_clone (tree fn, tree name) } } + /* A base constructor inheriting from a virtual base doesn't get the + arguments. */ + if (ctor_omit_inherited_parms (fn)) + DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone))) = NULL_TREE; + for (parms = DECL_ARGUMENTS (clone); parms; parms = DECL_CHAIN (parms)) { DECL_CONTEXT (parms) = clone; |