1 | /* |
---|
2 | * This file is part of the Cforall project |
---|
3 | * |
---|
4 | * $Id: Resolver.cc,v 1.19 2005/08/29 20:14:16 rcbilson Exp $ |
---|
5 | * |
---|
6 | */ |
---|
7 | |
---|
8 | #include "Resolver.h" |
---|
9 | #include "AlternativeFinder.h" |
---|
10 | #include "Alternative.h" |
---|
11 | #include "RenameVars.h" |
---|
12 | #include "ResolveTypeof.h" |
---|
13 | #include "SynTree/Statement.h" |
---|
14 | #include "SynTree/Type.h" |
---|
15 | #include "SynTree/Expression.h" |
---|
16 | #include "SynTree/Initializer.h" |
---|
17 | #include "SymTab/Indexer.h" |
---|
18 | #include "utility.h" |
---|
19 | |
---|
20 | namespace ResolvExpr { |
---|
21 | |
---|
22 | class Resolver : public SymTab::Indexer |
---|
23 | { |
---|
24 | public: |
---|
25 | Resolver() : SymTab::Indexer( false ), switchType( 0 ) {} |
---|
26 | |
---|
27 | virtual void visit( FunctionDecl *functionDecl ); |
---|
28 | virtual void visit( ObjectDecl *functionDecl ); |
---|
29 | virtual void visit( TypeDecl *typeDecl ); |
---|
30 | |
---|
31 | virtual void visit( ExprStmt *exprStmt ); |
---|
32 | virtual void visit( IfStmt *ifStmt ); |
---|
33 | virtual void visit( WhileStmt *whileStmt ); |
---|
34 | virtual void visit( ForStmt *forStmt ); |
---|
35 | virtual void visit( SwitchStmt *switchStmt ); |
---|
36 | virtual void visit( ChooseStmt *switchStmt ); |
---|
37 | virtual void visit( CaseStmt *caseStmt ); |
---|
38 | virtual void visit( ReturnStmt *returnStmt ); |
---|
39 | |
---|
40 | virtual void visit( SingleInit *singleInit ); |
---|
41 | |
---|
42 | private: |
---|
43 | std::list< Type* > functionReturn; |
---|
44 | Type* initContext; |
---|
45 | Type *switchType; |
---|
46 | }; |
---|
47 | |
---|
48 | void |
---|
49 | resolve( std::list< Declaration* > translationUnit ) |
---|
50 | { |
---|
51 | Resolver resolver; |
---|
52 | acceptAll( translationUnit, resolver ); |
---|
53 | /// for( std::list< Declaration* >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) { |
---|
54 | /// (*i)->print( std::cerr ); |
---|
55 | /// (*i)->accept( resolver ); |
---|
56 | /// } |
---|
57 | } |
---|
58 | |
---|
59 | Expression * |
---|
60 | resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ) |
---|
61 | { |
---|
62 | TypeEnvironment env; |
---|
63 | return resolveInVoidContext( expr, indexer, env ); |
---|
64 | } |
---|
65 | |
---|
66 | namespace { |
---|
67 | |
---|
68 | void |
---|
69 | finishExpr( Expression *expr, const TypeEnvironment &env ) |
---|
70 | { |
---|
71 | expr->set_env( new TypeSubstitution ); |
---|
72 | env.makeSubstitution( *expr->get_env() ); |
---|
73 | } |
---|
74 | |
---|
75 | Expression* |
---|
76 | findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) |
---|
77 | { |
---|
78 | global_renamer.reset(); |
---|
79 | TypeEnvironment env; |
---|
80 | Expression *newExpr = resolveInVoidContext( untyped, indexer, env ); |
---|
81 | finishExpr( newExpr, env ); |
---|
82 | return newExpr; |
---|
83 | } |
---|
84 | |
---|
85 | Expression* |
---|
86 | findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) |
---|
87 | { |
---|
88 | TypeEnvironment env; |
---|
89 | AlternativeFinder finder( indexer, env ); |
---|
90 | finder.find( untyped ); |
---|
91 | /// if( finder.get_alternatives().size() != 1 ) { |
---|
92 | /// std::cout << "untyped expr is "; |
---|
93 | /// untyped->print( std::cout ); |
---|
94 | /// std::cout << std::endl << "alternatives are:"; |
---|
95 | /// for( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) { |
---|
96 | /// i->print( std::cout ); |
---|
97 | /// } |
---|
98 | /// } |
---|
99 | assert( finder.get_alternatives().size() == 1 ); |
---|
100 | Alternative &choice = finder.get_alternatives().front(); |
---|
101 | Expression *newExpr = choice.expr->clone(); |
---|
102 | finishExpr( newExpr, choice.env ); |
---|
103 | return newExpr; |
---|
104 | } |
---|
105 | |
---|
106 | bool |
---|
107 | isIntegralType( Type *type ) |
---|
108 | { |
---|
109 | if( dynamic_cast< EnumInstType* >( type ) ) { |
---|
110 | return true; |
---|
111 | } else if( BasicType *bt = dynamic_cast< BasicType* >( type ) ) { |
---|
112 | return bt->isInteger(); |
---|
113 | } else { |
---|
114 | return true; |
---|
115 | } |
---|
116 | } |
---|
117 | |
---|
118 | Expression* |
---|
119 | findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) |
---|
120 | { |
---|
121 | TypeEnvironment env; |
---|
122 | AlternativeFinder finder( indexer, env ); |
---|
123 | finder.find( untyped ); |
---|
124 | /// if( finder.get_alternatives().size() != 1 ) { |
---|
125 | /// std::cout << "untyped expr is "; |
---|
126 | /// untyped->print( std::cout ); |
---|
127 | /// std::cout << std::endl << "alternatives are:"; |
---|
128 | /// for( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) { |
---|
129 | /// i->print( std::cout ); |
---|
130 | /// } |
---|
131 | /// } |
---|
132 | Expression *newExpr = 0; |
---|
133 | const TypeEnvironment *newEnv = 0; |
---|
134 | for( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) { |
---|
135 | if( i->expr->get_results().size() == 1 && isIntegralType( i->expr->get_results().front() ) ) { |
---|
136 | if( newExpr ) { |
---|
137 | throw SemanticError( "Too many interpretations for switch control expression", untyped ); |
---|
138 | } else { |
---|
139 | newExpr = i->expr->clone(); |
---|
140 | newEnv = &i->env; |
---|
141 | } |
---|
142 | } |
---|
143 | } |
---|
144 | if( !newExpr ) { |
---|
145 | throw SemanticError( "Too many interpretations for switch control expression", untyped ); |
---|
146 | } |
---|
147 | finishExpr( newExpr, *newEnv ); |
---|
148 | return newExpr; |
---|
149 | } |
---|
150 | |
---|
151 | } |
---|
152 | |
---|
153 | void |
---|
154 | Resolver::visit( ObjectDecl *objectDecl ) |
---|
155 | { |
---|
156 | Type *new_type = resolveTypeof( objectDecl->get_type(), *this ); |
---|
157 | objectDecl->set_type( new_type ); |
---|
158 | initContext = new_type; |
---|
159 | SymTab::Indexer::visit( objectDecl ); |
---|
160 | } |
---|
161 | |
---|
162 | void |
---|
163 | Resolver::visit( TypeDecl *typeDecl ) |
---|
164 | { |
---|
165 | if( typeDecl->get_base() ) { |
---|
166 | Type *new_type = resolveTypeof( typeDecl->get_base(), *this ); |
---|
167 | typeDecl->set_base( new_type ); |
---|
168 | } |
---|
169 | SymTab::Indexer::visit( typeDecl ); |
---|
170 | } |
---|
171 | |
---|
172 | void |
---|
173 | Resolver::visit( FunctionDecl *functionDecl ) |
---|
174 | { |
---|
175 | /// std::cout << "resolver visiting functiondecl "; |
---|
176 | /// functionDecl->print( std::cout ); |
---|
177 | /// std::cout << std::endl; |
---|
178 | Type *new_type = resolveTypeof( functionDecl->get_type(), *this ); |
---|
179 | functionDecl->set_type( new_type ); |
---|
180 | std::list< Type* > oldFunctionReturn = functionReturn; |
---|
181 | functionReturn.clear(); |
---|
182 | for( std::list< DeclarationWithType* >::const_iterator i = functionDecl->get_functionType()->get_returnVals().begin(); i != functionDecl->get_functionType()->get_returnVals().end(); ++i ) { |
---|
183 | functionReturn.push_back( (*i)->get_type() ); |
---|
184 | } |
---|
185 | SymTab::Indexer::visit( functionDecl ); |
---|
186 | functionReturn = oldFunctionReturn; |
---|
187 | } |
---|
188 | |
---|
189 | void |
---|
190 | Resolver::visit( ExprStmt *exprStmt ) |
---|
191 | { |
---|
192 | if( exprStmt->get_expr() ) { |
---|
193 | Expression *newExpr = findVoidExpression( exprStmt->get_expr(), *this ); |
---|
194 | delete exprStmt->get_expr(); |
---|
195 | exprStmt->set_expr( newExpr ); |
---|
196 | } |
---|
197 | } |
---|
198 | |
---|
199 | void |
---|
200 | Resolver::visit( IfStmt *ifStmt ) |
---|
201 | { |
---|
202 | Expression *newExpr = findSingleExpression( ifStmt->get_condition(), *this ); |
---|
203 | delete ifStmt->get_condition(); |
---|
204 | ifStmt->set_condition( newExpr ); |
---|
205 | Visitor::visit( ifStmt ); |
---|
206 | } |
---|
207 | |
---|
208 | void |
---|
209 | Resolver::visit( WhileStmt *whileStmt ) |
---|
210 | { |
---|
211 | Expression *newExpr = findSingleExpression( whileStmt->get_condition(), *this ); |
---|
212 | delete whileStmt->get_condition(); |
---|
213 | whileStmt->set_condition( newExpr ); |
---|
214 | Visitor::visit( whileStmt ); |
---|
215 | } |
---|
216 | |
---|
217 | void |
---|
218 | Resolver::visit( ForStmt *forStmt ) |
---|
219 | { |
---|
220 | Expression *newExpr; |
---|
221 | if( forStmt->get_condition() ) { |
---|
222 | newExpr = findSingleExpression( forStmt->get_condition(), *this ); |
---|
223 | delete forStmt->get_condition(); |
---|
224 | forStmt->set_condition( newExpr ); |
---|
225 | } |
---|
226 | |
---|
227 | if( forStmt->get_increment() ) { |
---|
228 | newExpr = findVoidExpression( forStmt->get_increment(), *this ); |
---|
229 | delete forStmt->get_increment(); |
---|
230 | forStmt->set_increment( newExpr ); |
---|
231 | } |
---|
232 | |
---|
233 | Visitor::visit( forStmt ); |
---|
234 | } |
---|
235 | |
---|
236 | template< typename SwitchClass > |
---|
237 | void |
---|
238 | handleSwitchStmt( SwitchClass *switchStmt, SymTab::Indexer &visitor ) |
---|
239 | { |
---|
240 | Expression *newExpr; |
---|
241 | newExpr = findIntegralExpression( switchStmt->get_condition(), visitor ); |
---|
242 | delete switchStmt->get_condition(); |
---|
243 | switchStmt->set_condition( newExpr ); |
---|
244 | |
---|
245 | visitor.Visitor::visit( switchStmt ); |
---|
246 | } |
---|
247 | |
---|
248 | void |
---|
249 | Resolver::visit( SwitchStmt *switchStmt ) |
---|
250 | { |
---|
251 | handleSwitchStmt( switchStmt, *this ); |
---|
252 | } |
---|
253 | |
---|
254 | void |
---|
255 | Resolver::visit( ChooseStmt *switchStmt ) |
---|
256 | { |
---|
257 | handleSwitchStmt( switchStmt, *this ); |
---|
258 | } |
---|
259 | |
---|
260 | void |
---|
261 | Resolver::visit( CaseStmt *caseStmt ) |
---|
262 | { |
---|
263 | Visitor::visit( caseStmt ); |
---|
264 | } |
---|
265 | |
---|
266 | void |
---|
267 | Resolver::visit( ReturnStmt *returnStmt ) |
---|
268 | { |
---|
269 | if( returnStmt->get_expr() ) { |
---|
270 | CastExpr *castExpr = new CastExpr( returnStmt->get_expr() ); |
---|
271 | cloneAll( functionReturn, castExpr->get_results() ); |
---|
272 | Expression *newExpr = findSingleExpression( castExpr, *this ); |
---|
273 | delete castExpr; |
---|
274 | returnStmt->set_expr( newExpr ); |
---|
275 | } |
---|
276 | } |
---|
277 | |
---|
278 | void |
---|
279 | Resolver::visit( SingleInit *singleInit ) |
---|
280 | { |
---|
281 | if( singleInit->get_value() ) { |
---|
282 | CastExpr *castExpr = new CastExpr( singleInit->get_value(), initContext->clone() ); |
---|
283 | Expression *newExpr = findSingleExpression( castExpr, *this ); |
---|
284 | delete castExpr; |
---|
285 | singleInit->set_value( newExpr ); |
---|
286 | } |
---|
287 | singleInit->get_value()->accept( *this ); |
---|
288 | } |
---|
289 | |
---|
290 | } // namespace ResolvExpr |
---|