summaryrefslogtreecommitdiff
path: root/utils/TableGen
diff options
context:
space:
mode:
authorSean Hunt <rideau3@gmail.com>2010-05-30 07:21:42 +0000
committerSean Hunt <rideau3@gmail.com>2010-05-30 07:21:42 +0000
commitc10a62b0d53a7cb39b2ccb12c2dd9748ccd12f43 (patch)
tree286be808e7f1b060e2bfcc38f6fed13df07ac2f7 /utils/TableGen
parent4ed81ecbcd139fe13985a1b962f6cd522b90b79e (diff)
downloadllvm-c10a62b0d53a7cb39b2ccb12c2dd9748ccd12f43.tar.gz
llvm-c10a62b0d53a7cb39b2ccb12c2dd9748ccd12f43.tar.bz2
llvm-c10a62b0d53a7cb39b2ccb12c2dd9748ccd12f43.tar.xz
Allow for creation of clang DeclNodes tables.
The StmtNodes generator has been generalized to allow for the creation of DeclNodes tables as well, and another emitter was added for DeclContexts. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@105164 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen')
-rw-r--r--utils/TableGen/ClangASTNodesEmitter.cpp116
-rw-r--r--utils/TableGen/ClangASTNodesEmitter.h58
-rw-r--r--utils/TableGen/TableGen.cpp9
3 files changed, 131 insertions, 52 deletions
diff --git a/utils/TableGen/ClangASTNodesEmitter.cpp b/utils/TableGen/ClangASTNodesEmitter.cpp
index 5d6423da08..187ab46799 100644
--- a/utils/TableGen/ClangASTNodesEmitter.cpp
+++ b/utils/TableGen/ClangASTNodesEmitter.cpp
@@ -12,33 +12,19 @@
//===----------------------------------------------------------------------===//
#include "ClangASTNodesEmitter.h"
-#include "Record.h"
-#include <map>
-#include <cctype>
+#include <set>
using namespace llvm;
//===----------------------------------------------------------------------===//
// Statement Node Tables (.inc file) generation.
//===----------------------------------------------------------------------===//
-// Create a macro-ized version of a name
-static std::string macroName(std::string S) {
- for (unsigned i = 0; i < S.size(); ++i)
- S[i] = std::toupper(S[i]);
-
- return S;
-}
-
-// A map from a node to each of its derived nodes.
-typedef std::multimap<Record*, Record*> ChildMap;
-typedef ChildMap::const_iterator ChildIterator;
-
// Returns the first and last non-abstract subrecords
// Called recursively to ensure that nodes remain contiguous
-static std::pair<Record *, Record *> EmitStmtNode(const ChildMap &Tree,
- raw_ostream &OS,
- Record *Base,
- bool Root = true) {
+std::pair<Record *, Record *> ClangASTNodesEmitter::EmitNode(
+ const ChildMap &Tree,
+ raw_ostream &OS,
+ Record *Base) {
std::string BaseName = macroName(Base->getName());
ChildIterator i = Tree.lower_bound(Base), e = Tree.upper_bound(Base);
@@ -60,15 +46,15 @@ static std::pair<Record *, Record *> EmitStmtNode(const ChildMap &Tree,
OS << "#endif\n";
if (Abstract)
- OS << "ABSTRACT_STMT(" << NodeName << "(" << R->getName() << ", "
- << Base->getName() << "))\n";
+ OS << "ABSTRACT_" << macroName(Root.getName()) << "(" << NodeName << "("
+ << R->getName() << ", " << baseName(*Base) << "))\n";
else
OS << NodeName << "(" << R->getName() << ", "
- << Base->getName() << ")\n";
+ << baseName(*Base) << ")\n";
if (Tree.find(R) != Tree.end()) {
const std::pair<Record *, Record *> &Result
- = EmitStmtNode(Tree, OS, R, false);
+ = EmitNode(Tree, OS, R);
if (!First && Result.first)
First = Result.first;
if (Result.second)
@@ -87,11 +73,10 @@ static std::pair<Record *, Record *> EmitStmtNode(const ChildMap &Tree,
if (First) {
assert (Last && "Got a first node but not a last node for a range!");
- if (Root)
- OS << "LAST_STMT_RANGE(";
+ if (Base == &Root)
+ OS << "LAST_" << macroName(Root.getName()) << "_RANGE(";
else
- OS << "STMT_RANGE(";
-
+ OS << macroName(Root.getName()) << "_RANGE(";
OS << Base->getName() << ", " << First->getName() << ", "
<< Last->getName() << ")\n\n";
}
@@ -99,43 +84,82 @@ static std::pair<Record *, Record *> EmitStmtNode(const ChildMap &Tree,
return std::make_pair(First, Last);
}
-void ClangStmtNodesEmitter::run(raw_ostream &OS) {
+void ClangASTNodesEmitter::run(raw_ostream &OS) {
// Write the preamble
- OS << "#ifndef ABSTRACT_STMT\n";
- OS << "# define ABSTRACT_STMT(Stmt) Stmt\n";
+ OS << "#ifndef ABSTRACT_" << macroName(Root.getName()) << "\n";
+ OS << "# define ABSTRACT_" << macroName(Root.getName()) << "(Type) Type\n";
OS << "#endif\n";
- OS << "#ifndef STMT_RANGE\n";
- OS << "# define STMT_RANGE(Base, First, Last)\n";
+ OS << "#ifndef " << macroName(Root.getName()) << "_RANGE\n";
+ OS << "# define "
+ << macroName(Root.getName()) << "_RANGE(Base, First, Last)\n";
OS << "#endif\n\n";
- OS << "#ifndef LAST_STMT_RANGE\n";
- OS << "# define LAST_STMT_RANGE(Base, First, Last) "
- "STMT_RANGE(Base, First, Last)\n";
+ OS << "#ifndef LAST_" << macroName(Root.getName()) << "_RANGE\n";
+ OS << "# define LAST_"
+ << macroName(Root.getName()) << "_RANGE(Base, First, Last) "
+ << macroName(Root.getName()) << "_RANGE(Base, First, Last)\n";
OS << "#endif\n\n";
// Emit statements
- const std::vector<Record*> Stmts = Records.getAllDerivedDefinitions("Stmt");
+ const std::vector<Record*> Stmts
+ = Records.getAllDerivedDefinitions(Root.getName());
ChildMap Tree;
- // Create a pseudo-record to serve as the Stmt node, which isn't actually
- // output.
- Record Stmt ("Stmt", SMLoc());
-
for (unsigned i = 0, e = Stmts.size(); i != e; ++i) {
Record *R = Stmts[i];
if (R->getValue("Base"))
Tree.insert(std::make_pair(R->getValueAsDef("Base"), R));
else
- Tree.insert(std::make_pair(&Stmt, R));
+ Tree.insert(std::make_pair(&Root, R));
}
- EmitStmtNode(Tree, OS, &Stmt);
+ EmitNode(Tree, OS, &Root);
+
+ OS << "#undef " << macroName(Root.getName()) << "\n";
+ OS << "#undef " << macroName(Root.getName()) << "_RANGE\n";
+ OS << "#undef LAST_" << macroName(Root.getName()) << "_RANGE\n";
+ OS << "#undef ABSTRACT_" << macroName(Root.getName()) << "\n";
+}
+
+void ClangDeclContextEmitter::run(raw_ostream &OS) {
+ // FIXME: Find a .td file format to allow for this to be represented better.
+
+ OS << "#ifndef DECL_CONTEXT\n";
+ OS << "# define DECL_CONTEXT(DECL)\n";
+ OS << "#endif\n";
+
+ OS << "#ifndef DECL_CONTEXT_BASE\n";
+ OS << "# define DECL_CONTEXT_BASE(DECL) DECL_CONTEXT(DECL)\n";
+ OS << "#endif\n";
+
+ typedef std::set<Record*> RecordSet;
+ typedef std::vector<Record*> RecordVector;
+
+ RecordVector DeclContextsVector
+ = Records.getAllDerivedDefinitions("DeclContext");
+ RecordVector Decls = Records.getAllDerivedDefinitions("Decl");
+ RecordSet DeclContexts (DeclContextsVector.begin(), DeclContextsVector.end());
+
+ for (RecordVector::iterator i = Decls.begin(), e = Decls.end(); i != e; ++i) {
+ Record *R = *i;
+
+ if (R->getValue("Base")) {
+ Record *B = R->getValueAsDef("Base");
+ if (DeclContexts.find(B) != DeclContexts.end()) {
+ OS << "DECL_CONTEXT_BASE(" << B->getName() << ")\n";
+ DeclContexts.erase(B);
+ }
+ }
+ }
+
+ for (RecordSet::iterator i = DeclContexts.begin(), e = DeclContexts.end();
+ i != e; ++i) {
+ OS << "DECL_CONTEXT(" << (*i)->getName() << ")\n";
+ }
- OS << "#undef STMT\n";
- OS << "#undef STMT_RANGE\n";
- OS << "#undef LAST_STMT_RANGE\n";
- OS << "#undef ABSTRACT_STMT\n";
+ OS << "#undef DECL_CONTEXT\n";
+ OS << "#undef DECL_CONTEXT_BASE\n";
}
diff --git a/utils/TableGen/ClangASTNodesEmitter.h b/utils/TableGen/ClangASTNodesEmitter.h
index c4ce9fa820..55d9a1c58b 100644
--- a/utils/TableGen/ClangASTNodesEmitter.h
+++ b/utils/TableGen/ClangASTNodesEmitter.h
@@ -15,19 +15,67 @@
#define CLANGAST_EMITTER_H
#include "TableGenBackend.h"
+#include "Record.h"
+#include <string>
+#include <cctype>
+#include <map>
namespace llvm {
-/// ClangStmtNodesEmitter - The top-level class emits .def files containing
+/// ClangStmtNodesEmitter - The top-level class emits .inc files containing
/// declarations of Clang statements.
///
-class ClangStmtNodesEmitter : public TableGenBackend {
+class ClangASTNodesEmitter : public TableGenBackend {
+ // A map from a node to each of its derived nodes.
+ typedef std::multimap<Record*, Record*> ChildMap;
+ typedef ChildMap::const_iterator ChildIterator;
+
RecordKeeper &Records;
+ Record Root;
+ const std::string &BaseSuffix;
+
+ // Create a macro-ized version of a name
+ static std::string macroName(std::string S) {
+ for (unsigned i = 0; i < S.size(); ++i)
+ S[i] = std::toupper(S[i]);
+
+ return S;
+ }
+
+ // Return the name to be printed in the base field. Normally this is
+ // the record's name plus the base suffix, but if it is the root node and
+ // the suffix is non-empty, it's just the suffix.
+ std::string baseName(Record &R) {
+ if (&R == &Root && !BaseSuffix.empty())
+ return BaseSuffix;
+
+ return R.getName() + BaseSuffix;
+ }
+
+ std::pair<Record *, Record *> EmitNode (const ChildMap &Tree, raw_ostream& OS,
+ Record *Base);
+public:
+ explicit ClangASTNodesEmitter(RecordKeeper &R, const std::string &N,
+ const std::string &S)
+ : Records(R), Root(N, SMLoc()), BaseSuffix(S)
+ {}
+
+ // run - Output the .inc file contents
+ void run(raw_ostream &OS);
+};
+
+/// ClangDeclContextEmitter - Emits an addendum to a .inc file to enumerate the
+/// clang declaration contexts.
+///
+class ClangDeclContextEmitter : public TableGenBackend {
+ RecordKeeper &Records;
+
public:
- explicit ClangStmtNodesEmitter(RecordKeeper &R)
- : Records(R) {}
+ explicit ClangDeclContextEmitter(RecordKeeper &R)
+ : Records(R)
+ {}
- // run - Output the .def file contents
+ // run - Output the .inc file contents
void run(raw_ostream &OS);
};
diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp
index 7697f4fa99..039653eb81 100644
--- a/utils/TableGen/TableGen.cpp
+++ b/utils/TableGen/TableGen.cpp
@@ -55,6 +55,7 @@ enum ActionType {
GenCallingConv,
GenClangDiagsDefs,
GenClangDiagGroups,
+ GenClangDeclNodes,
GenClangStmtNodes,
GenDAGISel,
GenFastISel,
@@ -113,6 +114,8 @@ namespace {
"Generate Clang diagnostics definitions"),
clEnumValN(GenClangDiagGroups, "gen-clang-diag-groups",
"Generate Clang diagnostic groups"),
+ clEnumValN(GenClangDeclNodes, "gen-clang-decl-nodes",
+ "Generate Clang AST statement nodes"),
clEnumValN(GenClangStmtNodes, "gen-clang-stmt-nodes",
"Generate Clang AST statement nodes"),
clEnumValN(GenLLVMCConf, "gen-llvmc",
@@ -248,8 +251,12 @@ int main(int argc, char **argv) {
case GenClangDiagGroups:
ClangDiagGroupsEmitter(Records).run(Out);
break;
+ case GenClangDeclNodes:
+ ClangASTNodesEmitter(Records, "Decl", "Decl").run(Out);
+ ClangDeclContextEmitter(Records).run(Out);
+ break;
case GenClangStmtNodes:
- ClangStmtNodesEmitter(Records).run(Out);
+ ClangASTNodesEmitter(Records, "Stmt", "").run(Out);
break;
case GenDisassembler:
DisassemblerEmitter(Records).run(Out);