]> granicus.if.org Git - clang/commitdiff
Fix cases where the optional nested-name-specifier erroneously preceeded a decltype...
authorDavid Blaikie <dblaikie@gmail.com>
Tue, 25 Oct 2011 17:10:12 +0000 (17:10 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Tue, 25 Oct 2011 17:10:12 +0000 (17:10 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142928 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Parse/Parser.h
lib/Parse/ParseDeclCXX.cpp
test/CXX/class.derived/p1.cpp

index 449d83f7c15ff413eb9ba6c6b101765308c832ad..c863e76b9d474a52a85bbe02d2380180c566170e 100644 (file)
@@ -2012,8 +2012,8 @@ private:
 
   //===--------------------------------------------------------------------===//
   // C++ 10: Derived classes [class.derived]
-  TypeResult ParseBaseTypeSpecifier(SourceLocation &EndLocation
-                                    CXXScopeSpec &SS);
+  TypeResult ParseBaseTypeSpecifier(SourceLocation &BaseLoc
+                                    SourceLocation &EndLocation);
   void ParseBaseClause(Decl *ClassDecl);
   BaseResult ParseBaseSpecifier(Decl *ClassDecl);
   AccessSpecifier getAccessSpecifierIfPresent() const;
index 9d2db2ae1c09de91ebc2bdba9fc915930b8275e5..10234ab89214cebdfcff211222d632486ea43b8d 100644 (file)
@@ -711,8 +711,26 @@ void Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) {
 ///         identifier
 ///         simple-template-id
 ///
-Parser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &EndLocation,
-                                                  CXXScopeSpec &SS) {
+Parser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
+                                                  SourceLocation &EndLocation) {
+  // Parse decltype-specifier
+  if (Tok.is(tok::kw_decltype)) {
+    // Fake up a Declarator to use with ActOnTypeName.
+    DeclSpec DS(AttrFactory);
+
+    ParseDecltypeSpecifier(DS);    
+    EndLocation = DS.getSourceRange().getEnd();
+
+    Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+    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);
@@ -733,17 +751,6 @@ Parser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &EndLocation,
     // Fall through to produce an error below.
   }
 
-  if (Tok.is(tok::kw_decltype)) {
-    // Fake up a Declarator to use with ActOnTypeName.
-    DeclSpec DS(AttrFactory);
-
-    ParseDecltypeSpecifier(DS);    
-    EndLocation = DS.getSourceRange().getEnd();
-
-    Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
-    return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
-  }
-
   if (Tok.isNot(tok::identifier)) {
     Diag(Tok, diag::err_expected_class_name);
     return true;
@@ -1410,16 +1417,10 @@ Parser::BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) {
     IsVirtual = true;
   }
 
-  // Parse optional '::' and optional nested-name-specifier.
-  CXXScopeSpec SS;
-  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
-
-  // The location of the base class itself.
-  SourceLocation BaseLoc = Tok.getLocation();
-
   // Parse the class-name.
   SourceLocation EndLocation;
-  TypeResult BaseType = ParseBaseTypeSpecifier(EndLocation, SS);
+  SourceLocation BaseLoc;
+  TypeResult BaseType = ParseBaseTypeSpecifier(BaseLoc, EndLocation);
   if (BaseType.isInvalid())
     return true;
 
index 98c1d354fabcca8708a94fffb8ffffb211c618e3..dcbe63fd09a718d70bd75fd8ccfcc8a21bdf36f4 100644 (file)
@@ -30,4 +30,8 @@ namespace PR11216 {
   struct Derived3 : decltype(T().foo()) { };
   struct Foo { Base foo(); };
   Derived3<Foo> d;
+
+  struct Derived4 : :: decltype(Base()) { }; // expected-error {{expected class name}}
+
+  struct Derived5 : PR11216:: decltype(Base()) { }; // expected-error {{expected class name}}
 }