Changes in src/GenPoly/GenPoly.cc [5a3ac84:7350ff97]
- File:
-
- 1 edited
-
src/GenPoly/GenPoly.cc (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/GenPoly.cc
r5a3ac84 r7350ff97 15 15 16 16 #include "GenPoly.h" 17 #include "assert.h"18 17 19 18 #include "SynTree/Expression.h" 20 19 #include "SynTree/Type.h" 21 #include "ResolvExpr/typeops.h"22 20 23 21 #include <iostream> 24 #include <iterator>25 #include <list>26 #include <typeindex>27 #include <typeinfo>28 #include <vector>29 22 using namespace std; 30 23 … … 45 38 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) { 46 39 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 47 assert f(paramType,"Aggregate parameters should be type expressions");40 assert(paramType && "Aggregate parameters should be type expressions"); 48 41 if ( isPolyType( paramType->get_type(), tyVars, env ) ) return true; 49 42 } … … 55 48 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) { 56 49 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 57 assert f(paramType,"Aggregate parameters should be type expressions");50 assert(paramType && "Aggregate parameters should be type expressions"); 58 51 if ( isDynType( paramType->get_type(), tyVars, env ) ) return true; 59 }60 return false;61 }62 63 /// Checks a parameter list for inclusion of polymorphic parameters; will substitute according to env if present64 bool includesPolyParams( std::list< Expression* >& params, const TypeSubstitution *env ) {65 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {66 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );67 assertf(paramType, "Aggregate parameters should be type expressions");68 if ( includesPolyType( paramType->get_type(), env ) ) return true;69 }70 return false;71 }72 73 /// Checks a parameter list for inclusion of polymorphic parameters from tyVars; will substitute according to env if present74 bool includesPolyParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) {75 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {76 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );77 assertf(paramType, "Aggregate parameters should be type expressions");78 if ( includesPolyType( paramType->get_type(), tyVars, env ) ) return true;79 52 } 80 53 return false; … … 214 187 215 188 return isPolyType( type, tyVars, env ); 216 }217 218 bool includesPolyType( Type *type, const TypeSubstitution *env ) {219 type = replaceTypeInst( type, env );220 221 if ( dynamic_cast< TypeInstType * >( type ) ) {222 return true;223 } else if ( PointerType *pointerType = dynamic_cast< PointerType* >( type ) ) {224 if ( includesPolyType( pointerType->get_base(), env ) ) return true;225 } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {226 if ( includesPolyParams( structType->get_parameters(), env ) ) return true;227 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {228 if ( includesPolyParams( unionType->get_parameters(), env ) ) return true;229 }230 return false;231 }232 233 bool includesPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {234 type = replaceTypeInst( type, env );235 236 if ( TypeInstType *typeInstType = dynamic_cast< TypeInstType * >( type ) ) {237 if ( tyVars.find( typeInstType->get_name() ) != tyVars.end() ) {238 return true;239 }240 } else if ( PointerType *pointerType = dynamic_cast< PointerType* >( type ) ) {241 if ( includesPolyType( pointerType->get_base(), tyVars, env ) ) return true;242 } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {243 if ( includesPolyParams( structType->get_parameters(), tyVars, env ) ) return true;244 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {245 if ( includesPolyParams( unionType->get_parameters(), tyVars, env ) ) return true;246 }247 return false;248 189 } 249 190 … … 296 237 } 297 238 298 namespace {299 /// Checks if is a pointer to D300 template<typename D, typename B>301 bool is( const B* p ) { return type_index{typeid(D)} == type_index{typeid(*p)}; }302 303 /// Converts to a pointer to D without checking for safety304 template<typename D, typename B>305 inline D* as( B* p ) { return reinterpret_cast<D*>(p); }306 307 /// Flattens a declaration list308 template<typename Output>309 void flattenList( list< DeclarationWithType* > src, Output out ) {310 for ( DeclarationWithType* decl : src ) {311 ResolvExpr::flatten( decl->get_type(), out );312 }313 }314 315 /// Flattens a list of types316 template<typename Output>317 void flattenList( list< Type* > src, Output out ) {318 for ( Type* ty : src ) {319 ResolvExpr::flatten( ty, out );320 }321 }322 323 /// Checks if two lists of parameters are equal up to polymorphic substitution.324 bool paramListsPolyCompatible( const list< Expression* >& aparams, const list< Expression* >& bparams ) {325 if ( aparams.size() != bparams.size() ) return false;326 327 for ( list< Expression* >::const_iterator at = aparams.begin(), bt = bparams.begin();328 at != aparams.end(); ++at, ++bt ) {329 TypeExpr *aparam = dynamic_cast< TypeExpr* >(*at);330 assertf(aparam, "Aggregate parameters should be type expressions");331 TypeExpr *bparam = dynamic_cast< TypeExpr* >(*bt);332 assertf(bparam, "Aggregate parameters should be type expressions");333 334 // xxx - might need to let VoidType be a wildcard here too; could have some voids335 // stuffed in for dtype-statics.336 // if ( is<VoidType>( aparam->get_type() ) || is<VoidType>( bparam->get_type() ) ) continue;337 if ( ! typesPolyCompatible( aparam->get_type(), bparam->get_type() ) ) return false;338 }339 340 return true;341 }342 }343 344 bool typesPolyCompatible( Type *a, Type *b ) {345 type_index aid{ typeid(*a) };346 // polymorphic types always match347 if ( aid == type_index{typeid(TypeInstType)} ) return true;348 349 type_index bid{ typeid(*b) };350 // polymorphic types always match351 if ( bid == type_index{typeid(TypeInstType)} ) return true;352 353 // can't match otherwise if different types354 if ( aid != bid ) return false;355 356 // recurse through type structure (conditions borrowed from Unify.cc)357 if ( aid == type_index{typeid(BasicType)} ) {358 return as<BasicType>(a)->get_kind() == as<BasicType>(b)->get_kind();359 } else if ( aid == type_index{typeid(PointerType)} ) {360 PointerType *ap = as<PointerType>(a), *bp = as<PointerType>(b);361 362 // void pointers should match any other pointer type363 return is<VoidType>( ap->get_base() ) || is<VoidType>( bp->get_base() )364 || typesPolyCompatible( ap->get_base(), bp->get_base() );365 } else if ( aid == type_index{typeid(ArrayType)} ) {366 ArrayType *aa = as<ArrayType>(a), *ba = as<ArrayType>(b);367 368 if ( aa->get_isVarLen() ) {369 if ( ! ba->get_isVarLen() ) return false;370 } else {371 if ( ba->get_isVarLen() ) return false;372 373 ConstantExpr *ad = dynamic_cast<ConstantExpr*>( aa->get_dimension() );374 ConstantExpr *bd = dynamic_cast<ConstantExpr*>( ba->get_dimension() );375 if ( ad && bd376 && ad->get_constant()->get_value() != bd->get_constant()->get_value() )377 return false;378 }379 380 return typesPolyCompatible( aa->get_base(), ba->get_base() );381 } else if ( aid == type_index{typeid(FunctionType)} ) {382 FunctionType *af = as<FunctionType>(a), *bf = as<FunctionType>(b);383 384 vector<Type*> aparams, bparams;385 flattenList( af->get_parameters(), back_inserter( aparams ) );386 flattenList( bf->get_parameters(), back_inserter( bparams ) );387 if ( aparams.size() != bparams.size() ) return false;388 389 vector<Type*> areturns, breturns;390 flattenList( af->get_returnVals(), back_inserter( areturns ) );391 flattenList( bf->get_returnVals(), back_inserter( breturns ) );392 if ( areturns.size() != breturns.size() ) return false;393 394 for ( unsigned i = 0; i < aparams.size(); ++i ) {395 if ( ! typesPolyCompatible( aparams[i], bparams[i] ) ) return false;396 }397 for ( unsigned i = 0; i < areturns.size(); ++i ) {398 if ( ! typesPolyCompatible( areturns[i], breturns[i] ) ) return false;399 }400 return true;401 } else if ( aid == type_index{typeid(StructInstType)} ) {402 StructInstType *aa = as<StructInstType>(a), *ba = as<StructInstType>(b);403 404 if ( aa->get_name() != ba->get_name() ) return false;405 return paramListsPolyCompatible( aa->get_parameters(), ba->get_parameters() );406 } else if ( aid == type_index{typeid(UnionInstType)} ) {407 UnionInstType *aa = as<UnionInstType>(a), *ba = as<UnionInstType>(b);408 409 if ( aa->get_name() != ba->get_name() ) return false;410 return paramListsPolyCompatible( aa->get_parameters(), ba->get_parameters() );411 } else if ( aid == type_index{typeid(EnumInstType)} ) {412 return as<EnumInstType>(a)->get_name() == as<EnumInstType>(b)->get_name();413 } else if ( aid == type_index{typeid(TraitInstType)} ) {414 return as<TraitInstType>(a)->get_name() == as<TraitInstType>(b)->get_name();415 } else if ( aid == type_index{typeid(TupleType)} ) {416 TupleType *at = as<TupleType>(a), *bt = as<TupleType>(b);417 418 vector<Type*> atypes, btypes;419 flattenList( at->get_types(), back_inserter( atypes ) );420 flattenList( bt->get_types(), back_inserter( btypes ) );421 if ( atypes.size() != btypes.size() ) return false;422 423 for ( unsigned i = 0; i < atypes.size(); ++i ) {424 if ( ! typesPolyCompatible( atypes[i], btypes[i] ) ) return false;425 }426 return true;427 } else return true; // VoidType, VarArgsType, ZeroType & OneType just need the same type428 }429 430 239 void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) { 431 240 tyVarMap[ tyVar->get_name() ] = TypeDecl::Data{ tyVar };
Note:
See TracChangeset
for help on using the changeset viewer.