Changes in / [a2d4d1c:4dfa562]
- Location:
- src
- Files:
-
- 6 added
- 24 edited
-
CodeGen/CodeGenerator.cc (modified) (8 diffs)
-
GenPoly/Box.cc (modified) (28 diffs)
-
GenPoly/DeclMutator.cc (added)
-
GenPoly/DeclMutator.h (added)
-
GenPoly/PolyMutator.cc (added)
-
GenPoly/PolyMutator.h (added)
-
GenPoly/Specialize.cc (modified) (9 diffs)
-
GenPoly/module.mk (modified) (3 diffs)
-
InitTweak/FixInit.cc (modified) (28 diffs)
-
InitTweak/GenInit.cc (modified) (16 diffs)
-
InitTweak/GenInit.h (modified) (1 diff)
-
InitTweak/InitTweak.cc (modified) (9 diffs)
-
InitTweak/InitTweak.h (modified) (1 diff)
-
Makefile.in (modified) (13 diffs)
-
ResolvExpr/Resolver.cc (modified) (1 diff)
-
ResolvExpr/Resolver.h (modified) (1 diff)
-
ResolvExpr/TypeEnvironment.cc (modified) (1 diff)
-
SymTab/Autogen.cc (modified) (17 diffs)
-
SymTab/FixFunction.cc (modified) (1 diff)
-
SymTab/Indexer.cc (modified) (2 diffs)
-
SymTab/Indexer.h (modified) (3 diffs)
-
SymTab/Mangler.cc (modified) (15 diffs)
-
SymTab/Validate.cc (modified) (6 diffs)
-
SynTree/AddStmtVisitor.cc (added)
-
SynTree/AddStmtVisitor.h (added)
-
SynTree/Visitor.h (modified) (1 diff)
-
SynTree/module.mk (modified) (1 diff)
-
Tuples/TupleExpansion.cc (modified) (1 diff)
-
main.cc (modified) (1 diff)
-
tests/.expect/64/sched-ext-parse.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
ra2d4d1c r4dfa562 443 443 void CodeGenerator::postvisit( UntypedExpr * untypedExpr ) { 444 444 extension( untypedExpr ); 445 if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr-> function) ) {445 if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) { 446 446 OperatorInfo opInfo; 447 if ( operatorLookup( nameExpr-> name, opInfo ) ) {448 std::list< Expression* >::iterator arg = untypedExpr-> args.begin();447 if ( operatorLookup( nameExpr->get_name(), opInfo ) ) { 448 std::list< Expression* >::iterator arg = untypedExpr->get_args().begin(); 449 449 switch ( opInfo.type ) { 450 450 case OT_INDEX: 451 assert( untypedExpr-> args.size() == 2 );451 assert( untypedExpr->get_args().size() == 2 ); 452 452 (*arg++)->accept( *visitor ); 453 453 output << "["; … … 461 461 case OT_CTOR: 462 462 case OT_DTOR: 463 if ( untypedExpr-> args.size() == 1 ) {463 if ( untypedExpr->get_args().size() == 1 ) { 464 464 // the expression fed into a single parameter constructor or destructor may contain side 465 465 // effects, so must still output this expression … … 480 480 (*arg++)->accept( *visitor ); 481 481 output << opInfo.symbol << "{ "; 482 genCommaList( arg, untypedExpr-> args.end() );482 genCommaList( arg, untypedExpr->get_args().end() ); 483 483 output << "}) /* " << opInfo.inputName << " */"; 484 484 } // if … … 488 488 case OT_PREFIXASSIGN: 489 489 case OT_LABELADDRESS: 490 assert( untypedExpr-> args.size() == 1 );490 assert( untypedExpr->get_args().size() == 1 ); 491 491 output << "("; 492 492 output << opInfo.symbol; … … 497 497 case OT_POSTFIX: 498 498 case OT_POSTFIXASSIGN: 499 assert( untypedExpr-> args.size() == 1 );499 assert( untypedExpr->get_args().size() == 1 ); 500 500 (*arg)->accept( *visitor ); 501 501 output << opInfo.symbol; … … 504 504 case OT_INFIX: 505 505 case OT_INFIXASSIGN: 506 assert( untypedExpr-> args.size() == 2 );506 assert( untypedExpr->get_args().size() == 2 ); 507 507 output << "("; 508 508 (*arg++)->accept( *visitor ); … … 517 517 } // switch 518 518 } else { 519 // builtin routines 520 nameExpr->accept( *visitor ); 521 output << "("; 522 genCommaList( untypedExpr->args.begin(), untypedExpr->args.end() ); 523 output << ")"; 519 if ( nameExpr->get_name() == "..." ) { // case V1 ... V2 or case V1~V2 520 assert( untypedExpr->get_args().size() == 2 ); 521 (*untypedExpr->get_args().begin())->accept( *visitor ); 522 output << " ... "; 523 (*--untypedExpr->get_args().end())->accept( *visitor ); 524 } else { // builtin routines 525 nameExpr->accept( *visitor ); 526 output << "("; 527 genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() ); 528 output << ")"; 529 } // if 524 530 } // if 525 531 } else { 526 untypedExpr-> function->accept( *visitor );532 untypedExpr->get_function()->accept( *visitor ); 527 533 output << "("; 528 genCommaList( untypedExpr-> args.begin(), untypedExpr->args.end() );534 genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() ); 529 535 output << ")"; 530 536 } // if … … 532 538 533 539 void CodeGenerator::postvisit( RangeExpr * rangeExpr ) { 534 rangeExpr-> low->accept( *visitor );540 rangeExpr->get_low()->accept( *visitor ); 535 541 output << " ... "; 536 rangeExpr-> high->accept( *visitor );542 rangeExpr->get_high()->accept( *visitor ); 537 543 } 538 544 -
src/GenPoly/Box.cc
ra2d4d1c r4dfa562 32 32 #include "Common/UniqueName.h" // for UniqueName 33 33 #include "Common/utility.h" // for toString 34 #include "DeclMutator.h" // for DeclMutator 34 35 #include "FindFunction.h" // for findFunction, findAndReplace... 35 36 #include "GenPoly/ErasableScopedMap.h" // for ErasableScopedMap<>::const_i... … … 38 39 #include "Lvalue.h" // for generalizedLvalue 39 40 #include "Parser/LinkageSpec.h" // for C, Spec, Cforall, Intrinsic 41 #include "PolyMutator.h" // for PolyMutator 40 42 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass 41 43 #include "ResolvExpr/typeops.h" // for typesCompatible … … 60 62 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 61 63 62 class BoxPass { 63 protected: 64 BoxPass() : scopeTyVars( TypeDecl::Data{} ) {} 65 TyVarMap scopeTyVars; 64 /// Adds layout-generation functions to polymorphic types 65 class LayoutFunctionBuilder final : public DeclMutator { 66 unsigned int functionNesting; // current level of nested functions 67 public: 68 LayoutFunctionBuilder() : functionNesting( 0 ) {} 69 70 using DeclMutator::mutate; 71 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override; 72 virtual Declaration *mutate( StructDecl *structDecl ) override; 73 virtual Declaration *mutate( UnionDecl *unionDecl ) override; 66 74 }; 67 75 68 /// Adds layout-generation functions to polymorphic types69 class LayoutFunctionBuilder final : public WithDeclsToAdd, public WithVisitorRef<LayoutFunctionBuilder>, public WithShortCircuiting {70 unsigned int functionNesting = 0; // current level of nested functions71 public:72 void previsit( FunctionDecl *functionDecl );73 void previsit( StructDecl *structDecl );74 void previsit( UnionDecl *unionDecl );75 };76 77 76 /// 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 78 class Pass1 final : public BoxPass, public WithTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting{77 class Pass1 final : public PolyMutator { 79 78 public: 80 79 Pass1(); 81 80 82 void premutate( FunctionDecl * functionDecl ); 83 void premutate( TypeDecl * typeDecl ); 84 void premutate( CommaExpr * commaExpr ); 85 Expression * postmutate( ApplicationExpr * appExpr ); 86 Expression * postmutate( UntypedExpr *expr ); 87 void premutate( AddressExpr * addrExpr ); 88 Expression * postmutate( AddressExpr * addrExpr ); 89 void premutate( ReturnStmt * returnStmt ); 90 void premutate( PointerType * pointerType ); 91 void premutate( FunctionType * functionType ); 92 93 void beginScope(); 94 void endScope(); 81 using PolyMutator::mutate; 82 virtual Expression *mutate( ApplicationExpr *appExpr ) override; 83 virtual Expression *mutate( AddressExpr *addrExpr ) override; 84 virtual Expression *mutate( UntypedExpr *expr ) override; 85 virtual DeclarationWithType* mutate( FunctionDecl *functionDecl ) override; 86 virtual TypeDecl *mutate( TypeDecl *typeDecl ) override; 87 virtual Expression *mutate( CommaExpr *commaExpr ) override; 88 virtual Expression *mutate( ConditionalExpr *condExpr ) override; 89 virtual Statement * mutate( ReturnStmt *returnStmt ) override; 90 virtual Type *mutate( PointerType *pointerType ) override; 91 virtual Type * mutate( FunctionType *functionType ) override; 92 93 virtual void doBeginScope() override; 94 virtual void doEndScope() override; 95 95 private: 96 96 /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application … … 129 129 /// * Moves polymorphic returns in function types to pointer-type parameters 130 130 /// * adds type size and assertion parameters to parameter lists 131 struct Pass2 final : public BoxPass, public WithGuards { 132 void handleAggDecl(); 133 134 DeclarationWithType * postmutate( FunctionDecl *functionDecl ); 135 void premutate( StructDecl *structDecl ); 136 void premutate( UnionDecl *unionDecl ); 137 void premutate( TraitDecl *unionDecl ); 138 void premutate( TypeDecl *typeDecl ); 139 void premutate( PointerType *pointerType ); 140 void premutate( FunctionType *funcType ); 131 class Pass2 final : public PolyMutator { 132 public: 133 template< typename DeclClass > 134 DeclClass *handleDecl( DeclClass *decl ); 135 template< typename AggDecl > 136 AggDecl * handleAggDecl( AggDecl * aggDecl ); 137 138 typedef PolyMutator Parent; 139 using Parent::mutate; 140 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override; 141 virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override; 142 virtual StructDecl *mutate( StructDecl *structDecl ) override; 143 virtual UnionDecl *mutate( UnionDecl *unionDecl ) override; 144 virtual TraitDecl *mutate( TraitDecl *unionDecl ) override; 145 virtual TypeDecl *mutate( TypeDecl *typeDecl ) override; 146 virtual TypedefDecl *mutate( TypedefDecl *typedefDecl ) override; 147 virtual Type *mutate( PointerType *pointerType ) override; 148 virtual Type *mutate( FunctionType *funcType ) override; 141 149 142 150 private: … … 150 158 /// * Calculates polymorphic offsetof expressions from offset array 151 159 /// * Inserts dynamic calculation of polymorphic type layouts where needed 152 class PolyGenericCalculator final : public BoxPass, publicWithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution {160 class PolyGenericCalculator final : public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution { 153 161 public: 154 162 PolyGenericCalculator(); … … 189 197 ScopedSet< std::string > knownOffsets; ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName 190 198 UniqueName bufNamer; ///< Namer for VLA buffers 199 TyVarMap scopeTyVars; 191 200 }; 192 201 193 202 /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, sizeof expressions of polymorphic types with the proper variable, and strips fields from generic struct declarations. 194 struct Pass3 final : public BoxPass, public WithGuards { 203 class Pass3 final : public PolyMutator { 204 public: 195 205 template< typename DeclClass > 196 void handleDecl( DeclClass * decl, Type * type ); 197 198 void premutate( ObjectDecl * objectDecl ); 199 void premutate( FunctionDecl * functionDecl ); 200 void premutate( TypedefDecl * typedefDecl ); 201 void premutate( StructDecl * structDecl ); 202 void premutate( UnionDecl * unionDecl ); 203 void premutate( TypeDecl * typeDecl ); 204 void premutate( PointerType * pointerType ); 205 void premutate( FunctionType * funcType ); 206 DeclClass *handleDecl( DeclClass *decl, Type *type ); 207 208 using PolyMutator::mutate; 209 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override; 210 virtual Declaration *mutate( StructDecl *structDecl ) override; 211 virtual Declaration *mutate( UnionDecl *unionDecl ) override; 212 virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override; 213 virtual TypedefDecl *mutate( TypedefDecl *objectDecl ) override; 214 virtual TypeDecl *mutate( TypeDecl *objectDecl ) override; 215 virtual Type *mutate( PointerType *pointerType ) override; 216 virtual Type *mutate( FunctionType *funcType ) override; 217 private: 206 218 }; 207 219 } // anonymous namespace … … 235 247 236 248 void box( std::list< Declaration *>& translationUnit ) { 237 PassVisitor<LayoutFunctionBuilder>layoutBuilder;238 Pass Visitor<Pass1>pass1;239 Pass Visitor<Pass2>pass2;249 LayoutFunctionBuilder layoutBuilder; 250 Pass1 pass1; 251 Pass2 pass2; 240 252 PassVisitor<PolyGenericCalculator> polyCalculator; 241 Pass Visitor<Pass3>pass3;242 243 acceptAll( translationUnit, layoutBuilder);244 mutate All( translationUnit, pass1 );245 mutate All( translationUnit, pass2 );253 Pass3 pass3; 254 255 layoutBuilder.mutateDeclarationList( translationUnit ); 256 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 257 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 246 258 mutateAll( translationUnit, polyCalculator ); 247 mutate All( translationUnit, pass3 );259 mutateTranslationUnit/*All*/( translationUnit, pass3 ); 248 260 } 249 261 250 262 ////////////////////////////////// LayoutFunctionBuilder //////////////////////////////////////////// 251 263 252 void LayoutFunctionBuilder::previsit( FunctionDecl *functionDecl ) { 253 visit_children = false; 254 maybeAccept( functionDecl->get_functionType(), *visitor ); 264 DeclarationWithType *LayoutFunctionBuilder::mutate( FunctionDecl *functionDecl ) { 265 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) ); 255 266 ++functionNesting; 256 maybeAccept( functionDecl->get_statements(), *visitor);267 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) ); 257 268 --functionNesting; 269 return functionDecl; 258 270 } 259 271 … … 344 356 } 345 357 346 void LayoutFunctionBuilder::previsit( StructDecl *structDecl ) {358 Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) { 347 359 // do not generate layout function for "empty" tag structs 348 visit_children = false; 349 if ( structDecl->get_members().empty() ) return; 360 if ( structDecl->get_members().empty() ) return structDecl; 350 361 351 362 // get parameters that can change layout, exiting early if none 352 363 std::list< TypeDecl* > otypeParams = takeOtypeOnly( structDecl->get_parameters() ); 353 if ( otypeParams.empty() ) return ;364 if ( otypeParams.empty() ) return structDecl; 354 365 355 366 // build layout function signature … … 402 413 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) ); 403 414 404 declsToAddAfter.push_back( layoutDecl ); 415 addDeclarationAfter( layoutDecl ); 416 return structDecl; 405 417 } 406 418 407 void LayoutFunctionBuilder::previsit( UnionDecl *unionDecl ) {419 Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) { 408 420 // do not generate layout function for "empty" tag unions 409 visit_children = false; 410 if ( unionDecl->get_members().empty() ) return; 421 if ( unionDecl->get_members().empty() ) return unionDecl; 411 422 412 423 // get parameters that can change layout, exiting early if none 413 424 std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() ); 414 if ( otypeParams.empty() ) return ;425 if ( otypeParams.empty() ) return unionDecl; 415 426 416 427 // build layout function signature … … 445 456 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) ); 446 457 447 declsToAddAfter.push_back( layoutDecl ); 458 addDeclarationAfter( layoutDecl ); 459 return unionDecl; 448 460 } 449 461 … … 489 501 Pass1::Pass1() : tempNamer( "_temp" ) {} 490 502 491 void Pass1::premutate( FunctionDecl *functionDecl ) {503 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) { 492 504 if ( functionDecl->get_statements() ) { // empty routine body ? 493 505 // std::cerr << "mutating function: " << functionDecl->get_mangleName() << std::endl; 494 GuardScope( scopeTyVars ); 495 GuardValue( retval ); 506 doBeginScope(); 507 scopeTyVars.beginScope(); 508 509 DeclarationWithType *oldRetval = retval; 496 510 497 511 // process polymorphic return value 498 512 retval = nullptr; 499 FunctionType *functionType = functionDecl->type; 500 if ( isDynRet( functionType ) && functionDecl->linkage != LinkageSpec::C ) { 501 retval = functionType->returnVals.front(); 513 if ( isDynRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() != LinkageSpec::C ) { 514 retval = functionDecl->get_functionType()->get_returnVals().front(); 502 515 503 516 // give names to unnamed return values 504 if ( retval-> name== "" ) {505 retval-> name = "_retparm";506 retval-> linkage = LinkageSpec::C;517 if ( retval->get_name() == "" ) { 518 retval->set_name( "_retparm" ); 519 retval->set_linkage( LinkageSpec::C ); 507 520 } // if 508 521 } // if 509 522 510 makeTyVarMap( functionType, scopeTyVars ); 511 512 std::list< DeclarationWithType *> ¶mList = functionType->parameters; 523 FunctionType *functionType = functionDecl->get_functionType(); 524 makeTyVarMap( functionDecl->get_functionType(), scopeTyVars ); 525 526 std::list< DeclarationWithType *> ¶mList = functionType->get_parameters(); 513 527 std::list< FunctionType *> functions; 514 for ( Type::ForallList::iterator tyVar = functionType-> forall.begin(); tyVar != functionType->forall.end(); ++tyVar ) {515 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)-> assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) {528 for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) { 529 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) { 516 530 findFunction( (*assert)->get_type(), functions, scopeTyVars, needsAdapter ); 517 531 } // for … … 528 542 } // if 529 543 } // for 544 545 functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) ); 546 547 scopeTyVars.endScope(); 548 retval = oldRetval; 549 doEndScope(); 530 550 // std::cerr << "end function: " << functionDecl->get_mangleName() << std::endl; 531 551 } // if 532 } 533 534 void Pass1::premutate( TypeDecl *typeDecl ) { 552 return functionDecl; 553 } 554 555 TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) { 535 556 addToTyVarMap( typeDecl, scopeTyVars ); 536 } 537 538 void Pass1::premutate( CommaExpr *commaExpr ) { 557 return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) ); 558 } 559 560 Expression *Pass1::mutate( CommaExpr *commaExpr ) { 539 561 // Attempting to find application expressions that were mutated by the copy constructor passes 540 562 // to use an explicit return variable, so that the variable can be reused as a parameter to the … … 552 574 } 553 575 } 576 577 commaExpr->set_arg1( maybeMutate( commaExpr->get_arg1(), *this ) ); 578 commaExpr->set_arg2( maybeMutate( commaExpr->get_arg2(), *this ) ); 579 return commaExpr; 580 } 581 582 Expression *Pass1::mutate( ConditionalExpr *condExpr ) { 583 condExpr->set_arg1( maybeMutate( condExpr->get_arg1(), *this ) ); 584 condExpr->set_arg2( maybeMutate( condExpr->get_arg2(), *this ) ); 585 condExpr->set_arg3( maybeMutate( condExpr->get_arg3(), *this ) ); 586 return condExpr; 587 554 588 } 555 589 … … 625 659 ObjectDecl *Pass1::makeTemporary( Type *type ) { 626 660 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, type, 0 ); 627 stmtsToAdd Before.push_back( new DeclStmt( noLabels, newObj ) );661 stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) ); 628 662 return newObj; 629 663 } … … 741 775 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, newType, 0 ); 742 776 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right??? 743 stmtsToAdd Before.push_back( new DeclStmt( noLabels, newObj ) );777 stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) ); 744 778 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax? 745 779 assign->get_args().push_back( new VariableExpr( newObj ) ); 746 780 assign->get_args().push_back( arg ); 747 stmtsToAdd Before.push_back( new ExprStmt( noLabels, assign ) );781 stmtsToAdd.push_back( new ExprStmt( noLabels, assign ) ); 748 782 arg = new AddressExpr( new VariableExpr( newObj ) ); 749 783 } // if … … 927 961 std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) ); 928 962 adapter = answer.first; 929 stmtsToAdd Before.push_back( new DeclStmt( noLabels, newAdapter ) );963 stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) ); 930 964 } // if 931 965 assert( adapter != adapters.end() ); … … 1084 1118 } 1085 1119 1086 Expression *Pass1:: postmutate( ApplicationExpr *appExpr ) {1120 Expression *Pass1::mutate( ApplicationExpr *appExpr ) { 1087 1121 // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl; 1088 1122 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) { … … 1090 1124 // } 1091 1125 // std::cerr << "\n"; 1092 1093 assert( appExpr->function->result ); 1094 FunctionType * function = getFunctionType( appExpr->function->result ); 1095 assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->function->result ).c_str() ); 1126 appExpr->get_function()->acceptMutator( *this ); 1127 mutateAll( appExpr->get_args(), *this ); 1128 1129 assert( appExpr->get_function()->has_result() ); 1130 FunctionType * function = getFunctionType( appExpr->get_function()->get_result() ); 1131 assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->get_function()->get_result() ).c_str() ); 1096 1132 1097 1133 if ( Expression *newExpr = handleIntrinsics( appExpr ) ) { … … 1146 1182 } 1147 1183 1148 Expression * Pass1::postmutate( UntypedExpr *expr ) {1149 if ( expr-> result && isPolyType( expr->result, scopeTyVars, env ) ) {1150 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr-> function) ) {1184 Expression *Pass1::mutate( UntypedExpr *expr ) { 1185 if ( expr->has_result() && isPolyType( expr->get_result(), scopeTyVars, env ) ) { 1186 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 1151 1187 if ( name->get_name() == "*?" ) { 1152 Expression *ret = expr-> args.front();1153 expr-> args.clear();1188 Expression *ret = expr->get_args().front(); 1189 expr->get_args().clear(); 1154 1190 delete expr; 1155 return ret ;1191 return ret->acceptMutator( *this ); 1156 1192 } // if 1157 1193 } // if 1158 1194 } // if 1159 return expr; 1160 } 1161 1162 void Pass1::premutate( AddressExpr * ) { visit_children = false; } 1163 Expression * Pass1::postmutate( AddressExpr * addrExpr ) { 1195 return PolyMutator::mutate( expr ); 1196 } 1197 1198 Expression *Pass1::mutate( AddressExpr *addrExpr ) { 1164 1199 assert( addrExpr->get_arg()->has_result() && ! addrExpr->get_arg()->get_result()->isVoid() ); 1165 1200 … … 1181 1216 // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward 1182 1217 // out of the if condition. 1183 addrExpr-> arg = addrExpr->get_arg()->acceptMutator( *visitor);1218 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) ); 1184 1219 // ... but must happen after mutate, since argument might change (e.g. intrinsic *?, ?[?]) - re-evaluate above comment 1185 1220 bool polytype = isPolyType( addrExpr->get_arg()->get_result(), scopeTyVars, env ); … … 1196 1231 } 1197 1232 1198 void Pass1::premutate( ReturnStmt *returnStmt ) { 1199 if ( retval && returnStmt->expr ) { 1200 assert( returnStmt->expr->result && ! returnStmt->expr->result->isVoid() ); 1201 delete returnStmt->expr; 1202 returnStmt->expr = nullptr; 1233 Statement * Pass1::mutate( ReturnStmt *returnStmt ) { 1234 if ( retval && returnStmt->get_expr() ) { 1235 assert( returnStmt->get_expr()->has_result() && ! returnStmt->get_expr()->get_result()->isVoid() ); 1236 delete returnStmt->get_expr(); 1237 returnStmt->set_expr( 0 ); 1238 } else { 1239 returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) ); 1203 1240 } // if 1204 } 1205 1206 void Pass1::premutate( PointerType *pointerType ) { 1207 GuardScope( scopeTyVars ); 1241 return returnStmt; 1242 } 1243 1244 Type * Pass1::mutate( PointerType *pointerType ) { 1245 scopeTyVars.beginScope(); 1208 1246 makeTyVarMap( pointerType, scopeTyVars ); 1209 } 1210 1211 void Pass1::premutate( FunctionType *functionType ) { 1212 GuardScope( scopeTyVars ); 1247 1248 Type *ret = Mutator::mutate( pointerType ); 1249 1250 scopeTyVars.endScope(); 1251 return ret; 1252 } 1253 1254 Type * Pass1::mutate( FunctionType *functionType ) { 1255 scopeTyVars.beginScope(); 1213 1256 makeTyVarMap( functionType, scopeTyVars ); 1214 } 1215 1216 void Pass1::beginScope() { 1257 1258 Type *ret = Mutator::mutate( functionType ); 1259 1260 scopeTyVars.endScope(); 1261 return ret; 1262 } 1263 1264 void Pass1::doBeginScope() { 1217 1265 adapters.beginScope(); 1218 1266 } 1219 1267 1220 void Pass1:: endScope() {1268 void Pass1::doEndScope() { 1221 1269 adapters.endScope(); 1222 1270 } … … 1245 1293 } 1246 1294 1247 DeclarationWithType * Pass2::postmutate( FunctionDecl *functionDecl ) { 1295 template< typename DeclClass > 1296 DeclClass * Pass2::handleDecl( DeclClass *decl ) { 1297 DeclClass *ret = static_cast< DeclClass *>( Parent::mutate( decl ) ); 1298 1299 return ret; 1300 } 1301 1302 DeclarationWithType * Pass2::mutate( FunctionDecl *functionDecl ) { 1303 functionDecl = strict_dynamic_cast< FunctionDecl * > ( handleDecl( functionDecl ) ); 1248 1304 FunctionType * ftype = functionDecl->get_functionType(); 1249 1305 if ( ! ftype->get_returnVals().empty() && functionDecl->get_statements() ) { … … 1269 1325 } 1270 1326 1271 void Pass2::premutate( StructDecl * ) { 1327 ObjectDecl * Pass2::mutate( ObjectDecl *objectDecl ) { 1328 return handleDecl( objectDecl ); 1329 } 1330 1331 template< typename AggDecl > 1332 AggDecl * Pass2::handleAggDecl( AggDecl * aggDecl ) { 1272 1333 // prevent tyVars from leaking into containing scope 1273 GuardScope( scopeTyVars ); 1274 } 1275 1276 void Pass2::premutate( UnionDecl * ) { 1277 // prevent tyVars from leaking into containing scope 1278 GuardScope( scopeTyVars ); 1279 } 1280 1281 void Pass2::premutate( TraitDecl * ) { 1282 // prevent tyVars from leaking into containing scope 1283 GuardScope( scopeTyVars ); 1284 } 1285 1286 void Pass2::premutate( TypeDecl *typeDecl ) { 1334 scopeTyVars.beginScope(); 1335 Parent::mutate( aggDecl ); 1336 scopeTyVars.endScope(); 1337 return aggDecl; 1338 } 1339 1340 StructDecl * Pass2::mutate( StructDecl *aggDecl ) { 1341 return handleAggDecl( aggDecl ); 1342 } 1343 1344 UnionDecl * Pass2::mutate( UnionDecl *aggDecl ) { 1345 return handleAggDecl( aggDecl ); 1346 } 1347 1348 TraitDecl * Pass2::mutate( TraitDecl *aggDecl ) { 1349 return handleAggDecl( aggDecl ); 1350 } 1351 1352 TypeDecl * Pass2::mutate( TypeDecl *typeDecl ) { 1287 1353 addToTyVarMap( typeDecl, scopeTyVars ); 1288 } 1289 1290 void Pass2::premutate( PointerType *pointerType ) { 1291 GuardScope( scopeTyVars ); 1354 if ( typeDecl->get_base() ) { 1355 return handleDecl( typeDecl ); 1356 } else { 1357 return dynamic_cast<TypeDecl*>( Parent::mutate( typeDecl ) ); 1358 } 1359 } 1360 1361 TypedefDecl * Pass2::mutate( TypedefDecl *typedefDecl ) { 1362 return handleDecl( typedefDecl ); 1363 } 1364 1365 Type * Pass2::mutate( PointerType *pointerType ) { 1366 scopeTyVars.beginScope(); 1292 1367 makeTyVarMap( pointerType, scopeTyVars ); 1293 } 1294 1295 void Pass2::premutate( FunctionType *funcType ) { 1296 GuardScope( scopeTyVars ); 1368 1369 Type *ret = Parent::mutate( pointerType ); 1370 1371 scopeTyVars.endScope(); 1372 return ret; 1373 } 1374 1375 Type *Pass2::mutate( FunctionType *funcType ) { 1376 scopeTyVars.beginScope(); 1377 1297 1378 makeTyVarMap( funcType, scopeTyVars ); 1298 1379 … … 1333 1414 // move all assertions into parameter list 1334 1415 for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) { 1416 // *assert = (*assert)->acceptMutator( *this ); 1335 1417 // assertion parameters may not be used in body, pass along with unused attribute. 1336 1418 (*assert)->get_attributes().push_back( new Attribute( "unused" ) ); … … 1368 1450 } 1369 1451 } 1452 1370 1453 seenTypes.insert( typeName ); 1371 1454 } … … 1375 1458 funcType->get_parameters().splice( last, inferredParams ); 1376 1459 addAdapters( funcType ); 1460 mutateAll( funcType->get_returnVals(), *this ); 1461 mutateAll( funcType->get_parameters(), *this ); 1462 1463 scopeTyVars.endScope(); 1464 return funcType; 1377 1465 } 1378 1466 … … 1380 1468 1381 1469 PolyGenericCalculator::PolyGenericCalculator() 1382 : knownLayouts(), knownOffsets(), bufNamer( "_buf" ) {}1470 : knownLayouts(), knownOffsets(), bufNamer( "_buf" ), scopeTyVars( TypeDecl::Data{} ) {} 1383 1471 1384 1472 void PolyGenericCalculator::beginTypeScope( Type *ty ) { … … 1741 1829 1742 1830 template< typename DeclClass > 1743 void Pass3::handleDecl( DeclClass * decl, Type *type ) {1744 GuardScope( scopeTyVars);1831 DeclClass * Pass3::handleDecl( DeclClass *decl, Type *type ) { 1832 scopeTyVars.beginScope(); 1745 1833 makeTyVarMap( type, scopeTyVars ); 1834 1835 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) ); 1836 // ScrubTyVars::scrub( decl, scopeTyVars ); 1746 1837 ScrubTyVars::scrubAll( decl ); 1747 } 1748 1749 void Pass3::premutate( ObjectDecl * objectDecl ) { 1750 handleDecl( objectDecl, objectDecl->type ); 1751 } 1752 1753 void Pass3::premutate( FunctionDecl * functionDecl ) { 1754 handleDecl( functionDecl, functionDecl->type ); 1755 } 1756 1757 void Pass3::premutate( TypedefDecl * typedefDecl ) { 1758 handleDecl( typedefDecl, typedefDecl->base ); 1838 1839 scopeTyVars.endScope(); 1840 return ret; 1841 } 1842 1843 ObjectDecl * Pass3::mutate( ObjectDecl *objectDecl ) { 1844 return handleDecl( objectDecl, objectDecl->get_type() ); 1845 } 1846 1847 DeclarationWithType * Pass3::mutate( FunctionDecl *functionDecl ) { 1848 return handleDecl( functionDecl, functionDecl->get_functionType() ); 1849 } 1850 1851 TypedefDecl * Pass3::mutate( TypedefDecl *typedefDecl ) { 1852 return handleDecl( typedefDecl, typedefDecl->get_base() ); 1759 1853 } 1760 1854 1761 1855 /// Strips the members from a generic aggregate 1762 void stripGenericMembers(AggregateDecl * decl) {1763 if ( ! decl-> parameters.empty() ) decl->members.clear();1764 } 1765 1766 void Pass3::premutate( StructDecl *structDecl ) {1856 void stripGenericMembers(AggregateDecl* decl) { 1857 if ( ! decl->get_parameters().empty() ) decl->get_members().clear(); 1858 } 1859 1860 Declaration *Pass3::mutate( StructDecl *structDecl ) { 1767 1861 stripGenericMembers( structDecl ); 1768 } 1769 1770 void Pass3::premutate( UnionDecl * unionDecl ) { 1862 return structDecl; 1863 } 1864 1865 Declaration *Pass3::mutate( UnionDecl *unionDecl ) { 1771 1866 stripGenericMembers( unionDecl ); 1772 } 1773 1774 void Pass3::premutate( TypeDecl * typeDecl ) { 1867 return unionDecl; 1868 } 1869 1870 TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) { 1871 // Initializer *init = 0; 1872 // std::list< Expression *> designators; 1873 // addToTyVarMap( typeDecl, scopeTyVars ); 1874 // if ( typeDecl->get_base() ) { 1875 // init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators ); 1876 // } 1877 // return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init ); 1878 1775 1879 addToTyVarMap( typeDecl, scopeTyVars ); 1776 } 1777 1778 void Pass3::premutate( PointerType * pointerType ) { 1779 GuardScope( scopeTyVars ); 1880 return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) ); 1881 } 1882 1883 Type * Pass3::mutate( PointerType *pointerType ) { 1884 scopeTyVars.beginScope(); 1780 1885 makeTyVarMap( pointerType, scopeTyVars ); 1781 } 1782 1783 void Pass3::premutate( FunctionType * functionType ) { 1784 GuardScope( scopeTyVars ); 1886 1887 Type *ret = Mutator::mutate( pointerType ); 1888 1889 scopeTyVars.endScope(); 1890 return ret; 1891 } 1892 1893 Type * Pass3::mutate( FunctionType *functionType ) { 1894 scopeTyVars.beginScope(); 1785 1895 makeTyVarMap( functionType, scopeTyVars ); 1896 1897 Type *ret = Mutator::mutate( functionType ); 1898 1899 scopeTyVars.endScope(); 1900 return ret; 1786 1901 } 1787 1902 } // anonymous namespace -
src/GenPoly/Specialize.cc
ra2d4d1c r4dfa562 22 22 #include <utility> // for pair 23 23 24 #include "Common/PassVisitor.h"25 24 #include "Common/SemanticError.h" // for SemanticError 26 25 #include "Common/UniqueName.h" // for UniqueName … … 29 28 #include "InitTweak/InitTweak.h" // for isIntrinsicCallExpr 30 29 #include "Parser/LinkageSpec.h" // for C 30 #include "PolyMutator.h" // for PolyMutator 31 31 #include "ResolvExpr/FindOpenVars.h" // for findOpenVars 32 32 #include "ResolvExpr/TypeEnvironment.h" // for OpenVarSet, AssertionSet … … 43 43 44 44 namespace GenPoly { 45 struct Specialize final : public WithTypeSubstitution, public WithStmtsToAdd, public WithVisitorRef<Specialize> { 46 Expression * postmutate( ApplicationExpr *applicationExpr ); 47 Expression * postmutate( AddressExpr *castExpr ); 48 Expression * postmutate( CastExpr *castExpr ); 45 class Specialize final : public PolyMutator { 46 public: 47 using PolyMutator::mutate; 48 virtual Expression * mutate( ApplicationExpr *applicationExpr ) override; 49 virtual Expression * mutate( AddressExpr *castExpr ) override; 50 virtual Expression * mutate( CastExpr *castExpr ) override; 51 // virtual Expression * mutate( LogicalExpr *logicalExpr ); 52 // virtual Expression * mutate( ConditionalExpr *conditionalExpr ); 53 // virtual Expression * mutate( CommaExpr *commaExpr ); 49 54 50 55 void handleExplicitParams( ApplicationExpr *appExpr ); … … 199 204 } 200 205 201 struct EnvTrimmer {206 struct EnvTrimmer : public Visitor { 202 207 TypeSubstitution * env, * newEnv; 203 208 EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){} 204 v oid previsit( TypeDecl * tyDecl ) {209 virtual void visit( TypeDecl * tyDecl ) { 205 210 // transfer known bindings for seen type variables 206 if ( Type * t = env->lookup( tyDecl-> name) ) {207 newEnv->add( tyDecl-> name, t );211 if ( Type * t = env->lookup( tyDecl->get_name() ) ) { 212 newEnv->add( tyDecl->get_name(), t ); 208 213 } 209 214 } … … 214 219 if ( env ) { 215 220 TypeSubstitution * newEnv = new TypeSubstitution(); 216 PassVisitor<EnvTrimmer>trimmer( env, newEnv );221 EnvTrimmer trimmer( env, newEnv ); 217 222 expr->accept( trimmer ); 218 223 return newEnv; … … 272 277 std::string oldParamPrefix = paramPrefix; 273 278 paramPrefix += "p"; 274 // save stmtsToAdd Beforein oldStmts279 // save stmtsToAdd in oldStmts 275 280 std::list< Statement* > oldStmts; 276 oldStmts.splice( oldStmts.end(), stmtsToAdd Before);277 appExpr->acceptMutator( *visitor );281 oldStmts.splice( oldStmts.end(), stmtsToAdd ); 282 mutate( appExpr ); 278 283 paramPrefix = oldParamPrefix; 279 284 // write any statements added for recursive specializations into the thunk body 280 thunkFunc-> statements->kids.splice( thunkFunc->statements->kids.end(), stmtsToAddBefore);281 // restore oldStmts into stmtsToAdd Before282 stmtsToAdd Before.splice( stmtsToAddBefore.end(), oldStmts );285 thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd ); 286 // restore oldStmts into stmtsToAdd 287 stmtsToAdd.splice( stmtsToAdd.end(), oldStmts ); 283 288 284 289 // add return (or valueless expression) to the thunk 285 290 Statement *appStmt; 286 if ( funType-> returnVals.empty() ) {291 if ( funType->get_returnVals().empty() ) { 287 292 appStmt = new ExprStmt( noLabels, appExpr ); 288 293 } else { 289 294 appStmt = new ReturnStmt( noLabels, appExpr ); 290 295 } // if 291 thunkFunc-> statements->kids.push_back( appStmt );296 thunkFunc->get_statements()->get_kids().push_back( appStmt ); 292 297 293 298 // add thunk definition to queue of statements to add 294 stmtsToAdd Before.push_back( new DeclStmt( noLabels, thunkFunc ) );299 stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) ); 295 300 // return address of thunk function as replacement expression 296 301 return new AddressExpr( new VariableExpr( thunkFunc ) ); … … 299 304 void Specialize::handleExplicitParams( ApplicationExpr *appExpr ) { 300 305 // create thunks for the explicit parameters 301 assert( appExpr-> function->result);302 FunctionType *function = getFunctionType( appExpr-> function->result);306 assert( appExpr->get_function()->has_result() ); 307 FunctionType *function = getFunctionType( appExpr->get_function()->get_result() ); 303 308 assert( function ); 304 309 std::list< DeclarationWithType* >::iterator formal; 305 310 std::list< Expression* >::iterator actual; 306 311 for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) { 307 *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->get_inferParams() ); 308 } 309 } 310 311 Expression * Specialize::postmutate( ApplicationExpr *appExpr ) { 312 *actual = doSpecialization( (*formal )->get_type(), *actual, &appExpr->get_inferParams() ); 313 } 314 } 315 316 Expression * Specialize::mutate( ApplicationExpr *appExpr ) { 317 appExpr->get_function()->acceptMutator( *this ); 318 mutateAll( appExpr->get_args(), *this ); 319 312 320 if ( ! InitTweak::isIntrinsicCallExpr( appExpr ) ) { 313 321 // create thunks for the inferred parameters … … 323 331 } 324 332 325 Expression * Specialize::postmutate( AddressExpr *addrExpr ) { 326 assert( addrExpr->result ); 327 addrExpr->set_arg( doSpecialization( addrExpr->result, addrExpr->arg ) ); 333 Expression * Specialize::mutate( AddressExpr *addrExpr ) { 334 addrExpr->get_arg()->acceptMutator( *this ); 335 assert( addrExpr->has_result() ); 336 addrExpr->set_arg( doSpecialization( addrExpr->get_result(), addrExpr->get_arg() ) ); 328 337 return addrExpr; 329 338 } 330 339 331 Expression * Specialize::postmutate( CastExpr *castExpr ) { 332 if ( castExpr->result->isVoid() ) { 340 Expression * Specialize::mutate( CastExpr *castExpr ) { 341 castExpr->get_arg()->acceptMutator( *this ); 342 if ( castExpr->get_result()->isVoid() ) { 333 343 // can't specialize if we don't have a return value 334 344 return castExpr; 335 345 } 336 Expression *specialized = doSpecialization( castExpr-> result, castExpr->arg);337 if ( specialized != castExpr-> arg) {346 Expression *specialized = doSpecialization( castExpr->get_result(), castExpr->get_arg() ); 347 if ( specialized != castExpr->get_arg() ) { 338 348 // assume here that the specialization incorporates the cast 339 349 return specialized; … … 343 353 } 344 354 355 // Removing these for now. Richard put these in for some reason, but it's not clear why. 356 // In particular, copy constructors produce a comma expression, and with this code the parts 357 // of that comma expression are not specialized, which causes problems. 358 359 // Expression * Specialize::mutate( LogicalExpr *logicalExpr ) { 360 // return logicalExpr; 361 // } 362 363 // Expression * Specialize::mutate( ConditionalExpr *condExpr ) { 364 // return condExpr; 365 // } 366 367 // Expression * Specialize::mutate( CommaExpr *commaExpr ) { 368 // return commaExpr; 369 // } 370 345 371 void convertSpecializations( std::list< Declaration* >& translationUnit ) { 346 PassVisitor<Specialize>spec;372 Specialize spec; 347 373 mutateAll( translationUnit, spec ); 348 374 } -
src/GenPoly/module.mk
ra2d4d1c r4dfa562 6 6 ## file "LICENCE" distributed with Cforall. 7 7 ## 8 ## module.mk -- 8 ## module.mk -- 9 9 ## 10 10 ## Author : Richard C. Bilson … … 17 17 SRC += GenPoly/Box.cc \ 18 18 GenPoly/GenPoly.cc \ 19 GenPoly/PolyMutator.cc \ 19 20 GenPoly/ScrubTyVars.cc \ 20 21 GenPoly/Lvalue.cc \ … … 22 23 GenPoly/CopyParams.cc \ 23 24 GenPoly/FindFunction.cc \ 25 GenPoly/DeclMutator.cc \ 24 26 GenPoly/InstantiateGeneric.cc -
src/InitTweak/FixInit.cc
ra2d4d1c r4dfa562 36 36 #include "FixGlobalInit.h" // for fixGlobalInit 37 37 #include "GenInit.h" // for genCtorDtor 38 #include "GenPoly/DeclMutator.h" // for DeclMutator 38 39 #include "GenPoly/GenPoly.h" // for getFunctionType 40 #include "GenPoly/PolyMutator.h" // for PolyMutator 39 41 #include "InitTweak.h" // for getFunctionName, getCallArg 40 42 #include "Parser/LinkageSpec.h" // for C, Spec, Cforall, isBuiltin … … 44 46 #include "SymTab/Indexer.h" // for Indexer 45 47 #include "SymTab/Mangler.h" // for Mangler 48 #include "SynTree/AddStmtVisitor.h" // for AddStmtVisitor 46 49 #include "SynTree/Attribute.h" // for Attribute 47 50 #include "SynTree/Constant.h" // for Constant … … 55 58 #include "SynTree/TypeSubstitution.h" // for TypeSubstitution, operator<< 56 59 #include "SynTree/Visitor.h" // for acceptAll, maybeAccept 60 #include "Tuples/Tuples.h" // for isTtype 57 61 58 62 bool ctordtorp = false; // print all debug … … 183 187 }; 184 188 185 class FixCopyCtors final : public WithStmtsToAdd, public WithShortCircuiting, public WithVisitorRef<FixCopyCtors>{189 class FixCopyCtors final : public GenPoly::PolyMutator { 186 190 public: 187 191 FixCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ){} … … 190 194 static void fixCopyCtors( std::list< Declaration * > &translationUnit, UnqCount & unqCount ); 191 195 192 Expression * postmutate( ImplicitCopyCtorExpr * impCpCtorExpr ); 193 void premutate( StmtExpr * stmtExpr ); 194 void premutate( UniqueExpr * unqExpr ); 196 typedef GenPoly::PolyMutator Parent; 197 using Parent::mutate; 198 virtual Expression * mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) override; 199 virtual Expression * mutate( UniqueExpr * unqExpr ) override; 200 virtual Expression * mutate( StmtExpr * stmtExpr ) override; 195 201 196 202 UnqCount & unqCount; … … 237 243 }; 238 244 239 struct FixCtorExprs final : public WithDeclsToAdd, public WithIndexer { 245 class FixCtorExprs final : public GenPoly::DeclMutator { 246 public: 240 247 /// expands ConstructorExpr nodes into comma expressions, using a temporary for the first argument 241 248 static void fix( std::list< Declaration * > & translationUnit ); 242 249 243 Expression * postmutate( ConstructorExpr * ctorExpr ); 250 using GenPoly::DeclMutator::mutate; 251 virtual Expression * mutate( ConstructorExpr * ctorExpr ) override; 244 252 }; 245 253 } // namespace … … 308 316 309 317 void FixCopyCtors::fixCopyCtors( std::list< Declaration * > & translationUnit, UnqCount & unqCount ) { 310 PassVisitor<FixCopyCtors>fixer( unqCount );318 FixCopyCtors fixer( unqCount ); 311 319 mutateAll( translationUnit, fixer ); 312 320 } … … 318 326 319 327 void FixCtorExprs::fix( std::list< Declaration * > & translationUnit ) { 320 PassVisitor<FixCtorExprs>fixer;321 mutateAll( translationUnit, fixer);328 FixCtorExprs fixer; 329 fixer.mutateDeclarationList( translationUnit ); 322 330 } 323 331 … … 331 339 } else if ( DeclarationWithType * funcDecl = dynamic_cast< DeclarationWithType * > ( function->get_var() ) ) { 332 340 FunctionType * ftype = dynamic_cast< FunctionType * >( GenPoly::getFunctionType( funcDecl->get_type() ) ); 333 assert f( ftype, "Function call without function type: %s", toString( funcDecl ).c_str());341 assert( ftype ); 334 342 if ( CodeGen::isConstructor( funcDecl->get_name() ) && ftype->get_parameters().size() == 2 ) { 335 343 Type * t1 = getPointerBase( ftype->get_parameters().front()->get_type() ); … … 360 368 } 361 369 362 bool ResolveCopyCtors::skipCopyConstruct( Type * type ) { return ! isConstructable( type ); } 370 bool ResolveCopyCtors::skipCopyConstruct( Type * type ) { 371 return dynamic_cast< VarArgsType * >( type ) || dynamic_cast< ReferenceType * >( type ) || GenPoly::getFunctionType( type ) || Tuples::isTtype( type ); 372 } 363 373 364 374 Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) { … … 397 407 result = result->clone(); 398 408 env->apply( result ); 399 ObjectDecl * tmp = ObjectDecl::newObject( "__tmp", result, nullptr);409 ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 ); 400 410 tmp->get_type()->set_const( false ); 401 411 … … 411 421 if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) return; 412 422 } 413 414 // set a unique name for the temporary once it's certain the call is necessary415 tmp->name = tempNamer.newName();416 423 417 424 // replace argument to function call with temporary … … 443 450 result = result->clone(); 444 451 env->apply( result ); 445 ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr);452 ObjectDecl * ret = new ObjectDecl( retNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 ); 446 453 ret->get_type()->set_const( false ); 447 454 impCpCtorExpr->get_returnDecls().push_back( ret ); 448 455 CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; ) 449 456 if ( ! dynamic_cast< ReferenceType * >( result ) ) { 450 // destructing reference returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary457 // destructing lvalue returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary 451 458 destructRet( ret, impCpCtorExpr ); 452 459 } … … 465 472 result = result->clone(); 466 473 env->apply( result ); 467 ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr);474 ObjectDecl * ret = new ObjectDecl( retNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 ); 468 475 ret->get_type()->set_const( false ); 469 476 stmtExpr->get_returnDecls().push_front( ret ); … … 502 509 } else { 503 510 // expr isn't a call expr, so create a new temporary variable to use to hold the value of the unique expression 504 unqExpr->set_object( ObjectDecl::newObject( toString("_unq", unqExpr->get_id()), unqExpr->get_result()->clone(), nullptr ) );511 unqExpr->set_object( new ObjectDecl( toString("_unq", unqExpr->get_id()), Type::StorageClasses(), LinkageSpec::C, nullptr, unqExpr->get_result()->clone(), nullptr ) ); 505 512 unqExpr->set_var( new VariableExpr( unqExpr->get_object() ) ); 506 513 } … … 508 515 } 509 516 510 Expression * FixCopyCtors:: postmutate( ImplicitCopyCtorExpr * impCpCtorExpr ) {517 Expression * FixCopyCtors::mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) { 511 518 CP_CTOR_PRINT( std::cerr << "FixCopyCtors: " << impCpCtorExpr << std::endl; ) 512 519 520 impCpCtorExpr = strict_dynamic_cast< ImplicitCopyCtorExpr * >( Parent::mutate( impCpCtorExpr ) ); 513 521 std::list< ObjectDecl * > & tempDecls = impCpCtorExpr->get_tempDecls(); 514 522 std::list< ObjectDecl * > & returnDecls = impCpCtorExpr->get_returnDecls(); … … 517 525 // add all temporary declarations and their constructors 518 526 for ( ObjectDecl * obj : tempDecls ) { 519 stmtsToAdd Before.push_back( new DeclStmt( noLabels, obj ) );527 stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) ); 520 528 } // for 521 529 for ( ObjectDecl * obj : returnDecls ) { 522 stmtsToAdd Before.push_back( new DeclStmt( noLabels, obj ) );530 stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) ); 523 531 } // for 524 532 … … 528 536 } // for 529 537 538 // xxx - update to work with multiple return values 530 539 ObjectDecl * returnDecl = returnDecls.empty() ? nullptr : returnDecls.front(); 531 540 Expression * callExpr = impCpCtorExpr->get_callExpr(); … … 560 569 } 561 570 562 void FixCopyCtors::premutate( StmtExpr * stmtExpr ) {571 Expression * FixCopyCtors::mutate( StmtExpr * stmtExpr ) { 563 572 // function call temporaries should be placed at statement-level, rather than nested inside of a new statement expression, 564 573 // since temporaries can be shared across sub-expressions, e.g. 565 574 // [A, A] f(); 566 575 // g([A] x, [A] y); 567 // g(f());576 // f(g()); 568 577 // f is executed once, so the return temporary is shared across the tuple constructors for x and y. 569 // Explicitly mutating children instead of mutating the inner compound statment forces the temporaries to be added570 // to the outer context, rather than inside of the statement expression.571 visit_children = false;572 578 std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids(); 573 579 for ( Statement *& stmt : stmts ) { 574 stmt = stmt->acceptMutator( * visitor);580 stmt = stmt->acceptMutator( *this ); 575 581 } // for 582 // stmtExpr = strict_dynamic_cast< StmtExpr * >( Parent::mutate( stmtExpr ) ); 576 583 assert( stmtExpr->get_result() ); 577 584 Type * result = stmtExpr->get_result(); 578 585 if ( ! result->isVoid() ) { 579 586 for ( ObjectDecl * obj : stmtExpr->get_returnDecls() ) { 580 stmtsToAdd Before.push_back( new DeclStmt( noLabels, obj ) );587 stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) ); 581 588 } // for 582 589 // add destructors after current statement … … 585 592 } // for 586 593 // must have a non-empty body, otherwise it wouldn't have a result 587 assert( ! stmts.empty() ); 594 CompoundStmt * body = stmtExpr->get_statements(); 595 assert( ! body->get_kids().empty() ); 588 596 assert( ! stmtExpr->get_returnDecls().empty() ); 589 stmts.push_back( new ExprStmt( noLabels, new VariableExpr( stmtExpr->get_returnDecls().front() ) ) );597 body->get_kids().push_back( new ExprStmt( noLabels, new VariableExpr( stmtExpr->get_returnDecls().front() ) ) ); 590 598 stmtExpr->get_returnDecls().clear(); 591 599 stmtExpr->get_dtors().clear(); … … 593 601 assert( stmtExpr->get_returnDecls().empty() ); 594 602 assert( stmtExpr->get_dtors().empty() ); 595 }596 597 void FixCopyCtors::premutate( UniqueExpr * unqExpr ) { 598 visit_children = false;603 return stmtExpr; 604 } 605 606 Expression * FixCopyCtors::mutate( UniqueExpr * unqExpr ) { 599 607 unqCount[ unqExpr->get_id() ]--; 600 608 static std::unordered_map< int, std::list< Statement * > > dtors; 601 609 static std::unordered_map< int, UniqueExpr * > unqMap; 610 static std::unordered_set< int > addDeref; 602 611 // has to be done to clean up ImplicitCopyCtorExpr nodes, even when this node was skipped in previous passes 603 612 if ( unqMap.count( unqExpr->get_id() ) ) { … … 610 619 stmtsToAddAfter.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] ); 611 620 } 612 return; 613 } 614 PassVisitor<FixCopyCtors> fixer( unqCount ); 621 if ( addDeref.count( unqExpr->get_id() ) ) { 622 // other UniqueExpr was dereferenced because it was an lvalue return, so this one should be too 623 return UntypedExpr::createDeref( unqExpr ); 624 } 625 return unqExpr; 626 } 627 FixCopyCtors fixer( unqCount ); 615 628 unqExpr->set_expr( unqExpr->get_expr()->acceptMutator( fixer ) ); // stmtexprs contained should not be separately fixed, so this must occur after the lookup 616 stmtsToAdd Before.splice( stmtsToAddBefore.end(), fixer.pass.stmtsToAddBefore);629 stmtsToAdd.splice( stmtsToAdd.end(), fixer.stmtsToAdd ); 617 630 unqMap[unqExpr->get_id()] = unqExpr; 618 631 if ( unqCount[ unqExpr->get_id() ] == 0 ) { // insert destructor after the last use of the unique expression 619 632 stmtsToAddAfter.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] ); 620 633 } else { // remember dtors for last instance of unique expr 621 dtors[ unqExpr->get_id() ] = fixer.pass.stmtsToAddAfter; 622 } 623 return; 634 dtors[ unqExpr->get_id() ] = fixer.stmtsToAddAfter; 635 } 636 if ( UntypedExpr * deref = dynamic_cast< UntypedExpr * >( unqExpr->get_expr() ) ) { 637 // unique expression is now a dereference, because the inner expression is an lvalue returning function call. 638 // Normalize the expression by dereferencing the unique expression, rather than the inner expression 639 // (i.e. move the dereference out a level) 640 assert( getFunctionName( deref ) == "*?" ); 641 unqExpr->set_expr( getCallArg( deref, 0 ) ); 642 getCallArg( deref, 0 ) = unqExpr; 643 addDeref.insert( unqExpr->get_id() ); 644 return deref; 645 } 646 return unqExpr; 624 647 } 625 648 … … 796 819 assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() ); 797 820 Statement * dtor = ctorInit->get_dtor(); 798 // don't need to call intrinsic dtor, because it does nothing, but799 // non-intrinsic dtors must be called800 821 if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) { 801 // set dtor location to the object's location for error messages802 ctorInit->dtor->location = objDecl->location;822 // don't need to call intrinsic dtor, because it does nothing, but 823 // non-intrinsic dtors must be called 803 824 reverseDeclOrder.front().push_front( objDecl ); 804 825 } // if … … 991 1012 // skip non-DWT members 992 1013 if ( ! field ) continue; 993 // skip non-constructable members994 if ( ! tryConstruct( field ) ) continue;995 1014 // skip handled members 996 1015 if ( ! unhandled.count( field ) ) continue; … … 1123 1142 } 1124 1143 1125 Expression * FixCtorExprs:: postmutate( ConstructorExpr * ctorExpr ) {1144 Expression * FixCtorExprs::mutate( ConstructorExpr * ctorExpr ) { 1126 1145 static UniqueName tempNamer( "_tmp_ctor_expr" ); 1127 1146 // xxx - is the size check necessary? … … 1129 1148 1130 1149 // xxx - ideally we would reuse the temporary generated from the copy constructor passes from within firstArg if it exists and not generate a temporary if it's unnecessary. 1131 ObjectDecl * tmp = ObjectDecl::newObject( tempNamer.newName(), ctorExpr->get_result()->clone(), nullptr );1132 declsToAddBefore.push_back( tmp );1150 ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, nullptr, ctorExpr->get_result()->clone(), nullptr ); 1151 addDeclaration( tmp ); 1133 1152 1134 1153 // xxx - this can be TupleAssignExpr now. Need to properly handle this case. … … 1139 1158 delete ctorExpr; 1140 1159 1141 // build assignment and replace constructor's first argument with new temporary1142 1160 Expression *& firstArg = callExpr->get_args().front(); 1143 Expression * assign = new UntypedExpr( new NameExpr( "?=?" ), { new AddressExpr( new VariableExpr( tmp ) ), new AddressExpr( firstArg ) } ); 1161 1162 // xxx - hack in 'fake' assignment operator until resolver can easily be called in this pass. Once the resolver can be used in PassVisitor, this hack goes away. 1163 1164 // generate the type of assignment operator using the type of tmp minus any reference types 1165 Type * type = tmp->get_type()->stripReferences(); 1166 FunctionType * ftype = SymTab::genAssignType( type ); 1167 1168 // generate fake assignment decl and call it using &tmp and &firstArg 1169 // since tmp is guaranteed to be a reference and we want to assign pointers 1170 FunctionDecl * assignDecl = new FunctionDecl( "?=?", Type::StorageClasses(), LinkageSpec::Intrinsic, ftype, nullptr ); 1171 ApplicationExpr * assign = new ApplicationExpr( VariableExpr::functionPointer( assignDecl ) ); 1172 assign->get_args().push_back( new AddressExpr( new VariableExpr( tmp ) ) ); 1173 Expression * addrArg = new AddressExpr( firstArg ); 1174 // if firstArg has type T&&, then &firstArg has type T*&. 1175 // Cast away the reference to a value type so that the argument 1176 // matches the assignment's parameter types 1177 if ( dynamic_cast<ReferenceType *>( addrArg->get_result() ) ) { 1178 addrArg = new CastExpr( addrArg, addrArg->get_result()->stripReferences()->clone() ); 1179 } 1180 assign->get_args().push_back( addrArg ); 1144 1181 firstArg = new VariableExpr( tmp ); 1145 1146 // resolve assignment and dispose of new env1147 Expression * resolvedAssign = ResolvExpr::findVoidExpression( assign, indexer );1148 delete resolvedAssign->env;1149 resolvedAssign->env = nullptr;1150 delete assign;1151 1182 1152 1183 // for constructor expr: … … 1157 1188 // T & tmp; 1158 1189 // &tmp = &x, ?{}(tmp), tmp 1159 CommaExpr * commaExpr = new CommaExpr( resolvedAssign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) );1190 CommaExpr * commaExpr = new CommaExpr( assign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) ); 1160 1191 commaExpr->set_env( env ); 1161 1192 return commaExpr; -
src/InitTweak/GenInit.cc
ra2d4d1c r4dfa562 26 26 #include "Common/UniqueName.h" // for UniqueName 27 27 #include "Common/utility.h" // for ValueGuard, maybeClone 28 #include "GenPoly/DeclMutator.h" // for DeclMutator 28 29 #include "GenPoly/GenPoly.h" // for getFunctionType, isPolyType 29 30 #include "GenPoly/ScopedSet.h" // for ScopedSet, ScopedSet<>::const_iter... … … 61 62 }; 62 63 63 struct CtorDtor : public WithGuards, public WithShortCircuiting , public WithVisitorRef<CtorDtor>{64 struct CtorDtor : public WithGuards, public WithShortCircuiting { 64 65 /// create constructor and destructor statements for object declarations. 65 66 /// the actual call statements will be added in after the resolver has run … … 74 75 // that need to be constructed or destructed 75 76 void previsit( StructDecl *aggregateDecl ); 76 void previsit( AggregateDecl * ) { visit_children = false; } 77 void previsit( NamedTypeDecl * ) { visit_children = false; } 78 void previsit( FunctionType * ) { visit_children = false; } 77 void previsit( __attribute__((unused)) UnionDecl * aggregateDecl ) { visit_children = false; } 78 void previsit( __attribute__((unused)) EnumDecl * aggregateDecl ) { visit_children = false; } 79 void previsit( __attribute__((unused)) TraitDecl * aggregateDecl ) { visit_children = false; } 80 void previsit( __attribute__((unused)) TypeDecl * typeDecl ) { visit_children = false; } 81 void previsit( __attribute__((unused)) TypedefDecl * typeDecl ) { visit_children = false; } 82 void previsit( __attribute__((unused)) FunctionType * funcType ) { visit_children = false; } 79 83 80 84 void previsit( CompoundStmt * compoundStmt ); … … 92 96 }; 93 97 94 struct HoistArrayDimension final : public WithDeclsToAdd, public WithShortCircuiting, public WithGuards { 98 class HoistArrayDimension final : public GenPoly::DeclMutator { 99 public: 100 typedef GenPoly::DeclMutator Parent; 101 95 102 /// hoist dimension from array types in object declaration so that it uses a single 96 103 /// const variable of type size_t, so that side effecting array dimensions are only … … 98 105 static void hoistArrayDimension( std::list< Declaration * > & translationUnit ); 99 106 100 void premutate( ObjectDecl * objectDecl ); 101 DeclarationWithType * postmutate( ObjectDecl * objectDecl ); 102 void premutate( FunctionDecl *functionDecl ); 107 private: 108 using Parent::mutate; 109 110 virtual DeclarationWithType * mutate( ObjectDecl * objectDecl ) override; 111 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ) override; 103 112 // should not traverse into any of these declarations to find objects 104 113 // that need to be constructed or destructed 105 void premutate( AggregateDecl * ) { visit_children = false; } 106 void premutate( NamedTypeDecl * ) { visit_children = false; } 107 void premutate( FunctionType * ) { visit_children = false; } 114 virtual Declaration* mutate( StructDecl *aggregateDecl ) override { return aggregateDecl; } 115 virtual Declaration* mutate( UnionDecl *aggregateDecl ) override { return aggregateDecl; } 116 virtual Declaration* mutate( EnumDecl *aggregateDecl ) override { return aggregateDecl; } 117 virtual Declaration* mutate( TraitDecl *aggregateDecl ) override { return aggregateDecl; } 118 virtual TypeDecl* mutate( TypeDecl *typeDecl ) override { return typeDecl; } 119 virtual Declaration* mutate( TypedefDecl *typeDecl ) override { return typeDecl; } 120 121 virtual Type* mutate( FunctionType *funcType ) override { return funcType; } 108 122 109 123 void hoist( Type * type ); … … 114 128 115 129 void genInit( std::list< Declaration * > & translationUnit ) { 116 fixReturnStatements( translationUnit );130 ReturnFixer::makeReturnTemp( translationUnit ); 117 131 HoistArrayDimension::hoistArrayDimension( translationUnit ); 118 132 CtorDtor::generateCtorDtor( translationUnit ); 119 133 } 120 134 121 void fixReturnStatements( std::list< Declaration * > & translationUnit ) {135 void ReturnFixer::makeReturnTemp( std::list< Declaration * > & translationUnit ) { 122 136 PassVisitor<ReturnFixer> fixer; 123 137 mutateAll( translationUnit, fixer ); … … 129 143 // hands off if the function returns a reference - we don't want to allocate a temporary if a variable's address 130 144 // is being returned 131 if ( returnStmt->get_expr() && returnVals.size() == 1 && isConstructable( returnVals.front()->get_type() ) ) {145 if ( returnStmt->get_expr() && returnVals.size() == 1 && ! dynamic_cast< ReferenceType * >( returnVals.front()->get_type() ) ) { 132 146 // explicitly construct the return value using the return expression and the retVal object 133 147 assertf( returnVals.front()->get_name() != "", "Function %s has unnamed return value\n", funcName.c_str() ); … … 144 158 GuardValue( funcName ); 145 159 146 ftype = functionDecl-> type;147 funcName = functionDecl-> name;160 ftype = functionDecl->get_functionType(); 161 funcName = functionDecl->get_name(); 148 162 } 149 163 … … 151 165 // which would be incorrect if it is a side-effecting computation. 152 166 void HoistArrayDimension::hoistArrayDimension( std::list< Declaration * > & translationUnit ) { 153 PassVisitor<HoistArrayDimension> hoister; 154 mutateAll( translationUnit, hoister ); 155 } 156 157 void HoistArrayDimension::premutate( ObjectDecl * objectDecl ) { 158 GuardValue( storageClasses ); 167 HoistArrayDimension hoister; 168 hoister.mutateDeclarationList( translationUnit ); 169 } 170 171 DeclarationWithType * HoistArrayDimension::mutate( ObjectDecl * objectDecl ) { 159 172 storageClasses = objectDecl->get_storageClasses(); 160 } 161 162 DeclarationWithType * HoistArrayDimension::postmutate( ObjectDecl * objectDecl ) { 173 DeclarationWithType * temp = Parent::mutate( objectDecl ); 163 174 hoist( objectDecl->get_type() ); 164 return objectDecl;175 return temp; 165 176 } 166 177 … … 183 194 184 195 arrayType->set_dimension( new VariableExpr( arrayDimension ) ); 185 declsToAddBefore.push_back( arrayDimension );196 addDeclaration( arrayDimension ); 186 197 187 198 hoist( arrayType->get_base() ); … … 190 201 } 191 202 192 void HoistArrayDimension::premutate( FunctionDecl * ) { 193 GuardValue( inFunction ); 203 DeclarationWithType * HoistArrayDimension::mutate( FunctionDecl *functionDecl ) { 204 ValueGuard< bool > oldInFunc( inFunction ); 205 inFunction = true; 206 DeclarationWithType * decl = Parent::mutate( functionDecl ); 207 return decl; 194 208 } 195 209 … … 200 214 201 215 bool CtorDtor::isManaged( Type * type ) const { 202 // references are never constructed216 // at least for now, references are never constructed 203 217 if ( dynamic_cast< ReferenceType * >( type ) ) return false; 204 218 // need to clear and reset qualifiers when determining if a type is managed … … 207 221 if ( TupleType * tupleType = dynamic_cast< TupleType * > ( type ) ) { 208 222 // tuple is also managed if any of its components are managed 209 if ( std::any_of( tupleType-> types.begin(), tupleType->types.end(), [&](Type * type) { return isManaged( type ); }) ) {223 if ( std::any_of( tupleType->get_types().begin(), tupleType->get_types().end(), [&](Type * type) { return isManaged( type ); }) ) { 210 224 return true; 211 225 } … … 291 305 292 306 void CtorDtor::previsit( FunctionDecl *functionDecl ) { 293 visit_children = false; // do not try and construct parameters or forall parameters294 307 GuardValue( inFunction ); 295 308 inFunction = true; … … 305 318 } 306 319 307 maybeAccept( functionDecl->get_statements(), *visitor ); 320 PassVisitor<CtorDtor> newCtorDtor; 321 newCtorDtor.pass = *this; 322 maybeAccept( functionDecl->get_statements(), newCtorDtor ); 323 visit_children = false; // do not try and construct parameters or forall parameters - must happen after maybeAccept 308 324 } 309 325 … … 324 340 } 325 341 326 void CtorDtor::previsit( CompoundStmt *) {342 void CtorDtor::previsit( __attribute__((unused)) CompoundStmt * compoundStmt ) { 327 343 GuardScope( managedTypes ); 328 344 } -
src/InitTweak/GenInit.h
ra2d4d1c r4dfa562 25 25 void genInit( std::list< Declaration * > & translationUnit ); 26 26 27 /// Converts return statements into copy constructor calls on the hidden return variable 28 void fixReturnStatements( std::list< Declaration * > & translationUnit ); 29 30 /// generates a single ctor/dtor statement using objDecl as the 'this' parameter and arg as the optional argument 31 ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg = nullptr ); 27 /// generates a single ctor/dtor statement using objDecl as the 'this' parameter and arg as the optional argument 28 ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg = nullptr ); 32 29 33 30 /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer -
src/InitTweak/InitTweak.cc
ra2d4d1c r4dfa562 1 #include <stddef.h> // for NULL 1 2 #include <algorithm> // for find, all_of 2 3 #include <cassert> // for assertf, assert, strict_dynamic_cast … … 22 23 #include "SynTree/Type.h" // for FunctionType, ArrayType, PointerType 23 24 #include "SynTree/Visitor.h" // for Visitor, maybeAccept 24 #include "Tuples/Tuples.h" // for Tuples::isTtype25 25 26 26 class UntypedValofExpr; … … 184 184 callExpr->get_args().splice( callExpr->get_args().end(), args ); 185 185 186 *out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels, callExpr ), nullptr);186 *out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels, callExpr ), NULL ); 187 187 188 188 UntypedExpr * increment = new UntypedExpr( new NameExpr( "++?" ) ); … … 250 250 // To accomplish this, generate switch statement, consuming all of expander's elements 251 251 Statement * InitImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) { 252 if ( ! init ) return nullptr;252 if ( ! init ) return NULL; 253 253 CompoundStmt * block = new CompoundStmt( noLabels ); 254 254 build( dst, indices.begin(), indices.end(), init, back_inserter( block->get_kids() ) ); 255 255 if ( block->get_kids().empty() ) { 256 256 delete block; 257 return nullptr;257 return NULL; 258 258 } else { 259 init = nullptr; // init was consumed in creating the list init259 init = NULL; // init was consumed in creating the list init 260 260 return block; 261 261 } 262 262 } 263 263 264 Statement * ExprImpl::buildListInit( UntypedExpr *, std::list< Expression * > &) {265 return nullptr;264 Statement * ExprImpl::buildListInit( __attribute((unused)) UntypedExpr * dst, __attribute((unused)) std::list< Expression * > & indices ) { 265 return NULL; 266 266 } 267 267 … … 270 270 } 271 271 272 bool tryConstruct( DeclarationWithType * dwt ) { 273 ObjectDecl * objDecl = dynamic_cast< ObjectDecl * >( dwt ); 274 if ( ! objDecl ) return false; 272 bool tryConstruct( ObjectDecl * objDecl ) { 275 273 return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) && 276 (objDecl->get_init() == nullptr || 277 ( objDecl->get_init() != nullptr && objDecl->get_init()->get_maybeConstructed() )) 278 && ! objDecl->get_storageClasses().is_extern 279 && isConstructable( objDecl->type ); 280 } 281 282 bool isConstructable( Type * type ) { 283 return ! dynamic_cast< VarArgsType * >( type ) && ! dynamic_cast< ReferenceType * >( type ) && ! dynamic_cast< FunctionType * >( type ) && ! Tuples::isTtype( type ); 274 (objDecl->get_init() == NULL || 275 ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() )) 276 && ! objDecl->get_storageClasses().is_extern; 284 277 } 285 278 … … 321 314 collectCtorDtorCalls( stmt, matches ); 322 315 assert( matches.size() <= 1 ); 323 return matches.size() == 1 ? matches.front() : nullptr;316 return matches.size() == 1 ? matches.front() : NULL; 324 317 } 325 318 … … 366 359 ApplicationExpr * isIntrinsicCallExpr( Expression * expr ) { 367 360 ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr ); 368 if ( ! appExpr ) return nullptr;361 if ( ! appExpr ) return NULL; 369 362 DeclarationWithType * function = getCalledFunction( appExpr->get_function() ); 370 363 assertf( function, "getCalledFunction returned nullptr: %s", toString( appExpr->get_function() ).c_str() ); 371 364 // check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor 372 365 // will call all member dtors, and some members may have a user defined dtor. 373 return function->get_linkage() == LinkageSpec::Intrinsic ? appExpr : nullptr;366 return function->get_linkage() == LinkageSpec::Intrinsic ? appExpr : NULL; 374 367 } 375 368 … … 489 482 return refType->get_base(); 490 483 } else { 491 return nullptr;484 return NULL; 492 485 } 493 486 } … … 495 488 Type * isPointerType( Type * type ) { 496 489 if ( getPointerBase( type ) ) return type; 497 else return nullptr;490 else return NULL; 498 491 } 499 492 -
src/InitTweak/InitTweak.h
ra2d4d1c r4dfa562 33 33 std::list< Expression * > makeInitList( Initializer * init ); 34 34 35 /// True if the resolver should try to construct dwt 36 bool tryConstruct( DeclarationWithType * dwt ); 37 38 /// True if the type can have a user-defined constructor 39 bool isConstructable( Type * t ); 35 /// True if the resolver should try to construct objDecl 36 bool tryConstruct( ObjectDecl * objDecl ); 40 37 41 38 /// True if the Initializer contains designations -
src/Makefile.in
ra2d4d1c r4dfa562 172 172 GenPoly/driver_cfa_cpp-Box.$(OBJEXT) \ 173 173 GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT) \ 174 GenPoly/driver_cfa_cpp-PolyMutator.$(OBJEXT) \ 174 175 GenPoly/driver_cfa_cpp-ScrubTyVars.$(OBJEXT) \ 175 176 GenPoly/driver_cfa_cpp-Lvalue.$(OBJEXT) \ … … 177 178 GenPoly/driver_cfa_cpp-CopyParams.$(OBJEXT) \ 178 179 GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT) \ 180 GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT) \ 179 181 GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT) \ 180 182 InitTweak/driver_cfa_cpp-GenInit.$(OBJEXT) \ … … 251 253 SynTree/driver_cfa_cpp-Visitor.$(OBJEXT) \ 252 254 SynTree/driver_cfa_cpp-Mutator.$(OBJEXT) \ 255 SynTree/driver_cfa_cpp-AddStmtVisitor.$(OBJEXT) \ 253 256 SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT) \ 254 257 SynTree/driver_cfa_cpp-Attribute.$(OBJEXT) \ … … 494 497 ControlStruct/ForExprMutator.cc \ 495 498 ControlStruct/ExceptTranslate.cc GenPoly/Box.cc \ 496 GenPoly/GenPoly.cc GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc \ 497 GenPoly/Specialize.cc GenPoly/CopyParams.cc \ 498 GenPoly/FindFunction.cc GenPoly/InstantiateGeneric.cc \ 499 GenPoly/GenPoly.cc GenPoly/PolyMutator.cc \ 500 GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \ 501 GenPoly/CopyParams.cc GenPoly/FindFunction.cc \ 502 GenPoly/DeclMutator.cc GenPoly/InstantiateGeneric.cc \ 499 503 InitTweak/GenInit.cc InitTweak/FixInit.cc \ 500 504 InitTweak/FixGlobalInit.cc InitTweak/InitTweak.cc \ … … 531 535 SynTree/NamedTypeDecl.cc SynTree/TypeDecl.cc \ 532 536 SynTree/Initializer.cc SynTree/Visitor.cc SynTree/Mutator.cc \ 533 SynTree/ TypeSubstitution.cc SynTree/Attribute.cc \534 SynTree/ VarExprReplacer.cc Tuples/TupleAssignment.cc \535 Tuples/Tuple Expansion.cc Tuples/Explode.cc \536 Virtual/ExpandCasts.cc537 SynTree/AddStmtVisitor.cc SynTree/TypeSubstitution.cc \ 538 SynTree/Attribute.cc SynTree/VarExprReplacer.cc \ 539 Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc \ 540 Tuples/Explode.cc Virtual/ExpandCasts.cc 537 541 MAINTAINERCLEANFILES = Parser/parser.output ${libdir}/${notdir \ 538 542 ${cfa_cpplib_PROGRAMS}} … … 713 717 GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT): GenPoly/$(am__dirstamp) \ 714 718 GenPoly/$(DEPDIR)/$(am__dirstamp) 719 GenPoly/driver_cfa_cpp-PolyMutator.$(OBJEXT): GenPoly/$(am__dirstamp) \ 720 GenPoly/$(DEPDIR)/$(am__dirstamp) 715 721 GenPoly/driver_cfa_cpp-ScrubTyVars.$(OBJEXT): GenPoly/$(am__dirstamp) \ 716 722 GenPoly/$(DEPDIR)/$(am__dirstamp) … … 723 729 GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT): \ 724 730 GenPoly/$(am__dirstamp) GenPoly/$(DEPDIR)/$(am__dirstamp) 731 GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT): GenPoly/$(am__dirstamp) \ 732 GenPoly/$(DEPDIR)/$(am__dirstamp) 725 733 GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT): \ 726 734 GenPoly/$(am__dirstamp) GenPoly/$(DEPDIR)/$(am__dirstamp) … … 921 929 SynTree/driver_cfa_cpp-Mutator.$(OBJEXT): SynTree/$(am__dirstamp) \ 922 930 SynTree/$(DEPDIR)/$(am__dirstamp) 931 SynTree/driver_cfa_cpp-AddStmtVisitor.$(OBJEXT): \ 932 SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp) 923 933 SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT): \ 924 934 SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp) … … 998 1008 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Po@am__quote@ 999 1009 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-CopyParams.Po@am__quote@ 1010 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Po@am__quote@ 1000 1011 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Po@am__quote@ 1001 1012 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Po@am__quote@ 1002 1013 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Po@am__quote@ 1003 1014 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Po@am__quote@ 1015 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Po@am__quote@ 1004 1016 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Po@am__quote@ 1005 1017 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Po@am__quote@ … … 1044 1056 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-TypeEquality.Po@am__quote@ 1045 1057 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Validate.Po@am__quote@ 1058 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Po@am__quote@ 1046 1059 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Po@am__quote@ 1047 1060 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AggregateDecl.Po@am__quote@ … … 1437 1450 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-GenPoly.obj `if test -f 'GenPoly/GenPoly.cc'; then $(CYGPATH_W) 'GenPoly/GenPoly.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/GenPoly.cc'; fi` 1438 1451 1452 GenPoly/driver_cfa_cpp-PolyMutator.o: GenPoly/PolyMutator.cc 1453 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-PolyMutator.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Tpo -c -o GenPoly/driver_cfa_cpp-PolyMutator.o `test -f 'GenPoly/PolyMutator.cc' || echo '$(srcdir)/'`GenPoly/PolyMutator.cc 1454 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Po 1455 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/PolyMutator.cc' object='GenPoly/driver_cfa_cpp-PolyMutator.o' libtool=no @AMDEPBACKSLASH@ 1456 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1457 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-PolyMutator.o `test -f 'GenPoly/PolyMutator.cc' || echo '$(srcdir)/'`GenPoly/PolyMutator.cc 1458 1459 GenPoly/driver_cfa_cpp-PolyMutator.obj: GenPoly/PolyMutator.cc 1460 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-PolyMutator.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Tpo -c -o GenPoly/driver_cfa_cpp-PolyMutator.obj `if test -f 'GenPoly/PolyMutator.cc'; then $(CYGPATH_W) 'GenPoly/PolyMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/PolyMutator.cc'; fi` 1461 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Po 1462 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/PolyMutator.cc' object='GenPoly/driver_cfa_cpp-PolyMutator.obj' libtool=no @AMDEPBACKSLASH@ 1463 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1464 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-PolyMutator.obj `if test -f 'GenPoly/PolyMutator.cc'; then $(CYGPATH_W) 'GenPoly/PolyMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/PolyMutator.cc'; fi` 1465 1439 1466 GenPoly/driver_cfa_cpp-ScrubTyVars.o: GenPoly/ScrubTyVars.cc 1440 1467 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-ScrubTyVars.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Tpo -c -o GenPoly/driver_cfa_cpp-ScrubTyVars.o `test -f 'GenPoly/ScrubTyVars.cc' || echo '$(srcdir)/'`GenPoly/ScrubTyVars.cc … … 1507 1534 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-FindFunction.obj `if test -f 'GenPoly/FindFunction.cc'; then $(CYGPATH_W) 'GenPoly/FindFunction.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/FindFunction.cc'; fi` 1508 1535 1536 GenPoly/driver_cfa_cpp-DeclMutator.o: GenPoly/DeclMutator.cc 1537 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-DeclMutator.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Tpo -c -o GenPoly/driver_cfa_cpp-DeclMutator.o `test -f 'GenPoly/DeclMutator.cc' || echo '$(srcdir)/'`GenPoly/DeclMutator.cc 1538 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Po 1539 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/DeclMutator.cc' object='GenPoly/driver_cfa_cpp-DeclMutator.o' libtool=no @AMDEPBACKSLASH@ 1540 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1541 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-DeclMutator.o `test -f 'GenPoly/DeclMutator.cc' || echo '$(srcdir)/'`GenPoly/DeclMutator.cc 1542 1543 GenPoly/driver_cfa_cpp-DeclMutator.obj: GenPoly/DeclMutator.cc 1544 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-DeclMutator.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Tpo -c -o GenPoly/driver_cfa_cpp-DeclMutator.obj `if test -f 'GenPoly/DeclMutator.cc'; then $(CYGPATH_W) 'GenPoly/DeclMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/DeclMutator.cc'; fi` 1545 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Po 1546 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GenPoly/DeclMutator.cc' object='GenPoly/driver_cfa_cpp-DeclMutator.obj' libtool=no @AMDEPBACKSLASH@ 1547 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1548 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-DeclMutator.obj `if test -f 'GenPoly/DeclMutator.cc'; then $(CYGPATH_W) 'GenPoly/DeclMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/DeclMutator.cc'; fi` 1549 1509 1550 GenPoly/driver_cfa_cpp-InstantiateGeneric.o: GenPoly/InstantiateGeneric.cc 1510 1551 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-InstantiateGeneric.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Tpo -c -o GenPoly/driver_cfa_cpp-InstantiateGeneric.o `test -f 'GenPoly/InstantiateGeneric.cc' || echo '$(srcdir)/'`GenPoly/InstantiateGeneric.cc … … 2542 2583 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2543 2584 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Mutator.obj `if test -f 'SynTree/Mutator.cc'; then $(CYGPATH_W) 'SynTree/Mutator.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Mutator.cc'; fi` 2585 2586 SynTree/driver_cfa_cpp-AddStmtVisitor.o: SynTree/AddStmtVisitor.cc 2587 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-AddStmtVisitor.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Tpo -c -o SynTree/driver_cfa_cpp-AddStmtVisitor.o `test -f 'SynTree/AddStmtVisitor.cc' || echo '$(srcdir)/'`SynTree/AddStmtVisitor.cc 2588 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Po 2589 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/AddStmtVisitor.cc' object='SynTree/driver_cfa_cpp-AddStmtVisitor.o' libtool=no @AMDEPBACKSLASH@ 2590 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2591 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-AddStmtVisitor.o `test -f 'SynTree/AddStmtVisitor.cc' || echo '$(srcdir)/'`SynTree/AddStmtVisitor.cc 2592 2593 SynTree/driver_cfa_cpp-AddStmtVisitor.obj: SynTree/AddStmtVisitor.cc 2594 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-AddStmtVisitor.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Tpo -c -o SynTree/driver_cfa_cpp-AddStmtVisitor.obj `if test -f 'SynTree/AddStmtVisitor.cc'; then $(CYGPATH_W) 'SynTree/AddStmtVisitor.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/AddStmtVisitor.cc'; fi` 2595 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Po 2596 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SynTree/AddStmtVisitor.cc' object='SynTree/driver_cfa_cpp-AddStmtVisitor.obj' libtool=no @AMDEPBACKSLASH@ 2597 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2598 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-AddStmtVisitor.obj `if test -f 'SynTree/AddStmtVisitor.cc'; then $(CYGPATH_W) 'SynTree/AddStmtVisitor.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/AddStmtVisitor.cc'; fi` 2544 2599 2545 2600 SynTree/driver_cfa_cpp-TypeSubstitution.o: SynTree/TypeSubstitution.cc -
src/ResolvExpr/Resolver.cc
ra2d4d1c r4dfa562 95 95 PassVisitor<Resolver> resolver; 96 96 acceptAll( translationUnit, resolver ); 97 }98 99 void resolveDecl( Declaration * decl, const SymTab::Indexer &indexer ) {100 PassVisitor<Resolver> resolver( indexer );101 maybeAccept( decl, resolver );102 97 } 103 98 -
src/ResolvExpr/Resolver.h
ra2d4d1c r4dfa562 29 29 /// Checks types and binds syntactic constructs to typed representations 30 30 void resolve( std::list< Declaration * > translationUnit ); 31 void resolveDecl( Declaration *, const SymTab::Indexer &indexer ); 32 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ); 33 Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ); 31 Expression * resolveInVoidContext( Expression *expr , const SymTab::Indexer &indexer ); 32 Expression * findVoidExpression ( Expression *untyped, const SymTab::Indexer &indexer ); 34 33 Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ); 35 34 void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer ); -
src/ResolvExpr/TypeEnvironment.cc
ra2d4d1c r4dfa562 123 123 for ( std::list< EqvClass >::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) { 124 124 for ( std::set< std::string >::const_iterator theVar = theClass->vars.begin(); theVar != theClass->vars.end(); ++theVar ) { 125 /// std::c err<< "adding " << *theVar;125 /// std::cout << "adding " << *theVar; 126 126 if ( theClass->type ) { 127 /// std::c err<< " bound to ";128 /// theClass->type->print( std::c err);129 /// std::c err<< std::endl;127 /// std::cout << " bound to "; 128 /// theClass->type->print( std::cout ); 129 /// std::cout << std::endl; 130 130 sub.add( *theVar, theClass->type ); 131 131 } else if ( theVar != theClass->vars.begin() ) { 132 132 TypeInstType *newTypeInst = new TypeInstType( Type::Qualifiers(), *theClass->vars.begin(), theClass->data.kind == TypeDecl::Ftype ); 133 /// std::c err<< " bound to variable " << *theClass->vars.begin() << std::endl;133 /// std::cout << " bound to variable " << *theClass->vars.begin() << std::endl; 134 134 sub.add( *theVar, newTypeInst ); 135 135 delete newTypeInst; -
src/SymTab/Autogen.cc
ra2d4d1c r4dfa562 16 16 #include "Autogen.h" 17 17 18 #include <cstddef> // for NULL 18 19 #include <algorithm> // for count_if 19 20 #include <cassert> // for strict_dynamic_cast, assert, assertf … … 26 27 #include "AddVisit.h" // for addVisit 27 28 #include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign 28 #include "Common/PassVisitor.h" // for PassVisitor29 29 #include "Common/ScopedMap.h" // for ScopedMap<>::const_iterator, Scope... 30 30 #include "Common/utility.h" // for cloneAll, operator+ 31 #include "GenPoly/DeclMutator.h" // for DeclMutator 31 32 #include "GenPoly/ScopedSet.h" // for ScopedSet, ScopedSet<>::iterator 32 #include "InitTweak/GenInit.h" // for fixReturnStatements33 #include "ResolvExpr/Resolver.h" // for resolveDecl34 33 #include "SymTab/Mangler.h" // for Mangler 35 34 #include "SynTree/Attribute.h" // For Attribute … … 54 53 }; 55 54 56 struct AutogenerateRoutines final : public WithDeclsToAdd, public WithVisitorRef<AutogenerateRoutines>, public WithGuards, public WithShortCircuiting { 55 class AutogenerateRoutines final : public Visitor { 56 template< typename Visitor > 57 friend void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor ); 58 template< typename Visitor > 59 friend void addVisitStatementList( std::list< Statement* > &stmts, Visitor &visitor ); 60 public: 61 std::list< Declaration * > &get_declsToAdd() { return declsToAdd; } 62 63 typedef Visitor Parent; 64 using Parent::visit; 65 57 66 AutogenerateRoutines(); 58 67 59 void previsit( EnumDecl * enumDecl ); 60 void previsit( StructDecl * structDecl ); 61 void previsit( UnionDecl * structDecl ); 62 void previsit( TypeDecl * typeDecl ); 63 void previsit( TraitDecl * traitDecl ); 64 void previsit( FunctionDecl * functionDecl ); 65 66 void previsit( FunctionType * ftype ); 67 void previsit( PointerType * ptype ); 68 69 void previsit( CompoundStmt * compoundStmt ); 68 virtual void visit( EnumDecl *enumDecl ); 69 virtual void visit( StructDecl *structDecl ); 70 virtual void visit( UnionDecl *structDecl ); 71 virtual void visit( TypeDecl *typeDecl ); 72 virtual void visit( TraitDecl *ctxDecl ); 73 virtual void visit( FunctionDecl *functionDecl ); 74 75 virtual void visit( FunctionType *ftype ); 76 virtual void visit( PointerType *ftype ); 77 78 virtual void visit( CompoundStmt *compoundStmt ); 79 virtual void visit( SwitchStmt *switchStmt ); 70 80 71 81 private: 72 GenPoly::ScopedSet< std::string > structsDone; 82 template< typename StmtClass > void visitStatement( StmtClass *stmt ); 83 84 std::list< Declaration * > declsToAdd, declsToAddAfter; 85 std::set< std::string > structsDone; 73 86 unsigned int functionNesting = 0; // current level of nested functions 74 87 /// Note: the following maps could be ScopedSets, but it should be easier to work … … 80 93 81 94 /// generates routines for tuple types. 82 struct AutogenTupleRoutines : public WithDeclsToAdd, public WithVisitorRef<AutogenTupleRoutines>, public WithGuards, public WithShortCircuiting { 83 void previsit( FunctionDecl *functionDecl ); 84 85 void postvisit( TupleType *tupleType ); 86 87 void previsit( CompoundStmt *compoundStmt ); 95 /// Doesn't really need to be a mutator, but it's easier to reuse DeclMutator than it is to use AddVisit 96 /// or anything we currently have that supports adding new declarations for visitors 97 class AutogenTupleRoutines : public GenPoly::DeclMutator { 98 public: 99 typedef GenPoly::DeclMutator Parent; 100 using Parent::mutate; 101 102 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ); 103 104 virtual Type * mutate( TupleType *tupleType ); 105 106 virtual CompoundStmt * mutate( CompoundStmt *compoundStmt ); 88 107 89 108 private: … … 93 112 94 113 void autogenerateRoutines( std::list< Declaration * > &translationUnit ) { 95 PassVisitor<AutogenerateRoutines>generator;96 acceptA ll( translationUnit, generator );114 AutogenerateRoutines generator; 115 acceptAndAdd( translationUnit, generator ); 97 116 98 117 // needs to be done separately because AutogenerateRoutines skips types that appear as function arguments, etc. 99 118 // AutogenTupleRoutines tupleGenerator; 100 // acceptAll( translationUnit, tupleGenerator);119 // tupleGenerator.mutateDeclarationList( translationUnit ); 101 120 } 102 121 103 122 bool isUnnamedBitfield( ObjectDecl * obj ) { 104 return obj != nullptr && obj->get_name() == "" && obj->get_bitfieldWidth() != nullptr;123 return obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL; 105 124 } 106 125 … … 109 128 FunctionDecl * decl = functionDecl->clone(); 110 129 delete decl->get_statements(); 111 decl->set_statements( nullptr);130 decl->set_statements( NULL ); 112 131 declsToAdd.push_back( decl ); 113 132 decl->fixUniqueId(); … … 320 339 assert( ! func->get_functionType()->get_parameters().empty() ); 321 340 ObjectDecl * dstParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().front() ); 322 ObjectDecl * srcParam = nullptr;341 ObjectDecl * srcParam = NULL; 323 342 if ( func->get_functionType()->get_parameters().size() == 2 ) { 324 343 srcParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().back() ); … … 327 346 assert( dstParam ); 328 347 329 Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : nullptr;348 Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL; 330 349 makeStructMemberOp( dstParam, srcselect, field, func, forward ); 331 350 } // if … … 366 385 } else { 367 386 // no matching parameter, initialize field with default ctor 368 makeStructMemberOp( dstParam, nullptr, field, func );387 makeStructMemberOp( dstParam, NULL, field, func ); 369 388 } 370 389 } … … 382 401 void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) { 383 402 // Builtins do not use autogeneration. 384 if ( LinkageSpec::isBuiltin( aggregateDecl->get_linkage() ) ) { 403 if ( aggregateDecl->get_linkage() == LinkageSpec::BuiltinCFA || 404 aggregateDecl->get_linkage() == LinkageSpec::BuiltinC ) { 385 405 return; 386 406 } 387 407 388 408 // Make function polymorphic in same parameters as generic struct, if applicable 389 const std::list< TypeDecl * > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions409 const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions 390 410 391 411 // generate each of the functions based on the supplied FuncData objects … … 552 572 // the order here determines the order that these functions are generated. 553 573 // assignment should come last since it uses copy constructor in return. 554 data.emplace_back( "?{}", genDefaultType, constructable ); 555 data.emplace_back( "?{}", genCopyType, copyable ); 556 data.emplace_back( "^?{}", genDefaultType, destructable ); 557 data.emplace_back( "?=?", genAssignType, assignable ); 558 } 559 560 void AutogenerateRoutines::previsit( EnumDecl * enumDecl ) { 561 visit_children = false; 574 data.push_back( FuncData( "?{}", genDefaultType, constructable ) ); 575 data.push_back( FuncData( "?{}", genCopyType, copyable ) ); 576 data.push_back( FuncData( "^?{}", genDefaultType, destructable ) ); 577 data.push_back( FuncData( "?=?", genAssignType, assignable ) ); 578 } 579 580 void AutogenerateRoutines::visit( EnumDecl *enumDecl ) { 562 581 if ( ! enumDecl->get_members().empty() ) { 563 582 EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() ); … … 567 586 } 568 587 569 void AutogenerateRoutines::previsit( StructDecl * structDecl ) { 570 visit_children = false; 571 if ( structDecl->has_body() && structsDone.find( structDecl->name ) == structsDone.end() ) { 572 StructInstType structInst( Type::Qualifiers(), structDecl->name ); 573 for ( TypeDecl * typeDecl : structDecl->parameters ) { 588 void AutogenerateRoutines::visit( StructDecl *structDecl ) { 589 if ( structDecl->has_body() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) { 590 StructInstType structInst( Type::Qualifiers(), structDecl->get_name() ); 591 for ( TypeDecl * typeDecl : structDecl->get_parameters() ) { 574 592 // need to visit assertions so that they are added to the appropriate maps 575 acceptAll( typeDecl-> assertions, *visitor);576 structInst. parameters.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl ) ) );593 acceptAll( typeDecl->get_assertions(), *this ); 594 structInst.get_parameters().push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), typeDecl ) ) ); 577 595 } 578 596 structInst.set_baseStruct( structDecl ); 579 597 makeStructFunctions( structDecl, &structInst, functionNesting, declsToAddAfter, data ); 580 structsDone.insert( structDecl-> name);598 structsDone.insert( structDecl->get_name() ); 581 599 } // if 582 600 } 583 601 584 void AutogenerateRoutines::previsit( UnionDecl * unionDecl ) { 585 visit_children = false; 602 void AutogenerateRoutines::visit( UnionDecl *unionDecl ) { 586 603 if ( ! unionDecl->get_members().empty() ) { 587 604 UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() ); … … 602 619 603 620 // generate ctor/dtors/assign for typedecls, e.g., otype T = int *; 604 void AutogenerateRoutines::previsit( TypeDecl * typeDecl ) { 605 visit_children = false; 621 void AutogenerateRoutines::visit( TypeDecl *typeDecl ) { 606 622 if ( ! typeDecl->base ) return; 607 623 … … 648 664 } 649 665 650 void AutogenerateRoutines::previsit( FunctionType *) { 666 void addDecls( std::list< Declaration * > &declsToAdd, std::list< Statement * > &statements, std::list< Statement * >::iterator i ) { 667 for ( std::list< Declaration * >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) { 668 statements.insert( i, new DeclStmt( noLabels, *decl ) ); 669 } // for 670 declsToAdd.clear(); 671 } 672 673 void AutogenerateRoutines::visit( FunctionType *) { 651 674 // ensure that we don't add assignment ops for types defined as part of the function 652 visit_children = false; 653 } 654 655 void AutogenerateRoutines::previsit( PointerType *) { 675 } 676 677 void AutogenerateRoutines::visit( PointerType *) { 656 678 // ensure that we don't add assignment ops for types defined as part of the pointer 657 visit_children = false; 658 } 659 660 void AutogenerateRoutines::previsit( TraitDecl * ) { 679 } 680 681 void AutogenerateRoutines::visit( TraitDecl *) { 661 682 // ensure that we don't add assignment ops for types defined as part of the trait 662 visit_children = false; 663 } 664 665 void AutogenerateRoutines::previsit( FunctionDecl * functionDecl ) { 666 visit_children = false; 683 } 684 685 template< typename StmtClass > 686 inline void AutogenerateRoutines::visitStatement( StmtClass *stmt ) { 687 std::set< std::string > oldStructs = structsDone; 688 addVisit( stmt, *this ); 689 structsDone = oldStructs; 690 } 691 692 void AutogenerateRoutines::visit( FunctionDecl *functionDecl ) { 667 693 // record the existence of this function as appropriate 668 694 insert( functionDecl, constructable, InitTweak::isDefaultConstructor ); … … 671 697 insert( functionDecl, destructable, InitTweak::isDestructor ); 672 698 673 maybeAccept( functionDecl-> type, *visitor);699 maybeAccept( functionDecl->get_functionType(), *this ); 674 700 functionNesting += 1; 675 maybeAccept( functionDecl-> statements, *visitor);701 maybeAccept( functionDecl->get_statements(), *this ); 676 702 functionNesting -= 1; 677 703 } 678 704 679 void AutogenerateRoutines::previsit( CompoundStmt * ) { 680 GuardScope( constructable ); 681 GuardScope( assignable ); 682 GuardScope( copyable ); 683 GuardScope( destructable ); 684 GuardScope( structsDone ); 705 void AutogenerateRoutines::visit( CompoundStmt *compoundStmt ) { 706 constructable.beginScope(); 707 assignable.beginScope(); 708 copyable.beginScope(); 709 destructable.beginScope(); 710 visitStatement( compoundStmt ); 711 constructable.endScope(); 712 assignable.endScope(); 713 copyable.endScope(); 714 destructable.endScope(); 715 } 716 717 void AutogenerateRoutines::visit( SwitchStmt *switchStmt ) { 718 visitStatement( switchStmt ); 685 719 } 686 720 … … 700 734 } 701 735 702 void AutogenTupleRoutines::postvisit( TupleType * tupleType ) { 736 Type * AutogenTupleRoutines::mutate( TupleType * tupleType ) { 737 tupleType = strict_dynamic_cast< TupleType * >( Parent::mutate( tupleType ) ); 703 738 std::string mangleName = SymTab::Mangler::mangleType( tupleType ); 704 if ( seenTuples.find( mangleName ) != seenTuples.end() ) return ;739 if ( seenTuples.find( mangleName ) != seenTuples.end() ) return tupleType; 705 740 seenTuples.insert( mangleName ); 706 741 … … 750 785 makeTupleFunctionBody( dtorDecl ); 751 786 752 declsToAddBefore.push_back( ctorDecl ); 753 declsToAddBefore.push_back( copyCtorDecl ); 754 declsToAddBefore.push_back( dtorDecl ); 755 declsToAddBefore.push_back( assignDecl ); // assignment should come last since it uses copy constructor in return 756 } 757 758 void AutogenTupleRoutines::previsit( FunctionDecl *functionDecl ) { 759 visit_children = false; 760 maybeAccept( functionDecl->type, *visitor ); 787 addDeclaration( ctorDecl ); 788 addDeclaration( copyCtorDecl ); 789 addDeclaration( dtorDecl ); 790 addDeclaration( assignDecl ); // assignment should come last since it uses copy constructor in return 791 792 return tupleType; 793 } 794 795 DeclarationWithType * AutogenTupleRoutines::mutate( FunctionDecl *functionDecl ) { 796 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) ); 761 797 functionNesting += 1; 762 maybeAccept( functionDecl->statements, *visitor);798 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) ); 763 799 functionNesting -= 1; 764 } 765 766 void AutogenTupleRoutines::previsit( CompoundStmt * ) { 767 GuardScope( seenTuples ); 800 return functionDecl; 801 } 802 803 CompoundStmt * AutogenTupleRoutines::mutate( CompoundStmt *compoundStmt ) { 804 seenTuples.beginScope(); 805 compoundStmt = strict_dynamic_cast< CompoundStmt * >( Parent::mutate( compoundStmt ) ); 806 seenTuples.endScope(); 807 return compoundStmt; 768 808 } 769 809 } // SymTab -
src/SymTab/FixFunction.cc
ra2d4d1c r4dfa562 27 27 28 28 DeclarationWithType * FixFunction::mutate(FunctionDecl *functionDecl) { 29 // can't delete function type because it may contain assertions, so transfer ownership to new object30 29 ObjectDecl *pointer = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClasses(), functionDecl->get_linkage(), 0, new PointerType( Type::Qualifiers(), functionDecl->get_type() ), 0, functionDecl->get_attributes() ); 31 30 functionDecl->get_attributes().clear(); 32 functionDecl->type = nullptr; 31 // can't delete function type because it may contain assertions, but can't transfer ownership without a clone since set_type checks for nullptr 32 functionDecl->set_type( functionDecl->get_type()->clone() ); 33 33 delete functionDecl; 34 34 return pointer; -
src/SymTab/Indexer.cc
ra2d4d1c r4dfa562 40 40 41 41 namespace SymTab { 42 struct NewScope { 43 NewScope( SymTab::Indexer & indexer ) : indexer( indexer ) { indexer.enterScope(); } 44 ~NewScope() { indexer.leaveScope(); } 45 SymTab::Indexer & indexer; 46 }; 47 48 template< typename TreeType, typename VisitorType > 49 inline void acceptNewScope( TreeType *tree, VisitorType &visitor ) { 50 visitor.enterScope(); 51 maybeAccept( tree, visitor ); 52 visitor.leaveScope(); 53 } 54 42 55 typedef std::unordered_map< std::string, DeclarationWithType* > MangleTable; 43 56 typedef std::unordered_map< std::string, MangleTable > IdTable; … … 185 198 } 186 199 187 Indexer::Indexer( ) : tables( 0 ), scope( 0) {}188 189 Indexer::Indexer( const Indexer &that ) : doDebug( that.doDebug ), tables( newRef( that.tables ) ), scope( that.scope) {}190 191 Indexer::Indexer( Indexer &&that ) : doDebug( that.doDebug ), tables( that.tables ), scope( that.scope) {200 Indexer::Indexer( bool _doDebug ) : tables( 0 ), scope( 0 ), doDebug( _doDebug ) {} 201 202 Indexer::Indexer( const Indexer &that ) : tables( newRef( that.tables ) ), scope( that.scope ), doDebug( that.doDebug ) {} 203 204 Indexer::Indexer( Indexer &&that ) : tables( that.tables ), scope( that.scope ), doDebug( that.doDebug ) { 192 205 that.tables = 0; 193 206 } -
src/SymTab/Indexer.h
ra2d4d1c r4dfa562 26 26 class Indexer { 27 27 public: 28 explicit Indexer( );28 explicit Indexer( bool useDebug = false ); 29 29 30 30 Indexer( const Indexer &that ); … … 76 76 void addTrait( TraitDecl *decl ); 77 77 78 bool doDebug = false; ///< Display debugging trace?79 78 private: 80 79 struct Impl; … … 82 81 Impl *tables; ///< Copy-on-write instance of table data structure 83 82 unsigned long scope; ///< Scope index of this pointer 83 bool doDebug; ///< Display debugging trace? 84 84 85 85 /// Takes a new ref to a table (returns null if null) -
src/SymTab/Mangler.cc
ra2d4d1c r4dfa562 31 31 32 32 namespace SymTab { 33 std::string Mangler::mangleType( Type * ty ) {33 std::string Mangler::mangleType( Type *ty ) { 34 34 Mangler mangler( false, true ); 35 35 maybeAccept( ty, mangler ); … … 48 48 } 49 49 50 void Mangler::mangleDecl( DeclarationWithType * declaration ) {50 void Mangler::mangleDecl( DeclarationWithType *declaration ) { 51 51 bool wasTopLevel = isTopLevel; 52 52 if ( isTopLevel ) { … … 79 79 } 80 80 81 void Mangler::visit( ObjectDecl * declaration ) {81 void Mangler::visit( ObjectDecl *declaration ) { 82 82 mangleDecl( declaration ); 83 83 } 84 84 85 void Mangler::visit( FunctionDecl * declaration ) {85 void Mangler::visit( FunctionDecl *declaration ) { 86 86 mangleDecl( declaration ); 87 87 } 88 88 89 void Mangler::visit( VoidType * voidType ) {89 void Mangler::visit( VoidType *voidType ) { 90 90 printQualifiers( voidType ); 91 91 mangleName << "v"; 92 92 } 93 93 94 void Mangler::visit( BasicType * basicType ) {94 void Mangler::visit( BasicType *basicType ) { 95 95 static const char *btLetter[] = { 96 96 "b", // Bool … … 121 121 } 122 122 123 void Mangler::visit( PointerType * pointerType ) {123 void Mangler::visit( PointerType *pointerType ) { 124 124 printQualifiers( pointerType ); 125 125 mangleName << "P"; … … 127 127 } 128 128 129 void Mangler::visit( ArrayType * arrayType ) {129 void Mangler::visit( ArrayType *arrayType ) { 130 130 // TODO: encode dimension 131 131 printQualifiers( arrayType ); … … 134 134 } 135 135 136 void Mangler::visit( ReferenceType * refType ) {136 void Mangler::visit( ReferenceType *refType ) { 137 137 printQualifiers( refType ); 138 138 mangleName << "R"; … … 149 149 } 150 150 151 void Mangler::visit( FunctionType * functionType ) {151 void Mangler::visit( FunctionType *functionType ) { 152 152 printQualifiers( functionType ); 153 153 mangleName << "F"; … … 160 160 } 161 161 162 void Mangler::mangleRef( ReferenceToType * refType, std::string prefix ) {162 void Mangler::mangleRef( ReferenceToType *refType, std::string prefix ) { 163 163 printQualifiers( refType ); 164 164 … … 166 166 } 167 167 168 void Mangler::mangleGenericRef( ReferenceToType * refType, std::string prefix ) {168 void Mangler::mangleGenericRef( ReferenceToType *refType, std::string prefix ) { 169 169 printQualifiers( refType ); 170 170 … … 189 189 } 190 190 191 void Mangler::visit( StructInstType * aggregateUseType ) {191 void Mangler::visit( StructInstType *aggregateUseType ) { 192 192 if ( typeMode ) mangleGenericRef( aggregateUseType, "s" ); 193 193 else mangleRef( aggregateUseType, "s" ); 194 194 } 195 195 196 void Mangler::visit( UnionInstType * aggregateUseType ) {196 void Mangler::visit( UnionInstType *aggregateUseType ) { 197 197 if ( typeMode ) mangleGenericRef( aggregateUseType, "u" ); 198 198 else mangleRef( aggregateUseType, "u" ); 199 199 } 200 200 201 void Mangler::visit( EnumInstType * aggregateUseType ) {201 void Mangler::visit( EnumInstType *aggregateUseType ) { 202 202 mangleRef( aggregateUseType, "e" ); 203 203 } 204 204 205 void Mangler::visit( TypeInstType * typeInst ) {205 void Mangler::visit( TypeInstType *typeInst ) { 206 206 VarMapType::iterator varNum = varNums.find( typeInst->get_name() ); 207 207 if ( varNum == varNums.end() ) { … … 231 231 } 232 232 233 void Mangler::visit( TupleType * tupleType ) {233 void Mangler::visit( TupleType *tupleType ) { 234 234 printQualifiers( tupleType ); 235 235 mangleName << "T"; 236 acceptAll( tupleType-> types, *this );236 acceptAll( tupleType->get_types(), *this ); 237 237 mangleName << "_"; 238 238 } 239 239 240 void Mangler::visit( VarArgsType * varArgsType ) {240 void Mangler::visit( VarArgsType *varArgsType ) { 241 241 printQualifiers( varArgsType ); 242 242 mangleName << "VARGS"; 243 243 } 244 244 245 void Mangler::visit( ZeroType *) {245 void Mangler::visit( __attribute__((unused)) ZeroType *zeroType ) { 246 246 mangleName << "Z"; 247 247 } 248 248 249 void Mangler::visit( OneType *) {249 void Mangler::visit( __attribute__((unused)) OneType *oneType ) { 250 250 mangleName << "O"; 251 251 } 252 252 253 void Mangler::visit( TypeDecl * decl ) {253 void Mangler::visit( TypeDecl *decl ) { 254 254 static const char *typePrefix[] = { "BT", "BD", "BF" }; 255 mangleName << typePrefix[ decl->get_kind() ] << ( decl-> name.length() + 1 ) << decl->name;255 mangleName << typePrefix[ decl->get_kind() ] << ( decl->get_name().length() + 1 ) << decl->get_name(); 256 256 } 257 257 … … 262 262 } 263 263 264 void Mangler::printQualifiers( Type * type ) {264 void Mangler::printQualifiers( Type *type ) { 265 265 // skip if not including qualifiers 266 266 if ( typeMode ) return; … … 270 270 int tcount = 0, dcount = 0, fcount = 0, vcount = 0; 271 271 mangleName << "A"; 272 for ( Type::ForallList::iterator i = type-> forall.begin(); i != type->forall.end(); ++i ) {272 for ( Type::ForallList::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) { 273 273 switch ( (*i)->get_kind() ) { 274 274 case TypeDecl::Any: … … 287 287 assert( false ); 288 288 } // switch 289 varNums[ (*i )->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() );290 for ( std::list< DeclarationWithType* >::iterator assert = (*i )->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) {289 varNums[ (*i )->get_name() ] = std::pair< int, int >( nextVarNum++, (int )(*i )->get_kind() ); 290 for ( std::list< DeclarationWithType* >::iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) { 291 291 Mangler sub_mangler( mangleOverridable, typeMode ); 292 292 sub_mangler.nextVarNum = nextVarNum; … … 315 315 // } // if 316 316 if ( type->get_lvalue() ) { 317 // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues318 317 mangleName << "L"; 319 } 318 } // if 320 319 if ( type->get_atomic() ) { 321 320 mangleName << "A"; -
src/SymTab/Validate.cc
ra2d4d1c r4dfa562 56 56 #include "FixFunction.h" // for FixFunction 57 57 #include "Indexer.h" // for Indexer 58 #include "InitTweak/GenInit.h" // for fixReturnStatements59 58 #include "InitTweak/InitTweak.h" // for isCtorDtorAssign 60 59 #include "Parser/LinkageSpec.h" // for C … … 151 150 /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID. 152 151 struct ForallPointerDecay final { 153 void previsit( ObjectDecl * object );154 void previsit( FunctionDecl * func );152 void previsit( ObjectDecl *object ); 153 void previsit( FunctionDecl *func ); 155 154 }; 156 155 … … 580 579 581 580 /// Fix up assertions - flattens assertion lists, removing all trait instances 582 void forallFixer( std::list< TypeDecl * > & forall, BaseSyntaxNode * node) {583 for ( TypeDecl * type : f orall) {581 void forallFixer( Type * func ) { 582 for ( TypeDecl * type : func->get_forall() ) { 584 583 std::list< DeclarationWithType * > asserts; 585 584 asserts.splice( asserts.end(), type->assertions ); … … 600 599 assertion = assertion->acceptMutator( fixer ); 601 600 if ( fixer.get_isVoid() ) { 602 throw SemanticError( "invalid type void in assertion of function ", node);601 throw SemanticError( "invalid type void in assertion of function ", func ); 603 602 } // if 604 603 } // for … … 608 607 609 608 void ForallPointerDecay::previsit( ObjectDecl *object ) { 610 forallFixer( object-> type->forall, object);611 if ( PointerType *pointer = dynamic_cast< PointerType * >( object-> type) ) {612 forallFixer( pointer-> base->forall, object);609 forallFixer( object->get_type() ); 610 if ( PointerType *pointer = dynamic_cast< PointerType * >( object->get_type() ) ) { 611 forallFixer( pointer->get_base() ); 613 612 } // if 614 613 object->fixUniqueId(); … … 616 615 617 616 void ForallPointerDecay::previsit( FunctionDecl *func ) { 618 forallFixer( func-> type->forall, func);617 forallFixer( func->get_type() ); 619 618 func->fixUniqueId(); 620 619 } -
src/SynTree/Visitor.h
ra2d4d1c r4dfa562 25 25 public: 26 26 // visit: Default implementation of all functions visits the children 27 // of the given syntax node, but performs no other action.27 // of the given syntax node, but performs no other action. 28 28 29 29 virtual void visit( ObjectDecl *objectDecl ); -
src/SynTree/module.mk
ra2d4d1c r4dfa562 48 48 SynTree/Visitor.cc \ 49 49 SynTree/Mutator.cc \ 50 SynTree/AddStmtVisitor.cc \ 50 51 SynTree/TypeSubstitution.cc \ 51 52 SynTree/Attribute.cc \ -
src/Tuples/TupleExpansion.cc
ra2d4d1c r4dfa562 21 21 #include "Common/ScopedMap.h" // for ScopedMap 22 22 #include "Common/utility.h" // for CodeLocation 23 #include "GenPoly/DeclMutator.h" // for DeclMutator 23 24 #include "InitTweak/InitTweak.h" // for getFunction 24 25 #include "Parser/LinkageSpec.h" // for Spec, C, Intrinsic -
src/main.cc
ra2d4d1c r4dfa562 239 239 } // if 240 240 241 // OPTPRINT( "Concurrency" ) 242 // Concurrency::applyKeywords( translationUnit ); 243 241 244 // add the assignment statement after the initialization of a type parameter 242 245 OPTPRINT( "validate" ) -
src/tests/.expect/64/sched-ext-parse.txt
ra2d4d1c r4dfa562 1055 1055 static inline struct condition ___operator_assign__F10scondition_R10scondition10scondition_autogen___1(struct condition *___dst__R10scondition_1, struct condition ___src__10scondition_1){ 1056 1056 struct condition ___ret__10scondition_1; 1057 struct __condition_blocked_queue_t _tmp_cp 4;1057 struct __condition_blocked_queue_t _tmp_cp56; 1058 1058 struct __condition_blocked_queue_t _tmp_cp_ret29; 1059 ((void)(((void)(_tmp_cp_ret29=___operator_assign__F28s__condition_blocked_queue_t_R28s__condition_blocked_queue_t28s__condition_blocked_queue_t_autogen___1((&(*___dst__R10scondition_1).__blocked__28s__condition_blocked_queue_t_1), (((void)___constructor__F_R28s__condition_blocked_queue_t28s__condition_blocked_queue_t_autogen___1((&_tmp_cp 4), ___src__10scondition_1.__blocked__28s__condition_blocked_queue_t_1)) , _tmp_cp4)))) , _tmp_cp_ret29));1059 ((void)(((void)(_tmp_cp_ret29=___operator_assign__F28s__condition_blocked_queue_t_R28s__condition_blocked_queue_t28s__condition_blocked_queue_t_autogen___1((&(*___dst__R10scondition_1).__blocked__28s__condition_blocked_queue_t_1), (((void)___constructor__F_R28s__condition_blocked_queue_t28s__condition_blocked_queue_t_autogen___1((&_tmp_cp56), ___src__10scondition_1.__blocked__28s__condition_blocked_queue_t_1)) , _tmp_cp56)))) , _tmp_cp_ret29)); 1060 1060 ((void)___destructor__F_R28s__condition_blocked_queue_t_autogen___1((&_tmp_cp_ret29))); 1061 ((void)___destructor__F_R28s__condition_blocked_queue_t_autogen___1((&_tmp_cp 4)));1061 ((void)___destructor__F_R28s__condition_blocked_queue_t_autogen___1((&_tmp_cp56))); 1062 1062 ((void)((*___dst__R10scondition_1).__monitors__PP13smonitor_desc_1=___src__10scondition_1.__monitors__PP13smonitor_desc_1)); 1063 1063 ((void)((*___dst__R10scondition_1).__monitor_count__Us_1=___src__10scondition_1.__monitor_count__Us_1)); … … 1155 1155 static inline struct M ___operator_assign__F2sM_R2sM2sM_autogen___1(struct M *___dst__R2sM_1, struct M ___src__2sM_1){ 1156 1156 struct M ___ret__2sM_1; 1157 struct monitor_desc _tmp_cp 5;1157 struct monitor_desc _tmp_cp60; 1158 1158 struct monitor_desc _tmp_cp_ret31; 1159 ((void)(((void)(_tmp_cp_ret31=___operator_assign__F13smonitor_desc_R13smonitor_desc13smonitor_desc_autogen___1((&(*___dst__R2sM_1).____mon__13smonitor_desc_1), (((void)___constructor__F_R13smonitor_desc13smonitor_desc_autogen___1((&_tmp_cp 5), ___src__2sM_1.____mon__13smonitor_desc_1)) , _tmp_cp5)))) , _tmp_cp_ret31));1159 ((void)(((void)(_tmp_cp_ret31=___operator_assign__F13smonitor_desc_R13smonitor_desc13smonitor_desc_autogen___1((&(*___dst__R2sM_1).____mon__13smonitor_desc_1), (((void)___constructor__F_R13smonitor_desc13smonitor_desc_autogen___1((&_tmp_cp60), ___src__2sM_1.____mon__13smonitor_desc_1)) , _tmp_cp60)))) , _tmp_cp_ret31)); 1160 1160 ((void)___destructor__F_R13smonitor_desc_autogen___1((&_tmp_cp_ret31))); 1161 ((void)___destructor__F_R13smonitor_desc_autogen___1((&_tmp_cp 5)));1161 ((void)___destructor__F_R13smonitor_desc_autogen___1((&_tmp_cp60))); 1162 1162 ((void)___constructor__F_R2sM2sM_autogen___1((&___ret__2sM_1), ___src__2sM_1)); 1163 1163 return ((struct M )___ret__2sM_1);
Note:
See TracChangeset
for help on using the changeset viewer.