Changes in src/ResolvExpr/Resolver.cc [7b3f66b:a436947]
- File:
-
- 1 edited
-
src/ResolvExpr/Resolver.cc (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Resolver.cc
r7b3f66b ra436947 38 38 virtual void visit( ObjectDecl *functionDecl ); 39 39 virtual void visit( TypeDecl *typeDecl ); 40 virtual void visit( EnumDecl * enumDecl ); 40 41 41 42 virtual void visit( ArrayType * at ); … … 52 53 virtual void visit( BranchStmt *branchStmt ); 53 54 virtual void visit( ReturnStmt *returnStmt ); 55 virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt ); 54 56 55 57 virtual void visit( SingleInit *singleInit ); … … 65 67 Type *initContext; 66 68 Type *switchType; 69 bool inEnumDecl = false; 67 70 }; 68 71 … … 177 180 Type *temp = initContext; 178 181 initContext = new_type; 182 if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) { 183 // enumerator initializers should not use the enum type to initialize, since 184 // the enum type is still incomplete at this point. Use signed int instead. 185 initContext = new BasicType( Type::Qualifiers(), BasicType::SignedInt ); 186 } 179 187 SymTab::Indexer::visit( objectDecl ); 188 if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) { 189 // delete newly created signed int type 190 delete initContext; 191 } 180 192 initContext = temp; 181 193 } … … 215 227 SymTab::Indexer::visit( functionDecl ); 216 228 functionReturn = oldFunctionReturn; 229 } 230 231 void Resolver::visit( EnumDecl * enumDecl ) { 232 // in case we decide to allow nested enums 233 bool oldInEnumDecl = inEnumDecl; 234 inEnumDecl = true; 235 SymTab::Indexer::visit( enumDecl ); 236 inEnumDecl = oldInEnumDecl; 217 237 } 218 238 … … 492 512 } catch ( SemanticError ) { 493 513 // no alternatives for the constructor initializer - fallback on C-style initializer 494 // xxx - not sure if this makes a ton of sense - should maybe never be able to have this situation?514 // xxx - not sure if this makes a ton of sense - should maybe never be able to have this situation? 495 515 fallbackInit( ctorInit ); 496 516 return; … … 513 533 } 514 534 } 535 536 void Resolver::visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) { 537 // before resolving ctor/dtor, need to remove type qualifiers from the first argument (the object being constructed). 538 // Do this through a cast expression to greatly simplify the code. 539 Expression * callExpr = InitTweak::getCtorDtorCall( impCtorDtorStmt ); 540 assert( callExpr ); 541 Expression *& constructee = InitTweak::getCallArg( callExpr, 0 ); 542 Type * type = 0; 543 544 // need to find the type of the first argument, which is unfortunately not uniform since array construction 545 // includes an untyped '+' expression. 546 if ( UntypedExpr * plusExpr = dynamic_cast< UntypedExpr * >( constructee ) ) { 547 // constructee is <array>+<index> 548 // get Variable <array>, then get the base type of the VariableExpr - this is the type that needs to be fixed 549 Expression * arr = InitTweak::getCallArg( plusExpr, 0 ); 550 assert( dynamic_cast< VariableExpr * >( arr ) ); 551 assert( arr && arr->get_results().size() == 1 ); 552 type = arr->get_results().front()->clone(); 553 } else { 554 // otherwise, constructing a plain object, which means the object's address is being taken. 555 // Need to get the type of the VariableExpr object, because the AddressExpr is rebuilt and uses the 556 // type of the VariableExpr to do so. 557 assert( constructee->get_results().size() == 1 ); 558 AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee ); 559 assert( addrExpr && addrExpr->get_results().size() == 1); 560 type = addrExpr->get_results().front()->clone(); 561 } 562 // cast to T* with qualifiers removed. 563 // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument 564 // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever 565 // remove lvalue as a qualifier, this can change to 566 // type->get_qualifiers() = Type::Qualifiers(); 567 Type * base = InitTweak::getPointerBase( type ); 568 assert( base ); 569 base->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true); 570 // if pointer has lvalue qualifier, cast won't appear in output 571 type->set_isLvalue( false ); 572 constructee = new CastExpr( constructee, type ); 573 574 // finally, resolve the ctor/dtor 575 impCtorDtorStmt->get_callStmt()->accept( *this ); 576 } 515 577 } // namespace ResolvExpr 516 578
Note:
See TracChangeset
for help on using the changeset viewer.