source: translator/SymTab/Indexer.cc@ 643a2e1

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay gc_noraii jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new string with_gc
Last change on this file since 643a2e1 was 17cd4eb, checked in by Peter A. Buhr <pabuhr@…>, 11 years ago

fixed restrict, fixed parameter copy, introduced name table for types, changed variable after to string

  • Property mode set to 100644
File size: 7.4 KB
Line 
1#include "SynTree/Declaration.h"
2#include "SynTree/Type.h"
3#include "SynTree/Expression.h"
4#include "SynTree/Initializer.h"
5#include "SynTree/Statement.h"
6#include "Indexer.h"
7#include <typeinfo>
8#include "utility.h"
9
10#define debugPrint(x) if ( doDebug ) { std::cout << x; }
11
12namespace SymTab {
13 Indexer::Indexer( bool useDebug ) : doDebug( useDebug ) {}
14
15 Indexer::~Indexer() {}
16
17 void Indexer::visit( ObjectDecl *objectDecl ) {
18 maybeAccept( objectDecl->get_type(), *this );
19 maybeAccept( objectDecl->get_init(), *this );
20 maybeAccept( objectDecl->get_bitfieldWidth(), *this );
21 if ( objectDecl->get_name() != "" ) {
22 debugPrint( "Adding object " << objectDecl->get_name() << std::endl );
23 idTable.addDecl( objectDecl );
24 }
25 }
26
27 void Indexer::visit( FunctionDecl *functionDecl ) {
28 if ( functionDecl->get_name() == "" ) return;
29 debugPrint( "Adding function " << functionDecl->get_name() << std::endl );
30 idTable.addDecl( functionDecl );
31 enterScope();
32 maybeAccept( functionDecl->get_functionType(), *this );
33 acceptAll( functionDecl->get_oldDecls(), *this );
34 maybeAccept( functionDecl->get_statements(), *this );
35 leaveScope();
36 }
37
38/********
39 * A NOTE ON THE ORDER OF TRAVERSAL
40 *
41 * Types and typedefs have their base types visited before they are added to the type table.
42 * This is ok, since there is no such thing as a recursive type or typedef.
43 * typedef struct { T *x; } T; // never allowed
44 *
45 * for structs/unions, it is possible to have recursion, so the decl should be added as if it's
46 * incomplete to begin, the members are traversed, and then the complete type should be added
47 * (assuming the type is completed by this particular declaration).
48 * struct T { struct T *x; }; // allowed
49 *
50 * It's important to add the complete type to the symbol table *after* the members/base has been
51 * traversed, since that traversal may modify the definition of the type and these modifications
52 * should be visible when the symbol table is queried later in this pass.
53 *
54 * TODO: figure out whether recursive contexts are sensible/possible/reasonable.
55 */
56
57 void Indexer::visit( TypeDecl *typeDecl ) {
58 // see A NOTE ON THE ORDER OF TRAVERSAL, above
59 // note that assertions come after the type is added to the symtab, since they aren't part
60 // of the type proper and may depend on the type itself
61 enterScope();
62 acceptAll( typeDecl->get_parameters(), *this );
63 maybeAccept( typeDecl->get_base(), *this );
64 leaveScope();
65 debugPrint( "Adding type " << typeDecl->get_name() << std::endl );
66 typeTable.add( typeDecl );
67 acceptAll( typeDecl->get_assertions(), *this );
68 }
69
70 void Indexer::visit( TypedefDecl *typeDecl ) {
71 enterScope();
72 acceptAll( typeDecl->get_parameters(), *this );
73 maybeAccept( typeDecl->get_base(), *this );
74 leaveScope();
75 debugPrint( "Adding typedef " << typeDecl->get_name() << std::endl );
76 typeTable.add( typeDecl );
77 }
78
79 void Indexer::visit( StructDecl *aggregateDecl ) {
80 // make up a forward declaration and add it before processing the members
81 StructDecl fwdDecl( aggregateDecl->get_name() );
82 cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
83 debugPrint( "Adding fwd decl for struct " << fwdDecl.get_name() << std::endl );
84 structTable.add( &fwdDecl );
85
86 enterScope();
87 acceptAll( aggregateDecl->get_parameters(), *this );
88 acceptAll( aggregateDecl->get_members(), *this );
89 leaveScope();
90
91 debugPrint( "Adding struct " << aggregateDecl->get_name() << std::endl );
92 // this addition replaces the forward declaration
93 structTable.add( aggregateDecl );
94 }
95
96 void Indexer::visit( UnionDecl *aggregateDecl ) {
97 // make up a forward declaration and add it before processing the members
98 UnionDecl fwdDecl( aggregateDecl->get_name() );
99 cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
100 debugPrint( "Adding fwd decl for union " << fwdDecl.get_name() << std::endl );
101 unionTable.add( &fwdDecl );
102
103 enterScope();
104 acceptAll( aggregateDecl->get_parameters(), *this );
105 acceptAll( aggregateDecl->get_members(), *this );
106 leaveScope();
107
108 debugPrint( "Adding union " << aggregateDecl->get_name() << std::endl );
109 unionTable.add( aggregateDecl );
110 }
111
112 void Indexer::visit( EnumDecl *aggregateDecl ) {
113 debugPrint( "Adding enum " << aggregateDecl->get_name() << std::endl );
114 enumTable.add( aggregateDecl );
115 // unlike structs, contexts, and unions, enums inject their members into the global scope
116 acceptAll( aggregateDecl->get_members(), *this );
117 }
118
119 void Indexer::visit( ContextDecl *aggregateDecl ) {
120 enterScope();
121 acceptAll( aggregateDecl->get_parameters(), *this );
122 acceptAll( aggregateDecl->get_members(), *this );
123 leaveScope();
124
125 debugPrint( "Adding context " << aggregateDecl->get_name() << std::endl );
126 contextTable.add( aggregateDecl );
127 }
128
129 void Indexer::visit( CompoundStmt *compoundStmt ) {
130 enterScope();
131 acceptAll( compoundStmt->get_kids(), *this );
132 leaveScope();
133 }
134
135 void Indexer::visit( ContextInstType *contextInst ) {
136 acceptAll( contextInst->get_parameters(), *this );
137 acceptAll( contextInst->get_members(), *this );
138 }
139
140 void Indexer::visit( StructInstType *structInst ) {
141 if ( ! structTable.lookup( structInst->get_name() ) ) {
142 debugPrint( "Adding struct " << structInst->get_name() << " from implicit forward declaration" << std::endl );
143 structTable.add( structInst->get_name() );
144 }
145 enterScope();
146 acceptAll( structInst->get_parameters(), *this );
147 leaveScope();
148 }
149
150 void Indexer::visit( UnionInstType *unionInst ) {
151 if ( ! unionTable.lookup( unionInst->get_name() ) ) {
152 debugPrint( "Adding union " << unionInst->get_name() << " from implicit forward declaration" << std::endl );
153 unionTable.add( unionInst->get_name() );
154 }
155 enterScope();
156 acceptAll( unionInst->get_parameters(), *this );
157 leaveScope();
158 }
159
160 void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &list ) const {
161 idTable.lookupId( id, list );
162 }
163
164 NamedTypeDecl *Indexer::lookupType( const std::string &id ) const {
165 return typeTable.lookup( id );
166 }
167
168 StructDecl *Indexer::lookupStruct( const std::string &id ) const {
169 return structTable.lookup( id );
170 }
171
172 EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
173 return enumTable.lookup( id );
174 }
175
176 UnionDecl *Indexer::lookupUnion( const std::string &id ) const {
177 return unionTable.lookup( id );
178 }
179
180 ContextDecl * Indexer::lookupContext( const std::string &id ) const {
181 return contextTable.lookup( id );
182 }
183
184 void Indexer::enterScope() {
185 if ( doDebug ) {
186 std::cout << "--- Entering scope" << std::endl;
187 }
188 idTable.enterScope();
189 typeTable.enterScope();
190 structTable.enterScope();
191 enumTable.enterScope();
192 unionTable.enterScope();
193 contextTable.enterScope();
194 }
195
196 void Indexer::leaveScope() {
197 using std::cout;
198 using std::endl;
199
200 if ( doDebug ) {
201 cout << "--- Leaving scope containing" << endl;
202 idTable.dump( cout );
203 typeTable.dump( cout );
204 structTable.dump( cout );
205 enumTable.dump( cout );
206 unionTable.dump( cout );
207 contextTable.dump( cout );
208 }
209 idTable.leaveScope();
210 typeTable.leaveScope();
211 structTable.leaveScope();
212 enumTable.leaveScope();
213 unionTable.leaveScope();
214 contextTable.leaveScope();
215 }
216
217 void Indexer::print( std::ostream &os, int indent ) const {
218 idTable.dump( os );
219 typeTable.dump( os );
220 structTable.dump( os );
221 enumTable.dump( os );
222 unionTable.dump( os );
223 contextTable.dump( os );
224 }
225} // namespace SymTab
Note: See TracBrowser for help on using the repository browser.