[cfe-commits] r171757 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseDeclCXX.cpp test/FixIt/fixit-cxx11-attributes.cpp test/Parser/cxx0x-attributes.cpp
Michael Han
fragmentshaders at gmail.com
Mon Jan 7 08:57:12 PST 2013
Author: hanm
Date: Mon Jan 7 10:57:11 2013
New Revision: 171757
URL: http://llvm.org/viewvc/llvm-project?rev=171757&view=rev
Log:
Add fixit hints for misplaced C++11 attributes around class specifiers.
Following r168626, in class declaration or definition, there are a combination of syntactic locations
where C++11 attributes could appear, and among those the only valid location permitted by standard is
between class-key and class-name. So for those attributes appear at wrong locations, fixit is used to
move them to expected location and we recover by applying them to the class specifier.
Added:
cfe/trunk/test/FixIt/fixit-cxx11-attributes.cpp
Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/test/Parser/cxx0x-attributes.cpp
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=171757&r1=171756&r2=171757&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon Jan 7 10:57:11 2013
@@ -2060,7 +2060,10 @@
AccessSpecifier AS, bool EnteringContext,
DeclSpecContext DSC,
ParsedAttributesWithRange &Attributes);
- void ParseCXXMemberSpecification(SourceLocation StartLoc, unsigned TagType,
+ void ParseCXXMemberSpecification(SourceLocation StartLoc,
+ SourceLocation AttrFixitLoc,
+ ParsedAttributes &Attrs,
+ unsigned TagType,
Decl *TagDecl);
ExprResult ParseCXXMemberInitializer(Decl *D, bool IsFunction,
SourceLocation &EqualLoc);
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=171757&r1=171756&r2=171757&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon Jan 7 10:57:11 2013
@@ -1106,6 +1106,10 @@
// styles of attributes?
MaybeParseCXX11Attributes(attrs);
+ // Source location used by FIXIT to insert misplaced
+ // C++11 attributes
+ SourceLocation AttrFixitLoc = Tok.getLocation();
+
if (TagType == DeclSpec::TST_struct &&
!Tok.is(tok::identifier) &&
Tok.getIdentifierInfo() &&
@@ -1322,9 +1326,25 @@
// Forbid misplaced attributes. In cases of a reference, we pass attributes
// to caller to handle.
- // FIXME: provide fix-it hints if we can.
- if (TUK != Sema::TUK_Reference)
- ProhibitAttributes(Attributes);
+ if (TUK != Sema::TUK_Reference) {
+ // If this is not a reference, then the only possible
+ // valid place for C++11 attributes to appear here
+ // is between class-key and class-name. If there are
+ // any attributes after class-name, we try a fixit to move
+ // them to the right place.
+ SourceRange AttrRange = Attributes.Range;
+ if (AttrRange.isValid()) {
+ Diag(AttrRange.getBegin(), diag::err_attributes_not_allowed)
+ << AttrRange
+ << FixItHint::CreateInsertionFromRange(AttrFixitLoc,
+ CharSourceRange(AttrRange, true))
+ << FixItHint::CreateRemoval(AttrRange);
+
+ // Recover by adding misplaced attributes to the attribute list
+ // of the class so they can be applied on the class later.
+ attrs.takeAllFrom(Attributes);
+ }
+ }
// If this is an elaborated type specifier, and we delayed
// diagnostics before, just merge them into the current pool.
@@ -1508,7 +1528,8 @@
(getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
isCXX11FinalKeyword());
if (getLangOpts().CPlusPlus)
- ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get());
+ ParseCXXMemberSpecification(StartLoc, AttrFixitLoc, attrs, TagType,
+ TagOrTempResult.get());
else
ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
}
@@ -2346,6 +2367,8 @@
/// access-specifier ':' member-specification[opt]
///
void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
+ SourceLocation AttrFixitLoc,
+ ParsedAttributes &Attrs,
unsigned TagType, Decl *TagDecl) {
assert((TagType == DeclSpec::TST_struct ||
TagType == DeclSpec::TST_interface ||
@@ -2414,10 +2437,24 @@
diag::ext_override_control_keyword) << "final";
}
- // Forbid C++11 attributes that appear here.
- ParsedAttributesWithRange Attrs(AttrFactory);
- MaybeParseCXX11Attributes(Attrs);
- ProhibitAttributes(Attrs);
+ // Parse any C++11 attributes after 'final' keyword.
+ // These attributes are not allowed to appear here,
+ // and the only possible place for them to appertain
+ // to the class would be between class-key and class-name.
+ ParsedAttributesWithRange Attributes(AttrFactory);
+ MaybeParseCXX11Attributes(Attributes);
+ SourceRange AttrRange = Attributes.Range;
+ if (AttrRange.isValid()) {
+ Diag(AttrRange.getBegin(), diag::err_attributes_not_allowed)
+ << AttrRange
+ << FixItHint::CreateInsertionFromRange(AttrFixitLoc,
+ CharSourceRange(AttrRange, true))
+ << FixItHint::CreateRemoval(AttrRange);
+
+ // Recover by adding attributes to the attribute list of the class
+ // so they can be applied on the class later.
+ Attrs.takeAllFrom(Attributes);
+ }
}
if (Tok.is(tok::colon)) {
Added: cfe/trunk/test/FixIt/fixit-cxx11-attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-cxx11-attributes.cpp?rev=171757&view=auto
==============================================================================
--- cfe/trunk/test/FixIt/fixit-cxx11-attributes.cpp (added)
+++ cfe/trunk/test/FixIt/fixit-cxx11-attributes.cpp Mon Jan 7 10:57:11 2013
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -verify -std=c++11 %s
+// RUN: cp %s %t
+// RUN: not %clang_cc1 -x c++ -std=c++11 -fixit %t
+// RUN: %clang_cc1 -Wall -pedantic -x c++ -std=c++11 %t
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+
+namespace ClassSpecifier {
+ class [[]] [[]]
+ attr_after_class_name_decl [[]] [[]]; // expected-error {{an attribute list cannot appear here}}
+ // CHECK: fix-it:{{.*}}:{9:5-9:5}
+ // CHECK: fix-it:{{.*}}:{9:32-9:41}
+
+ class [[]] [[]]
+ attr_after_class_name_definition [[]] [[]] [[]]{}; // expected-error {{an attribute list cannot appear here}}
+ // CHECK: fix-it:{{.*}}:{14:4-14:4}
+ // CHECK: fix-it:{{.*}}:{14:37-14:51}
+
+ class base {};
+ class [[]] [[]] final_class
+ alignas(float) [[]] final // expected-error {{an attribute list cannot appear here}}
+ alignas(float) [[]] [[]] alignas(float): base{}; // expected-error {{an attribute list cannot appear here}}
+ // CHECK: fix-it:{{.*}}:{19:19-19:19}
+ // CHECK: fix-it:{{.*}}:{20:5-20:25}
+ // CHECK: fix-it:{{.*}}:{19:19-19:19}
+ // CHECK: fix-it:{{.*}}:{21:5-21:44}
+
+ class [[]] [[]] final_class_another
+ [[]] [[]] alignas(16) final // expected-error {{an attribute list cannot appear here}}
+ [[]] [[]] alignas(16) [[]]{}; // expected-error {{an attribute list cannot appear here}}
+ // CHECK: fix-it:{{.*}}:{27:19-27:19}
+ // CHECK: fix-it:{{.*}}:{28:5-28:27}
+ // CHECK: fix-it:{{.*}}:{27:19-27:19}
+ // CHECK: fix-it:{{.*}}:{29:5-29:31}
+}
Modified: cfe/trunk/test/Parser/cxx0x-attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-attributes.cpp?rev=171757&r1=171756&r2=171757&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-attributes.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-attributes.cpp Mon Jan 7 10:57:11 2013
@@ -64,7 +64,6 @@
union [[]] union_attr;
// Checks attributes placed at wrong syntactic locations of class specifiers.
-// FIXME: provide fix-it hint.
class [[]] [[]]
attr_after_class_name_decl [[]] [[]]; // expected-error {{an attribute list cannot appear here}}
More information about the cfe-commits
mailing list