Changes in src/GenPoly/Box.cc [bd85400:974906e2]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
rbd85400 r974906e2 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 : Fri Feb 5 16:45:07201613 // Update Count : 2 8611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Thu Jan 07 13:40:05 2016 13 // Update Count : 219 14 14 // 15 15 … … 22 22 23 23 #include "Box.h" 24 #include "InstantiateGeneric.h"25 24 #include "PolyMutator.h" 26 25 #include "FindFunction.h" 27 #include "ScopedMap.h"28 26 #include "ScrubTyVars.h" 29 27 … … 41 39 #include "SymTab/Mangler.h" 42 40 43 #include " Common/SemanticError.h"44 #include " Common/UniqueName.h"45 #include " Common/utility.h"41 #include "SemanticError.h" 42 #include "UniqueName.h" 43 #include "utility.h" 46 44 47 45 #include <ext/functional> // temporary … … 71 69 virtual void doEndScope(); 72 70 private: 73 /// Makes a new temporary array holding the offsets of the fields of `type`, and returns a new variable expression referencing it74 Expression *makeOffsetArray( StructInstType *type );75 /// passes extra type parameters into a polymorphic function application76 71 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 value78 72 Expression *addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, 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 ); 73 Expression *addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg ); 86 74 Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 87 75 void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars ); 88 76 void boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 89 77 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 operations91 78 void findAssignOps( const std::list< TypeDecl *> &forall ); 92 79 void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars ); 93 80 FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ); 94 /// Replaces intrinsic operator functions with their arithmetic desugaring95 81 Expression *handleIntrinsics( ApplicationExpr *appExpr ); 96 /// Inserts a new temporary variable into the current scope with an auto-generated name97 82 ObjectDecl *makeTemporary( Type *type ); 98 83 99 84 typedef std::map< std::string, DeclarationWithType *> AdapterMap; 100 85 std::map< std::string, DeclarationWithType *> assignOps; 101 ScopedMap< std::string, DeclarationWithType *> scopedAssignOps;102 86 std::stack< AdapterMap > adapters; 103 87 DeclarationWithType *retval; … … 123 107 }; 124 108 125 /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference; 126 /// also fixes offsetof expressions. 127 class MemberExprFixer : public PolyMutator { 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 { 128 111 public: 129 112 template< typename DeclClass > … … 136 119 virtual Type *mutate( PointerType *pointerType ); 137 120 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 variable143 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 );153 121 private: 154 122 }; … … 165 133 } 166 134 167 /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging168 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 prelude179 }180 181 *i = dynamic_cast< Declaration* >( (*i)->acceptMutator( mutator ) );182 assert( *i );183 } // if184 } catch( SemanticError &e ) {185 errors.append( e );186 } // try187 } // for188 if ( ! errors.isEmpty() ) {189 throw errors;190 } // if191 }192 193 135 void box( std::list< Declaration *>& translationUnit ) { 194 136 Pass1 pass1; 195 137 Pass2 pass2; 196 MemberExprFixer memberFixer;197 138 Pass3 pass3; 198 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 199 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 200 instantiateGeneric( translationUnit ); 201 mutateTranslationUnit/*All*/( translationUnit, memberFixer ); 202 mutateTranslationUnit/*All*/( translationUnit, pass3 ); 139 mutateAll( translationUnit, pass1 ); 140 mutateAll( translationUnit, pass2 ); 141 mutateAll( translationUnit, pass3 ); 203 142 } 204 143 … … 246 185 } 247 186 248 // / returns T if the given declaration is: (*?=?)(T *, T) for some T (return not checked, but maybe should be), NULL otherwise249 ReferenceToType *isAssignment( DeclarationWithType *decl) {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 ) { 250 189 if ( decl->get_name() == "?=?" ) { 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; 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 258 200 } // if 259 201 } // if … … 263 205 } // if 264 206 } // if 265 return 0;207 return false; 266 208 } 267 209 … … 272 214 for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) { 273 215 std::string typeName; 274 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( isAssignment( *assert )) ) {275 assignOps[ type Inst->get_name()] = *assert;216 if ( checkAssignment( *assert, typeName ) ) { 217 assignOps[ typeName ] = *assert; 276 218 } // if 277 219 } // for … … 280 222 281 223 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) { 282 // if this is a polymorphic assignment function, put it in the map for this scope283 if ( ReferenceToType *refType = isAssignment( functionDecl ) ) {284 if ( ! dynamic_cast< TypeInstType* >( refType ) ) {285 scopedAssignOps.insert( refType->get_name(), functionDecl );286 }287 }288 289 224 if ( functionDecl->get_statements() ) { // empty routine body ? 290 225 doBeginScope(); … … 296 231 // process polymorphic return value 297 232 retval = 0; 298 if ( isPolyRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) { 233 std::string typeName; 234 if ( isPolyRet( functionDecl->get_functionType(), typeName ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) { 299 235 retval = functionDecl->get_functionType()->get_returnVals().front(); 300 236 … … 320 256 findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter ); 321 257 } // for 322 323 258 AdapterMap & adapters = Pass1::adapters.top(); 324 259 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) { … … 369 304 return condExpr; 370 305 371 }372 373 Expression *Pass1::makeOffsetArray( StructInstType *ty ) {374 std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();375 376 // make a new temporary array377 Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );378 std::stringstream lenGen;379 lenGen << baseMembers.size();380 ConstantExpr *lenExpr = new ConstantExpr( Constant( offsetType->clone(), lenGen.str() ) );381 ObjectDecl *arrayTemp = makeTemporary( new ArrayType( Type::Qualifiers(), offsetType, lenExpr, false, false ) );382 383 // build initializer list for temporary384 std::list< Initializer* > inits;385 for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) {386 DeclarationWithType *memberDecl;387 if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) {388 memberDecl = origMember->clone();389 } else {390 memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 );391 }392 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) );393 }394 arrayTemp->set_init( new ListInit( inits ) );395 396 // return variable pointing to temporary397 return new VariableExpr( arrayTemp );398 306 } 399 307 … … 417 325 418 326 // add size/align for generic types to parameter list 327 //assert( ! appExpr->get_function()->get_results().empty() ); 419 328 if ( appExpr->get_function()->get_results().empty() ) return; 420 329 FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() ); … … 425 334 std::set< std::string > seenTypes; //< names for generic types we've seen 426 335 for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) { 427 Type *p olyBase = hasPolyBase( (*fnParm)->get_type(), exprTyVars);428 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase) ) {429 std::string sizeName = sizeofName( p olyBase );336 Type *parmType = (*fnParm)->get_type(); 337 if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, exprTyVars ) ) { 338 std::string sizeName = sizeofName( parmType ); 430 339 if ( seenTypes.count( sizeName ) ) continue; 431 340 432 VariableExpr *fnArgBase = getBaseVar( *fnArg ); 433 assert( fnArgBase && ! fnArgBase->get_results().empty() ); 434 Type *argBaseType = fnArgBase->get_results().front(); 435 arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) ); 341 assert( ! (*fnArg)->get_results().empty() ); 342 Type *argType = (*fnArg)->get_results().front(); 343 arg = appExpr->get_args().insert( arg, new SizeofExpr( argType->clone() ) ); 436 344 arg++; 437 arg = appExpr->get_args().insert( arg, new AlignofExpr( arg BaseType->clone() ) );345 arg = appExpr->get_args().insert( arg, new AlignofExpr( argType->clone() ) ); 438 346 arg++; 439 if ( dynamic_cast< StructInstType* >( polyBase ) ) {440 if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) {441 arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) );442 arg++;443 } else {444 throw SemanticError( "Cannot pass non-struct type for generic struct" );445 }446 }447 347 448 348 seenTypes.insert( sizeName ); … … 486 386 } 487 387 488 void Pass1::replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params ) { 489 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) { 490 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 491 assert(paramType && "Aggregate parameters should be type expressions"); 492 paramType->set_type( replaceWithConcrete( appExpr, paramType->get_type(), false ) ); 493 } 494 } 495 496 Type *Pass1::replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone ) { 497 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) { 498 Type *concrete = env->lookup( typeInst->get_name() ); 499 if ( concrete == 0 ) { 500 throw SemanticError( "Unbound type variable " + typeInst->get_name() + " in ", appExpr ); 501 } // if 502 return concrete; 503 } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) { 504 if ( doClone ) { 505 structType = structType->clone(); 506 } 507 replaceParametersWithConcrete( appExpr, structType->get_parameters() ); 508 return structType; 509 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) { 510 if ( doClone ) { 511 unionType = unionType->clone(); 512 } 513 replaceParametersWithConcrete( appExpr, unionType->get_parameters() ); 514 return unionType; 515 } 516 return type; 517 } 518 519 Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *polyType, std::list< Expression *>::iterator &arg ) { 388 Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg ) { 389 ResolvExpr::EqvClass eqvClass; 520 390 assert( env ); 521 Type *concrete = replaceWithConcrete( appExpr, polyType ); 391 Type *concrete = env->lookup( typeName ); 392 if ( concrete == 0 ) { 393 throw SemanticError( "Unbound type variable " + typeName + " in ", appExpr ); 394 } // if 522 395 return addRetParam( appExpr, function, concrete, arg ); 523 396 } … … 531 404 std::string adapterName = makeAdapterName( mangleName ); 532 405 533 // cast adaptee to void (*)(), since it may have any type inside a polymorphic function 534 Type * adapteeType = new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ); 535 appExpr->get_args().push_front( new CastExpr( appExpr->get_function(), adapteeType ) ); 406 appExpr->get_args().push_front( appExpr->get_function() ); 536 407 appExpr->set_function( new NameExpr( adapterName ) ); 537 408 … … 541 412 void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) { 542 413 assert( ! arg->get_results().empty() ); 543 if ( isPolyType( param, exprTyVars ) ) { 414 // if ( ! dynamic_cast< PointerType *>( arg->get_results().front() ) ) { 415 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( param ); 416 if ( typeInst && exprTyVars.find( typeInst->get_name() ) != exprTyVars.end() ) { 544 417 if ( dynamic_cast< TypeInstType *>( arg->get_results().front() ) ) { 545 418 // if the argument's type is a type parameter, we don't need to box again! … … 549 422 arg = new AddressExpr( arg ); 550 423 } else { 551 // use type computed in unification to declare boxed variables 552 Type * newType = param->clone(); 553 if ( env ) env->apply( newType ); 554 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, newType, 0 ); 424 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, arg->get_results().front()->clone(), 0 ); 555 425 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right??? 556 426 stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) ); … … 562 432 } // if 563 433 } // if 564 } 565 566 /// cast parameters to polymorphic functions so that types are replaced with 567 /// void * if they are type parameters in the formal type. 568 /// this gets rid of warnings from gcc. 434 // } 435 } 436 569 437 void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) { 570 Type * newType = formal->clone(); 571 if ( getFunctionType( newType ) ) { 572 newType = ScrubTyVars::scrub( newType, tyVars ); 438 Type *newType = formal->clone(); 439 std::list< FunctionType *> functions; 440 // instead of functions needing adapters, this really ought to look for 441 // any function mentioning a polymorphic type 442 findAndReplaceFunction( newType, functions, tyVars, needsAdapter ); 443 if ( ! functions.empty() ) { 573 444 actual = new CastExpr( actual, newType ); 445 } else { 446 delete newType; 574 447 } // if 575 448 } … … 622 495 assert( arg ); 623 496 if ( isPolyType( realParam->get_type(), tyVars ) ) { 497 // if ( dynamic_cast< PointerType *>( arg->get_type() ) ) { 498 // return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() ); 499 // } else { 624 500 if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) { 625 501 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); … … 628 504 return deref; 629 505 } // if 506 // } 630 507 } // if 631 508 return new VariableExpr( param ); … … 917 794 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin(); 918 795 919 if ( ReferenceToType *polyType = isPolyRet( function ) ) { 920 ret = addPolyRetParam( appExpr, function, polyType, arg ); 796 std::string typeName; 797 if ( isPolyRet( function, typeName ) ) { 798 ret = addPolyRetParam( appExpr, function, typeName, arg ); 921 799 } else if ( needsAdapter( function, scopeTyVars ) ) { 922 800 // std::cerr << "needs adapter: "; … … 1005 883 delete castExpr; 1006 884 } //while 1007 1008 // find assignment operator for (polymorphic) return type 1009 DeclarationWithType *assignDecl = 0; 1010 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) { 1011 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 1012 if ( assignIter == assignOps.end() ) { 1013 throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() ); 1014 } // if 1015 assignDecl = assignIter->second; 1016 } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) { 1017 ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = scopedAssignOps.find( refType->get_name() ); 1018 if ( assignIter == scopedAssignOps.end() ) { 1019 throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() ); 1020 } 1021 DeclarationWithType *functionDecl = assignIter->second; 1022 // line below cloned from FixFunction.cc 1023 assignDecl = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0, 1024 new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 ); 1025 assignDecl->set_mangleName( functionDecl->get_mangleName() ); 1026 } 1027 assert( assignDecl ); 1028 1029 // replace return statement with appropriate assignment to out parameter 1030 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignDecl ) ); 885 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ); 886 assert( typeInst ); 887 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 888 if ( assignIter == assignOps.end() ) { 889 throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() ); 890 } // if 891 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) ); 1031 892 Expression *retParm = new NameExpr( retval->get_name() ); 1032 893 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); … … 1069 930 // push a copy of the current map 1070 931 adapters.push(adapters.top()); 1071 scopedAssignOps.beginScope();1072 932 } 1073 933 1074 934 void Pass1::doEndScope() { 1075 935 adapters.pop(); 1076 scopedAssignOps.endScope();1077 936 } 1078 937 … … 1142 1001 1143 1002 // move polymorphic return type to parameter list 1144 if ( isPolyRet( funcType ) ) { 1003 std::string typeName; 1004 if ( isPolyRet( funcType, typeName ) ) { 1145 1005 DeclarationWithType *ret = funcType->get_returnVals().front(); 1146 1006 ret->set_type( new PointerType( Type::Qualifiers(), ret->get_type() ) ); … … 1153 1013 std::list< DeclarationWithType *> inferredParams; 1154 1014 ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 ); 1155 ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0,1156 new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 );1157 1015 // ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 ); 1158 1016 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { … … 1181 1039 1182 1040 // add size/align for generic types to parameter list 1183 std::set< std::string > seenTypes; // sizeofName for generic types we've seen1041 std::set< std::string > seenTypes; //< sizeofName for generic types we've seen 1184 1042 for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) { 1185 Type *p olyBase = hasPolyBase( (*fnParm)->get_type(), scopeTyVars);1186 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase) ) {1187 std::string sizeName = sizeofName( p olyBase );1043 Type *parmType = (*fnParm)->get_type(); 1044 if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, scopeTyVars ) ) { 1045 std::string sizeName = sizeofName( parmType ); 1188 1046 if ( seenTypes.count( sizeName ) ) continue; 1189 1047 1190 ObjectDecl *sizeParm, *alignParm , *offsetParm;1048 ObjectDecl *sizeParm, *alignParm; 1191 1049 sizeParm = newObj.clone(); 1192 1050 sizeParm->set_name( sizeName ); … … 1195 1053 1196 1054 alignParm = newObj.clone(); 1197 alignParm->set_name( alignofName( p olyBase ) );1055 alignParm->set_name( alignofName( parmType ) ); 1198 1056 last = funcType->get_parameters().insert( last, alignParm ); 1199 1057 ++last; 1200 1201 if ( dynamic_cast< StructInstType* >( polyBase ) ) {1202 offsetParm = newPtr.clone();1203 offsetParm->set_name( offsetofName( polyBase ) );1204 last = funcType->get_parameters().insert( last, offsetParm );1205 ++last;1206 }1207 1058 1208 1059 seenTypes.insert( sizeName ); … … 1218 1069 scopeTyVars = oldtyVars; 1219 1070 return funcType; 1220 }1221 1222 ////////////////////////////////////////// MemberExprFixer ////////////////////////////////////////////////////1223 1224 template< typename DeclClass >1225 DeclClass * MemberExprFixer::handleDecl( DeclClass *decl, Type *type ) {1226 TyVarMap oldtyVars = scopeTyVars;1227 makeTyVarMap( type, scopeTyVars );1228 1229 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );1230 1231 scopeTyVars = oldtyVars;1232 return ret;1233 }1234 1235 ObjectDecl * MemberExprFixer::mutate( ObjectDecl *objectDecl ) {1236 return handleDecl( objectDecl, objectDecl->get_type() );1237 }1238 1239 DeclarationWithType * MemberExprFixer::mutate( FunctionDecl *functionDecl ) {1240 return handleDecl( functionDecl, functionDecl->get_functionType() );1241 }1242 1243 TypedefDecl * MemberExprFixer::mutate( TypedefDecl *typedefDecl ) {1244 return handleDecl( typedefDecl, typedefDecl->get_base() );1245 }1246 1247 TypeDecl * MemberExprFixer::mutate( TypeDecl *typeDecl ) {1248 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();1249 return Mutator::mutate( typeDecl );1250 }1251 1252 Type * MemberExprFixer::mutate( PointerType *pointerType ) {1253 TyVarMap oldtyVars = scopeTyVars;1254 makeTyVarMap( pointerType, scopeTyVars );1255 1256 Type *ret = Mutator::mutate( pointerType );1257 1258 scopeTyVars = oldtyVars;1259 return ret;1260 }1261 1262 Type * MemberExprFixer::mutate( FunctionType *functionType ) {1263 TyVarMap oldtyVars = scopeTyVars;1264 makeTyVarMap( functionType, scopeTyVars );1265 1266 Type *ret = Mutator::mutate( functionType );1267 1268 scopeTyVars = oldtyVars;1269 return ret;1270 }1271 1272 Statement *MemberExprFixer::mutate( DeclStmt *declStmt ) {1273 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {1274 if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) {1275 // change initialization of a polymorphic value object1276 // to allocate storage with alloca1277 Type *declType = objectDecl->get_type();1278 UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );1279 alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) );1280 1281 delete objectDecl->get_init();1282 1283 std::list<Expression*> designators;1284 objectDecl->set_init( new SingleInit( alloc, designators ) );1285 }1286 }1287 return Mutator::mutate( declStmt );1288 }1289 1290 /// Finds the member in the base list that matches the given declaration; returns its index, or -1 if not present1291 long findMember( DeclarationWithType *memberDecl, std::list< Declaration* > &baseDecls ) {1292 long i = 0;1293 for(std::list< Declaration* >::const_iterator decl = baseDecls.begin(); decl != baseDecls.end(); ++decl, ++i ) {1294 if ( memberDecl->get_name() != (*decl)->get_name() ) continue;1295 1296 if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) {1297 if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) return i;1298 else continue;1299 } else return i;1300 }1301 return -1;1302 }1303 1304 /// Returns an index expression into the offset array for a type1305 Expression *makeOffsetIndex( Type *objectType, long i ) {1306 std::stringstream offset_namer;1307 offset_namer << i;1308 ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) );1309 UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) );1310 fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) );1311 fieldOffset->get_args().push_back( fieldIndex );1312 return fieldOffset;1313 }1314 1315 /// Returns an expression dereferenced n times1316 Expression *makeDerefdVar( Expression *derefdVar, long n ) {1317 for ( int i = 1; i < n; ++i ) {1318 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );1319 derefExpr->get_args().push_back( derefdVar );1320 derefdVar = derefExpr;1321 }1322 return derefdVar;1323 }1324 1325 Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) {1326 // mutate, exiting early if no longer MemberExpr1327 Expression *expr = Mutator::mutate( memberExpr );1328 memberExpr = dynamic_cast< MemberExpr* >( expr );1329 if ( ! memberExpr ) return expr;1330 1331 // get declaration for base struct, exiting early if not found1332 int varDepth;1333 VariableExpr *varExpr = getBaseVar( memberExpr->get_aggregate(), &varDepth );1334 if ( ! varExpr ) return memberExpr;1335 ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );1336 if ( ! objectDecl ) return memberExpr;1337 1338 // only mutate member expressions for polymorphic types1339 int tyDepth;1340 Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars, &tyDepth );1341 if ( ! objectType ) return memberExpr;1342 1343 if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) {1344 // look up offset index1345 long i = findMember( memberExpr->get_member(), structType->get_baseStruct()->get_members() );1346 if ( i == -1 ) return memberExpr;1347 1348 // replace member expression with pointer to base plus offset1349 UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) );1350 fieldLoc->get_args().push_back( makeDerefdVar( varExpr->clone(), varDepth ) );1351 fieldLoc->get_args().push_back( makeOffsetIndex( objectType, i ) );1352 1353 delete memberExpr;1354 return fieldLoc;1355 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ) ) {1356 // union members are all at offset zero, so build appropriately-dereferenced variable1357 Expression *derefdVar = makeDerefdVar( varExpr->clone(), varDepth );1358 delete memberExpr;1359 return derefdVar;1360 } else return memberExpr;1361 }1362 1363 Expression *MemberExprFixer::mutate( OffsetofExpr *offsetofExpr ) {1364 // mutate, exiting early if no longer OffsetofExpr1365 Expression *expr = Mutator::mutate( offsetofExpr );1366 offsetofExpr = dynamic_cast< OffsetofExpr* >( expr );1367 if ( ! offsetofExpr ) return expr;1368 1369 // only mutate expressions for polymorphic structs/unions1370 Type *ty = isPolyType( offsetofExpr->get_type(), scopeTyVars );1371 if ( ! ty ) return offsetofExpr;1372 1373 if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) {1374 // replace offsetof expression by index into offset array1375 long i = findMember( offsetofExpr->get_member(), structType->get_baseStruct()->get_members() );1376 if ( i == -1 ) return offsetofExpr;1377 1378 Expression *offsetInd = makeOffsetIndex( ty, i );1379 delete offsetofExpr;1380 return offsetInd;1381 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( ty ) ) {1382 // all union members are at offset zero1383 delete offsetofExpr;1384 return new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), std::string("0") ) );1385 } else return offsetofExpr;1386 1071 } 1387 1072 … … 1444 1129 return ret; 1445 1130 } 1131 1132 Statement *Pass3::mutate( DeclStmt *declStmt ) { 1133 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) { 1134 if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) { 1135 // change initialization of a polymorphic value object 1136 // to allocate storage with alloca 1137 Type *declType = objectDecl->get_type(); 1138 UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) ); 1139 alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) ); 1140 1141 delete objectDecl->get_init(); 1142 1143 std::list<Expression*> designators; 1144 objectDecl->set_init( new SingleInit( alloc, designators, false ) ); // not constructed 1145 } 1146 } 1147 return Mutator::mutate( declStmt ); 1148 } 1446 1149 } // anonymous namespace 1447 1150 } // namespace GenPoly
Note:
See TracChangeset
for help on using the changeset viewer.