Changeset 6ce67ce for src/GenPoly/Box.cc
- Timestamp:
- Feb 23, 2016, 11:05:11 AM (8 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, string, with_gc
- Children:
- 3be261a, a172972, b502055
- Parents:
- 6ed1d4b (diff), 4318107 (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/GenPoly/Box.cc
r6ed1d4b r6ce67ce 73 73 /// Makes a new temporary array holding the offsets of the fields of `type`, and returns a new variable expression referencing it 74 74 Expression *makeOffsetArray( StructInstType *type ); 75 /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application 76 void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ); 75 77 /// passes extra type parameters into a polymorphic function application 76 void passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );78 void passTypeVars( ApplicationExpr *appExpr, ReferenceToType *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 77 79 /// wraps a function application with a new temporary for the out-parameter return value 78 80 Expression *addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ); … … 398 400 } 399 401 400 void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 402 void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) { 403 Type *polyBase = hasPolyBase( parmType, exprTyVars ); 404 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) { 405 std::string sizeName = sizeofName( polyBase ); 406 if ( seenTypes.count( sizeName ) ) return; 407 408 arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) ); 409 arg++; 410 arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) ); 411 arg++; 412 if ( dynamic_cast< StructInstType* >( polyBase ) ) { 413 if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) { 414 arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) ); 415 arg++; 416 } else { 417 throw SemanticError( "Cannot pass non-struct type for generic struct" ); 418 } 419 } 420 421 seenTypes.insert( sizeName ); 422 } 423 } 424 425 void Pass1::passTypeVars( ApplicationExpr *appExpr, ReferenceToType *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 401 426 // pass size/align for type variables 402 427 for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) { … … 424 449 std::list< Expression* >::const_iterator fnArg = arg; 425 450 std::set< std::string > seenTypes; //< names for generic types we've seen 451 452 // a polymorphic return type may need to be added to the argument list 453 if ( polyRetType ) { 454 Type *concRetType = replaceWithConcrete( appExpr, polyRetType ); 455 passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes ); 456 } 457 458 // add type information args for presently unseen types in parameter list 426 459 for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) { 427 Type *polyBase = hasPolyBase( (*fnParm)->get_type(), exprTyVars ); 428 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) { 429 std::string sizeName = sizeofName( polyBase ); 430 if ( seenTypes.count( sizeName ) ) continue; 431 432 VariableExpr *fnArgBase = getBaseVar( *fnArg ); 433 assert( fnArgBase && ! fnArgBase->get_results().empty() ); 434 Type *argBaseType = fnArgBase->get_results().front(); 435 arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) ); 436 arg++; 437 arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) ); 438 arg++; 439 if ( dynamic_cast< StructInstType* >( polyBase ) ) { 440 if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) { 441 arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) ); 442 arg++; 443 } else { 444 throw SemanticError( "Cannot pass non-struct type for generic struct" ); 445 } 446 } 447 448 seenTypes.insert( sizeName ); 449 } 460 VariableExpr *fnArgBase = getBaseVar( *fnArg ); 461 if ( ! fnArgBase || fnArgBase->get_results().empty() ) continue; 462 passArgTypeVars( appExpr, (*fnParm)->get_type(), fnArgBase->get_results().front(), arg, exprTyVars, seenTypes ); 450 463 } 451 464 } … … 470 483 ObjectDecl *newObj = makeTemporary( retType->clone() ); 471 484 Expression *paramExpr = new VariableExpr( newObj ); 472 // If the type of the temporary is not polymorphic, box temporary by taking its address; otherwise the 473 // temporary is already boxed and can be used directly. 485 486 // If the type of the temporary is not polymorphic, box temporary by taking its address; 487 // otherwise the temporary is already boxed and can be used directly. 474 488 if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) { 475 489 paramExpr = new AddressExpr( paramExpr ); … … 520 534 assert( env ); 521 535 Type *concrete = replaceWithConcrete( appExpr, polyType ); 536 // add out-parameter for return value 522 537 return addRetParam( appExpr, function, concrete, arg ); 523 538 } … … 542 557 assert( ! arg->get_results().empty() ); 543 558 if ( isPolyType( param, exprTyVars ) ) { 544 if ( dynamic_cast< TypeInstType *>( arg->get_results().front() ) ) {545 // if the argument's type is a type parameter, we don't need to box again!559 if ( isPolyType( arg->get_results().front() ) ) { 560 // if the argument's type is polymorphic, we don't need to box again! 546 561 return; 547 562 } else if ( arg->get_results().front()->get_isLvalue() ) { … … 622 637 assert( arg ); 623 638 if ( isPolyType( realParam->get_type(), tyVars ) ) { 624 if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL) {639 if ( ! isPolyType( arg->get_type() ) ) { 625 640 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 626 641 deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) ); … … 917 932 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin(); 918 933 919 if ( ReferenceToType *polyType = isPolyRet( function ) ) { 920 ret = addPolyRetParam( appExpr, function, polyType, arg ); 934 TyVarMap exprTyVars; 935 makeTyVarMap( function, exprTyVars ); 936 ReferenceToType *polyRetType = 0; 937 938 if ( polyRetType = isPolyRet( function ) ) { 939 ret = addPolyRetParam( appExpr, function, polyRetType, arg ); 921 940 } else if ( needsAdapter( function, scopeTyVars ) ) { 922 941 // std::cerr << "needs adapter: "; … … 930 949 arg = appExpr->get_args().begin(); 931 950 932 TyVarMap exprTyVars; 933 makeTyVarMap( function, exprTyVars ); 934 935 passTypeVars( appExpr, arg, exprTyVars ); 951 passTypeVars( appExpr, polyRetType, arg, exprTyVars ); 936 952 addInferredParams( appExpr, function, arg, exprTyVars ); 937 953 … … 992 1008 } 993 1009 1010 /// Wraps a function declaration in a new pointer-to-function variable expression 1011 VariableExpr *wrapFunctionDecl( DeclarationWithType *functionDecl ) { 1012 // line below cloned from FixFunction.cc 1013 ObjectDecl *functionObj = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0, 1014 new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 ); 1015 functionObj->set_mangleName( functionDecl->get_mangleName() ); 1016 return new VariableExpr( functionObj ); 1017 } 1018 994 1019 Statement * Pass1::mutate( ReturnStmt *returnStmt ) { 995 1020 if ( retval && returnStmt->get_expr() ) { … … 1007 1032 1008 1033 // find assignment operator for (polymorphic) return type 1009 DeclarationWithType *assignDecl= 0;1034 ApplicationExpr *assignExpr = 0; 1010 1035 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) { 1036 // find assignment operator for type variable 1011 1037 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 1012 1038 if ( assignIter == assignOps.end() ) { 1013 1039 throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() ); 1014 1040 } // if 1015 assign Decl = assignIter->second;1041 assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) ); 1016 1042 } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) { 1043 // find assignment operator for generic type 1017 1044 ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = scopedAssignOps.find( refType->get_name() ); 1018 1045 if ( assignIter == scopedAssignOps.end() ) { 1019 1046 throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() ); 1020 1047 } 1048 1049 // wrap it up in an application expression 1021 1050 DeclarationWithType *functionDecl = assignIter->second; 1022 // line below cloned from FixFunction.cc 1023 assignDecl = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0, 1024 new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 ); 1025 assignDecl->set_mangleName( functionDecl->get_mangleName() ); 1051 assignExpr = new ApplicationExpr( wrapFunctionDecl( functionDecl ) ); 1052 assignExpr->set_env( env->clone() ); 1053 1054 // find each of its needed secondary assignment operators 1055 std::list< Expression* > &tyParams = refType->get_parameters(); 1056 std::list< TypeDecl* > &forallParams = functionDecl->get_type()->get_forall(); 1057 std::list< Expression* >::const_iterator tyIt = tyParams.begin(); 1058 std::list< TypeDecl* >::const_iterator forallIt = forallParams.begin(); 1059 for ( ; tyIt != tyParams.end() && forallIt != forallParams.end(); ++tyIt, ++forallIt ) { 1060 if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue; // skip types with no assign op (ftype/dtype) 1061 1062 std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions(); 1063 assert( ! asserts.empty() && "Type param needs assignment operator assertion" ); 1064 DeclarationWithType *actualDecl = asserts.front(); 1065 ReferenceToType *actualType = isAssignment( actualDecl ); 1066 assert( actualType && "First assertion of type with assertions should be assignment operator" ); 1067 TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt ); 1068 assert( formalTypeExpr && "type parameters must be type expressions" ); 1069 Type *formalType = formalTypeExpr->get_type(); 1070 assignExpr->get_env()->add( actualType->get_name(), formalType ); 1071 1072 DeclarationWithType *assertAssign = 0; 1073 if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) { 1074 std::map< std::string, DeclarationWithType *>::const_iterator assertAssignIt = assignOps.find( formalTypeInstType->get_name() ); 1075 if ( assertAssignIt == assignOps.end() ) { 1076 throw SemanticError( "No assignment operation found for ", formalTypeInstType ); 1077 } 1078 assertAssign = assertAssignIt->second; 1079 //assignExpr->get_env()->add( formalTypeInstType->get_name(), actualType ); 1080 } else if ( ReferenceToType *formalReferenceType = dynamic_cast< ReferenceToType* >( formalType ) ) { 1081 ScopedMap< std::string, DeclarationWithType *>::const_iterator assertAssignIt = scopedAssignOps.find( formalReferenceType->get_name() ); 1082 if ( assertAssignIt == scopedAssignOps.end() ) { 1083 throw SemanticError( "No assignment operation found for ", formalReferenceType ); 1084 } 1085 assertAssign = assertAssignIt->second; 1086 } else assert( false && "returning polymorphic types with non struct/polymorphic parameters not yet supported" ); 1087 1088 1089 assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ] 1090 = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) ); 1091 } 1026 1092 } 1027 assert( assign Decl);1093 assert( assignExpr ); 1028 1094 1029 1095 // replace return statement with appropriate assignment to out parameter 1030 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignDecl ) );1031 1096 Expression *retParm = new NameExpr( retval->get_name() ); 1032 1097 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); … … 1180 1245 } 1181 1246 1182 // add size/align for generic types to parameter list1247 // add size/align for generic parameter types to parameter list 1183 1248 std::set< std::string > seenTypes; // sizeofName for generic types we've seen 1184 1249 for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) { … … 1295 1360 1296 1361 if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) { 1297 if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) return i; 1362 if ( memberDecl->get_mangleName().empty() || declWithType->get_mangleName().empty() 1363 || memberDecl->get_mangleName() == declWithType->get_mangleName() ) return i; 1298 1364 else continue; 1299 1365 } else return i; … … 1341 1407 if ( ! objectType ) return memberExpr; 1342 1408 1409 Expression *newMemberExpr = 0; 1343 1410 if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) { 1344 1411 // look up offset index … … 1350 1417 fieldLoc->get_args().push_back( makeDerefdVar( varExpr->clone(), varDepth ) ); 1351 1418 fieldLoc->get_args().push_back( makeOffsetIndex( objectType, i ) ); 1352 1353 delete memberExpr; 1354 return fieldLoc; 1355 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ) ) { 1419 newMemberExpr = fieldLoc; 1420 } else if ( dynamic_cast< UnionInstType* >( objectType ) ) { 1356 1421 // union members are all at offset zero, so build appropriately-dereferenced variable 1357 Expression *derefdVar = makeDerefdVar( varExpr->clone(), varDepth ); 1358 delete memberExpr; 1359 return derefdVar; 1422 newMemberExpr = makeDerefdVar( varExpr->clone(), varDepth ); 1360 1423 } else return memberExpr; 1424 assert( newMemberExpr ); 1425 1426 // wrap pointer members in appropriate cast 1427 if ( dynamic_cast< PointerType* >( memberExpr->get_member()->get_type() ) ) { 1428 CastExpr *ptrCastExpr = new CastExpr( newMemberExpr, new PointerType( Type::Qualifiers(), new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ) ) ); 1429 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 1430 derefExpr->get_args().push_back( ptrCastExpr ); 1431 newMemberExpr = derefExpr; 1432 } 1433 1434 delete memberExpr; 1435 return newMemberExpr; 1361 1436 } 1362 1437 … … 1379 1454 delete offsetofExpr; 1380 1455 return offsetInd; 1381 } else if ( UnionInstType *unionType =dynamic_cast< UnionInstType* >( ty ) ) {1456 } else if ( dynamic_cast< UnionInstType* >( ty ) ) { 1382 1457 // all union members are at offset zero 1383 1458 delete offsetofExpr;
Note: See TracChangeset
for help on using the changeset viewer.