source: translator/SymTab/Indexer.cc @ 02e9ae2

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 02e9ae2 was 17cd4eb, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

fixed restrict, fixed parameter copy, introduced name table for types, changed variable after to string

  • Property mode set to 100644
File size: 7.4 KB
Line 
1#include "SynTree/Declaration.h"
2#include "SynTree/Type.h"
3#include "SynTree/Expression.h"
4#include "SynTree/Initializer.h"
5#include "SynTree/Statement.h"
6#include "Indexer.h"
7#include <typeinfo>
8#include "utility.h"
9
10#define debugPrint(x) if ( doDebug ) { std::cout << x; }
11
12namespace SymTab {
13    Indexer::Indexer( bool useDebug ) : doDebug( useDebug ) {}
14
15    Indexer::~Indexer() {}
16
17    void Indexer::visit( ObjectDecl *objectDecl ) {
18        maybeAccept( objectDecl->get_type(), *this );
19        maybeAccept( objectDecl->get_init(), *this );
20        maybeAccept( objectDecl->get_bitfieldWidth(), *this );
21        if ( objectDecl->get_name() != "" ) {
22            debugPrint( "Adding object " << objectDecl->get_name() << std::endl );
23            idTable.addDecl( objectDecl );
24        }
25    }
26
27    void Indexer::visit( FunctionDecl *functionDecl ) {
28        if ( functionDecl->get_name() == "" ) return;
29        debugPrint( "Adding function " << functionDecl->get_name() << std::endl );
30        idTable.addDecl( functionDecl );
31        enterScope();
32        maybeAccept( functionDecl->get_functionType(), *this );
33        acceptAll( functionDecl->get_oldDecls(), *this );
34        maybeAccept( functionDecl->get_statements(), *this );
35        leaveScope();
36    }
37
38/********
39 * A NOTE ON THE ORDER OF TRAVERSAL
40 *
41 * Types and typedefs have their base types visited before they are added to the type table.
42 * This is ok, since there is no such thing as a recursive type or typedef.
43 *             typedef struct { T *x; } T; // never allowed
44 *
45 * for structs/unions, it is possible to have recursion, so the decl should be added as if it's
46 * incomplete to begin, the members are traversed, and then the complete type should be added
47 * (assuming the type is completed by this particular declaration).
48 *             struct T { struct T *x; }; // allowed
49 *
50 * It's important to add the complete type to the symbol table *after* the members/base has been
51 * traversed, since that traversal may modify the definition of the type and these modifications
52 * should be visible when the symbol table is queried later in this pass.
53 *
54 * TODO: figure out whether recursive contexts are sensible/possible/reasonable.
55 */
56
57    void Indexer::visit( TypeDecl *typeDecl ) {
58        // see A NOTE ON THE ORDER OF TRAVERSAL, above
59        // note that assertions come after the type is added to the symtab, since they aren't part
60        // of the type proper and may depend on the type itself
61        enterScope();
62        acceptAll( typeDecl->get_parameters(), *this );
63        maybeAccept( typeDecl->get_base(), *this );
64        leaveScope();
65        debugPrint( "Adding type " << typeDecl->get_name() << std::endl );
66        typeTable.add( typeDecl );
67        acceptAll( typeDecl->get_assertions(), *this );
68    }
69
70    void Indexer::visit( TypedefDecl *typeDecl ) {
71        enterScope();
72        acceptAll( typeDecl->get_parameters(), *this );
73        maybeAccept( typeDecl->get_base(), *this );
74        leaveScope();
75        debugPrint( "Adding typedef " << typeDecl->get_name() << std::endl );
76        typeTable.add( typeDecl );
77    }
78
79    void Indexer::visit( StructDecl *aggregateDecl ) {
80        // make up a forward declaration and add it before processing the members
81        StructDecl fwdDecl( aggregateDecl->get_name() );
82        cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
83        debugPrint( "Adding fwd decl for struct " << fwdDecl.get_name() << std::endl );
84        structTable.add( &fwdDecl );
85 
86        enterScope();
87        acceptAll( aggregateDecl->get_parameters(), *this );
88        acceptAll( aggregateDecl->get_members(), *this );
89        leaveScope();
90 
91        debugPrint( "Adding struct " << aggregateDecl->get_name() << std::endl );
92        // this addition replaces the forward declaration
93        structTable.add( aggregateDecl );
94    }
95
96    void Indexer::visit( UnionDecl *aggregateDecl ) {
97        // make up a forward declaration and add it before processing the members
98        UnionDecl fwdDecl( aggregateDecl->get_name() );
99        cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
100        debugPrint( "Adding fwd decl for union " << fwdDecl.get_name() << std::endl );
101        unionTable.add( &fwdDecl );
102 
103        enterScope();
104        acceptAll( aggregateDecl->get_parameters(), *this );
105        acceptAll( aggregateDecl->get_members(), *this );
106        leaveScope();
107 
108        debugPrint( "Adding union " << aggregateDecl->get_name() << std::endl );
109        unionTable.add( aggregateDecl );
110    }
111
112    void Indexer::visit( EnumDecl *aggregateDecl ) {
113        debugPrint( "Adding enum " << aggregateDecl->get_name() << std::endl );
114        enumTable.add( aggregateDecl );
115        // unlike structs, contexts, and unions, enums inject their members into the global scope
116        acceptAll( aggregateDecl->get_members(), *this );
117    }
118
119    void Indexer::visit( ContextDecl *aggregateDecl ) {
120        enterScope();
121        acceptAll( aggregateDecl->get_parameters(), *this );
122        acceptAll( aggregateDecl->get_members(), *this );
123        leaveScope();
124 
125        debugPrint( "Adding context " << aggregateDecl->get_name() << std::endl );
126        contextTable.add( aggregateDecl );
127    }
128
129    void Indexer::visit( CompoundStmt *compoundStmt ) {
130        enterScope();
131        acceptAll( compoundStmt->get_kids(), *this );
132        leaveScope();
133    }
134
135    void Indexer::visit( ContextInstType *contextInst ) {
136        acceptAll( contextInst->get_parameters(), *this );
137        acceptAll( contextInst->get_members(), *this );
138    }
139
140    void Indexer::visit( StructInstType *structInst ) {
141        if ( ! structTable.lookup( structInst->get_name() ) ) {
142            debugPrint( "Adding struct " << structInst->get_name() << " from implicit forward declaration" << std::endl );
143            structTable.add( structInst->get_name() );
144        }
145        enterScope();
146        acceptAll( structInst->get_parameters(), *this );
147        leaveScope();
148    }
149
150    void Indexer::visit( UnionInstType *unionInst ) {
151        if ( ! unionTable.lookup( unionInst->get_name() ) ) {
152            debugPrint( "Adding union " << unionInst->get_name() << " from implicit forward declaration" << std::endl );
153            unionTable.add( unionInst->get_name() );
154        }
155        enterScope();
156        acceptAll( unionInst->get_parameters(), *this );
157        leaveScope();
158    }
159
160    void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &list ) const {
161        idTable.lookupId( id, list );
162    }
163
164    NamedTypeDecl *Indexer::lookupType( const std::string &id ) const {
165        return typeTable.lookup( id );
166    }
167
168    StructDecl *Indexer::lookupStruct( const std::string &id ) const {
169        return structTable.lookup( id );
170    }
171
172    EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
173        return enumTable.lookup( id );
174    }
175
176    UnionDecl *Indexer::lookupUnion( const std::string &id ) const {
177        return unionTable.lookup( id );
178    }
179
180    ContextDecl  * Indexer::lookupContext( const std::string &id ) const {
181        return contextTable.lookup( id );
182    }
183
184    void Indexer::enterScope() {
185        if ( doDebug ) {
186            std::cout << "--- Entering scope" << std::endl;
187        }
188        idTable.enterScope();
189        typeTable.enterScope();
190        structTable.enterScope();
191        enumTable.enterScope();
192        unionTable.enterScope();
193        contextTable.enterScope();
194    }
195
196    void Indexer::leaveScope() {
197        using std::cout;
198        using std::endl;
199 
200        if ( doDebug ) {
201            cout << "--- Leaving scope containing" << endl;
202            idTable.dump( cout );
203            typeTable.dump( cout );
204            structTable.dump( cout );
205            enumTable.dump( cout );
206            unionTable.dump( cout );
207            contextTable.dump( cout );
208        }
209        idTable.leaveScope();
210        typeTable.leaveScope();
211        structTable.leaveScope();
212        enumTable.leaveScope();
213        unionTable.leaveScope();
214        contextTable.leaveScope();
215    }
216
217    void Indexer::print( std::ostream &os, int indent ) const {
218        idTable.dump( os );
219        typeTable.dump( os );
220        structTable.dump( os );
221        enumTable.dump( os );
222        unionTable.dump( os );
223        contextTable.dump( os );
224    }
225} // namespace SymTab
Note: See TracBrowser for help on using the repository browser.