source: translator/ResolvExpr/Resolver.cc @ a0d9f94

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 a0d9f94 was 51b7345, checked in by Peter A. Buhr <pabuhr@…>, 10 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.