source: translator/SymTab/Indexer.cc @ 51587aa

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 51587aa was 0dd3a2f, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

licencing: third groups of files

  • Property mode set to 100644
File size: 8.7 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 : Sun May 17 21:38:44 2015
13// Update Count     : 2
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    Indexer::Indexer( bool useDebug ) : doDebug( useDebug ) {}
29
30    Indexer::~Indexer() {}
31
32    void Indexer::visit( ObjectDecl *objectDecl ) {
33                maybeAccept( objectDecl->get_type(), *this );
34                maybeAccept( objectDecl->get_init(), *this );
35                maybeAccept( objectDecl->get_bitfieldWidth(), *this );
36                if ( objectDecl->get_name() != "" ) {
37                        debugPrint( "Adding object " << objectDecl->get_name() << std::endl );
38                        idTable.addDecl( objectDecl );
39                } // if
40    }
41
42    void Indexer::visit( FunctionDecl *functionDecl ) {
43                if ( functionDecl->get_name() == "" ) return;
44                debugPrint( "Adding function " << functionDecl->get_name() << std::endl );
45                idTable.addDecl( functionDecl );
46                enterScope();
47                maybeAccept( functionDecl->get_functionType(), *this );
48                acceptAll( functionDecl->get_oldDecls(), *this );
49                maybeAccept( functionDecl->get_statements(), *this );
50                leaveScope();
51    }
52
53/********
54 * A NOTE ON THE ORDER OF TRAVERSAL
55 *
56 * Types and typedefs have their base types visited before they are added to the type table.
57 * This is ok, since there is no such thing as a recursive type or typedef.
58 *             typedef struct { T *x; } T; // never allowed
59 *
60 * for structs/unions, it is possible to have recursion, so the decl should be added as if it's
61 * incomplete to begin, the members are traversed, and then the complete type should be added
62 * (assuming the type is completed by this particular declaration).
63 *             struct T { struct T *x; }; // allowed
64 *
65 * It's important to add the complete type to the symbol table *after* the members/base has been
66 * traversed, since that traversal may modify the definition of the type and these modifications
67 * should be visible when the symbol table is queried later in this pass.
68 *
69 * TODO: figure out whether recursive contexts are sensible/possible/reasonable.
70 */
71
72    void Indexer::visit( TypeDecl *typeDecl ) {
73                // see A NOTE ON THE ORDER OF TRAVERSAL, above
74                // note that assertions come after the type is added to the symtab, since they aren't part
75                // of the type proper and may depend on the type itself
76                enterScope();
77                acceptAll( typeDecl->get_parameters(), *this );
78                maybeAccept( typeDecl->get_base(), *this );
79                leaveScope();
80                debugPrint( "Adding type " << typeDecl->get_name() << std::endl );
81                typeTable.add( typeDecl );
82                acceptAll( typeDecl->get_assertions(), *this );
83    }
84
85    void Indexer::visit( TypedefDecl *typeDecl ) {
86                enterScope();
87                acceptAll( typeDecl->get_parameters(), *this );
88                maybeAccept( typeDecl->get_base(), *this );
89                leaveScope();
90                debugPrint( "Adding typedef " << typeDecl->get_name() << std::endl );
91                typeTable.add( typeDecl );
92    }
93
94    void Indexer::visit( StructDecl *aggregateDecl ) {
95                // make up a forward declaration and add it before processing the members
96                StructDecl fwdDecl( aggregateDecl->get_name() );
97                cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
98                debugPrint( "Adding fwd decl for struct " << fwdDecl.get_name() << std::endl );
99                structTable.add( &fwdDecl );
100 
101                enterScope();
102                acceptAll( aggregateDecl->get_parameters(), *this );
103                acceptAll( aggregateDecl->get_members(), *this );
104                leaveScope();
105 
106                debugPrint( "Adding struct " << aggregateDecl->get_name() << std::endl );
107                // this addition replaces the forward declaration
108                structTable.add( aggregateDecl );
109    }
110
111    void Indexer::visit( UnionDecl *aggregateDecl ) {
112                // make up a forward declaration and add it before processing the members
113                UnionDecl fwdDecl( aggregateDecl->get_name() );
114                cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
115                debugPrint( "Adding fwd decl for union " << fwdDecl.get_name() << std::endl );
116                unionTable.add( &fwdDecl );
117 
118                enterScope();
119                acceptAll( aggregateDecl->get_parameters(), *this );
120                acceptAll( aggregateDecl->get_members(), *this );
121                leaveScope();
122 
123                debugPrint( "Adding union " << aggregateDecl->get_name() << std::endl );
124                unionTable.add( aggregateDecl );
125    }
126
127    void Indexer::visit( EnumDecl *aggregateDecl ) {
128                debugPrint( "Adding enum " << aggregateDecl->get_name() << std::endl );
129                enumTable.add( aggregateDecl );
130                // unlike structs, contexts, and unions, enums inject their members into the global scope
131                acceptAll( aggregateDecl->get_members(), *this );
132    }
133
134    void Indexer::visit( ContextDecl *aggregateDecl ) {
135                enterScope();
136                acceptAll( aggregateDecl->get_parameters(), *this );
137                acceptAll( aggregateDecl->get_members(), *this );
138                leaveScope();
139 
140                debugPrint( "Adding context " << aggregateDecl->get_name() << std::endl );
141                contextTable.add( aggregateDecl );
142    }
143
144    void Indexer::visit( CompoundStmt *compoundStmt ) {
145                enterScope();
146                acceptAll( compoundStmt->get_kids(), *this );
147                leaveScope();
148    }
149
150    void Indexer::visit( ContextInstType *contextInst ) {
151                acceptAll( contextInst->get_parameters(), *this );
152                acceptAll( contextInst->get_members(), *this );
153    }
154
155    void Indexer::visit( StructInstType *structInst ) {
156                if ( ! structTable.lookup( structInst->get_name() ) ) {
157                        debugPrint( "Adding struct " << structInst->get_name() << " from implicit forward declaration" << std::endl );
158                        structTable.add( structInst->get_name() );
159                }
160                enterScope();
161                acceptAll( structInst->get_parameters(), *this );
162                leaveScope();
163    }
164
165    void Indexer::visit( UnionInstType *unionInst ) {
166                if ( ! unionTable.lookup( unionInst->get_name() ) ) {
167                        debugPrint( "Adding union " << unionInst->get_name() << " from implicit forward declaration" << std::endl );
168                        unionTable.add( unionInst->get_name() );
169                }
170                enterScope();
171                acceptAll( unionInst->get_parameters(), *this );
172                leaveScope();
173    }
174
175    void Indexer::visit( ForStmt *forStmt ) {
176        // for statements introduce a level of scope
177        enterScope();
178        Visitor::visit( forStmt );
179        leaveScope();
180    }
181
182
183    void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &list ) const {
184                idTable.lookupId( id, list );
185    }
186
187    DeclarationWithType* Indexer::lookupId( const std::string &id) const {
188                return idTable.lookupId(id);
189    }
190
191    NamedTypeDecl *Indexer::lookupType( const std::string &id ) const {
192                return typeTable.lookup( id );
193    }
194
195    StructDecl *Indexer::lookupStruct( const std::string &id ) const {
196                return structTable.lookup( id );
197    }
198
199    EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
200                return enumTable.lookup( id );
201    }
202
203    UnionDecl *Indexer::lookupUnion( const std::string &id ) const {
204                return unionTable.lookup( id );
205    }
206
207    ContextDecl  * Indexer::lookupContext( const std::string &id ) const {
208                return contextTable.lookup( id );
209    }
210
211    void Indexer::enterScope() {
212                if ( doDebug ) {
213                        std::cout << "--- Entering scope" << std::endl;
214                }
215                idTable.enterScope();
216                typeTable.enterScope();
217                structTable.enterScope();
218                enumTable.enterScope();
219                unionTable.enterScope();
220                contextTable.enterScope();
221    }
222
223    void Indexer::leaveScope() {
224                using std::cout;
225                using std::endl;
226 
227                if ( doDebug ) {
228                        cout << "--- Leaving scope containing" << endl;
229                        idTable.dump( cout );
230                        typeTable.dump( cout );
231                        structTable.dump( cout );
232                        enumTable.dump( cout );
233                        unionTable.dump( cout );
234                        contextTable.dump( cout );
235                }
236                idTable.leaveScope();
237                typeTable.leaveScope();
238                structTable.leaveScope();
239                enumTable.leaveScope();
240                unionTable.leaveScope();
241                contextTable.leaveScope();
242    }
243
244    void Indexer::print( std::ostream &os, int indent ) const {
245        using std::cerr;
246        using std::endl;
247
248        cerr << "===idTable===" << endl;
249        idTable.dump( os );
250        cerr << "===typeTable===" << endl;
251        typeTable.dump( os );
252        cerr << "===structTable===" << endl;
253        structTable.dump( os );
254        cerr << "===enumTable===" << endl;
255        enumTable.dump( os );
256        cerr << "===unionTable===" << endl;
257        unionTable.dump( os );
258        cerr << "===contextTable===" << endl;
259        contextTable.dump( os );
260#if 0
261                idTable.dump( os );
262                typeTable.dump( os );
263                structTable.dump( os );
264                enumTable.dump( os );
265                unionTable.dump( os );
266                contextTable.dump( os );
267#endif
268    }
269} // namespace SymTab
270
271// Local Variables: //
272// tab-width: 4 //
273// mode: c++ //
274// compile-command: "make install" //
275// End: //
Note: See TracBrowser for help on using the repository browser.