Changeset 6840e7c for src/InitTweak/FixInit.cc
- Timestamp:
- Oct 19, 2017, 12:01:04 PM (7 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 837ce06
- Parents:
- b96ec83 (diff), a15b72c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixInit.cc
rb96ec83 r6840e7c 94 94 /// true if type does not need to be copy constructed to ensure correctness 95 95 bool skipCopyConstruct( Type * type ); 96 void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr );96 void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr, Type * formal ); 97 97 void destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr ); 98 98 … … 259 259 260 260 GenStructMemberCalls::generate( translationUnit ); 261 261 262 // xxx - ctor expansion currently has to be after FixCopyCtors, because there is currently a 262 263 // hack in the way untyped assignments are generated, where the first argument cannot have … … 288 289 for ( std::list< Declaration * >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) { 289 290 try { 290 *i =maybeMutate( *i, fixer );291 maybeMutate( *i, fixer ); 291 292 translationUnit.splice( i, fixer.pass.staticDtorDecls ); 292 293 } catch( SemanticError &e ) { … … 322 323 323 324 Expression * InsertImplicitCalls::postmutate( ApplicationExpr * appExpr ) { 324 assert( appExpr );325 326 325 if ( VariableExpr * function = dynamic_cast< VariableExpr * > ( appExpr->get_function() ) ) { 327 if ( LinkageSpec::isBuiltin( function->get_var()->get_linkage() )) {326 if ( function->var->linkage.is_builtin ) { 328 327 // optimization: don't need to copy construct in order to call intrinsic functions 329 328 return appExpr; … … 331 330 FunctionType * ftype = dynamic_cast< FunctionType * >( GenPoly::getFunctionType( funcDecl->get_type() ) ); 332 331 assertf( ftype, "Function call without function type: %s", toString( funcDecl ).c_str() ); 333 if ( CodeGen::isConstructor( funcDecl->get_name() ) && ftype-> get_parameters().size() == 2 ) {334 Type * t1 = getPointerBase( ftype-> get_parameters().front()->get_type() );335 Type * t2 = ftype-> get_parameters().back()->get_type();332 if ( CodeGen::isConstructor( funcDecl->get_name() ) && ftype->parameters.size() == 2 ) { 333 Type * t1 = getPointerBase( ftype->parameters.front()->get_type() ); 334 Type * t2 = ftype->parameters.back()->get_type(); 336 335 assert( t1 ); 337 336 … … 366 365 ImplicitCtorDtorStmt * stmt = genCtorDtor( fname, var, cpArg ); 367 366 ExprStmt * exprStmt = strict_dynamic_cast< ExprStmt * >( stmt->get_callStmt() ); 368 Expression * untyped = exprStmt->get_expr(); 367 Expression * resolved = exprStmt->expr; 368 exprStmt->expr = nullptr; // take ownership of expr 369 369 370 370 // resolve copy constructor 371 371 // should only be one alternative for copy ctor and dtor expressions, since all arguments are fixed 372 372 // (VariableExpr and already resolved expression) 373 CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; )374 Expression * resolved = ResolvExpr::findVoidExpression( untyped, indexer );373 CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << resolved << std::endl; ) 374 ResolvExpr::findVoidExpression( resolved, indexer ); 375 375 assert( resolved ); 376 376 if ( resolved->get_env() ) { … … 380 380 resolved->set_env( nullptr ); 381 381 } // if 382 383 382 delete stmt; 384 383 return resolved; 385 384 } 386 385 387 void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ) {386 void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr, Type * formal ) { 388 387 static UniqueName tempNamer("_tmp_cp"); 389 388 assert( env ); 390 389 CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *env << std::endl; ) 391 assert( arg-> has_result());392 Type * result = arg-> get_result();390 assert( arg->result ); 391 Type * result = arg->result; 393 392 if ( skipCopyConstruct( result ) ) return; // skip certain non-copyable types 394 393 395 // type may involve type variables, so apply type substitution to get temporary variable's actual type 394 // type may involve type variables, so apply type substitution to get temporary variable's actual type. 395 // Use applyFree so that types bound in function pointers are not substituted, e.g. in forall(dtype T) void (*)(T). 396 396 result = result->clone(); 397 env->apply ( result );397 env->applyFree( result ); 398 398 ObjectDecl * tmp = ObjectDecl::newObject( "__tmp", result, nullptr ); 399 399 tmp->get_type()->set_const( false ); … … 406 406 // if the chosen constructor is intrinsic, the copy is unnecessary, so 407 407 // don't create the temporary and don't call the copy constructor 408 VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() ); 409 assert( function ); 410 if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) return; 408 VariableExpr * function = strict_dynamic_cast< VariableExpr * >( appExpr->function ); 409 if ( function->var->linkage == LinkageSpec::Intrinsic ) { 410 // arguments that need to be boxed need a temporary regardless of whether the copy constructor is intrinsic, 411 // so that the object isn't changed inside of the polymorphic function 412 if ( ! GenPoly::needsBoxing( formal, result, impCpCtorExpr->callExpr, env ) ) return; 413 } 411 414 } 412 415 … … 416 419 // replace argument to function call with temporary 417 420 arg = new CommaExpr( cpCtor, new VariableExpr( tmp ) ); 418 impCpCtorExpr-> get_tempDecls().push_back( tmp );419 impCpCtorExpr-> get_dtors().push_front( makeCtorDtor( "^?{}", tmp ) );421 impCpCtorExpr->tempDecls.push_back( tmp ); 422 impCpCtorExpr->dtors.push_front( makeCtorDtor( "^?{}", tmp ) ); 420 423 } 421 424 … … 427 430 CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; ) 428 431 429 ApplicationExpr * appExpr = impCpCtorExpr-> get_callExpr();432 ApplicationExpr * appExpr = impCpCtorExpr->callExpr; 430 433 431 434 // take each argument and attempt to copy construct it. 432 for ( Expression * & arg : appExpr->get_args() ) { 433 copyConstructArg( arg, impCpCtorExpr ); 435 FunctionType * ftype = GenPoly::getFunctionType( appExpr->function->result ); 436 assert( ftype ); 437 auto & params = ftype->parameters; 438 auto iter = params.begin(); 439 for ( Expression * & arg : appExpr->args ) { 440 Type * formal = nullptr; 441 if ( iter != params.end() ) { 442 DeclarationWithType * param = *iter++; 443 formal = param->get_type(); 444 } 445 446 copyConstructArg( arg, impCpCtorExpr, formal ); 434 447 } // for 435 448 … … 437 450 // initialized with the return value and is destructed later 438 451 // xxx - handle named return values? 439 Type * result = appExpr-> get_result();452 Type * result = appExpr->result; 440 453 if ( ! result->isVoid() ) { 441 454 static UniqueName retNamer("_tmp_cp_ret"); … … 443 456 env->apply( result ); 444 457 ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr ); 445 ret-> get_type()->set_const( false );446 impCpCtorExpr-> get_returnDecls().push_back( ret );458 ret->type->set_const( false ); 459 impCpCtorExpr->returnDecls.push_back( ret ); 447 460 CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; ) 448 461 if ( ! dynamic_cast< ReferenceType * >( result ) ) { … … 551 564 Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) ); 552 565 // move env from callExpr to retExpr 553 retExpr->set_env( callExpr->get_env() ); 554 callExpr->set_env( nullptr ); 566 std::swap( retExpr->env, callExpr->env ); 555 567 return retExpr; 556 568 } else { … … 754 766 if ( ctorStmt && (ctorCall = isIntrinsicCallExpr( ctorStmt->expr )) && ctorCall->get_args().size() == 2 ) { 755 767 // clean up intrinsic copy constructor calls by making them into SingleInits 756 objDecl->init = new SingleInit( ctorCall->args.back() ); 768 Expression * ctorArg = ctorCall->args.back(); 769 std::swap( ctorArg->env, ctorCall->env ); 770 objDecl->init = new SingleInit( ctorArg ); 771 757 772 ctorCall->args.pop_back(); 758 773 } else { … … 822 837 GuardValue( labelVars ); 823 838 labelVars.clear(); 839 // LabelFinder does not recurse into FunctionDecl, so need to visit 840 // its children manually. 824 841 maybeAccept( funcDecl->type, finder ); 825 842 maybeAccept( funcDecl->statements, finder ); … … 1079 1096 } 1080 1097 1081 DeclarationWithType * MutatingResolver::mutate( ObjectDecl * objectDecl ) {1098 DeclarationWithType * MutatingResolver::mutate( ObjectDecl * objectDecl ) { 1082 1099 // add object to the indexer assumes that there will be no name collisions 1083 1100 // in generated code. If this changes, add mutate methods for entities with … … 1087 1104 } 1088 1105 1089 Expression* MutatingResolver::mutate( UntypedExpr *untypedExpr ) { 1090 return strict_dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untypedExpr, indexer ) ); 1106 Expression * MutatingResolver::mutate( UntypedExpr * untypedExpr ) { 1107 Expression * newExpr = untypedExpr; 1108 ResolvExpr::findVoidExpression( newExpr, indexer ); 1109 return newExpr; 1091 1110 } 1092 1111 … … 1094 1113 static UniqueName tempNamer( "_tmp_ctor_expr" ); 1095 1114 // xxx - is the size check necessary? 1096 assert( ctorExpr-> has_result()&& ctorExpr->get_result()->size() == 1 );1115 assert( ctorExpr->result && ctorExpr->get_result()->size() == 1 ); 1097 1116 1098 1117 // xxx - ideally we would reuse the temporary generated from the copy constructor passes from within firstArg if it exists and not generate a temporary if it's unnecessary. … … 1113 1132 1114 1133 // resolve assignment and dispose of new env 1115 Expression * resolvedAssign = ResolvExpr::findVoidExpression( assign, indexer ); 1116 delete resolvedAssign->env; 1117 resolvedAssign->env = nullptr; 1118 delete assign; 1134 ResolvExpr::findVoidExpression( assign, indexer ); 1135 delete assign->env; 1136 assign->env = nullptr; 1119 1137 1120 1138 // for constructor expr: … … 1125 1143 // T & tmp; 1126 1144 // &tmp = &x, ?{}(tmp), tmp 1127 CommaExpr * commaExpr = new CommaExpr( resolvedAssign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) );1145 CommaExpr * commaExpr = new CommaExpr( assign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) ); 1128 1146 commaExpr->set_env( env ); 1129 1147 return commaExpr;
Note: See TracChangeset
for help on using the changeset viewer.