source: src/SymTab/Indexer.cc @ 8a95629

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 8a95629 was 44b5ca0, checked in by Peter A. Buhr <pabuhr@…>, 9 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.