1 //=== ClangASTNodesEmitter.cpp - Generate Clang AST node tables -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // These tablegen backends emit Clang AST node tables
12 //===----------------------------------------------------------------------===//
14 #include "ClangASTNodesEmitter.h"
18 //===----------------------------------------------------------------------===//
19 // Statement Node Tables (.inc file) generation.
20 //===----------------------------------------------------------------------===//
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(
28 std::string BaseName
= macroName(Base
->getName());
30 ChildIterator i
= Tree
.lower_bound(Base
), e
= Tree
.upper_bound(Base
);
32 Record
*First
= 0, *Last
= 0;
33 // This might be the pseudo-node for Stmt; don't assume it has an Abstract
35 if (Base
->getValue("Abstract") && !Base
->getValueAsBit("Abstract"))
39 Record
*R
= i
->second
;
40 bool Abstract
= R
->getValueAsBit("Abstract");
41 std::string NodeName
= macroName(R
->getName());
43 OS
<< "#ifndef " << NodeName
<< "\n";
44 OS
<< "# define " << NodeName
<< "(Type, Base) "
45 << BaseName
<< "(Type, Base)\n";
49 OS
<< "ABSTRACT_" << macroName(Root
.getName()) << "(" << NodeName
<< "("
50 << R
->getName() << ", " << baseName(*Base
) << "))\n";
52 OS
<< NodeName
<< "(" << R
->getName() << ", "
53 << baseName(*Base
) << ")\n";
55 if (Tree
.find(R
) != Tree
.end()) {
56 const std::pair
<Record
*, Record
*> &Result
57 = EmitNode(Tree
, OS
, R
);
58 if (!First
&& Result
.first
)
71 OS
<< "#undef " << NodeName
<< "\n\n";
75 assert (Last
&& "Got a first node but not a last node for a range!");
77 OS
<< "LAST_" << macroName(Root
.getName()) << "_RANGE(";
79 OS
<< macroName(Root
.getName()) << "_RANGE(";
80 OS
<< Base
->getName() << ", " << First
->getName() << ", "
81 << Last
->getName() << ")\n\n";
84 return std::make_pair(First
, Last
);
87 void ClangASTNodesEmitter::run(raw_ostream
&OS
) {
89 OS
<< "#ifndef ABSTRACT_" << macroName(Root
.getName()) << "\n";
90 OS
<< "# define ABSTRACT_" << macroName(Root
.getName()) << "(Type) Type\n";
93 OS
<< "#ifndef " << macroName(Root
.getName()) << "_RANGE\n";
95 << macroName(Root
.getName()) << "_RANGE(Base, First, Last)\n";
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";
105 const std::vector
<Record
*> Stmts
106 = Records
.getAllDerivedDefinitions(Root
.getName());
110 for (unsigned i
= 0, e
= Stmts
.size(); i
!= e
; ++i
) {
111 Record
*R
= Stmts
[i
];
113 if (R
->getValue("Base"))
114 Tree
.insert(std::make_pair(R
->getValueAsDef("Base"), R
));
116 Tree
.insert(std::make_pair(&Root
, R
));
119 EmitNode(Tree
, OS
, &Root
);
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";
127 void ClangDeclContextEmitter::run(raw_ostream
&OS
) {
128 // FIXME: Find a .td file format to allow for this to be represented better.
130 OS
<< "#ifndef DECL_CONTEXT\n";
131 OS
<< "# define DECL_CONTEXT(DECL)\n";
134 OS
<< "#ifndef DECL_CONTEXT_BASE\n";
135 OS
<< "# define DECL_CONTEXT_BASE(DECL) DECL_CONTEXT(DECL)\n";
138 typedef std::set
<Record
*> RecordSet
;
139 typedef std::vector
<Record
*> RecordVector
;
141 RecordVector DeclContextsVector
142 = Records
.getAllDerivedDefinitions("DeclContext");
143 RecordVector Decls
= Records
.getAllDerivedDefinitions("Decl");
144 RecordSet
DeclContexts (DeclContextsVector
.begin(), DeclContextsVector
.end());
146 for (RecordVector::iterator i
= Decls
.begin(), e
= Decls
.end(); i
!= e
; ++i
) {
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
);
158 for (RecordSet::iterator i
= DeclContexts
.begin(), e
= DeclContexts
.end();
160 OS
<< "DECL_CONTEXT(" << (*i
)->getName() << ")\n";
163 OS
<< "#undef DECL_CONTEXT\n";
164 OS
<< "#undef DECL_CONTEXT_BASE\n";