Changeset ae357ec for src/GenPoly/Box.cc
- Timestamp:
- Mar 8, 2016, 10:25:06 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:
- 5447e09
- Parents:
- b63e376 (diff), bed4c63e (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
rb63e376 rae357ec 14 14 // 15 15 16 #include <algorithm> 17 #include <iterator> 18 #include <list> 19 #include <map> 16 20 #include <set> 17 21 #include <stack> 18 22 #include <string> 19 #include < iterator>20 #include < algorithm>23 #include <utility> 24 #include <vector> 21 25 #include <cassert> 22 26 23 27 #include "Box.h" 24 #include " InstantiateGeneric.h"28 #include "DeclMutator.h" 25 29 #include "PolyMutator.h" 26 30 #include "FindFunction.h" 31 #include "ScopedMap.h" 27 32 #include "ScrubTyVars.h" 28 33 … … 30 35 31 36 #include "SynTree/Constant.h" 32 #include "SynTree/ Type.h"37 #include "SynTree/Declaration.h" 33 38 #include "SynTree/Expression.h" 34 39 #include "SynTree/Initializer.h" 40 #include "SynTree/Mutator.h" 35 41 #include "SynTree/Statement.h" 36 #include "SynTree/Mutator.h" 42 #include "SynTree/Type.h" 43 #include "SynTree/TypeSubstitution.h" 37 44 38 45 #include "ResolvExpr/TypeEnvironment.h" … … 40 47 #include "ResolvExpr/typeops.h" 41 48 49 #include "SymTab/Indexer.h" 42 50 #include "SymTab/Mangler.h" 43 51 … … 54 62 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 55 63 64 /// Key for a unique concrete type; generic base type paired with type parameter list 65 struct ConcreteType { 66 ConcreteType() : base(NULL), params() {} 67 68 ConcreteType(AggregateDecl *_base, const std::list< Type* >& _params) : base(_base), params() { cloneAll(_params, params); } 69 70 ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); } 71 72 /// Extracts types from a list of TypeExpr* 73 ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base), params() { 74 for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) { 75 params.push_back( (*param)->get_type()->clone() ); 76 } 77 } 78 79 ConcreteType& operator= (const ConcreteType& that) { 80 deleteAll( params ); 81 params.clear(); 82 83 base = that.base; 84 cloneAll( that.params, params ); 85 86 return *this; 87 } 88 89 ~ConcreteType() { deleteAll( params ); } 90 91 bool operator== (const ConcreteType& that) const { 92 if ( base != that.base ) return false; 93 94 SymTab::Indexer dummy; 95 if ( params.size() != that.params.size() ) return false; 96 for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) { 97 if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false; 98 } 99 return true; 100 } 101 102 AggregateDecl *base; ///< Base generic type 103 std::list< Type* > params; ///< Instantiation parameters 104 }; 105 106 /// Maps a concrete type to the some value, accounting for scope 107 template< typename Value > 108 class InstantiationMap { 109 /// Information about a specific instantiation of a generic type 110 struct Instantiation { 111 ConcreteType key; ///< Instantiation parameters for this type 112 Value *value; ///< Value for this instantiation 113 114 Instantiation() : key(), value(0) {} 115 Instantiation(const ConcreteType &_key, Value *_value) : key(_key), value(_value) {} 116 }; 117 /// Map of generic types to instantiations of them 118 typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope; 119 120 std::vector< Scope > scopes; ///< list of scopes, from outermost to innermost 121 122 public: 123 /// Starts a new scope 124 void beginScope() { 125 Scope scope; 126 scopes.push_back(scope); 127 } 128 129 /// Ends a scope 130 void endScope() { 131 scopes.pop_back(); 132 } 133 134 /// Default constructor initializes with one scope 135 InstantiationMap() { beginScope(); } 136 137 // private: 138 /// Gets the value for the concrete instantiation of this type, assuming it has already been instantiated in the current scope. 139 /// Returns NULL on none such. 140 Value *lookup( AggregateDecl *generic, const std::list< TypeExpr* >& params ) { 141 ConcreteType key(generic, params); 142 // scan scopes from innermost out 143 for ( typename std::vector< Scope >::const_reverse_iterator scope = scopes.rbegin(); scope != scopes.rend(); ++scope ) { 144 // skip scope if no instantiations of this generic type 145 typename Scope::const_iterator insts = scope->find( generic ); 146 if ( insts == scope->end() ) continue; 147 // look through instantiations for matches to concrete type 148 for ( typename std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) { 149 if ( inst->key == key ) return inst->value; 150 } 151 } 152 // no matching instantiation found 153 return 0; 154 } 155 public: 156 // StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)lookup( inst->get_baseStruct(), typeSubs ); } 157 // UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)lookup( inst->get_baseUnion(), typeSubs ); } 158 159 // private: 160 /// Adds a value for a concrete type to the current scope 161 void insert( AggregateDecl *generic, const std::list< TypeExpr* > ¶ms, Value *value ) { 162 ConcreteType key(generic, params); 163 scopes.back()[generic].push_back( Instantiation( key, value ) ); 164 } 165 // public: 166 // void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { insert( inst->get_baseStruct(), typeSubs, decl ); } 167 // void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { insert( inst->get_baseUnion(), typeSubs, decl ); } 168 }; 169 170 /// Adds layout-generation functions to polymorphic types 171 class LayoutFunctionBuilder : public DeclMutator { 172 unsigned int functionNesting; // current level of nested functions 173 public: 174 LayoutFunctionBuilder() : functionNesting( 0 ) {} 175 176 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ); 177 virtual Declaration *mutate( StructDecl *structDecl ); 178 virtual Declaration *mutate( UnionDecl *unionDecl ); 179 }; 180 56 181 /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call 57 182 class Pass1 : public PolyMutator { … … 100 225 ObjectDecl *makeTemporary( Type *type ); 101 226 102 typedef std::map< std::string, DeclarationWithType *> AdapterMap;103 227 std::map< std::string, DeclarationWithType *> assignOps; 104 228 ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps; 105 std::stack< AdapterMap> adapters;229 ScopedMap< std::string, DeclarationWithType* > adapters; 106 230 DeclarationWithType *retval; 107 231 bool useRetval; … … 124 248 125 249 std::map< UniqueId, std::string > adapterName; 250 }; 251 252 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately 253 class GenericInstantiator : public DeclMutator { 254 /// Map of (generic type, parameter list) pairs to concrete type instantiations 255 InstantiationMap< AggregateDecl > instantiations; 256 /// Namer for concrete types 257 UniqueName typeNamer; 258 259 public: 260 GenericInstantiator() : DeclMutator(), instantiations(), typeNamer("_conc_") {} 261 262 virtual Type* mutate( StructInstType *inst ); 263 virtual Type* mutate( UnionInstType *inst ); 264 265 // virtual Expression* mutate( MemberExpr *memberExpr ); 266 267 virtual void doBeginScope(); 268 virtual void doEndScope(); 269 private: 270 /// Wrap instantiation lookup for structs 271 StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)instantiations.lookup( inst->get_baseStruct(), typeSubs ); } 272 /// Wrap instantiation lookup for unions 273 UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)instantiations.lookup( inst->get_baseUnion(), typeSubs ); } 274 /// Wrap instantiation insertion for structs 275 void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { instantiations.insert( inst->get_baseStruct(), typeSubs, decl ); } 276 /// Wrap instantiation insertion for unions 277 void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { instantiations.insert( inst->get_baseUnion(), typeSubs, decl ); } 126 278 }; 127 279 … … 159 311 } // anonymous namespace 160 312 161 void printAllNotBuiltin( const std::list< Declaration *>& translationUnit, std::ostream &os ) {162 for ( std::list< Declaration *>::const_iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {163 if ( ! LinkageSpec::isBuiltin( (*i)->get_linkage() ) ) {164 (*i)->print( os );165 os << std::endl;166 } // if167 } // for168 }169 170 313 /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging 171 314 template< typename MutatorType > … … 195 338 196 339 void box( std::list< Declaration *>& translationUnit ) { 340 LayoutFunctionBuilder layoutBuilder; 197 341 Pass1 pass1; 198 342 Pass2 pass2; 343 GenericInstantiator instantiator; 199 344 MemberExprFixer memberFixer; 200 345 Pass3 pass3; 346 347 layoutBuilder.mutateDeclarationList( translationUnit ); 201 348 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 202 349 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 203 instantiateGeneric( translationUnit ); 350 // instantiateGeneric( translationUnit ); 351 instantiator.mutateDeclarationList( translationUnit ); 204 352 mutateTranslationUnit/*All*/( translationUnit, memberFixer ); 205 353 mutateTranslationUnit/*All*/( translationUnit, pass3 ); 206 354 } 207 355 356 ////////////////////////////////// LayoutFunctionBuilder //////////////////////////////////////////// 357 358 DeclarationWithType *LayoutFunctionBuilder::mutate( FunctionDecl *functionDecl ) { 359 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) ); 360 mutateAll( functionDecl->get_oldDecls(), *this ); 361 ++functionNesting; 362 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) ); 363 --functionNesting; 364 return functionDecl; 365 } 366 367 /// Get a list of type declarations that will affect a layout function 368 std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) { 369 std::list< TypeDecl * > otypeDecls; 370 371 for ( std::list< TypeDecl* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) { 372 if ( (*decl)->get_kind() == TypeDecl::Any ) { 373 otypeDecls.push_back( *decl ); 374 } 375 } 376 377 return otypeDecls; 378 } 379 380 /// Adds parameters for otype layout to a function type 381 void addOtypeParams( FunctionType *layoutFnType, std::list< TypeDecl* > &otypeParams ) { 382 BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 383 384 for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) { 385 TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param ); 386 layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( ¶mType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) ); 387 layoutFnType->get_parameters().push_back( new ObjectDecl( alignofName( ¶mType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) ); 388 } 389 } 390 391 /// Builds a layout function declaration 392 FunctionDecl *buildLayoutFunctionDecl( const std::string &typeName, unsigned int functionNesting, FunctionType *layoutFnType ) { 393 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units 394 // because each unit generates copies of the default routines for each aggregate. 395 FunctionDecl *layoutDecl = new FunctionDecl( 396 "__layoutof_" + typeName, functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, layoutFnType, new CompoundStmt( noLabels ), true, false ); 397 layoutDecl->fixUniqueId(); 398 return layoutDecl; 399 } 400 401 /// Makes a unary operation 402 Expression *makeOp( const std::string &name, Expression *arg ) { 403 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) ); 404 expr->get_args().push_back( arg ); 405 return expr; 406 } 407 408 /// Makes a binary operation 409 Expression *makeOp( const std::string &name, Expression *lhs, Expression *rhs ) { 410 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) ); 411 expr->get_args().push_back( lhs ); 412 expr->get_args().push_back( rhs ); 413 return expr; 414 } 415 416 /// Returns the dereference of a local pointer variable 417 Expression *derefVar( ObjectDecl *var ) { 418 return makeOp( "*?", new VariableExpr( var ) ); 419 } 420 421 /// makes an if-statement with a single-expression if-block and no then block 422 Statement *makeCond( Expression *cond, Expression *ifPart ) { 423 return new IfStmt( noLabels, cond, new ExprStmt( noLabels, ifPart ), 0 ); 424 } 425 426 /// makes a statement that assigns rhs to lhs if lhs < rhs 427 Statement *makeAssignMax( Expression *lhs, Expression *rhs ) { 428 return makeCond( makeOp( "?<?", lhs, rhs ), makeOp( "?=?", lhs->clone(), rhs->clone() ) ); 429 } 430 431 /// makes a statement that aligns lhs to rhs (rhs should be an integer power of two) 432 Statement *makeAlignTo( Expression *lhs, Expression *rhs ) { 433 // check that the lhs is zeroed out to the level of rhs 434 Expression *ifCond = makeOp( "?&?", lhs, makeOp( "?-?", rhs, new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), "1" ) ) ) ); 435 // if not aligned, increment to alignment 436 Expression *ifExpr = makeOp( "?+=?", lhs->clone(), makeOp( "?-?", rhs->clone(), ifCond->clone() ) ); 437 return makeCond( ifCond, ifExpr ); 438 } 439 440 /// adds an expression to a compound statement 441 void addExpr( CompoundStmt *stmts, Expression *expr ) { 442 stmts->get_kids().push_back( new ExprStmt( noLabels, expr ) ); 443 } 444 445 /// adds a statement to a compound statement 446 void addStmt( CompoundStmt *stmts, Statement *stmt ) { 447 stmts->get_kids().push_back( stmt ); 448 } 449 450 Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) { 451 // do not generate layout function for "empty" tag structs 452 if ( structDecl->get_members().empty() ) return structDecl; 453 454 // get parameters that can change layout, exiting early if none 455 std::list< TypeDecl* > otypeParams = takeOtypeOnly( structDecl->get_parameters() ); 456 if ( otypeParams.empty() ) return structDecl; 457 458 // build layout function signature 459 FunctionType *layoutFnType = new FunctionType( Type::Qualifiers(), false ); 460 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 461 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType ); 462 463 ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 ); 464 layoutFnType->get_parameters().push_back( sizeParam ); 465 ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 ); 466 layoutFnType->get_parameters().push_back( alignParam ); 467 ObjectDecl *offsetParam = new ObjectDecl( "__offsetof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 ); 468 layoutFnType->get_parameters().push_back( offsetParam ); 469 addOtypeParams( layoutFnType, otypeParams ); 470 471 // build function decl 472 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl->get_name(), functionNesting, layoutFnType ); 473 474 // calculate struct layout in function body 475 476 // initialize size and alignment to 0 and 1 (will have at least one member to re-edit size 477 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "0" ) ) ) ); 478 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) ); 479 unsigned long n_members = 0; 480 bool firstMember = true; 481 for ( std::list< Declaration* >::const_iterator member = structDecl->get_members().begin(); member != structDecl->get_members().end(); ++member ) { 482 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ); 483 assert( dwt ); 484 Type *memberType = dwt->get_type(); 485 486 if ( firstMember ) { 487 firstMember = false; 488 } else { 489 // make sure all members after the first (automatically aligned at 0) are properly padded for alignment 490 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) ); 491 } 492 493 // place current size in the current offset index 494 addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from( n_members ) ) ), 495 derefVar( sizeParam ) ) ); 496 ++n_members; 497 498 // add member size to current size 499 addExpr( layoutDecl->get_statements(), makeOp( "?+=?", derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) ); 500 501 // take max of member alignment and global alignment 502 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) ); 503 } 504 // make sure the type is end-padded to a multiple of its alignment 505 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) ); 506 507 addDeclarationAfter( layoutDecl ); 508 return structDecl; 509 } 510 511 Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) { 512 // do not generate layout function for "empty" tag unions 513 if ( unionDecl->get_members().empty() ) return unionDecl; 514 515 // get parameters that can change layout, exiting early if none 516 std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() ); 517 if ( otypeParams.empty() ) return unionDecl; 518 519 // build layout function signature 520 FunctionType *layoutFnType = new FunctionType( Type::Qualifiers(), false ); 521 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 522 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType ); 523 524 ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 ); 525 layoutFnType->get_parameters().push_back( sizeParam ); 526 ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 ); 527 layoutFnType->get_parameters().push_back( alignParam ); 528 addOtypeParams( layoutFnType, otypeParams ); 529 530 // build function decl 531 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl->get_name(), functionNesting, layoutFnType ); 532 533 // calculate union layout in function body 534 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) ); 535 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) ); 536 for ( std::list< Declaration* >::const_iterator member = unionDecl->get_members().begin(); member != unionDecl->get_members().end(); ++member ) { 537 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ); 538 assert( dwt ); 539 Type *memberType = dwt->get_type(); 540 541 // take max member size and global size 542 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) ); 543 544 // take max of member alignment and global alignment 545 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) ); 546 } 547 // make sure the type is end-padded to a multiple of its alignment 548 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) ); 549 550 addDeclarationAfter( layoutDecl ); 551 return unionDecl; 552 } 553 208 554 ////////////////////////////////////////// Pass1 //////////////////////////////////////////////////// 209 555 … … 245 591 } 246 592 247 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) { 248 adapters.push(AdapterMap()); 249 } 593 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {} 250 594 251 595 /// Returns T if the given declaration is (*?=?)(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise … … 350 694 } // for 351 695 352 AdapterMap & adapters = Pass1::adapters.top();353 696 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) { 354 697 std::string mangleName = mangleAdapterName( *funType, scopeTyVars ); … … 772 1115 mangleName += makePolyMonoSuffix( originalFunction, exprTyVars ); 773 1116 774 AdapterMap & adapters = Pass1::adapters.top();775 Adapter Map::iterator adapter = adapters.find( mangleName );1117 typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter; 1118 AdapterIter adapter = adapters.find( mangleName ); 776 1119 if ( adapter == adapters.end() ) { 777 1120 // adapter has not been created yet in the current scope, so define it 778 1121 FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars ); 779 adapter = adapters.insert( adapters.begin(), std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) ); 1122 std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) ); 1123 adapter = answer.first; 780 1124 stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) ); 781 1125 } // if … … 1156 1500 1157 1501 void Pass1::doBeginScope() { 1158 // push a copy of the current map 1159 adapters.push(adapters.top()); 1502 adapters.beginScope(); 1160 1503 scopedAssignOps.beginScope(); 1161 1504 } 1162 1505 1163 1506 void Pass1::doEndScope() { 1164 adapters. pop();1507 adapters.endScope(); 1165 1508 scopedAssignOps.endScope(); 1166 1509 } … … 1309 1652 } 1310 1653 1654 //////////////////////////////////////// GenericInstantiator ////////////////////////////////////////////////// 1655 1656 /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type 1657 bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) { 1658 bool allConcrete = true; // will finish the substitution list even if they're not all concrete 1659 1660 // substitute concrete types for given parameters, and incomplete types for placeholders 1661 std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin(); 1662 std::list< Expression* >::const_iterator param = params.begin(); 1663 for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) { 1664 // switch ( (*baseParam)->get_kind() ) { 1665 // case TypeDecl::Any: { // any type is a valid substitution here; complete types can be used to instantiate generics 1666 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 1667 assert(paramType && "Aggregate parameters should be type expressions"); 1668 out.push_back( paramType->clone() ); 1669 // check that the substituted type isn't a type variable itself 1670 if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) { 1671 allConcrete = false; 1672 } 1673 // break; 1674 // } 1675 // case TypeDecl::Dtype: // dtype can be consistently replaced with void [only pointers, which become void*] 1676 // out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) ); 1677 // break; 1678 // case TypeDecl::Ftype: // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype] 1679 // out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) ); 1680 // break; 1681 // } 1682 } 1683 1684 // if any parameters left over, not done 1685 if ( baseParam != baseParams.end() ) return false; 1686 // // if not enough parameters given, substitute remaining incomplete types for placeholders 1687 // for ( ; baseParam != baseParams.end(); ++baseParam ) { 1688 // switch ( (*baseParam)->get_kind() ) { 1689 // case TypeDecl::Any: // no more substitutions here, fail early 1690 // return false; 1691 // case TypeDecl::Dtype: // dtype can be consistently replaced with void [only pointers, which become void*] 1692 // out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) ); 1693 // break; 1694 // case TypeDecl::Ftype: // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype] 1695 // out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) ); 1696 // break; 1697 // } 1698 // } 1699 1700 return allConcrete; 1701 } 1702 1703 /// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out 1704 void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs, 1705 std::list< Declaration* >& out ) { 1706 // substitute types into new members 1707 TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() ); 1708 for ( std::list< Declaration* >::const_iterator member = in.begin(); member != in.end(); ++member ) { 1709 Declaration *newMember = (*member)->clone(); 1710 subs.apply(newMember); 1711 out.push_back( newMember ); 1712 } 1713 } 1714 1715 Type* GenericInstantiator::mutate( StructInstType *inst ) { 1716 // mutate subtypes 1717 Type *mutated = Mutator::mutate( inst ); 1718 inst = dynamic_cast< StructInstType* >( mutated ); 1719 if ( ! inst ) return mutated; 1720 1721 // exit early if no need for further mutation 1722 if ( inst->get_parameters().empty() ) return inst; 1723 assert( inst->get_baseParameters() && "Base struct has parameters" ); 1724 1725 // check if type can be concretely instantiated; put substitutions into typeSubs 1726 std::list< TypeExpr* > typeSubs; 1727 if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) { 1728 deleteAll( typeSubs ); 1729 return inst; 1730 } 1731 1732 // make concrete instantiation of generic type 1733 StructDecl *concDecl = lookup( inst, typeSubs ); 1734 if ( ! concDecl ) { 1735 // set concDecl to new type, insert type declaration into statements to add 1736 concDecl = new StructDecl( typeNamer.newName( inst->get_name() ) ); 1737 substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() ); 1738 DeclMutator::addDeclaration( concDecl ); 1739 insert( inst, typeSubs, concDecl ); 1740 } 1741 StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() ); 1742 newInst->set_baseStruct( concDecl ); 1743 1744 deleteAll( typeSubs ); 1745 delete inst; 1746 return newInst; 1747 } 1748 1749 Type* GenericInstantiator::mutate( UnionInstType *inst ) { 1750 // mutate subtypes 1751 Type *mutated = Mutator::mutate( inst ); 1752 inst = dynamic_cast< UnionInstType* >( mutated ); 1753 if ( ! inst ) return mutated; 1754 1755 // exit early if no need for further mutation 1756 if ( inst->get_parameters().empty() ) return inst; 1757 assert( inst->get_baseParameters() && "Base union has parameters" ); 1758 1759 // check if type can be concretely instantiated; put substitutions into typeSubs 1760 std::list< TypeExpr* > typeSubs; 1761 if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) { 1762 deleteAll( typeSubs ); 1763 return inst; 1764 } 1765 1766 // make concrete instantiation of generic type 1767 UnionDecl *concDecl = lookup( inst, typeSubs ); 1768 if ( ! concDecl ) { 1769 // set concDecl to new type, insert type declaration into statements to add 1770 concDecl = new UnionDecl( typeNamer.newName( inst->get_name() ) ); 1771 substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() ); 1772 DeclMutator::addDeclaration( concDecl ); 1773 insert( inst, typeSubs, concDecl ); 1774 } 1775 UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() ); 1776 newInst->set_baseUnion( concDecl ); 1777 1778 deleteAll( typeSubs ); 1779 delete inst; 1780 return newInst; 1781 } 1782 1783 // /// Gets the base struct or union declaration for a member expression; NULL if not applicable 1784 // AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) { 1785 // // get variable for member aggregate 1786 // VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() ); 1787 // if ( ! varExpr ) return NULL; 1788 // 1789 // // get object for variable 1790 // ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() ); 1791 // if ( ! objectDecl ) return NULL; 1792 // 1793 // // get base declaration from object type 1794 // Type *objectType = objectDecl->get_type(); 1795 // StructInstType *structType = dynamic_cast< StructInstType* >( objectType ); 1796 // if ( structType ) return structType->get_baseStruct(); 1797 // UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ); 1798 // if ( unionType ) return unionType->get_baseUnion(); 1799 // 1800 // return NULL; 1801 // } 1802 // 1803 // /// Finds the declaration with the given name, returning decls.end() if none such 1804 // std::list< Declaration* >::const_iterator findDeclNamed( const std::list< Declaration* > &decls, const std::string &name ) { 1805 // for( std::list< Declaration* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) { 1806 // if ( (*decl)->get_name() == name ) return decl; 1807 // } 1808 // return decls.end(); 1809 // } 1810 // 1811 // Expression* Instantiate::mutate( MemberExpr *memberExpr ) { 1812 // // mutate, exiting early if no longer MemberExpr 1813 // Expression *expr = Mutator::mutate( memberExpr ); 1814 // memberExpr = dynamic_cast< MemberExpr* >( expr ); 1815 // if ( ! memberExpr ) return expr; 1816 // 1817 // // get declaration of member and base declaration of member, exiting early if not found 1818 // AggregateDecl *memberBase = getMemberBaseDecl( memberExpr ); 1819 // if ( ! memberBase ) return memberExpr; 1820 // DeclarationWithType *memberDecl = memberExpr->get_member(); 1821 // std::list< Declaration* >::const_iterator baseIt = findDeclNamed( memberBase->get_members(), memberDecl->get_name() ); 1822 // if ( baseIt == memberBase->get_members().end() ) return memberExpr; 1823 // DeclarationWithType *baseDecl = dynamic_cast< DeclarationWithType* >( *baseIt ); 1824 // if ( ! baseDecl ) return memberExpr; 1825 // 1826 // // check if stated type of the member is not the type of the member's declaration; if so, need a cast 1827 // // this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker 1828 // SymTab::Indexer dummy; 1829 // if ( ResolvExpr::typesCompatible( memberDecl->get_type(), baseDecl->get_type(), dummy ) ) return memberExpr; 1830 // else return new CastExpr( memberExpr, memberDecl->get_type() ); 1831 // } 1832 1833 void GenericInstantiator::doBeginScope() { 1834 DeclMutator::doBeginScope(); 1835 instantiations.beginScope(); 1836 } 1837 1838 void GenericInstantiator::doEndScope() { 1839 DeclMutator::doEndScope(); 1840 instantiations.endScope(); 1841 } 1842 1311 1843 ////////////////////////////////////////// MemberExprFixer //////////////////////////////////////////////////// 1312 1844
Note: See TracChangeset
for help on using the changeset viewer.