Changeset d63eeb0 for src/GenPoly
- Timestamp:
- Feb 9, 2016, 3:25:05 PM (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:
- 7528ba1
- Parents:
- 771b3c3 (diff), bd85400 (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. - Location:
- src/GenPoly
- Files:
-
- 1 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r771b3c3 rd63eeb0 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : T hu Jan 07 13:40:05201613 // Update Count : 2 1912 // Last Modified On : Tue Feb 09 14:39:52 2016 13 // Update Count : 295 14 14 // 15 15 … … 22 22 23 23 #include "Box.h" 24 #include "InstantiateGeneric.h" 24 25 #include "PolyMutator.h" 25 26 #include "FindFunction.h" 27 #include "ScopedMap.h" 26 28 #include "ScrubTyVars.h" 27 29 … … 39 41 #include "SymTab/Mangler.h" 40 42 41 #include " SemanticError.h"42 #include " UniqueName.h"43 #include " utility.h"43 #include "Common/SemanticError.h" 44 #include "Common/UniqueName.h" 45 #include "Common/utility.h" 44 46 45 47 #include <ext/functional> // temporary … … 69 71 virtual void doEndScope(); 70 72 private: 73 /// Makes a new temporary array holding the offsets of the fields of `type`, and returns a new variable expression referencing it 74 Expression *makeOffsetArray( StructInstType *type ); 75 /// passes extra type parameters into a polymorphic function application 71 76 void passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 77 /// wraps a function application with a new temporary for the out-parameter return value 72 78 Expression *addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ); 73 Expression *addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg ); 79 /// Replaces all the type parameters of a generic type with their concrete equivalents under the current environment 80 void replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params ); 81 /// Replaces a polymorphic type with its concrete equivalant under the current environment (returns itself if concrete). 82 /// If `doClone` is set to false, will not clone interior types 83 Type *replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone = true ); 84 /// wraps a function application returning a polymorphic type with a new temporary for the out-parameter return value 85 Expression *addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *polyType, std::list< Expression *>::iterator &arg ); 74 86 Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 75 87 void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars ); 76 88 void boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 77 89 void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ); 90 /// Stores assignment operators from assertion list in local map of assignment operations 78 91 void findAssignOps( const std::list< TypeDecl *> &forall ); 79 92 void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars ); 80 93 FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ); 94 /// Replaces intrinsic operator functions with their arithmetic desugaring 81 95 Expression *handleIntrinsics( ApplicationExpr *appExpr ); 96 /// Inserts a new temporary variable into the current scope with an auto-generated name 82 97 ObjectDecl *makeTemporary( Type *type ); 83 98 84 99 typedef std::map< std::string, DeclarationWithType *> AdapterMap; 85 100 std::map< std::string, DeclarationWithType *> assignOps; 101 ScopedMap< std::string, DeclarationWithType *> scopedAssignOps; 86 102 std::stack< AdapterMap > adapters; 87 103 DeclarationWithType *retval; … … 107 123 }; 108 124 109 /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, and sizeof expressions of polymorphic types with the proper variable 110 class Pass3 : public PolyMutator { 125 /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference; 126 /// also fixes offsetof expressions. 127 class MemberExprFixer : public PolyMutator { 111 128 public: 112 129 template< typename DeclClass > … … 119 136 virtual Type *mutate( PointerType *pointerType ); 120 137 virtual Type *mutate( FunctionType *funcType ); 138 virtual Expression *mutate( MemberExpr *memberExpr ); 139 virtual Expression *mutate( OffsetofExpr *offsetofExpr ); 140 }; 141 142 /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, and sizeof expressions of polymorphic types with the proper variable 143 class Pass3 : public PolyMutator { 144 public: 145 template< typename DeclClass > 146 DeclClass *handleDecl( DeclClass *decl, Type *type ); 147 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ); 148 virtual ObjectDecl *mutate( ObjectDecl *objectDecl ); 149 virtual TypedefDecl *mutate( TypedefDecl *objectDecl ); 150 virtual TypeDecl *mutate( TypeDecl *objectDecl ); 151 virtual Type *mutate( PointerType *pointerType ); 152 virtual Type *mutate( FunctionType *funcType ); 121 153 private: 122 154 }; … … 133 165 } 134 166 167 /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging 168 template< typename MutatorType > 169 inline void mutateTranslationUnit( std::list< Declaration* > &translationUnit, MutatorType &mutator ) { 170 bool seenIntrinsic = false; 171 SemanticError errors; 172 for ( typename std::list< Declaration* >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) { 173 try { 174 if ( *i ) { 175 if ( (*i)->get_linkage() == LinkageSpec::Intrinsic ) { 176 seenIntrinsic = true; 177 } else if ( seenIntrinsic ) { 178 seenIntrinsic = false; // break on this line when debugging for end of prelude 179 } 180 181 *i = dynamic_cast< Declaration* >( (*i)->acceptMutator( mutator ) ); 182 assert( *i ); 183 } // if 184 } catch( SemanticError &e ) { 185 errors.append( e ); 186 } // try 187 } // for 188 if ( ! errors.isEmpty() ) { 189 throw errors; 190 } // if 191 } 192 135 193 void box( std::list< Declaration *>& translationUnit ) { 136 194 Pass1 pass1; 137 195 Pass2 pass2; 196 MemberExprFixer memberFixer; 138 197 Pass3 pass3; 139 mutateAll( translationUnit, pass1 ); 140 mutateAll( translationUnit, pass2 ); 141 mutateAll( translationUnit, pass3 ); 198 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 199 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 200 instantiateGeneric( translationUnit ); 201 mutateTranslationUnit/*All*/( translationUnit, memberFixer ); 202 mutateTranslationUnit/*All*/( translationUnit, pass3 ); 142 203 } 143 204 … … 185 246 } 186 247 187 // returns true if the given declaration is: (*?=?)(T *, T) for some T (return not checked, but maybe should be)188 bool checkAssignment( DeclarationWithType *decl, std::string &name) {248 /// returns T if the given declaration is: (*?=?)(T *, T) for some T (return not checked, but maybe should be), NULL otherwise 249 ReferenceToType *isAssignment( DeclarationWithType *decl ) { 189 250 if ( decl->get_name() == "?=?" ) { 190 if ( PointerType *ptrType = dynamic_cast< PointerType *>( decl->get_type() ) ) { 191 if ( FunctionType *funType = dynamic_cast< FunctionType *>( ptrType->get_base() ) ) { 192 if ( funType->get_parameters().size() == 2 ) { 193 if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) { 194 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) { 195 if ( TypeInstType *typeInst2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) { 196 if ( typeInst->get_name() == typeInst2->get_name() ) { 197 name = typeInst->get_name(); 198 return true; 199 } // if 251 if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) { 252 if ( funType->get_parameters().size() == 2 ) { 253 if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) { 254 if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( pointer->get_base() ) ) { 255 if ( ReferenceToType *refType2 = dynamic_cast< ReferenceToType *>( funType->get_parameters().back()->get_type() ) ) { 256 if ( refType->get_name() == refType2->get_name() ) { 257 return refType; 200 258 } // if 201 259 } // if … … 205 263 } // if 206 264 } // if 207 return false;265 return 0; 208 266 } 209 267 … … 214 272 for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) { 215 273 std::string typeName; 216 if ( checkAssignment( *assert, typeName) ) {217 assignOps[ type Name] = *assert;274 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( isAssignment( *assert ) ) ) { 275 assignOps[ typeInst->get_name() ] = *assert; 218 276 } // if 219 277 } // for … … 222 280 223 281 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) { 282 // if this is a polymorphic assignment function, put it in the map for this scope 283 if ( ReferenceToType *refType = isAssignment( functionDecl ) ) { 284 if ( ! dynamic_cast< TypeInstType* >( refType ) ) { 285 scopedAssignOps.insert( refType->get_name(), functionDecl ); 286 } 287 } 288 224 289 if ( functionDecl->get_statements() ) { // empty routine body ? 225 290 doBeginScope(); … … 231 296 // process polymorphic return value 232 297 retval = 0; 233 std::string typeName; 234 if ( isPolyRet( functionDecl->get_functionType(), typeName ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) { 298 if ( isPolyRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) { 235 299 retval = functionDecl->get_functionType()->get_returnVals().front(); 236 300 … … 256 320 findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter ); 257 321 } // for 322 258 323 AdapterMap & adapters = Pass1::adapters.top(); 259 324 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) { … … 304 369 return condExpr; 305 370 371 } 372 373 Expression *Pass1::makeOffsetArray( StructInstType *ty ) { 374 std::list<Expression*> noDesignators; 375 std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members(); 376 377 // make a new temporary array 378 Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 379 std::stringstream lenGen; 380 lenGen << baseMembers.size(); 381 ConstantExpr *lenExpr = new ConstantExpr( Constant( offsetType->clone(), lenGen.str() ) ); 382 ObjectDecl *arrayTemp = makeTemporary( new ArrayType( Type::Qualifiers(), offsetType, lenExpr, false, false ) ); 383 384 // build initializer list for temporary 385 std::list< Initializer* > inits; 386 for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) { 387 DeclarationWithType *memberDecl; 388 if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) { 389 memberDecl = origMember->clone(); 390 } else { 391 memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 ); 392 } 393 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ), noDesignators ) ); 394 } 395 arrayTemp->set_init( new ListInit( inits, noDesignators ) ); 396 397 // return variable pointing to temporary 398 return new VariableExpr( arrayTemp ); 306 399 } 307 400 … … 325 418 326 419 // add size/align for generic types to parameter list 327 //assert( ! appExpr->get_function()->get_results().empty() );328 420 if ( appExpr->get_function()->get_results().empty() ) return; 329 421 FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() ); … … 334 426 std::set< std::string > seenTypes; //< names for generic types we've seen 335 427 for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) { 336 Type *p armType = (*fnParm)->get_type();337 if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, exprTyVars) ) {338 std::string sizeName = sizeofName( p armType );428 Type *polyBase = hasPolyBase( (*fnParm)->get_type(), exprTyVars ); 429 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) { 430 std::string sizeName = sizeofName( polyBase ); 339 431 if ( seenTypes.count( sizeName ) ) continue; 340 432 341 assert( ! (*fnArg)->get_results().empty() ); 342 Type *argType = (*fnArg)->get_results().front(); 343 arg = appExpr->get_args().insert( arg, new SizeofExpr( argType->clone() ) ); 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() ) ); 344 437 arg++; 345 arg = appExpr->get_args().insert( arg, new AlignofExpr( arg Type->clone() ) );438 arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) ); 346 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 } 347 448 348 449 seenTypes.insert( sizeName ); … … 386 487 } 387 488 388 Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg ) { 389 ResolvExpr::EqvClass eqvClass; 489 void Pass1::replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params ) { 490 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) { 491 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 492 assert(paramType && "Aggregate parameters should be type expressions"); 493 paramType->set_type( replaceWithConcrete( appExpr, paramType->get_type(), false ) ); 494 } 495 } 496 497 Type *Pass1::replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone ) { 498 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) { 499 Type *concrete = env->lookup( typeInst->get_name() ); 500 if ( concrete == 0 ) { 501 throw SemanticError( "Unbound type variable " + typeInst->get_name() + " in ", appExpr ); 502 } // if 503 return concrete; 504 } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) { 505 if ( doClone ) { 506 structType = structType->clone(); 507 } 508 replaceParametersWithConcrete( appExpr, structType->get_parameters() ); 509 return structType; 510 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) { 511 if ( doClone ) { 512 unionType = unionType->clone(); 513 } 514 replaceParametersWithConcrete( appExpr, unionType->get_parameters() ); 515 return unionType; 516 } 517 return type; 518 } 519 520 Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *polyType, std::list< Expression *>::iterator &arg ) { 390 521 assert( env ); 391 Type *concrete = env->lookup( typeName ); 392 if ( concrete == 0 ) { 393 throw SemanticError( "Unbound type variable " + typeName + " in ", appExpr ); 394 } // if 522 Type *concrete = replaceWithConcrete( appExpr, polyType ); 395 523 return addRetParam( appExpr, function, concrete, arg ); 396 524 } … … 404 532 std::string adapterName = makeAdapterName( mangleName ); 405 533 406 appExpr->get_args().push_front( appExpr->get_function() ); 534 // cast adaptee to void (*)(), since it may have any type inside a polymorphic function 535 Type * adapteeType = new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ); 536 appExpr->get_args().push_front( new CastExpr( appExpr->get_function(), adapteeType ) ); 407 537 appExpr->set_function( new NameExpr( adapterName ) ); 408 538 … … 420 550 arg = new AddressExpr( arg ); 421 551 } else { 422 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, arg->get_results().front()->clone(), 0 ); 552 // use type computed in unification to declare boxed variables 553 Type * newType = param->clone(); 554 if ( env ) env->apply( newType ); 555 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, newType, 0 ); 423 556 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right??? 424 557 stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) ); … … 432 565 } 433 566 567 /// cast parameters to polymorphic functions so that types are replaced with 568 /// void * if they are type parameters in the formal type. 569 /// this gets rid of warnings from gcc. 434 570 void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) { 435 Type *newType = formal->clone(); 436 std::list< FunctionType *> functions; 437 // instead of functions needing adapters, this really ought to look for 438 // any function mentioning a polymorphic type 439 findAndReplaceFunction( newType, functions, tyVars, needsAdapter ); 440 if ( ! functions.empty() ) { 571 Type * newType = formal->clone(); 572 if ( getFunctionType( newType ) ) { 573 newType = ScrubTyVars::scrub( newType, tyVars ); 441 574 actual = new CastExpr( actual, newType ); 442 } else {443 delete newType;444 575 } // if 445 576 } … … 492 623 assert( arg ); 493 624 if ( isPolyType( realParam->get_type(), tyVars ) ) { 494 // if ( dynamic_cast< PointerType *>( arg->get_type() ) ) {495 // return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() );496 // } else {497 625 if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) { 498 626 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); … … 501 629 return deref; 502 630 } // if 503 // }504 631 } // if 505 632 return new VariableExpr( param ); … … 791 918 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin(); 792 919 793 std::string typeName; 794 if ( isPolyRet( function, typeName ) ) { 795 ret = addPolyRetParam( appExpr, function, typeName, arg ); 920 if ( ReferenceToType *polyType = isPolyRet( function ) ) { 921 ret = addPolyRetParam( appExpr, function, polyType, arg ); 796 922 } else if ( needsAdapter( function, scopeTyVars ) ) { 797 923 // std::cerr << "needs adapter: "; … … 880 1006 delete castExpr; 881 1007 } //while 882 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ); 883 assert( typeInst ); 884 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 885 if ( assignIter == assignOps.end() ) { 886 throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() ); 887 } // if 888 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) ); 1008 1009 // find assignment operator for (polymorphic) return type 1010 DeclarationWithType *assignDecl = 0; 1011 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) { 1012 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 1013 if ( assignIter == assignOps.end() ) { 1014 throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() ); 1015 } // if 1016 assignDecl = assignIter->second; 1017 } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) { 1018 ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = scopedAssignOps.find( refType->get_name() ); 1019 if ( assignIter == scopedAssignOps.end() ) { 1020 throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() ); 1021 } 1022 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() ); 1027 } 1028 assert( assignDecl ); 1029 1030 // replace return statement with appropriate assignment to out parameter 1031 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignDecl ) ); 889 1032 Expression *retParm = new NameExpr( retval->get_name() ); 890 1033 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); … … 927 1070 // push a copy of the current map 928 1071 adapters.push(adapters.top()); 1072 scopedAssignOps.beginScope(); 929 1073 } 930 1074 931 1075 void Pass1::doEndScope() { 932 1076 adapters.pop(); 1077 scopedAssignOps.endScope(); 933 1078 } 934 1079 … … 998 1143 999 1144 // move polymorphic return type to parameter list 1000 std::string typeName; 1001 if ( isPolyRet( funcType, typeName ) ) { 1145 if ( isPolyRet( funcType ) ) { 1002 1146 DeclarationWithType *ret = funcType->get_returnVals().front(); 1003 1147 ret->set_type( new PointerType( Type::Qualifiers(), ret->get_type() ) ); … … 1010 1154 std::list< DeclarationWithType *> inferredParams; 1011 1155 ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 ); 1156 ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, 1157 new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 ); 1012 1158 // ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 ); 1013 1159 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { … … 1036 1182 1037 1183 // add size/align for generic types to parameter list 1038 std::set< std::string > seenTypes; // <sizeofName for generic types we've seen1184 std::set< std::string > seenTypes; // sizeofName for generic types we've seen 1039 1185 for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) { 1040 Type *p armType = (*fnParm)->get_type();1041 if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, scopeTyVars) ) {1042 std::string sizeName = sizeofName( p armType );1186 Type *polyBase = hasPolyBase( (*fnParm)->get_type(), scopeTyVars ); 1187 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) { 1188 std::string sizeName = sizeofName( polyBase ); 1043 1189 if ( seenTypes.count( sizeName ) ) continue; 1044 1190 1045 ObjectDecl *sizeParm, *alignParm ;1191 ObjectDecl *sizeParm, *alignParm, *offsetParm; 1046 1192 sizeParm = newObj.clone(); 1047 1193 sizeParm->set_name( sizeName ); … … 1050 1196 1051 1197 alignParm = newObj.clone(); 1052 alignParm->set_name( alignofName( p armType ) );1198 alignParm->set_name( alignofName( polyBase ) ); 1053 1199 last = funcType->get_parameters().insert( last, alignParm ); 1054 1200 ++last; 1201 1202 if ( dynamic_cast< StructInstType* >( polyBase ) ) { 1203 offsetParm = newPtr.clone(); 1204 offsetParm->set_name( offsetofName( polyBase ) ); 1205 last = funcType->get_parameters().insert( last, offsetParm ); 1206 ++last; 1207 } 1055 1208 1056 1209 seenTypes.insert( sizeName ); … … 1066 1219 scopeTyVars = oldtyVars; 1067 1220 return funcType; 1221 } 1222 1223 ////////////////////////////////////////// MemberExprFixer //////////////////////////////////////////////////// 1224 1225 template< typename DeclClass > 1226 DeclClass * MemberExprFixer::handleDecl( DeclClass *decl, Type *type ) { 1227 TyVarMap oldtyVars = scopeTyVars; 1228 makeTyVarMap( type, scopeTyVars ); 1229 1230 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) ); 1231 1232 scopeTyVars = oldtyVars; 1233 return ret; 1234 } 1235 1236 ObjectDecl * MemberExprFixer::mutate( ObjectDecl *objectDecl ) { 1237 return handleDecl( objectDecl, objectDecl->get_type() ); 1238 } 1239 1240 DeclarationWithType * MemberExprFixer::mutate( FunctionDecl *functionDecl ) { 1241 return handleDecl( functionDecl, functionDecl->get_functionType() ); 1242 } 1243 1244 TypedefDecl * MemberExprFixer::mutate( TypedefDecl *typedefDecl ) { 1245 return handleDecl( typedefDecl, typedefDecl->get_base() ); 1246 } 1247 1248 TypeDecl * MemberExprFixer::mutate( TypeDecl *typeDecl ) { 1249 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 1250 return Mutator::mutate( typeDecl ); 1251 } 1252 1253 Type * MemberExprFixer::mutate( PointerType *pointerType ) { 1254 TyVarMap oldtyVars = scopeTyVars; 1255 makeTyVarMap( pointerType, scopeTyVars ); 1256 1257 Type *ret = Mutator::mutate( pointerType ); 1258 1259 scopeTyVars = oldtyVars; 1260 return ret; 1261 } 1262 1263 Type * MemberExprFixer::mutate( FunctionType *functionType ) { 1264 TyVarMap oldtyVars = scopeTyVars; 1265 makeTyVarMap( functionType, scopeTyVars ); 1266 1267 Type *ret = Mutator::mutate( functionType ); 1268 1269 scopeTyVars = oldtyVars; 1270 return ret; 1271 } 1272 1273 Statement *MemberExprFixer::mutate( DeclStmt *declStmt ) { 1274 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) { 1275 if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) { 1276 // change initialization of a polymorphic value object 1277 // to allocate storage with alloca 1278 Type *declType = objectDecl->get_type(); 1279 UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) ); 1280 alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) ); 1281 1282 delete objectDecl->get_init(); 1283 1284 std::list<Expression*> designators; 1285 objectDecl->set_init( new SingleInit( alloc, designators, false ) ); // not constructed 1286 } 1287 } 1288 return Mutator::mutate( declStmt ); 1289 } 1290 1291 /// Finds the member in the base list that matches the given declaration; returns its index, or -1 if not present 1292 long findMember( DeclarationWithType *memberDecl, std::list< Declaration* > &baseDecls ) { 1293 long i = 0; 1294 for(std::list< Declaration* >::const_iterator decl = baseDecls.begin(); decl != baseDecls.end(); ++decl, ++i ) { 1295 if ( memberDecl->get_name() != (*decl)->get_name() ) continue; 1296 1297 if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) { 1298 if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) return i; 1299 else continue; 1300 } else return i; 1301 } 1302 return -1; 1303 } 1304 1305 /// Returns an index expression into the offset array for a type 1306 Expression *makeOffsetIndex( Type *objectType, long i ) { 1307 std::stringstream offset_namer; 1308 offset_namer << i; 1309 ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) ); 1310 UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) ); 1311 fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) ); 1312 fieldOffset->get_args().push_back( fieldIndex ); 1313 return fieldOffset; 1314 } 1315 1316 /// Returns an expression dereferenced n times 1317 Expression *makeDerefdVar( Expression *derefdVar, long n ) { 1318 for ( int i = 1; i < n; ++i ) { 1319 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 1320 derefExpr->get_args().push_back( derefdVar ); 1321 derefdVar = derefExpr; 1322 } 1323 return derefdVar; 1324 } 1325 1326 Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) { 1327 // mutate, exiting early if no longer MemberExpr 1328 Expression *expr = Mutator::mutate( memberExpr ); 1329 memberExpr = dynamic_cast< MemberExpr* >( expr ); 1330 if ( ! memberExpr ) return expr; 1331 1332 // get declaration for base struct, exiting early if not found 1333 int varDepth; 1334 VariableExpr *varExpr = getBaseVar( memberExpr->get_aggregate(), &varDepth ); 1335 if ( ! varExpr ) return memberExpr; 1336 ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() ); 1337 if ( ! objectDecl ) return memberExpr; 1338 1339 // only mutate member expressions for polymorphic types 1340 int tyDepth; 1341 Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars, &tyDepth ); 1342 if ( ! objectType ) return memberExpr; 1343 1344 if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) { 1345 // look up offset index 1346 long i = findMember( memberExpr->get_member(), structType->get_baseStruct()->get_members() ); 1347 if ( i == -1 ) return memberExpr; 1348 1349 // replace member expression with pointer to base plus offset 1350 UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) ); 1351 fieldLoc->get_args().push_back( makeDerefdVar( varExpr->clone(), varDepth ) ); 1352 fieldLoc->get_args().push_back( makeOffsetIndex( objectType, i ) ); 1353 1354 delete memberExpr; 1355 return fieldLoc; 1356 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ) ) { 1357 // 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; 1361 } else return memberExpr; 1362 } 1363 1364 Expression *MemberExprFixer::mutate( OffsetofExpr *offsetofExpr ) { 1365 // mutate, exiting early if no longer OffsetofExpr 1366 Expression *expr = Mutator::mutate( offsetofExpr ); 1367 offsetofExpr = dynamic_cast< OffsetofExpr* >( expr ); 1368 if ( ! offsetofExpr ) return expr; 1369 1370 // only mutate expressions for polymorphic structs/unions 1371 Type *ty = isPolyType( offsetofExpr->get_type(), scopeTyVars ); 1372 if ( ! ty ) return offsetofExpr; 1373 1374 if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) { 1375 // replace offsetof expression by index into offset array 1376 long i = findMember( offsetofExpr->get_member(), structType->get_baseStruct()->get_members() ); 1377 if ( i == -1 ) return offsetofExpr; 1378 1379 Expression *offsetInd = makeOffsetIndex( ty, i ); 1380 delete offsetofExpr; 1381 return offsetInd; 1382 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( ty ) ) { 1383 // all union members are at offset zero 1384 delete offsetofExpr; 1385 return new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), std::string("0") ) ); 1386 } else return offsetofExpr; 1068 1387 } 1069 1388 … … 1126 1445 return ret; 1127 1446 } 1128 1129 Statement *Pass3::mutate( DeclStmt *declStmt ) {1130 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {1131 if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) {1132 // change initialization of a polymorphic value object1133 // to allocate storage with alloca1134 Type *declType = objectDecl->get_type();1135 UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );1136 alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) );1137 1138 delete objectDecl->get_init();1139 1140 std::list<Expression*> designators;1141 objectDecl->set_init( new SingleInit( alloc, designators, false ) ); // not constructed1142 }1143 }1144 return Mutator::mutate( declStmt );1145 }1146 1447 } // anonymous namespace 1147 1448 } // namespace GenPoly -
src/GenPoly/CopyParams.cc
r771b3c3 rd63eeb0 23 23 #include "SynTree/Statement.h" 24 24 #include "SynTree/Visitor.h" 25 #include " UniqueName.h"25 #include "Common/UniqueName.h" 26 26 27 27 namespace GenPoly { -
src/GenPoly/FindFunction.cc
r771b3c3 rd63eeb0 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // FindFunction.cc -- 7 // FindFunction.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Tue May 19 07:35:48 201513 // Update Count : 111 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri Feb 05 12:22:20 2016 13 // Update Count : 6 14 14 // 15 15 … … 19 19 #include "SynTree/Visitor.h" 20 20 21 #include "ScrubTyVars.h" 22 21 23 namespace GenPoly { 22 24 class FindFunction : public Mutator { 23 25 public: 24 26 FindFunction( std::list< FunctionType* > &functions, const TyVarMap &tyVars, bool replaceMode, FindFunctionPredicate predicate ); 25 27 26 28 virtual Type *mutate( FunctionType *functionType ); 27 29 virtual Type *mutate( PointerType *pointerType ); … … 66 68 functions.push_back( functionType ); 67 69 if ( replaceMode ) { 68 ret = new FunctionType( Type::Qualifiers(), true ); 70 // replace type parameters in function type with void* 71 ret = ScrubTyVars::scrub( functionType->clone(), tyVars ); 69 72 } // if 70 73 } // if -
src/GenPoly/GenPoly.cc
r771b3c3 rd63eeb0 36 36 } 37 37 38 bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars ) { 39 bool doTransform = false; 38 ReferenceToType *isPolyRet( FunctionType *function ) { 40 39 if ( ! function->get_returnVals().empty() ) { 41 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( function->get_returnVals().front()->get_type() ) ) { 42 43 // figure out if the return type is specified by a type parameter 44 for ( std::list< TypeDecl *>::const_iterator tyVar = function->get_forall().begin(); tyVar != function->get_forall().end(); ++tyVar ) { 45 if ( (*tyVar)->get_name() == typeInst->get_name() ) { 46 doTransform = true; 47 name = typeInst->get_name(); 48 break; 49 } // if 50 } // for 51 if ( ! doTransform && otherTyVars.find( typeInst->get_name() ) != otherTyVars.end() ) { 52 doTransform = true; 53 } // if 54 } // if 55 } // if 56 return doTransform; 57 } 58 59 bool isPolyRet( FunctionType *function, std::string &name ) { 60 TyVarMap dummyTyVars; 61 return isPolyRet( function, name, dummyTyVars ); 62 } 63 64 bool isPolyRet( FunctionType *function, const TyVarMap &otherTyVars ) { 65 std::string dummyString; 66 return isPolyRet( function, dummyString, otherTyVars ); 40 TyVarMap forallTypes; 41 makeTyVarMap( function, forallTypes ); 42 return (ReferenceToType*)isPolyType( function->get_returnVals().front()->get_type(), forallTypes ); 43 } // if 44 return 0; 67 45 } 68 46 … … 149 127 } 150 128 129 Type * hasPolyBase( Type *type, int *levels, const TypeSubstitution *env ) { 130 int dummy; 131 if ( ! levels ) { levels = &dummy; } 132 *levels = 0; 133 134 while ( true ) { 135 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { 136 type = ptr->get_base(); 137 ++(*levels); 138 } else if ( env ) { 139 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 140 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 141 type = newType; 142 } else break; 143 } else break; 144 } else break; 145 } 146 147 return isPolyType( type, env ); 148 } 149 150 Type * hasPolyBase( Type *type, const TyVarMap &tyVars, int *levels, const TypeSubstitution *env ) { 151 int dummy; 152 if ( ! levels ) { levels = &dummy; } 153 *levels = 0; 154 155 while ( true ) { 156 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { 157 type = ptr->get_base(); 158 ++(*levels); 159 } else if ( env ) { 160 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 161 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 162 type = newType; 163 } else break; 164 } else break; 165 } else break; 166 } 167 168 return isPolyType( type, tyVars, env ); 169 } 170 151 171 FunctionType * getFunctionType( Type *ty ) { 152 172 PointerType *ptrType; … … 158 178 } 159 179 180 VariableExpr * getBaseVar( Expression *expr, int *levels ) { 181 int dummy; 182 if ( ! levels ) { levels = &dummy; } 183 *levels = 0; 184 185 while ( true ) { 186 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( expr ) ) { 187 return varExpr; 188 } else if ( AddressExpr *addressExpr = dynamic_cast< AddressExpr* >( expr ) ) { 189 expr = addressExpr->get_arg(); 190 } else if ( UntypedExpr *untypedExpr = dynamic_cast< UntypedExpr* >( expr ) ) { 191 // look for compiler-inserted dereference operator 192 NameExpr *fn = dynamic_cast< NameExpr* >( untypedExpr->get_function() ); 193 if ( ! fn || fn->get_name() != std::string("*?") ) return 0; 194 expr = *untypedExpr->begin_args(); 195 } else break; 196 197 ++(*levels); 198 } 199 200 return 0; 201 } 202 203 void makeTyVarMap( Type *type, TyVarMap &tyVarMap ) { 204 for ( std::list< TypeDecl* >::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) { 205 assert( *tyVar ); 206 tyVarMap[ (*tyVar)->get_name() ] = (*tyVar)->get_kind(); 207 } 208 if ( PointerType *pointer = dynamic_cast< PointerType* >( type ) ) { 209 makeTyVarMap( pointer->get_base(), tyVarMap ); 210 } 211 } 212 160 213 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) { 161 214 for ( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) { … … 172 225 return std::string( "_alignof_" ) + SymTab::Mangler::mangleType( ty ); 173 226 } 227 228 std::string offsetofName( Type* ty ) { 229 return std::string( "_offsetof_" ) + SymTab::Mangler::mangleType( ty ); 230 } 231 174 232 } // namespace GenPoly 175 233 -
src/GenPoly/GenPoly.h
r771b3c3 rd63eeb0 20 20 #include <string> 21 21 #include <iostream> 22 #include <utility> 22 23 23 24 #include "SynTree/Declaration.h" 25 #include "SynTree/Type.h" 24 26 #include "SynTree/TypeSubstitution.h" 25 27 … … 32 34 33 35 /// true iff function has polymorphic return type 34 bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars ); 35 bool isPolyRet( FunctionType *function, std::string &name ); 36 bool isPolyRet( FunctionType *function, const TyVarMap &otherTyVars ); 36 ReferenceToType *isPolyRet( FunctionType *function ); 37 37 38 38 /// returns polymorphic type if is polymorphic type, NULL otherwise; will look up substitution in env if provided … … 48 48 Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 ); 49 49 50 /// if the base type (after dereferencing N >= 0 pointers) is a polymorphic type, returns the base type, NULL otherwise; 51 /// N will be stored in levels, if provided, will look up substitution in env if provided 52 Type *hasPolyBase( Type *type, int *levels = 0, const TypeSubstitution *env = 0 ); 53 54 /// if the base type (after dereferencing N >= 0 pointers) is a polymorphic type in tyVars, returns the base type, NULL otherwise; 55 /// N will be stored in levels, if provided, will look up substitution in env if provided 56 Type *hasPolyBase( Type *type, const TyVarMap &tyVars, int *levels = 0, const TypeSubstitution *env = 0 ); 57 50 58 /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise 51 FunctionType * 59 FunctionType *getFunctionType( Type *ty ); 52 60 61 /// If expr (after dereferencing N >= 0 pointers) is a variable expression, returns the variable expression, NULL otherwise; 62 /// N will be stored in levels, if provided 63 VariableExpr *getBaseVar( Expression *expr, int *levels = 0 ); 64 65 /// Adds the declarations in the forall list of type (and its pointed-to type if it's a pointer type) to `tyVarMap` 66 void makeTyVarMap( Type *type, TyVarMap &tyVarMap ); 67 53 68 /// Prints type variable map 54 69 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ); … … 59 74 /// Gets the name of the alignof parameter for the type 60 75 std::string alignofName( Type *ty ); 76 77 /// Gets the name of the offsetof parameter for the type 78 std::string offsetofName( Type *ty ); 61 79 } // namespace GenPoly 62 80 -
src/GenPoly/InstantiateGeneric.cc
r771b3c3 rd63eeb0 31 31 #include "SynTree/TypeSubstitution.h" 32 32 33 #include " UniqueName.h"34 #include " utility.h"33 #include "Common/UniqueName.h" 34 #include "Common/utility.h" 35 35 36 36 namespace GenPoly { -
src/GenPoly/Lvalue.cc
r771b3c3 rd63eeb0 28 28 #include "ResolvExpr/typeops.h" 29 29 30 #include " UniqueName.h"31 #include " utility.h"30 #include "Common/UniqueName.h" 31 #include "Common/utility.h" 32 32 33 33 namespace GenPoly { -
src/GenPoly/PolyMutator.cc
r771b3c3 rd63eeb0 152 152 } 153 153 154 155 /* static class method */156 void PolyMutator::makeTyVarMap( Type *type, TyVarMap &tyVarMap ) {157 for ( std::list< TypeDecl* >::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) {158 assert( *tyVar );159 tyVarMap[ (*tyVar)->get_name() ] = (*tyVar)->get_kind();160 }161 if ( PointerType *pointer = dynamic_cast< PointerType* >( type ) ) {162 makeTyVarMap( pointer->get_base(), tyVarMap );163 }164 }165 154 } // namespace GenPoly 166 155 -
src/GenPoly/PolyMutator.h
r771b3c3 rd63eeb0 51 51 virtual void doBeginScope() {} 52 52 virtual void doEndScope() {} 53 54 static void makeTyVarMap( Type *type, TyVarMap &tyVarMap );55 53 protected: 56 54 void mutateStatementList( std::list< Statement* > &statements ); -
src/GenPoly/ScrubTyVars.cc
r771b3c3 rd63eeb0 27 27 Type * ScrubTyVars::mutate( TypeInstType *typeInst ) { 28 28 TyVarMap::const_iterator tyVar = tyVars.find( typeInst->get_name() ); 29 if ( doAll ||tyVar != tyVars.end() ) {29 if ( tyVar != tyVars.end() ) { 30 30 switch ( tyVar->second ) { 31 31 case TypeDecl::Any: … … 42 42 } // if 43 43 return typeInst; 44 } 45 46 Type * ScrubTyVars::mutateAggregateType( Type *ty ) { 47 if ( isPolyType( ty, tyVars ) ) { 48 PointerType *ret = new PointerType( Type::Qualifiers(), new VoidType( ty->get_qualifiers() ) ); 49 delete ty; 50 return ret; 51 } 52 return ty; 53 } 54 55 Type * ScrubTyVars::mutate( StructInstType *structInst ) { 56 return mutateAggregateType( structInst ); 57 } 58 59 Type * ScrubTyVars::mutate( UnionInstType *unionInst ) { 60 return mutateAggregateType( unionInst ); 44 61 } 45 62 … … 65 82 66 83 Type * ScrubTyVars::mutate( PointerType *pointer ) { 67 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( pointer->get_base() ) ) { 68 if ( doAll || tyVars.find( typeInst->get_name() ) != tyVars.end() ) { 69 Type *ret = mutate( typeInst ); 70 ret->get_qualifiers() += pointer->get_qualifiers(); 71 pointer->set_base( 0 ); 72 delete pointer; 73 return ret; 74 } // if 75 } // if 84 if ( Type *polyType = isPolyType( pointer->get_base(), tyVars ) ) { 85 Type *ret = polyType->acceptMutator( *this ); 86 ret->get_qualifiers() += pointer->get_qualifiers(); 87 pointer->set_base( 0 ); 88 delete pointer; 89 return ret; 90 } 76 91 return Mutator::mutate( pointer ); 77 92 } -
src/GenPoly/ScrubTyVars.h
r771b3c3 rd63eeb0 27 27 class ScrubTyVars : public Mutator { 28 28 public: 29 ScrubTyVars( bool doAll, const TyVarMap &tyVars ): doAll( doAll ),tyVars( tyVars ) {}29 ScrubTyVars( const TyVarMap &tyVars ): tyVars( tyVars ) {} 30 30 31 /// Like scrub( SynTreeClass* ), but only applies to type variables in `tyVars` 31 /// For all polymorphic types with type variables in `tyVars`, replaces generic types, dtypes, and ftypes with the appropriate void type, 32 /// and sizeof/alignof expressions with the proper variable 32 33 template< typename SynTreeClass > 33 34 static SynTreeClass *scrub( SynTreeClass *target, const TyVarMap &tyVars ); 34 /// Replaces dtypes and ftypes with the appropriate void type, and sizeof expressions of polymorphic types with the proper variable 35 template< typename SynTreeClass > 36 static SynTreeClass *scrub( SynTreeClass *target ); 37 35 38 36 virtual Type* mutate( TypeInstType *typeInst ); 39 Expression* mutate( SizeofExpr *szeof ); 40 Expression* mutate( AlignofExpr *algnof ); 37 virtual Type* mutate( StructInstType *structInst ); 38 virtual Type* mutate( UnionInstType *unionInst ); 39 virtual Expression* mutate( SizeofExpr *szeof ); 40 virtual Expression* mutate( AlignofExpr *algnof ); 41 41 virtual Type* mutate( PointerType *pointer ); 42 42 43 private: 43 bool doAll; 44 /// Mutates (possibly generic) aggregate types appropriately 45 Type* mutateAggregateType( Type *ty ); 46 44 47 const TyVarMap &tyVars; 45 48 }; … … 48 51 template< typename SynTreeClass > 49 52 SynTreeClass * ScrubTyVars::scrub( SynTreeClass *target, const TyVarMap &tyVars ) { 50 ScrubTyVars scrubber( false,tyVars );53 ScrubTyVars scrubber( tyVars ); 51 54 return static_cast< SynTreeClass * >( target->acceptMutator( scrubber ) ); 52 55 } 53 56 54 /* static class method */55 template< typename SynTreeClass >56 SynTreeClass * ScrubTyVars::scrub( SynTreeClass *target ) {57 TyVarMap tyVars;58 ScrubTyVars scrubber( true, tyVars );59 return static_cast< SynTreeClass* >( target->acceptMutator( scrubber ) );60 }61 57 } // namespace GenPoly 62 58 -
src/GenPoly/Specialize.cc
r771b3c3 rd63eeb0 28 28 #include "SynTree/Mutator.h" 29 29 #include "ResolvExpr/FindOpenVars.h" 30 #include " UniqueName.h"31 #include " utility.h"30 #include "Common/UniqueName.h" 31 #include "Common/utility.h" 32 32 33 33 namespace GenPoly {
Note:
See TracChangeset
for help on using the changeset viewer.