source: src/ResolvExpr/Resolver.cc@ de62360d

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 stuck-waitfor-destruct with_gc
Last change on this file since de62360d was de62360d, checked in by Peter A. Buhr <pabuhr@…>, 11 years ago

fix computed goto, fixed -std=, implicit typedefs for enum and aggregates, add _Noreturn _Thread_local

  • Property mode set to 100644
File size: 12.6 KB
RevLine 
[a32b204]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// Resolver.cc --
8//
9// Author : Richard C. Bilson
10// Created On : Sun May 17 12:17:01 2015
[5f2f2d7]11// Last Modified By : Peter A. Buhr
[de62360d]12// Last Modified On : Wed Jun 24 15:47:16 2015
13// Update Count : 50
[a32b204]14//
15
[51b73452]16#include "Resolver.h"
17#include "AlternativeFinder.h"
18#include "Alternative.h"
19#include "RenameVars.h"
20#include "ResolveTypeof.h"
21#include "SynTree/Statement.h"
22#include "SynTree/Type.h"
23#include "SynTree/Expression.h"
24#include "SynTree/Initializer.h"
25#include "SymTab/Indexer.h"
26#include "utility.h"
27
[d9a0e76]28#include <iostream>
29using namespace std;
[51b73452]30
[d9a0e76]31namespace ResolvExpr {
[a32b204]32 class Resolver : public SymTab::Indexer {
33 public:
34 Resolver() : SymTab::Indexer( false ), switchType( 0 ) {}
[51b73452]35
[a32b204]36 virtual void visit( FunctionDecl *functionDecl );
37 virtual void visit( ObjectDecl *functionDecl );
38 virtual void visit( TypeDecl *typeDecl );
[d9a0e76]39
[a32b204]40 virtual void visit( ExprStmt *exprStmt );
41 virtual void visit( IfStmt *ifStmt );
42 virtual void visit( WhileStmt *whileStmt );
43 virtual void visit( ForStmt *forStmt );
44 virtual void visit( SwitchStmt *switchStmt );
45 virtual void visit( ChooseStmt *switchStmt );
46 virtual void visit( CaseStmt *caseStmt );
[de62360d]47 virtual void visit( BranchStmt *branchStmt );
[a32b204]48 virtual void visit( ReturnStmt *returnStmt );
[d9a0e76]49
[a32b204]50 virtual void visit( SingleInit *singleInit );
51 virtual void visit( ListInit *listInit );
52 private:
53 std::list< Type * > functionReturn;
54 Type *initContext;
55 Type *switchType;
56 };
[d9a0e76]57
[a32b204]58 void resolve( std::list< Declaration * > translationUnit ) {
59 Resolver resolver;
60 acceptAll( translationUnit, resolver );
[d9a0e76]61#if 0
[a32b204]62 resolver.print( cerr );
63 for ( std::list< Declaration * >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
64 (*i)->print( std::cerr );
65 (*i)->accept( resolver );
66 } // for
[d9a0e76]67#endif
68 }
69
[a32b204]70 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ) {
71 TypeEnvironment env;
72 return resolveInVoidContext( expr, indexer, env );
[d9a0e76]73 }
[a32b204]74
75 namespace {
76 void finishExpr( Expression *expr, const TypeEnvironment &env ) {
77 expr->set_env( new TypeSubstitution );
78 env.makeSubstitution( *expr->get_env() );
79 }
80
81 Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
82 global_renamer.reset();
83 TypeEnvironment env;
84 Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
85 finishExpr( newExpr, env );
86 return newExpr;
87 }
[51b73452]88
[a32b204]89 Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
90 TypeEnvironment env;
91 AlternativeFinder finder( indexer, env );
92 finder.find( untyped );
[d9a0e76]93#if 0
[a32b204]94 if ( finder.get_alternatives().size() != 1 ) {
95 std::cout << "untyped expr is ";
96 untyped->print( std::cout );
97 std::cout << std::endl << "alternatives are:";
98 for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
99 i->print( std::cout );
100 } // for
101 } // if
[d9a0e76]102#endif
[a32b204]103 assert( finder.get_alternatives().size() == 1 );
104 Alternative &choice = finder.get_alternatives().front();
105 Expression *newExpr = choice.expr->clone();
106 finishExpr( newExpr, choice.env );
107 return newExpr;
108 }
[d9a0e76]109
[a32b204]110 bool isIntegralType( Type *type ) {
111 if ( dynamic_cast< EnumInstType * >( type ) ) {
112 return true;
113 } else if ( BasicType *bt = dynamic_cast< BasicType * >( type ) ) {
114 return bt->isInteger();
115 } else {
116 return false;
117 } // if
118 }
[51b73452]119
[a32b204]120 Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
121 TypeEnvironment env;
122 AlternativeFinder finder( indexer, env );
123 finder.find( untyped );
[d9a0e76]124#if 0
[a32b204]125 if ( finder.get_alternatives().size() != 1 ) {
126 std::cout << "untyped expr is ";
127 untyped->print( std::cout );
128 std::cout << std::endl << "alternatives are:";
129 for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
130 i->print( std::cout );
131 } // for
132 } // if
[d9a0e76]133#endif
[a32b204]134 Expression *newExpr = 0;
135 const TypeEnvironment *newEnv = 0;
136 for ( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
137 if ( i->expr->get_results().size() == 1 && isIntegralType( i->expr->get_results().front() ) ) {
138 if ( newExpr ) {
139 throw SemanticError( "Too many interpretations for case control expression", untyped );
140 } else {
141 newExpr = i->expr->clone();
142 newEnv = &i->env;
143 } // if
144 } // if
145 } // for
146 if ( ! newExpr ) {
147 throw SemanticError( "No interpretations for case control expression", untyped );
148 } // if
149 finishExpr( newExpr, *newEnv );
150 return newExpr;
151 }
[51b73452]152
[a32b204]153 }
[51b73452]154
[a32b204]155 void Resolver::visit( ObjectDecl *objectDecl ) {
156 Type *new_type = resolveTypeof( objectDecl->get_type(), *this );
157 objectDecl->set_type( new_type );
158 initContext = new_type;
159 SymTab::Indexer::visit( objectDecl );
[d1d17f5]160
161 if ( ArrayType * at = dynamic_cast< ArrayType * >( new_type ) ){
[30651b0]162 if ( at->get_dimension() ) {
163 BasicType arrayLenType = BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
164 CastExpr *castExpr = new CastExpr( at->get_dimension(), arrayLenType.clone() );
165 Expression *newExpr = findSingleExpression( castExpr, *this );
166 delete at->get_dimension();
167 at->set_dimension( newExpr );
168 }
[d1d17f5]169 }
[a32b204]170 }
[51b73452]171
[a32b204]172 void Resolver::visit( TypeDecl *typeDecl ) {
173 if ( typeDecl->get_base() ) {
174 Type *new_type = resolveTypeof( typeDecl->get_base(), *this );
175 typeDecl->set_base( new_type );
176 } // if
177 SymTab::Indexer::visit( typeDecl );
178 }
[51b73452]179
[a32b204]180 void Resolver::visit( FunctionDecl *functionDecl ) {
[d9a0e76]181#if 0
[a32b204]182 std::cout << "resolver visiting functiondecl ";
183 functionDecl->print( std::cout );
184 std::cout << std::endl;
[d9a0e76]185#endif
[a32b204]186 Type *new_type = resolveTypeof( functionDecl->get_type(), *this );
187 functionDecl->set_type( new_type );
188 std::list< Type * > oldFunctionReturn = functionReturn;
189 functionReturn.clear();
190 for ( std::list< DeclarationWithType * >::const_iterator i = functionDecl->get_functionType()->get_returnVals().begin(); i != functionDecl->get_functionType()->get_returnVals().end(); ++i ) {
191 functionReturn.push_back( (*i)->get_type() );
192 } // for
193 SymTab::Indexer::visit( functionDecl );
194 functionReturn = oldFunctionReturn;
195 }
[51b73452]196
[a32b204]197 void Resolver::visit( ExprStmt *exprStmt ) {
198 if ( exprStmt->get_expr() ) {
199 Expression *newExpr = findVoidExpression( exprStmt->get_expr(), *this );
200 delete exprStmt->get_expr();
201 exprStmt->set_expr( newExpr );
202 } // if
203 }
[51b73452]204
[a32b204]205 void Resolver::visit( IfStmt *ifStmt ) {
206 Expression *newExpr = findSingleExpression( ifStmt->get_condition(), *this );
207 delete ifStmt->get_condition();
208 ifStmt->set_condition( newExpr );
209 Visitor::visit( ifStmt );
210 }
[51b73452]211
[a32b204]212 void Resolver::visit( WhileStmt *whileStmt ) {
213 Expression *newExpr = findSingleExpression( whileStmt->get_condition(), *this );
214 delete whileStmt->get_condition();
215 whileStmt->set_condition( newExpr );
216 Visitor::visit( whileStmt );
217 }
[51b73452]218
[a32b204]219 void Resolver::visit( ForStmt *forStmt ) {
220 // SymTab::Indexer::visit( forStmt );
221 Expression *newExpr;
222 // for statements introduce a level of scope
223 enterScope();
224 maybeAccept( forStmt->get_initialization(), *this );
225 if ( forStmt->get_condition() ) {
226 newExpr = findSingleExpression( forStmt->get_condition(), *this );
227 delete forStmt->get_condition();
228 forStmt->set_condition( newExpr );
229 } // if
[51b73452]230
[a32b204]231 if ( forStmt->get_increment() ) {
232 newExpr = findVoidExpression( forStmt->get_increment(), *this );
233 delete forStmt->get_increment();
234 forStmt->set_increment( newExpr );
235 } // if
[b1a6d6b]236
[a32b204]237 maybeAccept( forStmt->get_condition(), *this );
238 maybeAccept( forStmt->get_increment(), *this );
239 maybeAccept( forStmt->get_body(), *this );
240 leaveScope();
241 }
[51b73452]242
[a32b204]243 template< typename SwitchClass >
244 void handleSwitchStmt( SwitchClass *switchStmt, SymTab::Indexer &visitor ) {
245 Expression *newExpr;
246 newExpr = findIntegralExpression( switchStmt->get_condition(), visitor );
247 delete switchStmt->get_condition();
248 switchStmt->set_condition( newExpr );
[51b73452]249
[a32b204]250 visitor.Visitor::visit( switchStmt );
251 }
[51b73452]252
[a32b204]253 void Resolver::visit( SwitchStmt *switchStmt ) {
254 handleSwitchStmt( switchStmt, *this );
255 }
[51b73452]256
[a32b204]257 void Resolver::visit( ChooseStmt *switchStmt ) {
258 handleSwitchStmt( switchStmt, *this );
259 }
[51b73452]260
[a32b204]261 void Resolver::visit( CaseStmt *caseStmt ) {
262 Visitor::visit( caseStmt );
263 }
[51b73452]264
[de62360d]265 void Resolver::visit( BranchStmt *branchStmt ) {
266 // must resolve the argument for a computed goto
267 if ( branchStmt->get_type() == BranchStmt::Goto ) { // check for computed goto statement
268 if ( NameExpr * arg = dynamic_cast< NameExpr * >( branchStmt->get_computedTarget() ) ) {
269 VoidType v = Type::Qualifiers(); // cast to void * for the alternative finder
270 PointerType pt( Type::Qualifiers(), v.clone() );
271 CastExpr * castExpr = new CastExpr( arg, pt.clone() );
272 Expression * newExpr = findSingleExpression( castExpr, *this ); // find best expression
273 branchStmt->set_target( newExpr );
274 } // if
275 } // if
276 }
277
[a32b204]278 void Resolver::visit( ReturnStmt *returnStmt ) {
279 if ( returnStmt->get_expr() ) {
280 CastExpr *castExpr = new CastExpr( returnStmt->get_expr() );
281 cloneAll( functionReturn, castExpr->get_results() );
282 Expression *newExpr = findSingleExpression( castExpr, *this );
283 delete castExpr;
284 returnStmt->set_expr( newExpr );
285 } // if
286 }
[51b73452]287
[a32b204]288 void Resolver::visit( SingleInit *singleInit ) {
289 if ( singleInit->get_value() ) {
[bdd516a]290#if 0
[a32b204]291 if (NameExpr * ne = dynamic_cast<NameExpr*>(singleInit->get_value())) {
292 string n = ne->get_name();
293 if (n == "0") {
294 initContext = new BasicType(Type::Qualifiers(),
295 BasicType::SignedInt);
296 } else {
297 DeclarationWithType * decl = lookupId(n);
298 initContext = decl->get_type();
299 }
300 } else if (ConstantExpr * e =
301 dynamic_cast<ConstantExpr*>(singleInit->get_value())) {
302 Constant *c = e->get_constant();
303 initContext = c->get_type();
304 } else {
305 assert(0);
306 }
[bdd516a]307#endif
[a32b204]308 CastExpr *castExpr = new CastExpr( singleInit->get_value(), initContext->clone() );
309 Expression *newExpr = findSingleExpression( castExpr, *this );
310 delete castExpr;
311 singleInit->set_value( newExpr );
312 } // if
[6c3744e]313// singleInit->get_value()->accept( *this );
[a32b204]314 }
[51b73452]315
[a32b204]316 void Resolver::visit( ListInit *listInit ) {
317 Visitor::visit(listInit);
[bdd516a]318#if 0
[a32b204]319 if ( ArrayType *at = dynamic_cast<ArrayType*>(initContext) ) {
320 std::list<Initializer *>::iterator iter( listInit->begin_initializers() );
321 for ( ; iter != listInit->end_initializers(); ++iter ) {
322 initContext = at->get_base();
323 (*iter)->accept( *this );
324 } // for
325 } else if ( StructInstType *st = dynamic_cast<StructInstType*>(initContext) ) {
326 StructDecl *baseStruct = st->get_baseStruct();
327 std::list<Declaration *>::iterator iter1( baseStruct->get_members().begin() );
328 std::list<Initializer *>::iterator iter2( listInit->begin_initializers() );
329 for ( ; iter1 != baseStruct->get_members().end() && iter2 != listInit->end_initializers(); ++iter2 ) {
330 if ( (*iter2)->get_designators().empty() ) {
331 DeclarationWithType *dt = dynamic_cast<DeclarationWithType *>( *iter1 );
332 initContext = dt->get_type();
333 (*iter2)->accept( *this );
334 ++iter1;
335 } else {
336 StructDecl *st = baseStruct;
337 iter1 = st->get_members().begin();
338 std::list<Expression *>::iterator iter3( (*iter2)->get_designators().begin() );
339 for ( ; iter3 != (*iter2)->get_designators().end(); ++iter3 ) {
340 NameExpr *key = dynamic_cast<NameExpr *>( *iter3 );
341 assert( key );
342 for ( ; iter1 != st->get_members().end(); ++iter1 ) {
343 if ( key->get_name() == (*iter1)->get_name() ) {
344 (*iter1)->print( cout );
345 cout << key->get_name() << endl;
346 ObjectDecl *fred = dynamic_cast<ObjectDecl *>( *iter1 );
347 assert( fred );
348 StructInstType *mary = dynamic_cast<StructInstType*>( fred->get_type() );
349 assert( mary );
350 st = mary->get_baseStruct();
351 iter1 = st->get_members().begin();
352 break;
353 } // if
354 } // for
355 } // for
356 ObjectDecl *fred = dynamic_cast<ObjectDecl *>( *iter1 );
357 assert( fred );
358 initContext = fred->get_type();
359 (*listInit->begin_initializers())->accept( *this );
360 } // if
361 } // for
362 } else if ( UnionInstType *st = dynamic_cast<UnionInstType*>(initContext) ) {
363 DeclarationWithType *dt = dynamic_cast<DeclarationWithType *>( *st->get_baseUnion()->get_members().begin() );
364 initContext = dt->get_type();
365 (*listInit->begin_initializers())->accept( *this );
[2c2242c]366 } // if
[bdd516a]367#endif
[a32b204]368 }
[51b73452]369} // namespace ResolvExpr
[a32b204]370
371// Local Variables: //
372// tab-width: 4 //
373// mode: c++ //
374// compile-command: "make install" //
375// End: //
Note: See TracBrowser for help on using the repository browser.