Changeset 083cf31
- Timestamp:
- Jan 7, 2016, 11:28:48 AM (9 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, with_gc
- Children:
- 1e9d87b
- Parents:
- 267cb3d (diff), de91427b (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. - Files:
-
- 2 added
- 56 edited
Legend:
- Unmodified
- Added
- Removed
-
INSTALL
r267cb3d r083cf31 19 19 cfa-cc components. Some components will be installed in /some/directory/bin, 20 20 others in /some/directory/lib. If unspecified, this defaults to /usr/local. 21 If you wish to use (a subdirectory of) your home directory, ${HOME}/some/dir 22 works, but it is important not to put quotes around the directory path; 23 Cforall may appear to build, but the installed version may not work properly. 21 24 22 25 --with-backend-compiler=PROGRAM specifies the installed path of gcc. It -
configure
r267cb3d r083cf31 2999 2999 cfa_incdir="${cfa_prefix}/include" 3000 3000 else 3001 cfa_incdir=${ $includedir}3001 cfa_incdir=${includedir} 3002 3002 fi 3003 3003 -
configure.ac
r267cb3d r083cf31 41 41 cfa_incdir="${cfa_prefix}/include" 42 42 else 43 cfa_incdir=${ $includedir}43 cfa_incdir=${includedir} 44 44 fi 45 45 AC_DEFINE_UNQUOTED(CFA_INCDIR, "${cfa_incdir}", [Location of include files.]) -
doc/refrat/refrat.tex
r267cb3d r083cf31 112 112 \lstset{ 113 113 language=CFA, 114 columns=f ullflexible,114 columns=flexible, 115 115 basicstyle=\sf\small, 116 116 tabsize=4, 117 117 xleftmargin=\parindent, 118 118 escapechar=@, 119 %fancyvrb=true,119 keepspaces=true, 120 120 %showtabs=true, 121 keepspaces=true, 122 showtabs=true, 123 tab=, 121 %tab=\rightarrowfill, 124 122 }% 125 123 -
src/CodeGen/CodeGenerator.cc
r267cb3d r083cf31 446 446 output << ")"; 447 447 } 448 449 void CodeGenerator::visit( AlignofExpr *sizeofExpr ) { 450 // use GCC extension to avoid bumping std to C11 451 output << "__alignof__("; 452 if ( sizeofExpr->get_isType() ) { 453 output << genType( sizeofExpr->get_type(), "" ); 454 } else { 455 sizeofExpr->get_expr()->accept( *this ); 456 } // if 457 output << ")"; 458 } 448 459 449 460 void CodeGenerator::visit( LogicalExpr *logicalExpr ) { -
src/CodeGen/CodeGenerator.h
r267cb3d r083cf31 60 60 virtual void visit( ConstantExpr *constantExpr ); 61 61 virtual void visit( SizeofExpr *sizeofExpr ); 62 virtual void visit( AlignofExpr *alignofExpr ); 62 63 virtual void visit( LogicalExpr *logicalExpr ); 63 64 virtual void visit( ConditionalExpr *conditionalExpr ); -
src/GenPoly/Box.cc
r267cb3d r083cf31 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Box.cc -- 7 // Box.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Dec 02 11:52:37201513 // Update Count : 2 0112 // Last Modified On : Fri Dec 18 14:53:08 2015 13 // Update Count : 217 14 14 // 15 15 … … 28 28 #include "Parser/ParseNode.h" 29 29 30 #include "SynTree/Constant.h" 30 31 #include "SynTree/Type.h" 31 32 #include "SynTree/Expression.h" … … 50 51 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 51 52 53 /// 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 52 54 class Pass1 : public PolyMutator { 53 55 public: … … 60 62 virtual Expression *mutate( CommaExpr *commaExpr ); 61 63 virtual Expression *mutate( ConditionalExpr *condExpr ); 62 virtual Statement * mutate(ReturnStmt *catchStmt);64 virtual Statement * mutate( ReturnStmt *returnStmt ); 63 65 virtual Type *mutate( PointerType *pointerType ); 64 virtual Type * mutate( FunctionType *pointerType );65 66 virtual Type * mutate( FunctionType *functionType ); 67 66 68 virtual void doBeginScope(); 67 69 virtual void doEndScope(); … … 88 90 }; 89 91 92 /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well 90 93 class Pass2 : public PolyMutator { 91 94 public: 92 Pass2();93 95 template< typename DeclClass > 94 96 DeclClass *handleDecl( DeclClass *decl, Type *type ); … … 101 103 private: 102 104 void addAdapters( FunctionType *functionType ); 103 105 104 106 std::map< UniqueId, std::string > adapterName; 105 107 }; 106 108 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 107 110 class Pass3 : public PolyMutator { 108 111 public: … … 148 151 // the correct thing in some situations. It's not clear to me why this wasn't working. 149 152 150 // if the return type or a parameter type involved polymorphic types, then the adapter will need 151 // to take those polymorphic types as pointers. Therefore, there can be two different functions 153 // if the return type or a parameter type involved polymorphic types, then the adapter will need 154 // to take those polymorphic types as pointers. Therefore, there can be two different functions 152 155 // with the same mangled name, so we need to further mangle the names. 153 156 for ( std::list< DeclarationWithType *>::iterator retval = function->get_returnVals().begin(); retval != function->get_returnVals().end(); ++retval ) { 154 if ( isPoly Val( (*retval)->get_type(), tyVars ) ) {157 if ( isPolyType( (*retval)->get_type(), tyVars ) ) { 155 158 name << "P"; 156 159 } else { … … 161 164 std::list< DeclarationWithType *> ¶mList = function->get_parameters(); 162 165 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) { 163 if ( isPoly Val( (*arg)->get_type(), tyVars ) ) {166 if ( isPolyType( (*arg)->get_type(), tyVars ) ) { 164 167 name << "P"; 165 168 } else { 166 name << "M"; 169 name << "M"; 167 170 } 168 171 } // for … … 178 181 } 179 182 180 Pass1::Pass1() 181 : useRetval( false ), tempNamer( "_temp" ) { 183 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) { 182 184 adapters.push(AdapterMap()); 183 185 } … … 191 193 if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) { 192 194 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) { 193 name = typeInst->get_name(); 194 return true; 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 200 } // if 195 201 } // if 196 202 } // if … … 228 234 if ( isPolyRet( functionDecl->get_functionType(), typeName ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) { 229 235 retval = functionDecl->get_functionType()->get_returnVals().front(); 230 236 231 237 // give names to unnamed return values 232 238 if ( retval->get_name() == "" ) { … … 235 241 } // if 236 242 } // if 237 243 238 244 FunctionType *functionType = functionDecl->get_functionType(); 239 245 makeTyVarMap( functionDecl->get_functionType(), scopeTyVars ); … … 260 266 261 267 functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) ); 262 268 263 269 scopeTyVars = oldtyVars; 264 270 assignOps = oldassignOps; … … 276 282 277 283 TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) { 278 /// std::cerr << "add " << typeDecl->get_name() << "\n";279 284 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 280 285 return Mutator::mutate( typeDecl ); … … 302 307 303 308 void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 309 // pass size/align for type variables 304 310 for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) { 305 311 ResolvExpr::EqvClass eqvClass; … … 310 316 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) ); 311 317 arg++; 318 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) ); 319 arg++; 312 320 } else { 313 321 throw SemanticError( "unbound type variable in application ", appExpr ); … … 315 323 } // if 316 324 } // for 325 326 // add size/align for generic types to parameter list 327 //assert( ! appExpr->get_function()->get_results().empty() ); 328 if ( appExpr->get_function()->get_results().empty() ) return; 329 FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() ); 330 assert( funcType ); 331 332 std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); 333 std::list< Expression* >::const_iterator fnArg = arg; 334 std::set< std::string > seenTypes; //< names for generic types we've seen 335 for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) { 336 Type *parmType = (*fnParm)->get_type(); 337 if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, exprTyVars ) ) { 338 std::string sizeName = sizeofName( parmType ); 339 if ( seenTypes.count( sizeName ) ) continue; 340 341 assert( ! (*fnArg)->get_results().empty() ); 342 Type *argType = (*fnArg)->get_results().front(); 343 arg = appExpr->get_args().insert( arg, new SizeofExpr( argType->clone() ) ); 344 arg++; 345 arg = appExpr->get_args().insert( arg, new AlignofExpr( argType->clone() ) ); 346 arg++; 347 348 seenTypes.insert( sizeName ); 349 } 350 } 317 351 } 318 352 … … 323 357 } 324 358 325 TypeInstType *isPolyType( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {326 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {327 if ( env ) {328 if ( Type *newType = env->lookup( typeInst->get_name() ) ) {329 return isPolyType( newType, env, tyVars );330 } // if331 } // if332 if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {333 return typeInst;334 } else {335 return 0;336 } // if337 } else {338 return 0;339 } // if340 }341 342 359 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) { 343 if ( useRetval ) { 344 assert( retval ); 345 arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) ); 346 arg++; 347 } else { 348 ObjectDecl *newObj = makeTemporary( retType->clone() ); 349 Expression *paramExpr = new VariableExpr( newObj ); 350 if ( ! isPolyType( newObj->get_type(), env, scopeTyVars ) ) { 351 paramExpr = new AddressExpr( paramExpr ); 352 } // if 353 arg = appExpr->get_args().insert( arg, paramExpr ); 354 arg++; 355 /// stmtsToAdd.push_back( new ExprStmt( noLabels, appExpr ) ); 356 CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) ); 357 commaExpr->set_env( appExpr->get_env() ); 358 appExpr->set_env( 0 ); 359 return commaExpr; 360 } // if 361 return appExpr; 360 // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous. 361 // if ( useRetval ) { 362 // assert( retval ); 363 // arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) ); 364 // arg++; 365 // } else { 366 367 // Create temporary to hold return value of polymorphic function and produce that temporary as a result 368 // using a comma expression. Possibly change comma expression into statement expression "{}" for multiple 369 // return values. 370 ObjectDecl *newObj = makeTemporary( retType->clone() ); 371 Expression *paramExpr = new VariableExpr( newObj ); 372 // If the type of the temporary is not polymorphic, box temporary by taking its address; otherwise the 373 // temporary is already boxed and can be used directly. 374 if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) { 375 paramExpr = new AddressExpr( paramExpr ); 376 } // if 377 arg = appExpr->get_args().insert( arg, paramExpr ); // add argument to function call 378 arg++; 379 // Build a comma expression to call the function and emulate a normal return. 380 CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) ); 381 commaExpr->set_env( appExpr->get_env() ); 382 appExpr->set_env( 0 ); 383 return commaExpr; 384 // } // if 385 // return appExpr; 362 386 } 363 387 … … 374 398 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) { 375 399 Expression *ret = appExpr; 376 if ( ! function->get_returnVals().empty() && isPoly Val( function->get_returnVals().front()->get_type(), tyVars ) ) {400 if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) { 377 401 ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg ); 378 402 } // if … … 382 406 appExpr->get_args().push_front( appExpr->get_function() ); 383 407 appExpr->set_function( new NameExpr( adapterName ) ); 384 408 385 409 return ret; 386 410 } … … 388 412 void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) { 389 413 assert( ! arg->get_results().empty() ); 390 // /if ( ! dynamic_cast< PointerType *>( arg->get_results().front() ) ) {414 // if ( ! dynamic_cast< PointerType *>( arg->get_results().front() ) ) { 391 415 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( param ); 392 416 if ( typeInst && exprTyVars.find( typeInst->get_name() ) != exprTyVars.end() ) { … … 408 432 } // if 409 433 } // if 410 // /}434 // } 411 435 } 412 436 … … 425 449 426 450 void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 427 /// std::cout << "function is ";428 /// function->print( std::cout );429 451 for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) { 430 /// std::cout << "parameter is ";431 /// (*param)->print( std::fcout );432 /// std::cout << std::endl << "argument is ";433 /// (*arg)->print( std::cout );434 452 assert( arg != appExpr->get_args().end() ); 435 453 addCast( *arg, (*param)->get_type(), exprTyVars ); … … 466 484 // actually make the adapter type 467 485 FunctionType *adapter = adaptee->clone(); 468 if ( ! adapter->get_returnVals().empty() && isPoly Val( adapter->get_returnVals().front()->get_type(), tyVars ) ) {486 if ( ! adapter->get_returnVals().empty() && isPolyType( adapter->get_returnVals().front()->get_type(), tyVars ) ) { 469 487 makeRetParm( adapter ); 470 488 } // if … … 476 494 assert( param ); 477 495 assert( arg ); 478 /// std::cout << "arg type is "; 479 /// arg->get_type()->print( std::cout ); 480 /// std::cout << "param type is "; 481 /// param->get_type()->print( std::cout ); 482 /// std::cout << " tyVars are: "; 483 /// printTyVarMap( std::cout, tyVars ); 484 if ( isPolyVal( realParam->get_type(), tyVars ) ) { 485 /// if ( dynamic_cast< PointerType *>( arg->get_type() ) ) { 486 /// return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() ); 487 /// } else { 496 if ( isPolyType( realParam->get_type(), tyVars ) ) { 497 // if ( dynamic_cast< PointerType *>( arg->get_type() ) ) { 498 // return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() ); 499 // } else { 488 500 if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) { 489 501 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); … … 492 504 return deref; 493 505 } // if 494 // /}506 // } 495 507 } // if 496 508 return new VariableExpr( param ); … … 517 529 ApplicationExpr *adapteeApp = new ApplicationExpr( new CastExpr( new VariableExpr( adapteeDecl ), new PointerType( Type::Qualifiers(), realType ) ) ); 518 530 Statement *bodyStmt; 519 531 520 532 std::list< TypeDecl *>::iterator tyArg = realType->get_forall().begin(); 521 533 std::list< TypeDecl *>::iterator tyParam = adapterType->get_forall().begin(); … … 531 543 } // for 532 544 } // for 533 545 534 546 std::list< DeclarationWithType *>::iterator arg = realType->get_parameters().begin(); 535 547 std::list< DeclarationWithType *>::iterator param = adapterType->get_parameters().begin(); … … 539 551 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars ); 540 552 bodyStmt = new ExprStmt( noLabels, adapteeApp ); 541 } else if ( isPoly Val( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {553 } else if ( isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) { 542 554 if ( (*param)->get_name() == "" ) { 543 555 (*param)->set_name( "_ret" ); … … 588 600 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) { 589 601 adaptersDone.insert( adaptersDone.begin(), mangleName ); 590 602 591 603 // apply substitution to type variables to figure out what the adapter's type should look like 592 604 assert( env ); 593 605 env->apply( realFunction ); 594 mangleName = SymTab::Mangler::mangle( realFunction ); 606 mangleName = SymTab::Mangler::mangle( realFunction ); 595 607 mangleName += makePolyMonoSuffix( originalFunction, exprTyVars ); 596 608 … … 611 623 } // passAdapters 612 624 613 TypeInstType *isPolyPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) { 614 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { 615 return isPolyType( ptr->get_base(), env, tyVars ); 616 } else if ( env ) { 617 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 618 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 619 return isPolyPtr( newType, env, tyVars ); 620 } // if 621 } // if 622 } // if 623 return 0; 624 } 625 626 TypeInstType *isPolyPtrPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) { 627 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { 628 return isPolyPtr( ptr->get_base(), env, tyVars ); 629 } else if ( env ) { 630 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 631 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 632 return isPolyPtrPtr( newType, env, tyVars ); 633 } // if 634 } // if 635 } // if 636 return 0; 637 } 638 639 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr ) { 625 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) { 640 626 NameExpr *opExpr; 641 627 if ( isIncr ) { … … 650 636 addAssign->get_args().push_back( appExpr->get_args().front() ); 651 637 } // if 652 addAssign->get_args().push_back( new NameExpr( polyName) );638 addAssign->get_args().push_back( new NameExpr( sizeofName( polyType ) ) ); 653 639 addAssign->get_results().front() = appExpr->get_results().front()->clone(); 654 640 if ( appExpr->get_env() ) { … … 667 653 assert( ! appExpr->get_results().empty() ); 668 654 assert( appExpr->get_args().size() == 2 ); 669 Type InstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars);670 Type InstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars);671 assert( ! typeInst1 || ! typeInst2 );// the arguments cannot both be polymorphic pointers655 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env ); 656 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env ); 657 assert( ! baseType1 || ! baseType2 ); // the arguments cannot both be polymorphic pointers 672 658 UntypedExpr *ret = 0; 673 if ( typeInst1 || typeInst2 ) { // one of the arguments is a polymorphic pointer659 if ( baseType1 || baseType2 ) { // one of the arguments is a polymorphic pointer 674 660 ret = new UntypedExpr( new NameExpr( "?+?" ) ); 675 661 } // if 676 if ( typeInst1 ) {662 if ( baseType1 ) { 677 663 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 678 664 multiply->get_args().push_back( appExpr->get_args().back() ); 679 multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );665 multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) ); 680 666 ret->get_args().push_back( appExpr->get_args().front() ); 681 667 ret->get_args().push_back( multiply ); 682 } else if ( typeInst2 ) {668 } else if ( baseType2 ) { 683 669 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 684 670 multiply->get_args().push_back( appExpr->get_args().front() ); 685 multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );671 multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) ); 686 672 ret->get_args().push_back( multiply ); 687 673 ret->get_args().push_back( appExpr->get_args().back() ); 688 674 } // if 689 if ( typeInst1 || typeInst2 ) {675 if ( baseType1 || baseType2 ) { 690 676 ret->get_results().push_front( appExpr->get_results().front()->clone() ); 691 677 if ( appExpr->get_env() ) { … … 700 686 assert( ! appExpr->get_results().empty() ); 701 687 assert( ! appExpr->get_args().empty() ); 702 if ( isPolyType( appExpr->get_results().front(), env, scopeTyVars) ) {688 if ( isPolyType( appExpr->get_results().front(), scopeTyVars, env ) ) { 703 689 Expression *ret = appExpr->get_args().front(); 704 690 delete ret->get_results().front(); … … 715 701 assert( ! appExpr->get_results().empty() ); 716 702 assert( appExpr->get_args().size() == 1 ); 717 if ( Type InstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars) ) {703 if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) { 718 704 Type *tempType = appExpr->get_results().front()->clone(); 719 705 if ( env ) { … … 729 715 assignExpr->get_args().push_back( appExpr->get_args().front()->clone() ); 730 716 } // if 731 CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "?++" ) );717 CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "?++" ) ); 732 718 return new CommaExpr( firstComma, tempExpr ); 733 719 } // if … … 735 721 assert( ! appExpr->get_results().empty() ); 736 722 assert( appExpr->get_args().size() == 1 ); 737 if ( Type InstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars) ) {738 return makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "++?" );723 if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) { 724 return makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "++?" ); 739 725 } // if 740 726 } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) { 741 727 assert( ! appExpr->get_results().empty() ); 742 728 assert( appExpr->get_args().size() == 2 ); 743 Type InstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars);744 Type InstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars);745 if ( typeInst1 && typeInst2 ) {729 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env ); 730 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env ); 731 if ( baseType1 && baseType2 ) { 746 732 UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) ); 747 733 divide->get_args().push_back( appExpr ); 748 divide->get_args().push_back( new NameExpr( typeInst1->get_name() ) );734 divide->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) ); 749 735 divide->get_results().push_front( appExpr->get_results().front()->clone() ); 750 736 if ( appExpr->get_env() ) { … … 753 739 } // if 754 740 return divide; 755 } else if ( typeInst1 ) {741 } else if ( baseType1 ) { 756 742 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 757 743 multiply->get_args().push_back( appExpr->get_args().back() ); 758 multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );744 multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) ); 759 745 appExpr->get_args().back() = multiply; 760 } else if ( typeInst2 ) {746 } else if ( baseType2 ) { 761 747 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 762 748 multiply->get_args().push_back( appExpr->get_args().front() ); 763 multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );749 multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) ); 764 750 appExpr->get_args().front() = multiply; 765 751 } // if … … 767 753 assert( ! appExpr->get_results().empty() ); 768 754 assert( appExpr->get_args().size() == 2 ); 769 Type InstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars);770 if ( typeInst) {755 Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ); 756 if ( baseType ) { 771 757 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 772 758 multiply->get_args().push_back( appExpr->get_args().back() ); 773 multiply->get_args().push_back( new NameExpr( typeInst->get_name() ) );759 multiply->get_args().push_back( new NameExpr( sizeofName( baseType ) ) ); 774 760 appExpr->get_args().back() = multiply; 775 761 } // if … … 792 778 mutateAll( appExpr->get_args(), *this ); 793 779 useRetval = oldUseRetval; 794 780 795 781 assert( ! appExpr->get_function()->get_results().empty() ); 796 782 PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() ); … … 798 784 FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() ); 799 785 assert( function ); 800 786 801 787 if ( Expression *newExpr = handleIntrinsics( appExpr ) ) { 802 788 return newExpr; 803 789 } // if 804 790 805 791 Expression *ret = appExpr; 806 792 807 793 std::list< Expression *>::iterator arg = appExpr->get_args().begin(); 808 794 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin(); 809 795 810 796 std::string typeName; 811 797 if ( isPolyRet( function, typeName ) ) { … … 821 807 } // if 822 808 arg = appExpr->get_args().begin(); 823 809 824 810 TyVarMap exprTyVars; 825 811 makeTyVarMap( function, exprTyVars ); 826 812 827 813 passTypeVars( appExpr, arg, exprTyVars ); 828 814 addInferredParams( appExpr, function, arg, exprTyVars ); 829 815 830 816 arg = paramBegin; 831 817 832 818 boxParams( appExpr, function, arg, exprTyVars ); 833 819 … … 838 824 839 825 Expression *Pass1::mutate( UntypedExpr *expr ) { 840 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), env, scopeTyVars) ) {826 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) { 841 827 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 842 828 if ( name->get_name() == "*?" ) { … … 853 839 Expression *Pass1::mutate( AddressExpr *addrExpr ) { 854 840 assert( ! addrExpr->get_arg()->get_results().empty() ); 841 842 bool needs = false; 843 if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) { 844 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) { 845 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 846 if ( name->get_name() == "*?" ) { 847 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) { 848 assert( ! appExpr->get_function()->get_results().empty() ); 849 PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() ); 850 assert( pointer ); 851 FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() ); 852 assert( function ); 853 needs = needsAdapter( function, scopeTyVars ); 854 } // if 855 } // if 856 } // if 857 } // if 858 } // if 855 859 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) ); 856 if ( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars )) {860 if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) || needs ) { 857 861 Expression *ret = addrExpr->get_arg(); 858 862 delete ret->get_results().front(); … … 866 870 } 867 871 868 Statement * Pass1::mutate(ReturnStmt *retStmt) { 869 // by this point, a cast expr on a polymorphic return value is redundant 870 while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( retStmt->get_expr() ) ) { 871 retStmt->set_expr( castExpr->get_arg() ); 872 retStmt->get_expr()->set_env( castExpr->get_env() ); 873 castExpr->set_env( 0 ); 874 castExpr->set_arg( 0 ); 875 delete castExpr; 876 } 877 if ( retval && retStmt->get_expr() ) { 878 assert( ! retStmt->get_expr()->get_results().empty() ); 879 if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) { 880 /// retStmt->set_expr( mutateExpression( retStmt->get_expr() ) ); 881 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ); 882 assert( typeInst ); 883 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 884 if ( assignIter == assignOps.end() ) { 885 throw SemanticError( "Attempt to return dtype or ftype object in ", retStmt->get_expr() ); 886 } // if 887 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) ); 888 Expression *retParm = new NameExpr( retval->get_name() ); 889 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); 890 assignExpr->get_args().push_back( retParm ); 891 assignExpr->get_args().push_back( retStmt->get_expr() ); 892 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) ); 893 } else { 894 useRetval = true; 895 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( retStmt->get_expr() ) ) ); 896 useRetval = false; 872 Statement * Pass1::mutate( ReturnStmt *returnStmt ) { 873 if ( retval && returnStmt->get_expr() ) { 874 assert( ! returnStmt->get_expr()->get_results().empty() ); 875 // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous. 876 // if ( returnStmt->get_expr()->get_results().front()->get_isLvalue() ) { 877 // by this point, a cast expr on a polymorphic return value is redundant 878 while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( returnStmt->get_expr() ) ) { 879 returnStmt->set_expr( castExpr->get_arg() ); 880 returnStmt->get_expr()->set_env( castExpr->get_env() ); 881 castExpr->set_env( 0 ); 882 castExpr->set_arg( 0 ); 883 delete castExpr; 884 } //while 885 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ); 886 assert( typeInst ); 887 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 888 if ( assignIter == assignOps.end() ) { 889 throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() ); 897 890 } // if 898 retStmt->set_expr( 0 ); 891 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) ); 892 Expression *retParm = new NameExpr( retval->get_name() ); 893 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); 894 assignExpr->get_args().push_back( retParm ); 895 assignExpr->get_args().push_back( returnStmt->get_expr() ); 896 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) ); 897 // } else { 898 // useRetval = true; 899 // stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( returnStmt->get_expr() ) ) ); 900 // useRetval = false; 901 // } // if 902 returnStmt->set_expr( 0 ); 899 903 } else { 900 ret Stmt->set_expr( mutateExpression( retStmt->get_expr() ) );901 } // if 902 return ret Stmt;904 returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) ); 905 } // if 906 return returnStmt; 903 907 } 904 908 … … 906 910 TyVarMap oldtyVars = scopeTyVars; 907 911 makeTyVarMap( pointerType, scopeTyVars ); 908 912 909 913 Type *ret = Mutator::mutate( pointerType ); 910 914 911 915 scopeTyVars = oldtyVars; 912 916 return ret; … … 916 920 TyVarMap oldtyVars = scopeTyVars; 917 921 makeTyVarMap( functionType, scopeTyVars ); 918 922 919 923 Type *ret = Mutator::mutate( functionType ); 920 924 921 925 scopeTyVars = oldtyVars; 922 926 return ret; … … 933 937 934 938 ////////////////////////////////////////// Pass2 //////////////////////////////////////////////////// 935 936 Pass2::Pass2() {}937 939 938 940 void Pass2::addAdapters( FunctionType *functionType ) { … … 953 955 } 954 956 } 955 // /deleteAll( functions );957 // deleteAll( functions ); 956 958 } 957 959 … … 987 989 TyVarMap oldtyVars = scopeTyVars; 988 990 makeTyVarMap( pointerType, scopeTyVars ); 989 991 990 992 Type *ret = Mutator::mutate( pointerType ); 991 993 992 994 scopeTyVars = oldtyVars; 993 995 return ret; … … 997 999 TyVarMap oldtyVars = scopeTyVars; 998 1000 makeTyVarMap( funcType, scopeTyVars ); 999 1001 1002 // move polymorphic return type to parameter list 1000 1003 std::string typeName; 1001 1004 if ( isPolyRet( funcType, typeName ) ) { … … 1005 1008 funcType->get_returnVals().pop_front(); 1006 1009 } 1007 1010 1011 // add size/align and assertions for type parameters to parameter list 1008 1012 std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin(); 1009 1013 std::list< DeclarationWithType *> inferredParams; 1010 ObjectDecl *newObj = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );1011 // /ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );1014 ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 ); 1015 // ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 ); 1012 1016 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 1013 ObjectDecl * thisParm;1014 // add all size parameters to parameter list1017 ObjectDecl *sizeParm, *alignParm; 1018 // add all size and alignment parameters to parameter list 1015 1019 if ( (*tyParm)->get_kind() == TypeDecl::Any ) { 1016 thisParm = newObj->clone(); 1017 thisParm->set_name( (*tyParm)->get_name() ); 1018 last = funcType->get_parameters().insert( last, thisParm ); 1020 TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm ); 1021 1022 sizeParm = newObj.clone(); 1023 sizeParm->set_name( sizeofName( &parmType ) ); 1024 last = funcType->get_parameters().insert( last, sizeParm ); 1025 ++last; 1026 1027 alignParm = newObj.clone(); 1028 alignParm->set_name( alignofName( &parmType ) ); 1029 last = funcType->get_parameters().insert( last, alignParm ); 1019 1030 ++last; 1020 1031 } 1021 1032 // move all assertions into parameter list 1022 1033 for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) { 1023 // /*assert = (*assert)->acceptMutator( *this );1034 // *assert = (*assert)->acceptMutator( *this ); 1024 1035 inferredParams.push_back( *assert ); 1025 1036 } 1026 1037 (*tyParm)->get_assertions().clear(); 1027 1038 } 1028 delete newObj; 1039 1040 // add size/align for generic types to parameter list 1041 std::set< std::string > seenTypes; //< sizeofName for generic types we've seen 1042 for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) { 1043 Type *parmType = (*fnParm)->get_type(); 1044 if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, scopeTyVars ) ) { 1045 std::string sizeName = sizeofName( parmType ); 1046 if ( seenTypes.count( sizeName ) ) continue; 1047 1048 ObjectDecl *sizeParm, *alignParm; 1049 sizeParm = newObj.clone(); 1050 sizeParm->set_name( sizeName ); 1051 last = funcType->get_parameters().insert( last, sizeParm ); 1052 ++last; 1053 1054 alignParm = newObj.clone(); 1055 alignParm->set_name( alignofName( parmType ) ); 1056 last = funcType->get_parameters().insert( last, alignParm ); 1057 ++last; 1058 1059 seenTypes.insert( sizeName ); 1060 } 1061 } 1062 1063 // splice assertion parameters into parameter list 1029 1064 funcType->get_parameters().splice( last, inferredParams ); 1030 1065 addAdapters( funcType ); 1031 1066 mutateAll( funcType->get_returnVals(), *this ); 1032 1067 mutateAll( funcType->get_parameters(), *this ); 1033 1068 1034 1069 scopeTyVars = oldtyVars; 1035 1070 return funcType; … … 1042 1077 TyVarMap oldtyVars = scopeTyVars; 1043 1078 makeTyVarMap( type, scopeTyVars ); 1044 1079 1045 1080 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) ); 1046 1081 ScrubTyVars::scrub( decl, scopeTyVars ); … … 1063 1098 1064 1099 TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) { 1065 // /Initializer *init = 0;1066 // /std::list< Expression *> designators;1067 // /scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();1068 // /if ( typeDecl->get_base() ) {1069 // /init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );1070 // /}1071 // /return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );1100 // Initializer *init = 0; 1101 // std::list< Expression *> designators; 1102 // scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 1103 // if ( typeDecl->get_base() ) { 1104 // init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators ); 1105 // } 1106 // return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init ); 1072 1107 1073 1108 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); … … 1078 1113 TyVarMap oldtyVars = scopeTyVars; 1079 1114 makeTyVarMap( pointerType, scopeTyVars ); 1080 1115 1081 1116 Type *ret = Mutator::mutate( pointerType ); 1082 1117 1083 1118 scopeTyVars = oldtyVars; 1084 1119 return ret; … … 1088 1123 TyVarMap oldtyVars = scopeTyVars; 1089 1124 makeTyVarMap( functionType, scopeTyVars ); 1090 1125 1091 1126 Type *ret = Mutator::mutate( functionType ); 1092 1127 1093 1128 scopeTyVars = oldtyVars; 1094 1129 return ret; … … 1097 1132 Statement *Pass3::mutate( DeclStmt *declStmt ) { 1098 1133 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) { 1099 if ( isPoly Val( objectDecl->get_type(), scopeTyVars ) ) {1134 if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) { 1100 1135 // change initialization of a polymorphic value object 1101 1136 // to allocate storage with alloca 1102 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( objectDecl->get_type() ); 1103 assert( typeInst ); 1137 Type *declType = objectDecl->get_type(); 1104 1138 UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) ); 1105 alloc->get_args().push_back( new NameExpr( typeInst->get_name() ) );1139 alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) ); 1106 1140 1107 1141 delete objectDecl->get_init(); -
src/GenPoly/FindFunction.h
r267cb3d r083cf31 23 23 typedef bool (*FindFunctionPredicate)( FunctionType*, const TyVarMap& ); 24 24 25 /// recursively walk `type`, placing all functions that match `predicate` under `tyVars` into `functions` 25 26 void findFunction( Type *type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ); 27 /// like `findFunction`, but also replaces the function type with void ()(void) 26 28 void findAndReplaceFunction( Type *&type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ); 27 29 } // namespace GenPoly -
src/GenPoly/GenPoly.cc
r267cb3d r083cf31 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 Nov 24 15:23:08 201513 // Update Count : 1 111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Dec 15 16:11:18 2015 13 // Update Count : 13 14 14 // 15 15 16 16 #include "GenPoly.h" 17 18 #include "SymTab/Mangler.h" 19 #include "SynTree/Expression.h" 17 20 #include "SynTree/Type.h" 18 21 … … 21 24 22 25 namespace GenPoly { 23 // A function needs an adapter if it returns a polymorphic value or if any of its24 // parameters have polymorphic type25 26 bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) { 26 if ( ! adaptee->get_returnVals().empty() && isPoly Val( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {27 if ( ! adaptee->get_returnVals().empty() && isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) { 27 28 return true; 28 29 } // if 29 30 for ( std::list< DeclarationWithType* >::const_iterator innerArg = adaptee->get_parameters().begin(); innerArg != adaptee->get_parameters().end(); ++innerArg ) { 30 if ( isPoly Val( (*innerArg)->get_type(), tyVars ) ) {31 if ( isPolyType( (*innerArg)->get_type(), tyVars ) ) { 31 32 return true; 32 33 } // if … … 66 67 } 67 68 68 bool isPolyVal( Type *type, const TyVarMap &tyVars ) { 69 namespace { 70 /// Checks a parameter list for polymorphic parameters; will substitute according to env if present 71 bool hasPolyParams( std::list< Expression* >& params, const TypeSubstitution *env ) { 72 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) { 73 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 74 assert(paramType && "Aggregate parameters should be type expressions"); 75 if ( isPolyType( paramType->get_type(), env ) ) return true; 76 } 77 return false; 78 } 79 80 /// Checks a parameter list for polymorphic parameters from tyVars; will substitute according to env if present 81 bool hasPolyParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) { 82 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) { 83 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 84 assert(paramType && "Aggregate parameters should be type expressions"); 85 if ( isPolyType( paramType->get_type(), tyVars, env ) ) return true; 86 } 87 return false; 88 } 89 } 90 91 Type *isPolyType( Type *type, const TypeSubstitution *env ) { 69 92 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) { 93 if ( env ) { 94 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 95 return isPolyType( newType, env ); 96 } // if 97 } // if 98 return type; 99 } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) { 100 if ( hasPolyParams( structType->get_parameters(), env ) ) return type; 101 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) { 102 if ( hasPolyParams( unionType->get_parameters(), env ) ) return type; 103 } 104 return 0; 105 } 106 107 Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) { 108 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) { 109 if ( env ) { 110 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 111 return isPolyType( newType, tyVars, env ); 112 } // if 113 } // if 70 114 if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) { 71 return true; 115 return type; 116 } 117 } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) { 118 if ( hasPolyParams( structType->get_parameters(), tyVars, env ) ) return type; 119 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) { 120 if ( hasPolyParams( unionType->get_parameters(), tyVars, env ) ) return type; 121 } 122 return 0; 123 } 124 125 Type *isPolyPtr( Type *type, const TypeSubstitution *env ) { 126 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { 127 return isPolyType( ptr->get_base(), env ); 128 } else if ( env ) { 129 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 130 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 131 return isPolyPtr( newType, env ); 132 } // if 72 133 } // if 73 134 } // if 74 return false; 135 return 0; 136 } 137 138 Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) { 139 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { 140 return isPolyType( ptr->get_base(), tyVars, env ); 141 } else if ( env ) { 142 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 143 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 144 return isPolyPtr( newType, tyVars, env ); 145 } // if 146 } // if 147 } // if 148 return 0; 75 149 } 76 150 77 bool isPolyObj( Type *type, const TyVarMap &tyVars ) { 78 if ( isPolyVal( type, tyVars ) ) { 79 return true; 80 } else if ( PointerType *pt = dynamic_cast<PointerType*>( type ) ) { 81 return isPolyObj( pt->get_base(), tyVars ); 151 FunctionType * getFunctionType( Type *ty ) { 152 PointerType *ptrType; 153 if ( ( ptrType = dynamic_cast< PointerType* >( ty ) ) ) { 154 return dynamic_cast< FunctionType* >( ptrType->get_base() ); // pointer if FunctionType, NULL otherwise 82 155 } else { 83 return false;156 return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise 84 157 } 85 158 } … … 91 164 os << std::endl; 92 165 } 166 167 std::string sizeofName( Type *ty ) { 168 return std::string( "_sizeof_" ) + SymTab::Mangler::mangleType( ty ); 169 } 170 171 std::string alignofName( Type *ty ) { 172 return std::string( "_alignof_" ) + SymTab::Mangler::mangleType( ty ); 173 } 93 174 } // namespace GenPoly 94 175 -
src/GenPoly/GenPoly.h
r267cb3d r083cf31 20 20 #include <string> 21 21 #include <iostream> 22 22 23 #include "SynTree/Declaration.h" 24 #include "SynTree/TypeSubstitution.h" 23 25 24 26 namespace GenPoly { 25 27 typedef std::map< std::string, TypeDecl::Kind > TyVarMap; 26 28 29 /// A function needs an adapter if it returns a polymorphic value or if any of its 30 /// parameters have polymorphic type 27 31 bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVarr ); 32 33 /// true iff function has polymorphic return type 28 34 bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars ); 29 35 bool isPolyRet( FunctionType *function, std::string &name ); 30 36 bool isPolyRet( FunctionType *function, const TyVarMap &otherTyVars ); 31 // bool isPolyFun( FunctionType *fun, const TyVarMap &tyVars );32 bool isPolyVal( Type *type, const TyVarMap &tyVars );33 37 34 // true if type variable or any number of pointers to type variable 35 bool isPolyObj( Type *type, const TyVarMap &tyVars ); 38 /// returns polymorphic type if is polymorphic type, NULL otherwise; will look up substitution in env if provided 39 Type *isPolyType( Type *type, const TypeSubstitution *env = 0 ); 40 41 /// returns polymorphic type if is polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided 42 Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 ); 43 44 /// returns polymorphic type if is pointer to polymorphic type, NULL otherwise; will look up substitution in env if provided 45 Type *isPolyPtr( Type *type, const TypeSubstitution *env = 0 ); 46 47 /// returns polymorphic type if is pointer to polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided 48 Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 ); 49 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 ); 52 53 /// Prints type variable map 36 54 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ); 55 56 /// Gets the name of the sizeof parameter for the type 57 std::string sizeofName( Type *ty ); 58 59 /// Gets the name of the alignof parameter for the type 60 std::string alignofName( Type *ty ); 37 61 } // namespace GenPoly 38 62 -
src/GenPoly/InstantiateGeneric.cc
r267cb3d r083cf31 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // InstantiateGeneric. h--7 // InstantiateGeneric.cc -- 8 8 // 9 9 // Author : Aaron B. Moss … … 21 21 22 22 #include "InstantiateGeneric.h" 23 #include " PolyMutator.h"23 #include "DeclMutator.h" 24 24 25 25 #include "ResolvExpr/typeops.h" … … 44 44 ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); } 45 45 46 /// Extracts types from a list of Expression* (which should be TypeExpr*) 47 ConcreteType(AggregateDecl *_base, const std::list< Expression* >& _params) : base(_base), params() { 48 for ( std::list< Expression* >::const_iterator it = _params.begin(); it != _params.end(); ++it ) { 49 TypeExpr *param = dynamic_cast< TypeExpr* >(*it); 50 assert(param && "Aggregate parameters should be type expressions"); 51 params.push_back( param->get_type()->clone() ); 46 /// Extracts types from a list of TypeExpr* 47 ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base), params() { 48 for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) { 49 params.push_back( (*param)->get_type()->clone() ); 52 50 } 53 51 } … … 66 64 67 65 bool operator== (const ConcreteType& that) const { 66 if ( base != that.base ) return false; 67 68 68 SymTab::Indexer dummy; 69 70 if ( base != that.base ) return false;71 69 if ( params.size() != that.params.size() ) return false; 72 70 for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) { … … 79 77 std::list< Type* > params; ///< Instantiation parameters 80 78 }; 81 79 82 80 /// Maps a concrete type to the instantiated struct type, accounting for scope 83 81 class InstantiationMap { 84 /// Pair of concrete type and declaration that instantiates it 85 typedef std::pair< ConcreteType, AggregateDecl* > Instantiation; 82 /// Instantiation of a generic type, with key information to find it 83 struct Instantiation { 84 ConcreteType key; ///< Instantiation parameters for this type 85 AggregateDecl *decl; ///< Declaration of the instantiated generic type 86 87 Instantiation() : key(), decl(0) {} 88 Instantiation(const ConcreteType &_key, AggregateDecl *_decl) : key(_key), decl(_decl) {} 89 }; 86 90 /// Map of generic types to instantiations of them 87 91 typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope; … … 107 111 /// Gets the declaration for the concrete instantiation of this type, assuming it has already been instantiated in the current scope. 108 112 /// Returns NULL on none such. 109 AggregateDecl* lookup( AggregateDecl *generic, std::list< Expression* >& params ) {113 AggregateDecl* lookup( AggregateDecl *generic, const std::list< TypeExpr* >& params ) { 110 114 ConcreteType key(generic, params); 111 115 // scan scopes from innermost out … … 116 120 // look through instantiations for matches to concrete type 117 121 for ( std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) { 118 if ( inst-> first == key ) return inst->second;122 if ( inst->key == key ) return inst->decl; 119 123 } 120 124 } … … 123 127 } 124 128 public: 125 StructDecl* lookup( StructInstType *inst ) { return (StructDecl*)lookup( inst->get_baseStruct(), inst->get_parameters()); }126 UnionDecl* lookup( UnionInstType *inst ) { return (UnionDecl*)lookup( inst->get_baseUnion(), inst->get_parameters()); }129 StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)lookup( inst->get_baseStruct(), typeSubs ); } 130 UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)lookup( inst->get_baseUnion(), typeSubs ); } 127 131 128 132 private: 129 133 /// Adds a declaration for a concrete type to the current scope 130 void insert( AggregateDecl *generic, std::list< Expression* >¶ms, AggregateDecl *decl ) {134 void insert( AggregateDecl *generic, const std::list< TypeExpr* > ¶ms, AggregateDecl *decl ) { 131 135 ConcreteType key(generic, params); 132 scopes.back()[generic].push_back( std::make_pair( key, decl ) );136 scopes.back()[generic].push_back( Instantiation( key, decl ) ); 133 137 } 134 138 public: 135 void insert( StructInstType *inst, StructDecl *decl ) { insert( inst->get_baseStruct(), inst->get_parameters(), decl ); }136 void insert( UnionInstType *inst, UnionDecl *decl ) { insert( inst->get_baseUnion(), inst->get_parameters(), decl ); }139 void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { insert( inst->get_baseStruct(), typeSubs, decl ); } 140 void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { insert( inst->get_baseUnion(), typeSubs, decl ); } 137 141 }; 138 142 139 143 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately 140 class Instantiate : public PolyMutator { 144 class Instantiate : public DeclMutator { 145 /// Map of (generic type, parameter list) pairs to concrete type instantiations 141 146 InstantiationMap instantiations; 147 /// Namer for concrete types 142 148 UniqueName typeNamer; 143 149 144 150 public: 145 Instantiate() : instantiations(), typeNamer("_conc_") {} 146 147 /// Mutates the whole translation unit, inserting new struct declarations as appropriate 148 void mutateAll( std::list< Declaration* >& translationUnit ); 149 151 Instantiate() : DeclMutator(), instantiations(), typeNamer("_conc_") {} 152 150 153 virtual Type* mutate( StructInstType *inst ); 151 154 virtual Type* mutate( UnionInstType *inst ); 155 156 // virtual Expression* mutate( MemberExpr *memberExpr ); 152 157 153 158 virtual void doBeginScope(); 154 159 virtual void doEndScope(); 155 156 private:157 /// Adds a declaration to the current environment and the statements to add158 void addDeclaration( AggregateDecl *decl ) {159 std::list< Label > nolabels;160 DeclStmt *stmt = new DeclStmt( nolabels, decl );161 PolyMutator::stmtsToAdd.push_back( stmt );162 }163 160 }; 164 161 165 162 void instantiateGeneric( std::list< Declaration* >& translationUnit ) { 166 163 Instantiate instantiator; 167 // mutateAll( translationUnit, instantiator ); 168 instantiator.mutateAll( translationUnit ); 169 } 170 171 void Instantiate::mutateAll( std::list< Declaration* >& translationUnit ) { 172 // below copied and modified from Mutator.h:mutateAll() 173 SemanticError errors; 174 for ( std::list< Declaration* >::iterator decl = translationUnit.begin(); decl != translationUnit.end(); ++decl ) { 175 try { 176 if ( *decl ) { 177 *decl = dynamic_cast< Declaration* >( (*decl)->acceptMutator( *this ) ); 178 assert( *decl ); 179 // account for missing top-level declarations 180 for ( std::list< Statement* >::const_iterator stmt = PolyMutator::stmtsToAdd.begin(); stmt != PolyMutator::stmtsToAdd.end(); ++stmt ) { 181 DeclStmt *declStmt = dynamic_cast< DeclStmt* >( *stmt ); 182 assert( declStmt ); 183 translationUnit.insert( decl, declStmt->get_decl() ); 184 } 185 PolyMutator::stmtsToAdd.clear(); 186 } // if 187 } catch( SemanticError &e ) { 188 errors.append( e ); 189 } // try 190 } // for 191 if ( ! errors.isEmpty() ) { 192 throw errors; 193 } // if 194 } 195 196 /// Substitutes types of members of in according to baseParams => params, appending the result to out 197 void substituteMembers( const std::list< Declaration* >& in, 198 const std::list< TypeDecl * >& baseParams, const std::list< Expression* >& params, 164 instantiator.mutateDeclarationList( translationUnit ); 165 } 166 167 /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type 168 bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) { 169 bool allConcrete = true; // will finish the substitution list even if they're not all concrete 170 171 // substitute concrete types for given parameters, and incomplete types for placeholders 172 std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin(); 173 std::list< Expression* >::const_iterator param = params.begin(); 174 for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) { 175 // switch ( (*baseParam)->get_kind() ) { 176 // case TypeDecl::Any: { // any type is a valid substitution here; complete types can be used to instantiate generics 177 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 178 assert(paramType && "Aggregate parameters should be type expressions"); 179 out.push_back( paramType->clone() ); 180 // check that the substituted type isn't a type variable itself 181 if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) { 182 allConcrete = false; 183 } 184 // break; 185 // } 186 // case TypeDecl::Dtype: // dtype can be consistently replaced with void [only pointers, which become void*] 187 // out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) ); 188 // break; 189 // case TypeDecl::Ftype: // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype] 190 // out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) ); 191 // break; 192 // } 193 } 194 195 // if any parameters left over, not done 196 if ( baseParam != baseParams.end() ) return false; 197 // // if not enough parameters given, substitute remaining incomplete types for placeholders 198 // for ( ; baseParam != baseParams.end(); ++baseParam ) { 199 // switch ( (*baseParam)->get_kind() ) { 200 // case TypeDecl::Any: // no more substitutions here, fail early 201 // return false; 202 // case TypeDecl::Dtype: // dtype can be consistently replaced with void [only pointers, which become void*] 203 // out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) ); 204 // break; 205 // case TypeDecl::Ftype: // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype] 206 // out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) ); 207 // break; 208 // } 209 // } 210 211 return allConcrete; 212 } 213 214 /// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out 215 void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs, 199 216 std::list< Declaration* >& out ) { 200 217 // substitute types into new members 201 TypeSubstitution subs( baseParams.begin(), baseParams.end(), params.begin() );218 TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() ); 202 219 for ( std::list< Declaration* >::const_iterator member = in.begin(); member != in.end(); ++member ) { 203 220 Declaration *newMember = (*member)->clone(); … … 215 232 // exit early if no need for further mutation 216 233 if ( inst->get_parameters().empty() ) return inst; 234 assert( inst->get_baseParameters() && "Base struct has parameters" ); 235 236 // check if type can be concretely instantiated; put substitutions into typeSubs 237 std::list< TypeExpr* > typeSubs; 238 if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) { 239 deleteAll( typeSubs ); 240 return inst; 241 } 217 242 218 243 // make concrete instantiation of generic type 219 StructDecl *concDecl = instantiations.lookup( inst );244 StructDecl *concDecl = instantiations.lookup( inst, typeSubs ); 220 245 if ( ! concDecl ) { 221 assert( inst->get_baseParameters() && "Base struct has parameters" );222 246 // set concDecl to new type, insert type declaration into statements to add 223 247 concDecl = new StructDecl( typeNamer.newName( inst->get_name() ) ); 224 substituteMembers( inst->get_baseStruct()->get_members(), 225 *inst->get_baseParameters(), inst->get_parameters(), 226 concDecl->get_members() ); 227 addDeclaration( concDecl ); 228 instantiations.insert( inst, concDecl ); 248 substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() ); 249 DeclMutator::addDeclaration( concDecl ); 250 instantiations.insert( inst, typeSubs, concDecl ); 229 251 } 230 252 StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() ); 231 253 newInst->set_baseStruct( concDecl ); 254 255 deleteAll( typeSubs ); 232 256 delete inst; 233 257 return newInst; … … 242 266 // exit early if no need for further mutation 243 267 if ( inst->get_parameters().empty() ) return inst; 244 268 assert( inst->get_baseParameters() && "Base union has parameters" ); 269 270 // check if type can be concretely instantiated; put substitutions into typeSubs 271 std::list< TypeExpr* > typeSubs; 272 if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) { 273 deleteAll( typeSubs ); 274 return inst; 275 } 276 245 277 // make concrete instantiation of generic type 246 UnionDecl *concDecl = instantiations.lookup( inst );278 UnionDecl *concDecl = instantiations.lookup( inst, typeSubs ); 247 279 if ( ! concDecl ) { 248 280 // set concDecl to new type, insert type declaration into statements to add 249 assert( inst->get_baseParameters() && "Base union has parameters" );250 281 concDecl = new UnionDecl( typeNamer.newName( inst->get_name() ) ); 251 substituteMembers( inst->get_baseUnion()->get_members(), 252 *inst->get_baseParameters(), inst->get_parameters(), 253 concDecl->get_members() ); 254 addDeclaration( concDecl ); 255 instantiations.insert( inst, concDecl ); 282 substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() ); 283 DeclMutator::addDeclaration( concDecl ); 284 instantiations.insert( inst, typeSubs, concDecl ); 256 285 } 257 286 UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() ); 258 287 newInst->set_baseUnion( concDecl ); 288 289 deleteAll( typeSubs ); 259 290 delete inst; 260 291 return newInst; 261 292 } 293 294 // /// Gets the base struct or union declaration for a member expression; NULL if not applicable 295 // AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) { 296 // // get variable for member aggregate 297 // VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() ); 298 // if ( ! varExpr ) return NULL; 299 // 300 // // get object for variable 301 // ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() ); 302 // if ( ! objectDecl ) return NULL; 303 // 304 // // get base declaration from object type 305 // Type *objectType = objectDecl->get_type(); 306 // StructInstType *structType = dynamic_cast< StructInstType* >( objectType ); 307 // if ( structType ) return structType->get_baseStruct(); 308 // UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ); 309 // if ( unionType ) return unionType->get_baseUnion(); 310 // 311 // return NULL; 312 // } 313 // 314 // /// Finds the declaration with the given name, returning decls.end() if none such 315 // std::list< Declaration* >::const_iterator findDeclNamed( const std::list< Declaration* > &decls, const std::string &name ) { 316 // for( std::list< Declaration* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) { 317 // if ( (*decl)->get_name() == name ) return decl; 318 // } 319 // return decls.end(); 320 // } 321 // 322 // Expression* Instantiate::mutate( MemberExpr *memberExpr ) { 323 // // mutate, exiting early if no longer MemberExpr 324 // Expression *expr = Mutator::mutate( memberExpr ); 325 // memberExpr = dynamic_cast< MemberExpr* >( expr ); 326 // if ( ! memberExpr ) return expr; 327 // 328 // // get declaration of member and base declaration of member, exiting early if not found 329 // AggregateDecl *memberBase = getMemberBaseDecl( memberExpr ); 330 // if ( ! memberBase ) return memberExpr; 331 // DeclarationWithType *memberDecl = memberExpr->get_member(); 332 // std::list< Declaration* >::const_iterator baseIt = findDeclNamed( memberBase->get_members(), memberDecl->get_name() ); 333 // if ( baseIt == memberBase->get_members().end() ) return memberExpr; 334 // DeclarationWithType *baseDecl = dynamic_cast< DeclarationWithType* >( *baseIt ); 335 // if ( ! baseDecl ) return memberExpr; 336 // 337 // // check if stated type of the member is not the type of the member's declaration; if so, need a cast 338 // // this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker 339 // SymTab::Indexer dummy; 340 // if ( ResolvExpr::typesCompatible( memberDecl->get_type(), baseDecl->get_type(), dummy ) ) return memberExpr; 341 // else return new CastExpr( memberExpr, memberDecl->get_type() ); 342 // } 262 343 263 344 void Instantiate::doBeginScope() { 264 // push a new concrete type scope345 DeclMutator::doBeginScope(); 265 346 instantiations.beginScope(); 266 347 } 267 348 268 349 void Instantiate::doEndScope() { 269 // pop the last concrete type scope350 DeclMutator::doEndScope(); 270 351 instantiations.endScope(); 271 352 } -
src/GenPoly/Lvalue.cc
r267cb3d r083cf31 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:41:33 201513 // Update Count : 112 // Last Modified On : Tue Dec 15 15:33:13 2015 13 // Update Count : 3 14 14 // 15 15 … … 35 35 const std::list<Label> noLabels; 36 36 37 /// Replace uses of lvalue returns with appropriate pointers 37 38 class Pass1 : public Mutator { 38 39 public: … … 46 47 }; 47 48 49 /// Replace declarations of lvalue returns with appropriate pointers 48 50 class Pass2 : public Visitor { 49 51 public: … … 120 122 if ( retval && retStmt->get_expr() ) { 121 123 assert( ! retStmt->get_expr()->get_results().empty() ); 122 while ( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {123 retStmt->set_expr( castExpr->get_arg() );124 retStmt->get_expr()->set_env( castExpr->get_env() );125 castExpr->set_env( 0 );126 castExpr->set_arg( 0 );127 delete castExpr;128 } // while129 124 if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) { 125 // ***** Code Removal ***** because casts may be stripped already 126 127 // strip casts because not allowed to take address of cast 128 // while ( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) { 129 // retStmt->set_expr( castExpr->get_arg() ); 130 // retStmt->get_expr()->set_env( castExpr->get_env() ); 131 // castExpr->set_env( 0 ); 132 // castExpr->set_arg( 0 ); 133 // delete castExpr; 134 // } // while 130 135 retStmt->set_expr( new AddressExpr( retStmt->get_expr()->acceptMutator( *this ) ) ); 131 136 } else { -
src/GenPoly/PolyMutator.h
r267cb3d r083cf31 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri Aug 14 15:27:38201513 // Update Count : 412 // Last Modified On : Tue Dec 08 15:19:05 2015 13 // Update Count : 5 14 14 // 15 15 … … 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 ); 55 57 Statement* mutateStatement( Statement *stmt ); 56 58 Expression* mutateExpression( Expression *expr ); 57 static void makeTyVarMap( Type *type, TyVarMap &tyVarMap );58 59 59 60 TyVarMap scopeTyVars; -
src/GenPoly/ScrubTyVars.cc
r267cb3d r083cf31 13 13 // Update Count : 2 14 14 // 15 16 #include <sstream> 17 #include <string> 15 18 16 19 #include "GenPoly.h" … … 42 45 43 46 Expression * ScrubTyVars::mutate( SizeofExpr *szeof ) { 44 // sizeof( T ) => T parameter, which is the size of T45 if ( Type InstType *typeInst = dynamic_cast< TypeInstType * >( szeof->get_type() ) ) {46 Expression *expr = new NameExpr( typeInst->get_name() );47 // sizeof( T ) => _sizeof_T parameter, which is the size of T 48 if ( Type *polyType = isPolyType( szeof->get_type() ) ) { 49 Expression *expr = new NameExpr( sizeofName( polyType ) ); 47 50 return expr; 48 51 } else { 49 52 return Mutator::mutate( szeof ); 53 } // if 54 } 55 56 Expression * ScrubTyVars::mutate( AlignofExpr *algnof ) { 57 // alignof( T ) => _alignof_T parameter, which is the alignment of T 58 if ( Type *polyType = isPolyType( algnof->get_type() ) ) { 59 Expression *expr = new NameExpr( alignofName( polyType ) ); 60 return expr; 61 } else { 62 return Mutator::mutate( algnof ); 50 63 } // if 51 64 } -
src/GenPoly/ScrubTyVars.h
r267cb3d r083cf31 17 17 #define _SCRUBTYVARS_H 18 18 19 #include <string> 20 19 21 #include "GenPoly.h" 20 22 … … 26 28 public: 27 29 ScrubTyVars( bool doAll, const TyVarMap &tyVars ): doAll( doAll ), tyVars( tyVars ) {} 28 30 31 /// Like scrub( SynTreeClass* ), but only applies to type variables in `tyVars` 29 32 template< typename SynTreeClass > 30 33 static SynTreeClass *scrub( SynTreeClass *target, const TyVarMap &tyVars ); 34 /// Replaces dtypes and ftypes with the appropriate void type, and sizeof expressions of polymorphic types with the proper variable 31 35 template< typename SynTreeClass > 32 36 static SynTreeClass *scrub( SynTreeClass *target ); … … 34 38 virtual Type* mutate( TypeInstType *typeInst ); 35 39 Expression* mutate( SizeofExpr *szeof ); 40 Expression* mutate( AlignofExpr *algnof ); 36 41 virtual Type* mutate( PointerType *pointer ); 37 42 private: -
src/GenPoly/Specialize.cc
r267cb3d r083cf31 17 17 18 18 #include "Specialize.h" 19 #include "GenPoly.h" 19 20 #include "PolyMutator.h" 20 21 … … 87 88 } 88 89 89 /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise90 FunctionType * getFunctionType( Type *ty ) {91 PointerType *ptrType;92 if ( ( ptrType = dynamic_cast< PointerType* >( ty ) ) ) {93 return dynamic_cast< FunctionType* >( ptrType->get_base() ); // pointer if FunctionType, NULL otherwise94 } else {95 return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise96 }97 }98 99 90 /// Generates a thunk that calls `actual` with type `funType` and returns its address 100 91 Expression * Specialize::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) { -
src/GenPoly/module.mk
r267cb3d r083cf31 23 23 GenPoly/CopyParams.cc \ 24 24 GenPoly/FindFunction.cc \ 25 GenPoly/InstantiateGeneric.cc 25 GenPoly/InstantiateGeneric.cc \ 26 GenPoly/DeclMutator.cc -
src/InitTweak/InitModel.h
r267cb3d r083cf31 72 72 void visit( ConstantExpr * ); 73 73 void visit( SizeofExpr * ) { throw 0; } 74 void visit( AlignofExpr * ) { throw 0; } 74 75 void visit( AttrExpr * ) { throw 0; } 75 76 void visit( LogicalExpr * ) { throw 0; } -
src/InitTweak/RemoveInit.cc
r267cb3d r083cf31 7 7 // RemoveInit.cc -- 8 8 // 9 // Author : Ro dolfo G. Esteves9 // Author : Rob Schluntz 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 16:39:32201513 // Update Count : 1 12 // Last Modified On : Tue Dec 15 15:37:26 2015 13 // Update Count : 15 14 14 // 15 15 … … 26 26 const std::list<Label> noLabels; 27 27 } 28 29 class RemoveInit : public Mutator { 30 public: 31 RemoveInit(); 32 virtual ObjectDecl * mutate(ObjectDecl *objDecl); 33 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ); 34 35 virtual Statement * mutate( ReturnStmt * returnStmt ); 36 37 virtual CompoundStmt * mutate(CompoundStmt * compoundStmt); 38 39 protected: 40 std::list< Statement* > stmtsToAddBefore; 41 std::list< Statement* > stmtsToAddAfter; 42 void mutateStatementList( std::list< Statement* > &statements ); 43 44 std::list<DeclarationWithType*> returnVals; 45 UniqueName tempNamer; 46 std::string funcName; 47 }; 28 48 29 49 void tweak( std::list< Declaration * > translationUnit ) { … … 32 52 } 33 53 54 RemoveInit::RemoveInit() : tempNamer( "_retVal" ) {} 55 34 56 void RemoveInit::mutateStatementList( std::list< Statement* > &statements ) { 35 57 for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) { … … 38 60 } // if 39 61 *i = (*i)->acceptMutator( *this ); 62 if ( ! stmtsToAddBefore.empty() ) { 63 statements.splice( i, stmtsToAddBefore ); 64 } // if 40 65 } // for 41 66 if ( ! stmtsToAddAfter.empty() ) { … … 49 74 } 50 75 51 // in the case where an object has an initializer and a polymorphic type, insert an assignment 52 // immediately after the declaration. This will (seemingly) cause the later phases to do the right 53 // thing with the assignment 76 // in the case where an object has an initializer and a polymorphic type, insert an assignment immediately after the 77 // declaration. This will (seemingly) cause the later phases to do the right thing with the assignment 54 78 ObjectDecl *RemoveInit::mutate( ObjectDecl *objDecl ) { 55 79 if (objDecl->get_init() && dynamic_cast<TypeInstType*>(objDecl->get_type())) { … … 63 87 return objDecl; 64 88 } 89 90 Statement *RemoveInit::mutate( ReturnStmt *returnStmt ) { 91 // update for multiple return values 92 assert( returnVals.size() == 0 || returnVals.size() == 1 ); 93 // hands off if the function returns an lvalue - we don't want to allocate a temporary if a variable's address 94 // is being returned 95 if ( returnStmt->get_expr() && returnVals.size() == 1 && funcName != "?=?" && ! returnVals.front()->get_type()->get_isLvalue() ) { 96 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, returnVals.front()->get_type()->clone(), 0 ); 97 stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) ); 98 99 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); 100 assign->get_args().push_back( new AddressExpr (new NameExpr( newObj->get_name() ) ) ); 101 assign->get_args().push_back( returnStmt->get_expr() ); 102 stmtsToAddBefore.push_back(new ExprStmt(noLabels, assign)); 103 104 returnStmt->set_expr( new VariableExpr( newObj ) ); 105 } // if 106 return returnStmt; 107 } 108 109 DeclarationWithType* RemoveInit::mutate( FunctionDecl *functionDecl ) { 110 std::list<DeclarationWithType*> oldReturnVals = returnVals; 111 std::string oldFuncName = funcName; 112 113 FunctionType * type = functionDecl->get_functionType(); 114 returnVals = type->get_returnVals(); 115 funcName = functionDecl->get_name(); 116 DeclarationWithType * decl = Mutator::mutate( functionDecl ); 117 returnVals = oldReturnVals; 118 funcName = oldFuncName; 119 return decl; 120 } 65 121 } // namespace InitTweak 66 122 -
src/InitTweak/RemoveInit.h
r267cb3d r083cf31 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 16:40:11201513 // Update Count : 112 // Last Modified On : Fri Nov 27 17:00:47 2015 13 // Update Count : 2 14 14 // 15 15 … … 27 27 /// Adds assignment statements for polymorphic type initializers 28 28 void tweak( std::list< Declaration * > translationUnit ); 29 30 class RemoveInit : public Mutator {31 public:32 // RemoveInit();33 virtual ObjectDecl *mutate(ObjectDecl *objDecl);34 virtual CompoundStmt *mutate(CompoundStmt *compoundStmt);35 protected:36 std::list< Statement* > stmtsToAddAfter;37 void mutateStatementList( std::list< Statement* > &statements );38 };39 29 } // namespace 40 30 -
src/Makefile.in
r267cb3d r083cf31 122 122 GenPoly/cfa_cpp-FindFunction.$(OBJEXT) \ 123 123 GenPoly/cfa_cpp-InstantiateGeneric.$(OBJEXT) \ 124 GenPoly/cfa_cpp-DeclMutator.$(OBJEXT) \ 124 125 InitTweak/cfa_cpp-InitModel.$(OBJEXT) \ 125 126 InitTweak/cfa_cpp-InitExpander.$(OBJEXT) \ … … 348 349 GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \ 349 350 GenPoly/CopyParams.cc GenPoly/FindFunction.cc \ 350 GenPoly/InstantiateGeneric.cc InitTweak/InitModel.cc \ 351 InitTweak/InitExpander.cc InitTweak/Mutate.cc \ 352 InitTweak/Association.cc InitTweak/RemoveInit.cc \ 353 Parser/parser.yy Parser/lex.ll Parser/TypedefTable.cc \ 354 Parser/ParseNode.cc Parser/DeclarationNode.cc \ 355 Parser/ExpressionNode.cc Parser/StatementNode.cc \ 356 Parser/InitializerNode.cc Parser/TypeData.cc \ 357 Parser/LinkageSpec.cc Parser/parseutility.cc Parser/Parser.cc \ 351 GenPoly/InstantiateGeneric.cc GenPoly/DeclMutator.cc \ 352 InitTweak/InitModel.cc InitTweak/InitExpander.cc \ 353 InitTweak/Mutate.cc InitTweak/Association.cc \ 354 InitTweak/RemoveInit.cc Parser/parser.yy Parser/lex.ll \ 355 Parser/TypedefTable.cc Parser/ParseNode.cc \ 356 Parser/DeclarationNode.cc Parser/ExpressionNode.cc \ 357 Parser/StatementNode.cc Parser/InitializerNode.cc \ 358 Parser/TypeData.cc Parser/LinkageSpec.cc \ 359 Parser/parseutility.cc Parser/Parser.cc \ 358 360 ResolvExpr/AlternativeFinder.cc ResolvExpr/Alternative.cc \ 359 361 ResolvExpr/Unify.cc ResolvExpr/PtrsAssignable.cc \ … … 411 413 esac; \ 412 414 done; \ 413 echo ' cd $(top_srcdir) && $(AUTOMAKE) -- gnusrc/Makefile'; \415 echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ 414 416 $(am__cd) $(top_srcdir) && \ 415 $(AUTOMAKE) -- gnusrc/Makefile417 $(AUTOMAKE) --foreign src/Makefile 416 418 .PRECIOUS: Makefile 417 419 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status … … 556 558 GenPoly/$(DEPDIR)/$(am__dirstamp) 557 559 GenPoly/cfa_cpp-InstantiateGeneric.$(OBJEXT): GenPoly/$(am__dirstamp) \ 560 GenPoly/$(DEPDIR)/$(am__dirstamp) 561 GenPoly/cfa_cpp-DeclMutator.$(OBJEXT): GenPoly/$(am__dirstamp) \ 558 562 GenPoly/$(DEPDIR)/$(am__dirstamp) 559 563 InitTweak/$(am__dirstamp): … … 785 789 -rm -f GenPoly/cfa_cpp-Box.$(OBJEXT) 786 790 -rm -f GenPoly/cfa_cpp-CopyParams.$(OBJEXT) 791 -rm -f GenPoly/cfa_cpp-DeclMutator.$(OBJEXT) 787 792 -rm -f GenPoly/cfa_cpp-FindFunction.$(OBJEXT) 788 793 -rm -f GenPoly/cfa_cpp-GenPoly.$(OBJEXT) … … 895 900 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/cfa_cpp-Box.Po@am__quote@ 896 901 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/cfa_cpp-CopyParams.Po@am__quote@ 902 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Po@am__quote@ 897 903 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/cfa_cpp-FindFunction.Po@am__quote@ 898 904 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/cfa_cpp-GenPoly.Po@am__quote@ … … 1376 1382 @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/cfa_cpp-InstantiateGeneric.obj `if test -f 'GenPoly/InstantiateGeneric.cc'; then $(CYGPATH_W) 'GenPoly/InstantiateGeneric.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/InstantiateGeneric.cc'; fi` 1377 1383 1384 GenPoly/cfa_cpp-DeclMutator.o: GenPoly/DeclMutator.cc 1385 @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/cfa_cpp-DeclMutator.o -MD -MP -MF GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Tpo -c -o GenPoly/cfa_cpp-DeclMutator.o `test -f 'GenPoly/DeclMutator.cc' || echo '$(srcdir)/'`GenPoly/DeclMutator.cc 1386 @am__fastdepCXX_TRUE@ $(am__mv) GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Tpo GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Po 1387 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='GenPoly/DeclMutator.cc' object='GenPoly/cfa_cpp-DeclMutator.o' libtool=no @AMDEPBACKSLASH@ 1388 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1389 @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/cfa_cpp-DeclMutator.o `test -f 'GenPoly/DeclMutator.cc' || echo '$(srcdir)/'`GenPoly/DeclMutator.cc 1390 1391 GenPoly/cfa_cpp-DeclMutator.obj: GenPoly/DeclMutator.cc 1392 @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/cfa_cpp-DeclMutator.obj -MD -MP -MF GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Tpo -c -o GenPoly/cfa_cpp-DeclMutator.obj `if test -f 'GenPoly/DeclMutator.cc'; then $(CYGPATH_W) 'GenPoly/DeclMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/DeclMutator.cc'; fi` 1393 @am__fastdepCXX_TRUE@ $(am__mv) GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Tpo GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Po 1394 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='GenPoly/DeclMutator.cc' object='GenPoly/cfa_cpp-DeclMutator.obj' libtool=no @AMDEPBACKSLASH@ 1395 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1396 @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/cfa_cpp-DeclMutator.obj `if test -f 'GenPoly/DeclMutator.cc'; then $(CYGPATH_W) 'GenPoly/DeclMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/DeclMutator.cc'; fi` 1397 1378 1398 InitTweak/cfa_cpp-InitModel.o: InitTweak/InitModel.cc 1379 1399 @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/cfa_cpp-InitModel.o -MD -MP -MF InitTweak/$(DEPDIR)/cfa_cpp-InitModel.Tpo -c -o InitTweak/cfa_cpp-InitModel.o `test -f 'InitTweak/InitModel.cc' || echo '$(srcdir)/'`InitTweak/InitModel.cc -
src/Parser/ExpressionNode.cc
r267cb3d r083cf31 586 586 } 587 587 case OperatorNode::AlignOf: 588 { 589 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) { 590 return new AlignofExpr( arg->get_decl()->buildType()); 591 } else { 592 return new AlignofExpr( args.front()); 593 } // if 594 } 588 595 case OperatorNode::SizeOf: 589 596 { 590 /// bool isSizeOf = ( op->get_type() == OperatorNode::SizeOf );591 592 597 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) { 593 598 return new SizeofExpr( arg->get_decl()->buildType()); -
src/ResolvExpr/AlternativeFinder.cc
r267cb3d r083cf31 792 792 } 793 793 794 void AlternativeFinder::visit( AlignofExpr *alignofExpr ) { 795 if ( alignofExpr->get_isType() ) { 796 alternatives.push_back( Alternative( alignofExpr->clone(), env, Cost::zero ) ); 797 } else { 798 // find all alternatives for the argument to sizeof 799 AlternativeFinder finder( indexer, env ); 800 finder.find( alignofExpr->get_expr() ); 801 // find the lowest cost alternative among the alternatives, otherwise ambiguous 802 AltList winners; 803 findMinCost( finder.alternatives.begin(), finder.alternatives.end(), back_inserter( winners ) ); 804 if ( winners.size() != 1 ) { 805 throw SemanticError( "Ambiguous expression in alignof operand: ", alignofExpr->get_expr() ); 806 } // if 807 // return the lowest cost alternative for the argument 808 Alternative &choice = winners.front(); 809 alternatives.push_back( Alternative( new AlignofExpr( choice.expr->clone() ), choice.env, Cost::zero ) ); 810 } // if 811 } 812 794 813 void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) { 795 814 // assume no polymorphism -
src/ResolvExpr/AlternativeFinder.h
r267cb3d r083cf31 56 56 virtual void visit( ConstantExpr *constantExpr ); 57 57 virtual void visit( SizeofExpr *sizeofExpr ); 58 virtual void visit( AlignofExpr *sizeofExpr ); 58 59 virtual void visit( AttrExpr *attrExpr ); 59 60 virtual void visit( LogicalExpr *logicalExpr ); -
src/SymTab/Indexer.cc
r267cb3d r083cf31 215 215 } else { 216 216 maybeAccept( sizeofExpr->get_expr(), *this ); 217 } 218 } 219 220 void Indexer::visit( AlignofExpr *alignofExpr ) { 221 acceptAllNewScope( alignofExpr->get_results(), *this ); 222 if ( alignofExpr->get_isType() ) { 223 maybeAccept( alignofExpr->get_type(), *this ); 224 } else { 225 maybeAccept( alignofExpr->get_expr(), *this ); 217 226 } 218 227 } -
src/SymTab/Indexer.h
r267cb3d r083cf31 54 54 virtual void visit( ConstantExpr *constantExpr ); 55 55 virtual void visit( SizeofExpr *sizeofExpr ); 56 virtual void visit( AlignofExpr *alignofExpr ); 56 57 virtual void visit( AttrExpr *attrExpr ); 57 58 virtual void visit( LogicalExpr *logicalExpr ); -
src/SymTab/Mangler.cc
r267cb3d r083cf31 30 30 31 31 namespace SymTab { 32 Mangler::Mangler( bool mangleOverridable ) : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ) { 33 } 34 35 //Mangler::Mangler( const Mangler & ) 36 // : mangleName(), varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( isTopLevel ) 37 //{ 38 //} 32 std::string Mangler::mangleType( Type *ty ) { 33 Mangler mangler( false, true ); 34 maybeAccept( ty, mangler ); 35 return mangler.get_mangleName(); 36 } 37 38 Mangler::Mangler( bool mangleOverridable, bool typeMode ) 39 : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ) {} 40 39 41 Mangler::Mangler( const Mangler &rhs ) : mangleName() { 40 42 varNums = rhs.varNums; … … 42 44 isTopLevel = rhs.isTopLevel; 43 45 mangleOverridable = rhs.mangleOverridable; 46 typeMode = rhs.typeMode; 44 47 } 45 48 … … 152 155 void Mangler::mangleRef( ReferenceToType *refType, std::string prefix ) { 153 156 printQualifiers( refType ); 157 154 158 mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name(); 155 159 } 156 160 161 void Mangler::mangleGenericRef( ReferenceToType *refType, std::string prefix ) { 162 printQualifiers( refType ); 163 164 std::ostringstream oldName( mangleName.str() ); 165 mangleName.clear(); 166 167 mangleName << prefix << refType->get_name(); 168 169 std::list< Expression* >& params = refType->get_parameters(); 170 if ( ! params.empty() ) { 171 mangleName << "_"; 172 for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) { 173 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 174 assert(paramType && "Aggregate parameters should be type expressions"); 175 maybeAccept( paramType->get_type(), *this ); 176 } 177 mangleName << "_"; 178 } 179 180 oldName << mangleName.str().length() << mangleName.str(); 181 mangleName.str( oldName.str() ); 182 } 183 157 184 void Mangler::visit( StructInstType *aggregateUseType ) { 158 mangleRef( aggregateUseType, "s" ); 185 if ( typeMode ) mangleGenericRef( aggregateUseType, "s" ); 186 else mangleRef( aggregateUseType, "s" ); 159 187 } 160 188 161 189 void Mangler::visit( UnionInstType *aggregateUseType ) { 162 mangleRef( aggregateUseType, "u" ); 190 if ( typeMode ) mangleGenericRef( aggregateUseType, "u" ); 191 else mangleRef( aggregateUseType, "u" ); 163 192 } 164 193 … … 209 238 210 239 void Mangler::printQualifiers( Type *type ) { 240 // skip if not including qualifiers 241 if ( typeMode ) return; 242 211 243 if ( ! type->get_forall().empty() ) { 212 244 std::list< std::string > assertionNames; … … 227 259 varNums[ (*i )->get_name() ] = std::pair< int, int >( nextVarNum++, (int )(*i )->get_kind() ); 228 260 for ( std::list< DeclarationWithType* >::iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) { 229 Mangler sub_mangler( mangleOverridable );261 Mangler sub_mangler( mangleOverridable, typeMode ); 230 262 sub_mangler.nextVarNum = nextVarNum; 231 263 sub_mangler.isTopLevel = false; -
src/SymTab/Mangler.h
r267cb3d r083cf31 22 22 23 23 namespace SymTab { 24 /// Mangles names to a unique C identifier 24 25 class Mangler : public Visitor { 25 26 public: 27 /// Mangle syntax tree object; primary interface to clients 26 28 template< typename SynTreeClass > 27 static std::string mangle( SynTreeClass *decl, bool mangleOverridable = true ); // interface to clients 29 static std::string mangle( SynTreeClass *decl, bool mangleOverridable = true ); 30 /// Mangle a type name; secondary interface 31 static std::string mangleType( Type* ty ); 28 32 29 /// using Visitor::visit;30 33 virtual void visit( ObjectDecl *declaration ); 31 34 virtual void visit( FunctionDecl *declaration ); … … 45 48 std::string get_mangleName() { return mangleName.str(); } 46 49 private: 47 std::ostringstream mangleName; 50 std::ostringstream mangleName; ///< Mangled name being constructed 48 51 typedef std::map< std::string, std::pair< int, int > > VarMapType; 49 VarMapType varNums; 50 int nextVarNum; 51 bool isTopLevel; 52 bool mangleOverridable; 52 VarMapType varNums; ///< Map of type variables to indices 53 int nextVarNum; ///< Next type variable index 54 bool isTopLevel; ///< Is the Mangler at the top level 55 bool mangleOverridable; ///< Specially mangle overridable built-in methods 56 bool typeMode; ///< Produce a unique mangled name for a type 53 57 54 Mangler( bool mangleOverridable );58 Mangler( bool mangleOverridable, bool typeMode ); 55 59 Mangler( const Mangler & ); 56 60 57 61 void mangleDecl( DeclarationWithType *declaration ); 58 62 void mangleRef( ReferenceToType *refType, std::string prefix ); 63 void mangleGenericRef( ReferenceToType *refType, std::string prefix ); 59 64 60 65 void printQualifiers( Type *type ); … … 63 68 template< typename SynTreeClass > 64 69 std::string Mangler::mangle( SynTreeClass *decl, bool mangleOverridable ) { 65 Mangler mangler( mangleOverridable );70 Mangler mangler( mangleOverridable, false ); 66 71 maybeAccept( decl, mangler ); 67 72 return mangler.get_mangleName(); -
src/SymTab/Validate.cc
r267cb3d r083cf31 10 10 // Created On : Sun May 17 21:50:04 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri Dec 18 14:32:59 201513 // Update Count : 26 812 // Last Modified On : Thu Jan 07 11:27:49 2016 13 // Update Count : 269 14 14 // 15 15 … … 86 86 }; 87 87 88 /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers 88 /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers. 89 89 class Pass1 : public Visitor { 90 90 typedef Visitor Parent; … … 161 161 }; 162 162 163 class ReturnChecker : public Visitor { 164 public: 165 /// Checks that return statements return nothing if their return type is void 166 /// and return something if the return type is non-void. 167 static void checkFunctionReturns( std::list< Declaration * > & translationUnit ); 168 169 private: 170 virtual void visit( FunctionDecl * functionDecl ); 171 172 virtual void visit( ReturnStmt * returnStmt ); 173 174 std::list< DeclarationWithType * > returnVals; 175 }; 176 163 177 class EliminateTypedef : public Mutator { 164 178 public: 165 166 179 EliminateTypedef() : scopeLevel( 0 ) {} 180 /// Replaces typedefs by forward declarations 167 181 static void eliminateTypedef( std::list< Declaration * > &translationUnit ); 168 182 private: … … 209 223 acceptAll( translationUnit, pass1 ); 210 224 acceptAll( translationUnit, pass2 ); 225 ReturnChecker::checkFunctionReturns( translationUnit ); 211 226 AutogenerateRoutines::autogenerateRoutines( translationUnit ); 212 227 acceptAll( translationUnit, pass3 ); … … 850 865 } 851 866 867 void ReturnChecker::checkFunctionReturns( std::list< Declaration * > & translationUnit ) { 868 ReturnChecker checker; 869 acceptAll( translationUnit, checker ); 870 } 871 872 void ReturnChecker::visit( FunctionDecl * functionDecl ) { 873 std::list< DeclarationWithType * > oldReturnVals = returnVals; 874 returnVals = functionDecl->get_functionType()->get_returnVals(); 875 Visitor::visit( functionDecl ); 876 returnVals = oldReturnVals; 877 } 878 879 void ReturnChecker::visit( ReturnStmt * returnStmt ) { 880 if ( returnStmt->get_expr() == NULL && returnVals.size() != 0 ) { 881 throw SemanticError( "Non-void function returns no values: " , returnStmt ); 882 } else if ( returnStmt->get_expr() != NULL && returnVals.size() == 0 ) { 883 throw SemanticError( "void function returns values: " , returnStmt ); 884 } 885 } 886 887 852 888 bool isTypedef( Declaration *decl ) { 853 889 return dynamic_cast< TypedefDecl * >( decl ); -
src/SynTree/Declaration.cc
r267cb3d r083cf31 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Jul 13 17:58:38201513 // Update Count : 1 011 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Dec 09 14:08:29 2015 13 // Update Count : 12 14 14 // 15 15 … … 55 55 } 56 56 57 std::ostream & operator<<( std::ostream & out, Declaration * decl ) { 58 decl->print( out ); 59 return out; 60 } 61 62 57 63 // Local Variables: // 58 64 // tab-width: 4 // -
src/SynTree/Declaration.h
r267cb3d r083cf31 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Jul 13 18:15:59201513 // Update Count : 2811 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Dec 09 14:08:22 2015 13 // Update Count : 32 14 14 // 15 15 … … 259 259 }; 260 260 261 std::ostream & operator<<( std::ostream & out, Declaration * decl ); 262 261 263 #endif // DECLARATION_H 262 264 -
src/SynTree/Expression.cc
r267cb3d r083cf31 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Sep 02 12:07:10201513 // Update Count : 3 312 // Last Modified On : Wed Dec 09 14:10:29 2015 13 // Update Count : 34 14 14 // 15 15 … … 122 122 void SizeofExpr::print( std::ostream &os, int indent) const { 123 123 os << std::string( indent, ' ' ) << "Sizeof Expression on: "; 124 125 if (isType) 126 type->print(os, indent + 2); 127 else 128 expr->print(os, indent + 2); 129 130 os << std::endl; 131 Expression::print( os, indent ); 132 } 133 134 AlignofExpr::AlignofExpr( Expression *expr_, Expression *_aname ) : 135 Expression( _aname ), expr(expr_), type(0), isType(false) { 136 add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) ); 137 } 138 139 AlignofExpr::AlignofExpr( Type *type_, Expression *_aname ) : 140 Expression( _aname ), expr(0), type(type_), isType(true) { 141 add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) ); 142 } 143 144 AlignofExpr::AlignofExpr( const AlignofExpr &other ) : 145 Expression( other ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) { 146 } 147 148 AlignofExpr::~AlignofExpr() { 149 delete expr; 150 delete type; 151 } 152 153 void AlignofExpr::print( std::ostream &os, int indent) const { 154 os << std::string( indent, ' ' ) << "Alignof Expression on: "; 124 155 125 156 if (isType) … … 345 376 } 346 377 378 std::ostream & operator<<( std::ostream & out, Expression * expr ) { 379 expr->print( out ); 380 return out; 381 } 382 347 383 // Local Variables: // 348 384 // tab-width: 4 // -
src/SynTree/Expression.h
r267cb3d r083cf31 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Jul 24 13:49:28201513 // Update Count : 1 811 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Dec 09 14:10:21 2015 13 // Update Count : 19 14 14 // 15 15 … … 23 23 #include "Constant.h" 24 24 25 /// Expression is the root type for all expressions 25 26 class Expression { 26 27 public: … … 47 48 }; 48 49 49 // ParamEntry contains the i.d. of a declaration and a type that is derived from that declaration, 50 // but subject to decay-to-pointer and type parameter renaming 51 50 /// ParamEntry contains the i.d. of a declaration and a type that is derived from that declaration, 51 /// but subject to decay-to-pointer and type parameter renaming 52 52 struct ParamEntry { 53 53 ParamEntry(): decl( 0 ), actualType( 0 ), formalType( 0 ), expr( 0 ) {} … … 65 65 typedef std::map< UniqueId, ParamEntry > InferredParams; 66 66 67 // ApplicationExpr represents the application of a function to a set of parameters. This is the 68 // result of running an UntypedExpr through the expression analyzer. 69 67 /// ApplicationExpr represents the application of a function to a set of parameters. This is the 68 /// result of running an UntypedExpr through the expression analyzer. 70 69 class ApplicationExpr : public Expression { 71 70 public: … … 89 88 }; 90 89 91 // UntypedExpr represents the application of a function to a set of parameters, but where the 92 // particular overload for the function name has not yet been determined. Most operators are 93 // converted into functional form automatically, to permit operator overloading. 94 90 /// UntypedExpr represents the application of a function to a set of parameters, but where the 91 /// particular overload for the function name has not yet been determined. Most operators are 92 /// converted into functional form automatically, to permit operator overloading. 95 93 class UntypedExpr : public Expression { 96 94 public: … … 118 116 }; 119 117 120 // this classcontains a name whose meaning is still not determined118 /// NameExpr contains a name whose meaning is still not determined 121 119 class NameExpr : public Expression { 122 120 public: … … 139 137 // function-call format. 140 138 141 // AddressExpr represents a address-of expression, e.g. &e139 /// AddressExpr represents a address-of expression, e.g. &e 142 140 class AddressExpr : public Expression { 143 141 public: … … 174 172 }; 175 173 176 // CastExpr represents a type cast expression, e.g. (int)e174 /// CastExpr represents a type cast expression, e.g. (int)e 177 175 class CastExpr : public Expression { 178 176 public: … … 193 191 }; 194 192 195 // UntypedMemberExpr represents a member selection operation, e.g. q.p before processing by the expression analyzer193 /// UntypedMemberExpr represents a member selection operation, e.g. q.p before processing by the expression analyzer 196 194 class UntypedMemberExpr : public Expression { 197 195 public: … … 214 212 }; 215 213 216 // MemberExpr represents a member selection operation, e.g. q.p after processing by the expression analyzer214 /// MemberExpr represents a member selection operation, e.g. q.p after processing by the expression analyzer 217 215 class MemberExpr : public Expression { 218 216 public: … … 235 233 }; 236 234 237 // VariableExpr represents an expression that simply refers to the value of a named variable235 /// VariableExpr represents an expression that simply refers to the value of a named variable 238 236 class VariableExpr : public Expression { 239 237 public: … … 253 251 }; 254 252 255 // ConstantExpr represents an expression that simply refers to the value of a constant253 /// ConstantExpr represents an expression that simply refers to the value of a constant 256 254 class ConstantExpr : public Expression { 257 255 public: … … 271 269 }; 272 270 273 // SizeofExpr represents a sizeof expression (could be sizeof(int) or sizeof 3+4)271 /// SizeofExpr represents a sizeof expression (could be sizeof(int) or sizeof 3+4) 274 272 class SizeofExpr : public Expression { 275 273 public: … … 296 294 }; 297 295 298 // AttrExpr represents an @attribute expression (like sizeof, but user-defined) 296 /// AlignofExpr represents an alignof expression 297 class AlignofExpr : public Expression { 298 public: 299 AlignofExpr( Expression *expr, Expression *_aname = 0 ); 300 AlignofExpr( const AlignofExpr &other ); 301 AlignofExpr( Type *type, Expression *_aname = 0 ); 302 virtual ~AlignofExpr(); 303 304 Expression *get_expr() const { return expr; } 305 void set_expr( Expression *newValue ) { expr = newValue; } 306 Type *get_type() const { return type; } 307 void set_type( Type *newValue ) { type = newValue; } 308 bool get_isType() const { return isType; } 309 void set_isType( bool newValue ) { isType = newValue; } 310 311 virtual AlignofExpr *clone() const { return new AlignofExpr( *this ); } 312 virtual void accept( Visitor &v ) { v.visit( this ); } 313 virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); } 314 virtual void print( std::ostream &os, int indent = 0 ) const; 315 private: 316 Expression *expr; 317 Type *type; 318 bool isType; 319 }; 320 321 /// AttrExpr represents an @attribute expression (like sizeof, but user-defined) 299 322 class AttrExpr : public Expression { 300 323 public: … … 324 347 }; 325 348 326 // LogicalExpr represents a short-circuit boolean expression (&& or ||)349 /// LogicalExpr represents a short-circuit boolean expression (&& or ||) 327 350 class LogicalExpr : public Expression { 328 351 public: … … 347 370 }; 348 371 349 // ConditionalExpr represents the three-argument conditional ( p ? a : b )372 /// ConditionalExpr represents the three-argument conditional ( p ? a : b ) 350 373 class ConditionalExpr : public Expression { 351 374 public: … … 371 394 }; 372 395 373 // CommaExpr represents the sequence operator ( a, b )396 /// CommaExpr represents the sequence operator ( a, b ) 374 397 class CommaExpr : public Expression { 375 398 public: … … 392 415 }; 393 416 394 // TupleExpr represents a tuple expression ( [a, b, c] )417 /// TupleExpr represents a tuple expression ( [a, b, c] ) 395 418 class TupleExpr : public Expression { 396 419 public: … … 410 433 }; 411 434 412 // SolvedTupleExpr represents a TupleExpr whose components have been type-resolved. It is effectively a shell for the code generator to work on435 /// SolvedTupleExpr represents a TupleExpr whose components have been type-resolved. It is effectively a shell for the code generator to work on 413 436 class SolvedTupleExpr : public Expression { 414 437 public: … … 428 451 }; 429 452 430 // TypeExpr represents a type used in an expression (e.g. as a type generator parameter)453 /// TypeExpr represents a type used in an expression (e.g. as a type generator parameter) 431 454 class TypeExpr : public Expression { 432 455 public: … … 446 469 }; 447 470 448 // AsmExpr represents a GCC 'asm constraint operand' used in an asm statement: [output] "=f" (result)471 /// AsmExpr represents a GCC 'asm constraint operand' used in an asm statement: [output] "=f" (result) 449 472 class AsmExpr : public Expression { 450 473 public: … … 472 495 }; 473 496 474 // ValofExpr represents a GCC 'lambda expression'497 /// ValofExpr represents a GCC 'lambda expression' 475 498 class UntypedValofExpr : public Expression { 476 499 public: … … 488 511 Statement *body; 489 512 }; 513 514 std::ostream & operator<<( std::ostream & out, Expression * expr ); 490 515 491 516 #endif // EXPRESSION_H -
src/SynTree/Mutator.cc
r267cb3d r083cf31 251 251 } 252 252 253 Expression *Mutator::mutate( AlignofExpr *alignofExpr ) { 254 mutateAll( alignofExpr->get_results(), *this ); 255 if ( alignofExpr->get_isType() ) { 256 alignofExpr->set_type( maybeMutate( alignofExpr->get_type(), *this ) ); 257 } else { 258 alignofExpr->set_expr( maybeMutate( alignofExpr->get_expr(), *this ) ); 259 } 260 return alignofExpr; 261 } 262 253 263 Expression *Mutator::mutate( AttrExpr *attrExpr ) { 254 264 mutateAll( attrExpr->get_results(), *this ); -
src/SynTree/Mutator.h
r267cb3d r083cf31 64 64 virtual Expression* mutate( ConstantExpr *constantExpr ); 65 65 virtual Expression* mutate( SizeofExpr *sizeofExpr ); 66 virtual Expression* mutate( AlignofExpr *alignofExpr ); 66 67 virtual Expression* mutate( AttrExpr *attrExpr ); 67 68 virtual Expression* mutate( LogicalExpr *logicalExpr ); -
src/SynTree/PointerType.cc
r267cb3d r083cf31 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon May 18 10:15:16201513 // Update Count : 212 // Last Modified On : Tue Dec 15 15:39:10 2015 13 // Update Count : 5 14 14 // 15 15 … … 20 20 PointerType::PointerType( const Type::Qualifiers &tq, Type *base ) 21 21 : Type( tq ), base( base ), dimension( 0 ), isVarLen( false ), isStatic( false ) { 22 base->set_isLvalue( false );23 22 } 24 23 25 24 PointerType::PointerType( const Type::Qualifiers &tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic ) 26 25 : Type( tq ), base( base ), dimension( dimension ), isVarLen( isVarLen ), isStatic( isStatic ) { 27 base->set_isLvalue( false );28 26 } 29 27 -
src/SynTree/Statement.cc
r267cb3d r083cf31 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 25 12:19:50201513 // Update Count : 5 311 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Dec 09 14:09:34 2015 13 // Update Count : 54 14 14 // 15 15 … … 337 337 } 338 338 339 std::ostream & operator<<( std::ostream & out, Statement * statement ) { 340 statement->print( out ); 341 return out; 342 } 343 339 344 // Local Variables: // 340 345 // tab-width: 4 // -
src/SynTree/Statement.h
r267cb3d r083cf31 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 25 18:25:37201513 // Update Count : 4 411 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Dec 09 14:09:24 2015 13 // Update Count : 46 14 14 // 15 15 … … 396 396 }; 397 397 398 std::ostream & operator<<( std::ostream & out, Statement * statement ); 399 398 400 #endif // STATEMENT_H 399 401 -
src/SynTree/SynTree.h
r267cb3d r083cf31 69 69 class ConstantExpr; 70 70 class SizeofExpr; 71 class AlignofExpr; 71 72 class AttrExpr; 72 73 class LogicalExpr; -
src/SynTree/Type.cc
r267cb3d r083cf31 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Jul 9 16:45:13201513 // Update Count : 311 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Dec 09 14:08:48 2015 13 // Update Count : 4 14 14 // 15 15 … … 80 80 } 81 81 82 std::ostream & operator<<( std::ostream & out, Type * type ) { 83 type->print( out ); 84 return out; 85 } 86 82 87 // Local Variables: // 83 88 // tab-width: 4 // -
src/SynTree/Type.h
r267cb3d r083cf31 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Type.h -- 7 // Type.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Nov 20 12:54:09201513 // Update Count : 1 511 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri Dec 18 14:46:18 2015 13 // Update Count : 18 14 14 // 15 15 … … 23 23 class Type { 24 24 public: 25 struct Qualifiers { 25 struct Qualifiers { 26 26 Qualifiers(): isConst( false ), isVolatile( false ), isRestrict( false ), isLvalue( false ), isAtomic( false ), isAttribute( false ) {} 27 27 Qualifiers( bool isConst, bool isVolatile, bool isRestrict, bool isLvalue, bool isAtomic, bool isAttribute ): isConst( isConst ), isVolatile( isVolatile ), isRestrict( isRestrict ), isLvalue( isLvalue ), isAtomic( isAtomic ), isAttribute( isAttribute ) {} 28 28 29 29 Qualifiers &operator+=( const Qualifiers &other ); 30 30 Qualifiers &operator-=( const Qualifiers &other ); … … 36 36 bool operator<( const Qualifiers &other ); 37 37 bool operator>( const Qualifiers &other ); 38 38 39 39 bool isConst; 40 40 bool isVolatile; … … 43 43 bool isAtomic; 44 44 bool isAttribute; 45 }; 45 }; 46 46 47 47 Type( const Qualifiers &tq ); … … 85 85 class BasicType : public Type { 86 86 public: 87 enum Kind { 87 enum Kind { 88 88 Bool, 89 89 Char, … … 108 108 LongDoubleImaginary, 109 109 NUMBER_OF_BASIC_TYPES 110 }; 110 }; 111 111 112 112 static const char *typeNames[]; // string names for basic types, MUST MATCH with Kind … … 149 149 private: 150 150 Type *base; 151 151 152 152 // In C99, pointer types can be qualified in many ways e.g., int f( int a[ static 3 ] ) 153 153 Expression *dimension; … … 188 188 virtual ~FunctionType(); 189 189 190 std::list<DeclarationWithType*> & get_returnVals() { return returnVals; }191 std::list<DeclarationWithType*> & get_parameters() { return parameters; }190 std::list<DeclarationWithType*> & get_returnVals() { return returnVals; } 191 std::list<DeclarationWithType*> & get_parameters() { return parameters; } 192 192 bool get_isVarArgs() { return isVarArgs; } 193 193 void set_isVarArgs( bool newValue ) { isVarArgs = newValue; } … … 217 217 void set_name( std::string newValue ) { name = newValue; } 218 218 std::list< Expression* >& get_parameters() { return parameters; } 219 219 220 220 virtual ReferenceToType *clone() const = 0; 221 221 virtual void accept( Visitor &v ) = 0; … … 240 240 /// Accesses generic parameters of base struct (NULL if none such) 241 241 std::list<TypeDecl*> * get_baseParameters(); 242 242 243 243 /// Looks up the members of this struct named "name" and places them into "foundDecls". 244 244 /// Clones declarations into "foundDecls", caller responsible for freeing … … 250 250 private: 251 251 virtual std::string typeString() const; 252 252 253 253 // this decl is not "owned" by the struct inst; it is merely a pointer to elsewhere in the tree, 254 254 // where the structure used in this type is actually defined … … 267 267 /// Accesses generic parameters of base union (NULL if none such) 268 268 std::list<TypeDecl*> * get_baseParameters(); 269 269 270 270 /// looks up the members of this union named "name" and places them into "foundDecls" 271 271 /// Clones declarations into "foundDecls", caller responsible for freeing … … 277 277 private: 278 278 virtual std::string typeString() const; 279 279 280 280 // this decl is not "owned" by the union inst; it is merely a pointer to elsewhere in the tree, 281 281 // where the union used in this type is actually defined … … 310 310 private: 311 311 virtual std::string typeString() const; 312 312 313 313 // this member is filled in by the validate pass, which instantiates the members of the correponding 314 314 // aggregate with the actual type parameters specified for this use of the context … … 327 327 bool get_isFtype() const { return isFtype; } 328 328 void set_isFtype( bool newValue ) { isFtype = newValue; } 329 329 330 330 virtual TypeInstType *clone() const { return new TypeInstType( *this ); } 331 331 virtual void accept( Visitor &v ) { v.visit( this ); } … … 463 463 } 464 464 465 std::ostream & operator<<( std::ostream & out, Type * type ); 466 465 467 #endif // TYPE_H 466 468 -
src/SynTree/Visitor.cc
r267cb3d r083cf31 210 210 } 211 211 212 void Visitor::visit( AlignofExpr *alignofExpr ) { 213 acceptAll( alignofExpr->get_results(), *this ); 214 if ( alignofExpr->get_isType() ) { 215 maybeAccept( alignofExpr->get_type(), *this ); 216 } else { 217 maybeAccept( alignofExpr->get_expr(), *this ); 218 } 219 } 220 212 221 void Visitor::visit( AttrExpr *attrExpr ) { 213 222 acceptAll( attrExpr->get_results(), *this ); -
src/SynTree/Visitor.h
r267cb3d r083cf31 64 64 virtual void visit( ConstantExpr *constantExpr ); 65 65 virtual void visit( SizeofExpr *sizeofExpr ); 66 virtual void visit( AlignofExpr *alignofExpr ); 66 67 virtual void visit( AttrExpr *attrExpr ); 67 68 virtual void visit( LogicalExpr *logicalExpr ); -
src/Tuples/FlattenTuple.cc
r267cb3d r083cf31 46 46 void FlattenTuple::CollectArgs::visit( ConstantExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } 47 47 void FlattenTuple::CollectArgs::visit( SizeofExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } 48 void FlattenTuple::CollectArgs::visit( AlignofExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } 48 49 void FlattenTuple::CollectArgs::visit( AttrExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } 49 50 void FlattenTuple::CollectArgs::visit( LogicalExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } -
src/Tuples/FlattenTuple.h
r267cb3d r083cf31 42 42 virtual void visit( ConstantExpr * ); 43 43 virtual void visit( SizeofExpr * ); 44 virtual void visit( AlignofExpr * ); 44 45 virtual void visit( AttrExpr * ); 45 46 virtual void visit( LogicalExpr * ); -
src/driver/Makefile.in
r267cb3d r083cf31 195 195 esac; \ 196 196 done; \ 197 echo ' cd $(top_srcdir) && $(AUTOMAKE) -- gnusrc/driver/Makefile'; \197 echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/driver/Makefile'; \ 198 198 $(am__cd) $(top_srcdir) && \ 199 $(AUTOMAKE) -- gnusrc/driver/Makefile199 $(AUTOMAKE) --foreign src/driver/Makefile 200 200 .PRECIOUS: Makefile 201 201 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status -
src/examples/Makefile.in
r267cb3d r083cf31 191 191 esac; \ 192 192 done; \ 193 echo ' cd $(top_srcdir) && $(AUTOMAKE) -- gnusrc/examples/Makefile'; \193 echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/examples/Makefile'; \ 194 194 $(am__cd) $(top_srcdir) && \ 195 $(AUTOMAKE) -- gnusrc/examples/Makefile195 $(AUTOMAKE) --foreign src/examples/Makefile 196 196 .PRECIOUS: Makefile 197 197 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status -
src/examples/fstream_test.c
r267cb3d r083cf31 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed May 27 18:13:43201513 // Update Count : 212 // Last Modified On : Mon Nov 23 14:43:32 2015 13 // Update Count : 40 14 14 // 15 15 … … 20 20 ifstream *sin = ifstream_stdin(); 21 21 int nombre; 22 sout << "Appuyez un nombre, s'il vous plâit:\n"; 23 sin >> &nombre; 24 sout << "Vous avez appuyé: " << nombre << "\n"; 22 sout | "Entrez un nombre, s'il vous plaît:\n"; 23 sin | &nombre; 24 sout | "Vous avez entré " | nombre | " stocké à l'adresse " | &nombre | endl; 25 sout | "nombre " | nombre | " est " 26 | (nombre > 0 ? "plus grand que" : 27 nombre == 0 ? "égal à" : "moins de") 28 | " zéro" | endl; 29 30 sout | "Entrez trois nombres, s'il vous plaît:\n"; 31 int i, j, k; 32 sin | &i | &j | &k; 33 sout | "Vous avez entré " | "i:" | i | " j:" | j | " k:" | k | endl; 34 35 sout | 3 | ' ' | 3.5 | ' ' | 'a' | ' ' | "abc" | endl; 25 36 } 26 37 -
src/examples/hello.c
r267cb3d r083cf31 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Nov 20 16:02:50201513 // Update Count : 312 // Last Modified On : Sun Nov 22 17:40:37 2015 13 // Update Count : 5 14 14 // 15 15 … … 19 19 ofstream *sout = ofstream_stdout(); 20 20 ifstream *sin = ifstream_stdin(); 21 sout << "Bonjour au monde!\n"; 22 sout << 3 << " " << 3.5 << " " << 'a' << " " << "abc" << "\n"; 23 int i, j, k; 24 sin >> &i >> &j >> &k; 25 sout << "i:" << i << " j:" << j << " k:" << k << "\n"; 21 sout | "Bonjour au monde!\n"; 26 22 } 27 23 -
src/examples/iostream.c
r267cb3d r083cf31 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Nov 20 13:19:19201513 // Update Count : 912 // Last Modified On : Mon Dec 7 23:08:02 2015 13 // Update Count : 24 14 14 // 15 15 … … 21 21 22 22 forall( dtype ostype | ostream( ostype ) ) 23 ostype * ? <<?( ostype *os, char c ) {23 ostype * ?|?( ostype *os, char c ) { 24 24 return write( os, &c, 1 ); 25 } // ? <<?25 } // ?|? 26 26 27 27 forall( dtype ostype | ostream( ostype ) ) 28 ostype * ? <<?( ostype *os, int i ) {28 ostype * ?|?( ostype *os, int i ) { 29 29 char buffer[32]; // larger than the largest integer 30 30 sprintf( buffer, "%d", i ); 31 31 return write( os, buffer, strlen( buffer ) ); 32 } // ? <<?32 } // ?|? 33 33 34 34 forall( dtype ostype | ostream( ostype ) ) 35 ostype * ? <<?( ostype *os, double d ) {35 ostype * ?|?( ostype *os, double d ) { 36 36 char buffer[32]; // larger than the largest double 37 37 sprintf( buffer, "%g", d ); 38 38 return write( os, buffer, strlen( buffer ) ); 39 } // ? <<?39 } // ?|? 40 40 41 41 forall( dtype ostype | ostream( ostype ) ) 42 ostype * ? <<?( ostype *os, const char *cp ) {42 ostype * ?|?( ostype *os, const char *cp ) { 43 43 return write( os, cp, strlen( cp ) ); 44 } // ? <<?44 } // ?|? 45 45 46 46 forall( dtype ostype | ostream( ostype ) ) 47 ostype * ? <<?( ostype *os, const void *p ) {47 ostype * ?|?( ostype *os, const void *p ) { 48 48 char buffer[32]; // larger than the largest pointer 49 49 sprintf( buffer, "%p", p ); 50 50 return write( os, buffer, strlen( buffer ) ); 51 } // ?<<? 51 } // ?|? 52 53 54 forall( dtype ostype, dtype retostype | ostream( ostype ) | ostream( retostype ) ) 55 retostype * ?|?( ostype *os, retostype * (*manip)(ostype*) ) { 56 return manip(os); 57 } 58 59 forall( dtype ostype | ostream( ostype ) ) 60 ostype * endl( ostype * os ) { 61 os | "\n"; 62 // flush 63 return os; 64 } // endl 52 65 53 66 forall( type elt_type | writeable( elt_type ), … … 56 69 void write( iterator_type begin, iterator_type end, os_type *os ) { 57 70 void print( elt_type i ) { 58 os << i <<' ';71 os | i | ' '; 59 72 } 60 73 for_each( begin, end, print ); 61 } // ? <<?74 } // ?|? 62 75 63 76 forall( type elt_type | writeable( elt_type ), … … 65 78 dtype os_type | ostream( os_type ) ) 66 79 void write_reverse( iterator_type begin, iterator_type end, os_type *os ) { 67 void print( elt_type i ) { 68 os << i << ' '; 69 } 80 void print( elt_type i ) { os | i | ' '; } 70 81 for_each_reverse( begin, end, print ); 71 } // ? <<?82 } // ?|? 72 83 73 84 74 85 forall( dtype istype | istream( istype ) ) 75 istype * ? >>?( istype *is, char *cp ) {86 istype * ?|?( istype *is, char *cp ) { 76 87 return read( is, cp, 1 ); 77 } // ? >>?88 } // ?|? 78 89 79 90 forall( dtype istype | istream( istype ) ) 80 istype * ? >>?( istype *is, int *ip ) {91 istype * ?|?( istype *is, int *ip ) { 81 92 char cur; 82 93 83 94 // skip some whitespace 84 95 do { 85 is >>&cur;96 is | &cur; 86 97 if ( fail( is ) || eof( is ) ) return is; 87 98 } while ( !( cur >= '0' && cur <= '9' ) ); … … 91 102 while ( cur >= '0' && cur <= '9' ) { 92 103 *ip = *ip * 10 + ( cur - '0' ); 93 is >>&cur;104 is | &cur; 94 105 if ( fail( is ) || eof( is ) ) return is; 95 106 } … … 97 108 unread( is, cur ); 98 109 return is; 99 } // ? >>?110 } // ?|? 100 111 101 112 // Local Variables: // -
src/examples/iostream.h
r267cb3d r083cf31 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Nov 19 17:56:51201513 // Update Count : 512 // Last Modified On : Mon Nov 23 14:15:25 2015 13 // Update Count : 17 14 14 // 15 15 … … 27 27 28 28 context writeable( type T ) { 29 forall( dtype ostype | ostream( ostype ) ) ostype * ? <<?( ostype *, T );29 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, T ); 30 30 }; 31 31 32 32 // implement writable for some intrinsic types 33 33 34 forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, char ); 35 forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, int ); 36 forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, double ); 37 forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, const char * ); 38 forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, void * ); 34 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, char ); 35 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, int ); 36 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, double ); 37 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, const char * ); 38 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, const void * ); 39 40 forall( dtype ostype, dtype retostype | ostream( ostype ) | ostream( retostype ) ) retostype * ?|?( ostype *os, retostype * (* manip)(ostype*) ); 41 forall( dtype ostype | ostream( ostype ) ) ostype * endl( ostype * ); 39 42 40 43 // writes the range [begin, end) to the given stream … … 49 52 void write_reverse( iterator_type begin, iterator_type end, os_type *os ); 50 53 54 //****************************************************************************** 51 55 52 56 context istream( dtype istype ) { … … 58 62 59 63 context readable( type T ) { 60 forall( dtype istype | istream( istype ) ) istype * ? <<?( istype *, T );64 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, T ); 61 65 }; 62 66 63 67 forall( dtype istype | istream( istype ) ) 64 istype * ? >>?( istype *, char * );68 istype * ?|?( istype *, char * ); 65 69 66 70 forall( dtype istype | istream( istype ) ) 67 istype * ? >>?( istype *, int * );71 istype * ?|?( istype *, int * ); 68 72 69 73 #endif // IOSTREAM_H -
src/examples/sum.c
r267cb3d r083cf31 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Sep 28 15:09:55201513 // Update Count : 11 812 // Last Modified On : Sat Nov 21 18:08:18 2015 13 // Update Count : 119 14 14 // 15 15 … … 53 53 } 54 54 sout << "sum from " << low << " to " << High << " is " 55 << (int)sum( size, a ) << ", check " << (int)s << "\n";55 << (int)sum( size, a ) << ", check " << (int)s << endl; 56 56 57 57 int s = 0, a[size]; … … 62 62 } 63 63 sout << "sum from " << low << " to " << High << " is " 64 << sum( size, (int *)a ) << ", check " << (int)s << "\n";64 << sum( size, (int *)a ) << ", check " << (int)s << endl; 65 65 66 66 double s = 0.0, a[size]; … … 72 72 printf( "%g\n", sum( size, (double *)a ) ); 73 73 // sout << "sum from " << low / 10.0 << " to " << High / 10.0 << " is " 74 // << sum( size, (double *)a ) << ", check " << (double)s << "\n";74 // << sum( size, (double *)a ) << ", check " << (double)s << endl; 75 75 76 76 float s = 0.0, a[size]; … … 82 82 printf( "%g\n", sum( size, (float *)a ) ); 83 83 // sout << "sum from " << low / 10.0 << " to " << High / 10.0 << " is " 84 // << sum( size, (float *)a ) << ", check " << (float)s << "\n";84 // << sum( size, (float *)a ) << ", check " << (float)s << endl; 85 85 } 86 86 -
src/examples/vector_test.c
r267cb3d r083cf31 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T hu Nov 19 17:54:34201513 // Update Count : 912 // Last Modified On : Tue Dec 15 16:02:56 2015 13 // Update Count : 13 14 14 // 15 15 … … 27 27 int num; 28 28 29 sout << "enter N elements and C-d on a separate line:\n";29 sout | "enter N elements and C-d on a separate line:" | endl; 30 30 for ( ;; ) { 31 sin >>#31 sin | # 32 32 if ( fail( sin ) || eof( sin ) ) break; 33 33 append( &vec, num ); … … 35 35 // write out the numbers 36 36 37 sout << "Array elements:\n";37 sout | "Array elements:" | endl; 38 38 write( begin( vec ), end( vec ), sout ); 39 sout << "\n";39 sout | endl; 40 40 41 sout << "Array elements reversed:\n";41 sout | "Array elements reversed:" | endl; 42 42 write_reverse( begin( vec ), end( vec ), sout ); 43 sout << "\n";43 sout | endl; 44 44 } 45 45 -
src/libcfa/Makefile.am
r267cb3d r083cf31 11 11 ## Created On : Sun May 31 08:54:01 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Thu Jun 4 22:49:16201514 ## Update Count : 713 ## Last Modified On : Wed Dec 16 22:58:17 2015 14 ## Update Count : 9 15 15 ############################################################################### 16 16 … … 44 44 45 45 libcfa-prelude.c : ${srcdir}/prelude.cf 46 ${libdir}/cfa-cpp -l ${srcdir}/prelude.cf $@46 ../cfa-cpp -l ${srcdir}/prelude.cf $@ # use src/cfa-cpp as not in lib until after install 47 47 48 48 libcfa-prelude.o : libcfa-prelude.c -
src/libcfa/Makefile.in
r267cb3d r083cf31 220 220 esac; \ 221 221 done; \ 222 echo ' cd $(top_srcdir) && $(AUTOMAKE) -- gnusrc/libcfa/Makefile'; \222 echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/libcfa/Makefile'; \ 223 223 $(am__cd) $(top_srcdir) && \ 224 $(AUTOMAKE) -- gnusrc/libcfa/Makefile224 $(AUTOMAKE) --foreign src/libcfa/Makefile 225 225 .PRECIOUS: Makefile 226 226 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status … … 542 542 543 543 libcfa-prelude.c : ${srcdir}/prelude.cf 544 ${libdir}/cfa-cpp -l ${srcdir}/prelude.cf $@544 ../cfa-cpp -l ${srcdir}/prelude.cf $@ # use src/cfa-cpp as not in lib until after install 545 545 546 546 libcfa-prelude.o : libcfa-prelude.c -
src/main.cc
r267cb3d r083cf31 10 10 // Created On : Fri May 15 23:12:02 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Nov 19 22:31:40201513 // Update Count : 1 6812 // Last Modified On : Thu Dec 17 12:59:06 2015 13 // Update Count : 179 14 14 // 15 15 … … 187 187 // read in the builtins and the prelude 188 188 if ( ! nopreludep ) { // include gcc builtins 189 FILE * builtins = fopen( CFA_LIBDIR "/builtins.cf", "r" ); 189 // -l is for initial build ONLY and builtins.cf is not in the lib directory so access it here. 190 FILE * builtins = fopen( libcfap ? "./builtins.cf" : CFA_LIBDIR "/builtins.cf", "r" ); 190 191 if ( builtins == NULL ) { 191 192 std::cerr << "Error: can't open builtins" << std::endl; … … 196 197 197 198 if ( ! libcfap ) { 198 // read the prelude in, if we'renot generating the cfa library199 // read the prelude in, if not generating the cfa library 199 200 FILE * prelude = fopen( CFA_LIBDIR "/prelude.cf", "r" ); 200 201 if ( prelude == NULL ) { … … 203 204 } // if 204 205 205 206 parse( prelude, LinkageSpec::Intrinsic ); 206 207 } // if 207 208 } // if 208 209 209 if ( libcfap ) { 210 parse( input, LinkageSpec::Intrinsic ); 211 } else { 212 parse( input, LinkageSpec::Cforall, grammarp ); 213 } 210 parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, grammarp ); 214 211 215 212 if ( parsep ) {
Note: See TracChangeset
for help on using the changeset viewer.