Changeset ae8b942 for src/GenPoly/Box.cc
- Timestamp:
- Jan 29, 2016, 4:36:46 PM (8 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, string, with_gc
- Children:
- 5721a6d
- Parents:
- d3b7937 (diff), 73a28e2 (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
rd3b7937 rae8b942 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 … … 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 variable110 class Pass3: public PolyMutator {125 /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference 126 class MemberExprFixer : public PolyMutator { 111 127 public: 112 128 template< typename DeclClass > … … 119 135 virtual Type *mutate( PointerType *pointerType ); 120 136 virtual Type *mutate( FunctionType *funcType ); 137 virtual Expression *mutate( MemberExpr *memberExpr ); 138 }; 139 140 /// 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 141 class Pass3 : public PolyMutator { 142 public: 143 template< typename DeclClass > 144 DeclClass *handleDecl( DeclClass *decl, Type *type ); 145 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ); 146 virtual ObjectDecl *mutate( ObjectDecl *objectDecl ); 147 virtual TypedefDecl *mutate( TypedefDecl *objectDecl ); 148 virtual TypeDecl *mutate( TypeDecl *objectDecl ); 149 virtual Type *mutate( PointerType *pointerType ); 150 virtual Type *mutate( FunctionType *funcType ); 121 151 private: 122 152 }; … … 133 163 } 134 164 165 /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging 166 template< typename MutatorType > 167 inline void mutateTranslationUnit( std::list< Declaration* > &translationUnit, MutatorType &mutator ) { 168 bool seenIntrinsic = false; 169 SemanticError errors; 170 for ( typename std::list< Declaration* >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) { 171 try { 172 if ( *i ) { 173 if ( (*i)->get_linkage() == LinkageSpec::Intrinsic ) { 174 seenIntrinsic = true; 175 } else if ( seenIntrinsic ) { 176 seenIntrinsic = false; // break on this line when debugging for end of prelude 177 } 178 179 *i = dynamic_cast< Declaration* >( (*i)->acceptMutator( mutator ) ); 180 assert( *i ); 181 } // if 182 } catch( SemanticError &e ) { 183 errors.append( e ); 184 } // try 185 } // for 186 if ( ! errors.isEmpty() ) { 187 throw errors; 188 } // if 189 } 190 135 191 void box( std::list< Declaration *>& translationUnit ) { 136 192 Pass1 pass1; 137 193 Pass2 pass2; 194 MemberExprFixer memberFixer; 138 195 Pass3 pass3; 139 mutateAll( translationUnit, pass1 ); 140 mutateAll( translationUnit, pass2 ); 141 mutateAll( translationUnit, pass3 ); 196 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 197 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 198 instantiateGeneric( translationUnit ); 199 mutateTranslationUnit/*All*/( translationUnit, memberFixer ); 200 mutateTranslationUnit/*All*/( translationUnit, pass3 ); 142 201 } 143 202 … … 185 244 } 186 245 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) {246 /// returns T if the given declaration is: (*?=?)(T *, T) for some T (return not checked, but maybe should be), NULL otherwise 247 ReferenceToType *isAssignment( DeclarationWithType *decl ) { 189 248 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 249 if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) { 250 if ( funType->get_parameters().size() == 2 ) { 251 if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) { 252 if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( pointer->get_base() ) ) { 253 if ( ReferenceToType *refType2 = dynamic_cast< ReferenceToType *>( funType->get_parameters().back()->get_type() ) ) { 254 if ( refType->get_name() == refType2->get_name() ) { 255 return refType; 200 256 } // if 201 257 } // if … … 205 261 } // if 206 262 } // if 207 return false;263 return 0; 208 264 } 209 265 … … 214 270 for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) { 215 271 std::string typeName; 216 if ( checkAssignment( *assert, typeName) ) {217 assignOps[ type Name] = *assert;272 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( isAssignment( *assert ) ) ) { 273 assignOps[ typeInst->get_name() ] = *assert; 218 274 } // if 219 275 } // for … … 222 278 223 279 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) { 280 // if this is a polymorphic assignment function, put it in the map for this scope 281 if ( ReferenceToType *refType = isAssignment( functionDecl ) ) { 282 if ( ! dynamic_cast< TypeInstType* >( refType ) ) { 283 scopedAssignOps.insert( refType->get_name(), functionDecl ); 284 } 285 } 286 224 287 if ( functionDecl->get_statements() ) { // empty routine body ? 225 288 doBeginScope(); … … 231 294 // process polymorphic return value 232 295 retval = 0; 233 std::string typeName; 234 if ( isPolyRet( functionDecl->get_functionType(), typeName ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) { 296 if ( isPolyRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) { 235 297 retval = functionDecl->get_functionType()->get_returnVals().front(); 236 298 … … 256 318 findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter ); 257 319 } // for 320 258 321 AdapterMap & adapters = Pass1::adapters.top(); 259 322 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) { … … 306 369 } 307 370 371 Expression *Pass1::makeOffsetArray( StructInstType *ty ) { 372 std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members(); 373 374 // make a new temporary array 375 Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 376 std::stringstream lenGen; 377 lenGen << baseMembers.size(); 378 ConstantExpr *lenExpr = new ConstantExpr( Constant( offsetType->clone(), lenGen.str() ) ); 379 ObjectDecl *arrayTemp = makeTemporary( new ArrayType( Type::Qualifiers(), offsetType, lenExpr, false, false ) ); 380 381 // build initializer list for temporary 382 std::list< Initializer* > inits; 383 for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) { 384 DeclarationWithType *memberDecl; 385 if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) { 386 memberDecl = origMember->clone(); 387 } else { 388 memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 ); 389 } 390 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) ); 391 } 392 arrayTemp->set_init( new ListInit( inits ) ); 393 394 // return variable pointing to temporary 395 return new VariableExpr( arrayTemp ); 396 } 397 308 398 void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 309 399 // pass size/align for type variables … … 325 415 326 416 // add size/align for generic types to parameter list 327 //assert( ! appExpr->get_function()->get_results().empty() );328 417 if ( appExpr->get_function()->get_results().empty() ) return; 329 418 FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() ); … … 334 423 std::set< std::string > seenTypes; //< names for generic types we've seen 335 424 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 );425 Type *polyBase = hasPolyBase( (*fnParm)->get_type(), exprTyVars ); 426 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) { 427 std::string sizeName = sizeofName( polyBase ); 339 428 if ( seenTypes.count( sizeName ) ) continue; 340 429 341 assert( ! (*fnArg)->get_results().empty() ); 342 Type *argType = (*fnArg)->get_results().front(); 343 arg = appExpr->get_args().insert( arg, new SizeofExpr( argType->clone() ) ); 430 VariableExpr *fnArgBase = getBaseVar( *fnArg ); 431 assert( fnArgBase && ! fnArgBase->get_results().empty() ); 432 Type *argBaseType = fnArgBase->get_results().front(); 433 arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) ); 344 434 arg++; 345 arg = appExpr->get_args().insert( arg, new AlignofExpr( arg Type->clone() ) );435 arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) ); 346 436 arg++; 437 if ( dynamic_cast< StructInstType* >( polyBase ) ) { 438 if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) { 439 arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) ); 440 arg++; 441 } else { 442 throw SemanticError( "Cannot pass non-struct type for generic struct" ); 443 } 444 } 347 445 348 446 seenTypes.insert( sizeName ); … … 386 484 } 387 485 388 Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg ) { 389 ResolvExpr::EqvClass eqvClass; 486 void Pass1::replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params ) { 487 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) { 488 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 489 assert(paramType && "Aggregate parameters should be type expressions"); 490 paramType->set_type( replaceWithConcrete( appExpr, paramType->get_type(), false ) ); 491 } 492 } 493 494 Type *Pass1::replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone ) { 495 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) { 496 Type *concrete = env->lookup( typeInst->get_name() ); 497 if ( concrete == 0 ) { 498 throw SemanticError( "Unbound type variable " + typeInst->get_name() + " in ", appExpr ); 499 } // if 500 return concrete; 501 } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) { 502 if ( doClone ) { 503 structType = structType->clone(); 504 } 505 replaceParametersWithConcrete( appExpr, structType->get_parameters() ); 506 return structType; 507 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) { 508 if ( doClone ) { 509 unionType = unionType->clone(); 510 } 511 replaceParametersWithConcrete( appExpr, unionType->get_parameters() ); 512 return unionType; 513 } 514 return type; 515 } 516 517 Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *polyType, std::list< Expression *>::iterator &arg ) { 390 518 assert( env ); 391 Type *concrete = env->lookup( typeName ); 392 if ( concrete == 0 ) { 393 throw SemanticError( "Unbound type variable " + typeName + " in ", appExpr ); 394 } // if 519 Type *concrete = replaceWithConcrete( appExpr, polyType ); 395 520 return addRetParam( appExpr, function, concrete, arg ); 396 521 } … … 492 617 assert( arg ); 493 618 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 619 if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) { 498 620 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); … … 501 623 return deref; 502 624 } // if 503 // }504 625 } // if 505 626 return new VariableExpr( param ); … … 791 912 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin(); 792 913 793 std::string typeName; 794 if ( isPolyRet( function, typeName ) ) { 795 ret = addPolyRetParam( appExpr, function, typeName, arg ); 914 if ( ReferenceToType *polyType = isPolyRet( function ) ) { 915 ret = addPolyRetParam( appExpr, function, polyType, arg ); 796 916 } else if ( needsAdapter( function, scopeTyVars ) ) { 797 917 // std::cerr << "needs adapter: "; … … 880 1000 delete castExpr; 881 1001 } //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 ) ); 1002 1003 // find assignment operator for (polymorphic) return type 1004 DeclarationWithType *assignDecl = 0; 1005 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) { 1006 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 1007 if ( assignIter == assignOps.end() ) { 1008 throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() ); 1009 } // if 1010 assignDecl = assignIter->second; 1011 } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) { 1012 ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = scopedAssignOps.find( refType->get_name() ); 1013 if ( assignIter == scopedAssignOps.end() ) { 1014 throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() ); 1015 } 1016 DeclarationWithType *functionDecl = assignIter->second; 1017 // line below cloned from FixFunction.cc 1018 assignDecl = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0, 1019 new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 ); 1020 assignDecl->set_mangleName( functionDecl->get_mangleName() ); 1021 } 1022 assert( assignDecl ); 1023 1024 // replace return statement with appropriate assignment to out parameter 1025 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignDecl ) ); 889 1026 Expression *retParm = new NameExpr( retval->get_name() ); 890 1027 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); … … 927 1064 // push a copy of the current map 928 1065 adapters.push(adapters.top()); 1066 scopedAssignOps.beginScope(); 929 1067 } 930 1068 931 1069 void Pass1::doEndScope() { 932 1070 adapters.pop(); 1071 scopedAssignOps.endScope(); 933 1072 } 934 1073 … … 998 1137 999 1138 // move polymorphic return type to parameter list 1000 std::string typeName; 1001 if ( isPolyRet( funcType, typeName ) ) { 1139 if ( isPolyRet( funcType ) ) { 1002 1140 DeclarationWithType *ret = funcType->get_returnVals().front(); 1003 1141 ret->set_type( new PointerType( Type::Qualifiers(), ret->get_type() ) ); … … 1010 1148 std::list< DeclarationWithType *> inferredParams; 1011 1149 ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 ); 1150 ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, 1151 new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 ); 1012 1152 // ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 ); 1013 1153 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { … … 1036 1176 1037 1177 // add size/align for generic types to parameter list 1038 std::set< std::string > seenTypes; // <sizeofName for generic types we've seen1178 std::set< std::string > seenTypes; // sizeofName for generic types we've seen 1039 1179 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 );1180 Type *polyBase = hasPolyBase( (*fnParm)->get_type(), scopeTyVars ); 1181 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) { 1182 std::string sizeName = sizeofName( polyBase ); 1043 1183 if ( seenTypes.count( sizeName ) ) continue; 1044 1184 1045 ObjectDecl *sizeParm, *alignParm ;1185 ObjectDecl *sizeParm, *alignParm, *offsetParm; 1046 1186 sizeParm = newObj.clone(); 1047 1187 sizeParm->set_name( sizeName ); … … 1050 1190 1051 1191 alignParm = newObj.clone(); 1052 alignParm->set_name( alignofName( p armType ) );1192 alignParm->set_name( alignofName( polyBase ) ); 1053 1193 last = funcType->get_parameters().insert( last, alignParm ); 1054 1194 ++last; 1195 1196 if ( dynamic_cast< StructInstType* >( polyBase ) ) { 1197 offsetParm = newPtr.clone(); 1198 offsetParm->set_name( offsetofName( polyBase ) ); 1199 last = funcType->get_parameters().insert( last, offsetParm ); 1200 ++last; 1201 } 1055 1202 1056 1203 seenTypes.insert( sizeName ); … … 1066 1213 scopeTyVars = oldtyVars; 1067 1214 return funcType; 1215 } 1216 1217 ////////////////////////////////////////// MemberExprFixer //////////////////////////////////////////////////// 1218 1219 template< typename DeclClass > 1220 DeclClass * MemberExprFixer::handleDecl( DeclClass *decl, Type *type ) { 1221 TyVarMap oldtyVars = scopeTyVars; 1222 makeTyVarMap( type, scopeTyVars ); 1223 1224 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) ); 1225 1226 scopeTyVars = oldtyVars; 1227 return ret; 1228 } 1229 1230 ObjectDecl * MemberExprFixer::mutate( ObjectDecl *objectDecl ) { 1231 return handleDecl( objectDecl, objectDecl->get_type() ); 1232 } 1233 1234 DeclarationWithType * MemberExprFixer::mutate( FunctionDecl *functionDecl ) { 1235 return handleDecl( functionDecl, functionDecl->get_functionType() ); 1236 } 1237 1238 TypedefDecl * MemberExprFixer::mutate( TypedefDecl *typedefDecl ) { 1239 return handleDecl( typedefDecl, typedefDecl->get_base() ); 1240 } 1241 1242 TypeDecl * MemberExprFixer::mutate( TypeDecl *typeDecl ) { 1243 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 1244 return Mutator::mutate( typeDecl ); 1245 } 1246 1247 Type * MemberExprFixer::mutate( PointerType *pointerType ) { 1248 TyVarMap oldtyVars = scopeTyVars; 1249 makeTyVarMap( pointerType, scopeTyVars ); 1250 1251 Type *ret = Mutator::mutate( pointerType ); 1252 1253 scopeTyVars = oldtyVars; 1254 return ret; 1255 } 1256 1257 Type * MemberExprFixer::mutate( FunctionType *functionType ) { 1258 TyVarMap oldtyVars = scopeTyVars; 1259 makeTyVarMap( functionType, scopeTyVars ); 1260 1261 Type *ret = Mutator::mutate( functionType ); 1262 1263 scopeTyVars = oldtyVars; 1264 return ret; 1265 } 1266 1267 Statement *MemberExprFixer::mutate( DeclStmt *declStmt ) { 1268 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) { 1269 if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) { 1270 // change initialization of a polymorphic value object 1271 // to allocate storage with alloca 1272 Type *declType = objectDecl->get_type(); 1273 UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) ); 1274 alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) ); 1275 1276 delete objectDecl->get_init(); 1277 1278 std::list<Expression*> designators; 1279 objectDecl->set_init( new SingleInit( alloc, designators ) ); 1280 } 1281 } 1282 return Mutator::mutate( declStmt ); 1283 } 1284 1285 Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) { 1286 // mutate, exiting early if no longer MemberExpr 1287 Expression *expr = Mutator::mutate( memberExpr ); 1288 memberExpr = dynamic_cast< MemberExpr* >( expr ); 1289 if ( ! memberExpr ) return expr; 1290 1291 // get declaration for base struct, exiting early if not found 1292 int varDepth; 1293 VariableExpr *varExpr = getBaseVar( memberExpr->get_aggregate(), &varDepth ); 1294 if ( ! varExpr ) return memberExpr; 1295 ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() ); 1296 if ( ! objectDecl ) return memberExpr; 1297 1298 // only mutate member expressions for polymorphic types 1299 int tyDepth; 1300 Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars, &tyDepth ); 1301 if ( ! objectType ) return memberExpr; 1302 1303 // get base aggregate for type so members can be looked up 1304 AggregateDecl *memberBase = 0; 1305 if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) { 1306 memberBase = structType->get_baseStruct(); 1307 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ) ) { 1308 memberBase = unionType->get_baseUnion(); 1309 } else return memberExpr; 1310 1311 // look up numeric index of member in base aggregate 1312 DeclarationWithType *memberDecl = memberExpr->get_member(); 1313 std::list< Declaration* > &baseDecls = memberBase->get_members(); 1314 std::list< Declaration* >::const_iterator decl = baseDecls.begin(); 1315 unsigned long i = 0; 1316 for( ; decl != baseDecls.end(); ++decl, ++i ) { 1317 if ( memberDecl->get_name() != (*decl)->get_name() ) continue; 1318 1319 if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) { 1320 if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) break; 1321 else continue; 1322 } else break; 1323 } 1324 if ( decl == baseDecls.end() ) return memberExpr; 1325 1326 // replace member expression with pointer to base plus offset 1327 // get offset for field 1328 std::stringstream offset_namer; 1329 offset_namer << i; 1330 ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) ); 1331 UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) ); 1332 fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) ); 1333 fieldOffset->get_args().push_back( fieldIndex ); 1334 // build appropriately-dereferenced variable 1335 Expression *derefdVar = varExpr->clone(); 1336 for ( int i = 1; i < varDepth; ++i ) { 1337 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 1338 derefExpr->get_args().push_back( derefdVar ); 1339 derefdVar = derefExpr; 1340 } 1341 // add offset to deref'd variable 1342 UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) ); 1343 fieldLoc->get_args().push_back( derefdVar ); 1344 fieldLoc->get_args().push_back( fieldOffset ); 1345 1346 delete memberExpr; 1347 return fieldLoc; 1068 1348 } 1069 1349 … … 1126 1406 return ret; 1127 1407 } 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 ) );1142 }1143 }1144 return Mutator::mutate( declStmt );1145 }1146 1408 } // anonymous namespace 1147 1409 } // namespace GenPoly
Note: See TracChangeset
for help on using the changeset viewer.