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.
This commit is contained in:
parent
2e6562043c
commit
79c1b9fb44
@ -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<tree, va_gc> *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<tree, va_gc> *
|
||||
set_class_bindings (tree klass, int extra)
|
||||
{
|
||||
unsigned n_fields = count_class_fields (klass);
|
||||
vec<tree, va_gc> *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);
|
||||
|
@ -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<tree, va_gc> *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);
|
||||
|
Loading…
Reference in New Issue
Block a user