Changes in / [74bba15:af58ee0]
- Location:
- src
- Files:
-
- 6 added
- 12 deleted
- 59 edited
-
CodeGen/CodeGenerator.cc (modified) (10 diffs)
-
Concurrency/Keywords.cc (modified) (1 diff)
-
Concurrency/Waitfor.cc (modified) (20 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)
-
Parser/StatementNode.cc (modified) (4 diffs)
-
Parser/parserutility.cc (modified) (1 diff)
-
ResolvExpr/AlternativeFinder.cc (modified) (1 diff)
-
ResolvExpr/AlternativeFinder.h (modified) (3 diffs)
-
ResolvExpr/Resolver.cc (modified) (5 diffs)
-
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) (16 diffs)
-
SymTab/Validate.cc (modified) (6 diffs)
-
SynTree/AddStmtVisitor.cc (added)
-
SynTree/AddStmtVisitor.h (added)
-
SynTree/BaseSyntaxNode.h (modified) (1 diff)
-
SynTree/CompoundStmt.cc (modified) (1 diff)
-
SynTree/Constant.cc (modified) (1 diff)
-
SynTree/Constant.h (modified) (1 diff)
-
SynTree/Declaration.cc (modified) (1 diff)
-
SynTree/Declaration.h (modified) (15 diffs)
-
SynTree/Expression.cc (modified) (1 diff)
-
SynTree/Expression.h (modified) (1 diff)
-
SynTree/Initializer.cc (modified) (1 diff)
-
SynTree/Initializer.h (modified) (6 diffs)
-
SynTree/Statement.cc (modified) (3 diffs)
-
SynTree/Statement.h (modified) (21 diffs)
-
SynTree/Type.cc (modified) (1 diff)
-
SynTree/Type.h (modified) (19 diffs)
-
SynTree/Visitor.h (modified) (1 diff)
-
SynTree/module.mk (modified) (1 diff)
-
Tuples/TupleExpansion.cc (modified) (1 diff)
-
benchmark/bench.h (modified) (1 diff)
-
libcfa/Makefile.am (modified) (1 diff)
-
libcfa/Makefile.in (modified) (1 diff)
-
libcfa/concurrency/coroutine.c (modified) (1 diff)
-
libcfa/concurrency/invoke.h (modified) (2 diffs)
-
libcfa/concurrency/kernel.c (modified) (5 diffs)
-
libcfa/concurrency/monitor (modified) (3 diffs)
-
libcfa/concurrency/monitor.c (modified) (24 diffs)
-
libcfa/concurrency/preemption.c (modified) (1 diff)
-
libcfa/concurrency/thread (modified) (1 diff)
-
libcfa/concurrency/thread.c (modified) (1 diff)
-
main.cc (modified) (1 diff)
-
prelude/prelude.cf (modified) (2 diffs)
-
tests/.expect/32/sched-ext-parse.txt (deleted)
-
tests/.expect/64/sched-ext-parse.txt (deleted)
-
tests/.expect/concurrent/sched-ext-barge.txt (deleted)
-
tests/.expect/concurrent/sched-ext-statment.txt (deleted)
-
tests/.expect/pingpong.txt (deleted)
-
tests/.expect/prodcons.txt (deleted)
-
tests/.expect/sched-ext-else.txt (deleted)
-
tests/Makefile.am (modified) (2 diffs)
-
tests/Makefile.in (modified) (2 diffs)
-
tests/pingpong.c (deleted)
-
tests/prodcons.c (deleted)
-
tests/sched-ext-barge.c (deleted)
-
tests/sched-ext-else.c (deleted)
-
tests/sched-ext-parse.c (modified) (1 diff)
-
tests/sched-ext-statment.c (deleted)
-
tests/sched-ext.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r74bba15 raf58ee0 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 … … 879 885 880 886 void CodeGenerator::postvisit( CaseStmt * caseStmt ) { 881 updateLocation( caseStmt );882 output << indent;883 887 if ( caseStmt->isDefault()) { 884 888 output << "default"; … … 1022 1026 } // namespace CodeGen 1023 1027 1024 std::ostream & operator<<( std::ostream & out, const BaseSyntaxNode * node ) {1025 if ( node ) {1026 node->print( out );1027 } else {1028 out << "nullptr";1029 }1030 return out;1031 }1032 1033 1028 // Local Variables: // 1034 1029 // tab-width: 4 // -
src/Concurrency/Keywords.cc
r74bba15 raf58ee0 528 528 DeclarationWithType * param = decl->get_functionType()->get_parameters().front(); 529 529 auto type = dynamic_cast< StructInstType * >( InitTweak::getPointerBase( param->get_type() ) ); 530 // if( type ) std::cerr << "FRED2" << std::endl; 530 531 if( type && type->get_baseStruct()->is_thread() ) { 531 532 addStartStatement( decl, param ); -
src/Concurrency/Waitfor.cc
r74bba15 raf58ee0 27 27 #include "InitTweak/InitTweak.h" // for getPointerBase 28 28 #include "Parser/LinkageSpec.h" // for Cforall 29 #include " ResolvExpr/Resolver.h" // for findVoidExpression29 #include "SymTab/AddVisit.h" // for acceptAndAdd 30 30 #include "SynTree/Constant.h" // for Constant 31 31 #include "SynTree/Declaration.h" // for StructDecl, FunctionDecl, ObjectDecl … … 112 112 //============================================================================================= 113 113 114 class GenerateWaitForPass final : public With Indexer{114 class GenerateWaitForPass final : public WithStmtsToAdd { 115 115 public: 116 116 … … 126 126 127 127 ObjectDecl * declare( unsigned long count, CompoundStmt * stmt ); 128 ObjectDecl * declareFlag( CompoundStmt * stmt );129 Statement * makeSetter( ObjectDecl * flag );130 128 ObjectDecl * declMon( WaitForStmt::Clause & clause, CompoundStmt * stmt ); 131 void init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, Statement * settter,CompoundStmt * stmt );132 Expression * init_timeout( Expression *& time, Expression *& time_cond, bool has_else, Expression *& else_cond, Statement * settter,CompoundStmt * stmt );133 Expression * call( size_t count, ObjectDecl * acceptables, Expression * timeout, CompoundStmt * stmt);134 void choose( WaitForStmt * waitfor, Expression * result, CompoundStmt * stmt);129 void init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, CompoundStmt * stmt ); 130 Expression * init_timeout( Expression *& time, Expression *& time_cond, bool has_else, Expression *& else_cond, CompoundStmt * stmt ); 131 Expression * call(); 132 void choose(); 135 133 136 134 static void implement( std::list< Declaration * > & translationUnit ) { … … 142 140 private: 143 141 FunctionDecl * decl_waitfor = nullptr; 144 StructDecl * decl_mask = nullptr;145 142 StructDecl * decl_acceptable = nullptr; 146 143 StructDecl * decl_monitor = nullptr; 144 DeclarationWithType * decl_m_func = nullptr; 145 DeclarationWithType * decl_m_count = nullptr; 146 DeclarationWithType * decl_m_monitors = nullptr; 147 DeclarationWithType * decl_m_isdtor = nullptr; 147 148 148 149 static std::unique_ptr< Type > generic_func; 149 150 151 UniqueName namer_mon = "__monitors_"s; 150 152 UniqueName namer_acc = "__acceptables_"s; 151 UniqueName namer_idx = "__index_"s;152 UniqueName namer_flg = "__do_run_"s;153 UniqueName namer_msk = "__mask_"s;154 UniqueName namer_mon = "__monitors_"s;155 153 UniqueName namer_tim = "__timeout_"s; 156 154 }; … … 169 167 namespace { 170 168 Expression * makeOpIndex( DeclarationWithType * array, unsigned long index ) { 171 return new UntypedExpr(169 return new ApplicationExpr( 172 170 new NameExpr( "?[?]" ), 173 171 { … … 179 177 180 178 Expression * makeOpAssign( Expression * lhs, Expression * rhs ) { 181 return new UntypedExpr(179 return new ApplicationExpr( 182 180 new NameExpr( "?=?" ), 183 181 { lhs, rhs } … … 185 183 } 186 184 187 Expression * makeOpMember( Expression * sue, const std::string & mem ) { 188 return new UntypedMemberExpr( new NameExpr( mem ), sue ); 189 } 190 191 Statement * makeAccStatement( DeclarationWithType * object, unsigned long index, const std::string & member, Expression * value, const SymTab::Indexer & indexer ) { 192 std::unique_ptr< Expression > expr( makeOpAssign( 193 makeOpMember( 194 makeOpIndex( 195 object, 196 index 185 Expression * makeOpMember( Expression * sue, DeclarationWithType * mem ) { 186 return new MemberExpr( mem, sue ); 187 } 188 189 Statement * makeAccStatement( DeclarationWithType * object, unsigned long index, DeclarationWithType * member, Expression * value ) { 190 return new ExprStmt( 191 noLabels, 192 makeOpAssign( 193 makeOpMember( 194 makeOpIndex( 195 object, 196 index 197 ), 198 member 197 199 ), 198 member 199 ), 200 value 201 ) ); 202 203 return new ExprStmt( noLabels, ResolvExpr::findVoidExpression( expr.get(), indexer ) ); 200 value 201 ) 202 ); 204 203 } 205 204 … … 209 208 return new ConstantExpr( Constant::from_bool( ifnull ) ); 210 209 } 211 212 VariableExpr * extractVariable( Expression * func ) {213 if( VariableExpr * var = dynamic_cast< VariableExpr * >( func ) ) {214 return var;215 }216 217 CastExpr * cast = strict_dynamic_cast< CastExpr * >( func );218 return strict_dynamic_cast< VariableExpr * >( cast->arg );219 }220 221 Expression * detectIsDtor( Expression * func ) {222 VariableExpr * typed_func = extractVariable( func );223 bool is_dtor = InitTweak::isDestructor( typed_func->var );224 return new ConstantExpr( Constant::from_bool( is_dtor ) );225 }226 210 }; 227 211 … … 232 216 233 217 void GenerateWaitForPass::premutate( FunctionDecl * decl) { 234 if( decl->name != "__ waitfor_internal" ) return;218 if( decl->name != "__accept_internal" ) return; 235 219 236 220 decl_waitfor = decl; … … 243 227 assert( !decl_acceptable ); 244 228 decl_acceptable = decl; 245 } 246 else if( decl->name == "__waitfor_mask_t" ) { 247 assert( !decl_mask ); 248 decl_mask = decl; 229 for( Declaration * field : decl_acceptable->members ) { 230 if( field->name == "func" ) decl_m_func = strict_dynamic_cast< DeclarationWithType * >( field ); 231 else if( field->name == "count" ) decl_m_count = strict_dynamic_cast< DeclarationWithType * >( field ); 232 else if( field->name == "monitor" ) decl_m_monitors = strict_dynamic_cast< DeclarationWithType * >( field ); 233 else if( field->name == "is_dtor" ) decl_m_isdtor = strict_dynamic_cast< DeclarationWithType * >( field ); 234 } 235 249 236 } 250 237 else if( decl->name == "monitor_desc" ) { … … 255 242 256 243 Statement * GenerateWaitForPass::postmutate( WaitForStmt * waitfor ) { 257 if( !decl_monitor || !decl_acceptable || !decl_mask ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor ); 244 return waitfor; 245 246 if( !decl_monitor || !decl_acceptable ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor ); 258 247 259 248 CompoundStmt * stmt = new CompoundStmt( noLabels ); 260 249 261 250 ObjectDecl * acceptables = declare( waitfor->clauses.size(), stmt ); 262 ObjectDecl * flag = declareFlag( stmt );263 Statement * setter = makeSetter( flag );264 251 265 252 int index = 0; 266 253 for( auto & clause : waitfor->clauses ) { 267 init( acceptables, index, clause, s etter, stmt );254 init( acceptables, index, clause, stmt ); 268 255 269 256 index++; … … 275 262 waitfor->orelse .statement, 276 263 waitfor->orelse .condition, 277 setter,278 264 stmt 279 265 ); 280 266 281 CompoundStmt * compound = new CompoundStmt( noLabels ); 282 stmt->push_back( new IfStmt( 283 noLabels, 284 safeCond( new VariableExpr( flag ) ), 285 compound, 286 nullptr 287 )); 288 289 Expression * result = call( waitfor->clauses.size(), acceptables, timeout, compound ); 290 291 choose( waitfor, result, compound ); 267 // Expression * result = call( acceptables, timeout, orelse, stmt ); 268 269 // choose( waitfor, result ); 292 270 293 271 return stmt; … … 296 274 ObjectDecl * GenerateWaitForPass::declare( unsigned long count, CompoundStmt * stmt ) 297 275 { 298 ObjectDecl * acceptables = ObjectDecl::newObject(276 ObjectDecl * acceptables = new ObjectDecl( 299 277 namer_acc.newName(), 278 noStorage, 279 LinkageSpec::Cforall, 280 nullptr, 300 281 new ArrayType( 301 282 noQualifiers, … … 313 294 stmt->push_back( new DeclStmt( noLabels, acceptables) ); 314 295 315 UntypedExpr * set = new UntypedExpr(316 new NameExpr( "__builtin_memset" ),317 {318 new VariableExpr( acceptables ),319 new ConstantExpr( Constant::from_int( 0 ) ),320 new SizeofExpr( new VariableExpr( acceptables ) )321 }322 );323 324 Expression * resolved_set = ResolvExpr::findVoidExpression( set, indexer );325 delete set;326 327 stmt->push_back( new ExprStmt( noLabels, resolved_set ) );328 329 296 return acceptables; 330 297 } 331 298 332 ObjectDecl * GenerateWaitForPass::declareFlag( CompoundStmt * stmt ) {333 ObjectDecl * flag = ObjectDecl::newObject(334 namer_flg.newName(),335 new BasicType(336 noQualifiers,337 BasicType::Bool338 ),339 new SingleInit( new ConstantExpr( Constant::from_ulong( 0 ) ) )340 );341 342 stmt->push_back( new DeclStmt( noLabels, flag) );343 344 return flag;345 }346 347 Statement * GenerateWaitForPass::makeSetter( ObjectDecl * flag ) {348 Expression * untyped = new UntypedExpr(349 new NameExpr( "?=?" ),350 {351 new VariableExpr( flag ),352 new ConstantExpr( Constant::from_ulong( 1 ) )353 }354 );355 356 Expression * expr = ResolvExpr::findVoidExpression( untyped, indexer );357 delete untyped;358 359 return new ExprStmt( noLabels, expr );360 }361 362 299 ObjectDecl * GenerateWaitForPass::declMon( WaitForStmt::Clause & clause, CompoundStmt * stmt ) { 363 300 364 ObjectDecl * mon = ObjectDecl::newObject(301 ObjectDecl * mon = new ObjectDecl( 365 302 namer_mon.newName(), 303 noStorage, 304 LinkageSpec::Cforall, 305 nullptr, 366 306 new ArrayType( 367 307 noQualifiers, 368 new PointerType(308 new StructInstType( 369 309 noQualifiers, 370 new StructInstType( 371 noQualifiers, 372 decl_monitor 373 ) 310 decl_monitor 374 311 ), 375 312 new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ), … … 379 316 new ListInit( 380 317 map_range < std::list<Initializer*> > ( clause.target.arguments, [this](Expression * expr ){ 381 Expression * untyped = new CastExpr( 382 new UntypedExpr( 383 new NameExpr( "get_monitor" ), 384 { expr } 385 ), 386 new PointerType( 387 noQualifiers, 388 new StructInstType( 389 noQualifiers, 390 decl_monitor 391 ) 392 ) 393 ); 394 395 Expression * init = ResolvExpr::findSingleExpression( untyped, indexer ); 396 delete untyped; 397 return new SingleInit( init ); 318 return new SingleInit( expr ); 398 319 }) 399 320 ) … … 405 326 } 406 327 407 void GenerateWaitForPass::init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, Statement * setter,CompoundStmt * stmt ) {328 void GenerateWaitForPass::init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, CompoundStmt * stmt ) { 408 329 409 330 ObjectDecl * monitors = declMon( clause, stmt ); 410 331 411 Type * fptr_t = new PointerType( noQualifiers, new FunctionType( noQualifiers, true ) ); 332 CompoundStmt * compound = new CompoundStmt( noLabels ); 333 compound->push_back( makeAccStatement( acceptables, index, decl_m_func , clause.target.function ) ); 334 compound->push_back( makeAccStatement( acceptables, index, decl_m_count , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ) ) ); 335 compound->push_back( makeAccStatement( acceptables, index, decl_m_monitors, new VariableExpr( monitors ) ) ); 336 compound->push_back( makeAccStatement( acceptables, index, decl_m_isdtor , new ConstantExpr( Constant::from_bool( true ) ) ) ); 412 337 413 338 stmt->push_back( new IfStmt( 414 339 noLabels, 415 340 safeCond( clause.condition ), 416 new CompoundStmt({ 417 makeAccStatement( acceptables, index, "is_dtor", detectIsDtor( clause.target.function ) , indexer ), 418 makeAccStatement( acceptables, index, "func" , new CastExpr( clause.target.function, fptr_t ) , indexer ), 419 makeAccStatement( acceptables, index, "list" , new VariableExpr( monitors ) , indexer ), 420 makeAccStatement( acceptables, index, "size" , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ), indexer ), 421 setter->clone() 422 }), 341 compound, 423 342 nullptr 424 343 )); … … 434 353 bool has_else, 435 354 Expression *& else_cond, 436 Statement * setter,437 355 CompoundStmt * stmt 438 356 ) { 439 ObjectDecl * timeout = ObjectDecl::newObject(357 ObjectDecl * timeout = new ObjectDecl( 440 358 namer_tim.newName(), 359 noStorage, 360 LinkageSpec::Cforall, 361 nullptr, 441 362 new BasicType( 442 363 noQualifiers, … … 453 374 stmt->push_back( new IfStmt( 454 375 noLabels, 455 safeCond( time_cond ), 456 new CompoundStmt({ 457 new ExprStmt( 458 noLabels, 459 makeOpAssign( 460 new VariableExpr( timeout ), 461 time 462 ) 463 ), 464 setter->clone() 465 }), 376 safeCond( else_cond ), 377 new ExprStmt( 378 noLabels, 379 makeOpAssign( 380 new VariableExpr( timeout ), 381 time 382 ) 383 ), 466 384 nullptr 467 385 )); … … 474 392 noLabels, 475 393 safeCond( else_cond ), 476 new CompoundStmt({ 477 new ExprStmt( 478 noLabels, 479 makeOpAssign( 480 new VariableExpr( timeout ), 481 new ConstantExpr( Constant::from_ulong( 0 ) ) 482 ) 483 ), 484 setter->clone() 485 }), 394 new ExprStmt( 395 noLabels, 396 makeOpAssign( 397 new VariableExpr( timeout ), 398 new ConstantExpr( Constant::from_ulong( 0 ) ) 399 ) 400 ), 486 401 nullptr 487 402 )); … … 490 405 } 491 406 492 delete setter;493 494 407 return new VariableExpr( timeout ); 495 }496 497 Expression * GenerateWaitForPass::call(498 size_t count,499 ObjectDecl * acceptables,500 Expression * timeout,501 CompoundStmt * stmt502 ) {503 ObjectDecl * index = ObjectDecl::newObject(504 namer_idx.newName(),505 new BasicType(506 noQualifiers,507 BasicType::ShortSignedInt508 ),509 new SingleInit(510 new ConstantExpr( Constant::from_int( -1 ) )511 )512 );513 514 stmt->push_back( new DeclStmt( noLabels, index ) );515 516 ObjectDecl * mask = ObjectDecl::newObject(517 namer_msk.newName(),518 new StructInstType(519 noQualifiers,520 decl_mask521 ),522 new ListInit({523 new SingleInit( new AddressExpr( new VariableExpr( index ) ) ),524 new SingleInit( new VariableExpr( acceptables ) ),525 new SingleInit( new ConstantExpr( Constant::from_ulong( count ) ) )526 })527 );528 529 stmt->push_back( new DeclStmt( noLabels, mask ) );530 531 stmt->push_back( new ExprStmt(532 noLabels,533 new ApplicationExpr(534 VariableExpr::functionPointer( decl_waitfor ),535 {536 new CastExpr(537 new VariableExpr( mask ),538 new ReferenceType(539 noQualifiers,540 new StructInstType(541 noQualifiers,542 decl_mask543 )544 )545 ),546 timeout547 }548 )549 ));550 551 return new VariableExpr( index );552 }553 554 void GenerateWaitForPass::choose(555 WaitForStmt * waitfor,556 Expression * result,557 CompoundStmt * stmt558 ) {559 SwitchStmt * swtch = new SwitchStmt(560 noLabels,561 result,562 std::list<Statement *>()563 );564 565 unsigned long i = 0;566 for( auto & clause : waitfor->clauses ) {567 swtch->statements.push_back(568 new CaseStmt(569 noLabels,570 new ConstantExpr( Constant::from_ulong( i++ ) ),571 {572 clause.statement,573 new BranchStmt(574 noLabels,575 "",576 BranchStmt::Break577 )578 }579 )580 );581 }582 583 if(waitfor->timeout.statement) {584 swtch->statements.push_back(585 new CaseStmt(586 noLabels,587 new ConstantExpr( Constant::from_int( -2 ) ),588 {589 waitfor->timeout.statement,590 new BranchStmt(591 noLabels,592 "",593 BranchStmt::Break594 )595 }596 )597 );598 }599 600 if(waitfor->orelse.statement) {601 swtch->statements.push_back(602 new CaseStmt(603 noLabels,604 new ConstantExpr( Constant::from_int( -1 ) ),605 {606 waitfor->orelse.statement,607 new BranchStmt(608 noLabels,609 "",610 BranchStmt::Break611 )612 }613 )614 );615 }616 617 stmt->push_back( swtch );618 408 } 619 409 }; -
src/GenPoly/Box.cc
r74bba15 raf58ee0 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
r74bba15 raf58ee0 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
r74bba15 raf58ee0 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
r74bba15 raf58ee0 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
r74bba15 raf58ee0 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
r74bba15 raf58ee0 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
r74bba15 raf58ee0 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
r74bba15 raf58ee0 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
r74bba15 raf58ee0 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/Parser/StatementNode.cc
r74bba15 raf58ee0 234 234 target, 235 235 maybeMoveBuild<Statement >( stmt ), 236 notZeroExpr( maybeMoveBuild<Expression>( when ))236 maybeMoveBuild<Expression>( when ) 237 237 }); 238 238 … … 250 250 delete targetExpr; 251 251 252 node->clauses. insert( node->clauses.begin(),WaitForStmt::Clause{252 node->clauses.push_back( WaitForStmt::Clause{ 253 253 std::move( target ), 254 254 maybeMoveBuild<Statement >( stmt ), 255 notZeroExpr( maybeMoveBuild<Expression>( when ))255 maybeMoveBuild<Expression>( when ) 256 256 }); 257 257 … … 265 265 node->timeout.time = maybeMoveBuild<Expression>( timeout ); 266 266 node->timeout.statement = maybeMoveBuild<Statement >( stmt ); 267 node->timeout.condition = notZeroExpr( maybeMoveBuild<Expression>( when ));267 node->timeout.condition = maybeMoveBuild<Expression>( when ); 268 268 } 269 269 else { 270 node->orelse.statement = maybeMoveBuild<Statement >( stmt );271 node->orelse.condition = notZeroExpr( maybeMoveBuild<Expression>( when ));270 node->orelse.statement = maybeMoveBuild<Statement >( stmt ); 271 node->orelse.condition = maybeMoveBuild<Expression>( when ); 272 272 } 273 273 … … 280 280 node->timeout.time = maybeMoveBuild<Expression>( timeout ); 281 281 node->timeout.statement = maybeMoveBuild<Statement >( stmt ); 282 node->timeout.condition = notZeroExpr( maybeMoveBuild<Expression>( when ));282 node->timeout.condition = maybeMoveBuild<Expression>( when ); 283 283 284 284 node->orelse.statement = maybeMoveBuild<Statement >( else_stmt ); 285 node->orelse.condition = notZeroExpr( maybeMoveBuild<Expression>( else_when ));285 node->orelse.condition = maybeMoveBuild<Expression>( else_when ); 286 286 287 287 return node; 288 288 } 289 290 // WaitForStmt::Target build_waitfor( const std::string * name, ExpressionNode * arguments ) { 291 // return WaitForStmt::Clause{ 292 293 // }; 294 // } 289 295 290 296 Statement *build_compound( StatementNode *first ) { -
src/Parser/parserutility.cc
r74bba15 raf58ee0 29 29 30 30 Expression *notZeroExpr( Expression *orig ) { 31 if( !orig ) return nullptr;32 31 UntypedExpr *comparison = new UntypedExpr( new NameExpr( "?!=?" ) ); 33 32 comparison->get_args().push_back( orig ); -
src/ResolvExpr/AlternativeFinder.cc
r74bba15 raf58ee0 144 144 expr->get_result()->accept( global_renamer ); 145 145 } 146 147 void referenceToRvalueConversion( Expression *& expr ) { 148 if ( dynamic_cast< ReferenceType * >( expr->get_result() ) ) { 149 // cast away reference from expr 150 expr = new CastExpr( expr, expr->get_result()->stripReferences()->clone() ); 151 } 152 } 146 153 } // namespace 147 148 void referenceToRvalueConversion( Expression *& expr ) {149 if ( dynamic_cast< ReferenceType * >( expr->get_result() ) ) {150 // cast away reference from expr151 expr = new CastExpr( expr, expr->get_result()->stripReferences()->clone() );152 }153 }154 154 155 155 template< typename InputIterator, typename OutputIterator > -
src/ResolvExpr/AlternativeFinder.h
r74bba15 raf58ee0 50 50 const SymTab::Indexer &get_indexer() const { return indexer; } 51 51 const TypeEnvironment &get_environ() const { return env; } 52 53 /// Runs a new alternative finder on each element in [begin, end)54 /// and writes each alternative finder to out.55 template< typename InputIterator, typename OutputIterator >56 void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );57 52 private: 58 53 virtual void visit( ApplicationExpr *applicationExpr ); … … 86 81 virtual void visit( StmtExpr *stmtExpr ); 87 82 virtual void visit( UntypedInitExpr *initExpr ); 83 /// Runs a new alternative finder on each element in [begin, end) 84 /// and writes each alternative finder to out. 85 template< typename InputIterator, typename OutputIterator > 86 void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out ); 88 87 89 88 /// Adds alternatives for anonymous members … … 109 108 110 109 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env ); 111 void referenceToRvalueConversion( Expression *& expr );112 110 113 111 template< typename InputIterator, typename OutputIterator > -
src/ResolvExpr/Resolver.cc
r74bba15 raf58ee0 40 40 #include "SynTree/Visitor.h" // for acceptAll, maybeAccept 41 41 #include "typeops.h" // for extractResultType 42 #include "Unify.h" // for unify43 42 44 43 using namespace std; … … 72 71 void previsit( ThrowStmt *throwStmt ); 73 72 void previsit( CatchStmt *catchStmt ); 74 void previsit( WaitForStmt * stmt );75 73 76 74 void previsit( SingleInit *singleInit ); … … 95 93 PassVisitor<Resolver> resolver; 96 94 acceptAll( translationUnit, resolver ); 97 }98 99 void resolveDecl( Declaration * decl, const SymTab::Indexer &indexer ) {100 PassVisitor<Resolver> resolver( indexer );101 maybeAccept( decl, resolver );102 95 } 103 96 … … 123 116 } 124 117 125 Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {126 TypeEnvironment env;127 AlternativeFinder finder( indexer, env );128 finder.find( untyped );129 #if 0130 if ( finder.get_alternatives().size() != 1 ) {131 std::cout << "untyped expr is ";132 untyped->print( std::cout );133 std::cout << std::endl << "alternatives are:";134 for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {135 i->print( std::cout );136 } // for137 } // if138 #endif139 assertf( finder.get_alternatives().size() == 1, "findSingleExpression: must have exactly one alternative at the end." );140 Alternative &choice = finder.get_alternatives().front();141 Expression *newExpr = choice.expr->clone();142 finishExpr( newExpr, choice.env );143 return newExpr;144 }145 146 118 namespace { 119 Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) { 120 TypeEnvironment env; 121 AlternativeFinder finder( indexer, env ); 122 finder.find( untyped ); 123 #if 0 124 if ( finder.get_alternatives().size() != 1 ) { 125 std::cout << "untyped expr is "; 126 untyped->print( std::cout ); 127 std::cout << std::endl << "alternatives are:"; 128 for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) { 129 i->print( std::cout ); 130 } // for 131 } // if 132 #endif 133 assertf( finder.get_alternatives().size() == 1, "findSingleExpression: must have exactly one alternative at the end." ); 134 Alternative &choice = finder.get_alternatives().front(); 135 Expression *newExpr = choice.expr->clone(); 136 finishExpr( newExpr, choice.env ); 137 return newExpr; 138 } 139 147 140 bool isIntegralType( Type *type ) { 148 141 if ( dynamic_cast< EnumInstType * >( type ) ) { … … 398 391 } 399 392 400 inline void resolveAsIf( Expression *& expr, SymTab::Indexer & indexer ) {401 if( !expr ) return;402 Expression * newExpr = findSingleExpression( expr, indexer );403 delete expr;404 expr = newExpr;405 }406 407 inline void resolveAsType( Expression *& expr, Type * type, SymTab::Indexer & indexer ) {408 if( !expr ) return;409 Expression * newExpr = findSingleExpression( new CastExpr( expr, type ), indexer );410 delete expr;411 expr = newExpr;412 }413 414 template< typename iterator_t >415 inline bool advance_to_mutex( iterator_t & it, const iterator_t & end ) {416 while( it != end && !(*it)->get_type()->get_mutex() ) {417 it++;418 }419 420 return it != end;421 }422 423 void Resolver::previsit( WaitForStmt * stmt ) {424 visit_children = false;425 426 // Resolve all clauses first427 for( auto& clause : stmt->clauses ) {428 429 TypeEnvironment env;430 AlternativeFinder funcFinder( indexer, env );431 432 // Find all alternatives for a function in canonical form433 funcFinder.findWithAdjustment( clause.target.function );434 435 if ( funcFinder.get_alternatives().empty() ) {436 stringstream ss;437 ss << "Use of undeclared indentifier '";438 ss << strict_dynamic_cast<NameExpr*>( clause.target.function )->name;439 ss << "' in call to waitfor";440 throw SemanticError( ss.str() );441 }442 443 // Find all alternatives for all arguments in canonical form444 std::list< AlternativeFinder > argAlternatives;445 funcFinder.findSubExprs( clause.target.arguments.begin(), clause.target.arguments.end(), back_inserter( argAlternatives ) );446 447 // List all combinations of arguments448 std::list< AltList > possibilities;449 combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) );450 451 AltList func_candidates;452 std::vector< AltList > args_candidates;453 454 // For every possible function :455 // try matching the arguments to the parameters456 // not the other way around because we have more arguments than parameters457 SemanticError errors;458 for ( Alternative & func : funcFinder.get_alternatives() ) {459 try {460 PointerType * pointer = dynamic_cast< PointerType* >( func.expr->get_result()->stripReferences() );461 if( !pointer ) {462 throw SemanticError( "candidate not viable: not a pointer type\n", func.expr->get_result() );463 }464 465 FunctionType * function = dynamic_cast< FunctionType* >( pointer->get_base() );466 if( !function ) {467 throw SemanticError( "candidate not viable: not a function type\n", pointer->get_base() );468 }469 470 471 {472 auto param = function->parameters.begin();473 auto param_end = function->parameters.end();474 475 if( !advance_to_mutex( param, param_end ) ) {476 throw SemanticError("candidate function not viable: no mutex parameters\n", function);477 }478 }479 480 Alternative newFunc( func );481 // Strip reference from function482 referenceToRvalueConversion( newFunc.expr );483 484 // For all the set of arguments we have try to match it with the parameter of the current function alternative485 for ( auto & argsList : possibilities ) {486 487 try {488 // Declare data structures need for resolution489 OpenVarSet openVars;490 AssertionSet resultNeed, resultHave;491 TypeEnvironment resultEnv;492 493 // Load type variables from arguemnts into one shared space494 simpleCombineEnvironments( argsList.begin(), argsList.end(), resultEnv );495 496 // Make sure we don't widen any existing bindings497 for ( auto & i : resultEnv ) {498 i.allowWidening = false;499 }500 501 // Find any unbound type variables502 resultEnv.extractOpenVars( openVars );503 504 auto param = function->parameters.begin();505 auto param_end = function->parameters.end();506 507 // For every arguments of its set, check if it matches one of the parameter508 // The order is important509 for( auto & arg : argsList ) {510 511 // Ignore non-mutex arguments512 if( !advance_to_mutex( param, param_end ) ) {513 // We ran out of parameters but still have arguments514 // this function doesn't match515 throw SemanticError("candidate function not viable: too many mutex arguments\n", function);516 }517 518 // Check if the argument matches the parameter type in the current scope519 if( ! unify( (*param)->get_type(), arg.expr->get_result(), resultEnv, resultNeed, resultHave, openVars, this->indexer ) ) {520 // Type doesn't match521 stringstream ss;522 ss << "candidate function not viable: no known convertion from '";523 arg.expr->get_result()->print( ss );524 ss << "' to '";525 (*param)->get_type()->print( ss );526 ss << "'\n";527 throw SemanticError(ss.str(), function);528 }529 530 param++;531 }532 533 // All arguments match !534 535 // Check if parameters are missing536 if( advance_to_mutex( param, param_end ) ) {537 // We ran out of arguments but still have parameters left538 // this function doesn't match539 throw SemanticError("candidate function not viable: too few mutex arguments\n", function);540 }541 542 // All parameters match !543 544 // Finish the expressions to tie in the proper environments545 finishExpr( newFunc.expr, resultEnv );546 for( Alternative & alt : argsList ) {547 finishExpr( alt.expr, resultEnv );548 }549 550 // This is a match store it and save it for later551 func_candidates.push_back( newFunc );552 args_candidates.push_back( argsList );553 554 }555 catch( SemanticError &e ) {556 errors.append( e );557 }558 }559 }560 catch( SemanticError &e ) {561 errors.append( e );562 }563 }564 565 // Make sure we got the right number of arguments566 if( func_candidates.empty() ) { SemanticError top( "No alternatives for function in call to waitfor" ); top.append( errors ); throw top; }567 if( args_candidates.empty() ) { SemanticError top( "No alternatives for arguments in call to waitfor" ); top.append( errors ); throw top; }568 if( func_candidates.size() > 1 ) { SemanticError top( "Ambiguous function in call to waitfor" ); top.append( errors ); throw top; }569 if( args_candidates.size() > 1 ) { SemanticError top( "Ambiguous arguments in call to waitfor" ); top.append( errors ); throw top; }570 571 572 // Swap the results from the alternative with the unresolved values.573 // Alternatives will handle deletion on destruction574 std::swap( clause.target.function, func_candidates.front().expr );575 for( auto arg_pair : group_iterate( clause.target.arguments, args_candidates.front() ) ) {576 std::swap ( std::get<0>( arg_pair), std::get<1>( arg_pair).expr );577 }578 579 // Resolve the conditions as if it were an IfStmt580 // Resolve the statments normally581 resolveAsIf( clause.condition, this->indexer );582 clause.statement->accept( *visitor );583 }584 585 586 if( stmt->timeout.statement ) {587 // Resolve the timeout as an size_t for now588 // Resolve the conditions as if it were an IfStmt589 // Resolve the statments normally590 resolveAsType( stmt->timeout.time, new BasicType( noQualifiers, BasicType::LongLongUnsignedInt ), this->indexer );591 resolveAsIf ( stmt->timeout.condition, this->indexer );592 stmt->timeout.statement->accept( *visitor );593 }594 595 if( stmt->orelse.statement ) {596 // Resolve the conditions as if it were an IfStmt597 // Resolve the statments normally598 resolveAsIf( stmt->orelse.condition, this->indexer );599 stmt->orelse.statement->accept( *visitor );600 }601 }602 603 393 template< typename T > 604 394 bool isCharType( T t ) { -
src/ResolvExpr/Resolver.h
r74bba15 raf58ee0 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 31 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ); 33 32 Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ); 34 Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer );35 33 void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer ); 36 34 void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer ); -
src/ResolvExpr/TypeEnvironment.cc
r74bba15 raf58ee0 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
r74bba15 raf58ee0 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
r74bba15 raf58ee0 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
r74bba15 raf58ee0 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
r74bba15 raf58ee0 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
r74bba15 raf58ee0 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; … … 307 307 mangleName << "V"; 308 308 } // if 309 if ( type->get_mutex() ) {310 mangleName << "M";311 } // if312 309 // Removed due to restrict not affecting function compatibility in GCC 313 310 // if ( type->get_isRestrict() ) { … … 315 312 // } // if 316 313 if ( type->get_lvalue() ) { 317 // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues318 314 mangleName << "L"; 319 } 315 } // if 320 316 if ( type->get_atomic() ) { 321 317 mangleName << "A"; -
src/SymTab/Validate.cc
r74bba15 raf58ee0 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/BaseSyntaxNode.h
r74bba15 raf58ee0 26 26 27 27 virtual void accept( Visitor & v ) = 0; 28 virtual void print( std::ostream & os, int indent = 0 ) const = 0;28 virtual void print( std::ostream & os, int indent = 0 ) const = 0; 29 29 }; 30 31 std::ostream & operator<<( std::ostream & out, const BaseSyntaxNode * node );32 30 33 31 // Local Variables: // -
src/SynTree/CompoundStmt.cc
r74bba15 raf58ee0 29 29 30 30 CompoundStmt::CompoundStmt( std::list<Label> labels ) : Statement( labels ) { 31 }32 33 CompoundStmt::CompoundStmt( std::list<Statement *> stmts ) : Statement( noLabels ), kids( stmts ) {34 31 } 35 32 -
src/SynTree/Constant.cc
r74bba15 raf58ee0 32 32 Constant Constant::from_bool( bool b ) { 33 33 return Constant( new BasicType( Type::Qualifiers(), BasicType::Bool ), b ? "1" : "0" , (unsigned long long int)b ); 34 }35 36 Constant Constant::from_char( char c ) {37 return Constant( new BasicType( Type::Qualifiers(), BasicType::Char ), std::to_string( c ), (unsigned long long int)c );38 34 } 39 35 -
src/SynTree/Constant.h
r74bba15 raf58ee0 40 40 /// generates a boolean constant of the given bool 41 41 static Constant from_bool( bool b ); 42 /// generates a char constant of the given char43 static Constant from_char( char c );44 42 /// generates an integer constant of the given int 45 43 static Constant from_int( int i ); -
src/SynTree/Declaration.cc
r74bba15 raf58ee0 59 59 } 60 60 61 std::ostream & operator<<( std::ostream & out, const Declaration * decl ) { 62 if ( decl ){ 63 decl->print( out ); 64 } else { 65 out << "nullptr"; 66 } 67 return out; 68 } 69 61 70 62 71 AsmDecl::AsmDecl( AsmStmt *stmt ) : Declaration( "", Type::StorageClasses(), LinkageSpec::C ), stmt( stmt ) { -
src/SynTree/Declaration.h
r74bba15 raf58ee0 62 62 void fixUniqueId( void ); 63 63 virtual Declaration *clone() const = 0; 64 virtual void accept( Visitor &v ) override= 0;64 virtual void accept( Visitor &v ) = 0; 65 65 virtual Declaration *acceptMutator( Mutator &m ) = 0; 66 virtual void print( std::ostream &os, int indent = 0 ) const override= 0;66 virtual void print( std::ostream &os, int indent = 0 ) const = 0; 67 67 virtual void printShort( std::ostream &os, int indent = 0 ) const = 0; 68 68 … … 106 106 //void set_functionSpecifiers( Type::FuncSpecifiers newValue ) { fs = newValue; } 107 107 108 virtual DeclarationWithType *clone() const override= 0;109 virtual DeclarationWithType *acceptMutator( Mutator &m ) override= 0;108 virtual DeclarationWithType *clone() const = 0; 109 virtual DeclarationWithType *acceptMutator( Mutator &m ) = 0; 110 110 111 111 virtual Type * get_type() const = 0; … … 128 128 virtual ~ObjectDecl(); 129 129 130 virtual Type * get_type() const override{ return type; }131 virtual void set_type(Type *newType) override{ type = newType; }130 virtual Type * get_type() const { return type; } 131 virtual void set_type(Type *newType) { type = newType; } 132 132 133 133 Initializer *get_init() const { return init; } … … 139 139 static ObjectDecl * newObject( const std::string & name, Type * type, Initializer * init ); 140 140 141 virtual ObjectDecl *clone() const override{ return new ObjectDecl( *this ); }142 virtual void accept( Visitor &v ) override{ v.visit( this ); }143 virtual DeclarationWithType *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }144 virtual void print( std::ostream &os, int indent = 0 ) const override;145 virtual void printShort( std::ostream &os, int indent = 0 ) const override;141 virtual ObjectDecl *clone() const { return new ObjectDecl( *this ); } 142 virtual void accept( Visitor &v ) { v.visit( this ); } 143 virtual DeclarationWithType *acceptMutator( Mutator &m ) { return m.mutate( this ); } 144 virtual void print( std::ostream &os, int indent = 0 ) const; 145 virtual void printShort( std::ostream &os, int indent = 0 ) const; 146 146 }; 147 147 … … 157 157 virtual ~FunctionDecl(); 158 158 159 virtual Type * get_type() const override{ return type; }160 virtual void set_type(Type * t) override{ type = strict_dynamic_cast< FunctionType* >( t ); }159 Type * get_type() const { return type; } 160 virtual void set_type(Type * t) { type = strict_dynamic_cast< FunctionType* >( t ); } 161 161 162 162 FunctionType * get_functionType() const { return type; } … … 165 165 void set_statements( CompoundStmt *newValue ) { statements = newValue; } 166 166 167 virtual FunctionDecl *clone() const override{ return new FunctionDecl( *this ); }168 virtual void accept( Visitor &v ) override{ v.visit( this ); }169 virtual DeclarationWithType *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }170 virtual void print( std::ostream &os, int indent = 0 ) const override;171 virtual void printShort( std::ostream &os, int indent = 0 ) const override;167 virtual FunctionDecl *clone() const { return new FunctionDecl( *this ); } 168 virtual void accept( Visitor &v ) { v.visit( this ); } 169 virtual DeclarationWithType *acceptMutator( Mutator &m ) { return m.mutate( this ); } 170 virtual void print( std::ostream &os, int indent = 0 ) const; 171 virtual void printShort( std::ostream &os, int indent = 0 ) const; 172 172 }; 173 173 … … 190 190 virtual std::string typeString() const = 0; 191 191 192 virtual NamedTypeDecl *clone() const override= 0;193 virtual void print( std::ostream &os, int indent = 0 ) const override;194 virtual void printShort( std::ostream &os, int indent = 0 ) const override;192 virtual NamedTypeDecl *clone() const = 0; 193 virtual void print( std::ostream &os, int indent = 0 ) const; 194 virtual void printShort( std::ostream &os, int indent = 0 ) const; 195 195 }; 196 196 … … 227 227 TypeDecl * set_sized( bool newValue ) { sized = newValue; return this; } 228 228 229 virtual std::string typeString() const override;229 virtual std::string typeString() const; 230 230 virtual std::string genTypeString() const; 231 231 232 virtual TypeDecl *clone() const override{ return new TypeDecl( *this ); }233 virtual void accept( Visitor &v ) override{ v.visit( this ); }234 virtual Declaration *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }235 virtual void print( std::ostream &os, int indent = 0 ) const override;232 virtual TypeDecl *clone() const { return new TypeDecl( *this ); } 233 virtual void accept( Visitor &v ) { v.visit( this ); } 234 virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); } 235 virtual void print( std::ostream &os, int indent = 0 ) const; 236 236 237 237 private: … … 245 245 TypedefDecl( const TypedefDecl &other ) : Parent( other ) {} 246 246 247 virtual std::string typeString() const override;248 249 virtual TypedefDecl *clone() const override{ return new TypedefDecl( *this ); }250 virtual void accept( Visitor &v ) override{ v.visit( this ); }251 virtual Declaration *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }247 virtual std::string typeString() const; 248 249 virtual TypedefDecl *clone() const { return new TypedefDecl( *this ); } 250 virtual void accept( Visitor &v ) { v.visit( this ); } 251 virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); } 252 252 private: 253 253 }; … … 274 274 AggregateDecl * set_body( bool body ) { AggregateDecl::body = body; return this; } 275 275 276 virtual void print( std::ostream &os, int indent = 0 ) const override;277 virtual void printShort( std::ostream &os, int indent = 0 ) const override;276 virtual void print( std::ostream &os, int indent = 0 ) const; 277 virtual void printShort( std::ostream &os, int indent = 0 ) const; 278 278 protected: 279 279 virtual std::string typeString() const = 0; … … 290 290 bool is_thread() { return kind == DeclarationNode::Thread; } 291 291 292 virtual StructDecl *clone() const override{ return new StructDecl( *this ); }293 virtual void accept( Visitor &v ) override{ v.visit( this ); }294 virtual Declaration *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }292 virtual StructDecl *clone() const { return new StructDecl( *this ); } 293 virtual void accept( Visitor &v ) { v.visit( this ); } 294 virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); } 295 295 private: 296 296 DeclarationNode::Aggregate kind; 297 virtual std::string typeString() const override;297 virtual std::string typeString() const; 298 298 }; 299 299 … … 304 304 UnionDecl( const UnionDecl &other ) : Parent( other ) {} 305 305 306 virtual UnionDecl *clone() const override{ return new UnionDecl( *this ); }307 virtual void accept( Visitor &v ) override{ v.visit( this ); }308 virtual Declaration *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }309 private: 310 virtual std::string typeString() const override;306 virtual UnionDecl *clone() const { return new UnionDecl( *this ); } 307 virtual void accept( Visitor &v ) { v.visit( this ); } 308 virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); } 309 private: 310 virtual std::string typeString() const; 311 311 }; 312 312 … … 317 317 EnumDecl( const EnumDecl &other ) : Parent( other ) {} 318 318 319 virtual EnumDecl *clone() const override{ return new EnumDecl( *this ); }320 virtual void accept( Visitor &v ) override{ v.visit( this ); }321 virtual Declaration *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }322 private: 323 virtual std::string typeString() const override;319 virtual EnumDecl *clone() const { return new EnumDecl( *this ); } 320 virtual void accept( Visitor &v ) { v.visit( this ); } 321 virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); } 322 private: 323 virtual std::string typeString() const; 324 324 }; 325 325 … … 332 332 TraitDecl( const TraitDecl &other ) : Parent( other ) {} 333 333 334 virtual TraitDecl *clone() const override{ return new TraitDecl( *this ); }335 virtual void accept( Visitor &v ) override{ v.visit( this ); }336 virtual Declaration *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }337 private: 338 virtual std::string typeString() const override;334 virtual TraitDecl *clone() const { return new TraitDecl( *this ); } 335 virtual void accept( Visitor &v ) { v.visit( this ); } 336 virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); } 337 private: 338 virtual std::string typeString() const; 339 339 }; 340 340 … … 350 350 void set_stmt( AsmStmt *newValue ) { stmt = newValue; } 351 351 352 virtual AsmDecl *clone() const override { return new AsmDecl( *this ); } 353 virtual void accept( Visitor &v ) override { v.visit( this ); } 354 virtual AsmDecl *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 355 virtual void print( std::ostream &os, int indent = 0 ) const override; 356 virtual void printShort( std::ostream &os, int indent = 0 ) const override; 357 }; 358 352 virtual AsmDecl *clone() const { return new AsmDecl( *this ); } 353 virtual void accept( Visitor &v ) { v.visit( this ); } 354 virtual AsmDecl *acceptMutator( Mutator &m ) { return m.mutate( this ); } 355 virtual void print( std::ostream &os, int indent = 0 ) const; 356 virtual void printShort( std::ostream &os, int indent = 0 ) const; 357 }; 358 359 std::ostream & operator<<( std::ostream & out, const Declaration * decl ); 359 360 std::ostream & operator<<( std::ostream & os, const TypeDecl::Data & data ); 360 361 -
src/SynTree/Expression.cc
r74bba15 raf58ee0 741 741 } 742 742 743 744 std::ostream & operator<<( std::ostream & out, const Expression * expr ) { 745 if ( expr ) { 746 expr->print( out ); 747 } else { 748 out << "nullptr"; 749 } 750 return out; 751 } 752 743 753 // Local Variables: // 744 754 // tab-width: 4 // -
src/SynTree/Expression.h
r74bba15 raf58ee0 821 821 }; 822 822 823 824 std::ostream & operator<<( std::ostream & out, const Expression * expr ); 825 823 826 // Local Variables: // 824 827 // tab-width: 4 // -
src/SynTree/Initializer.cc
r74bba15 raf58ee0 137 137 } 138 138 139 std::ostream & operator<<( std::ostream & out, const Initializer * init ) { 140 if ( init ) { 141 init->print( out ); 142 } else { 143 out << "nullptr"; 144 } 145 return out; 146 } 147 148 std::ostream & operator<<( std::ostream & out, const Designation * des ) { 149 if ( des ) { 150 des->print( out ); 151 } else { 152 out << "nullptr"; 153 } 154 return out; 155 } 156 139 157 // Local Variables: // 140 158 // tab-width: 4 // -
src/SynTree/Initializer.h
r74bba15 raf58ee0 38 38 39 39 virtual Designation * clone() const { return new Designation( *this ); }; 40 virtual void accept( Visitor &v ) override{ v.visit( this ); }40 virtual void accept( Visitor &v ) { v.visit( this ); } 41 41 virtual Designation * acceptMutator( Mutator &m ) { return m.mutate( this ); } 42 virtual void print( std::ostream &os, int indent = 0 ) const override;42 virtual void print( std::ostream &os, int indent = 0 ) const; 43 43 }; 44 44 … … 55 55 56 56 virtual Initializer *clone() const = 0; 57 virtual void accept( Visitor &v ) override= 0;57 virtual void accept( Visitor &v ) = 0; 58 58 virtual Initializer *acceptMutator( Mutator &m ) = 0; 59 virtual void print( std::ostream &os, int indent = 0 ) const override= 0;59 virtual void print( std::ostream &os, int indent = 0 ) const = 0; 60 60 private: 61 61 bool maybeConstructed; … … 75 75 void set_value( Expression *newValue ) { value = newValue; } 76 76 77 virtual SingleInit *clone() const override{ return new SingleInit( *this); }78 virtual void accept( Visitor &v ) override{ v.visit( this ); }79 virtual Initializer *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }80 virtual void print( std::ostream &os, int indent = 0 ) const override;77 virtual SingleInit *clone() const { return new SingleInit( *this); } 78 virtual void accept( Visitor &v ) { v.visit( this ); } 79 virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); } 80 virtual void print( std::ostream &os, int indent = 0 ) const; 81 81 }; 82 82 … … 103 103 const_iterator end() const { return initializers.end(); } 104 104 105 virtual ListInit *clone() const override{ return new ListInit( *this ); }106 virtual void accept( Visitor &v ) override{ v.visit( this ); }107 virtual Initializer *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }108 virtual void print( std::ostream &os, int indent = 0 ) const override;105 virtual ListInit *clone() const { return new ListInit( *this ); } 106 virtual void accept( Visitor &v ) { v.visit( this ); } 107 virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); } 108 virtual void print( std::ostream &os, int indent = 0 ) const; 109 109 }; 110 110 … … 129 129 Initializer * get_init() const { return init; } 130 130 131 ConstructorInit *clone() const override{ return new ConstructorInit( *this ); }132 virtual void accept( Visitor &v ) override{ v.visit( this ); }133 virtual Initializer *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }134 virtual void print( std::ostream &os, int indent = 0 ) const override;131 ConstructorInit *clone() const { return new ConstructorInit( *this ); } 132 virtual void accept( Visitor &v ) { v.visit( this ); } 133 virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); } 134 virtual void print( std::ostream &os, int indent = 0 ) const; 135 135 136 136 private: … … 140 140 }; 141 141 142 std::ostream & operator<<( std::ostream & out, const Initializer * init ); 143 std::ostream & operator<<( std::ostream & out, const Designation * des ); 144 142 145 // Local Variables: // 143 146 // tab-width: 4 // -
src/SynTree/Statement.cc
r74bba15 raf58ee0 168 168 } 169 169 170 SwitchStmt::SwitchStmt( std::list<Label> labels, Expression * condition, conststd::list<Statement *> &statements ):170 SwitchStmt::SwitchStmt( std::list<Label> labels, Expression * condition, std::list<Statement *> &statements ): 171 171 Statement( labels ), condition( condition ), statements( statements ) { 172 172 } … … 196 196 } 197 197 198 CaseStmt::CaseStmt( std::list<Label> labels, Expression *condition, conststd::list<Statement *> &statements, bool deflt ) throw ( SemanticError ) :198 CaseStmt::CaseStmt( std::list<Label> labels, Expression *condition, std::list<Statement *> &statements, bool deflt ) throw ( SemanticError ) : 199 199 Statement( labels ), condition( condition ), stmts( statements ), _isDefault( deflt ) { 200 200 if ( isDefault() && condition != 0 ) … … 497 497 } 498 498 499 std::ostream & operator<<( std::ostream & out, const Statement * statement ) { 500 if ( statement ) { 501 statement->print( out ); 502 } else { 503 out << "nullptr"; 504 } 505 return out; 506 } 507 499 508 // Local Variables: // 500 509 // tab-width: 4 // -
src/SynTree/Statement.h
r74bba15 raf58ee0 44 44 45 45 virtual Statement *clone() const = 0; 46 virtual void accept( Visitor &v ) override= 0;46 virtual void accept( Visitor &v ) = 0; 47 47 virtual Statement *acceptMutator( Mutator &m ) = 0; 48 virtual void print( std::ostream &os, int indent = 0 ) const override;48 virtual void print( std::ostream &os, int indent = 0 ) const; 49 49 }; 50 50 … … 54 54 55 55 CompoundStmt( std::list<Label> labels ); 56 CompoundStmt( std::list<Statement *> stmts );57 56 CompoundStmt( const CompoundStmt &other ); 58 57 virtual ~CompoundStmt(); … … 62 61 void push_front( Statement * stmt ) { kids.push_front( stmt ); } 63 62 64 virtual CompoundStmt *clone() const override{ return new CompoundStmt( *this ); }65 virtual void accept( Visitor &v ) override{ v.visit( this ); }66 virtual CompoundStmt *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }67 virtual void print( std::ostream &os, int indent = 0 ) const override;63 virtual CompoundStmt *clone() const { return new CompoundStmt( *this ); } 64 virtual void accept( Visitor &v ) { v.visit( this ); } 65 virtual CompoundStmt *acceptMutator( Mutator &m ) { return m.mutate( this ); } 66 virtual void print( std::ostream &os, int indent = 0 ) const; 68 67 }; 69 68 … … 73 72 NullStmt( std::list<Label> labels ); 74 73 75 virtual NullStmt *clone() const override{ return new NullStmt( *this ); }76 virtual void accept( Visitor &v ) override{ v.visit( this ); }77 virtual NullStmt *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }78 virtual void print( std::ostream &os, int indent = 0 ) const override;74 virtual NullStmt *clone() const { return new NullStmt( *this ); } 75 virtual void accept( Visitor &v ) { v.visit( this ); } 76 virtual NullStmt *acceptMutator( Mutator &m ) { return m.mutate( this ); } 77 virtual void print( std::ostream &os, int indent = 0 ) const; 79 78 }; 80 79 … … 90 89 void set_expr( Expression *newValue ) { expr = newValue; } 91 90 92 virtual ExprStmt *clone() const override{ return new ExprStmt( *this ); }93 virtual void accept( Visitor &v ) override{ v.visit( this ); }94 virtual Statement *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }95 virtual void print( std::ostream &os, int indent = 0 ) const override;91 virtual ExprStmt *clone() const { return new ExprStmt( *this ); } 92 virtual void accept( Visitor &v ) { v.visit( this ); } 93 virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); } 94 virtual void print( std::ostream &os, int indent = 0 ) const; 96 95 }; 97 96 … … 147 146 void set_elsePart( Statement *newValue ) { elsePart = newValue; } 148 147 149 virtual IfStmt *clone() const override{ return new IfStmt( *this ); }150 virtual void accept( Visitor &v ) override{ v.visit( this ); }151 virtual Statement *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }152 virtual void print( std::ostream &os, int indent = 0 ) const override;148 virtual IfStmt *clone() const { return new IfStmt( *this ); } 149 virtual void accept( Visitor &v ) { v.visit( this ); } 150 virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); } 151 virtual void print( std::ostream &os, int indent = 0 ) const; 153 152 }; 154 153 … … 158 157 std::list<Statement *> statements; 159 158 160 SwitchStmt( std::list<Label> labels, Expression *condition, conststd::list<Statement *> &statements );159 SwitchStmt( std::list<Label> labels, Expression *condition, std::list<Statement *> &statements ); 161 160 SwitchStmt( const SwitchStmt &other ); 162 161 virtual ~SwitchStmt(); … … 167 166 std::list<Statement *> & get_statements() { return statements; } 168 167 169 virtual void accept( Visitor &v ) override{ v.visit( this ); }170 virtual Statement *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }171 172 virtual SwitchStmt *clone() const override{ return new SwitchStmt( *this ); }173 virtual void print( std::ostream &os, int indent = 0 ) const override;168 virtual void accept( Visitor &v ) { v.visit( this ); } 169 virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); } 170 171 virtual SwitchStmt *clone() const { return new SwitchStmt( *this ); } 172 virtual void print( std::ostream &os, int indent = 0 ) const; 174 173 175 174 }; … … 180 179 std::list<Statement *> stmts; 181 180 182 CaseStmt( std::list<Label> labels, Expression *conditions, conststd::list<Statement *> &stmts, bool isdef = false ) throw(SemanticError);181 CaseStmt( std::list<Label> labels, Expression *conditions, std::list<Statement *> &stmts, bool isdef = false ) throw(SemanticError); 183 182 CaseStmt( const CaseStmt &other ); 184 183 virtual ~CaseStmt(); … … 195 194 void set_statements( std::list<Statement *> &newValue ) { stmts = newValue; } 196 195 197 virtual void accept( Visitor &v ) override{ v.visit( this ); }198 virtual Statement *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }199 200 virtual CaseStmt *clone() const override{ return new CaseStmt( *this ); }201 virtual void print( std::ostream &os, int indent = 0 ) const override;196 virtual void accept( Visitor &v ) { v.visit( this ); } 197 virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); } 198 199 virtual CaseStmt *clone() const { return new CaseStmt( *this ); } 200 virtual void print( std::ostream &os, int indent = 0 ) const; 202 201 private: 203 202 bool _isDefault; … … 222 221 void set_isDoWhile( bool newValue ) { isDoWhile = newValue; } 223 222 224 virtual WhileStmt *clone() const override{ return new WhileStmt( *this ); }225 virtual void accept( Visitor &v ) override{ v.visit( this ); }226 virtual Statement *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }227 virtual void print( std::ostream &os, int indent = 0 ) const override;223 virtual WhileStmt *clone() const { return new WhileStmt( *this ); } 224 virtual void accept( Visitor &v ) { v.visit( this ); } 225 virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); } 226 virtual void print( std::ostream &os, int indent = 0 ) const; 228 227 }; 229 228 … … 248 247 void set_body( Statement *newValue ) { body = newValue; } 249 248 250 virtual ForStmt *clone() const override{ return new ForStmt( *this ); }251 virtual void accept( Visitor &v ) override{ v.visit( this ); }252 virtual Statement *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }253 virtual void print( std::ostream &os, int indent = 0 ) const override;249 virtual ForStmt *clone() const { return new ForStmt( *this ); } 250 virtual void accept( Visitor &v ) { v.visit( this ); } 251 virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); } 252 virtual void print( std::ostream &os, int indent = 0 ) const; 254 253 }; 255 254 … … 277 276 const char *get_typename() { return brType[ type ]; } 278 277 279 virtual BranchStmt *clone() const override{ return new BranchStmt( *this ); }280 virtual void accept( Visitor &v ) override{ v.visit( this ); }281 virtual Statement *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }282 virtual void print( std::ostream &os, int indent = 0 ) const override;278 virtual BranchStmt *clone() const { return new BranchStmt( *this ); } 279 virtual void accept( Visitor &v ) { v.visit( this ); } 280 virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); } 281 virtual void print( std::ostream &os, int indent = 0 ) const; 283 282 private: 284 283 static const char *brType[]; … … 296 295 void set_expr( Expression *newValue ) { expr = newValue; } 297 296 298 virtual ReturnStmt *clone() const override{ return new ReturnStmt( *this ); }299 virtual void accept( Visitor &v ) override{ v.visit( this ); }300 virtual Statement *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }301 virtual void print( std::ostream &os, int indent = 0 ) const override;297 virtual ReturnStmt *clone() const { return new ReturnStmt( *this ); } 298 virtual void accept( Visitor &v ) { v.visit( this ); } 299 virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); } 300 virtual void print( std::ostream &os, int indent = 0 ) const; 302 301 }; 303 302 … … 320 319 void set_target( Expression * newTarget ) { target = newTarget; } 321 320 322 virtual ThrowStmt *clone() const override{ return new ThrowStmt( *this ); }323 virtual void accept( Visitor &v ) override{ v.visit( this ); }324 virtual Statement *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }325 virtual void print( std::ostream &os, int indent = 0 ) const override;321 virtual ThrowStmt *clone() const { return new ThrowStmt( *this ); } 322 virtual void accept( Visitor &v ) { v.visit( this ); } 323 virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); } 324 virtual void print( std::ostream &os, int indent = 0 ) const; 326 325 }; 327 326 … … 343 342 void set_finally( FinallyStmt *newValue ) { finallyBlock = newValue; } 344 343 345 virtual TryStmt *clone() const override{ return new TryStmt( *this ); }346 virtual void accept( Visitor &v ) override{ v.visit( this ); }347 virtual Statement *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }348 virtual void print( std::ostream &os, int indent = 0 ) const override;344 virtual TryStmt *clone() const { return new TryStmt( *this ); } 345 virtual void accept( Visitor &v ) { v.visit( this ); } 346 virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); } 347 virtual void print( std::ostream &os, int indent = 0 ) const; 349 348 }; 350 349 … … 371 370 void set_body( Statement *newValue ) { body = newValue; } 372 371 373 virtual CatchStmt *clone() const override{ return new CatchStmt( *this ); }374 virtual void accept( Visitor &v ) override{ v.visit( this ); }375 virtual Statement *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }376 virtual void print( std::ostream &os, int indent = 0 ) const override;372 virtual CatchStmt *clone() const { return new CatchStmt( *this ); } 373 virtual void accept( Visitor &v ) { v.visit( this ); } 374 virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); } 375 virtual void print( std::ostream &os, int indent = 0 ) const; 377 376 }; 378 377 … … 388 387 void set_block( CompoundStmt *newValue ) { block = newValue; } 389 388 390 virtual FinallyStmt *clone() const override{ return new FinallyStmt( *this ); }391 virtual void accept( Visitor &v ) override{ v.visit( this ); }392 virtual Statement *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }393 virtual void print( std::ostream &os, int indent = 0 ) const override;389 virtual FinallyStmt *clone() const { return new FinallyStmt( *this ); } 390 virtual void accept( Visitor &v ) { v.visit( this ); } 391 virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); } 392 virtual void print( std::ostream &os, int indent = 0 ) const; 394 393 }; 395 394 … … 425 424 } orelse; 426 425 427 virtual WaitForStmt *clone() const override{ return new WaitForStmt( *this ); }428 virtual void accept( Visitor &v ) override{ v.visit( this ); }429 virtual Statement *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }430 virtual void print( std::ostream &os, int indent = 0 ) const override;426 virtual WaitForStmt *clone() const { return new WaitForStmt( *this ); } 427 virtual void accept( Visitor &v ) { v.visit( this ); } 428 virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); } 429 virtual void print( std::ostream &os, int indent = 0 ) const; 431 430 432 431 }; … … 445 444 void set_decl( Declaration *newValue ) { decl = newValue; } 446 445 447 virtual DeclStmt *clone() const override{ return new DeclStmt( *this ); }448 virtual void accept( Visitor &v ) override{ v.visit( this ); }449 virtual Statement *acceptMutator( Mutator &m ) override{ return m.mutate( this ); }450 virtual void print( std::ostream &os, int indent = 0 ) const override;446 virtual DeclStmt *clone() const { return new DeclStmt( *this ); } 447 virtual void accept( Visitor &v ) { v.visit( this ); } 448 virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); } 449 virtual void print( std::ostream &os, int indent = 0 ) const; 451 450 }; 452 451 … … 467 466 void set_callStmt( Statement * newValue ) { callStmt = newValue; } 468 467 469 virtual ImplicitCtorDtorStmt *clone() const override { return new ImplicitCtorDtorStmt( *this ); } 470 virtual void accept( Visitor &v ) override { v.visit( this ); } 471 virtual Statement *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 472 virtual void print( std::ostream &os, int indent = 0 ) const override; 473 }; 468 virtual ImplicitCtorDtorStmt *clone() const { return new ImplicitCtorDtorStmt( *this ); } 469 virtual void accept( Visitor &v ) { v.visit( this ); } 470 virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); } 471 virtual void print( std::ostream &os, int indent = 0 ) const; 472 }; 473 474 475 std::ostream & operator<<( std::ostream & out, const Statement * statement ); 474 476 475 477 // Local Variables: // -
src/SynTree/Type.cc
r74bba15 raf58ee0 99 99 const Type::Qualifiers noQualifiers; 100 100 101 std::ostream & operator<<( std::ostream & out, const Type * type ) { 102 if ( type ) { 103 type->print( out ); 104 } else { 105 out << "nullptr"; 106 } // if 107 return out; 108 } 109 101 110 // Local Variables: // 102 111 // tab-width: 4 // -
src/SynTree/Type.h
r74bba15 raf58ee0 192 192 VoidType( const Type::Qualifiers & tq, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 193 193 194 virtual unsigned size() const override{ return 0; };195 virtual bool isComplete() const override{ return false; }196 197 virtual VoidType *clone() const override{ return new VoidType( *this ); }198 virtual void accept( Visitor & v ) override{ v.visit( this ); }199 virtual Type *acceptMutator( Mutator & m ) override{ return m.mutate( this ); }200 virtual void print( std::ostream & os, int indent = 0 ) const override;194 virtual unsigned size() const { return 0; }; 195 virtual bool isComplete() const { return false; } 196 197 virtual VoidType *clone() const { return new VoidType( *this ); } 198 virtual void accept( Visitor & v ) { v.visit( this ); } 199 virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); } 200 virtual void print( std::ostream & os, int indent = 0 ) const; 201 201 }; 202 202 … … 235 235 void set_kind( Kind newValue ) { kind = newValue; } 236 236 237 virtual BasicType *clone() const override{ return new BasicType( *this ); }238 virtual void accept( Visitor & v ) override{ v.visit( this ); }239 virtual Type *acceptMutator( Mutator & m ) override{ return m.mutate( this ); }240 virtual void print( std::ostream & os, int indent = 0 ) const override;237 virtual BasicType *clone() const { return new BasicType( *this ); } 238 virtual void accept( Visitor & v ) { v.visit( this ); } 239 virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); } 240 virtual void print( std::ostream & os, int indent = 0 ) const; 241 241 242 242 bool isInteger() const; … … 268 268 bool is_array() const { return isStatic || isVarLen || dimension; } 269 269 270 virtual bool isComplete() const override{ return ! isVarLen; }271 272 virtual PointerType *clone() const override{ return new PointerType( *this ); }273 virtual void accept( Visitor & v ) override{ v.visit( this ); }274 virtual Type *acceptMutator( Mutator & m ) override{ return m.mutate( this ); }275 virtual void print( std::ostream & os, int indent = 0 ) const override;270 virtual bool isComplete() const { return ! isVarLen; } 271 272 virtual PointerType *clone() const { return new PointerType( *this ); } 273 virtual void accept( Visitor & v ) { v.visit( this ); } 274 virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); } 275 virtual void print( std::ostream & os, int indent = 0 ) const; 276 276 }; 277 277 … … 296 296 void set_isStatic( bool newValue ) { isStatic = newValue; } 297 297 298 virtual bool isComplete() const override{ return ! isVarLen; }299 300 virtual ArrayType *clone() const override{ return new ArrayType( *this ); }301 virtual void accept( Visitor & v ) override{ v.visit( this ); }302 virtual Type *acceptMutator( Mutator & m ) override{ return m.mutate( this ); }303 virtual void print( std::ostream & os, int indent = 0 ) const override;298 virtual bool isComplete() const { return ! isVarLen; } 299 300 virtual ArrayType *clone() const { return new ArrayType( *this ); } 301 virtual void accept( Visitor & v ) { v.visit( this ); } 302 virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); } 303 virtual void print( std::ostream & os, int indent = 0 ) const; 304 304 }; 305 305 … … 315 315 void set_base( Type *newValue ) { base = newValue; } 316 316 317 virtual int referenceDepth() const override;317 virtual int referenceDepth() const; 318 318 319 319 // Since reference types act like value types, their size is the size of the base. 320 320 // This makes it simple to cast the empty tuple to a reference type, since casts that increase 321 321 // the number of values are disallowed. 322 virtual unsigned size() const override{ return base->size(); }323 324 virtual ReferenceType *clone() const override{ return new ReferenceType( *this ); }325 virtual void accept( Visitor & v ) override{ v.visit( this ); }326 virtual Type *acceptMutator( Mutator & m ) override{ return m.mutate( this ); }327 virtual void print( std::ostream & os, int indent = 0 ) const override;322 virtual unsigned size() const { return base->size(); } 323 324 virtual ReferenceType *clone() const { return new ReferenceType( *this ); } 325 virtual void accept( Visitor & v ) { v.visit( this ); } 326 virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); } 327 virtual void print( std::ostream & os, int indent = 0 ) const; 328 328 }; 329 329 … … 349 349 bool isTtype() const; 350 350 351 virtual FunctionType *clone() const override{ return new FunctionType( *this ); }352 virtual void accept( Visitor & v ) override{ v.visit( this ); }353 virtual Type *acceptMutator( Mutator & m ) override{ return m.mutate( this ); }354 virtual void print( std::ostream & os, int indent = 0 ) const override;351 virtual FunctionType *clone() const { return new FunctionType( *this ); } 352 virtual void accept( Visitor & v ) { v.visit( this ); } 353 virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); } 354 virtual void print( std::ostream & os, int indent = 0 ) const; 355 355 }; 356 356 … … 371 371 void set_hoistType( bool newValue ) { hoistType = newValue; } 372 372 373 virtual ReferenceToType *clone() const override= 0;374 virtual void accept( Visitor & v ) override= 0;375 virtual Type *acceptMutator( Mutator & m ) override= 0;376 virtual void print( std::ostream & os, int indent = 0 ) const override;373 virtual ReferenceToType *clone() const = 0; 374 virtual void accept( Visitor & v ) = 0; 375 virtual Type *acceptMutator( Mutator & m ) = 0; 376 virtual void print( std::ostream & os, int indent = 0 ) const; 377 377 378 378 virtual void lookup( __attribute__((unused)) const std::string & name, __attribute__((unused)) std::list< Declaration* > & foundDecls ) const {} … … 398 398 std::list<TypeDecl*> * get_baseParameters(); 399 399 400 virtual bool isComplete() const override;400 virtual bool isComplete() const; 401 401 402 402 /// Looks up the members of this struct named "name" and places them into "foundDecls". 403 403 /// Clones declarations into "foundDecls", caller responsible for freeing 404 void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const override;405 406 virtual StructInstType *clone() const override{ return new StructInstType( *this ); }407 virtual void accept( Visitor & v ) override{ v.visit( this ); }408 virtual Type *acceptMutator( Mutator & m ) override{ return m.mutate( this ); }409 410 virtual void print( std::ostream & os, int indent = 0 ) const override;404 void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const; 405 406 virtual StructInstType *clone() const { return new StructInstType( *this ); } 407 virtual void accept( Visitor & v ) { v.visit( this ); } 408 virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); } 409 410 virtual void print( std::ostream & os, int indent = 0 ) const; 411 411 private: 412 virtual std::string typeString() const override;412 virtual std::string typeString() const; 413 413 }; 414 414 … … 430 430 std::list< TypeDecl * > * get_baseParameters(); 431 431 432 virtual bool isComplete() const override;432 virtual bool isComplete() const; 433 433 434 434 /// looks up the members of this union named "name" and places them into "foundDecls" 435 435 /// Clones declarations into "foundDecls", caller responsible for freeing 436 void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const override;437 438 virtual UnionInstType *clone() const override{ return new UnionInstType( *this ); }439 virtual void accept( Visitor & v ) override{ v.visit( this ); }440 virtual Type *acceptMutator( Mutator & m ) override{ return m.mutate( this ); }441 442 virtual void print( std::ostream & os, int indent = 0 ) const override;436 void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const; 437 438 virtual UnionInstType *clone() const { return new UnionInstType( *this ); } 439 virtual void accept( Visitor & v ) { v.visit( this ); } 440 virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); } 441 442 virtual void print( std::ostream & os, int indent = 0 ) const; 443 443 private: 444 virtual std::string typeString() const override;444 virtual std::string typeString() const; 445 445 }; 446 446 … … 459 459 void set_baseEnum( EnumDecl *newValue ) { baseEnum = newValue; } 460 460 461 virtual bool isComplete() const override;462 463 virtual EnumInstType *clone() const override{ return new EnumInstType( *this ); }464 virtual void accept( Visitor & v ) override{ v.visit( this ); }465 virtual Type *acceptMutator( Mutator & m ) override{ return m.mutate( this ); }461 virtual bool isComplete() const; 462 463 virtual EnumInstType *clone() const { return new EnumInstType( *this ); } 464 virtual void accept( Visitor & v ) { v.visit( this ); } 465 virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); } 466 466 private: 467 virtual std::string typeString() const override;467 virtual std::string typeString() const; 468 468 }; 469 469 … … 480 480 ~TraitInstType(); 481 481 482 virtual bool isComplete() const override;483 484 virtual TraitInstType *clone() const override{ return new TraitInstType( *this ); }485 virtual void accept( Visitor & v ) override{ v.visit( this ); }486 virtual Type *acceptMutator( Mutator & m ) override{ return m.mutate( this ); }482 virtual bool isComplete() const; 483 484 virtual TraitInstType *clone() const { return new TraitInstType( *this ); } 485 virtual void accept( Visitor & v ) { v.visit( this ); } 486 virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); } 487 487 private: 488 virtual std::string typeString() const override;488 virtual std::string typeString() const; 489 489 }; 490 490 … … 507 507 void set_isFtype( bool newValue ) { isFtype = newValue; } 508 508 509 virtual bool isComplete() const override;510 511 virtual TypeInstType *clone() const override{ return new TypeInstType( *this ); }512 virtual void accept( Visitor & v ) override{ v.visit( this ); }513 virtual Type *acceptMutator( Mutator & m ) override{ return m.mutate( this ); }514 virtual void print( std::ostream & os, int indent = 0 ) const override;509 virtual bool isComplete() const; 510 511 virtual TypeInstType *clone() const { return new TypeInstType( *this ); } 512 virtual void accept( Visitor & v ) { v.visit( this ); } 513 virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); } 514 virtual void print( std::ostream & os, int indent = 0 ) const; 515 515 private: 516 virtual std::string typeString() const override;516 virtual std::string typeString() const; 517 517 }; 518 518 … … 530 530 531 531 std::list<Type *> & get_types() { return types; } 532 virtual unsigned size() const override{ return types.size(); };532 virtual unsigned size() const { return types.size(); }; 533 533 534 534 // For now, this is entirely synthetic -- tuple types always have unnamed members. … … 539 539 iterator end() { return types.end(); } 540 540 541 virtual Type * getComponent( unsigned i ) override{541 virtual Type * getComponent( unsigned i ) { 542 542 assertf( i < size(), "TupleType::getComponent: index %d must be less than size %d", i, size() ); 543 543 return *(begin()+i); 544 544 } 545 545 546 // virtual bool isComplete() const override{ return true; } // xxx - not sure if this is right, might need to recursively check complete-ness547 548 virtual TupleType *clone() const override{ return new TupleType( *this ); }549 virtual void accept( Visitor & v ) override{ v.visit( this ); }550 virtual Type *acceptMutator( Mutator & m ) override{ return m.mutate( this ); }551 virtual void print( std::ostream & os, int indent = 0 ) const override;546 // virtual bool isComplete() const { return true; } // xxx - not sure if this is right, might need to recursively check complete-ness 547 548 virtual TupleType *clone() const { return new TupleType( *this ); } 549 virtual void accept( Visitor & v ) { v.visit( this ); } 550 virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); } 551 virtual void print( std::ostream & os, int indent = 0 ) const; 552 552 }; 553 553 … … 563 563 void set_expr( Expression *newValue ) { expr = newValue; } 564 564 565 virtual bool isComplete() const override{ assert( false ); return false; }566 567 virtual TypeofType *clone() const override{ return new TypeofType( *this ); }568 virtual void accept( Visitor & v ) override{ v.visit( this ); }569 virtual Type *acceptMutator( Mutator & m ) override{ return m.mutate( this ); }570 virtual void print( std::ostream & os, int indent = 0 ) const override;565 virtual bool isComplete() const { assert( false ); return false; } 566 567 virtual TypeofType *clone() const { return new TypeofType( *this ); } 568 virtual void accept( Visitor & v ) { v.visit( this ); } 569 virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); } 570 virtual void print( std::ostream & os, int indent = 0 ) const; 571 571 }; 572 572 … … 592 592 void set_isType( bool newValue ) { isType = newValue; } 593 593 594 virtual bool isComplete() const override{ assert( false ); } // xxx - not sure what to do here595 596 virtual AttrType *clone() const override{ return new AttrType( *this ); }597 virtual void accept( Visitor & v ) override{ v.visit( this ); }598 virtual Type *acceptMutator( Mutator & m ) override{ return m.mutate( this ); }599 virtual void print( std::ostream & os, int indent = 0 ) const override;594 virtual bool isComplete() const { assert( false ); } // xxx - not sure what to do here 595 596 virtual AttrType *clone() const { return new AttrType( *this ); } 597 virtual void accept( Visitor & v ) { v.visit( this ); } 598 virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); } 599 virtual void print( std::ostream & os, int indent = 0 ) const; 600 600 }; 601 601 … … 606 606 VarArgsType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 607 607 608 virtual bool isComplete() const override{ return true; } // xxx - is this right?609 610 virtual VarArgsType *clone() const override{ return new VarArgsType( *this ); }611 virtual void accept( Visitor & v ) override{ v.visit( this ); }612 virtual Type *acceptMutator( Mutator & m ) override{ return m.mutate( this ); }613 virtual void print( std::ostream & os, int indent = 0 ) const override;608 virtual bool isComplete() const{ return true; } // xxx - is this right? 609 610 virtual VarArgsType *clone() const { return new VarArgsType( *this ); } 611 virtual void accept( Visitor & v ) { v.visit( this ); } 612 virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); } 613 virtual void print( std::ostream & os, int indent = 0 ) const; 614 614 }; 615 615 … … 620 620 ZeroType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 621 621 622 virtual ZeroType *clone() const override{ return new ZeroType( *this ); }623 virtual void accept( Visitor & v ) override{ v.visit( this ); }624 virtual Type *acceptMutator( Mutator & m ) override{ return m.mutate( this ); }625 virtual void print( std::ostream & os, int indent = 0 ) const override;622 virtual ZeroType *clone() const { return new ZeroType( *this ); } 623 virtual void accept( Visitor & v ) { v.visit( this ); } 624 virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); } 625 virtual void print( std::ostream & os, int indent = 0 ) const; 626 626 }; 627 627 … … 632 632 OneType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 633 633 634 virtual OneType *clone() const override { return new OneType( *this ); } 635 virtual void accept( Visitor & v ) override { v.visit( this ); } 636 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 637 virtual void print( std::ostream & os, int indent = 0 ) const override; 638 }; 634 virtual OneType *clone() const { return new OneType( *this ); } 635 virtual void accept( Visitor & v ) { v.visit( this ); } 636 virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); } 637 virtual void print( std::ostream & os, int indent = 0 ) const; 638 }; 639 640 std::ostream & operator<<( std::ostream & out, const Type * type ); 639 641 640 642 // Local Variables: // -
src/SynTree/Visitor.h
r74bba15 raf58ee0 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
r74bba15 raf58ee0 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
r74bba15 raf58ee0 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/benchmark/bench.h
r74bba15 raf58ee0 11 11 #endif 12 12 13 staticinline unsigned long long int Time() {13 inline unsigned long long int Time() { 14 14 struct timespec ts; 15 15 clock_gettime( -
src/libcfa/Makefile.am
r74bba15 raf58ee0 36 36 ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -D__CFA_DEBUG__ -O0 -c -o $@ $< 37 37 38 EXTRA_FLAGS = -g -Wall -W no-unused-function -imacros libcfa-prelude.c @CFA_FLAGS@38 EXTRA_FLAGS = -g -Wall -Werror -Wno-unused-function -imacros libcfa-prelude.c @CFA_FLAGS@ 39 39 40 40 AM_CCASFLAGS = @CFA_FLAGS@ -
src/libcfa/Makefile.in
r74bba15 raf58ee0 416 416 ARFLAGS = cr 417 417 lib_LIBRARIES = $(am__append_1) $(am__append_2) 418 EXTRA_FLAGS = -g -Wall -W no-unused-function -imacros libcfa-prelude.c @CFA_FLAGS@418 EXTRA_FLAGS = -g -Wall -Werror -Wno-unused-function -imacros libcfa-prelude.c @CFA_FLAGS@ 419 419 AM_CCASFLAGS = @CFA_FLAGS@ 420 420 headers = fstream iostream iterator limits rational stdlib \ -
src/libcfa/concurrency/coroutine.c
r74bba15 raf58ee0 123 123 if(pageSize == 0ul) pageSize = sysconf( _SC_PAGESIZE ); 124 124 125 LIB_DEBUG_PRINT_SAFE("FRED"); 126 125 127 size_t cxtSize = libCeiling( sizeof(machine_context_t), 8 ); // minimum alignment 126 128 -
src/libcfa/concurrency/invoke.h
r74bba15 raf58ee0 84 84 }; 85 85 86 struct __waitfor_mask_t {87 short * accepted; // the index of the accepted function, -1 if none88 struct __acceptable_t * clauses; // list of acceptable functions, null if any89 short size; // number of acceptable functions90 };91 92 86 struct monitor_desc { 93 87 struct spinlock lock; // spinlock to protect internal data … … 96 90 struct __condition_stack_t signal_stack; // stack of conditions to run next once we exit the monitor 97 91 unsigned int recursion; // monitor routines can be called recursively, we need to keep track of that 98 struct __waitfor_mask_t mask; // mask used to know if some thread is waiting for something while holding the monitor99 };100 92 101 struct __monitor_group_t { 102 struct monitor_desc ** list; // currently held monitors 103 short size; // number of currently held monitors 104 fptr_t func; // last function that acquired monitors 105 }; 93 struct __acceptable_t * acceptables; // list of acceptable functions, null if any 94 unsigned short acceptable_count; // number of acceptable functions 95 short accepted_index; // the index of the accepted function, -1 if none 96 }; 106 97 107 98 struct thread_desc { 108 99 // Core threading fields 109 struct coroutine_desc self_cor; // coroutine body used to store context 110 struct monitor_desc self_mon; // monitor body used for mutual exclusion 111 struct monitor_desc * self_mon_p; // pointer to monitor with sufficient lifetime for current monitors 112 struct __monitor_group_t monitors; // monitors currently held by this thread 100 struct coroutine_desc cor; // coroutine body used to store context 101 struct monitor_desc mon; // monitor body used for mutual exclusion 113 102 114 103 // Link lists fields 115 104 struct thread_desc * next; // instrusive link field for threads 116 105 117 106 // Current status related to monitors 107 struct monitor_desc ** current_monitors; // currently held monitors 108 unsigned short current_monitor_count; // number of currently held monitors 109 fptr_t current_monitor_func; // last function that acquired monitors 118 110 }; 119 120 #ifdef __CFORALL__121 extern "Cforall" {122 static inline monitor_desc * ?[?]( const __monitor_group_t & this, ptrdiff_t index ) {123 return this.list[index];124 }125 126 static inline bool ?==?( const __monitor_group_t & lhs, const __monitor_group_t & rhs ) {127 if( (lhs.list != 0) != (rhs.list != 0) ) return false;128 if( lhs.size != rhs.size ) return false;129 if( lhs.func != rhs.func ) return false;130 131 // Check that all the monitors match132 for( int i = 0; i < lhs.size; i++ ) {133 // If not a match, check next function134 if( lhs[i] != rhs[i] ) return false;135 }136 137 return true;138 }139 }140 #endif141 111 142 112 #endif //_INVOKE_H_ -
src/libcfa/concurrency/kernel.c
r74bba15 raf58ee0 106 106 107 107 void ?{}( thread_desc & this, current_stack_info_t * info) { 108 (this. self_cor){ info };108 (this.cor){ info }; 109 109 } 110 110 … … 328 328 // if( !thrd ) return; 329 329 verify( thrd ); 330 verify( thrd-> self_cor.state != Halted );330 verify( thrd->cor.state != Halted ); 331 331 332 332 verify( disable_preempt_count > 0 ); … … 373 373 assert(thrd); 374 374 disable_interrupts(); 375 assert( thrd-> self_cor.state != Halted );375 assert( thrd->cor.state != Halted ); 376 376 this_processor->finish.action_code = Schedule; 377 377 this_processor->finish.thrd = thrd; … … 466 466 this_processor = mainProcessor; 467 467 this_thread = mainThread; 468 this_coroutine = &mainThread-> self_cor;468 this_coroutine = &mainThread->cor; 469 469 470 470 // Enable preemption … … 547 547 thread_desc * thrd = kernel_data; 548 548 549 int len = snprintf( abort_text, abort_text_size, "Error occurred while executing task %.256s (%p)", thrd-> self_cor.name, thrd );549 int len = snprintf( abort_text, abort_text_size, "Error occurred while executing task %.256s (%p)", thrd->cor.name, thrd ); 550 550 __lib_debug_write( STDERR_FILENO, abort_text, len ); 551 551 -
src/libcfa/concurrency/monitor
r74bba15 raf58ee0 22 22 #include "stdlib" 23 23 24 trait is_monitor(dtype T) {25 monitor_desc * get_monitor( T & );26 void ^?{}( T & mutex );27 };28 29 24 static inline void ?{}(monitor_desc & this) { 30 25 (this.lock){}; … … 33 28 (this.signal_stack){}; 34 29 this.recursion = 0; 35 this. mask.accepted= NULL;36 this. mask.clauses = NULL;37 this. mask.size = 0;30 this.acceptables = NULL; 31 this.acceptable_count = 0; 32 this.accepted_index = -1; 38 33 } 39 34 … … 105 100 106 101 struct __acceptable_t { 107 __monitor_group_t; 102 fptr_t func; 103 unsigned short count; 104 monitor_desc ** monitors; 108 105 bool is_dtor; 109 106 }; 110 107 111 void __waitfor_internal( const __waitfor_mask_t & mask, int duration);108 int __accept_internal( unsigned short count, __acceptable_t * acceptables ); 112 109 113 110 // Local Variables: // -
src/libcfa/concurrency/monitor.c
r74bba15 raf58ee0 23 23 //----------------------------------------------------------------------------- 24 24 // Forward declarations 25 static inline void set_owner ( monitor_desc * this, thread_desc * owner ); 26 static inline void set_owner ( monitor_desc ** storage, short count, thread_desc * owner ); 27 static inline void set_mask ( monitor_desc ** storage, short count, const __waitfor_mask_t & mask ); 28 static inline void reset_mask( monitor_desc * this ); 29 25 static inline void set_owner( monitor_desc * this, thread_desc * owner ); 30 26 static inline thread_desc * next_thread( monitor_desc * this ); 31 static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & monitors);27 static inline int is_accepted( thread_desc * owner, monitor_desc * this, monitor_desc ** group, int group_cnt, void (*func)() ); 32 28 33 29 static inline void lock_all( spinlock ** locks, unsigned short count ); … … 36 32 static inline void unlock_all( monitor_desc ** locks, unsigned short count ); 37 33 38 static inline void save ( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks);39 static inline void restore ( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*in */ recursions, __waitfor_mask_t * /*in */ masks);34 static inline void save_recursion ( monitor_desc ** ctx, unsigned int * /*out*/ recursions, unsigned short count ); 35 static inline void restore_recursion( monitor_desc ** ctx, unsigned int * /*in */ recursions, unsigned short count ); 40 36 41 37 static inline void init ( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ); 42 38 static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ); 43 39 44 static inline thread_desc * check_condition ( __condition_criterion_t * ); 45 static inline void brand_condition ( condition * ); 46 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t &, monitor_desc ** monitors, int count ); 47 48 forall(dtype T | sized( T )) 49 static inline short insert_unique( T ** array, short & size, T * val ); 50 static inline short count_max ( const __waitfor_mask_t & mask ); 51 static inline short aggregate ( monitor_desc ** storage, const __waitfor_mask_t & mask ); 40 static inline thread_desc * check_condition( __condition_criterion_t * ); 41 static inline void brand_condition( condition * ); 42 static inline unsigned short insert_unique( thread_desc ** thrds, unsigned short end, thread_desc * val ); 43 44 static inline thread_desc * search_entry_queue( __acceptable_t * acceptables, int acc_count, monitor_desc ** monitors, int count ); 52 45 53 46 //----------------------------------------------------------------------------- 54 47 // Useful defines 55 #define wait_ctx(thrd, user_info) /* Create the necessary information to use the signaller stack */ \ 56 __condition_node_t waiter = { thrd, count, user_info }; /* Create the node specific to this wait operation */ \ 57 __condition_criterion_t criteria[count]; /* Create the creteria this wait operation needs to wake up */ \ 58 init( count, monitors, &waiter, criteria ); /* Link everything together */ \ 59 60 #define wait_ctx_primed(thrd, user_info) /* Create the necessary information to use the signaller stack */ \ 61 __condition_node_t waiter = { thrd, count, user_info }; /* Create the node specific to this wait operation */ \ 62 __condition_criterion_t criteria[count]; /* Create the creteria this wait operation needs to wake up */ \ 63 init_push( count, monitors, &waiter, criteria ); /* Link everything together and push it to the AS-Stack */ \ 64 65 #define monitor_ctx( mons, cnt ) /* Define that create the necessary struct for internal/external scheduling operations */ \ 66 monitor_desc ** monitors = mons; /* Save the targeted monitors */ \ 67 unsigned short count = cnt; /* Save the count to a local variable */ \ 68 unsigned int recursions[ count ]; /* Save the current recursion levels to restore them later */ \ 69 __waitfor_mask_t masks[ count ]; /* Save the current waitfor masks to restore them later */ \ 70 spinlock * locks [ count ]; /* We need to pass-in an array of locks to BlockInternal */ \ 71 72 #define monitor_save save ( monitors, count, locks, recursions, masks ) 73 #define monitor_restore restore( monitors, count, locks, recursions, masks ) 74 48 #define wait_ctx(thrd, user_info) /* Create the necessary information to use the signaller stack */ \ 49 __condition_node_t waiter = { thrd, count, user_info }; /* Create the node specific to this wait operation */ \ 50 __condition_criterion_t criteria[count]; /* Create the creteria this wait operation needs to wake up */ \ 51 init( count, monitors, &waiter, criteria ); /* Link everything together */ \ 52 53 #define wait_ctx_primed(thrd, user_info) /* Create the necessary information to use the signaller stack */ \ 54 __condition_node_t waiter = { thrd, count, user_info }; /* Create the node specific to this wait operation */ \ 55 __condition_criterion_t criteria[count]; /* Create the creteria this wait operation needs to wake up */ \ 56 init_push( count, monitors, &waiter, criteria ); /* Link everything together and push it to the AS-Stack */ \ 57 58 #define monitor_ctx( mons, cnt ) /* Define that create the necessary struct for internal/external scheduling operations */ \ 59 monitor_desc ** monitors = mons; /* Save the targeted monitors */ \ 60 unsigned short count = cnt; /* Save the count to a local variable */ \ 61 unsigned int recursions[ count ]; /* Save the current recursion levels to restore them later */ \ 62 spinlock * locks [ count ]; /* We need to pass-in an array of locks to BlockInternal */ \ 75 63 76 64 //----------------------------------------------------------------------------- … … 80 68 extern "C" { 81 69 // Enter single monitor 82 static void __enter_monitor_desc( monitor_desc * this, const __monitor_group_t & group) {70 static void __enter_monitor_desc( monitor_desc * this, monitor_desc ** group, int group_cnt, void (*func)() ) { 83 71 // Lock the monitor spinlock, lock_yield to reduce contention 84 72 lock_yield( &this->lock DEBUG_CTX2 ); … … 87 75 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner); 88 76 77 this->accepted_index = -1; 89 78 if( !this->owner ) { 90 79 // No one has the monitor, just take it … … 100 89 LIB_DEBUG_PRINT_SAFE("Kernel : mon already owned \n"); 101 90 } 102 else if( is_accepted( this, group)) {91 else if( (this->accepted_index = is_accepted( thrd, this, group, group_cnt, func)) >= 0 ) { 103 92 // Some one was waiting for us, enter 104 93 set_owner( this, thrd ); 105 106 // Reset mask107 reset_mask( this );108 94 109 95 LIB_DEBUG_PRINT_SAFE("Kernel : mon accepts \n"); … … 134 120 lock_yield( &this->lock DEBUG_CTX2 ); 135 121 136 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Leaving mon %p (%p)\n", this_thread, this, this->owner); 137 138 verifyf( this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", this_thread, this->owner, this->recursion, this ); 122 verifyf( this_thread == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread, this->owner, this->recursion ); 139 123 140 124 // Leaving a recursion level, decrement the counter … … 162 146 // Should never return 163 147 void __leave_thread_monitor( thread_desc * thrd ) { 164 monitor_desc * this = &thrd-> self_mon;148 monitor_desc * this = &thrd->mon; 165 149 166 150 // Lock the monitor now … … 169 153 disable_interrupts(); 170 154 171 thrd-> self_cor.state = Halted;172 173 verifyf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i , m: %p)", thrd, this->owner, this->recursion, this);155 thrd->cor.state = Halted; 156 157 verifyf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", thrd, this->owner, this->recursion ); 174 158 175 159 // Leaving a recursion level, decrement the counter … … 194 178 // Enter multiple monitor 195 179 // relies on the monitor array being sorted 196 static inline void enter( __monitor_group_t monitors) {197 for(int i = 0; i < monitors.size; i++) {198 __enter_monitor_desc( monitors .list[i], monitors);180 static inline void enter(monitor_desc ** monitors, int count, void (*func)() ) { 181 for(int i = 0; i < count; i++) { 182 __enter_monitor_desc( monitors[i], monitors, count, func ); 199 183 } 200 184 } … … 219 203 220 204 // Save previous thread context 221 this.prev_mntrs = this_thread-> monitors.list;222 this.prev_count = this_thread-> monitors.size;223 this.prev_func = this_thread-> monitors.func;205 this.prev_mntrs = this_thread->current_monitors; 206 this.prev_count = this_thread->current_monitor_count; 207 this.prev_func = this_thread->current_monitor_func; 224 208 225 209 // Update thread context (needed for conditions) 226 this_thread->monitors.list = m; 227 this_thread->monitors.size = count; 228 this_thread->monitors.func = func; 229 230 // LIB_DEBUG_PRINT_SAFE("MGUARD : enter %d\n", count); 210 this_thread->current_monitors = m; 211 this_thread->current_monitor_count = count; 212 this_thread->current_monitor_func = func; 231 213 232 214 // Enter the monitors in order 233 __monitor_group_t group = {this.m, this.count, func}; 234 enter( group ); 235 236 // LIB_DEBUG_PRINT_SAFE("MGUARD : entered\n"); 215 enter( this.m, this.count, func ); 237 216 } 238 217 … … 240 219 // Dtor for monitor guard 241 220 void ^?{}( monitor_guard_t & this ) { 242 // LIB_DEBUG_PRINT_SAFE("MGUARD : leaving %d\n", this.count);243 244 221 // Leave the monitors in order 245 222 leave( this.m, this.count ); 246 223 247 // LIB_DEBUG_PRINT_SAFE("MGUARD : left\n");248 249 224 // Restore thread context 250 this_thread-> monitors.list= this.prev_mntrs;251 this_thread-> monitors.size= this.prev_count;252 this_thread-> monitors.func= this.prev_func;225 this_thread->current_monitors = this.prev_mntrs; 226 this_thread->current_monitor_count = this.prev_count; 227 this_thread->current_monitor_func = this.prev_func; 253 228 } 254 229 … … 296 271 append( &this->blocked, &waiter ); 297 272 298 // Lock all monitors (aggregates the lock sas well)273 // Lock all monitors (aggregates the lock them as well) 299 274 lock_all( monitors, locks, count ); 300 275 276 // DON'T unlock, ask the kernel to do it 277 278 // Save monitor state 279 save_recursion( monitors, recursions, count ); 280 301 281 // Find the next thread(s) to run 302 short thread_count = 0;282 unsigned short thread_count = 0; 303 283 thread_desc * threads[ count ]; 304 284 for(int i = 0; i < count; i++) { … … 306 286 } 307 287 308 // Save monitor states309 monitor_save;310 311 288 // Remove any duplicate threads 312 289 for( int i = 0; i < count; i++) { 313 290 thread_desc * new_owner = next_thread( monitors[i] ); 314 insert_unique( threads, thread_count, new_owner );291 thread_count = insert_unique( threads, thread_count, new_owner ); 315 292 } 316 293 … … 318 295 BlockInternal( locks, count, threads, thread_count ); 319 296 297 298 // WE WOKE UP 299 300 320 301 // We are back, restore the owners and recursions 321 monitor_restore; 302 lock_all( locks, count ); 303 restore_recursion( monitors, recursions, count ); 304 unlock_all( locks, count ); 322 305 } 323 306 … … 332 315 LIB_DEBUG_DO( 333 316 thread_desc * this_thrd = this_thread; 334 if ( this->monitor_count != this_thrd-> monitors.size) {335 abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd-> monitors.size);317 if ( this->monitor_count != this_thrd->current_monitor_count ) { 318 abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd->current_monitor_count ); 336 319 } 337 320 338 321 for(int i = 0; i < this->monitor_count; i++) { 339 if ( this->monitors[i] != this_thrd-> monitors.list[i] ) {340 abortf( "Signal on condition %p made with different monitor, expected %p got %i", this, this->monitors[i], this_thrd-> monitors.list[i] );322 if ( this->monitors[i] != this_thrd->current_monitors[i] ) { 323 abortf( "Signal on condition %p made with different monitor, expected %p got %i", this, this->monitors[i], this_thrd->current_monitors[i] ); 341 324 } 342 325 } … … 381 364 382 365 //save contexts 383 monitor_save;366 save_recursion( monitors, recursions, count ); 384 367 385 368 //Find the thread to run 386 369 thread_desc * signallee = pop_head( &this->blocked )->waiting_thread; 387 set_owner( monitors, count, signallee ); 370 for(int i = 0; i < count; i++) { 371 set_owner( monitors[i], signallee ); 372 } 388 373 389 374 //Everything is ready to go to sleep … … 394 379 395 380 396 //We are back, restore the masks and recursions 397 monitor_restore; 381 //We are back, restore the owners and recursions 382 lock_all( locks, count ); 383 restore_recursion( monitors, recursions, count ); 384 unlock_all( locks, count ); 398 385 399 386 return true; … … 410 397 411 398 //----------------------------------------------------------------------------- 412 // External scheduling 413 // cases to handle : 414 // - target already there : 415 // block and wake 416 // - dtor already there 417 // put thread on signaller stack 418 // - non-blocking 419 // return else 420 // - timeout 421 // return timeout 422 // - block 423 // setup mask 424 // block 425 void __waitfor_internal( const __waitfor_mask_t & mask, int duration ) { 426 // This statment doesn't have a contiguous list of monitors... 427 // Create one! 428 short max = count_max( mask ); 429 monitor_desc * mon_storage[max]; 430 short actual_count = aggregate( mon_storage, mask ); 431 432 if(actual_count == 0) return; 433 434 LIB_DEBUG_PRINT_SAFE("Kernel : waitfor internal proceeding\n"); 399 // Internal scheduling 400 int __accept_internal( unsigned short acc_count, __acceptable_t * acceptables ) { 401 thread_desc * thrd = this_thread; 435 402 436 403 // Create storage for monitor context 437 monitor_ctx( mon_storage, actual_count );438 439 // Lock all monitors (aggregates the lock sas well)404 monitor_ctx( acceptables->monitors, acceptables->count ); 405 406 // Lock all monitors (aggregates the lock them as well) 440 407 lock_all( monitors, locks, count ); 441 408 442 {443 // Check if the entry queue444 thread_desc * next; int index;445 [next, index] = search_entry_queue( mask, monitors, count );446 447 if( next ) {448 *mask.accepted = index;449 if( mask.clauses[index].is_dtor ) {450 #warning case not implemented451 }452 else {453 LIB_DEBUG_PRINT_SAFE("Kernel : thread present, baton-passing\n");454 455 // Create the node specific to this wait operation456 wait_ctx_primed( this_thread, 0 );457 458 // Save monitor states459 monitor_save;460 461 // Set the owners to be the next thread462 set_owner( monitors, count, next );463 464 // Everything is ready to go to sleep465 BlockInternal( locks, count, &next, 1 );466 467 // We are back, restore the owners and recursions468 monitor_restore;469 470 LIB_DEBUG_PRINT_SAFE("Kernel : thread present, returned\n");471 }472 473 LIB_DEBUG_PRINT_SAFE("Kernel : accepted %d\n", *mask.accepted);474 475 return;476 }477 }478 479 480 if( duration == 0 ) {481 LIB_DEBUG_PRINT_SAFE("Kernel : non-blocking, exiting\n");482 483 unlock_all( locks, count );484 485 LIB_DEBUG_PRINT_SAFE("Kernel : accepted %d\n", *mask.accepted);486 return;487 }488 489 490 verifyf( duration < 0, "Timeout on waitfor statments not supported yet.");491 492 LIB_DEBUG_PRINT_SAFE("Kernel : blocking waitfor\n");493 494 409 // Create the node specific to this wait operation 495 wait_ctx_primed( this_thread, 0 ); 496 497 monitor_save; 498 set_mask( monitors, count, mask ); 499 410 wait_ctx_primed( thrd, 0 ); 411 412 // Check if the entry queue 413 thread_desc * next = search_entry_queue( acceptables, acc_count, monitors, count ); 414 415 LIB_DEBUG_PRINT_SAFE("Owner(s) :"); 500 416 for(int i = 0; i < count; i++) { 501 verify( monitors[i]->owner == this_thread ); 502 } 503 504 //Everything is ready to go to sleep 505 BlockInternal( locks, count ); 506 507 508 // WE WOKE UP 509 510 511 //We are back, restore the masks and recursions 512 monitor_restore; 513 514 LIB_DEBUG_PRINT_SAFE("Kernel : exiting\n"); 515 516 LIB_DEBUG_PRINT_SAFE("Kernel : accepted %d\n", *mask.accepted); 417 LIB_DEBUG_PRINT_SAFE(" %p", monitors[i]->owner ); 418 } 419 LIB_DEBUG_PRINT_SAFE("\n"); 420 421 LIB_DEBUG_PRINT_SAFE("Passing mon to %p\n", next); 422 423 if( !next ) { 424 // Update acceptables on the current monitors 425 for(int i = 0; i < count; i++) { 426 monitors[i]->acceptables = acceptables; 427 monitors[i]->acceptable_count = acc_count; 428 } 429 } 430 else { 431 for(int i = 0; i < count; i++) { 432 set_owner( monitors[i], next ); 433 } 434 } 435 436 437 save_recursion( monitors, recursions, count ); 438 439 440 // Everything is ready to go to sleep 441 BlockInternal( locks, count, &next, next ? 1 : 0 ); 442 443 444 //WE WOKE UP 445 446 447 //We are back, restore the owners and recursions 448 lock_all( locks, count ); 449 restore_recursion( monitors, recursions, count ); 450 int acc_idx = monitors[0]->accepted_index; 451 unlock_all( locks, count ); 452 453 return acc_idx; 517 454 } 518 455 … … 521 458 522 459 static inline void set_owner( monitor_desc * this, thread_desc * owner ) { 523 // LIB_DEBUG_PRINT_SAFE("Kernal : Setting owner of %p to %p ( was %p)\n", this, owner, this->owner );524 525 460 //Pass the monitor appropriately 526 461 this->owner = owner; … … 528 463 //We are passing the monitor to someone else, which means recursion level is not 0 529 464 this->recursion = owner ? 1 : 0; 530 }531 532 static inline void set_owner( monitor_desc ** monitors, short count, thread_desc * owner ) {533 for( int i = 0; i < count; i++ ) {534 set_owner( monitors[i], owner );535 }536 }537 538 static inline void set_mask( monitor_desc ** storage, short count, const __waitfor_mask_t & mask ) {539 for(int i = 0; i < count; i++) {540 storage[i]->mask = mask;541 }542 }543 544 static inline void reset_mask( monitor_desc * this ) {545 this->mask.accepted = NULL;546 this->mask.clauses = NULL;547 this->mask.size = 0;548 465 } 549 466 … … 568 485 } 569 486 570 static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & group) {571 __acceptable_t * it = this->mask.clauses; // Optim572 int count = this->mask.size;487 static inline int is_accepted( thread_desc * owner, monitor_desc * this, monitor_desc ** group, int group_cnt, void (*func)() ) { 488 __acceptable_t* accs = this->acceptables; // Optim 489 int acc_cnt = this->acceptable_count; 573 490 574 491 // Check if there are any acceptable functions 575 if( ! it ) return false;492 if( !accs ) return -1; 576 493 577 494 // If this isn't the first monitor to test this, there is no reason to repeat the test. 578 if( this != group[0] ) return group[0]-> mask.accepted >= 0;495 if( this != group[0] ) return group[0]->accepted_index; 579 496 580 497 // For all acceptable functions check if this is the current function. 581 for( short i = 0; i < count; i++, it++ ) { 582 if( *it == group ) { 583 *this->mask.accepted = i; 584 return true; 498 OUT_LOOP: 499 for( int i = 0; i < acc_cnt; i++ ) { 500 __acceptable_t * acc = &accs[i]; 501 502 // if function matches, check the monitors 503 if( acc->func == func ) { 504 505 // If the group count is different then it can't be a match 506 if( acc->count != group_cnt ) return -1; 507 508 // Check that all the monitors match 509 for( int j = 0; j < group_cnt; j++ ) { 510 // If not a match, check next function 511 if( acc->monitors[j] != group[j] ) continue OUT_LOOP; 512 } 513 514 // It's a complete match, accept the call 515 return i; 585 516 } 586 517 } 587 518 588 519 // No function matched 589 return false;520 return -1; 590 521 } 591 522 … … 633 564 } 634 565 635 static inline void save( monitor_desc ** ctx, short count, __attribute((unused)) spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks ) { 566 567 static inline void save_recursion ( monitor_desc ** ctx, unsigned int * /*out*/ recursions, unsigned short count ) { 636 568 for( int i = 0; i < count; i++ ) { 637 569 recursions[i] = ctx[i]->recursion; 638 masks[i] = ctx[i]->mask; 639 } 640 } 641 642 static inline void restore( monitor_desc ** ctx, short count, spinlock ** locks, unsigned int * /*out*/ recursions, __waitfor_mask_t * /*out*/ masks ) { 643 lock_all( locks, count ); 570 } 571 } 572 573 static inline void restore_recursion( monitor_desc ** ctx, unsigned int * /*in */ recursions, unsigned short count ) { 644 574 for( int i = 0; i < count; i++ ) { 645 575 ctx[i]->recursion = recursions[i]; 646 ctx[i]->mask = masks[i]; 647 } 648 unlock_all( locks, count ); 576 } 649 577 } 650 578 … … 679 607 if( !this->monitors ) { 680 608 // LIB_DEBUG_PRINT_SAFE("Branding\n"); 681 assertf( thrd-> monitors.list != NULL, "No current monitor to brand condition %p", thrd->monitors.list);682 this->monitor_count = thrd-> monitors.size;609 assertf( thrd->current_monitors != NULL, "No current monitor to brand condition %p", thrd->current_monitors ); 610 this->monitor_count = thrd->current_monitor_count; 683 611 684 612 this->monitors = malloc( this->monitor_count * sizeof( *this->monitors ) ); 685 613 for( int i = 0; i < this->monitor_count; i++ ) { 686 this->monitors[i] = thrd->monitors.list[i]; 687 } 688 } 689 } 690 691 static inline [thread_desc *, int] search_entry_queue( const __waitfor_mask_t & mask, monitor_desc ** monitors, int count ) { 614 this->monitors[i] = thrd->current_monitors[i]; 615 } 616 } 617 } 618 619 static inline unsigned short insert_unique( thread_desc ** thrds, unsigned short end, thread_desc * val ) { 620 if( !val ) return end; 621 622 for(int i = 0; i <= end; i++) { 623 if( thrds[i] == val ) return end; 624 } 625 626 thrds[end] = val; 627 return end + 1; 628 } 629 630 631 static inline bool match( __acceptable_t * acc, thread_desc * thrd ) { 632 verify( thrd ); 633 verify( acc ); 634 if( acc->func != thrd->current_monitor_func ) return false; 635 636 return true; 637 } 638 639 static inline thread_desc * search_entry_queue( __acceptable_t * acceptables, int acc_count, monitor_desc ** monitors, int count ) { 692 640 693 641 __thread_queue_t * entry_queue = &monitors[0]->entry_queue; … … 696 644 for( thread_desc ** thrd_it = &entry_queue->head; 697 645 *thrd_it; 698 thrd_it = &(*thrd_it)->next 699 ){646 thrd_it = &(*thrd_it)->next) 647 { 700 648 // For each acceptable check if it matches 701 int i = 0; 702 __acceptable_t * end = mask.clauses + mask.size; 703 for( __acceptable_t * it = mask.clauses; it != end; it++, i++ ) { 649 __acceptable_t * acc_end = acceptables + acc_count; 650 for( __acceptable_t * acc_it = acceptables; acc_it != acc_end; acc_it++ ) { 704 651 // Check if we have a match 705 if( *it == (*thrd_it)->monitors) {652 if( match( acc_it, *thrd_it ) ) { 706 653 707 654 // If we have a match return it 708 655 // after removeing it from the entry queue 709 return [remove( entry_queue, thrd_it ), i];656 return remove( entry_queue, thrd_it ); 710 657 } 711 658 } 712 659 } 713 660 714 return [0, -1]; 715 } 716 717 forall(dtype T | sized( T )) 718 static inline short insert_unique( T ** array, short & size, T * val ) { 719 if( !val ) return size; 720 721 for(int i = 0; i <= size; i++) { 722 if( array[i] == val ) return size; 723 } 724 725 array[size] = val; 726 size = size + 1; 727 return size; 728 } 729 730 static inline short count_max( const __waitfor_mask_t & mask ) { 731 short max = 0; 732 for( int i = 0; i < mask.size; i++ ) { 733 max += mask.clauses[i].size; 734 } 735 return max; 736 } 737 738 static inline short aggregate( monitor_desc ** storage, const __waitfor_mask_t & mask ) { 739 short size = 0; 740 for( int i = 0; i < mask.size; i++ ) { 741 for( int j = 0; j < mask.clauses[i].size; j++) { 742 insert_unique( storage, size, mask.clauses[i].list[j] ); 743 } 744 } 745 qsort( storage, size ); 746 return size; 747 } 748 661 return NULL; 662 } 749 663 void ?{}( __condition_blocked_queue_t & this ) { 750 664 this.head = NULL; -
src/libcfa/concurrency/preemption.c
r74bba15 raf58ee0 328 328 siginfo_t info; 329 329 int sig = sigwaitinfo( &mask, &info ); 330 331 if( sig < 0 ) {332 //Error!333 int err = errno;334 switch( err ) {335 case EAGAIN :336 case EINTR :337 continue;338 case EINVAL :339 abortf("Timeout was invalid.");340 default:341 abortf("Unhandled error %d", err);342 }343 }344 330 345 331 // If another signal arrived something went wrong -
src/libcfa/concurrency/thread
r74bba15 raf58ee0 36 36 forall( dtype T | is_thread(T) ) 37 37 static inline coroutine_desc* get_coroutine(T & this) { 38 return &get_thread(this)-> self_cor;38 return &get_thread(this)->cor; 39 39 } 40 40 41 41 forall( dtype T | is_thread(T) ) 42 42 static inline monitor_desc* get_monitor(T & this) { 43 return &get_thread(this)-> self_mon;43 return &get_thread(this)->mon; 44 44 } 45 45 46 46 static inline coroutine_desc* get_coroutine(thread_desc * this) { 47 return &this-> self_cor;47 return &this->cor; 48 48 } 49 49 50 50 static inline monitor_desc* get_monitor(thread_desc * this) { 51 return &this-> self_mon;51 return &this->mon; 52 52 } 53 53 -
src/libcfa/concurrency/thread.c
r74bba15 raf58ee0 33 33 34 34 void ?{}(thread_desc& this) { 35 (this.self_cor){}; 36 this.self_cor.name = "Anonymous Coroutine"; 37 this.self_mon.owner = &this; 38 this.self_mon.recursion = 1; 39 this.self_mon_p = &this.self_mon; 35 (this.cor){}; 36 this.cor.name = "Anonymous Coroutine"; 37 this.mon.owner = &this; 38 this.mon.recursion = 1; 40 39 this.next = NULL; 41 40 42 (this.monitors){ &this.self_mon_p, 1, (fptr_t)0 }; 41 this.current_monitors = &this.mon; 42 this.current_monitor_count = 1; 43 43 } 44 44 45 45 void ^?{}(thread_desc& this) { 46 ^(this. self_cor){};46 ^(this.cor){}; 47 47 } 48 48 -
src/main.cc
r74bba15 raf58ee0 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/prelude/prelude.cf
r74bba15 raf58ee0 42 42 _Bool ?--( _Bool & ), ?--( volatile _Bool & ); 43 43 unsigned char ?++( unsigned char & ), ?++( volatile unsigned char & ); 44 signed short ?++( signed short & ), ?++( volatile signed short & );45 signed short ?--( signed short & ), ?--( volatile signed short & );46 unsigned short ?++( unsigned short & ), ?++( volatile unsigned short & );47 unsigned short ?--( unsigned short & ), ?--( volatile unsigned short & );48 44 signed int ?++( signed int & ), ?++( volatile signed int & ); 49 45 signed int ?--( signed int & ), ?--( volatile signed int & ); … … 96 92 97 93 _Bool ++?( _Bool & ), --?( _Bool & ); 98 signed short ++?( signed short & ), --?( signed short & );99 94 signed int ++?( signed int & ), --?( signed int & ); 100 unsigned short ++?( unsigned int & ), --?( unsigned int & ); 101 unsigned int ++?( unsigned short & ), --?( unsigned short & ); 95 unsigned int ++?( unsigned int & ), --?( unsigned int & ); 102 96 signed long int ++?( signed long int & ), --?( signed long int & ); 103 97 unsigned long int ++?( unsigned long int & ), --?( unsigned long int & ); -
src/tests/Makefile.am
r74bba15 raf58ee0 22 22 concurrent = yes 23 23 quick_test += coroutine thread monitor 24 concurrent_test = coroutine thread monitor multi-monitor sched-int-b lock sched-int-disjoint sched-int-wait sched-ext-barge sched-ext-else sched-ext-parse sched-ext-statmentpreempt24 concurrent_test = coroutine thread monitor multi-monitor sched-int-barge sched-int-block sched-int-disjoint sched-int-wait sched-ext sched-ext-multi preempt 25 25 else 26 26 concurrent=no … … 104 104 ${CC} ${AM_CFLAGS} ${CFLAGS} -CFA -XCFA -p -XCFA -L ${<} -o ${@} 105 105 106 sched-ext-parse : sched-ext-parse.c @CFA_BINDIR@/@CFA_NAME@107 ${CC} ${AM_CFLAGS} ${CFLAGS} -CFA -XCFA -p -XCFA -L ${<} -o ${@}108 109 106 gmp : gmp.c @CFA_BINDIR@/@CFA_NAME@ 110 107 ${CC} ${AM_CFLAGS} ${CFLAGS} -lgmp ${<} -o ${@} -
src/tests/Makefile.in
r74bba15 raf58ee0 320 320 @BUILD_CONCURRENCY_TRUE@concurrent = yes 321 321 @BUILD_CONCURRENCY_FALSE@concurrent_test = 322 @BUILD_CONCURRENCY_TRUE@concurrent_test = coroutine thread monitor multi-monitor sched-int-b lock sched-int-disjoint sched-int-wait sched-ext-barge sched-ext-else sched-ext-parse sched-ext-statmentpreempt322 @BUILD_CONCURRENCY_TRUE@concurrent_test = coroutine thread monitor multi-monitor sched-int-barge sched-int-block sched-int-disjoint sched-int-wait sched-ext sched-ext-multi preempt 323 323 324 324 # applies to both programs … … 856 856 ${CC} ${AM_CFLAGS} ${CFLAGS} -CFA -XCFA -p -XCFA -L ${<} -o ${@} 857 857 858 sched-ext-parse : sched-ext-parse.c @CFA_BINDIR@/@CFA_NAME@859 ${CC} ${AM_CFLAGS} ${CFLAGS} -CFA -XCFA -p -XCFA -L ${<} -o ${@}860 861 858 gmp : gmp.c @CFA_BINDIR@/@CFA_NAME@ 862 859 ${CC} ${AM_CFLAGS} ${CFLAGS} -lgmp ${<} -o ${@} -
src/tests/sched-ext-parse.c
r74bba15 raf58ee0 80 80 16; 81 81 } 82 or waitfor( f 2, a, a ) {82 or waitfor( f1, a, a ) { 83 83 17; 84 84 } -
src/tests/sched-ext.c
r74bba15 raf58ee0 45 45 acceptable.monitors = &a; 46 46 47 __ waitfor_internal( 1, &acceptable );47 __accept_internal( 1, &acceptable ); 48 48 49 49 sout | "Accepted" | endl;
Note:
See TracChangeset
for help on using the changeset viewer.