Changes in src/ResolvExpr/Resolver.cc [679864e1:f9cebb5]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Resolver.cc
r679864e1 rf9cebb5 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Resolver.cc -- 7 // Resolver.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 12:17:01 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Tue Sep 15 16:24:07 201513 // Update Count : 18111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jul 12 17:45:42 2016 13 // Update Count : 204 14 14 // 15 15 … … 24 24 #include "SynTree/Initializer.h" 25 25 #include "SymTab/Indexer.h" 26 #include "utility.h" 26 #include "SymTab/Autogen.h" 27 #include "Common/utility.h" 28 #include "InitTweak/InitTweak.h" 27 29 28 30 #include <iostream> … … 33 35 public: 34 36 Resolver() : SymTab::Indexer( false ), switchType( 0 ) {} 35 37 36 38 virtual void visit( FunctionDecl *functionDecl ); 37 39 virtual void visit( ObjectDecl *functionDecl ); 38 40 virtual void visit( TypeDecl *typeDecl ); 41 virtual void visit( EnumDecl * enumDecl ); 39 42 40 43 virtual void visit( ArrayType * at ); 44 virtual void visit( PointerType * at ); 41 45 42 46 virtual void visit( ExprStmt *exprStmt ); … … 47 51 virtual void visit( ForStmt *forStmt ); 48 52 virtual void visit( SwitchStmt *switchStmt ); 49 virtual void visit( ChooseStmt *switchStmt );50 53 virtual void visit( CaseStmt *caseStmt ); 51 54 virtual void visit( BranchStmt *branchStmt ); … … 54 57 virtual void visit( SingleInit *singleInit ); 55 58 virtual void visit( ListInit *listInit ); 59 virtual void visit( ConstructorInit *ctorInit ); 56 60 private: 57 61 typedef std::list< Initializer * >::iterator InitIterator; 58 62 63 template< typename PtrType > 64 void handlePtrType( PtrType * type ); 65 59 66 void resolveAggrInit( AggregateDecl *, InitIterator &, InitIterator & ); 60 67 void resolveSingleAggrInit( Declaration *, InitIterator &, InitIterator & ); 61 68 void fallbackInit( ConstructorInit * ctorInit ); 62 69 std::list< Type * > functionReturn; 63 70 Type *initContext; 64 71 Type *switchType; 72 bool inEnumDecl = false; 65 73 }; 66 74 … … 82 90 } 83 91 92 84 93 namespace { 85 94 void finishExpr( Expression *expr, const TypeEnvironment &env ) { … … 87 96 env.makeSubstitution( *expr->get_env() ); 88 97 } 89 90 Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) { 91 global_renamer.reset(); 92 TypeEnvironment env; 93 Expression *newExpr = resolveInVoidContext( untyped, indexer, env ); 94 finishExpr( newExpr, env ); 95 return newExpr; 96 } 97 98 } // namespace 99 100 Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) { 101 global_renamer.reset(); 102 TypeEnvironment env; 103 Expression *newExpr = resolveInVoidContext( untyped, indexer, env ); 104 finishExpr( newExpr, env ); 105 return newExpr; 106 } 107 108 namespace { 98 109 Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) { 99 110 TypeEnvironment env; … … 126 137 } // if 127 138 } 128 139 129 140 Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) { 130 141 TypeEnvironment env; … … 159 170 return newExpr; 160 171 } 161 162 } 163 172 173 } 174 164 175 void Resolver::visit( ObjectDecl *objectDecl ) { 165 176 Type *new_type = resolveTypeof( objectDecl->get_type(), *this ); 166 177 objectDecl->set_type( new_type ); 178 // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that class-variable 179 // initContext is changed multiple time because the LHS is analysed twice. The second analysis changes 180 // initContext because of a function type can contain object declarations in the return and parameter types. So 181 // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting 182 // the RHS. 183 Type *temp = initContext; 167 184 initContext = new_type; 185 if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) { 186 // enumerator initializers should not use the enum type to initialize, since 187 // the enum type is still incomplete at this point. Use signed int instead. 188 initContext = new BasicType( Type::Qualifiers(), BasicType::SignedInt ); 189 } 168 190 SymTab::Indexer::visit( objectDecl ); 191 if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) { 192 // delete newly created signed int type 193 delete initContext; 194 } 195 initContext = temp; 196 } 197 198 template< typename PtrType > 199 void Resolver::handlePtrType( PtrType * type ) { 200 if ( type->get_dimension() ) { 201 CastExpr *castExpr = new CastExpr( type->get_dimension(), SymTab::SizeType->clone() ); 202 Expression *newExpr = findSingleExpression( castExpr, *this ); 203 delete type->get_dimension(); 204 type->set_dimension( newExpr ); 205 } 169 206 } 170 207 171 208 void Resolver::visit( ArrayType * at ) { 172 if ( at->get_dimension() ) { 173 BasicType arrayLenType = BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 174 CastExpr *castExpr = new CastExpr( at->get_dimension(), arrayLenType.clone() ); 175 Expression *newExpr = findSingleExpression( castExpr, *this ); 176 delete at->get_dimension(); 177 at->set_dimension( newExpr ); 178 } 209 handlePtrType( at ); 179 210 Visitor::visit( at ); 211 } 212 213 void Resolver::visit( PointerType * pt ) { 214 handlePtrType( pt ); 215 Visitor::visit( pt ); 180 216 } 181 217 … … 205 241 } 206 242 243 void Resolver::visit( EnumDecl * enumDecl ) { 244 // in case we decide to allow nested enums 245 bool oldInEnumDecl = inEnumDecl; 246 inEnumDecl = true; 247 SymTab::Indexer::visit( enumDecl ); 248 inEnumDecl = oldInEnumDecl; 249 } 250 207 251 void Resolver::visit( ExprStmt *exprStmt ) { 208 252 if ( exprStmt->get_expr() ) { … … 251 295 forStmt->set_condition( newExpr ); 252 296 } // if 253 297 254 298 if ( forStmt->get_increment() ) { 255 299 Expression * newExpr = findVoidExpression( forStmt->get_increment(), *this ); … … 265 309 delete switchStmt->get_condition(); 266 310 switchStmt->set_condition( newExpr ); 267 311 268 312 visitor.Visitor::visit( switchStmt ); 269 313 } 270 314 271 315 void Resolver::visit( SwitchStmt *switchStmt ) { 272 handleSwitchStmt( switchStmt, *this );273 }274 275 void Resolver::visit( ChooseStmt *switchStmt ) {276 316 handleSwitchStmt( switchStmt, *this ); 277 317 } … … 307 347 bool isCharType( T t ) { 308 348 if ( BasicType * bt = dynamic_cast< BasicType * >( t ) ) { 309 return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar || 349 return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar || 310 350 bt->get_kind() == BasicType::UnsignedChar; 311 351 } … … 319 359 string n = ne->get_name(); 320 360 if (n == "0") { 321 initContext = new BasicType(Type::Qualifiers(), 361 initContext = new BasicType(Type::Qualifiers(), 322 362 BasicType::SignedInt); 323 363 } else { 324 DeclarationWithType * decl = lookupId( n);364 DeclarationWithType * decl = lookupId( n ); 325 365 initContext = decl->get_type(); 326 366 } 327 } else if (ConstantExpr * e = 367 } else if (ConstantExpr * e = 328 368 dynamic_cast<ConstantExpr*>(singleInit->get_value())) { 329 369 Constant *c = e->get_constant(); … … 344 384 if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_results().front() ) ) { 345 385 if ( isCharType( pt->get_base() ) ) { 346 // strip cast if we're initializing a char[] with a char *, e.g. 347 // char x[] = "hello"; 386 // strip cast if we're initializing a char[] with a char *, e.g. char x[] = "hello"; 348 387 CastExpr *ce = dynamic_cast< CastExpr * >( newExpr ); 349 388 singleInit->set_value( ce->get_arg() ); 350 389 ce->set_arg( NULL ); 351 delete ce; 390 delete ce; 352 391 } 353 392 } … … 396 435 397 436 void Resolver::visit( ListInit * listInit ) { 398 InitIterator iter = listInit->begin _initializers();399 InitIterator end = listInit->end _initializers();437 InitIterator iter = listInit->begin(); 438 InitIterator end = listInit->end(); 400 439 401 440 if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) { … … 407 446 } else if ( StructInstType * st = dynamic_cast< StructInstType * >( initContext ) ) { 408 447 resolveAggrInit( st->get_baseStruct(), iter, end ); 409 } else if ( UnionInstType * 448 } else if ( UnionInstType *st = dynamic_cast< UnionInstType * >( initContext ) ) { 410 449 resolveAggrInit( st->get_baseUnion(), iter, end ); 411 } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) {412 // try again...413 initContext = tt->get_baseType()->get_base();414 visit(listInit);415 450 } else { 416 assert( dynamic_cast< BasicType * >( initContext ) );417 451 // basic types are handled here 418 452 Visitor::visit( listInit ); … … 470 504 #endif 471 505 } 506 507 // ConstructorInit - fall back on C-style initializer 508 void Resolver::fallbackInit( ConstructorInit * ctorInit ) { 509 // could not find valid constructor, or found an intrinsic constructor 510 // fall back on C-style initializer 511 delete ctorInit->get_ctor(); 512 ctorInit->set_ctor( NULL ); 513 delete ctorInit->get_dtor(); 514 ctorInit->set_dtor( NULL ); 515 maybeAccept( ctorInit->get_init(), *this ); 516 } 517 518 void Resolver::visit( ConstructorInit *ctorInit ) { 519 try { 520 maybeAccept( ctorInit->get_ctor(), *this ); 521 maybeAccept( ctorInit->get_dtor(), *this ); 522 } catch ( SemanticError ) { 523 // no alternatives for the constructor initializer - fallback on C-style initializer 524 // xxx - not sure if this makes a ton of sense - should maybe never be able to have this situation? 525 fallbackInit( ctorInit ); 526 return; 527 } 528 529 // found a constructor - can get rid of C-style initializer 530 delete ctorInit->get_init(); 531 ctorInit->set_init( NULL ); 532 533 // intrinsic single parameter constructors and destructors do nothing. Since this was 534 // implicitly generated, there's no way for it to have side effects, so get rid of it 535 // to clean up generated code. 536 if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->get_ctor() ) ) { 537 delete ctorInit->get_ctor(); 538 ctorInit->set_ctor( NULL ); 539 } 540 541 // xxx - todo 542 // if ( InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) { 543 // // can reduce the constructor down to a SingleInit using the 544 // // second argument from the ctor call 545 // } 546 547 if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->get_dtor() ) ) { 548 delete ctorInit->get_dtor(); 549 ctorInit->set_dtor( NULL ); 550 } 551 } 472 552 } // namespace ResolvExpr 473 553
Note:
See TracChangeset
for help on using the changeset viewer.