diff options
author | David Blaikie <dblaikie@gmail.com> | 2011-10-25 17:10:12 +0000 |
---|---|---|
committer | David Blaikie <dblaikie@gmail.com> | 2011-10-25 17:10:12 +0000 |
commit | 1cd50022b2fd8c8845f452a9aca4d4483578dd4e (patch) | |
tree | a3017561cd0ba333338335a917d13c4a7e2045d8 /clang | |
parent | 00ee7a081d09de7e46771524a95a8555c512222a (diff) | |
download | bcm5719-llvm-1cd50022b2fd8c8845f452a9aca4d4483578dd4e.tar.gz bcm5719-llvm-1cd50022b2fd8c8845f452a9aca4d4483578dd4e.zip |
Fix cases where the optional nested-name-specifier erroneously preceeded a decltype-specification when specifying a base type.
llvm-svn: 142928
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/Parse/Parser.h | 4 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 43 | ||||
-rw-r--r-- | clang/test/CXX/class.derived/p1.cpp | 4 |
3 files changed, 28 insertions, 23 deletions
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 449d83f7c15..c863e76b9d4 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -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; diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 9d2db2ae1c0..10234ab8921 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -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; diff --git a/clang/test/CXX/class.derived/p1.cpp b/clang/test/CXX/class.derived/p1.cpp index 98c1d354fab..dcbe63fd09a 100644 --- a/clang/test/CXX/class.derived/p1.cpp +++ b/clang/test/CXX/class.derived/p1.cpp @@ -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}} } |