source: src/SymTab/Indexer.cc @ 36ebd03

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since 36ebd03 was 4040425, checked in by Peter A. Buhr <pabuhr@…>, 8 years ago

change keyword type to otype and context to trait

  • Property mode set to 100644
File size: 13.0 KB
Line 
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
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Wed Mar  2 17:31:29 2016
13// Update Count     : 11
14//
15
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>
23#include "Common/utility.h"
24
25#define debugPrint(x) if ( doDebug ) { std::cout << x; }
26
27namespace SymTab {
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
35        Indexer::Indexer( bool useDebug ) : doDebug( useDebug ) {}
36
37        Indexer::~Indexer() {}
38
39        void Indexer::visit( ObjectDecl *objectDecl ) {
40                enterScope();
41                maybeAccept( objectDecl->get_type(), *this );
42                leaveScope();
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
49        }
50
51        void Indexer::visit( FunctionDecl *functionDecl ) {
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();
60        }
61
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
82
83        void Indexer::visit( TypeDecl *typeDecl ) {
84                // see A NOTE ON THE ORDER OF TRAVERSAL, above
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
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 );
94        }
95
96        void Indexer::visit( TypedefDecl *typeDecl ) {
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 );
103        }
104
105        void Indexer::visit( StructDecl *aggregateDecl ) {
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 );
111 
112                enterScope();
113                acceptAll( aggregateDecl->get_parameters(), *this );
114                acceptAll( aggregateDecl->get_members(), *this );
115                leaveScope();
116 
117                debugPrint( "Adding struct " << aggregateDecl->get_name() << std::endl );
118                // this addition replaces the forward declaration
119                structTable.add( aggregateDecl );
120        }
121
122        void Indexer::visit( UnionDecl *aggregateDecl ) {
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 );
128 
129                enterScope();
130                acceptAll( aggregateDecl->get_parameters(), *this );
131                acceptAll( aggregateDecl->get_members(), *this );
132                leaveScope();
133 
134                debugPrint( "Adding union " << aggregateDecl->get_name() << std::endl );
135                unionTable.add( aggregateDecl );
136        }
137
138        void Indexer::visit( EnumDecl *aggregateDecl ) {
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 );
143        }
144
145        void Indexer::visit( TraitDecl *aggregateDecl ) {
146                enterScope();
147                acceptAll( aggregateDecl->get_parameters(), *this );
148                acceptAll( aggregateDecl->get_members(), *this );
149                leaveScope();
150 
151                debugPrint( "Adding context " << aggregateDecl->get_name() << std::endl );
152                contextTable.add( aggregateDecl );
153        }
154
155        void Indexer::visit( CompoundStmt *compoundStmt ) {
156                enterScope();
157                acceptAll( compoundStmt->get_kids(), *this );
158                leaveScope();
159        }
160
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
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
229        void Indexer::visit( UntypedOffsetofExpr *offsetofExpr ) {
230                acceptAllNewScope( offsetofExpr->get_results(), *this );
231                maybeAccept( offsetofExpr->get_type(), *this );
232        }
233
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
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
295        void Indexer::visit( TraitInstType *contextInst ) {
296                acceptAll( contextInst->get_parameters(), *this );
297                acceptAll( contextInst->get_members(), *this );
298        }
299
300        void Indexer::visit( StructInstType *structInst ) {
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();
308        }
309
310        void Indexer::visit( UnionInstType *unionInst ) {
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();
318        }
319
320        void Indexer::visit( ForStmt *forStmt ) {
321            // for statements introduce a level of scope
322            enterScope();
323            Visitor::visit( forStmt );
324            leaveScope();
325        }
326
327
328        void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &list ) const {
329                idTable.lookupId( id, list );
330        }
331
332        DeclarationWithType* Indexer::lookupId( const std::string &id) const {
333                return idTable.lookupId(id);
334        }
335
336        NamedTypeDecl *Indexer::lookupType( const std::string &id ) const {
337                return typeTable.lookup( id );
338        }
339
340        StructDecl *Indexer::lookupStruct( const std::string &id ) const {
341                return structTable.lookup( id );
342        }
343
344        EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
345                return enumTable.lookup( id );
346        }
347
348        UnionDecl *Indexer::lookupUnion( const std::string &id ) const {
349                return unionTable.lookup( id );
350        }
351
352        TraitDecl  * Indexer::lookupTrait( const std::string &id ) const {
353                return contextTable.lookup( id );
354        }
355
356        void Indexer::enterScope() {
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();
366        }
367
368        void Indexer::leaveScope() {
369                using std::cout;
370                using std::endl;
371 
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();
387        }
388
389        void Indexer::print( std::ostream &os, int indent ) const {
390            using std::cerr;
391            using std::endl;
392
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 );
405#if 0
406                idTable.dump( os );
407                typeTable.dump( os );
408                structTable.dump( os );
409                enumTable.dump( os );
410                unionTable.dump( os );
411                contextTable.dump( os );
412#endif
413        }
414} // namespace SymTab
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.