We were frobing lamda scopes to regular classes when pushing them, but
with a few tweaks name lookup can cope directly.
nathan
--
Nathan Sidwell
2017-05-11 Nathan Sidwell <nat...@acm.org>
* decl.c (xref_tag_1): Don't frob ts_lambda scope here.
* name-lookup.c (pushtag_1): Deal with ts_lambda scope.
Index: decl.c
===================================================================
--- decl.c (revision 247908)
+++ decl.c (working copy)
@@ -13514,12 +13514,10 @@ lookup_and_check_tag (enum tag_types tag
static tree
xref_tag_1 (enum tag_types tag_code, tree name,
- tag_scope orig_scope, bool template_header_p)
+ tag_scope scope, bool template_header_p)
{
enum tree_code code;
- tree t;
tree context = NULL_TREE;
- tag_scope scope;
gcc_assert (identifier_p (name));
@@ -13539,19 +13537,12 @@ xref_tag_1 (enum tag_types tag_code, tre
gcc_unreachable ();
}
- if (orig_scope == ts_lambda)
- scope = ts_current;
- else
- scope = orig_scope;
-
/* In case of anonymous name, xref_tag is only called to
make type node and push name. Name lookup is not required. */
- if (anon_aggrname_p (name))
- t = NULL_TREE;
- else
- t = lookup_and_check_tag (tag_code, name,
- scope, template_header_p);
-
+ tree t = NULL_TREE;
+ if (scope != ts_lambda && !anon_aggrname_p (name))
+ t = lookup_and_check_tag (tag_code, name, scope, template_header_p);
+
if (t == error_mark_node)
return error_mark_node;
@@ -13617,9 +13608,8 @@ xref_tag_1 (enum tag_types tag_code, tre
{
t = make_class_type (code);
TYPE_CONTEXT (t) = context;
- if (orig_scope == ts_lambda)
- /* Remember that we're declaring a lambda to avoid bogus errors
- in push_template_decl. */
+ if (scope == ts_lambda)
+ /* Mark it as a lambda type. */
CLASSTYPE_LAMBDA_EXPR (t) = error_mark_node;
t = pushtag (name, t, scope);
}
Index: name-lookup.c
===================================================================
--- name-lookup.c (revision 247908)
+++ name-lookup.c (working copy)
@@ -6079,7 +6079,9 @@ pushtag_1 (tree name, tree type, tag_sco
view of the language. */
|| (b->kind == sk_template_parms
&& (b->explicit_spec_p || scope == ts_global))
+ /* Pushing into a class is ok for lambdas or when we want current */
|| (b->kind == sk_class
+ && scope != ts_lambda
&& (scope != ts_current
/* We may be defining a new type in the initializer
of a static member variable. We allow this when
@@ -6102,9 +6104,10 @@ pushtag_1 (tree name, tree type, tag_sco
tree cs = current_scope ();
if (scope == ts_current
+ || scope == ts_lambda
|| (cs && TREE_CODE (cs) == FUNCTION_DECL))
context = cs;
- else if (cs != NULL_TREE && TYPE_P (cs))
+ else if (cs && TYPE_P (cs))
/* When declaring a friend class of a local class, we want
to inject the newly named class into the scope
containing the local class, not the namespace
@@ -6138,7 +6141,8 @@ pushtag_1 (tree name, tree type, tag_sco
if (b->kind == sk_class)
{
- if (!TYPE_BEING_DEFINED (current_class_type))
+ if (!TYPE_BEING_DEFINED (current_class_type)
+ && scope != ts_lambda)
return error_mark_node;
if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
@@ -6189,6 +6193,7 @@ pushtag_1 (tree name, tree type, tag_sco
vec_safe_push (local_classes, type);
}
}
+
if (b->kind == sk_class
&& !COMPLETE_TYPE_P (current_class_type))
{