source: translator/SymTab/Indexer.cc @ 42dcae7

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 42dcae7 was 51b7345, checked in by Peter A. Buhr <pabuhr@…>, 10 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.