diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-11-02 01:50:29 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-11-02 01:50:29 +0000 |
commit | 7896267da348b7e9f4e8c930f2b3fa41577ebf45 (patch) | |
tree | 1dffc88ff5b0ae93ef01f8ea3bba2713ee747362 /gcc/cp/class.c | |
parent | 36f431a6ed5f28b30834942c25cf875bccc88276 (diff) | |
download | gcc-7896267da348b7e9f4e8c930f2b3fa41577ebf45.tar.gz |
Implement P0136R1, Rewording inheriting constructors.
gcc/c-family/
* c.opt (-fnew-inheriting-ctors): New.
* c-opts.c: Default to on for ABI 11+.
gcc/cp/
* call.c (enum rejection_reason_code): Add rr_inherited_ctor.
(inherited_ctor_rejection): New.
(add_function_candidate): Reject inherited ctors for copying.
(enforce_access): Use strip_inheriting_ctors.
(print_z_candidate): Likewise. Handle rr_inherited_ctor.
(convert_like_real): Avoid copying inheriting ctor parameters.
(build_over_call): Likewise. A base ctor inheriting from vbase
has no parms. Sorry about varargs.
(joust): A local constructor beats inherited with the same convs.
* class.c (add_method): Handle hiding inheriting ctors.
(one_inherited_ctor): Handle new semantics.
(add_implicitly_declared_members): Pass using_decl down.
(build_clone): A base ctor inheriting from vbase has no parms.
* cp-tree.h (DECL_INHERITED_CTOR): Store this instead of the base.
(SET_DECL_INHERITED_CTOR): Likewise.
(DECL_INHERITED_CTOR_BASE): Adjust.
* constexpr.c: Adjust.
* error.c (dump_function_decl): Decorate inheriting ctors.
* init.c (emit_mem_initializers): Suppress access control in
inheriting ctor.
* mangle.c (write_special_name_constructor): Handle new inheriting
ctor mangling.
* method.c (strip_inheriting_ctors, inherited_ctor_binfo)
(ctor_omit_inherited_parms, binfo_inherited_from): New.
(synthesized_method_walk): Use binfo_inherited_from. Suppress
access control in inheriting ctor.
(deduce_inheriting_ctor): Deleted if ambiguous ctor inheritance.
(maybe_explain_implicit_delete): Explain ambigous ctor inheritance.
(add_one_base_init, do_build_copy_constructor): Adjust.
(locate_fn_flags, explain_implicit_non_constexpr): Adjust.
(implicitly_declare_fn): Adjust.
(get_inherited_ctor): Remove.
* name-lookup.c (do_class_using_decl): Check for indirect ctor
inheritance.
* optimize.c (cdtor_comdat_group): Adjust for new mangling.
(maybe_clone_body): Handle omitted parms in base clone.
(maybe_thunk_body): Don't thunk if base clone omits parms.
* pt.c (tsubst_decl): Adjust.
(instantiate_template_1): Suppress access control in inheriting
ctor.
(fn_type_unification): Do deduction with inherited ctor.
* tree.c (special_function_p): Adjust.
gcc/
* tree-inline.c (copy_tree_body_r): Only copy the taken branch of
a COND_EXPR with constant condition.
libiberty/
* cp-demangle.c (d_ctor_dtor_name): Handle inheriting constructor.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@241765 138bc75d-0d04-0410-961f-82ee72b054a4
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 1a379348e5f..c6b4ed6af33 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; |