]> granicus.if.org Git - clang/commitdiff
Fix erroneous name-specifiers prior to decltypes better/correctly as per Doug's feedback.
authorDavid Blaikie <dblaikie@gmail.com>
Tue, 25 Oct 2011 18:17:58 +0000 (18:17 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Tue, 25 Oct 2011 18:17:58 +0000 (18:17 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142935 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticParseKinds.td
lib/Parse/ParseDeclCXX.cpp
test/CXX/class.derived/p1.cpp

index 3ec893ec51444bdd396cb932ee1c8787ef4915e6..f8b54400e017f3289a9a0b3a6c57fea56fbd00ef 100644 (file)
@@ -249,6 +249,8 @@ def err_missing_comma_before_ellipsis : Error<
   "C requires a comma prior to the ellipsis in a variadic function type">;
 def err_unexpected_typedef_ident : Error<
   "unexpected type name %0: expected identifier">;
+def err_unexpected_scope_on_base_decltype : Error<
+  "unexpected namespace scope prior to decltype">;
 def err_expected_class_name : Error<"expected class name">;
 def err_unspecified_vla_size_with_static : Error<
   "'static' may not be used with an unspecified variable length array size">;
index bdd41a27dfef9e2b76d9aedfd9c6d046a42443ae..8530ff2740a7bedec91d03a75650793d4535c4e5 100644 (file)
@@ -713,13 +713,20 @@ void Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) {
 ///
 Parser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
                                                   SourceLocation &EndLocation) {
+  // Parse optional nested-name-specifier
+  CXXScopeSpec SS;
+  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
+
+  BaseLoc = Tok.getLocation();
+
   // Parse decltype-specifier
   if (Tok.is(tok::kw_decltype)) {
+    if (SS.isNotEmpty())
+      Diag(SS.getBeginLoc(), diag::err_unexpected_scope_on_base_decltype)
+        << FixItHint::CreateRemoval(SS.getRange());
     // Fake up a Declarator to use with ActOnTypeName.
     DeclSpec DS(AttrFactory);
 
-    BaseLoc = Tok.getLocation();
-
     ParseDecltypeSpecifier(DS);    
     EndLocation = DS.getSourceRange().getEnd();
 
@@ -727,12 +734,6 @@ Parser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
     return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
   }
 
-  // Parse optional nested-name-specifier
-  CXXScopeSpec SS;
-  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
-
-  BaseLoc = Tok.getLocation();
-
   // Check whether we have a template-id that names a type.
   if (Tok.is(tok::annot_template_id)) {
     TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
index dcbe63fd09a718d70bd75fd8ccfcc8a21bdf36f4..d819ea2389472ec7a0b8405dec1db5bccc773b60 100644 (file)
@@ -31,7 +31,7 @@ namespace PR11216 {
   struct Foo { Base foo(); };
   Derived3<Foo> d;
 
-  struct Derived4 : :: decltype(Base()) { }; // expected-error {{expected class name}}
+  struct Derived4 : :: decltype(Base()) { }; // expected-error {{unexpected namespace scope prior to decltype}}
 
-  struct Derived5 : PR11216:: decltype(Base()) { }; // expected-error {{expected class name}}
+  struct Derived5 : PR11216:: decltype(Base()) { }; // expected-error {{unexpected namespace scope prior to decltype}}
 }