Changes in / [ae8b942:d3b7937]
- Location:
- src
- Files:
-
- 1 deleted
- 26 edited
-
CodeGen/CodeGenerator.cc (modified) (34 diffs)
-
CodeGen/CodeGenerator.h (modified) (1 diff)
-
GenPoly/Box.cc (modified) (26 diffs)
-
GenPoly/GenPoly.cc (modified) (4 diffs)
-
GenPoly/GenPoly.h (modified) (4 diffs)
-
GenPoly/PolyMutator.cc (modified) (1 diff)
-
GenPoly/PolyMutator.h (modified) (1 diff)
-
GenPoly/ScopedMap.h (deleted)
-
GenPoly/ScrubTyVars.cc (modified) (3 diffs)
-
GenPoly/ScrubTyVars.h (modified) (2 diffs)
-
InitTweak/InitModel.h (modified) (1 diff)
-
ResolvExpr/AlternativeFinder.cc (modified) (1 diff)
-
ResolvExpr/AlternativeFinder.h (modified) (1 diff)
-
SymTab/Indexer.cc (modified) (1 diff)
-
SymTab/Indexer.h (modified) (1 diff)
-
SymTab/Validate.cc (modified) (7 diffs)
-
SynTree/Expression.cc (modified) (3 diffs)
-
SynTree/Expression.h (modified) (1 diff)
-
SynTree/Initializer.h (modified) (1 diff)
-
SynTree/Mutator.cc (modified) (1 diff)
-
SynTree/Mutator.h (modified) (1 diff)
-
SynTree/SynTree.h (modified) (1 diff)
-
SynTree/Visitor.cc (modified) (1 diff)
-
SynTree/Visitor.h (modified) (1 diff)
-
Tuples/FlattenTuple.cc (modified) (1 diff)
-
Tuples/FlattenTuple.h (modified) (1 diff)
-
main.cc (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
rae8b942 rd3b7937 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // CodeGenerator.cc -- 7 // CodeGenerator.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 98 98 handleStorageClass( objectDecl ); 99 99 output << genType( objectDecl->get_type(), mangleName( objectDecl ) ); 100 100 101 101 if ( objectDecl->get_init() ) { 102 102 output << " = "; … … 112 112 if ( aggDecl->get_name() != "" ) 113 113 output << aggDecl->get_name(); 114 114 115 115 std::list< Declaration * > &memb = aggDecl->get_members(); 116 116 … … 118 118 output << " {" << endl; 119 119 120 cur_indent += CodeGenerator::tabsize; 120 cur_indent += CodeGenerator::tabsize; 121 121 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++) { 122 output << indent; 122 output << indent; 123 123 (*i)->accept( *this ); 124 124 output << ";" << endl; 125 125 } 126 126 127 cur_indent -= CodeGenerator::tabsize; 127 cur_indent -= CodeGenerator::tabsize; 128 128 129 129 output << indent << "}"; … … 140 140 handleAggregate( aggregateDecl ); 141 141 } 142 142 143 143 void CodeGenerator::visit( EnumDecl *aggDecl ) { 144 144 output << "enum "; … … 146 146 if ( aggDecl->get_name() != "" ) 147 147 output << aggDecl->get_name(); 148 148 149 149 std::list< Declaration* > &memb = aggDecl->get_members(); 150 150 … … 152 152 output << " {" << endl; 153 153 154 cur_indent += CodeGenerator::tabsize; 154 cur_indent += CodeGenerator::tabsize; 155 155 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++) { 156 156 ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i ); 157 157 assert( obj ); 158 output << indent << mangleName( obj ); 158 output << indent << mangleName( obj ); 159 159 if ( obj->get_init() ) { 160 160 output << " = "; … … 164 164 } // for 165 165 166 cur_indent -= CodeGenerator::tabsize; 166 cur_indent -= CodeGenerator::tabsize; 167 167 168 168 output << indent << "}"; 169 169 } // if 170 170 } 171 171 172 172 void CodeGenerator::visit( ContextDecl *aggregateDecl ) {} 173 173 174 174 void CodeGenerator::visit( TypedefDecl *typeDecl ) { 175 175 output << "typedef "; 176 176 output << genType( typeDecl->get_base(), typeDecl->get_name() ); 177 177 } 178 178 179 179 void CodeGenerator::visit( TypeDecl *typeDecl ) { 180 180 // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes, … … 216 216 } 217 217 218 void CodeGenerator::visit( Constant *constant ) { 218 void CodeGenerator::visit( Constant *constant ) { 219 219 output << constant->get_value() ; 220 220 } … … 233 233 assert( arg != applicationExpr->get_args().end() ); 234 234 if ( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) { 235 235 236 236 *arg = addrExpr->get_arg(); 237 237 } else { … … 242 242 break; 243 243 } 244 244 245 245 default: 246 246 // do nothing 247 247 ; 248 248 } 249 249 250 250 switch ( opInfo.type ) { 251 251 case OT_INDEX: … … 256 256 output << "]"; 257 257 break; 258 258 259 259 case OT_CALL: 260 260 // there are no intrinsic definitions of the function call operator 261 261 assert( false ); 262 262 break; 263 263 264 264 case OT_PREFIX: 265 265 case OT_PREFIXASSIGN: … … 270 270 output << ")"; 271 271 break; 272 272 273 273 case OT_POSTFIX: 274 274 case OT_POSTFIXASSIGN: … … 287 287 output << ")"; 288 288 break; 289 289 290 290 case OT_CONSTANT: 291 291 case OT_LABELADDRESS: … … 306 306 } // if 307 307 } 308 308 309 309 void CodeGenerator::visit( UntypedExpr *untypedExpr ) { 310 310 if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) { … … 320 320 output << "]"; 321 321 break; 322 322 323 323 case OT_CALL: 324 324 assert( false ); 325 325 break; 326 326 327 327 case OT_PREFIX: 328 328 case OT_PREFIXASSIGN: … … 334 334 output << ")"; 335 335 break; 336 336 337 337 case OT_POSTFIX: 338 338 case OT_POSTFIXASSIGN: … … 341 341 output << opInfo.symbol; 342 342 break; 343 343 344 344 case OT_INFIX: 345 345 case OT_INFIXASSIGN: … … 351 351 output << ")"; 352 352 break; 353 353 354 354 case OT_CONSTANT: 355 355 // there are no intrinsic definitions of 0 or 1 as functions … … 369 369 } // if 370 370 } 371 371 372 372 void CodeGenerator::visit( NameExpr *nameExpr ) { 373 373 OperatorInfo opInfo; … … 379 379 } // if 380 380 } 381 381 382 382 void CodeGenerator::visit( AddressExpr *addressExpr ) { 383 383 output << "(&"; … … 408 408 output << ")"; 409 409 } 410 410 411 411 void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) { 412 412 assert( false ); 413 413 } 414 414 415 415 void CodeGenerator::visit( MemberExpr *memberExpr ) { 416 416 memberExpr->get_aggregate()->accept( *this ); 417 417 output << "." << mangleName( memberExpr->get_member() ); 418 418 } 419 419 420 420 void CodeGenerator::visit( VariableExpr *variableExpr ) { 421 421 OperatorInfo opInfo; … … 426 426 } // if 427 427 } 428 428 429 429 void CodeGenerator::visit( ConstantExpr *constantExpr ) { 430 430 assert( constantExpr->get_constant() ); 431 431 constantExpr->get_constant()->accept( *this ); 432 432 } 433 433 434 434 void CodeGenerator::visit( SizeofExpr *sizeofExpr ) { 435 435 output << "sizeof("; … … 442 442 } 443 443 444 void CodeGenerator::visit( AlignofExpr * alignofExpr ) {444 void CodeGenerator::visit( AlignofExpr *sizeofExpr ) { 445 445 // use GCC extension to avoid bumping std to C11 446 446 output << "__alignof__("; 447 if ( alignofExpr->get_isType() ) {448 output << genType( alignofExpr->get_type(), "" );449 } else { 450 alignofExpr->get_expr()->accept( *this );447 if ( sizeofExpr->get_isType() ) { 448 output << genType( sizeofExpr->get_type(), "" ); 449 } else { 450 sizeofExpr->get_expr()->accept( *this ); 451 451 } // if 452 452 output << ")"; 453 453 } 454 454 455 void CodeGenerator::visit( OffsetofExpr *offsetofExpr ) {456 // use GCC builtin457 output << "__builtin_offsetof(";458 output << genType( offsetofExpr->get_type(), "" );459 output << ", " << mangleName( offsetofExpr->get_member() );460 output << ")";461 }462 463 455 void CodeGenerator::visit( LogicalExpr *logicalExpr ) { 464 456 output << "("; … … 472 464 output << ")"; 473 465 } 474 466 475 467 void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) { 476 468 output << "("; … … 482 474 output << ")"; 483 475 } 484 476 485 477 void CodeGenerator::visit( CommaExpr *commaExpr ) { 486 478 output << "("; … … 490 482 output << ")"; 491 483 } 492 484 493 485 void CodeGenerator::visit( TupleExpr *tupleExpr ) {} 494 486 495 487 void CodeGenerator::visit( TypeExpr *typeExpr ) {} 496 488 … … 523 515 } 524 516 } 525 cur_indent -= CodeGenerator::tabsize; 517 cur_indent -= CodeGenerator::tabsize; 526 518 527 519 output << indent << "}"; … … 529 521 530 522 void CodeGenerator::visit( ExprStmt *exprStmt ) { 531 // I don't see why this check is necessary. 532 // If this starts to cause problems then put it back in, 523 // I don't see why this check is necessary. 524 // If this starts to cause problems then put it back in, 533 525 // with an explanation 534 526 assert( exprStmt ); … … 580 572 switchStmt->get_condition()->accept( *this ); 581 573 output << " ) "; 582 574 583 575 output << "{" << std::endl; 584 576 cur_indent += CodeGenerator::tabsize; … … 600 592 } // if 601 593 output << ":\n"; 602 594 603 595 std::list<Statement *> sts = caseStmt->get_statements(); 604 596 … … 617 609 if ( ! branchStmt->get_target().empty() ) 618 610 output << "goto " << branchStmt->get_target(); 619 else { 611 else { 620 612 if ( branchStmt->get_computedTarget() != 0 ) { 621 613 output << "goto *"; … … 668 660 669 661 void CodeGenerator::visit( ForStmt *forStmt ) { 670 // initialization is always hoisted, so don't 671 // bother doing anything with that 662 // initialization is always hoisted, so don't 663 // bother doing anything with that 672 664 output << "for (;"; 673 665 … … 693 685 void CodeGenerator::visit( DeclStmt *declStmt ) { 694 686 declStmt->get_decl()->accept( *this ); 695 687 696 688 if ( doSemicolon( declStmt->get_decl() ) ) { 697 689 output << ";"; -
src/CodeGen/CodeGenerator.h
rae8b942 rd3b7937 61 61 virtual void visit( SizeofExpr *sizeofExpr ); 62 62 virtual void visit( AlignofExpr *alignofExpr ); 63 virtual void visit( OffsetofExpr *offsetofExpr );64 63 virtual void visit( LogicalExpr *logicalExpr ); 65 64 virtual void visit( ConditionalExpr *conditionalExpr ); -
src/GenPoly/Box.cc
rae8b942 rd3b7937 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 … … 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-dereference126 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 { 127 111 public: 128 112 template< typename DeclClass > … … 135 119 virtual Type *mutate( PointerType *pointerType ); 136 120 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 variable141 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 );151 121 private: 152 122 }; … … 163 133 } 164 134 165 /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging166 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 prelude177 }178 179 *i = dynamic_cast< Declaration* >( (*i)->acceptMutator( mutator ) );180 assert( *i );181 } // if182 } catch( SemanticError &e ) {183 errors.append( e );184 } // try185 } // for186 if ( ! errors.isEmpty() ) {187 throw errors;188 } // if189 }190 191 135 void box( std::list< Declaration *>& translationUnit ) { 192 136 Pass1 pass1; 193 137 Pass2 pass2; 194 MemberExprFixer memberFixer;195 138 Pass3 pass3; 196 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 197 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 198 instantiateGeneric( translationUnit ); 199 mutateTranslationUnit/*All*/( translationUnit, memberFixer ); 200 mutateTranslationUnit/*All*/( translationUnit, pass3 ); 139 mutateAll( translationUnit, pass1 ); 140 mutateAll( translationUnit, pass2 ); 141 mutateAll( translationUnit, pass3 ); 201 142 } 202 143 … … 244 185 } 245 186 246 // / returns T if the given declaration is: (*?=?)(T *, T) for some T (return not checked, but maybe should be), NULL otherwise247 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 ) { 248 189 if ( decl->get_name() == "?=?" ) { 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; 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 256 200 } // if 257 201 } // if … … 261 205 } // if 262 206 } // if 263 return 0;207 return false; 264 208 } 265 209 … … 270 214 for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) { 271 215 std::string typeName; 272 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( isAssignment( *assert )) ) {273 assignOps[ type Inst->get_name()] = *assert;216 if ( checkAssignment( *assert, typeName ) ) { 217 assignOps[ typeName ] = *assert; 274 218 } // if 275 219 } // for … … 278 222 279 223 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) { 280 // if this is a polymorphic assignment function, put it in the map for this scope281 if ( ReferenceToType *refType = isAssignment( functionDecl ) ) {282 if ( ! dynamic_cast< TypeInstType* >( refType ) ) {283 scopedAssignOps.insert( refType->get_name(), functionDecl );284 }285 }286 287 224 if ( functionDecl->get_statements() ) { // empty routine body ? 288 225 doBeginScope(); … … 294 231 // process polymorphic return value 295 232 retval = 0; 296 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 ) { 297 235 retval = functionDecl->get_functionType()->get_returnVals().front(); 298 236 … … 318 256 findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter ); 319 257 } // for 320 321 258 AdapterMap & adapters = Pass1::adapters.top(); 322 259 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) { … … 369 306 } 370 307 371 Expression *Pass1::makeOffsetArray( StructInstType *ty ) {372 std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();373 374 // make a new temporary array375 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 temporary382 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 temporary395 return new VariableExpr( arrayTemp );396 }397 398 308 void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 399 309 // pass size/align for type variables … … 415 325 416 326 // add size/align for generic types to parameter list 327 //assert( ! appExpr->get_function()->get_results().empty() ); 417 328 if ( appExpr->get_function()->get_results().empty() ) return; 418 329 FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() ); … … 423 334 std::set< std::string > seenTypes; //< names for generic types we've seen 424 335 for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) { 425 Type *p olyBase = hasPolyBase( (*fnParm)->get_type(), exprTyVars);426 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase) ) {427 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 ); 428 339 if ( seenTypes.count( sizeName ) ) continue; 429 340 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() ) ); 341 assert( ! (*fnArg)->get_results().empty() ); 342 Type *argType = (*fnArg)->get_results().front(); 343 arg = appExpr->get_args().insert( arg, new SizeofExpr( argType->clone() ) ); 434 344 arg++; 435 arg = appExpr->get_args().insert( arg, new AlignofExpr( arg BaseType->clone() ) );345 arg = appExpr->get_args().insert( arg, new AlignofExpr( argType->clone() ) ); 436 346 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 }445 347 446 348 seenTypes.insert( sizeName ); … … 484 386 } 485 387 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 ) { 388 Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg ) { 389 ResolvExpr::EqvClass eqvClass; 518 390 assert( env ); 519 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 520 395 return addRetParam( appExpr, function, concrete, arg ); 521 396 } … … 617 492 assert( arg ); 618 493 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 { 619 497 if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) { 620 498 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); … … 623 501 return deref; 624 502 } // if 503 // } 625 504 } // if 626 505 return new VariableExpr( param ); … … 912 791 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin(); 913 792 914 if ( ReferenceToType *polyType = isPolyRet( function ) ) { 915 ret = addPolyRetParam( appExpr, function, polyType, arg ); 793 std::string typeName; 794 if ( isPolyRet( function, typeName ) ) { 795 ret = addPolyRetParam( appExpr, function, typeName, arg ); 916 796 } else if ( needsAdapter( function, scopeTyVars ) ) { 917 797 // std::cerr << "needs adapter: "; … … 1000 880 delete castExpr; 1001 881 } //while 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 ) ); 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 ) ); 1026 889 Expression *retParm = new NameExpr( retval->get_name() ); 1027 890 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); … … 1064 927 // push a copy of the current map 1065 928 adapters.push(adapters.top()); 1066 scopedAssignOps.beginScope();1067 929 } 1068 930 1069 931 void Pass1::doEndScope() { 1070 932 adapters.pop(); 1071 scopedAssignOps.endScope();1072 933 } 1073 934 … … 1137 998 1138 999 // move polymorphic return type to parameter list 1139 if ( isPolyRet( funcType ) ) { 1000 std::string typeName; 1001 if ( isPolyRet( funcType, typeName ) ) { 1140 1002 DeclarationWithType *ret = funcType->get_returnVals().front(); 1141 1003 ret->set_type( new PointerType( Type::Qualifiers(), ret->get_type() ) ); … … 1148 1010 std::list< DeclarationWithType *> inferredParams; 1149 1011 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 );1152 1012 // ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 ); 1153 1013 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { … … 1176 1036 1177 1037 // add size/align for generic types to parameter list 1178 std::set< std::string > seenTypes; // sizeofName for generic types we've seen1038 std::set< std::string > seenTypes; //< sizeofName for generic types we've seen 1179 1039 for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) { 1180 Type *p olyBase = hasPolyBase( (*fnParm)->get_type(), scopeTyVars);1181 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase) ) {1182 std::string sizeName = sizeofName( p olyBase );1040 Type *parmType = (*fnParm)->get_type(); 1041 if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, scopeTyVars ) ) { 1042 std::string sizeName = sizeofName( parmType ); 1183 1043 if ( seenTypes.count( sizeName ) ) continue; 1184 1044 1185 ObjectDecl *sizeParm, *alignParm , *offsetParm;1045 ObjectDecl *sizeParm, *alignParm; 1186 1046 sizeParm = newObj.clone(); 1187 1047 sizeParm->set_name( sizeName ); … … 1190 1050 1191 1051 alignParm = newObj.clone(); 1192 alignParm->set_name( alignofName( p olyBase ) );1052 alignParm->set_name( alignofName( parmType ) ); 1193 1053 last = funcType->get_parameters().insert( last, alignParm ); 1194 1054 ++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 }1202 1055 1203 1056 seenTypes.insert( sizeName ); … … 1213 1066 scopeTyVars = oldtyVars; 1214 1067 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 object1271 // to allocate storage with alloca1272 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 MemberExpr1287 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 found1292 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 types1299 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 up1304 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 aggregate1312 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 offset1327 // get offset for field1328 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 variable1335 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 variable1342 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;1348 1068 } 1349 1069 … … 1406 1126 return ret; 1407 1127 } 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 object 1133 // to allocate storage with alloca 1134 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 } 1408 1146 } // anonymous namespace 1409 1147 } // namespace GenPoly -
src/GenPoly/GenPoly.cc
rae8b942 rd3b7937 36 36 } 37 37 38 ReferenceToType *isPolyRet( FunctionType *function ) { 38 bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars ) { 39 bool doTransform = false; 39 40 if ( ! function->get_returnVals().empty() ) { 40 TyVarMap forallTypes; 41 makeTyVarMap( function, forallTypes ); 42 return (ReferenceToType*)isPolyType( function->get_returnVals().front()->get_type(), forallTypes ); 41 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( function->get_returnVals().front()->get_type() ) ) { 42 43 // figure out if the return type is specified by a type parameter 44 for ( std::list< TypeDecl *>::const_iterator tyVar = function->get_forall().begin(); tyVar != function->get_forall().end(); ++tyVar ) { 45 if ( (*tyVar)->get_name() == typeInst->get_name() ) { 46 doTransform = true; 47 name = typeInst->get_name(); 48 break; 49 } // if 50 } // for 51 if ( ! doTransform && otherTyVars.find( typeInst->get_name() ) != otherTyVars.end() ) { 52 doTransform = true; 53 } // if 54 } // if 43 55 } // if 44 return 0; 56 return doTransform; 57 } 58 59 bool isPolyRet( FunctionType *function, std::string &name ) { 60 TyVarMap dummyTyVars; 61 return isPolyRet( function, name, dummyTyVars ); 62 } 63 64 bool isPolyRet( FunctionType *function, const TyVarMap &otherTyVars ) { 65 std::string dummyString; 66 return isPolyRet( function, dummyString, otherTyVars ); 45 67 } 46 68 … … 127 149 } 128 150 129 Type * hasPolyBase( Type *type, int *levels, const TypeSubstitution *env ) {130 int dummy;131 if ( ! levels ) { levels = &dummy; }132 *levels = 0;133 134 while ( true ) {135 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {136 type = ptr->get_base();137 ++(*levels);138 } else if ( env ) {139 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {140 if ( Type *newType = env->lookup( typeInst->get_name() ) ) {141 type = newType;142 } else break;143 } else break;144 } else break;145 }146 147 return isPolyType( type, env );148 }149 150 Type * hasPolyBase( Type *type, const TyVarMap &tyVars, int *levels, const TypeSubstitution *env ) {151 int dummy;152 if ( ! levels ) { levels = &dummy; }153 *levels = 0;154 155 while ( true ) {156 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {157 type = ptr->get_base();158 ++(*levels);159 } else if ( env ) {160 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {161 if ( Type *newType = env->lookup( typeInst->get_name() ) ) {162 type = newType;163 } else break;164 } else break;165 } else break;166 }167 168 return isPolyType( type, tyVars, env );169 }170 171 151 FunctionType * getFunctionType( Type *ty ) { 172 152 PointerType *ptrType; … … 178 158 } 179 159 180 VariableExpr * getBaseVar( Expression *expr, int *levels ) {181 int dummy;182 if ( ! levels ) { levels = &dummy; }183 *levels = 0;184 185 while ( true ) {186 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( expr ) ) {187 return varExpr;188 } else if ( AddressExpr *addressExpr = dynamic_cast< AddressExpr* >( expr ) ) {189 expr = addressExpr->get_arg();190 } else if ( UntypedExpr *untypedExpr = dynamic_cast< UntypedExpr* >( expr ) ) {191 // look for compiler-inserted dereference operator192 NameExpr *fn = dynamic_cast< NameExpr* >( untypedExpr->get_function() );193 if ( ! fn || fn->get_name() != std::string("*?") ) return 0;194 expr = *untypedExpr->begin_args();195 } else break;196 197 ++(*levels);198 }199 200 return 0;201 }202 203 void makeTyVarMap( Type *type, TyVarMap &tyVarMap ) {204 for ( std::list< TypeDecl* >::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) {205 assert( *tyVar );206 tyVarMap[ (*tyVar)->get_name() ] = (*tyVar)->get_kind();207 }208 if ( PointerType *pointer = dynamic_cast< PointerType* >( type ) ) {209 makeTyVarMap( pointer->get_base(), tyVarMap );210 }211 }212 213 160 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) { 214 161 for ( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) { … … 225 172 return std::string( "_alignof_" ) + SymTab::Mangler::mangleType( ty ); 226 173 } 227 228 std::string offsetofName( Type* ty ) {229 return std::string( "_offsetof_" ) + SymTab::Mangler::mangleType( ty );230 }231 232 174 } // namespace GenPoly 233 175 -
src/GenPoly/GenPoly.h
rae8b942 rd3b7937 20 20 #include <string> 21 21 #include <iostream> 22 #include <utility>23 22 24 23 #include "SynTree/Declaration.h" 25 #include "SynTree/Type.h"26 24 #include "SynTree/TypeSubstitution.h" 27 25 … … 34 32 35 33 /// true iff function has polymorphic return type 36 ReferenceToType *isPolyRet( FunctionType *function ); 34 bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars ); 35 bool isPolyRet( FunctionType *function, std::string &name ); 36 bool isPolyRet( FunctionType *function, const TyVarMap &otherTyVars ); 37 37 38 38 /// returns polymorphic type if is polymorphic type, NULL otherwise; will look up substitution in env if provided … … 48 48 Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 ); 49 49 50 /// if the base type (after dereferencing N >= 0 pointers) is a polymorphic type, returns the base type, NULL otherwise; 51 /// N will be stored in levels, if provided, will look up substitution in env if provided 52 Type *hasPolyBase( Type *type, int *levels = 0, const TypeSubstitution *env = 0 ); 50 /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise 51 FunctionType * getFunctionType( Type *ty ); 53 52 54 /// if the base type (after dereferencing N >= 0 pointers) is a polymorphic type in tyVars, returns the base type, NULL otherwise;55 /// N will be stored in levels, if provided, will look up substitution in env if provided56 Type *hasPolyBase( Type *type, const TyVarMap &tyVars, int *levels = 0, const TypeSubstitution *env = 0 );57 58 /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise59 FunctionType *getFunctionType( Type *ty );60 61 /// If expr (after dereferencing N >= 0 pointers) is a variable expression, returns the variable expression, NULL otherwise;62 /// N will be stored in levels, if provided63 VariableExpr *getBaseVar( Expression *expr, int *levels = 0 );64 65 /// Adds the declarations in the forall list of type (and its pointed-to type if it's a pointer type) to `tyVarMap`66 void makeTyVarMap( Type *type, TyVarMap &tyVarMap );67 68 53 /// Prints type variable map 69 54 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ); … … 74 59 /// Gets the name of the alignof parameter for the type 75 60 std::string alignofName( Type *ty ); 76 77 /// Gets the name of the offsetof parameter for the type78 std::string offsetofName( Type *ty );79 61 } // namespace GenPoly 80 62 -
src/GenPoly/PolyMutator.cc
rae8b942 rd3b7937 152 152 } 153 153 154 155 /* static class method */ 156 void PolyMutator::makeTyVarMap( Type *type, TyVarMap &tyVarMap ) { 157 for ( std::list< TypeDecl* >::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) { 158 assert( *tyVar ); 159 tyVarMap[ (*tyVar)->get_name() ] = (*tyVar)->get_kind(); 160 } 161 if ( PointerType *pointer = dynamic_cast< PointerType* >( type ) ) { 162 makeTyVarMap( pointer->get_base(), tyVarMap ); 163 } 164 } 154 165 } // namespace GenPoly 155 166 -
src/GenPoly/PolyMutator.h
rae8b942 rd3b7937 51 51 virtual void doBeginScope() {} 52 52 virtual void doEndScope() {} 53 54 static void makeTyVarMap( Type *type, TyVarMap &tyVarMap ); 53 55 protected: 54 56 void mutateStatementList( std::list< Statement* > &statements ); -
src/GenPoly/ScrubTyVars.cc
rae8b942 rd3b7937 27 27 Type * ScrubTyVars::mutate( TypeInstType *typeInst ) { 28 28 TyVarMap::const_iterator tyVar = tyVars.find( typeInst->get_name() ); 29 if ( tyVar != tyVars.end() ) {29 if ( doAll || tyVar != tyVars.end() ) { 30 30 switch ( tyVar->second ) { 31 31 case TypeDecl::Any: … … 42 42 } // if 43 43 return typeInst; 44 }45 46 Type * ScrubTyVars::mutateAggregateType( Type *ty ) {47 if ( isPolyType( ty, tyVars ) ) {48 PointerType *ret = new PointerType( Type::Qualifiers(), new VoidType( ty->get_qualifiers() ) );49 delete ty;50 return ret;51 }52 return ty;53 }54 55 Type * ScrubTyVars::mutate( StructInstType *structInst ) {56 return mutateAggregateType( structInst );57 }58 59 Type * ScrubTyVars::mutate( UnionInstType *unionInst ) {60 return mutateAggregateType( unionInst );61 44 } 62 45 … … 82 65 83 66 Type * ScrubTyVars::mutate( PointerType *pointer ) { 84 if ( Type *polyType = isPolyType( pointer->get_base(), tyVars ) ) { 85 Type *ret = polyType->acceptMutator( *this ); 86 ret->get_qualifiers() += pointer->get_qualifiers(); 87 pointer->set_base( 0 ); 88 delete pointer; 89 return ret; 90 } 67 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( pointer->get_base() ) ) { 68 if ( doAll || tyVars.find( typeInst->get_name() ) != tyVars.end() ) { 69 Type *ret = mutate( typeInst ); 70 ret->get_qualifiers() += pointer->get_qualifiers(); 71 pointer->set_base( 0 ); 72 delete pointer; 73 return ret; 74 } // if 75 } // if 91 76 return Mutator::mutate( pointer ); 92 77 } -
src/GenPoly/ScrubTyVars.h
rae8b942 rd3b7937 27 27 class ScrubTyVars : public Mutator { 28 28 public: 29 ScrubTyVars( const TyVarMap &tyVars ):tyVars( tyVars ) {}29 ScrubTyVars( bool doAll, const TyVarMap &tyVars ): doAll( doAll ), tyVars( tyVars ) {} 30 30 31 /// For all polymorphic types with type variables in `tyVars`, replaces generic types, dtypes, and ftypes with the appropriate void type, 32 /// and sizeof/alignof expressions with the proper variable 31 /// Like scrub( SynTreeClass* ), but only applies to type variables in `tyVars` 33 32 template< typename SynTreeClass > 34 33 static SynTreeClass *scrub( SynTreeClass *target, const TyVarMap &tyVars ); 35 34 /// Replaces dtypes and ftypes with the appropriate void type, and sizeof expressions of polymorphic types with the proper variable 35 template< typename SynTreeClass > 36 static SynTreeClass *scrub( SynTreeClass *target ); 37 36 38 virtual Type* mutate( TypeInstType *typeInst ); 37 virtual Type* mutate( StructInstType *structInst ); 38 virtual Type* mutate( UnionInstType *unionInst ); 39 virtual Expression* mutate( SizeofExpr *szeof ); 40 virtual Expression* mutate( AlignofExpr *algnof ); 39 Expression* mutate( SizeofExpr *szeof ); 40 Expression* mutate( AlignofExpr *algnof ); 41 41 virtual Type* mutate( PointerType *pointer ); 42 43 42 private: 44 /// Mutates (possibly generic) aggregate types appropriately 45 Type* mutateAggregateType( Type *ty ); 46 43 bool doAll; 47 44 const TyVarMap &tyVars; 48 45 }; … … 51 48 template< typename SynTreeClass > 52 49 SynTreeClass * ScrubTyVars::scrub( SynTreeClass *target, const TyVarMap &tyVars ) { 53 ScrubTyVars scrubber( tyVars );50 ScrubTyVars scrubber( false, tyVars ); 54 51 return static_cast< SynTreeClass * >( target->acceptMutator( scrubber ) ); 55 52 } 56 53 54 /* static class method */ 55 template< typename SynTreeClass > 56 SynTreeClass * ScrubTyVars::scrub( SynTreeClass *target ) { 57 TyVarMap tyVars; 58 ScrubTyVars scrubber( true, tyVars ); 59 return static_cast< SynTreeClass* >( target->acceptMutator( scrubber ) ); 60 } 57 61 } // namespace GenPoly 58 62 -
src/InitTweak/InitModel.h
rae8b942 rd3b7937 73 73 void visit( SizeofExpr * ) { throw 0; } 74 74 void visit( AlignofExpr * ) { throw 0; } 75 void visit( OffsetofExpr * ) { throw 0; }76 75 void visit( AttrExpr * ) { throw 0; } 77 76 void visit( LogicalExpr * ) { throw 0; } -
src/ResolvExpr/AlternativeFinder.cc
rae8b942 rd3b7937 811 811 } 812 812 813 void AlternativeFinder::visit( OffsetofExpr *offsetofExpr ) {814 alternatives.push_back( Alternative( offsetofExpr->clone(), env, Cost::zero ) );815 }816 817 813 void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) { 818 814 // assume no polymorphism -
src/ResolvExpr/AlternativeFinder.h
rae8b942 rd3b7937 56 56 virtual void visit( ConstantExpr *constantExpr ); 57 57 virtual void visit( SizeofExpr *sizeofExpr ); 58 virtual void visit( AlignofExpr *alignofExpr ); 59 virtual void visit( OffsetofExpr *offsetofExpr ); 58 virtual void visit( AlignofExpr *sizeofExpr ); 60 59 virtual void visit( AttrExpr *attrExpr ); 61 60 virtual void visit( LogicalExpr *logicalExpr ); -
src/SymTab/Indexer.cc
rae8b942 rd3b7937 225 225 maybeAccept( alignofExpr->get_expr(), *this ); 226 226 } 227 }228 229 void Indexer::visit( OffsetofExpr *offsetofExpr ) {230 acceptAllNewScope( offsetofExpr->get_results(), *this );231 maybeAccept( offsetofExpr->get_type(), *this );232 maybeAccept( offsetofExpr->get_member(), *this );233 227 } 234 228 -
src/SymTab/Indexer.h
rae8b942 rd3b7937 55 55 virtual void visit( SizeofExpr *sizeofExpr ); 56 56 virtual void visit( AlignofExpr *alignofExpr ); 57 virtual void visit( OffsetofExpr *offsetofExpr );58 57 virtual void visit( AttrExpr *attrExpr ); 59 58 virtual void visit( LogicalExpr *logicalExpr ); -
src/SymTab/Validate.cc
rae8b942 rd3b7937 585 585 } 586 586 587 template< typename OutputIterator >588 void makeUnionFieldsAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, UnionInstType *unionType, OutputIterator out ) {589 UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );590 copy->get_args().push_back( new VariableExpr( dstParam ) );591 copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );592 copy->get_args().push_back( new SizeofExpr( unionType ) );593 594 *out++ = new ExprStmt( noLabels, copy );595 }596 597 587 //E ?=?(E volatile*, int), 598 588 // ?=?(E _Atomic volatile*, int); … … 663 653 664 654 // Make function polymorphic in same parameters as generic struct, if applicable 665 bool isGeneric = false; // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)666 655 std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters(); 667 656 std::list< Expression* > structParams; // List of matching parameters to put on types 668 657 for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) { 669 isGeneric = true;670 658 TypeDecl *typeParam = (*param)->clone(); 671 659 assignType->get_forall().push_back( typeParam ); … … 673 661 } 674 662 675 ObjectDecl *returnVal = new ObjectDecl( " _ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );663 ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 ); 676 664 assignType->get_returnVals().push_back( returnVal ); 677 665 … … 703 691 if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) { 704 692 makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) ); 705 if ( isGeneric ) makeArrayAssignment( srcParam, returnVal, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );706 693 } else { 707 694 makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) ); 708 if ( isGeneric ) makeScalarAssignment( srcParam, returnVal, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );709 695 } // if 710 696 } // if 711 697 } // for 712 if ( ! isGeneric )assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );698 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 713 699 714 700 return assignDecl; … … 719 705 720 706 // Make function polymorphic in same parameters as generic union, if applicable 721 bool isGeneric = false; // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for struct)722 707 std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters(); 723 708 std::list< Expression* > unionParams; // List of matching parameters to put on types 724 709 for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) { 725 isGeneric = true;726 710 TypeDecl *typeParam = (*param)->clone(); 727 711 assignType->get_forall().push_back( typeParam ); … … 729 713 } 730 714 731 ObjectDecl *returnVal = new ObjectDecl( " _ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );715 ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 ); 732 716 assignType->get_returnVals().push_back( returnVal ); 733 717 … … 743 727 assignDecl->fixUniqueId(); 744 728 745 makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) ); 746 if ( isGeneric ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) ); 747 748 if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 729 UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) ); 730 copy->get_args().push_back( new VariableExpr( dstParam ) ); 731 copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) ); 732 copy->get_args().push_back( new SizeofExpr( cloneWithParams( refType, unionParams ) ) ); 733 734 assignDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, copy ) ); 735 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 749 736 750 737 return assignDecl; -
src/SynTree/Expression.cc
rae8b942 rd3b7937 103 103 SizeofExpr::SizeofExpr( Expression *expr_, Expression *_aname ) : 104 104 Expression( _aname ), expr(expr_), type(0), isType(false) { 105 add_result( new BasicType( Type::Qualifiers(), BasicType:: LongUnsignedInt ) );105 add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) ); 106 106 } 107 107 108 108 SizeofExpr::SizeofExpr( Type *type_, Expression *_aname ) : 109 109 Expression( _aname ), expr(0), type(type_), isType(true) { 110 add_result( new BasicType( Type::Qualifiers(), BasicType:: LongUnsignedInt ) );110 add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) ); 111 111 } 112 112 … … 134 134 AlignofExpr::AlignofExpr( Expression *expr_, Expression *_aname ) : 135 135 Expression( _aname ), expr(expr_), type(0), isType(false) { 136 add_result( new BasicType( Type::Qualifiers(), BasicType:: LongUnsignedInt ) );136 add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) ); 137 137 } 138 138 139 139 AlignofExpr::AlignofExpr( Type *type_, Expression *_aname ) : 140 140 Expression( _aname ), expr(0), type(type_), isType(true) { 141 add_result( new BasicType( Type::Qualifiers(), BasicType:: LongUnsignedInt ) );141 add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) ); 142 142 } 143 143 … … 158 158 else 159 159 expr->print(os, indent + 2); 160 161 os << std::endl;162 Expression::print( os, indent );163 }164 165 OffsetofExpr::OffsetofExpr( Type *type_, DeclarationWithType *member_, Expression *_aname ) :166 Expression( _aname ), type(type_), member(member_) {167 add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );168 }169 170 OffsetofExpr::OffsetofExpr( const OffsetofExpr &other ) :171 Expression( other ), type( maybeClone( other.type ) ), member( maybeClone( other.member ) ) {}172 173 OffsetofExpr::~OffsetofExpr() {174 delete type;175 delete member;176 }177 178 void OffsetofExpr::print( std::ostream &os, int indent) const {179 os << std::string( indent, ' ' ) << "Offsetof Expression on member ";180 181 if ( member ) {182 os << member->get_name();183 } else {184 os << "<NULL>";185 }186 187 os << " of ";188 189 if ( type ) {190 type->print(os, indent + 2);191 } else {192 os << "<NULL>";193 }194 160 195 161 os << std::endl; -
src/SynTree/Expression.h
rae8b942 rd3b7937 319 319 }; 320 320 321 /// OffsetofExpr represents an offsetof expression322 class OffsetofExpr : public Expression {323 public:324 OffsetofExpr( Type *type, DeclarationWithType *member, Expression *_aname = 0 );325 OffsetofExpr( const OffsetofExpr &other );326 virtual ~OffsetofExpr();327 328 Type *get_type() const { return type; }329 void set_type( Type *newValue ) { type = newValue; }330 DeclarationWithType *get_member() const { return member; }331 void set_member( DeclarationWithType *newValue ) { member = newValue; }332 333 virtual OffsetofExpr *clone() const { return new OffsetofExpr( *this ); }334 virtual void accept( Visitor &v ) { v.visit( this ); }335 virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }336 virtual void print( std::ostream &os, int indent = 0 ) const;337 private:338 Type *type;339 DeclarationWithType *member;340 };341 342 321 /// AttrExpr represents an @attribute expression (like sizeof, but user-defined) 343 322 class AttrExpr : public Expression { -
src/SynTree/Initializer.h
rae8b942 rd3b7937 55 55 class SingleInit : public Initializer { 56 56 public: 57 SingleInit( Expression *value, std::list< Expression *> &designators = *(new std::list<Expression *>()));57 SingleInit( Expression *value, std::list< Expression *> &designators ); 58 58 SingleInit( const SingleInit &other ); 59 59 virtual ~SingleInit(); -
src/SynTree/Mutator.cc
rae8b942 rd3b7937 261 261 } 262 262 263 Expression *Mutator::mutate( OffsetofExpr *offsetofExpr ) {264 mutateAll( offsetofExpr->get_results(), *this );265 offsetofExpr->set_type( maybeMutate( offsetofExpr->get_type(), *this ) );266 offsetofExpr->set_member( maybeMutate( offsetofExpr->get_member(), *this ) );267 return offsetofExpr;268 }269 270 263 Expression *Mutator::mutate( AttrExpr *attrExpr ) { 271 264 mutateAll( attrExpr->get_results(), *this ); -
src/SynTree/Mutator.h
rae8b942 rd3b7937 65 65 virtual Expression* mutate( SizeofExpr *sizeofExpr ); 66 66 virtual Expression* mutate( AlignofExpr *alignofExpr ); 67 virtual Expression* mutate( OffsetofExpr *offsetofExpr );68 67 virtual Expression* mutate( AttrExpr *attrExpr ); 69 68 virtual Expression* mutate( LogicalExpr *logicalExpr ); -
src/SynTree/SynTree.h
rae8b942 rd3b7937 70 70 class SizeofExpr; 71 71 class AlignofExpr; 72 class OffsetofExpr;73 72 class AttrExpr; 74 73 class LogicalExpr; -
src/SynTree/Visitor.cc
rae8b942 rd3b7937 219 219 } 220 220 221 void Visitor::visit( OffsetofExpr *offsetofExpr ) {222 acceptAll( offsetofExpr->get_results(), *this );223 maybeAccept( offsetofExpr->get_type(), *this );224 maybeAccept( offsetofExpr->get_member(), *this );225 }226 227 221 void Visitor::visit( AttrExpr *attrExpr ) { 228 222 acceptAll( attrExpr->get_results(), *this ); -
src/SynTree/Visitor.h
rae8b942 rd3b7937 65 65 virtual void visit( SizeofExpr *sizeofExpr ); 66 66 virtual void visit( AlignofExpr *alignofExpr ); 67 virtual void visit( OffsetofExpr *offsetofExpr );68 67 virtual void visit( AttrExpr *attrExpr ); 69 68 virtual void visit( LogicalExpr *logicalExpr ); -
src/Tuples/FlattenTuple.cc
rae8b942 rd3b7937 47 47 void FlattenTuple::CollectArgs::visit( SizeofExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } 48 48 void FlattenTuple::CollectArgs::visit( AlignofExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } 49 void FlattenTuple::CollectArgs::visit( OffsetofExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); }50 49 void FlattenTuple::CollectArgs::visit( AttrExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } 51 50 void FlattenTuple::CollectArgs::visit( LogicalExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } -
src/Tuples/FlattenTuple.h
rae8b942 rd3b7937 43 43 virtual void visit( SizeofExpr * ); 44 44 virtual void visit( AlignofExpr * ); 45 virtual void visit( OffsetofExpr * );46 45 virtual void visit( AttrExpr * ); 47 46 virtual void visit( LogicalExpr * ); -
src/main.cc
rae8b942 rd3b7937 24 24 #include "SynTree/Declaration.h" 25 25 #include "SynTree/Visitor.h" 26 #include "GenPoly/InstantiateGeneric.h" 26 27 #include "GenPoly/Lvalue.h" 27 28 #include "GenPoly/Specialize.h" … … 270 271 } 271 272 273 OPTPRINT( "instantiateGeneric" ) 274 GenPoly::instantiateGeneric( translationUnit ); 272 275 OPTPRINT( "copyParams" ); 273 276 GenPoly::copyParams( translationUnit ); … … 278 281 OPTPRINT( "box" ) 279 282 GenPoly::box( translationUnit ); 280 283 281 284 // print tree right before code generation 282 285 if ( codegenp ) {
Note:
See TracChangeset
for help on using the changeset viewer.