source: src/SymTab/Indexer.cc@ f7d59bf

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 f7d59bf was 843054c2, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

licencing: seventh groups of files

  • Property mode set to 100644
File size: 8.6 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 : Tue May 19 16:49:55 2015
13// Update Count : 3
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.