summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp14
-rw-r--r--clang/lib/Parse/Parser.cpp26
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,
OpenPOWER on IntegriCloud