[cfe-commits] r158661 - in /cfe/trunk: include/clang/Basic/Attr.td include/clang/Sema/AttributeList.h lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp lib/Sema/AttributeList.cpp lib/Sema/SemaStmtAttr.cpp lib/Sema/SemaType.cpp test/SemaCXX/switch-implicit-fallthrough-per-method.cpp utils/TableGen/ClangAttrEmitter.cpp
Sean Hunt
scshunt at csclub.uwaterloo.ca
Mon Jun 18 09:13:53 PDT 2012
Author: coppro
Date: Mon Jun 18 11:13:52 2012
New Revision: 158661
URL: http://llvm.org/viewvc/llvm-project?rev=158661&view=rev
Log:
Handle C++11 attribute namespaces automatically.
Now, as long as the 'Namespaces' variable is correct inside Attr.td, the
generated code will correctly admit a C++11 attribute only when it has the
appropriate namespace(s).
Modified:
cfe/trunk/include/clang/Basic/Attr.td
cfe/trunk/include/clang/Sema/AttributeList.h
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Sema/AttributeList.cpp
cfe/trunk/lib/Sema/SemaStmtAttr.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp
cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=158661&r1=158660&r2=158661&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Mon Jun 18 11:13:52 2012
@@ -320,8 +320,9 @@
}
def FallThrough : Attr {
- let Spellings = ["clang___fallthrough"];
- let Subjects = [CaseStmt, DefaultStmt];
+ let Namespaces = ["clang"];
+ let Spellings = ["fallthrough"];
+ let Subjects = [NullStmt];
}
def FastCall : InheritableAttr {
@@ -850,4 +851,4 @@
def VirtualInheritance : InheritableAttr {
let Spellings = ["__virtual_inheritance"];
-}
\ No newline at end of file
+}
Modified: cfe/trunk/include/clang/Sema/AttributeList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?rev=158661&r1=158660&r2=158661&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/AttributeList.h (original)
+++ cfe/trunk/include/clang/Sema/AttributeList.h Mon Jun 18 11:13:52 2012
@@ -52,6 +52,13 @@
/// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
///
class AttributeList { // TODO: This should really be called ParsedAttribute
+public:
+ /// The style used to specify an attribute.
+ enum Syntax {
+ AS_GNU,
+ AS_CXX11,
+ AS_Declspec
+ };
private:
IdentifierInfo *AttrName;
IdentifierInfo *ScopeName;
@@ -64,11 +71,8 @@
/// The expressions themselves are stored after the object.
unsigned NumArgs : 16;
- /// True if Microsoft style: declspec(foo).
- unsigned DeclspecAttribute : 1;
-
- /// True if C++0x-style: [[foo]].
- unsigned CXX0XAttribute : 1;
+ /// Corresponds to the Syntax enum.
+ unsigned SyntaxUsed : 2;
/// True if already diagnosed as invalid.
mutable unsigned Invalid : 1;
@@ -123,15 +127,14 @@
IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierInfo *parmName, SourceLocation parmLoc,
Expr **args, unsigned numArgs,
- bool declspec, bool cxx0x)
+ Syntax syntaxUsed)
: AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
- NumArgs(numArgs),
- DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false),
+ NumArgs(numArgs), SyntaxUsed(syntaxUsed), Invalid(false),
UsedAsTypeAttr(false), IsAvailability(false),
NextInPosition(0), NextInPool(0) {
if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*));
- AttrKind = getKind(getName(), getScopeName());
+ AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
@@ -142,17 +145,17 @@
const AvailabilityChange &obsoleted,
SourceLocation unavailable,
const Expr *messageExpr,
- bool declspec, bool cxx0x)
+ Syntax syntaxUsed)
: AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
- NumArgs(0), DeclspecAttribute(declspec), CXX0XAttribute(cxx0x),
+ NumArgs(0), SyntaxUsed(syntaxUsed),
Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
UnavailableLoc(unavailable), MessageExpr(messageExpr),
NextInPosition(0), NextInPool(0) {
new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced);
new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated);
new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted);
- AttrKind = getKind(getName(), getScopeName());
+ AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
friend class AttributePool;
@@ -178,8 +181,8 @@
IdentifierInfo *getParameterName() const { return ParmName; }
SourceLocation getParameterLoc() const { return ParmLoc; }
- bool isDeclspecAttribute() const { return DeclspecAttribute; }
- bool isCXX0XAttribute() const { return CXX0XAttribute; }
+ bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
+ bool isCXX0XAttribute() const { return SyntaxUsed == AS_CXX11; }
bool isInvalid() const { return Invalid; }
void setInvalid(bool b = true) const { Invalid = b; }
@@ -188,7 +191,8 @@
void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
Kind getKind() const { return Kind(AttrKind); }
- static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope);
+ static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
+ Syntax SyntaxUsed);
AttributeList *getNext() const { return NextInPosition; }
void setNext(AttributeList *N) { NextInPosition = N; }
@@ -372,14 +376,13 @@
IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierInfo *parmName, SourceLocation parmLoc,
Expr **args, unsigned numArgs,
- bool declspec = false, bool cxx0x = false) {
+ AttributeList::Syntax syntax) {
void *memory = allocate(sizeof(AttributeList)
+ numArgs * sizeof(Expr*));
return add(new (memory) AttributeList(attrName, attrRange,
scopeName, scopeLoc,
parmName, parmLoc,
- args, numArgs,
- declspec, cxx0x));
+ args, numArgs, syntax));
}
AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
@@ -390,14 +393,13 @@
const AvailabilityChange &obsoleted,
SourceLocation unavailable,
const Expr *MessageExpr,
- bool declspec = false, bool cxx0x = false) {
+ AttributeList::Syntax syntax) {
void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
return add(new (memory) AttributeList(attrName, attrRange,
scopeName, scopeLoc,
parmName, parmLoc,
introduced, deprecated, obsoleted,
- unavailable, MessageExpr,
- declspec, cxx0x));
+ unavailable, MessageExpr, syntax));
}
AttributeList *createIntegerAttribute(ASTContext &C, IdentifierInfo *Name,
@@ -499,10 +501,10 @@
IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierInfo *parmName, SourceLocation parmLoc,
Expr **args, unsigned numArgs,
- bool declspec = false, bool cxx0x = false) {
+ AttributeList::Syntax syntax) {
AttributeList *attr =
pool.create(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc,
- args, numArgs, declspec, cxx0x);
+ args, numArgs, syntax);
add(attr);
return attr;
}
@@ -515,12 +517,11 @@
const AvailabilityChange &obsoleted,
SourceLocation unavailable,
const Expr *MessageExpr,
- bool declspec = false, bool cxx0x = false) {
+ AttributeList::Syntax syntax) {
AttributeList *attr =
pool.create(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc,
introduced, deprecated, obsoleted, unavailable,
- MessageExpr,
- declspec, cxx0x);
+ MessageExpr, syntax);
add(attr);
return attr;
}
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=158661&r1=158660&r2=158661&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Jun 18 11:13:52 2012
@@ -159,7 +159,7 @@
}
} else {
attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
- 0, SourceLocation(), 0, 0);
+ 0, SourceLocation(), 0, 0, AttributeList::AS_GNU);
}
}
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
@@ -275,7 +275,8 @@
if (!ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
AttributeList *attr =
Attrs.addNew(AttrName, SourceRange(AttrNameLoc, RParen), 0, AttrNameLoc,
- ParmName, ParmLoc, ArgExprs.take(), ArgExprs.size());
+ ParmName, ParmLoc, ArgExprs.take(), ArgExprs.size(),
+ AttributeList::AS_GNU);
if (BuiltinType && attr->getKind() == AttributeList::AT_iboutletcollection)
Diag(Tok, diag::err_iboutletcollection_builtintype);
}
@@ -319,13 +320,14 @@
if (!ArgExpr.isInvalid()) {
Expr *ExprList = ArgExpr.take();
attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
- SourceLocation(), &ExprList, 1, true);
+ SourceLocation(), &ExprList, 1,
+ AttributeList::AS_Declspec);
}
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
SkipUntil(tok::r_paren, false);
} else {
attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
- 0, SourceLocation(), 0, 0, true);
+ 0, SourceLocation(), 0, 0, AttributeList::AS_Declspec);
}
}
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
@@ -344,7 +346,7 @@
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
SourceLocation AttrNameLoc = ConsumeToken();
attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
- SourceLocation(), 0, 0, true);
+ SourceLocation(), 0, 0, AttributeList::AS_Declspec);
}
}
@@ -354,7 +356,7 @@
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
SourceLocation AttrNameLoc = ConsumeToken();
attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
- SourceLocation(), 0, 0, true);
+ SourceLocation(), 0, 0, AttributeList::AS_Declspec);
}
}
@@ -364,7 +366,7 @@
SourceLocation AttrNameLoc = ConsumeToken();
attrs.addNew(PP.getIdentifierInfo("opencl_kernel_function"),
AttrNameLoc, 0, AttrNameLoc, 0,
- SourceLocation(), 0, 0, false);
+ SourceLocation(), 0, 0, AttributeList::AS_GNU);
}
}
@@ -700,7 +702,7 @@
Changes[Deprecated],
Changes[Obsoleted],
UnavailableLoc, MessageExpr.take(),
- false, false);
+ AttributeList::AS_GNU);
}
@@ -905,7 +907,7 @@
// Match the ')'.
if (ArgExprsOk && !T.consumeClose()) {
Attrs.addNew(&AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(),
- ArgExprs.take(), ArgExprs.size());
+ ArgExprs.take(), ArgExprs.size(), AttributeList::AS_GNU);
}
if (EndLoc)
*EndLoc = T.getCloseLocation();
@@ -1874,7 +1876,8 @@
ExprVector ArgExprs(Actions);
ArgExprs.push_back(ArgExpr.release());
Attrs.addNew(PP.getIdentifierInfo("aligned"), KWLoc, 0, KWLoc,
- 0, T.getOpenLocation(), ArgExprs.take(), 1, false, true);
+ 0, T.getOpenLocation(), ArgExprs.take(), 1,
+ AttributeList::AS_CXX11);
}
/// ParseDeclarationSpecifiers
@@ -2255,8 +2258,10 @@
isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec, DiagID);
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
SourceLocation AttrNameLoc = ConsumeToken();
+ // FIXME: This does not work correctly if it is set to be a declspec
+ // attribute, and a GNU attribute is simply incorrect.
DS.getAttributes().addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
- SourceLocation(), 0, 0);
+ SourceLocation(), 0, 0, AttributeList::AS_GNU);
continue;
}
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=158661&r1=158660&r2=158661&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon Jun 18 11:13:52 2012
@@ -907,7 +907,7 @@
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
SourceLocation AttrNameLoc = ConsumeToken();
attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
- SourceLocation(), 0, 0, false);
+ SourceLocation(), 0, 0, AttributeList::AS_GNU);
}
}
@@ -2899,12 +2899,13 @@
}
bool AttrParsed = false;
- switch (AttributeList::getKind(AttrName, ScopeName)) {
+ switch (AttributeList::getKind(AttrName, ScopeName,
+ AttributeList::AS_CXX11)) {
// No arguments
case AttributeList::AT_carries_dependency:
// FIXME: implement generic support of attributes with C++11 syntax
// see Parse/ParseDecl.cpp: ParseGNUAttributes
- case AttributeList::AT_clang___fallthrough:
+ case AttributeList::AT_fallthrough:
case AttributeList::AT_noreturn: {
if (Tok.is(tok::l_paren)) {
Diag(Tok.getLocation(), diag::err_cxx11_attribute_forbids_arguments)
@@ -2916,7 +2917,7 @@
SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc,
AttrLoc),
ScopeName, ScopeLoc, 0,
- SourceLocation(), 0, 0, false, true);
+ SourceLocation(), 0, 0, AttributeList::AS_CXX11);
AttrParsed = true;
break;
}
Modified: cfe/trunk/lib/Sema/AttributeList.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AttributeList.cpp?rev=158661&r1=158660&r2=158661&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/AttributeList.cpp (original)
+++ cfe/trunk/lib/Sema/AttributeList.cpp Mon Jun 18 11:13:52 2012
@@ -95,13 +95,15 @@
SourceLocation TokLoc, int Arg) {
Expr *IArg = IntegerLiteral::Create(C, llvm::APInt(32, (uint64_t) Arg),
C.IntTy, TokLoc);
- return create(Name, TokLoc, 0, TokLoc, 0, TokLoc, &IArg, 1, 0);
+ return create(Name, TokLoc, 0, TokLoc, 0, TokLoc, &IArg, 1,
+ AttributeList::AS_GNU);
}
#include "clang/Sema/AttrParsedAttrKinds.inc"
AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name,
- const IdentifierInfo *ScopeName) {
+ const IdentifierInfo *ScopeName,
+ Syntax SyntaxUsed) {
StringRef AttrName = Name->getName();
// Normalize the attribute name, __foo__ becomes foo.
@@ -109,10 +111,14 @@
AttrName.size() >= 4)
AttrName = AttrName.substr(2, AttrName.size() - 4);
- // FIXME: implement attribute namespacing correctly.
SmallString<64> Buf;
if (ScopeName)
- AttrName = ((Buf += ScopeName->getName()) += "___") += AttrName;
+ Buf += ScopeName->getName();
+ // Ensure that in the case of C++11 attributes, we look for '::foo' if it is
+ // unscoped.
+ if (ScopeName || SyntaxUsed == AS_CXX11)
+ Buf += "::";
+ Buf += AttrName;
- return ::getAttrKind(AttrName);
+ return ::getAttrKind(Buf);
}
Modified: cfe/trunk/lib/Sema/SemaStmtAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmtAttr.cpp?rev=158661&r1=158660&r2=158661&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmtAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmtAttr.cpp Mon Jun 18 11:13:52 2012
@@ -48,7 +48,7 @@
static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const AttributeList &A,
SourceRange Range) {
switch (A.getKind()) {
- case AttributeList::AT_clang___fallthrough:
+ case AttributeList::AT_fallthrough:
return handleFallThroughAttr(S, St, A, Range);
default:
// if we're here, then we parsed an attribute, but didn't recognize it as a
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=158661&r1=158660&r2=158661&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Mon Jun 18 11:13:52 2012
@@ -2728,8 +2728,7 @@
.create(&S.Context.Idents.get("objc_ownership"), SourceLocation(),
/*scope*/ 0, SourceLocation(),
&S.Context.Idents.get(attrStr), SourceLocation(),
- /*args*/ 0, 0,
- /*declspec*/ false, /*C++0x*/ false);
+ /*args*/ 0, 0, AttributeList::AS_GNU);
spliceAttrIntoList(*attr, chunk.getAttrListRef());
// TODO: mark whether we did this inference?
Modified: cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp?rev=158661&r1=158660&r2=158661&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp (original)
+++ cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp Mon Jun 18 11:13:52 2012
@@ -37,3 +37,15 @@
}
return n;
}
+
+void unscoped(int n) {
+ switch (n % 2) {
+ case 0:
+ // FIXME: This should be typo-corrected, probably.
+ [[fallthrough]];
+ case 2: // expected-warning{{unannotated fall-through}} expected-note{{clang::fallthrough}} expected-note{{break;}}
+ [[clang::fallthrough]];
+ case 1:
+ break;
+ }
+}
Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=158661&r1=158660&r2=158661&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)
+++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Mon Jun 18 11:13:52 2012
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/StringMatcher.h"
@@ -1128,6 +1129,8 @@
if (SemaHandler || Ignored) {
std::vector<StringRef> Spellings =
getValueAsListOfStrings(Attr, "Spellings");
+ std::vector<StringRef> Namespaces =
+ getValueAsListOfStrings(Attr, "Namespaces");
for (std::vector<StringRef>::const_iterator I = Spellings.begin(),
E = Spellings.end(); I != E; ++I) {
@@ -1136,16 +1139,35 @@
: Spellings.front());
StringRef Spelling = NormalizeAttrSpelling(*I);
+ for (std::vector<StringRef>::const_iterator NI = Namespaces.begin(),
+ NE = Namespaces.end(); NI != NE; ++NI) {
+ SmallString<64> Buf;
+ Buf += *NI;
+ Buf += "::";
+ Buf += Spelling;
+
+ if (SemaHandler)
+ Matches.push_back(
+ StringMatcher::StringPair(
+ Buf.str(),
+ "return AttributeList::AT_" + AttrName.str() + ";"));
+ else
+ Matches.push_back(
+ StringMatcher::StringPair(
+ Buf.str(),
+ "return AttributeList::IgnoredAttribute;"));
+ }
+
if (SemaHandler)
Matches.push_back(
StringMatcher::StringPair(
Spelling,
- std::string("return AttributeList::AT_")+AttrName.str() + ";"));
+ "return AttributeList::AT_" + AttrName.str() + ";"));
else
Matches.push_back(
StringMatcher::StringPair(
Spelling,
- std::string("return AttributeList::IgnoredAttribute;")));
+ "return AttributeList::IgnoredAttribute;"));
}
}
}
More information about the cfe-commits
mailing list