Changes in src/GenPoly/Box.cc [2e3a379:aa19ccf]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r2e3a379 raa19ccf 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Tue May 03 16:44:47 201613 // Update Count : 2 9511 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Feb 5 16:45:07 2016 13 // Update Count : 286 14 14 // 15 15 … … 133 133 Value *lookup( Key *key, const std::list< TypeExpr* >& params ) const { 134 134 TypeList typeList( params ); 135 135 136 136 // scan scopes for matches to the key 137 137 for ( typename InnerMap::const_iterator insts = instantiations.find( key ); insts != instantiations.end(); insts = instantiations.findNext( insts, key ) ) { … … 160 160 virtual Declaration *mutate( UnionDecl *unionDecl ); 161 161 }; 162 162 163 163 /// 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 164 164 class Pass1 : public PolyMutator { … … 208 208 ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps; ///< Currently known assignment operators 209 209 ScopedMap< std::string, DeclarationWithType* > adapters; ///< Set of adapter functions in the current scope 210 210 211 211 DeclarationWithType *retval; 212 212 bool useRetval; … … 226 226 virtual Type *mutate( PointerType *pointerType ); 227 227 virtual Type *mutate( FunctionType *funcType ); 228 228 229 229 private: 230 230 void addAdapters( FunctionType *functionType ); … … 297 297 /// Exits the type-variable scope 298 298 void endTypeScope(); 299 299 300 300 ScopedSet< std::string > knownLayouts; ///< Set of generic type layouts known in the current scope, indexed by sizeofName 301 301 ScopedSet< std::string > knownOffsets; ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName … … 351 351 PolyGenericCalculator polyCalculator; 352 352 Pass3 pass3; 353 353 354 354 layoutBuilder.mutateDeclarationList( translationUnit ); 355 355 mutateTranslationUnit/*All*/( translationUnit, pass1 ); … … 370 370 return functionDecl; 371 371 } 372 372 373 373 /// Get a list of type declarations that will affect a layout function 374 374 std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) { … … 380 380 } 381 381 } 382 382 383 383 return otypeDecls; 384 384 } … … 387 387 void addOtypeParams( FunctionType *layoutFnType, std::list< TypeDecl* > &otypeParams ) { 388 388 BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 389 389 390 390 for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) { 391 391 TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param ); … … 444 444 return makeCond( ifCond, ifExpr ); 445 445 } 446 446 447 447 /// adds an expression to a compound statement 448 448 void addExpr( CompoundStmt *stmts, Expression *expr ) { … … 454 454 stmts->get_kids().push_back( stmt ); 455 455 } 456 456 457 457 Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) { 458 458 // do not generate layout function for "empty" tag structs … … 467 467 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 468 468 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType ); 469 469 470 470 ObjectDecl *sizeParam = new ObjectDecl( sizeofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 ); 471 471 layoutFnType->get_parameters().push_back( sizeParam ); … … 497 497 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) ); 498 498 } 499 499 500 500 // place current size in the current offset index 501 501 addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from( n_members ) ) ), … … 505 505 // add member size to current size 506 506 addExpr( layoutDecl->get_statements(), makeOp( "?+=?", derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) ); 507 507 508 508 // take max of member alignment and global alignment 509 509 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) ); … … 515 515 return structDecl; 516 516 } 517 517 518 518 Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) { 519 519 // do not generate layout function for "empty" tag unions 520 520 if ( unionDecl->get_members().empty() ) return unionDecl; 521 521 522 522 // get parameters that can change layout, exiting early if none 523 523 std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() ); … … 528 528 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 529 529 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType ); 530 530 531 531 ObjectDecl *sizeParam = new ObjectDecl( sizeofName( unionDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 ); 532 532 layoutFnType->get_parameters().push_back( sizeParam ); … … 545 545 assert( dwt ); 546 546 Type *memberType = dwt->get_type(); 547 547 548 548 // take max member size and global size 549 549 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) ); 550 550 551 551 // take max of member alignment and global alignment 552 552 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) ); … … 558 558 return unionDecl; 559 559 } 560 560 561 561 ////////////////////////////////////////// Pass1 //////////////////////////////////////////////////// 562 562 … … 619 619 return 0; 620 620 } 621 621 622 622 /// returns T if the given declaration is: (*?=?)(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise 623 623 /// Only picks assignments where neither parameter is cv-qualified … … 631 631 Type *paramType2 = funType->get_parameters().back()->get_type(); 632 632 if ( paramType2->get_qualifiers() != defaultQualifiers ) return 0; 633 633 634 634 if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType1 ) ) { 635 635 Type *baseType1 = pointerType->get_base(); … … 784 784 arg++; 785 785 } else { 786 /// xxx - should this be an assertion? 787 throw SemanticError( "unbound type variable: " + tyParm->first + " in application ", appExpr ); 786 throw SemanticError( "unbound type variable in application ", appExpr ); 788 787 } // if 789 788 } // if … … 804 803 passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes ); 805 804 } 806 805 807 806 // add type information args for presently unseen types in parameter list 808 807 for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) { … … 883 882 assert( env ); 884 883 Type *concrete = replaceWithConcrete( appExpr, polyType ); 885 // add out-parameter for return value 884 // add out-parameter for return value 886 885 return addRetParam( appExpr, function, concrete, arg ); 887 886 } … … 911 910 } else if ( arg->get_results().front()->get_isLvalue() ) { 912 911 // VariableExpr and MemberExpr are lvalues; need to check this isn't coming from the second arg of a comma expression though (not an lvalue) 913 // xxx - need to test that this code is still reachable914 912 if ( CommaExpr *commaArg = dynamic_cast< CommaExpr* >( arg ) ) { 915 913 commaArg->set_arg2( new AddressExpr( commaArg->get_arg2() ) ); … … 1293 1291 } else if ( needsAdapter( function, scopeTyVars ) ) { 1294 1292 // std::cerr << "needs adapter: "; 1295 // printTyVarMap( std::cerr, scopeTyVars ); 1296 // std::cerr << *env << std::endl; 1293 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) { 1294 // std::cerr << i->first << " "; 1295 // } 1296 // std::cerr << "\n"; 1297 1297 // change the application so it calls the adapter rather than the passed function 1298 1298 ret = applyAdapter( appExpr, function, arg, scopeTyVars ); … … 1345 1345 } // if 1346 1346 } // if 1347 // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward1348 // out of the if condition.1349 bool polytype = isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env );1350 1347 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) ); 1351 if ( polytype|| needs ) {1348 if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) || needs ) { 1352 1349 Expression *ret = addrExpr->get_arg(); 1353 1350 delete ret->get_results().front(); … … 1369 1366 return new VariableExpr( functionObj ); 1370 1367 } 1371 1368 1372 1369 Statement * Pass1::mutate( ReturnStmt *returnStmt ) { 1373 1370 if ( retval && returnStmt->get_expr() ) { … … 1889 1886 } 1890 1887 } 1891 1888 1892 1889 Type *ret = Mutator::mutate( funcType ); 1893 1890 … … 1908 1905 1909 1906 std::list<Expression*> designators; 1910 objectDecl->set_init( new SingleInit( alloc, designators , false ) ); // not constructed1907 objectDecl->set_init( new SingleInit( alloc, designators ) ); 1911 1908 } 1912 1909 } … … 1949 1946 return derefdVar; 1950 1947 } 1951 1948 1952 1949 Expression *PolyGenericCalculator::mutate( MemberExpr *memberExpr ) { 1953 1950 // mutate, exiting early if no longer MemberExpr … … 2147 2144 Type *ty = offsetofExpr->get_type(); 2148 2145 if ( ! findGeneric( ty ) ) return offsetofExpr; 2149 2146 2150 2147 if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) { 2151 2148 // replace offsetof expression by index into offset array
Note: See TracChangeset
for help on using the changeset viewer.