source: src/SymTab/Indexer.cc@ 4789f44

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 4789f44 was 2a4b088, checked in by Aaron Moss <a3moss@…>, 10 years ago

Make offsetof expressions work

  • Property mode set to 100644
File size: 13.0 KB
RevLine 
[0dd3a2f]1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// Indexer.cc --
8//
9// Author : Richard C. Bilson
10// Created On : Sun May 17 21:37:33 2015
[ae4c85a]11// Last Modified By : Rob Schluntz
12// Last Modified On : Wed Aug 05 13:52:42 2015
13// Update Count : 10
[0dd3a2f]14//
15
[51b73452]16#include "SynTree/Declaration.h"
17#include "SynTree/Type.h"
18#include "SynTree/Expression.h"
19#include "SynTree/Initializer.h"
20#include "SynTree/Statement.h"
21#include "Indexer.h"
22#include <typeinfo>
[d3b7937]23#include "Common/utility.h"
[51b73452]24
[17cd4eb]25#define debugPrint(x) if ( doDebug ) { std::cout << x; }
[51b73452]26
27namespace SymTab {
[ae4c85a]28 template< typename Container, typename VisitorType >
29 inline void acceptAllNewScope( Container &container, VisitorType &visitor ) {
30 visitor.enterScope();
31 acceptAll( container, visitor );
32 visitor.leaveScope();
33 }
34
[a08ba92]35 Indexer::Indexer( bool useDebug ) : doDebug( useDebug ) {}
[17cd4eb]36
[a08ba92]37 Indexer::~Indexer() {}
[17cd4eb]38
[a08ba92]39 void Indexer::visit( ObjectDecl *objectDecl ) {
[ae4c85a]40 enterScope();
[0dd3a2f]41 maybeAccept( objectDecl->get_type(), *this );
[ae4c85a]42 leaveScope();
[0dd3a2f]43 maybeAccept( objectDecl->get_init(), *this );
44 maybeAccept( objectDecl->get_bitfieldWidth(), *this );
45 if ( objectDecl->get_name() != "" ) {
46 debugPrint( "Adding object " << objectDecl->get_name() << std::endl );
47 idTable.addDecl( objectDecl );
48 } // if
[a08ba92]49 }
[17cd4eb]50
[a08ba92]51 void Indexer::visit( FunctionDecl *functionDecl ) {
[0dd3a2f]52 if ( functionDecl->get_name() == "" ) return;
53 debugPrint( "Adding function " << functionDecl->get_name() << std::endl );
54 idTable.addDecl( functionDecl );
55 enterScope();
56 maybeAccept( functionDecl->get_functionType(), *this );
57 acceptAll( functionDecl->get_oldDecls(), *this );
58 maybeAccept( functionDecl->get_statements(), *this );
59 leaveScope();
[a08ba92]60 }
[51b73452]61
[44b5ca0]62
63// A NOTE ON THE ORDER OF TRAVERSAL
64//
65// Types and typedefs have their base types visited before they are added to the type table. This is ok, since there is
66// no such thing as a recursive type or typedef.
67//
68// typedef struct { T *x; } T; // never allowed
69//
70// for structs/unions, it is possible to have recursion, so the decl should be added as if it's incomplete to begin, the
71// members are traversed, and then the complete type should be added (assuming the type is completed by this particular
72// declaration).
73//
74// struct T { struct T *x; }; // allowed
75//
76// It is important to add the complete type to the symbol table *after* the members/base has been traversed, since that
77// traversal may modify the definition of the type and these modifications should be visible when the symbol table is
78// queried later in this pass.
79//
80// TODO: figure out whether recursive contexts are sensible/possible/reasonable.
81
[51b73452]82
[a08ba92]83 void Indexer::visit( TypeDecl *typeDecl ) {
[0dd3a2f]84 // see A NOTE ON THE ORDER OF TRAVERSAL, above
[44b5ca0]85 // note that assertions come after the type is added to the symtab, since they are not part of the type proper
86 // and may depend on the type itself
[0dd3a2f]87 enterScope();
88 acceptAll( typeDecl->get_parameters(), *this );
89 maybeAccept( typeDecl->get_base(), *this );
90 leaveScope();
91 debugPrint( "Adding type " << typeDecl->get_name() << std::endl );
92 typeTable.add( typeDecl );
93 acceptAll( typeDecl->get_assertions(), *this );
[a08ba92]94 }
[17cd4eb]95
[a08ba92]96 void Indexer::visit( TypedefDecl *typeDecl ) {
[0dd3a2f]97 enterScope();
98 acceptAll( typeDecl->get_parameters(), *this );
99 maybeAccept( typeDecl->get_base(), *this );
100 leaveScope();
101 debugPrint( "Adding typedef " << typeDecl->get_name() << std::endl );
102 typeTable.add( typeDecl );
[a08ba92]103 }
[17cd4eb]104
[a08ba92]105 void Indexer::visit( StructDecl *aggregateDecl ) {
[0dd3a2f]106 // make up a forward declaration and add it before processing the members
107 StructDecl fwdDecl( aggregateDecl->get_name() );
108 cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
109 debugPrint( "Adding fwd decl for struct " << fwdDecl.get_name() << std::endl );
110 structTable.add( &fwdDecl );
[51b73452]111
[0dd3a2f]112 enterScope();
113 acceptAll( aggregateDecl->get_parameters(), *this );
114 acceptAll( aggregateDecl->get_members(), *this );
115 leaveScope();
[51b73452]116
[0dd3a2f]117 debugPrint( "Adding struct " << aggregateDecl->get_name() << std::endl );
118 // this addition replaces the forward declaration
119 structTable.add( aggregateDecl );
[a08ba92]120 }
[17cd4eb]121
[a08ba92]122 void Indexer::visit( UnionDecl *aggregateDecl ) {
[0dd3a2f]123 // make up a forward declaration and add it before processing the members
124 UnionDecl fwdDecl( aggregateDecl->get_name() );
125 cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
126 debugPrint( "Adding fwd decl for union " << fwdDecl.get_name() << std::endl );
127 unionTable.add( &fwdDecl );
[51b73452]128
[0dd3a2f]129 enterScope();
130 acceptAll( aggregateDecl->get_parameters(), *this );
131 acceptAll( aggregateDecl->get_members(), *this );
132 leaveScope();
[51b73452]133
[0dd3a2f]134 debugPrint( "Adding union " << aggregateDecl->get_name() << std::endl );
135 unionTable.add( aggregateDecl );
[a08ba92]136 }
[17cd4eb]137
[a08ba92]138 void Indexer::visit( EnumDecl *aggregateDecl ) {
[0dd3a2f]139 debugPrint( "Adding enum " << aggregateDecl->get_name() << std::endl );
140 enumTable.add( aggregateDecl );
141 // unlike structs, contexts, and unions, enums inject their members into the global scope
142 acceptAll( aggregateDecl->get_members(), *this );
[a08ba92]143 }
[17cd4eb]144
[a08ba92]145 void Indexer::visit( ContextDecl *aggregateDecl ) {
[0dd3a2f]146 enterScope();
147 acceptAll( aggregateDecl->get_parameters(), *this );
148 acceptAll( aggregateDecl->get_members(), *this );
149 leaveScope();
[51b73452]150
[0dd3a2f]151 debugPrint( "Adding context " << aggregateDecl->get_name() << std::endl );
152 contextTable.add( aggregateDecl );
[a08ba92]153 }
[17cd4eb]154
[a08ba92]155 void Indexer::visit( CompoundStmt *compoundStmt ) {
[0dd3a2f]156 enterScope();
157 acceptAll( compoundStmt->get_kids(), *this );
158 leaveScope();
[a08ba92]159 }
[17cd4eb]160
[ae4c85a]161
162 void Indexer::visit( ApplicationExpr *applicationExpr ) {
163 acceptAllNewScope( applicationExpr->get_results(), *this );
164 maybeAccept( applicationExpr->get_function(), *this );
165 acceptAll( applicationExpr->get_args(), *this );
166 }
167
168 void Indexer::visit( UntypedExpr *untypedExpr ) {
169 acceptAllNewScope( untypedExpr->get_results(), *this );
170 acceptAll( untypedExpr->get_args(), *this );
171 }
172
173 void Indexer::visit( NameExpr *nameExpr ) {
174 acceptAllNewScope( nameExpr->get_results(), *this );
175 }
176
177 void Indexer::visit( AddressExpr *addressExpr ) {
178 acceptAllNewScope( addressExpr->get_results(), *this );
179 maybeAccept( addressExpr->get_arg(), *this );
180 }
181
182 void Indexer::visit( LabelAddressExpr *labAddressExpr ) {
183 acceptAllNewScope( labAddressExpr->get_results(), *this );
184 maybeAccept( labAddressExpr->get_arg(), *this );
185 }
186
187 void Indexer::visit( CastExpr *castExpr ) {
188 acceptAllNewScope( castExpr->get_results(), *this );
189 maybeAccept( castExpr->get_arg(), *this );
190 }
191
192 void Indexer::visit( UntypedMemberExpr *memberExpr ) {
193 acceptAllNewScope( memberExpr->get_results(), *this );
194 maybeAccept( memberExpr->get_aggregate(), *this );
195 }
196
197 void Indexer::visit( MemberExpr *memberExpr ) {
198 acceptAllNewScope( memberExpr->get_results(), *this );
199 maybeAccept( memberExpr->get_aggregate(), *this );
200 }
201
202 void Indexer::visit( VariableExpr *variableExpr ) {
203 acceptAllNewScope( variableExpr->get_results(), *this );
204 }
205
206 void Indexer::visit( ConstantExpr *constantExpr ) {
207 acceptAllNewScope( constantExpr->get_results(), *this );
208 maybeAccept( constantExpr->get_constant(), *this );
209 }
210
211 void Indexer::visit( SizeofExpr *sizeofExpr ) {
212 acceptAllNewScope( sizeofExpr->get_results(), *this );
213 if ( sizeofExpr->get_isType() ) {
214 maybeAccept( sizeofExpr->get_type(), *this );
215 } else {
216 maybeAccept( sizeofExpr->get_expr(), *this );
217 }
218 }
219
[47534159]220 void Indexer::visit( AlignofExpr *alignofExpr ) {
221 acceptAllNewScope( alignofExpr->get_results(), *this );
222 if ( alignofExpr->get_isType() ) {
223 maybeAccept( alignofExpr->get_type(), *this );
224 } else {
225 maybeAccept( alignofExpr->get_expr(), *this );
226 }
227 }
228
[2a4b088]229 void Indexer::visit( UntypedOffsetofExpr *offsetofExpr ) {
230 acceptAllNewScope( offsetofExpr->get_results(), *this );
231 maybeAccept( offsetofExpr->get_type(), *this );
232 }
233
[25a054f]234 void Indexer::visit( OffsetofExpr *offsetofExpr ) {
235 acceptAllNewScope( offsetofExpr->get_results(), *this );
236 maybeAccept( offsetofExpr->get_type(), *this );
237 maybeAccept( offsetofExpr->get_member(), *this );
238 }
239
[ae4c85a]240 void Indexer::visit( AttrExpr *attrExpr ) {
241 acceptAllNewScope( attrExpr->get_results(), *this );
242 if ( attrExpr->get_isType() ) {
243 maybeAccept( attrExpr->get_type(), *this );
244 } else {
245 maybeAccept( attrExpr->get_expr(), *this );
246 }
247 }
248
249 void Indexer::visit( LogicalExpr *logicalExpr ) {
250 acceptAllNewScope( logicalExpr->get_results(), *this );
251 maybeAccept( logicalExpr->get_arg1(), *this );
252 maybeAccept( logicalExpr->get_arg2(), *this );
253 }
254
255 void Indexer::visit( ConditionalExpr *conditionalExpr ) {
256 acceptAllNewScope( conditionalExpr->get_results(), *this );
257 maybeAccept( conditionalExpr->get_arg1(), *this );
258 maybeAccept( conditionalExpr->get_arg2(), *this );
259 maybeAccept( conditionalExpr->get_arg3(), *this );
260 }
261
262 void Indexer::visit( CommaExpr *commaExpr ) {
263 acceptAllNewScope( commaExpr->get_results(), *this );
264 maybeAccept( commaExpr->get_arg1(), *this );
265 maybeAccept( commaExpr->get_arg2(), *this );
266 }
267
268 void Indexer::visit( TupleExpr *tupleExpr ) {
269 acceptAllNewScope( tupleExpr->get_results(), *this );
270 acceptAll( tupleExpr->get_exprs(), *this );
271 }
272
273 void Indexer::visit( SolvedTupleExpr *tupleExpr ) {
274 acceptAllNewScope( tupleExpr->get_results(), *this );
275 acceptAll( tupleExpr->get_exprs(), *this );
276 }
277
278 void Indexer::visit( TypeExpr *typeExpr ) {
279 acceptAllNewScope( typeExpr->get_results(), *this );
280 maybeAccept( typeExpr->get_type(), *this );
281 }
282
283 void Indexer::visit( AsmExpr *asmExpr ) {
284 maybeAccept( asmExpr->get_inout(), *this );
285 maybeAccept( asmExpr->get_constraint(), *this );
286 maybeAccept( asmExpr->get_operand(), *this );
287 }
288
289 void Indexer::visit( UntypedValofExpr *valofExpr ) {
290 acceptAllNewScope( valofExpr->get_results(), *this );
291 maybeAccept( valofExpr->get_body(), *this );
292 }
293
294
[a08ba92]295 void Indexer::visit( ContextInstType *contextInst ) {
[0dd3a2f]296 acceptAll( contextInst->get_parameters(), *this );
297 acceptAll( contextInst->get_members(), *this );
[a08ba92]298 }
[17cd4eb]299
[a08ba92]300 void Indexer::visit( StructInstType *structInst ) {
[0dd3a2f]301 if ( ! structTable.lookup( structInst->get_name() ) ) {
302 debugPrint( "Adding struct " << structInst->get_name() << " from implicit forward declaration" << std::endl );
303 structTable.add( structInst->get_name() );
304 }
305 enterScope();
306 acceptAll( structInst->get_parameters(), *this );
307 leaveScope();
[a08ba92]308 }
[17cd4eb]309
[a08ba92]310 void Indexer::visit( UnionInstType *unionInst ) {
[0dd3a2f]311 if ( ! unionTable.lookup( unionInst->get_name() ) ) {
312 debugPrint( "Adding union " << unionInst->get_name() << " from implicit forward declaration" << std::endl );
313 unionTable.add( unionInst->get_name() );
314 }
315 enterScope();
316 acceptAll( unionInst->get_parameters(), *this );
317 leaveScope();
[a08ba92]318 }
[17cd4eb]319
[a08ba92]320 void Indexer::visit( ForStmt *forStmt ) {
321 // for statements introduce a level of scope
322 enterScope();
323 Visitor::visit( forStmt );
324 leaveScope();
325 }
[d4778a6]326
327
[a08ba92]328 void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &list ) const {
[0dd3a2f]329 idTable.lookupId( id, list );
[a08ba92]330 }
[17cd4eb]331
[a08ba92]332 DeclarationWithType* Indexer::lookupId( const std::string &id) const {
[0dd3a2f]333 return idTable.lookupId(id);
[a08ba92]334 }
[bdd516a]335
[a08ba92]336 NamedTypeDecl *Indexer::lookupType( const std::string &id ) const {
[0dd3a2f]337 return typeTable.lookup( id );
[a08ba92]338 }
[17cd4eb]339
[a08ba92]340 StructDecl *Indexer::lookupStruct( const std::string &id ) const {
[0dd3a2f]341 return structTable.lookup( id );
[a08ba92]342 }
[17cd4eb]343
[a08ba92]344 EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
[0dd3a2f]345 return enumTable.lookup( id );
[a08ba92]346 }
[17cd4eb]347
[a08ba92]348 UnionDecl *Indexer::lookupUnion( const std::string &id ) const {
[0dd3a2f]349 return unionTable.lookup( id );
[a08ba92]350 }
[17cd4eb]351
[a08ba92]352 ContextDecl * Indexer::lookupContext( const std::string &id ) const {
[0dd3a2f]353 return contextTable.lookup( id );
[a08ba92]354 }
[17cd4eb]355
[a08ba92]356 void Indexer::enterScope() {
[0dd3a2f]357 if ( doDebug ) {
358 std::cout << "--- Entering scope" << std::endl;
359 }
360 idTable.enterScope();
361 typeTable.enterScope();
362 structTable.enterScope();
363 enumTable.enterScope();
364 unionTable.enterScope();
365 contextTable.enterScope();
[a08ba92]366 }
[17cd4eb]367
[a08ba92]368 void Indexer::leaveScope() {
[0dd3a2f]369 using std::cout;
370 using std::endl;
[51b73452]371
[0dd3a2f]372 if ( doDebug ) {
373 cout << "--- Leaving scope containing" << endl;
374 idTable.dump( cout );
375 typeTable.dump( cout );
376 structTable.dump( cout );
377 enumTable.dump( cout );
378 unionTable.dump( cout );
379 contextTable.dump( cout );
380 }
381 idTable.leaveScope();
382 typeTable.leaveScope();
383 structTable.leaveScope();
384 enumTable.leaveScope();
385 unionTable.leaveScope();
386 contextTable.leaveScope();
[a08ba92]387 }
[17cd4eb]388
[a08ba92]389 void Indexer::print( std::ostream &os, int indent ) const {
390 using std::cerr;
391 using std::endl;
[bdd516a]392
[a08ba92]393 cerr << "===idTable===" << endl;
394 idTable.dump( os );
395 cerr << "===typeTable===" << endl;
396 typeTable.dump( os );
397 cerr << "===structTable===" << endl;
398 structTable.dump( os );
399 cerr << "===enumTable===" << endl;
400 enumTable.dump( os );
401 cerr << "===unionTable===" << endl;
402 unionTable.dump( os );
403 cerr << "===contextTable===" << endl;
404 contextTable.dump( os );
[bdd516a]405#if 0
[0dd3a2f]406 idTable.dump( os );
407 typeTable.dump( os );
408 structTable.dump( os );
409 enumTable.dump( os );
410 unionTable.dump( os );
411 contextTable.dump( os );
[bdd516a]412#endif
[a08ba92]413 }
[51b73452]414} // namespace SymTab
[0dd3a2f]415
416// Local Variables: //
417// tab-width: 4 //
418// mode: c++ //
419// compile-command: "make install" //
420// End: //
Note: See TracBrowser for help on using the repository browser.