From 79c1b9fb44ce9abd0e2f6642b65684b9721233ee Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Wed, 9 Dec 2020 10:46:58 -0800 Subject: [PATCH] c++: name-lookup cleanups Name-lookup is the most changed piece of the front end for modules. Here are some preparatort cleanups and API extensions. gcc/cp/ * name-lookup.h (set_class_bindings): Return vector, take signed 'extra' parm. * name-lookup.c (maybe_lazily_declare): Break out ... (get_class_binding): .. of here, call it. (find_member_slot): Adjust get_class_bindings call. (set_class_bindings): Allow -ve extra. Return the vector. (set_identifier_type_value_with_scope): Remove checking assert. (lookup_using_decl): Set decl's context. (do_pushtag): Adjust set_identifier_type_value_with_scope handling. --- gcc/cp/name-lookup.c | 105 +++++++++++++++++++++---------------------- gcc/cp/name-lookup.h | 2 +- 2 files changed, 53 insertions(+), 54 deletions(-) diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index c87d151b441..fa372810349 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -1338,6 +1338,36 @@ get_class_binding_direct (tree klass, tree name, bool want_type) return val; } +/* We're about to lookup NAME in KLASS. Make sure any lazily declared + members are now declared. */ + +static void +maybe_lazily_declare (tree klass, tree name) +{ + /* Lazily declare functions, if we're going to search these. */ + if (IDENTIFIER_CTOR_P (name)) + { + if (CLASSTYPE_LAZY_DEFAULT_CTOR (klass)) + lazily_declare_fn (sfk_constructor, klass); + if (CLASSTYPE_LAZY_COPY_CTOR (klass)) + lazily_declare_fn (sfk_copy_constructor, klass); + if (CLASSTYPE_LAZY_MOVE_CTOR (klass)) + lazily_declare_fn (sfk_move_constructor, klass); + } + else if (IDENTIFIER_DTOR_P (name)) + { + if (CLASSTYPE_LAZY_DESTRUCTOR (klass)) + lazily_declare_fn (sfk_destructor, klass); + } + else if (name == assign_op_identifier) + { + if (CLASSTYPE_LAZY_COPY_ASSIGN (klass)) + lazily_declare_fn (sfk_copy_assignment, klass); + if (CLASSTYPE_LAZY_MOVE_ASSIGN (klass)) + lazily_declare_fn (sfk_move_assignment, klass); + } +} + /* Look for NAME's binding in exactly KLASS. See get_class_binding_direct for argument description. Does lazy special function creation as necessary. */ @@ -1348,30 +1378,7 @@ get_class_binding (tree klass, tree name, bool want_type /*=false*/) klass = complete_type (klass); if (COMPLETE_TYPE_P (klass)) - { - /* Lazily declare functions, if we're going to search these. */ - if (IDENTIFIER_CTOR_P (name)) - { - if (CLASSTYPE_LAZY_DEFAULT_CTOR (klass)) - lazily_declare_fn (sfk_constructor, klass); - if (CLASSTYPE_LAZY_COPY_CTOR (klass)) - lazily_declare_fn (sfk_copy_constructor, klass); - if (CLASSTYPE_LAZY_MOVE_CTOR (klass)) - lazily_declare_fn (sfk_move_constructor, klass); - } - else if (IDENTIFIER_DTOR_P (name)) - { - if (CLASSTYPE_LAZY_DESTRUCTOR (klass)) - lazily_declare_fn (sfk_destructor, klass); - } - else if (name == assign_op_identifier) - { - if (CLASSTYPE_LAZY_COPY_ASSIGN (klass)) - lazily_declare_fn (sfk_copy_assignment, klass); - if (CLASSTYPE_LAZY_MOVE_ASSIGN (klass)) - lazily_declare_fn (sfk_move_assignment, klass); - } - } + maybe_lazily_declare (klass, name); return get_class_binding_direct (klass, name, want_type); } @@ -1392,14 +1399,11 @@ find_member_slot (tree klass, tree name) vec_alloc (member_vec, 8); CLASSTYPE_MEMBER_VEC (klass) = member_vec; if (complete_p) - { - /* If the class is complete but had no member_vec, we need - to add the TYPE_FIELDS into it. We're also most likely - to be adding ctors & dtors, so ask for 6 spare slots (the - abstract cdtors and their clones). */ - set_class_bindings (klass, 6); - member_vec = CLASSTYPE_MEMBER_VEC (klass); - } + /* If the class is complete but had no member_vec, we need to + add the TYPE_FIELDS into it. We're also most likely to be + adding ctors & dtors, so ask for 6 spare slots (the + abstract cdtors and their clones). */ + member_vec = set_class_bindings (klass, 6); } if (IDENTIFIER_CONV_OP_P (name)) @@ -1741,18 +1745,18 @@ member_vec_dedup (vec *member_vec) no existing MEMBER_VEC and fewer than 8 fields, do nothing. We know there must be at least 1 field -- the self-reference TYPE_DECL, except for anon aggregates, which will have at least - one field anyway. */ + one field anyway. If EXTRA < 0, always create the vector. */ -void -set_class_bindings (tree klass, unsigned extra) +vec * +set_class_bindings (tree klass, int extra) { unsigned n_fields = count_class_fields (klass); vec *member_vec = CLASSTYPE_MEMBER_VEC (klass); - if (member_vec || n_fields >= 8) + if (member_vec || n_fields >= 8 || extra < 0) { /* Append the new fields. */ - vec_safe_reserve_exact (member_vec, extra + n_fields); + vec_safe_reserve_exact (member_vec, n_fields + (extra >= 0 ? extra : 0)); member_vec_append_class_fields (member_vec, klass); } @@ -1762,6 +1766,8 @@ set_class_bindings (tree klass, unsigned extra) member_vec->qsort (member_name_cmp); member_vec_dedup (member_vec); } + + return member_vec; } /* Insert lately defined enum ENUMTYPE into KLASS for the sorted case. */ @@ -3717,13 +3723,6 @@ set_identifier_type_value_with_scope (tree id, tree decl, cp_binding_level *b) else { gcc_assert (decl); - if (CHECKING_P) - { - tree *slot = find_namespace_slot (current_namespace, id); - gcc_checking_assert (slot - && (decl == MAYBE_STAT_TYPE (*slot) - || decl == MAYBE_STAT_DECL (*slot))); - } /* Store marker instead of real type. */ type = global_type_node; @@ -4547,7 +4546,8 @@ push_class_level_binding (tree name, tree x) } /* Process and lookup a using decl SCOPE::lookup.name, filling in - lookup.values & lookup.type. Return true if ok. */ + lookup.values & lookup.type. Return a USING_DECL, or NULL_TREE on + failure. */ static tree lookup_using_decl (tree scope, name_lookup &lookup) @@ -4757,6 +4757,7 @@ lookup_using_decl (tree scope, name_lookup &lookup) USING_DECL_SCOPE (using_decl) = scope; USING_DECL_DECLS (using_decl) = lookup.value; DECL_DEPENDENT_P (using_decl) = dependent_p; + DECL_CONTEXT (using_decl) = current; if (TYPE_P (current) && b_kind == bk_not_base) USING_DECL_UNRELATED_P (using_decl) = true; @@ -6918,7 +6919,6 @@ do_pushtag (tree name, tree type, TAG_how how) if (identifier_type_value_1 (name) != type) { tree tdef; - int in_class = 0; tree context = TYPE_CONTEXT (type); if (! context) @@ -6949,11 +6949,6 @@ do_pushtag (tree name, tree type, TAG_how how) if (!context) context = current_namespace; - if (b->kind == sk_class - || (b->kind == sk_template_parms - && b->level_chain->kind == sk_class)) - in_class = 1; - tdef = create_implicit_typedef (name, type); DECL_CONTEXT (tdef) = FROB_CONTEXT (context); decl = maybe_process_template_type_declaration @@ -6961,8 +6956,10 @@ do_pushtag (tree name, tree type, TAG_how how) if (decl == error_mark_node) return decl; + bool in_class = false; if (b->kind == sk_class) { + in_class = true; if (!TYPE_BEING_DEFINED (current_class_type)) /* Don't push anywhere if the class is complete; a lambda in an NSDMI is not a member of the class. */ @@ -6976,7 +6973,9 @@ do_pushtag (tree name, tree type, TAG_how how) else pushdecl_class_level (decl); } - else if (b->kind != sk_template_parms) + else if (b->kind == sk_template_parms) + in_class = b->level_chain->kind == sk_class; + else { decl = do_pushdecl_with_scope (decl, b, /*hiding=*/(how == TAG_how::HIDDEN_FRIEND)); @@ -6993,7 +6992,7 @@ do_pushtag (tree name, tree type, TAG_how how) } } - if (! in_class) + if (!in_class) set_identifier_type_value_with_scope (name, tdef, b); TYPE_CONTEXT (type) = DECL_CONTEXT (decl); diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index 9cc8a42f4bd..671977ffc92 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -457,7 +457,7 @@ extern tree *find_member_slot (tree klass, tree name); extern tree *add_member_slot (tree klass, tree name); extern void resort_type_member_vec (void *, void *, gt_pointer_operator, void *); -extern void set_class_bindings (tree, unsigned extra = 0); +extern vec *set_class_bindings (tree, int extra = 0); extern void insert_late_enum_def_bindings (tree, tree); extern tree innermost_non_namespace_value (tree); extern cxx_binding *outer_binding (tree, cxx_binding *, bool); -- 2.30.2