1 //=== ClangASTNodesEmitter.cpp - Generate Clang AST node tables -*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // These tablegen backends emit Clang AST node tables 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "ClangASTNodesEmitter.h" 15 #include <set> 16 using namespace llvm; 17 18 //===----------------------------------------------------------------------===// 19 // Statement Node Tables (.inc file) generation. 20 //===----------------------------------------------------------------------===// 21 22 // Returns the first and last non-abstract subrecords 23 // Called recursively to ensure that nodes remain contiguous 24 std::pair<Record *, Record *> ClangASTNodesEmitter::EmitNode( 25 const ChildMap &Tree, 26 raw_ostream &OS, 27 Record *Base) { 28 std::string BaseName = macroName(Base->getName()); 29 30 ChildIterator i = Tree.lower_bound(Base), e = Tree.upper_bound(Base); 31 32 Record *First = 0, *Last = 0; 33 // This might be the pseudo-node for Stmt; don't assume it has an Abstract 34 // bit 35 if (Base->getValue("Abstract") && !Base->getValueAsBit("Abstract")) 36 First = Last = Base; 37 38 for (; i != e; ++i) { 39 Record *R = i->second; 40 bool Abstract = R->getValueAsBit("Abstract"); 41 std::string NodeName = macroName(R->getName()); 42 43 OS << "#ifndef " << NodeName << "\n"; 44 OS << "# define " << NodeName << "(Type, Base) " 45 << BaseName << "(Type, Base)\n"; 46 OS << "#endif\n"; 47 48 if (Abstract) 49 OS << "ABSTRACT_" << macroName(Root.getName()) << "(" << NodeName << "(" 50 << R->getName() << ", " << baseName(*Base) << "))\n"; 51 else 52 OS << NodeName << "(" << R->getName() << ", " 53 << baseName(*Base) << ")\n"; 54 55 if (Tree.find(R) != Tree.end()) { 56 const std::pair<Record *, Record *> &Result 57 = EmitNode(Tree, OS, R); 58 if (!First && Result.first) 59 First = Result.first; 60 if (Result.second) 61 Last = Result.second; 62 } else { 63 if (!Abstract) { 64 Last = R; 65 66 if (!First) 67 First = R; 68 } 69 } 70 71 OS << "#undef " << NodeName << "\n\n"; 72 } 73 74 if (First) { 75 assert (Last && "Got a first node but not a last node for a range!"); 76 if (Base == &Root) 77 OS << "LAST_" << macroName(Root.getName()) << "_RANGE("; 78 else 79 OS << macroName(Root.getName()) << "_RANGE("; 80 OS << Base->getName() << ", " << First->getName() << ", " 81 << Last->getName() << ")\n\n"; 82 } 83 84 return std::make_pair(First, Last); 85 } 86 87 void ClangASTNodesEmitter::run(raw_ostream &OS) { 88 // Write the preamble 89 OS << "#ifndef ABSTRACT_" << macroName(Root.getName()) << "\n"; 90 OS << "# define ABSTRACT_" << macroName(Root.getName()) << "(Type) Type\n"; 91 OS << "#endif\n"; 92 93 OS << "#ifndef " << macroName(Root.getName()) << "_RANGE\n"; 94 OS << "# define " 95 << macroName(Root.getName()) << "_RANGE(Base, First, Last)\n"; 96 OS << "#endif\n\n"; 97 98 OS << "#ifndef LAST_" << macroName(Root.getName()) << "_RANGE\n"; 99 OS << "# define LAST_" 100 << macroName(Root.getName()) << "_RANGE(Base, First, Last) " 101 << macroName(Root.getName()) << "_RANGE(Base, First, Last)\n"; 102 OS << "#endif\n\n"; 103 104 // Emit statements 105 const std::vector<Record*> Stmts 106 = Records.getAllDerivedDefinitions(Root.getName()); 107 108 ChildMap Tree; 109 110 for (unsigned i = 0, e = Stmts.size(); i != e; ++i) { 111 Record *R = Stmts[i]; 112 113 if (R->getValue("Base")) 114 Tree.insert(std::make_pair(R->getValueAsDef("Base"), R)); 115 else 116 Tree.insert(std::make_pair(&Root, R)); 117 } 118 119 EmitNode(Tree, OS, &Root); 120 121 OS << "#undef " << macroName(Root.getName()) << "\n"; 122 OS << "#undef " << macroName(Root.getName()) << "_RANGE\n"; 123 OS << "#undef LAST_" << macroName(Root.getName()) << "_RANGE\n"; 124 OS << "#undef ABSTRACT_" << macroName(Root.getName()) << "\n"; 125 } 126 127 void ClangDeclContextEmitter::run(raw_ostream &OS) { 128 // FIXME: Find a .td file format to allow for this to be represented better. 129 130 OS << "#ifndef DECL_CONTEXT\n"; 131 OS << "# define DECL_CONTEXT(DECL)\n"; 132 OS << "#endif\n"; 133 134 OS << "#ifndef DECL_CONTEXT_BASE\n"; 135 OS << "# define DECL_CONTEXT_BASE(DECL) DECL_CONTEXT(DECL)\n"; 136 OS << "#endif\n"; 137 138 typedef std::set<Record*> RecordSet; 139 typedef std::vector<Record*> RecordVector; 140 141 RecordVector DeclContextsVector 142 = Records.getAllDerivedDefinitions("DeclContext"); 143 RecordVector Decls = Records.getAllDerivedDefinitions("Decl"); 144 RecordSet DeclContexts (DeclContextsVector.begin(), DeclContextsVector.end()); 145 146 for (RecordVector::iterator i = Decls.begin(), e = Decls.end(); i != e; ++i) { 147 Record *R = *i; 148 149 if (R->getValue("Base")) { 150 Record *B = R->getValueAsDef("Base"); 151 if (DeclContexts.find(B) != DeclContexts.end()) { 152 OS << "DECL_CONTEXT_BASE(" << B->getName() << ")\n"; 153 DeclContexts.erase(B); 154 } 155 } 156 } 157 158 // To keep identical order, RecordVector may be used 159 // instead of RecordSet. 160 for (RecordVector::iterator 161 i = DeclContextsVector.begin(), e = DeclContextsVector.end(); 162 i != e; ++i) 163 if (DeclContexts.find(*i) != DeclContexts.end()) 164 OS << "DECL_CONTEXT(" << (*i)->getName() << ")\n"; 165 166 OS << "#undef DECL_CONTEXT\n"; 167 OS << "#undef DECL_CONTEXT_BASE\n"; 168 } 169