[llvm-commits] [llvm] r105164 - in /llvm/trunk/utils/TableGen: ClangASTNodesEmitter.cpp ClangASTNodesEmitter.h TableGen.cpp
Chris Lattner
clattner at apple.com
Sun May 30 10:03:44 PDT 2010
On May 30, 2010, at 12:21 AM, Sean Hunt wrote:
> Author: coppro
> Date: Sun May 30 02:21:42 2010
> New Revision: 105164
>
> URL: http://llvm.org/viewvc/llvm-project?rev=105164&view=rev
> Log:
> 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.
Hi Sean,
Instead of having separate modes (and files) for stmts and decls, why not merge them together into one .inc file with #ifdefs around them? include/clang/Basic/DiagnosticGroups.inc is an example of a file that does this.
-Chris
>
> Modified:
> llvm/trunk/utils/TableGen/ClangASTNodesEmitter.cpp
> llvm/trunk/utils/TableGen/ClangASTNodesEmitter.h
> llvm/trunk/utils/TableGen/TableGen.cpp
>
> Modified: llvm/trunk/utils/TableGen/ClangASTNodesEmitter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangASTNodesEmitter.cpp?rev=105164&r1=105163&r2=105164&view=diff
> ==============================================================================
> --- llvm/trunk/utils/TableGen/ClangASTNodesEmitter.cpp (original)
> +++ llvm/trunk/utils/TableGen/ClangASTNodesEmitter.cpp Sun May 30 02:21:42 2010
> @@ -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 @@
> 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 @@
>
> 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 @@
> 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";
> }
>
> Modified: llvm/trunk/utils/TableGen/ClangASTNodesEmitter.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangASTNodesEmitter.h?rev=105164&r1=105163&r2=105164&view=diff
> ==============================================================================
> --- llvm/trunk/utils/TableGen/ClangASTNodesEmitter.h (original)
> +++ llvm/trunk/utils/TableGen/ClangASTNodesEmitter.h Sun May 30 02:21:42 2010
> @@ -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);
> };
>
>
> Modified: llvm/trunk/utils/TableGen/TableGen.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TableGen.cpp?rev=105164&r1=105163&r2=105164&view=diff
> ==============================================================================
> --- llvm/trunk/utils/TableGen/TableGen.cpp (original)
> +++ llvm/trunk/utils/TableGen/TableGen.cpp Sun May 30 02:21:42 2010
> @@ -55,6 +55,7 @@
> GenCallingConv,
> GenClangDiagsDefs,
> GenClangDiagGroups,
> + GenClangDeclNodes,
> GenClangStmtNodes,
> GenDAGISel,
> GenFastISel,
> @@ -113,6 +114,8 @@
> "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 @@
> 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);
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list