Changeset 5a3ac84 for src/GenPoly/GenPoly.cc
- Timestamp:
- Mar 15, 2017, 5:01:18 PM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 9b443c7f
- Parents:
- 17df48e
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/GenPoly.cc
r17df48e r5a3ac84 15 15 16 16 #include "GenPoly.h" 17 #include "assert.h" 17 18 18 19 #include "SynTree/Expression.h" 19 20 #include "SynTree/Type.h" 21 #include "ResolvExpr/typeops.h" 20 22 21 23 #include <iostream> 24 #include <iterator> 25 #include <list> 26 #include <typeindex> 27 #include <typeinfo> 28 #include <vector> 22 29 using namespace std; 23 30 … … 38 45 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) { 39 46 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 40 assert (paramType &&"Aggregate parameters should be type expressions");47 assertf(paramType, "Aggregate parameters should be type expressions"); 41 48 if ( isPolyType( paramType->get_type(), tyVars, env ) ) return true; 42 49 } … … 48 55 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) { 49 56 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 50 assert (paramType &&"Aggregate parameters should be type expressions");57 assertf(paramType, "Aggregate parameters should be type expressions"); 51 58 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 present 64 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 present 74 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; 52 79 } 53 80 return false; … … 187 214 188 215 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; 189 248 } 190 249 … … 237 296 } 238 297 298 namespace { 299 /// Checks if is a pointer to D 300 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 safety 304 template<typename D, typename B> 305 inline D* as( B* p ) { return reinterpret_cast<D*>(p); } 306 307 /// Flattens a declaration list 308 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 types 316 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 voids 335 // 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 match 347 if ( aid == type_index{typeid(TypeInstType)} ) return true; 348 349 type_index bid{ typeid(*b) }; 350 // polymorphic types always match 351 if ( bid == type_index{typeid(TypeInstType)} ) return true; 352 353 // can't match otherwise if different types 354 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 type 363 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 && bd 376 && 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 type 428 } 429 239 430 void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) { 240 431 tyVarMap[ tyVar->get_name() ] = TypeDecl::Data{ tyVar };
Note: See TracChangeset
for help on using the changeset viewer.