forked from OSchip/llvm-project
Fix cases where the optional nested-name-specifier erroneously preceeded a decltype-specification when specifying a base type.
llvm-svn: 142928
This commit is contained in:
parent
00ee7a081d
commit
1cd50022b2
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue