diff options
author | Michael Han <Michael.Han@autodesk.com> | 2012-11-26 22:54:45 +0000 |
---|---|---|
committer | Michael Han <Michael.Han@autodesk.com> | 2012-11-26 22:54:45 +0000 |
commit | 2e39713a3d72c243a2bcd13cc8f5036ba6b487d9 (patch) | |
tree | 331962074706dbedb7bbc3b98d4c975b54b0a7e5 /lib/Parse/ParseDecl.cpp | |
parent | f5824998702fad8eb2450e992b48d710a59723ff (diff) |
Improve diagnostic on C++11 attribute specifiers that appear at wrong syntactic locations around class specifiers.
This change list implemented logic that explicitly detects several combinations of locations where C++11 attribute
specifiers might be incorrectly placed within a class specifier. Previously we emit generic diagnostics like
"expected identifier" for such cases; now we emit specific diagnostic against the misplaced attributes, this also
fixed a bug in old code where attributes appear at legitimate locations were incorrectly rejected.
Thanks to Richard Smith for reviewing!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@168626 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 7c5b153140..23d1f40e9e 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -1842,7 +1842,8 @@ static bool isValidAfterIdentifierInDeclarator(const Token &T) { /// bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS, const ParsedTemplateInfo &TemplateInfo, - AccessSpecifier AS, DeclSpecContext DSC) { + AccessSpecifier AS, DeclSpecContext DSC, + ParsedAttributesWithRange &Attrs) { assert(Tok.is(tok::identifier) && "should have identifier"); SourceLocation Loc = Tok.getLocation(); @@ -1928,7 +1929,7 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS, ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSC_normal); else ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS, - /*EnteringContext*/ false, DSC_normal); + /*EnteringContext*/ false, DSC_normal, Attrs); return true; } } @@ -2352,7 +2353,14 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // typename. if (TypeRep == 0) { ConsumeToken(); // Eat the scope spec so the identifier is current. - if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext)) continue; + ParsedAttributesWithRange Attrs(AttrFactory); + if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) { + if (!Attrs.empty()) { + AttrsLastTime = true; + attrs.takeAllFrom(Attrs); + } + continue; + } goto DoneWithDeclSpec; } @@ -2448,7 +2456,14 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // If this is not a typedef name, don't parse it as part of the declspec, // it must be an implicit int or an error. if (!TypeRep) { - if (ParseImplicitInt(DS, 0, TemplateInfo, AS, DSContext)) continue; + ParsedAttributesWithRange Attrs(AttrFactory); + if (ParseImplicitInt(DS, 0, TemplateInfo, AS, DSContext, Attrs)) { + if (!Attrs.empty()) { + AttrsLastTime = true; + attrs.takeAllFrom(Attrs); + } + continue; + } goto DoneWithDeclSpec; } @@ -2749,8 +2764,20 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, case tok::kw_union: { tok::TokenKind Kind = Tok.getKind(); ConsumeToken(); + + // These are attributes following class specifiers. + // To produce better diagnostic, we parse them when + // parsing class specifier. + ParsedAttributesWithRange Attributes(AttrFactory); ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS, - EnteringContext, DSContext); + EnteringContext, DSContext, Attributes); + + // If there are attributes following class specifier, + // take them over and handle them here. + if (!Attributes.empty()) { + AttrsLastTime = true; + attrs.takeAllFrom(Attributes); + } continue; } |