X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FClangASTNodesEmitter.cpp;h=2e7c52166f81b19f7002c2ab8d0cb9bff4194105;hb=44ed2c31a5b3233fd11575346d2bd3551578f631;hp=d6d16a6cef36b96ec672ab4361994ecb5d7b15b3;hpb=1ef7c821287cd7734efb148aa3044de3e3e377a7;p=oota-llvm.git diff --git a/utils/TableGen/ClangASTNodesEmitter.cpp b/utils/TableGen/ClangASTNodesEmitter.cpp index d6d16a6cef3..2e7c52166f8 100644 --- a/utils/TableGen/ClangASTNodesEmitter.cpp +++ b/utils/TableGen/ClangASTNodesEmitter.cpp @@ -1,10 +1,19 @@ +//=== ClangASTNodesEmitter.cpp - Generate Clang AST node tables -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// These tablegen backends emit Clang AST node tables +// +//===----------------------------------------------------------------------===// + #include "ClangASTNodesEmitter.h" #include "Record.h" -#include -#include -#include #include -#include #include using namespace llvm; @@ -12,87 +21,86 @@ using namespace llvm; // Statement Node Tables (.inc file) generation. //===----------------------------------------------------------------------===// -// Sort to create a tree-like structure based on the 'Base' field. -namespace { - // Create a macro-ized version of a name - std::string macroName(std::string S) { - for (unsigned i = 0; i < S.size(); ++i) - S[i] = std::toupper(S[i]); +// 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 S; +} - // A map from a node to each of its derived nodes. - typedef std::multimap ChildMap; - typedef ChildMap::const_iterator ChildIterator; - - // Returns the first and last non-abstract subrecords - std::pair EmitStmtNode(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); - - Record *First = 0, *Last = 0; - // This might be the pseudo-node for Stmt; don't assume it has an Abstract - // bit - if (Base->getValue("Abstract") && !Base->getValueAsBit("Abstract")) - First = Last = Base; - - for (; i != e; ++i) { - Record *R = i->second; - bool Abstract = R->getValueAsBit("Abstract"); - std::string NodeName = macroName(R->getName()); - - OS << "#ifndef " << NodeName << "\n"; - OS << "# define " << NodeName << "(Type, Base) " - << BaseName << "(Type, Base)\n"; - OS << "#endif\n"; - - if (Abstract) - OS << "ABSTRACT(" << NodeName << "(" << R->getName() << ", " - << Base->getName() << "))\n"; - else - OS << NodeName << "(" << R->getName() << ", " - << Base->getName() << ")\n"; - - if (Tree.find(R) != Tree.end()) { - const std::pair &Result = EmitStmtNode(Tree, OS, R); - if (!First && Result.first) - First = Result.first; - if (Result.second) - Last = Result.second; - } else { - if (!Abstract) { - Last = R; - - if (!First) - First = R; - } +// A map from a node to each of its derived nodes. +typedef std::multimap 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 EmitStmtNode(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); + + Record *First = 0, *Last = 0; + // This might be the pseudo-node for Stmt; don't assume it has an Abstract + // bit + if (Base->getValue("Abstract") && !Base->getValueAsBit("Abstract")) + First = Last = Base; + + for (; i != e; ++i) { + Record *R = i->second; + bool Abstract = R->getValueAsBit("Abstract"); + std::string NodeName = macroName(R->getName()); + + OS << "#ifndef " << NodeName << "\n"; + OS << "# define " << NodeName << "(Type, Base) " + << BaseName << "(Type, Base)\n"; + OS << "#endif\n"; + + if (Abstract) + OS << "ABSTRACT(" << NodeName << "(" << R->getName() << ", " + << Base->getName() << "))\n"; + else + OS << NodeName << "(" << R->getName() << ", " + << Base->getName() << ")\n"; + + if (Tree.find(R) != Tree.end()) { + const std::pair &Result = EmitStmtNode(Tree, OS, R); + if (!First && Result.first) + First = Result.first; + if (Result.second) + Last = Result.second; + } else { + if (!Abstract) { + Last = R; + + if (!First) + First = R; } - - OS << "#undef " << NodeName << "\n\n"; } - assert(!First == !Last && "Got a first or last node, but not the other"); - - if (First) { - OS << "#ifndef FIRST_" << BaseName << "\n"; - OS << "# define FIRST_" << BaseName << "(CLASS)\n"; - OS << "#endif\n"; - OS << "#ifndef LAST_" << BaseName << "\n"; - OS << "# define LAST_" << BaseName << "(CLASS)\n"; - OS << "#endif\n\n"; + OS << "#undef " << NodeName << "\n\n"; + } - OS << "FIRST_" << BaseName << "(" << First->getName() << ")\n"; - OS << "LAST_" << BaseName << "(" << Last->getName() << ")\n\n"; - } + assert(!First == !Last && "Got a first or last node, but not the other"); - OS << "#undef FIRST_" << BaseName << "\n"; - OS << "#undef LAST_" << BaseName << "\n\n"; + if (First) { + OS << "#ifndef FIRST_" << BaseName << "\n"; + OS << "# define FIRST_" << BaseName << "(CLASS)\n"; + OS << "#endif\n"; + OS << "#ifndef LAST_" << BaseName << "\n"; + OS << "# define LAST_" << BaseName << "(CLASS)\n"; + OS << "#endif\n\n"; - return std::make_pair(First, Last); + OS << "FIRST_" << BaseName << "(" << First->getName() << ")\n"; + OS << "LAST_" << BaseName << "(" << Last->getName() << ")\n\n"; } + + OS << "#undef FIRST_" << BaseName << "\n"; + OS << "#undef LAST_" << BaseName << "\n\n"; + + return std::make_pair(First, Last); } void ClangStmtNodesEmitter::run(raw_ostream &OS) {