Changeset 64071c2
- Timestamp:
- Jun 6, 2016, 2:16:00 PM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 7baed7d
- Parents:
- 321a2481
- Location:
- src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r321a2481 r64071c2 257 257 std::list< Expression* >::iterator arg = applicationExpr->get_args().begin(); 258 258 switch ( opInfo.type ) { 259 case OT_CTOR:260 case OT_DTOR:261 {262 // if the first argument's type is const then GCC complains. In this263 // case, output an explicit ctor/dtor call and exit, rather than following264 // the normal path265 assert( arg != applicationExpr->get_args().end() );266 assert( (*arg)->get_results().size() >= 1 );267 Type * baseType = InitTweak::getPointerBase( (*arg)->get_results().front() );268 if ( baseType->get_isConst() ) {269 // cast away the qualifiers, to eliminate warnings270 Type * newType = baseType->clone();271 newType->get_qualifiers() = Type::Qualifiers();272 *arg = new CastExpr( *arg, new PointerType( Type::Qualifiers(), newType ) );273 varExpr->accept( *this );274 output << "(";275 genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );276 output << ")";277 return;278 }279 }280 // intentional fallthrough - instrinsic ctor/dtor for non-const objects should281 // be handled the same way as assignment282 259 case OT_PREFIXASSIGN: 283 260 case OT_POSTFIXASSIGN: 284 261 case OT_INFIXASSIGN: 262 case OT_CTOR: 263 case OT_DTOR: 285 264 { 286 265 assert( arg != applicationExpr->get_args().end() ); … … 324 303 if ( applicationExpr->get_args().size() == 1 ) { 325 304 // the expression fed into a single parameter constructor or destructor 326 // may contain side effects - output as a voidexpression327 output << "( (void)(";305 // may contain side effects, so must still output this expression 306 output << "("; 328 307 (*arg++)->accept( *this ); 329 output << ") )/* " << opInfo.inputName << " */";308 output << ") /* " << opInfo.inputName << " */"; 330 309 } else if ( applicationExpr->get_args().size() == 2 ) { 331 310 // intrinsic two parameter constructors are essentially bitwise assignment … … 409 388 if ( untypedExpr->get_args().size() == 1 ) { 410 389 // the expression fed into a single parameter constructor or destructor 411 // may contain side effects - output as a voidexpression412 output << "( (void)(";390 // may contain side effects, so must still output this expression 391 output << "("; 413 392 (*arg++)->accept( *this ); 414 output << ") )/* " << opInfo.inputName << " */";393 output << ") /* " << opInfo.inputName << " */"; 415 394 } else if ( untypedExpr->get_args().size() == 2 ) { 416 395 // intrinsic two parameter constructors are essentially bitwise assignment -
src/InitTweak/InitTweak.cc
r321a2481 r64071c2 7 7 8 8 namespace InitTweak { 9 10 11 12 13 14 15 16 17 18 19 20 9 namespace { 10 class HasDesignations : public Visitor { 11 public: 12 bool hasDesignations = false; 13 template<typename Init> 14 void handleInit( Init * init ) { 15 if ( ! init->get_designators().empty() ) hasDesignations = true; 16 else Visitor::visit( init ); 17 } 18 virtual void visit( SingleInit * singleInit ) { handleInit( singleInit); } 19 virtual void visit( ListInit * listInit ) { handleInit( listInit); } 20 }; 21 21 22 23 24 25 26 27 28 22 class InitExpander : public Visitor { 23 public: 24 InitExpander() {} 25 virtual void visit( SingleInit * singleInit ); 26 virtual void visit( ListInit * listInit ); 27 std::list< Expression * > argList; 28 }; 29 29 30 31 32 30 void InitExpander::visit( SingleInit * singleInit ) { 31 argList.push_back( singleInit->get_value()->clone() ); 32 } 33 33 34 35 36 37 38 39 40 41 34 void InitExpander::visit( ListInit * listInit ) { 35 // xxx - for now, assume no nested list inits 36 std::list<Initializer*>::iterator it = listInit->begin_initializers(); 37 for ( ; it != listInit->end_initializers(); ++it ) { 38 (*it)->accept( *this ); 39 } 40 } 41 } 42 42 43 44 45 46 47 43 std::list< Expression * > makeInitList( Initializer * init ) { 44 InitExpander expander; 45 maybeAccept( init, expander ); 46 return expander.argList; 47 } 48 48 49 50 51 52 53 49 bool isDesignated( Initializer * init ) { 50 HasDesignations finder; 51 maybeAccept( init, finder ); 52 return finder.hasDesignations; 53 } 54 54 55 56 57 58 59 60 55 bool tryConstruct( ObjectDecl * objDecl ) { 56 return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) && 57 (objDecl->get_init() == NULL || 58 ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() )) && 59 ! isDesignated( objDecl->get_init() ); 60 } 61 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 62 Expression * getCtorDtorCall( Statement * stmt ) { 63 if ( stmt == NULL ) return NULL; 64 if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) { 65 return exprStmt->get_expr(); 66 } else if ( CompoundStmt * compoundStmt = dynamic_cast< CompoundStmt * >( stmt ) ) { 67 // could also be a compound statement with a loop, in the case of an array 68 assert( compoundStmt->get_kids().size() == 2 ); // loop variable and loop 69 ForStmt * forStmt = dynamic_cast< ForStmt * >( compoundStmt->get_kids().back() ); 70 assert( forStmt && forStmt->get_body() ); 71 return getCtorDtorCall( forStmt->get_body() ); 72 } if ( ImplicitCtorDtorStmt * impCtorDtorStmt = dynamic_cast< ImplicitCtorDtorStmt * > ( stmt ) ) { 73 return getCtorDtorCall( impCtorDtorStmt->get_callStmt() ); 74 } else { 75 // should never get here 76 assert( false && "encountered unknown call statement" ); 77 } 78 } 79 79 80 81 82 83 84 85 86 87 88 89 90 91 92 80 bool isInstrinsicSingleArgCallStmt( Statement * stmt ) { 81 Expression * callExpr = getCtorDtorCall( stmt ); 82 if ( ! callExpr ) return false; 83 ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( callExpr ); 84 assert( appExpr ); 85 VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() ); 86 assert( function ); 87 // check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor 88 // will call all member dtors, and some members may have a user defined dtor. 89 FunctionType * funcType = GenPoly::getFunctionType( function->get_var()->get_type() ); 90 assert( funcType ); 91 return function->get_var()->get_linkage() == LinkageSpec::Intrinsic && funcType->get_parameters().size() == 1; 92 } 93 93 94 95 96 Expression *callArg( CallExpr * callExpr, unsigned int pos ) {97 98 for ( Expression *arg : callExpr->get_args() ) {99 100 101 102 103 104 94 namespace { 95 template<typename CallExpr> 96 Expression *& callArg( CallExpr * callExpr, unsigned int pos ) { 97 if ( pos >= callExpr->get_args().size() ) assert( false && "asking for argument that doesn't exist. Return NULL/throw exception?" ); 98 for ( Expression *& arg : callExpr->get_args() ) { 99 if ( pos == 0 ) return arg; 100 pos--; 101 } 102 assert( false ); 103 } 104 } 105 105 106 Expression *getCallArg( Expression * callExpr, unsigned int pos ) {107 108 109 110 111 112 113 114 106 Expression *& getCallArg( Expression * callExpr, unsigned int pos ) { 107 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( callExpr ) ) { 108 return callArg( appExpr, pos ); 109 } else if ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * >( callExpr ) ) { 110 return callArg( untypedExpr, pos ); 111 } else { 112 assert( false && "Unexpected expression type passed to getCallArg" ); 113 } 114 } 115 115 116 117 118 119 120 121 122 123 124 125 126 127 128 116 namespace { 117 template<typename CallExpr> 118 std::string funcName( CallExpr * expr ) { 119 Expression * func = expr->get_function(); 120 if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( func ) ) { 121 return nameExpr->get_name(); 122 } else if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( func ) ) { 123 return varExpr->get_var()->get_name(); 124 } else { 125 assert( false && "Unexpected expression type being called as a function in call expression" ); 126 } 127 } 128 } 129 129 130 131 132 133 134 135 136 137 138 130 std::string getFunctionName( Expression * expr ) { 131 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr ) ) { 132 return funcName( appExpr ); 133 } else if ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * > ( expr ) ) { 134 return funcName( untypedExpr ); 135 } else { 136 assert( false && "Unexpected expression type passed to getFunctionName" ); 137 } 138 } 139 139 140 141 142 143 144 145 146 147 148 140 Type * getPointerBase( Type * type ) { 141 if ( PointerType * ptrType = dynamic_cast< PointerType * >( type ) ) { 142 return ptrType->get_base(); 143 } else if ( ArrayType * arrayType = dynamic_cast< ArrayType * >( type ) ) { 144 return arrayType->get_base(); 145 } else { 146 return NULL; 147 } 148 } 149 149 150 Type * isPointerType( Type * type ) { 151 if ( getPointerBase( type ) ) return type; 152 else return NULL; 153 } 150 154 } -
src/InitTweak/InitTweak.h
r321a2481 r64071c2 47 47 48 48 /// returns the argument to a call expression in position N indexed from 0 49 Expression * getCallArg( Expression * callExpr, unsigned int pos );49 Expression *& getCallArg( Expression * callExpr, unsigned int pos ); 50 50 51 /// returns the base type of a PointerType or ArrayType 51 /// returns the base type of a PointerType or ArrayType, else returns NULL 52 52 Type * getPointerBase( Type * ); 53 54 /// returns the argument if it is a PointerType or ArrayType, else returns NULL 55 Type * isPointerType( Type * ); 53 56 } // namespace 54 57 -
src/ResolvExpr/Resolver.cc
r321a2481 r64071c2 516 516 517 517 void Resolver::visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) { 518 // this code is fairly gross. If VariableExpr didn't have its own results list then this could be cleaned up a bit 519 // by remembering the ObjectDecl in the ImplicitCtorDtorStmt and changing the ObjectDecl's type temporarily, but currently 520 // VariableExprs have their own type list which is manipulated in AlternativeFinder (e.g. in inferRecursive). 521 522 // before resolving ctor/dtor, need to remove type qualifiers from the first argument (the object being constructed) 518 // before resolving ctor/dtor, need to remove type qualifiers from the first argument (the object being constructed). 519 // Do this through a cast expression to greatly simplify the code. 523 520 Expression * callExpr = InitTweak::getCtorDtorCall( impCtorDtorStmt ); 524 521 assert( callExpr ); 525 Expression * constructee = InitTweak::getCallArg( callExpr, 0 );522 Expression *& constructee = InitTweak::getCallArg( callExpr, 0 ); 526 523 Type * type = 0; 524 525 // need to find the type of the first argument, which is unfortunately not uniform since array construction 526 // includes an untyped '+' expression. 527 527 if ( UntypedExpr * plusExpr = dynamic_cast< UntypedExpr * >( constructee ) ) { 528 528 // constructee is <array>+<index> … … 531 531 assert( dynamic_cast< VariableExpr * >( arr ) ); 532 532 assert( arr && arr->get_results().size() == 1 ); 533 type = InitTweak::getPointerBase( arr->get_results().front() ); 534 assert( type ); 533 type = arr->get_results().front()->clone(); 535 534 } else { 536 535 // otherwise, constructing a plain object, which means the object's address is being taken. … … 539 538 assert( constructee->get_results().size() == 1 ); 540 539 AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee ); 541 assert( addrExpr ); 542 VariableExpr * varExpr = dynamic_cast< VariableExpr * >( addrExpr->get_arg() ); 543 assert( varExpr && varExpr->get_results().size() == 1 ); 544 type = varExpr->get_results().front(); 545 } 546 // remember qualifiers so they can be replaced 547 Type::Qualifiers qualifiers = type->get_qualifiers(); 548 540 assert( addrExpr && addrExpr->get_results().size() == 1); 541 type = addrExpr->get_results().front()->clone(); 542 } 543 // cast to T* with qualifiers removed. 549 544 // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument 550 545 // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever 551 546 // remove lvalue as a qualifier, this can change to 552 547 // type->get_qualifiers() = Type::Qualifiers(); 553 type->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true); 548 Type * base = InitTweak::getPointerBase( type ); 549 assert( base ); 550 base->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true); 551 // if pointer has lvalue qualifier, cast won't appear in output 552 type->set_isLvalue( false ); 553 constructee = new CastExpr( constructee, type ); 554 554 555 555 // finally, resolve the ctor/dtor 556 556 impCtorDtorStmt->get_callStmt()->accept( *this ); 557 558 // reset type qualifiers, but first need to figure out where everything is again559 // because the expressions are often changed by the resolver.560 callExpr = InitTweak::getCtorDtorCall( impCtorDtorStmt );561 assert( callExpr );562 constructee = InitTweak::getCallArg( callExpr, 0 );563 if ( ApplicationExpr * plusExpr = dynamic_cast< ApplicationExpr * >( constructee ) ) {564 // constructee is <array>+<index>565 // get Variable <array>, then get the base type of the VariableExpr - this is the type that needs to be fixed566 Expression * arr = InitTweak::getCallArg( plusExpr, 0 );567 assert( dynamic_cast< VariableExpr * >( arr ) );568 assert( arr && arr->get_results().size() == 1 );569 type = InitTweak::getPointerBase( arr->get_results().front() );570 assert( type );571 type->get_qualifiers() = qualifiers;572 } else {573 // otherwise constructing a plain object574 // replace qualifiers on AddressExpr and on inner VariableExpr575 assert( constructee->get_results().size() == 1 );576 AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee );577 assert( addrExpr );578 type = InitTweak::getPointerBase( addrExpr->get_results().front() );579 assert( type );580 type->get_qualifiers() = qualifiers;581 582 VariableExpr * varExpr = dynamic_cast< VariableExpr * >( addrExpr->get_arg() );583 assert( varExpr && varExpr->get_results().size() == 1 );584 type = varExpr->get_results().front();585 type->get_qualifiers() = qualifiers;586 }587 557 } 588 558 } // namespace ResolvExpr
Note: See TracChangeset
for help on using the changeset viewer.