source: src/SymTab/Indexer.cc@ 893256d

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 with_gc
Last change on this file since 893256d was 44b5ca0, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

remove all carriage returns from printing, work on regression testing

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