Hi,

On 01/22/2014 06:13 PM, Jason Merrill wrote:
On 01/21/2014 09:55 AM, Jason Merrill wrote:
I think I would prefer to change the "child" assert to be
MAYBE_CLASS_TYPE_P rather than CLASS_TYPE_P.
On second thought, no, I think we do want to specifically handle TYPENAME_TYPE. But I think we want a different error message; getting a TYPENAME_TYPE here means that B has not been declared. The current scope is irrelevant. So we want to check for TYPENAME_TYPE before we think about checking prev_scope.
Ok. In fact I entertained myself this kind of reasoning, a couple of days ago...

I tested the below, which uses "by hand" %Es instead of %qT for more concise error messages (consistent with the non-template case).

Thanks,
Paolo.

////////////////////
/cp
2014-01-22  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/58980
        * parser.c (cp_parser_enum_specifier): Handle TYPENAME_TYPE as
        nested_name_specifier.

/testsuite
2014-01-22  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/58980
        * g++.dg/parse/enum11.C: New.
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 206933)
+++ cp/parser.c (working copy)
@@ -15469,9 +15469,17 @@ cp_parser_enum_specifier (cp_parser* parser)
            error_at (type_start_token->location, "cannot add an enumerator "
                      "list to a template instantiation");
 
+         if (prev_scope && TREE_CODE (nested_name_specifier) == TYPENAME_TYPE)
+           {
+             error_at (type_start_token->location,
+                       "%<%E::%E%> has not been declared",
+                       prev_scope, nested_name_specifier);
+             type = error_mark_node;
+           }
          /* If that scope does not contain the scope in which the
             class was originally declared, the program is invalid.  */
-         if (prev_scope && !is_ancestor (prev_scope, nested_name_specifier))
+         else if (prev_scope && !is_ancestor (prev_scope,
+                                              nested_name_specifier))
            {
              if (at_namespace_scope_p ())
                error_at (type_start_token->location,
@@ -15480,7 +15488,8 @@ cp_parser_enum_specifier (cp_parser* parser)
                          type, prev_scope, nested_name_specifier);
              else
                error_at (type_start_token->location,
-                         "declaration of %qD in %qD which does not enclose 
%qD",
+                         "declaration of %qD in %qD which does not "
+                         "enclose %qD",
                          type, prev_scope, nested_name_specifier);
              type = error_mark_node;
            }
Index: testsuite/g++.dg/parse/enum11.C
===================================================================
--- testsuite/g++.dg/parse/enum11.C     (revision 0)
+++ testsuite/g++.dg/parse/enum11.C     (working copy)
@@ -0,0 +1,6 @@
+// PR c++/58980
+
+template<typename> struct A
+{ 
+  enum A::B::C {};   // { dg-error "has not been declared" }
+};

Reply via email to