source: src/SymTab/Indexer.cc @ 8360977

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 8360977 was 47534159, checked in by Aaron Moss <a3moss@…>, 8 years ago

Added support for alignof expressions for everything but polymorphic types

  • Property mode set to 100644
File size: 12.6 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 : Rob Schluntz
12// Last Modified On : Wed Aug 05 13:52:42 2015
13// Update Count     : 10
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 "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( ContextDecl *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( AttrExpr *attrExpr ) {
230                acceptAllNewScope( attrExpr->get_results(), *this );
231                if ( attrExpr->get_isType() ) {
232                        maybeAccept( attrExpr->get_type(), *this );
233                } else {
234                        maybeAccept( attrExpr->get_expr(), *this );
235                }
236        }
237
238        void Indexer::visit( LogicalExpr *logicalExpr ) {
239                acceptAllNewScope( logicalExpr->get_results(), *this );
240                maybeAccept( logicalExpr->get_arg1(), *this );
241                maybeAccept( logicalExpr->get_arg2(), *this );
242        }
243
244        void Indexer::visit( ConditionalExpr *conditionalExpr ) {
245                acceptAllNewScope( conditionalExpr->get_results(), *this );
246                maybeAccept( conditionalExpr->get_arg1(), *this );
247                maybeAccept( conditionalExpr->get_arg2(), *this );
248                maybeAccept( conditionalExpr->get_arg3(), *this );
249        }
250
251        void Indexer::visit( CommaExpr *commaExpr ) {
252                acceptAllNewScope( commaExpr->get_results(), *this );
253                maybeAccept( commaExpr->get_arg1(), *this );
254                maybeAccept( commaExpr->get_arg2(), *this );
255        }
256
257        void Indexer::visit( TupleExpr *tupleExpr ) {
258                acceptAllNewScope( tupleExpr->get_results(), *this );
259                acceptAll( tupleExpr->get_exprs(), *this );
260        }
261
262        void Indexer::visit( SolvedTupleExpr *tupleExpr ) {
263                acceptAllNewScope( tupleExpr->get_results(), *this );
264                acceptAll( tupleExpr->get_exprs(), *this );
265        }
266
267        void Indexer::visit( TypeExpr *typeExpr ) {
268                acceptAllNewScope( typeExpr->get_results(), *this );
269                maybeAccept( typeExpr->get_type(), *this );
270        }
271
272        void Indexer::visit( AsmExpr *asmExpr ) {
273                maybeAccept( asmExpr->get_inout(), *this );
274                maybeAccept( asmExpr->get_constraint(), *this );
275                maybeAccept( asmExpr->get_operand(), *this );
276        }
277
278        void Indexer::visit( UntypedValofExpr *valofExpr ) {
279                acceptAllNewScope( valofExpr->get_results(), *this );
280                maybeAccept( valofExpr->get_body(), *this );
281        }
282
283
284        void Indexer::visit( ContextInstType *contextInst ) {
285                acceptAll( contextInst->get_parameters(), *this );
286                acceptAll( contextInst->get_members(), *this );
287        }
288
289        void Indexer::visit( StructInstType *structInst ) {
290                if ( ! structTable.lookup( structInst->get_name() ) ) {
291                        debugPrint( "Adding struct " << structInst->get_name() << " from implicit forward declaration" << std::endl );
292                        structTable.add( structInst->get_name() );
293                }
294                enterScope();
295                acceptAll( structInst->get_parameters(), *this );
296                leaveScope();
297        }
298
299        void Indexer::visit( UnionInstType *unionInst ) {
300                if ( ! unionTable.lookup( unionInst->get_name() ) ) {
301                        debugPrint( "Adding union " << unionInst->get_name() << " from implicit forward declaration" << std::endl );
302                        unionTable.add( unionInst->get_name() );
303                }
304                enterScope();
305                acceptAll( unionInst->get_parameters(), *this );
306                leaveScope();
307        }
308
309        void Indexer::visit( ForStmt *forStmt ) {
310            // for statements introduce a level of scope
311            enterScope();
312            Visitor::visit( forStmt );
313            leaveScope();
314        }
315
316
317        void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &list ) const {
318                idTable.lookupId( id, list );
319        }
320
321        DeclarationWithType* Indexer::lookupId( const std::string &id) const {
322                return idTable.lookupId(id);
323        }
324
325        NamedTypeDecl *Indexer::lookupType( const std::string &id ) const {
326                return typeTable.lookup( id );
327        }
328
329        StructDecl *Indexer::lookupStruct( const std::string &id ) const {
330                return structTable.lookup( id );
331        }
332
333        EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
334                return enumTable.lookup( id );
335        }
336
337        UnionDecl *Indexer::lookupUnion( const std::string &id ) const {
338                return unionTable.lookup( id );
339        }
340
341        ContextDecl  * Indexer::lookupContext( const std::string &id ) const {
342                return contextTable.lookup( id );
343        }
344
345        void Indexer::enterScope() {
346                if ( doDebug ) {
347                        std::cout << "--- Entering scope" << std::endl;
348                }
349                idTable.enterScope();
350                typeTable.enterScope();
351                structTable.enterScope();
352                enumTable.enterScope();
353                unionTable.enterScope();
354                contextTable.enterScope();
355        }
356
357        void Indexer::leaveScope() {
358                using std::cout;
359                using std::endl;
360 
361                if ( doDebug ) {
362                        cout << "--- Leaving scope containing" << endl;
363                        idTable.dump( cout );
364                        typeTable.dump( cout );
365                        structTable.dump( cout );
366                        enumTable.dump( cout );
367                        unionTable.dump( cout );
368                        contextTable.dump( cout );
369                }
370                idTable.leaveScope();
371                typeTable.leaveScope();
372                structTable.leaveScope();
373                enumTable.leaveScope();
374                unionTable.leaveScope();
375                contextTable.leaveScope();
376        }
377
378        void Indexer::print( std::ostream &os, int indent ) const {
379            using std::cerr;
380            using std::endl;
381
382            cerr << "===idTable===" << endl;
383            idTable.dump( os );
384            cerr << "===typeTable===" << endl;
385            typeTable.dump( os );
386            cerr << "===structTable===" << endl;
387            structTable.dump( os );
388            cerr << "===enumTable===" << endl;
389            enumTable.dump( os );
390            cerr << "===unionTable===" << endl;
391            unionTable.dump( os );
392            cerr << "===contextTable===" << endl;
393            contextTable.dump( os );
394#if 0
395                idTable.dump( os );
396                typeTable.dump( os );
397                structTable.dump( os );
398                enumTable.dump( os );
399                unionTable.dump( os );
400                contextTable.dump( os );
401#endif
402        }
403} // namespace SymTab
404
405// Local Variables: //
406// tab-width: 4 //
407// mode: c++ //
408// compile-command: "make install" //
409// End: //
Note: See TracBrowser for help on using the repository browser.