source: src/SymTab/Indexer.cc @ 5721a6d

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 5721a6d was ae8b942, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

Merge branch 'master' of plg2:software/cfa/cfa-cc

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