Changeset b3212de
- Timestamp:
- Nov 1, 2022, 2:05:16 PM (2 years ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- 75f6a5f
- Parents:
- 1dafdfc
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r1dafdfc rb3212de 676 676 } 677 677 678 // find instances of polymorphic type parameters 679 struct PolyFinder { 680 const TyVarMap * tyVars = nullptr; 681 bool found = false; 682 683 void previsit( TypeInstType * t ) { 684 if ( isPolyType( t, *tyVars ) ) { 685 found = true; 686 } 687 } 688 }; 689 690 // true if there is an instance of a polymorphic type parameter in t 691 bool hasPolymorphism( Type * t, const TyVarMap &tyVars ) { 692 PassVisitor<PolyFinder> finder; 693 finder.pass.tyVars = &tyVars; 694 maybeAccept( t, finder ); 695 return finder.pass.found; 696 } 697 698 /// cast parameters to polymorphic functions so that types are replaced with 699 /// void * if they are type parameters in the formal type. 700 /// this gets rid of warnings from gcc. 701 void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) { 702 // type contains polymorphism, but isn't exactly a polytype, in which case it 703 // has some real actual type (e.g. unsigned int) and casting to void * is wrong 704 if ( hasPolymorphism( formal, tyVars ) && ! isPolyType( formal, tyVars ) ) { 705 Type * newType = formal->clone(); 706 newType = ScrubTyVars::scrub( newType, tyVars ); 707 actual = new CastExpr( actual, newType ); 708 } // if 709 } 710 678 711 void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) { 679 712 assertf( arg->result, "arg does not have result: %s", toString( arg ).c_str() ); 713 addCast( arg, param, exprTyVars ); 680 714 if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return; 681 715 … … 708 742 } 709 743 710 // find instances of polymorphic type parameters711 struct PolyFinder {712 const TyVarMap * tyVars = nullptr;713 bool found = false;714 715 void previsit( TypeInstType * t ) {716 if ( isPolyType( t, *tyVars ) ) {717 found = true;718 }719 }720 };721 722 // true if there is an instance of a polymorphic type parameter in t723 bool hasPolymorphism( Type * t, const TyVarMap &tyVars ) {724 PassVisitor<PolyFinder> finder;725 finder.pass.tyVars = &tyVars;726 maybeAccept( t, finder );727 return finder.pass.found;728 }729 730 /// cast parameters to polymorphic functions so that types are replaced with731 /// void * if they are type parameters in the formal type.732 /// this gets rid of warnings from gcc.733 void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) {734 // type contains polymorphism, but isn't exactly a polytype, in which case it735 // has some real actual type (e.g. unsigned int) and casting to void * is wrong736 if ( hasPolymorphism( formal, tyVars ) && ! isPolyType( formal, tyVars ) ) {737 Type * newType = formal->clone();738 newType = ScrubTyVars::scrub( newType, tyVars );739 actual = new CastExpr( actual, newType );740 } // if741 }742 743 744 void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 744 745 for ( DeclarationWithType * param : function->parameters ) { 745 746 assertf( arg != appExpr->args.end(), "boxParams: missing argument for param %s to %s in %s", toString( param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() ); 746 addCast( *arg, param->get_type(), exprTyVars );747 747 boxParam( param->get_type(), *arg, exprTyVars ); 748 748 ++arg; … … 757 757 assertf( inferParam != appExpr->inferParams.end(), "addInferredParams missing inferred parameter: %s in: %s", toString( assert ).c_str(), toString( appExpr ).c_str() ); 758 758 Expression *newExpr = inferParam->second.expr->clone(); 759 addCast( newExpr, assert->get_type(), tyVars );760 759 boxParam( assert->get_type(), newExpr, tyVars ); 761 760 appExpr->get_args().insert( cur, newExpr ); … … 788 787 assert( param ); 789 788 assert( arg ); 790 if ( isPolyType( realParam->get_type(), tyVars ) ) { 791 if ( ! isPolyType( arg->get_type() ) ) { 792 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 793 deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) ); 794 deref->result = arg->get_type()->clone(); 795 return deref; 796 } // if 789 if ( isPolyType( realParam->get_type(), tyVars ) 790 && ! isPolyType( arg->get_type() ) ) { 791 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 792 deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) ); 793 deref->result = arg->get_type()->clone(); 794 return deref; 797 795 } // if 798 796 return new VariableExpr( param ); … … 1130 1128 } 1131 1129 1132 Expression * Pass1::postmutate( UntypedExpr *expr) {1130 bool isPolyDeref( UntypedExpr * expr, TyVarMap const & scopeTyVars, TypeSubstitution const * env ) { 1133 1131 if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) { 1134 1132 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) { 1135 1133 if ( name->name == "*?" ) { 1136 Expression *ret = expr->args.front(); 1137 expr->args.clear(); 1138 delete expr; 1139 return ret; 1134 return true; 1140 1135 } // if 1141 1136 } // if 1142 1137 } // if 1138 return false; 1139 } 1140 1141 Expression * Pass1::postmutate( UntypedExpr *expr ) { 1142 if ( isPolyDeref( expr, scopeTyVars, env ) ) { 1143 Expression *ret = expr->args.front(); 1144 expr->args.clear(); 1145 delete expr; 1146 return ret; 1147 } 1143 1148 return expr; 1144 1149 } … … 1150 1155 bool needs = false; 1151 1156 if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->arg ) ) { 1152 if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) { 1153 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) { 1154 if ( name->name == "*?" ) { 1155 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->args.front() ) ) { 1156 assert( appExpr->function->result ); 1157 FunctionType *function = getFunctionType( appExpr->function->result ); 1158 assert( function ); 1159 needs = needsAdapter( function, scopeTyVars ); 1160 } // if 1161 } // if 1157 if ( isPolyDeref( expr, scopeTyVars, env ) ) { 1158 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->args.front() ) ) { 1159 assert( appExpr->function->result ); 1160 FunctionType *function = getFunctionType( appExpr->function->result ); 1161 assert( function ); 1162 needs = needsAdapter( function, scopeTyVars ); 1162 1163 } // if 1163 1164 } // if … … 1432 1433 1433 1434 if(!expect_func_type) { 1434 GuardAction( [this]() {1435 knownLayouts.endScope();1436 knownOffsets.endScope();1437 });1438 1435 // If this is the first function type we see 1439 1436 // Then it's the type of the declaration and we care about it 1440 knownLayouts.beginScope(); 1441 knownOffsets.beginScope(); 1437 GuardScope( *this ); 1442 1438 } 1443 1439
Note: See TracChangeset
for help on using the changeset viewer.