diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 14 | ||||
| -rw-r--r-- | clang/lib/Parse/Parser.cpp | 26 |
2 files changed, 35 insertions, 5 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 9fe4309ca12..2a999399fb5 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -1548,15 +1548,21 @@ void Parser::DiagnoseMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs, SourceLocation Loc = Tok.getLocation(); ParseCXX11Attributes(Attrs); CharSourceRange AttrRange(SourceRange(Loc, Attrs.Range.getEnd()), true); - + // FIXME: use err_attributes_misplaced Diag(Loc, diag::err_attributes_not_allowed) << FixItHint::CreateInsertionFromRange(CorrectLocation, AttrRange) << FixItHint::CreateRemoval(AttrRange); } -void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) { - Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed) - << attrs.Range; +void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs, + const SourceLocation CorrectLocation) { + if (CorrectLocation.isValid()) { + CharSourceRange AttrRange(attrs.Range, true); + Diag(CorrectLocation, diag::err_attributes_misplaced) + << FixItHint::CreateInsertionFromRange(CorrectLocation, AttrRange) + << FixItHint::CreateRemoval(AttrRange); + } else + Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed) << attrs.Range; } void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs, diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 72d653797c6..8aa50a2c7f2 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -930,7 +930,31 @@ Parser::ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs, // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };" // declaration-specifiers init-declarator-list[opt] ';' if (Tok.is(tok::semi)) { - ProhibitAttributes(attrs); + auto LengthOfTSTToken = [](DeclSpec::TST TKind) { + assert(DeclSpec::isDeclRep(TKind)); + switch(TKind) { + case DeclSpec::TST_class: + return 5; + case DeclSpec::TST_struct: + return 6; + case DeclSpec::TST_union: + return 5; + case DeclSpec::TST_enum: + return 4; + case DeclSpec::TST_interface: + return 9; + default: + llvm_unreachable("we only expect to get the length of the class/struct/union/enum"); + } + + }; + // Suggest correct location to fix '[[attrib]] struct' to 'struct [[attrib]]' + SourceLocation CorrectLocationForAttributes = + DeclSpec::isDeclRep(DS.getTypeSpecType()) + ? DS.getTypeSpecTypeLoc().getLocWithOffset( + LengthOfTSTToken(DS.getTypeSpecType())) + : SourceLocation(); + ProhibitAttributes(attrs, CorrectLocationForAttributes); ConsumeToken(); RecordDecl *AnonRecord = nullptr; Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none, |

