source: translator/ResolvExpr/Resolver.cc@ 1ead581

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 1ead581 was 51b73452, checked in by Peter A. Buhr <pabuhr@…>, 11 years ago

initial commit

  • Property mode set to 100644
File size: 7.9 KB
Line 
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
20namespace ResolvExpr {
21
22class Resolver : public SymTab::Indexer
23{
24public:
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
42private:
43 std::list< Type* > functionReturn;
44 Type* initContext;
45 Type *switchType;
46};
47
48void
49resolve( 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
59Expression *
60resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer )
61{
62 TypeEnvironment env;
63 return resolveInVoidContext( expr, indexer, env );
64}
65
66namespace {
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
153void
154Resolver::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
162void
163Resolver::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
172void
173Resolver::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
189void
190Resolver::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
199void
200Resolver::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
208void
209Resolver::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
217void
218Resolver::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
236template< typename SwitchClass >
237void
238handleSwitchStmt( 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
248void
249Resolver::visit( SwitchStmt *switchStmt )
250{
251 handleSwitchStmt( switchStmt, *this );
252}
253
254void
255Resolver::visit( ChooseStmt *switchStmt )
256{
257 handleSwitchStmt( switchStmt, *this );
258}
259
260void
261Resolver::visit( CaseStmt *caseStmt )
262{
263 Visitor::visit( caseStmt );
264}
265
266void
267Resolver::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
278void
279Resolver::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
Note: See TracBrowser for help on using the repository browser.