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