summaryrefslogtreecommitdiffstats
path: root/clang/utils
diff options
context:
space:
mode:
Diffstat (limited to 'clang/utils')
-rw-r--r--clang/utils/TableGen/ClangAttrEmitter.cpp43
-rw-r--r--clang/utils/TableGen/TableGen.cpp8
-rw-r--r--clang/utils/TableGen/TableGenBackends.h1
3 files changed, 52 insertions, 0 deletions
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp
index 7c8603fc6c3..36de06e2df6 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -971,6 +971,49 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) {
OS << "#endif\n";
}
+// Emits the LateParsed property for attributes.
+void EmitClangAttrExprArgsList(RecordKeeper &Records, raw_ostream &OS) {
+ emitSourceFileHeader("llvm::StringSwitch code to match attributes with "
+ "expression arguments", 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 something that is always
+ // an expression.
+ std::vector<Record *> Args = Attr.getValueAsListOfDefs("Args");
+ if (Args.empty() || Args[0]->getSuperClasses().empty())
+ continue;
+
+ // Check whether this is one of the argument kinds that implies an
+ // expression.
+ // FIXME: Aligned is weird.
+ if (!llvm::StringSwitch<bool>(Args[0]->getSuperClasses().back()->getName())
+ .Case("AlignedArgument", true)
+ .Case("BoolArgument", true)
+ .Case("DefaultIntArgument", true)
+ .Case("IntArgument", true)
+ .Case("StringArgument", true)
+ .Case("ExprArgument", true)
+ .Case("UnsignedArgument", true)
+ .Case("VariadicUnsignedArgument", true)
+ .Case("VariadicExprArgument", true)
+ .Default(false))
+ continue;
+
+ std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
+
+ for (std::vector<Record*>::const_iterator I = Spellings.begin(),
+ E = Spellings.end(); I != E; ++I) {
+ OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", "
+ << "true" << ")\n";
+ }
+ }
+}
+
// Emits the class method definitions for attributes.
void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
emitSourceFileHeader("Attribute classes' member function definitions", OS);
diff --git a/clang/utils/TableGen/TableGen.cpp b/clang/utils/TableGen/TableGen.cpp
index 3df8940b055..12e1c47725e 100644
--- a/clang/utils/TableGen/TableGen.cpp
+++ b/clang/utils/TableGen/TableGen.cpp
@@ -24,6 +24,7 @@ using namespace clang;
enum ActionType {
GenClangAttrClasses,
+ GenClangAttrExprArgsList,
GenClangAttrImpl,
GenClangAttrList,
GenClangAttrPCHRead,
@@ -62,6 +63,10 @@ namespace {
"Generate option parser implementation"),
clEnumValN(GenClangAttrClasses, "gen-clang-attr-classes",
"Generate clang attribute clases"),
+ clEnumValN(GenClangAttrExprArgsList,
+ "gen-clang-attr-expr-args-list",
+ "Generate a clang attribute expression "
+ "arguments list"),
clEnumValN(GenClangAttrImpl, "gen-clang-attr-impl",
"Generate clang attribute implementations"),
clEnumValN(GenClangAttrList, "gen-clang-attr-list",
@@ -143,6 +148,9 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
case GenClangAttrClasses:
EmitClangAttrClass(Records, OS);
break;
+ case GenClangAttrExprArgsList:
+ EmitClangAttrExprArgsList(Records, OS);
+ break;
case GenClangAttrImpl:
EmitClangAttrImpl(Records, OS);
break;
diff --git a/clang/utils/TableGen/TableGenBackends.h b/clang/utils/TableGen/TableGenBackends.h
index 03708b6a766..0ff33d775cc 100644
--- a/clang/utils/TableGen/TableGenBackends.h
+++ b/clang/utils/TableGen/TableGenBackends.h
@@ -30,6 +30,7 @@ void EmitClangASTNodes(RecordKeeper &RK, raw_ostream &OS,
const std::string &N, const std::string &S);
void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS);
+void EmitClangAttrExprArgsList(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);
OpenPOWER on IntegriCloud