source: translator/SymTab/Indexer.cc@ d0e8cfe4

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay gc_noraii jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new string with_gc
Last change on this file since d0e8cfe4 was 51b73452, checked in by Peter A. Buhr <pabuhr@…>, 11 years ago

initial commit

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