Skip to content

Commit 1cd5002

Browse files
committed
Fix cases where the optional nested-name-specifier erroneously preceeded a decltype-specification when specifying a base type.
llvm-svn: 142928
1 parent 00ee7a0 commit 1cd5002

File tree

3 files changed

+28
-23
lines changed

3 files changed

+28
-23
lines changed

clang/include/clang/Parse/Parser.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2012,8 +2012,8 @@ class Parser : public CodeCompletionHandler {
20122012

20132013
//===--------------------------------------------------------------------===//
20142014
// C++ 10: Derived classes [class.derived]
2015-
TypeResult ParseBaseTypeSpecifier(SourceLocation &EndLocation,
2016-
CXXScopeSpec &SS);
2015+
TypeResult ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
2016+
SourceLocation &EndLocation);
20172017
void ParseBaseClause(Decl *ClassDecl);
20182018
BaseResult ParseBaseSpecifier(Decl *ClassDecl);
20192019
AccessSpecifier getAccessSpecifierIfPresent() const;

clang/lib/Parse/ParseDeclCXX.cpp

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -711,8 +711,26 @@ void Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) {
711711
/// identifier
712712
/// simple-template-id
713713
///
714-
Parser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &EndLocation,
715-
CXXScopeSpec &SS) {
714+
Parser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
715+
SourceLocation &EndLocation) {
716+
// Parse decltype-specifier
717+
if (Tok.is(tok::kw_decltype)) {
718+
// Fake up a Declarator to use with ActOnTypeName.
719+
DeclSpec DS(AttrFactory);
720+
721+
ParseDecltypeSpecifier(DS);
722+
EndLocation = DS.getSourceRange().getEnd();
723+
724+
Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
725+
return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
726+
}
727+
728+
// Parse optional nested-name-specifier
729+
CXXScopeSpec SS;
730+
ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
731+
732+
BaseLoc = Tok.getLocation();
733+
716734
// Check whether we have a template-id that names a type.
717735
if (Tok.is(tok::annot_template_id)) {
718736
TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
@@ -733,17 +751,6 @@ Parser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &EndLocation,
733751
// Fall through to produce an error below.
734752
}
735753

736-
if (Tok.is(tok::kw_decltype)) {
737-
// Fake up a Declarator to use with ActOnTypeName.
738-
DeclSpec DS(AttrFactory);
739-
740-
ParseDecltypeSpecifier(DS);
741-
EndLocation = DS.getSourceRange().getEnd();
742-
743-
Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
744-
return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
745-
}
746-
747754
if (Tok.isNot(tok::identifier)) {
748755
Diag(Tok, diag::err_expected_class_name);
749756
return true;
@@ -1410,16 +1417,10 @@ Parser::BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) {
14101417
IsVirtual = true;
14111418
}
14121419

1413-
// Parse optional '::' and optional nested-name-specifier.
1414-
CXXScopeSpec SS;
1415-
ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
1416-
1417-
// The location of the base class itself.
1418-
SourceLocation BaseLoc = Tok.getLocation();
1419-
14201420
// Parse the class-name.
14211421
SourceLocation EndLocation;
1422-
TypeResult BaseType = ParseBaseTypeSpecifier(EndLocation, SS);
1422+
SourceLocation BaseLoc;
1423+
TypeResult BaseType = ParseBaseTypeSpecifier(BaseLoc, EndLocation);
14231424
if (BaseType.isInvalid())
14241425
return true;
14251426

clang/test/CXX/class.derived/p1.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,8 @@ namespace PR11216 {
3030
struct Derived3 : decltype(T().foo()) { };
3131
struct Foo { Base foo(); };
3232
Derived3<Foo> d;
33+
34+
struct Derived4 : :: decltype(Base()) { }; // expected-error {{expected class name}}
35+
36+
struct Derived5 : PR11216:: decltype(Base()) { }; // expected-error {{expected class name}}
3337
}

0 commit comments

Comments
 (0)