extern bool grok_ctor_properties (const_tree, const_tree);
extern bool grok_op_properties (tree, bool);
extern tree xref_tag (tag_types, tree,
- tag_scope = ts_current,
+ TAG_how = TAG_how::CURRENT_ONLY,
bool tpl_header_p = false);
extern void xref_basetypes (tree, tree);
extern tree start_enum (tree, tree, tree, tree, bool, bool *);
static int member_function_or_else (tree, tree, enum overload_flags);
static tree local_variable_p_walkfn (tree *, int *, void *);
static const char *tag_name (enum tag_types);
-static tree lookup_and_check_tag (enum tag_types, tree, tag_scope, bool);
+static tree lookup_and_check_tag (enum tag_types, tree, TAG_how, bool);
static void maybe_deduce_size_from_array_init (tree, tree);
static void layout_var_decl (tree);
static tree check_initializer (tree, tree, int, vec<tree, va_gc> **);
static tree
lookup_and_check_tag (enum tag_types tag_code, tree name,
- tag_scope scope, bool template_header_p)
+ TAG_how how, bool template_header_p)
{
- tree t;
tree decl;
- if (scope == ts_global)
+ if (how == TAG_how::GLOBAL)
{
/* First try ordinary name lookup, ignoring hidden class name
injected via friend declaration. */
If we find one, that name will be made visible rather than
creating a new tag. */
if (!decl)
- decl = lookup_type_scope (name, ts_within_enclosing_non_class);
+ decl = lookup_elaborated_type (name, TAG_how::INNERMOST_NON_CLASS);
}
else
- decl = lookup_type_scope (name, scope);
+ decl = lookup_elaborated_type (name, how);
if (decl
&& (DECL_CLASS_TEMPLATE_P (decl)
- /* If scope is ts_current we're defining a class, so ignore a
- template template parameter. */
- || (scope != ts_current
+ /* If scope is TAG_how::CURRENT_ONLY we're defining a class,
+ so ignore a template template parameter. */
+ || (how != TAG_how::CURRENT_ONLY
&& DECL_TEMPLATE_TEMPLATE_PARM_P (decl))))
decl = DECL_TEMPLATE_RESULT (decl);
class C {
class C {};
}; */
- if (scope == ts_current && DECL_SELF_REFERENCE_P (decl))
+ if (how == TAG_how::CURRENT_ONLY && DECL_SELF_REFERENCE_P (decl))
{
error ("%qD has the same name as the class in which it is "
- "declared",
- decl);
+ "declared", decl);
return error_mark_node;
}
class C *c2; // DECL_SELF_REFERENCE_P is true
}; */
- t = check_elaborated_type_specifier (tag_code,
- decl,
- template_header_p
- | DECL_SELF_REFERENCE_P (decl));
+ tree t = check_elaborated_type_specifier (tag_code,
+ decl,
+ template_header_p
+ | DECL_SELF_REFERENCE_P (decl));
if (template_header_p && t && CLASS_TYPE_P (t)
&& (!CLASSTYPE_TEMPLATE_INFO (t)
|| (!PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)))))
static tree
xref_tag_1 (enum tag_types tag_code, tree name,
- tag_scope scope, bool template_header_p)
+ TAG_how how, bool template_header_p)
{
enum tree_code code;
tree context = NULL_TREE;
make type node and push name. Name lookup is not required. */
tree t = NULL_TREE;
if (!IDENTIFIER_ANON_P (name))
- t = lookup_and_check_tag (tag_code, name, scope, template_header_p);
+ t = lookup_and_check_tag (tag_code, name, how, template_header_p);
if (t == error_mark_node)
return error_mark_node;
- if (scope != ts_current && t && current_class_type
+ if (how != TAG_how::CURRENT_ONLY && t && current_class_type
&& template_class_depth (current_class_type)
&& template_header_p)
{
if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM)
return t;
- /* Since SCOPE is not TS_CURRENT, we are not looking at a
- definition of this tag. Since, in addition, we are currently
- processing a (member) template declaration of a template
- class, we must be very careful; consider:
+ /* Since HOW is not TAG_how::CURRENT_ONLY, we are not looking at
+ a definition of this tag. Since, in addition, we are
+ currently processing a (member) template declaration of a
+ template class, we must be very careful; consider:
template <class X> struct S1
/* Mark it as a lambda type right now. Our caller will
correct the value. */
CLASSTYPE_LAMBDA_EXPR (t) = error_mark_node;
- t = pushtag (name, t, scope);
+ t = pushtag (name, t, how);
}
else
{
return error_mark_node;
}
- if (scope != ts_within_enclosing_non_class && TYPE_HIDDEN_P (t))
+ if (how != TAG_how::HIDDEN_FRIEND && TYPE_HIDDEN_P (t))
{
/* This is no longer an invisible friend. Make it
visible. */
tree
xref_tag (enum tag_types tag_code, tree name,
- tag_scope scope, bool template_header_p)
+ TAG_how how, bool template_header_p)
{
- tree ret;
- bool subtime;
- subtime = timevar_cond_start (TV_NAME_LOOKUP);
- ret = xref_tag_1 (tag_code, name, scope, template_header_p);
+ bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+ tree ret = xref_tag_1 (tag_code, name, how, template_header_p);
timevar_cond_stop (TV_NAME_LOOKUP, subtime);
return ret;
}
forward reference. */
if (!enumtype)
enumtype = lookup_and_check_tag (enum_type, name,
- /*tag_scope=*/ts_current,
+ /*tag_scope=*/TAG_how::CURRENT_ONLY,
/*template_header_p=*/false);
/* In case of a template_decl, the only check that should be deferred
}
/* Look up NAME for type used in elaborated name specifier in
- the scopes given by SCOPE. SCOPE can be either TS_CURRENT or
- TS_WITHIN_ENCLOSING_NON_CLASS. Although not implied by the
- name, more scopes are checked if cleanup or template parameter
- scope is encountered.
+ the scopes given by HOW.
Unlike lookup_name_1, we make sure that NAME is actually
declared in the desired scope, not from inheritance, nor using
directive. For using declaration, there is DR138 still waiting
to be resolved. Hidden name coming from an earlier friend
- declaration is also returned.
+ declaration is also returned, and will be made visible unless HOW
+ is TAG_how::HIDDEN_FRIEND.
A TYPE_DECL best matching the NAME is returned. Catching error
and issuing diagnostics are caller's responsibility. */
static tree
-lookup_type_scope_1 (tree name, tag_scope scope)
+lookup_elaborated_type_1 (tree name, TAG_how how)
{
cp_binding_level *b = current_binding_level;
if (!(b->kind == sk_cleanup
|| b->kind == sk_template_parms
|| b->kind == sk_function_parms
- || (b->kind == sk_class
- && scope == ts_within_enclosing_non_class)))
+ || (b->kind == sk_class && how != TAG_how::CURRENT_ONLY)))
return NULL_TREE;
/* Check if this is the kind of thing we're looking for. If
- SCOPE is TS_CURRENT, also make sure it doesn't come from
- base class. For ITER->VALUE, we can simply use
- INHERITED_VALUE_BINDING_P. For ITER->TYPE, we have to
- use our own check.
+ HOW is TAG_how::CURRENT_ONLY, also make sure it doesn't
+ come from base class. For ITER->VALUE, we can simply use
+ INHERITED_VALUE_BINDING_P. For ITER->TYPE, we have to use
+ our own check.
We check ITER->TYPE before ITER->VALUE in order to handle
typedef struct C {} C;
correctly. */
+
if (tree type = iter->type)
if (qualify_lookup (type, LOOK_want::TYPE)
- && (scope != ts_current
+ && (how != TAG_how::CURRENT_ONLY
|| LOCAL_BINDING_P (iter)
|| DECL_CONTEXT (type) == iter->scope->this_entity))
return type;
if (qualify_lookup (iter->value, LOOK_want::TYPE)
- && (scope != ts_current
+ && (how != TAG_how::CURRENT_ONLY
|| !INHERITED_VALUE_BINDING_P (iter)))
return iter->value;
}
if (!(b->kind == sk_cleanup
|| b->kind == sk_template_parms
|| b->kind == sk_function_parms
- || (b->kind == sk_class
- && scope == ts_within_enclosing_non_class)))
+ || (b->kind == sk_class && how != TAG_how::CURRENT_ONLY)))
return NULL_TREE;
/* Look in the innermost namespace. */
return NULL_TREE;
}
-
+
/* Wrapper for lookup_type_scope_1. */
tree
-lookup_type_scope (tree name, tag_scope scope)
+lookup_elaborated_type (tree name, TAG_how how)
{
- tree ret;
bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
- ret = lookup_type_scope_1 (name, scope);
+ tree ret = lookup_elaborated_type_1 (name, how);
timevar_cond_stop (TV_NAME_LOOKUP, subtime);
return ret;
}
Returns TYPE upon success and ERROR_MARK_NODE otherwise. */
static tree
-do_pushtag (tree name, tree type, tag_scope scope)
+do_pushtag (tree name, tree type, TAG_how how)
{
tree decl;
declaration, these scopes are not scopes from the point of
view of the language. */
|| (b->kind == sk_template_parms
- && (b->explicit_spec_p || scope == ts_global)))
+ && (b->explicit_spec_p || how == TAG_how::GLOBAL)))
b = b->level_chain;
- else if (b->kind == sk_class
- && scope != ts_current)
+ else if (b->kind == sk_class && how != TAG_how::CURRENT_ONLY)
{
b = b->level_chain;
if (b->kind == sk_template_parms)
: TYPE_P (cs) ? cs == current_class_type
: cs == current_namespace);
- if (scope == ts_current
+ if (how == TAG_how::CURRENT_ONLY
|| (cs && TREE_CODE (cs) == FUNCTION_DECL))
context = cs;
else if (cs && TYPE_P (cs))
tdef = create_implicit_typedef (name, type);
DECL_CONTEXT (tdef) = FROB_CONTEXT (context);
- if (scope == ts_within_enclosing_non_class)
+ bool is_friend = how == TAG_how::HIDDEN_FRIEND;
+ if (is_friend)
{
+ // FIXME: can go away
/* This is a friend. Make this TYPE_DECL node hidden from
ordinary name lookup. Its corresponding TEMPLATE_DECL
- will be marked in push_template_decl_real. */
+ will be marked in push_template_decl. */
retrofit_lang_decl (tdef);
DECL_ANTICIPATED (tdef) = 1;
DECL_FRIEND_P (tdef) = 1;
}
- decl = maybe_process_template_type_declaration
- (type, scope == ts_within_enclosing_non_class, b);
+ decl = maybe_process_template_type_declaration (type, is_friend, b);
if (decl == error_mark_node)
return decl;
}
else if (b->kind != sk_template_parms)
{
- decl = do_pushdecl_with_scope (decl, b, /*is_friend=*/false);
+ decl = do_pushdecl_with_scope
+ (decl, b, /*hiding=*/(how == TAG_how::HIDDEN_FRIEND));
if (decl == error_mark_node)
return decl;
/* Wrapper for do_pushtag. */
tree
-pushtag (tree name, tree type, tag_scope scope)
+pushtag (tree name, tree type, TAG_how how)
{
- tree ret;
bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
- ret = do_pushtag (name, type, scope);
+ tree ret = do_pushtag (name, type, how);
timevar_cond_stop (TV_NAME_LOOKUP, subtime);
return ret;
}
sk_omp /* An OpenMP structured block. */
};
-/* The scope where the class/struct/union/enum tag applies. */
-enum tag_scope {
- ts_current = 0, /* Current scope only. This is for the
- class-key identifier;
- case mentioned in [basic.lookup.elab]/2,
- or the class/enum definition
- class-key identifier { ... }; */
- ts_global = 1, /* All scopes. This is the 3.4.1
- [basic.lookup.unqual] lookup mentioned
- in [basic.lookup.elab]/2. */
- ts_within_enclosing_non_class = 2, /* Search within enclosing non-class
- only, for friend class lookup
- according to [namespace.memdef]/3
- and [class.friend]/9. */
-};
-
struct GTY(()) cp_class_binding {
cxx_binding *base;
/* The bound name. */
return lookup_name (name, LOOK_where::ALL, want);
}
-extern tree lookup_type_scope (tree, tag_scope);
+enum class TAG_how
+{
+ CURRENT_ONLY = 0, // Look and insert only in current scope
+
+ GLOBAL = 1, // Unqualified lookup, innermost-non-class insertion
+
+ INNERMOST_NON_CLASS = 2, // Look and insert only into
+ // innermost-non-class
+
+ HIDDEN_FRIEND = 3, // As INNERMOST_NON_CLASS, but hide it
+};
+
+extern tree lookup_elaborated_type (tree, TAG_how);
extern tree get_namespace_binding (tree ns, tree id);
extern void set_global_binding (tree decl);
inline tree get_global_binding (tree id)
extern tree pushdecl_outermost_localscope (tree);
extern tree pushdecl_top_level (tree, bool is_friend = false);
extern tree pushdecl_top_level_and_finish (tree, tree);
-extern tree pushtag (tree, tree, tag_scope = ts_current);
+extern tree pushtag (tree, tree, TAG_how = TAG_how::CURRENT_ONLY);
extern int push_namespace (tree, bool make_inline = false);
extern void pop_namespace (void);
extern void push_nested_namespace (tree);
definition of a new type; a new type can only be declared in a
declaration context. */
- tag_scope ts;
- bool template_p;
+ TAG_how how;
if (is_friend)
/* Friends have special name lookup rules. */
- ts = ts_within_enclosing_non_class;
+ how = TAG_how::HIDDEN_FRIEND;
else if (is_declaration
&& cp_lexer_next_token_is (parser->lexer,
CPP_SEMICOLON))
/* This is a `class-key identifier ;' */
- ts = ts_current;
+ how = TAG_how::CURRENT_ONLY;
else
- ts = ts_global;
+ how = TAG_how::GLOBAL;
- template_p =
+ bool template_p =
(template_parm_lists_apply
&& (cp_parser_next_token_starts_class_definition_p (parser)
|| cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)));
token->location,
/*declarator=*/NULL))
return error_mark_node;
- type = xref_tag (tag_type, identifier, ts, template_p);
+
+ type = xref_tag (tag_type, identifier, how, template_p);
}
}
/* If the class was unnamed, create a dummy name. */
if (!id)
id = make_anon_name ();
- tag_scope tag_scope = (parser->in_type_id_in_expr_p
- ? ts_within_enclosing_non_class
- : ts_current);
- type = xref_tag (class_key, id, tag_scope,
+ TAG_how how = (parser->in_type_id_in_expr_p
+ ? TAG_how::INNERMOST_NON_CLASS
+ : TAG_how::CURRENT_ONLY);
+ type = xref_tag (class_key, id, how,
parser->num_template_parameter_lists);
}
if (!name)
name = make_anon_name ();
- s = xref_tag (record_type, name, ts_global);
+ s = xref_tag (record_type, name, TAG_how::GLOBAL);
CLASSTYPE_DECLARED_CLASS (s) = 0; /* this is a 'struct', not a 'class'. */
xref_basetypes (s, NULL_TREE); /* no base classes here! */
tree
objcp_xref_tag (enum tree_code code ATTRIBUTE_UNUSED, tree name)
{
- return xref_tag (record_type, name, ts_global);
+ return xref_tag (record_type, name, TAG_how::GLOBAL);
}
int