[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