r193989 - Attributes which accept a type as their sole argument are no longer hard coded into the parser. Instead, they are automatically listed through tablegen.
Aaron Ballman
aaron at aaronballman.com
Mon Nov 4 04:55:56 PST 2013
Author: aaronballman
Date: Mon Nov 4 06:55:56 2013
New Revision: 193989
URL: http://llvm.org/viewvc/llvm-project?rev=193989&view=rev
Log:
Attributes which accept a type as their sole argument are no longer hard coded into the parser. Instead, they are automatically listed through tablegen.
Modified:
cfe/trunk/include/clang/Parse/CMakeLists.txt
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
cfe/trunk/utils/TableGen/TableGen.cpp
cfe/trunk/utils/TableGen/TableGenBackends.h
Modified: cfe/trunk/include/clang/Parse/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/CMakeLists.txt?rev=193989&r1=193988&r2=193989&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/CMakeLists.txt (original)
+++ cfe/trunk/include/clang/Parse/CMakeLists.txt Mon Nov 4 06:55:56 2013
@@ -3,6 +3,11 @@ clang_tablegen(AttrIdentifierArg.inc -ge
SOURCE ../Basic/Attr.td
TARGET ClangAttrIdentifierArg)
+clang_tablegen(AttrTypeArg.inc -gen-clang-attr-type-arg-list
+ -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
+ SOURCE ../Basic/Attr.td
+ TARGET ClangAttrTypeArg)
+
clang_tablegen(AttrLateParsed.inc -gen-clang-attr-late-parsed-list
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
SOURCE ../Basic/Attr.td
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=193989&r1=193988&r2=193989&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Nov 4 06:55:56 2013
@@ -181,16 +181,27 @@ void Parser::ParseGNUAttributes(ParsedAt
}
}
-/// \brief Determine whether the given attribute has an identifier argument.
-static bool attributeHasIdentifierArg(const IdentifierInfo &II) {
- StringRef Name = II.getName();
+/// \brief Normalizes an attribute name by dropping prefixed and suffixed __.
+static StringRef normalizeAttrName(StringRef Name) {
if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__"))
Name = Name.drop_front(2).drop_back(2);
- return llvm::StringSwitch<bool>(Name)
+ return Name;
+}
+
+/// \brief Determine whether the given attribute has an identifier argument.
+static bool attributeHasIdentifierArg(const IdentifierInfo &II) {
+ return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
#include "clang/Parse/AttrIdentifierArg.inc"
.Default(false);
}
+/// \brief Determine whether the given attribute parses a type argument.
+static bool attributeIsTypeArgAttr(const IdentifierInfo &II) {
+ return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
+#include "clang/Parse/AttrTypeArg.inc"
+ .Default(false);
+}
+
IdentifierLoc *Parser::ParseIdentifierLoc() {
assert(Tok.is(tok::identifier) && "expected an identifier");
IdentifierLoc *IL = IdentifierLoc::create(Actions.Context,
@@ -260,9 +271,8 @@ void Parser::ParseGNUAttributeArgs(Ident
ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
return;
}
- // __attribute__((vec_type_hint)) and iboutletcollection expect a type arg.
- if (AttrKind == AttributeList::AT_VecTypeHint ||
- AttrKind == AttributeList::AT_IBOutletCollection) {
+ // Some attributes expect solely a type parameter.
+ if (attributeIsTypeArgAttr(*AttrName)) {
ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, EndLoc);
return;
}
Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=193989&r1=193988&r2=193989&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)
+++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Mon Nov 4 06:55:56 2013
@@ -1195,6 +1195,37 @@ static bool isIdentifierArgument(Record
.Default(false);
}
+/// \brief Emits the first-argument-is-type property for attributes.
+void EmitClangAttrTypeArgList(RecordKeeper &Records, raw_ostream &OS) {
+ emitSourceFileHeader("llvm::StringSwitch code to match attributes with a "
+ "type argument", OS);
+
+ std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
+
+ for (std::vector<Record *>::iterator I = Attrs.begin(), E = Attrs.end();
+ I != E; ++I) {
+ Record &Attr = **I;
+
+ // Determine whether the first argument is a type.
+ std::vector<Record *> Args = Attr.getValueAsListOfDefs("Args");
+ if (Args.empty())
+ continue;
+
+ if (Args[0]->getSuperClasses().back()->getName() != "TypeArgument")
+ continue;
+
+ // All these spellings take a single type argument.
+ std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
+ std::set<std::string> Emitted;
+ for (std::vector<Record*>::const_iterator I = Spellings.begin(),
+ E = Spellings.end(); I != E; ++I) {
+ if (Emitted.insert((*I)->getValueAsString("Name")).second)
+ OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", "
+ << "true" << ")\n";
+ }
+ }
+}
+
// Emits the first-argument-is-identifier property for attributes.
void EmitClangAttrIdentifierArgList(RecordKeeper &Records, raw_ostream &OS) {
emitSourceFileHeader("llvm::StringSwitch code to match attributes with "
Modified: cfe/trunk/utils/TableGen/TableGen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGen.cpp?rev=193989&r1=193988&r2=193989&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/TableGen.cpp (original)
+++ cfe/trunk/utils/TableGen/TableGen.cpp Mon Nov 4 06:55:56 2013
@@ -25,6 +25,7 @@ using namespace clang;
enum ActionType {
GenClangAttrClasses,
GenClangAttrIdentifierArgList,
+ GenClangAttrTypeArgList,
GenClangAttrImpl,
GenClangAttrList,
GenClangAttrPCHRead,
@@ -64,6 +65,10 @@ cl::opt<ActionType> Action(
"gen-clang-attr-identifier-arg-list",
"Generate a list of attributes that take an "
"identifier as their first argument"),
+ clEnumValN(GenClangAttrTypeArgList,
+ "gen-clang-attr-type-arg-list",
+ "Generate a list of attributes that take a type as their "
+ "first argument"),
clEnumValN(GenClangAttrImpl, "gen-clang-attr-impl",
"Generate clang attribute implementations"),
clEnumValN(GenClangAttrList, "gen-clang-attr-list",
@@ -145,6 +150,9 @@ bool ClangTableGenMain(raw_ostream &OS,
case GenClangAttrIdentifierArgList:
EmitClangAttrIdentifierArgList(Records, OS);
break;
+ case GenClangAttrTypeArgList:
+ EmitClangAttrTypeArgList(Records, OS);
+ break;
case GenClangAttrImpl:
EmitClangAttrImpl(Records, OS);
break;
Modified: cfe/trunk/utils/TableGen/TableGenBackends.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGenBackends.h?rev=193989&r1=193988&r2=193989&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/TableGenBackends.h (original)
+++ cfe/trunk/utils/TableGen/TableGenBackends.h Mon Nov 4 06:55:56 2013
@@ -31,6 +31,7 @@ void EmitClangASTNodes(RecordKeeper &RK,
void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS);
void EmitClangAttrIdentifierArgList(RecordKeeper &Records, raw_ostream &OS);
+void EmitClangAttrTypeArgList(RecordKeeper &Records, raw_ostream &OS);
void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS);
void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS);
void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS);
More information about the cfe-commits
mailing list