- Timestamp:
- Dec 5, 2017, 2:35:03 PM (8 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- f9feab8
- Parents:
- 9c35431 (diff), 65197c2 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src
- Files:
-
- 5 added
- 7 deleted
- 78 edited
- 68 moved
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r9c35431 rc13e8dc8 1012 1012 } 1013 1013 1014 void CodeGenerator::postvisit( WithStmt * with ) { 1015 if ( ! genC ) { 1016 output << "with ( "; 1017 genCommaList( with->exprs.begin(), with->exprs.end() ); 1018 output << " ) "; 1019 } 1020 with->stmt->accept( *visitor ); 1021 } 1014 1022 1015 1023 void CodeGenerator::postvisit( WhileStmt * whileStmt ) { -
src/CodeGen/CodeGenerator.h
r9c35431 rc13e8dc8 102 102 void postvisit( CatchStmt * ); 103 103 void postvisit( WaitForStmt * ); 104 void postvisit( WithStmt * ); 104 105 void postvisit( WhileStmt * ); 105 106 void postvisit( ForStmt * ); -
src/CodeGen/FixNames.cc
r9c35431 rc13e8dc8 19 19 #include <string> // for string, operator!=, operator== 20 20 21 #include "Common/PassVisitor.h" 21 22 #include "Common/SemanticError.h" // for SemanticError 22 23 #include "FixMain.h" // for FixMain … … 32 33 33 34 namespace CodeGen { 34 class FixNames : public Visitor{35 class FixNames : public WithGuards { 35 36 public: 36 v irtual voidvisit( ObjectDecl *objectDecl );37 v irtual voidvisit( FunctionDecl *functionDecl );37 void postvisit( ObjectDecl *objectDecl ); 38 void postvisit( FunctionDecl *functionDecl ); 38 39 39 v irtual voidvisit( CompoundStmt *compoundStmt );40 void previsit( CompoundStmt *compoundStmt ); 40 41 private: 41 42 int scopeLevel = 1; … … 93 94 } 94 95 95 void fixNames( std::list< Declaration* > translationUnit ) {96 FixNamesfixer;96 void fixNames( std::list< Declaration* > & translationUnit ) { 97 PassVisitor<FixNames> fixer; 97 98 acceptAll( translationUnit, fixer ); 98 99 } 99 100 100 void FixNames::fixDWT( DeclarationWithType * dwt ) {101 void FixNames::fixDWT( DeclarationWithType * dwt ) { 101 102 if ( dwt->get_name() != "" ) { 102 103 if ( LinkageSpec::isMangled( dwt->get_linkage() ) ) { … … 107 108 } 108 109 109 void FixNames::visit( ObjectDecl *objectDecl ) { 110 Visitor::visit( objectDecl ); 110 void FixNames::postvisit( ObjectDecl * objectDecl ) { 111 111 fixDWT( objectDecl ); 112 112 } 113 113 114 void FixNames::visit( FunctionDecl *functionDecl ) { 115 Visitor::visit( functionDecl ); 114 void FixNames::postvisit( FunctionDecl * functionDecl ) { 116 115 fixDWT( functionDecl ); 117 116 … … 121 120 throw SemanticError("Main expected to have 0, 2 or 3 arguments\n", functionDecl); 122 121 } 123 functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( n oLabels, new ConstantExpr( Constant::from_int( 0 ) ) ) );122 functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( new ConstantExpr( Constant::from_int( 0 ) ) ) ); 124 123 CodeGen::FixMain::registerMain( functionDecl ); 125 124 } 126 125 } 127 126 128 void FixNames:: visit( CompoundStmt *compoundStmt) {127 void FixNames::previsit( CompoundStmt * ) { 129 128 scopeLevel++; 130 Visitor::visit( compoundStmt ); 131 scopeLevel--; 129 GuardAction( [this](){ scopeLevel--; } ); 132 130 } 133 131 } // namespace CodeGen -
src/CodeGen/FixNames.h
r9c35431 rc13e8dc8 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // FixNames.h -- 7 // FixNames.h -- 8 8 // 9 9 // Author : Richard C. Bilson … … 22 22 namespace CodeGen { 23 23 /// mangles object and function names 24 void fixNames( std::list< Declaration* > translationUnit );24 void fixNames( std::list< Declaration* > & translationUnit ); 25 25 } // namespace CodeGen 26 26 -
src/Common/PassVisitor.h
r9c35431 rc13e8dc8 81 81 virtual void visit( FinallyStmt * finallyStmt ) override final; 82 82 virtual void visit( WaitForStmt * waitforStmt ) override final; 83 virtual void visit( WithStmt * withStmt ) override final; 83 84 virtual void visit( NullStmt * nullStmt ) override final; 84 85 virtual void visit( DeclStmt * declStmt ) override final; … … 172 173 virtual Statement * mutate( FinallyStmt * finallyStmt ) override final; 173 174 virtual Statement * mutate( WaitForStmt * waitforStmt ) override final; 175 virtual Statement * mutate( WithStmt * withStmt ) override final; 174 176 virtual NullStmt * mutate( NullStmt * nullStmt ) override final; 175 177 virtual Statement * mutate( DeclStmt * declStmt ) override final; … … 296 298 void indexerAddUnionFwd ( UnionDecl * node ) { indexer_impl_addUnionFwd ( pass, 0, node ); } 297 299 void indexerAddTrait ( TraitDecl * node ) { indexer_impl_addTrait ( pass, 0, node ); } 300 void indexerAddWith ( WithStmt * node ) { indexer_impl_addWith ( pass, 0, node ); } 301 298 302 299 303 template< typename TreeType, typename VisitorType > -
src/Common/PassVisitor.impl.h
r9c35431 rc13e8dc8 55 55 it, 56 56 [](Declaration * decl) -> auto { 57 return new DeclStmt( noLabels,decl );57 return new DeclStmt( decl ); 58 58 } 59 59 ); … … 251 251 || ( empty( beforeDecls ) && empty( afterDecls )) ); 252 252 253 CompoundStmt *compound = new CompoundStmt( noLabels);253 CompoundStmt *compound = new CompoundStmt(); 254 254 if( !empty(beforeDecls) ) { splice( std::back_inserter( compound->get_kids() ), beforeDecls ); } 255 255 if( !empty(beforeStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *beforeStmts ); } … … 400 400 { 401 401 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 402 // implicit add __func__ identifier as specified in the C manual 6.4.2.2 403 static ObjectDecl func( 404 "__func__", noStorageClasses, LinkageSpec::C, nullptr, 405 new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ), 406 nullptr 407 ); 408 indexerAddId( &func ); 402 409 maybeAccept_impl( node->type, *this ); 403 410 maybeAccept_impl( node->statements, *this ); … … 418 425 { 419 426 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 427 // implicit add __func__ identifier as specified in the C manual 6.4.2.2 428 static ObjectDecl func( 429 "__func__", noStorageClasses, LinkageSpec::C, nullptr, 430 new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ), 431 nullptr 432 ); 433 indexerAddId( &func ); 420 434 maybeMutate_impl( node->type, *this ); 421 435 maybeMutate_impl( node->statements, *this ); … … 969 983 Statement * PassVisitor< pass_type >::mutate( WaitForStmt * node ) { 970 984 MUTATE_BODY( Statement, node ); 985 } 986 987 988 989 //-------------------------------------------------------------------------- 990 // NullStmt 991 template< typename pass_type > 992 void PassVisitor< pass_type >::visit( WithStmt * node ) { 993 VISIT_START( node ); 994 maybeAccept_impl( node->exprs, *this ); 995 { 996 // catch statements introduce a level of scope (for the caught exception) 997 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 998 indexerAddWith( node ); 999 maybeAccept_impl( node->stmt, *this ); 1000 } 1001 VISIT_END( node ); 1002 } 1003 1004 template< typename pass_type > 1005 Statement * PassVisitor< pass_type >::mutate( WithStmt * node ) { 1006 MUTATE_START( node ); 1007 maybeMutate_impl( node->exprs, *this ); 1008 { 1009 // catch statements introduce a level of scope (for the caught exception) 1010 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1011 indexerAddWith( node ); 1012 maybeMutate_impl( node->stmt, *this ); 1013 } 1014 MUTATE_END( Statement, node ); 971 1015 } 972 1016 -
src/Common/PassVisitor.proto.h
r9c35431 rc13e8dc8 208 208 INDEXER_FUNC( addUnion , UnionDecl * ); 209 209 INDEXER_FUNC( addTrait , TraitDecl * ); 210 INDEXER_FUNC( addWith , WithStmt * ); 210 211 211 212 -
src/Concurrency/Keywords.cc
r9c35431 rc13e8dc8 38 38 39 39 namespace Concurrency { 40 41 namespace {42 const std::list<Label> noLabels;43 const std::list< Attribute * > noAttributes;44 Type::StorageClasses noStorage;45 Type::Qualifiers noQualifiers;46 }47 48 40 //============================================================================================= 49 41 // Pass declarations … … 296 288 ObjectDecl * this_decl = new ObjectDecl( 297 289 "this", 298 noStorage ,290 noStorageClasses, 299 291 LinkageSpec::Cforall, 300 292 nullptr, … … 313 305 new ObjectDecl( 314 306 "ret", 315 noStorage ,307 noStorageClasses, 316 308 LinkageSpec::Cforall, 317 309 nullptr, … … 346 338 main_decl = new FunctionDecl( 347 339 "main", 348 noStorage ,340 noStorageClasses, 349 341 LinkageSpec::Cforall, 350 342 main_type, … … 363 355 ObjectDecl * field = new ObjectDecl( 364 356 field_name, 365 noStorage ,357 noStorageClasses, 366 358 LinkageSpec::Cforall, 367 359 nullptr, … … 379 371 380 372 void ConcurrentSueKeyword::addRoutines( ObjectDecl * field, FunctionDecl * func ) { 381 CompoundStmt * statement = new CompoundStmt( noLabels);373 CompoundStmt * statement = new CompoundStmt(); 382 374 statement->push_back( 383 375 new ReturnStmt( 384 noLabels,385 376 new AddressExpr( 386 377 new MemberExpr( … … 488 479 ObjectDecl * monitors = new ObjectDecl( 489 480 "__monitor", 490 noStorage ,481 noStorageClasses, 491 482 LinkageSpec::Cforall, 492 483 nullptr, … … 509 500 // monitor_guard_t __guard = { __monitors, #, func }; 510 501 body->push_front( 511 new DeclStmt( n oLabels, new ObjectDecl(502 new DeclStmt( new ObjectDecl( 512 503 "__guard", 513 noStorage ,504 noStorageClasses, 514 505 LinkageSpec::Cforall, 515 506 nullptr, … … 530 521 531 522 //monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) }; 532 body->push_front( new DeclStmt( noLabels,monitors) );523 body->push_front( new DeclStmt( monitors) ); 533 524 } 534 525 … … 536 527 ObjectDecl * monitors = new ObjectDecl( 537 528 "__monitors", 538 noStorage ,529 noStorageClasses, 539 530 LinkageSpec::Cforall, 540 531 nullptr, … … 569 560 // monitor_guard_t __guard = { __monitors, #, func }; 570 561 body->push_front( 571 new DeclStmt( n oLabels, new ObjectDecl(562 new DeclStmt( new ObjectDecl( 572 563 "__guard", 573 noStorage ,564 noStorageClasses, 574 565 LinkageSpec::Cforall, 575 566 nullptr, … … 591 582 592 583 //monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) }; 593 body->push_front( new DeclStmt( noLabels,monitors) );584 body->push_front( new DeclStmt( monitors) ); 594 585 } 595 586 … … 631 622 stmt->push_back( 632 623 new ExprStmt( 633 noLabels,634 624 new UntypedExpr( 635 625 new NameExpr( "__thrd_start" ), -
src/Concurrency/Waitfor.cc
r9c35431 rc13e8dc8 100 100 101 101 namespace Concurrency { 102 103 namespace {104 const std::list<Label> noLabels;105 const std::list< Attribute * > noAttributes;106 Type::StorageClasses noStorage;107 Type::Qualifiers noQualifiers;108 }109 110 102 //============================================================================================= 111 103 // Pass declarations … … 203 195 ResolvExpr::findVoidExpression( expr, indexer ); 204 196 205 return new ExprStmt( noLabels,expr );197 return new ExprStmt( expr ); 206 198 } 207 199 … … 259 251 if( !decl_monitor || !decl_acceptable || !decl_mask ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor ); 260 252 261 CompoundStmt * stmt = new CompoundStmt( noLabels);253 CompoundStmt * stmt = new CompoundStmt(); 262 254 263 255 ObjectDecl * acceptables = declare( waitfor->clauses.size(), stmt ); … … 281 273 ); 282 274 283 CompoundStmt * compound = new CompoundStmt( noLabels);275 CompoundStmt * compound = new CompoundStmt(); 284 276 stmt->push_back( new IfStmt( 285 noLabels,286 277 safeCond( new VariableExpr( flag ) ), 287 278 compound, … … 313 304 ); 314 305 315 stmt->push_back( new DeclStmt( noLabels,acceptables) );306 stmt->push_back( new DeclStmt( acceptables) ); 316 307 317 308 Expression * set = new UntypedExpr( … … 326 317 ResolvExpr::findVoidExpression( set, indexer ); 327 318 328 stmt->push_back( new ExprStmt( noLabels,set ) );319 stmt->push_back( new ExprStmt( set ) ); 329 320 330 321 return acceptables; … … 341 332 ); 342 333 343 stmt->push_back( new DeclStmt( noLabels,flag) );334 stmt->push_back( new DeclStmt( flag) ); 344 335 345 336 return flag; … … 357 348 ResolvExpr::findVoidExpression( expr, indexer ); 358 349 359 return new ExprStmt( noLabels,expr );350 return new ExprStmt( expr ); 360 351 } 361 352 … … 399 390 ); 400 391 401 stmt->push_back( new DeclStmt( noLabels,mon) );392 stmt->push_back( new DeclStmt( mon) ); 402 393 403 394 return mon; … … 411 402 412 403 stmt->push_back( new IfStmt( 413 noLabels,414 404 safeCond( clause.condition ), 415 405 new CompoundStmt({ … … 447 437 ); 448 438 449 stmt->push_back( new DeclStmt( noLabels,timeout ) );439 stmt->push_back( new DeclStmt( timeout ) ); 450 440 451 441 if( time ) { 452 442 stmt->push_back( new IfStmt( 453 noLabels,454 443 safeCond( time_cond ), 455 444 new CompoundStmt({ 456 445 new ExprStmt( 457 noLabels,458 446 makeOpAssign( 459 447 new VariableExpr( timeout ), … … 471 459 if( has_else ) { 472 460 stmt->push_back( new IfStmt( 473 noLabels,474 461 safeCond( else_cond ), 475 462 new CompoundStmt({ 476 463 new ExprStmt( 477 noLabels,478 464 makeOpAssign( 479 465 new VariableExpr( timeout ), … … 511 497 ); 512 498 513 stmt->push_back( new DeclStmt( noLabels,index ) );499 stmt->push_back( new DeclStmt( index ) ); 514 500 515 501 ObjectDecl * mask = ObjectDecl::newObject( … … 526 512 ); 527 513 528 stmt->push_back( new DeclStmt( noLabels,mask ) );514 stmt->push_back( new DeclStmt( mask ) ); 529 515 530 516 stmt->push_back( new ExprStmt( 531 noLabels,532 517 new ApplicationExpr( 533 518 VariableExpr::functionPointer( decl_waitfor ), … … 557 542 ) { 558 543 SwitchStmt * swtch = new SwitchStmt( 559 noLabels,560 544 result, 561 545 std::list<Statement *>() … … 566 550 swtch->statements.push_back( 567 551 new CaseStmt( 568 noLabels,569 552 new ConstantExpr( Constant::from_ulong( i++ ) ), 570 553 { 571 554 clause.statement, 572 555 new BranchStmt( 573 noLabels,574 556 "", 575 557 BranchStmt::Break … … 583 565 swtch->statements.push_back( 584 566 new CaseStmt( 585 noLabels,586 567 new ConstantExpr( Constant::from_int( -2 ) ), 587 568 { 588 569 waitfor->timeout.statement, 589 570 new BranchStmt( 590 noLabels,591 571 "", 592 572 BranchStmt::Break … … 600 580 swtch->statements.push_back( 601 581 new CaseStmt( 602 noLabels,603 582 new ConstantExpr( Constant::from_int( -1 ) ), 604 583 { 605 584 waitfor->orelse.statement, 606 585 new BranchStmt( 607 noLabels,608 586 "", 609 587 BranchStmt::Break -
src/ControlStruct/ExceptTranslate.cc
r9c35431 rc13e8dc8 30 30 #include "SynTree/Expression.h" // for UntypedExpr, ConstantExpr, Name... 31 31 #include "SynTree/Initializer.h" // for SingleInit, ListInit 32 #include "SynTree/Label.h" // for Label , noLabels32 #include "SynTree/Label.h" // for Label 33 33 #include "SynTree/Mutator.h" // for mutateAll 34 34 #include "SynTree/Statement.h" // for CompoundStmt, CatchStmt, ThrowStmt … … 57 57 58 58 void appendDeclStmt( CompoundStmt * block, Declaration * item ) { 59 block->push_back(new DeclStmt( noLabels,item));59 block->push_back(new DeclStmt(item)); 60 60 } 61 61 … … 205 205 throwStmt->set_expr( nullptr ); 206 206 delete throwStmt; 207 return new ExprStmt( noLabels,call );207 return new ExprStmt( call ); 208 208 } 209 209 … … 211 211 ThrowStmt *throwStmt ) { 212 212 // __throw_terminate( `throwStmt->get_name()` ); } 213 return create_given_throw( "__cfa ehm__throw_terminate", throwStmt );213 return create_given_throw( "__cfaabi_ehm__throw_terminate", throwStmt ); 214 214 } 215 215 … … 220 220 assert( handler_except_decl ); 221 221 222 CompoundStmt * result = new CompoundStmt( throwStmt->get_labels() ); 223 result->push_back( new ExprStmt( noLabels, UntypedExpr::createAssign( 222 CompoundStmt * result = new CompoundStmt(); 223 result->labels = throwStmt->labels; 224 result->push_back( new ExprStmt( UntypedExpr::createAssign( 224 225 nameOf( handler_except_decl ), 225 226 new ConstantExpr( Constant::null( … … 231 232 ) ) ); 232 233 result->push_back( new ExprStmt( 233 noLabels, 234 new UntypedExpr( new NameExpr( "__cfaehm__rethrow_terminate" ) ) 234 new UntypedExpr( new NameExpr( "__cfaabi_ehm__rethrow_terminate" ) ) 235 235 ) ); 236 236 delete throwStmt; … … 241 241 ThrowStmt *throwStmt ) { 242 242 // __throw_resume( `throwStmt->get_name` ); 243 return create_given_throw( "__cfa ehm__throw_resume", throwStmt );243 return create_given_throw( "__cfaabi_ehm__throw_resume", throwStmt ); 244 244 } 245 245 … … 248 248 // return false; 249 249 Statement * result = new ReturnStmt( 250 throwStmt->get_labels(),251 250 new ConstantExpr( Constant::from_bool( false ) ) 252 251 ); 252 result->labels = throwStmt->labels; 253 253 delete throwStmt; 254 254 return result; … … 291 291 // } 292 292 // return; 293 CompoundStmt * block = new CompoundStmt( noLabels);293 CompoundStmt * block = new CompoundStmt(); 294 294 295 295 // Just copy the exception value. (Post Validation) … … 304 304 ) }) 305 305 ); 306 block->push_back( new DeclStmt( noLabels,local_except ) );306 block->push_back( new DeclStmt( local_except ) ); 307 307 308 308 // Add the cleanup attribute. 309 309 local_except->get_attributes().push_back( new Attribute( 310 310 "cleanup", 311 { new NameExpr( "__cfa ehm__cleanup_terminate" ) }311 { new NameExpr( "__cfaabi_ehm__cleanup_terminate" ) } 312 312 ) ); 313 313 … … 324 324 325 325 std::list<Statement *> caseBody 326 { block, new ReturnStmt( n oLabels, nullptr ) };326 { block, new ReturnStmt( nullptr ) }; 327 327 handler_wrappers.push_back( new CaseStmt( 328 noLabels,329 328 new ConstantExpr( Constant::from_int( index ) ), 330 329 caseBody … … 340 339 341 340 SwitchStmt * handler_lookup = new SwitchStmt( 342 noLabels,343 341 nameOf( index_obj ), 344 342 stmt_handlers 345 343 ); 346 CompoundStmt * body = new CompoundStmt( noLabels);344 CompoundStmt * body = new CompoundStmt(); 347 345 body->push_back( handler_lookup ); 348 346 … … 363 361 // } 364 362 365 CompoundStmt * block = new CompoundStmt( noLabels);363 CompoundStmt * block = new CompoundStmt(); 366 364 367 365 // Local Declaration … … 369 367 dynamic_cast<ObjectDecl *>( modded_handler->get_decl() ); 370 368 assert( local_except ); 371 block->push_back( new DeclStmt( noLabels,local_except ) );369 block->push_back( new DeclStmt( local_except ) ); 372 370 373 371 // Check for type match. … … 381 379 } 382 380 // Construct the match condition. 383 block->push_back( new IfStmt( noLabels,381 block->push_back( new IfStmt( 384 382 cond, modded_handler->get_body(), nullptr ) ); 385 383 … … 397 395 // } 398 396 399 CompoundStmt * body = new CompoundStmt( noLabels);397 CompoundStmt * body = new CompoundStmt(); 400 398 401 399 FunctionType * func_type = match_func_t.clone(); … … 413 411 414 412 // Create new body. 415 handler->set_body( new ReturnStmt( noLabels,413 handler->set_body( new ReturnStmt( 416 414 new ConstantExpr( Constant::from_int( index ) ) ) ); 417 415 … … 421 419 } 422 420 423 body->push_back( new ReturnStmt( noLabels,421 body->push_back( new ReturnStmt( 424 422 new ConstantExpr( Constant::from_int( 0 ) ) ) ); 425 423 … … 432 430 FunctionDecl * terminate_catch, 433 431 FunctionDecl * terminate_match ) { 434 // { __cfa ehm__try_terminate(`try`, `catch`, `match`); }432 // { __cfaabi_ehm__try_terminate(`try`, `catch`, `match`); } 435 433 436 434 UntypedExpr * caller = new UntypedExpr( new NameExpr( 437 "__cfa ehm__try_terminate" ) );435 "__cfaabi_ehm__try_terminate" ) ); 438 436 std::list<Expression *>& args = caller->get_args(); 439 437 args.push_back( nameOf( try_wrapper ) ); … … 441 439 args.push_back( nameOf( terminate_match ) ); 442 440 443 CompoundStmt * callStmt = new CompoundStmt( noLabels);444 callStmt->push_back( new ExprStmt( noLabels,caller ) );441 CompoundStmt * callStmt = new CompoundStmt(); 442 callStmt->push_back( new ExprStmt( caller ) ); 445 443 return callStmt; 446 444 } … … 451 449 // HANDLER WRAPPERS { `hander->body`; return true; } 452 450 // } 453 CompoundStmt * body = new CompoundStmt( noLabels);451 CompoundStmt * body = new CompoundStmt(); 454 452 455 453 FunctionType * func_type = handle_func_t.clone(); … … 464 462 dynamic_cast<CompoundStmt*>( handler->get_body() ); 465 463 if ( ! handling_code ) { 466 handling_code = new CompoundStmt( noLabels);464 handling_code = new CompoundStmt(); 467 465 handling_code->push_back( handler->get_body() ); 468 466 } 469 handling_code->push_back( new ReturnStmt( noLabels,467 handling_code->push_back( new ReturnStmt( 470 468 new ConstantExpr( Constant::from_bool( true ) ) ) ); 471 469 handler->set_body( handling_code ); … … 476 474 } 477 475 478 body->push_back( new ReturnStmt( noLabels,476 body->push_back( new ReturnStmt( 479 477 new ConstantExpr( Constant::from_bool( false ) ) ) ); 480 478 … … 486 484 Statement * wraps, 487 485 FunctionDecl * resume_handler ) { 488 CompoundStmt * body = new CompoundStmt( noLabels);486 CompoundStmt * body = new CompoundStmt(); 489 487 490 488 // struct __try_resume_node __resume_node 491 // __attribute__((cleanup( __cfa ehm__try_resume_cleanup )));489 // __attribute__((cleanup( __cfaabi_ehm__try_resume_cleanup ))); 492 490 // ** unwinding of the stack here could cause problems ** 493 491 // ** however I don't think that can happen currently ** 494 // __cfa ehm__try_resume_setup( &__resume_node, resume_handler );492 // __cfaabi_ehm__try_resume_setup( &__resume_node, resume_handler ); 495 493 496 494 std::list< Attribute * > attributes; … … 498 496 std::list< Expression * > attr_params; 499 497 attr_params.push_back( new NameExpr( 500 "__cfa ehm__try_resume_cleanup" ) );498 "__cfaabi_ehm__try_resume_cleanup" ) ); 501 499 attributes.push_back( new Attribute( "cleanup", attr_params ) ); 502 500 } … … 517 515 518 516 UntypedExpr *setup = new UntypedExpr( new NameExpr( 519 "__cfa ehm__try_resume_setup" ) );517 "__cfaabi_ehm__try_resume_setup" ) ); 520 518 setup->get_args().push_back( new AddressExpr( nameOf( obj ) ) ); 521 519 setup->get_args().push_back( nameOf( resume_handler ) ); 522 520 523 body->push_back( new ExprStmt( noLabels,setup ) );521 body->push_back( new ExprStmt( setup ) ); 524 522 525 523 body->push_back( wraps ); … … 542 540 ObjectDecl * ExceptionMutatorCore::create_finally_hook( 543 541 FunctionDecl * finally_wrapper ) { 544 // struct __cfa ehm__cleanup_hook __finally_hook542 // struct __cfaabi_ehm__cleanup_hook __finally_hook 545 543 // __attribute__((cleanup( finally_wrapper ))); 546 544 … … 596 594 // Skip children? 597 595 return; 598 } else if ( structDecl->get_name() == "__cfa ehm__base_exception_t" ) {596 } else if ( structDecl->get_name() == "__cfaabi_ehm__base_exception_t" ) { 599 597 assert( nullptr == except_decl ); 600 598 except_decl = structDecl; 601 599 init_func_types(); 602 } else if ( structDecl->get_name() == "__cfa ehm__try_resume_node" ) {600 } else if ( structDecl->get_name() == "__cfaabi_ehm__try_resume_node" ) { 603 601 assert( nullptr == node_decl ); 604 602 node_decl = structDecl; 605 } else if ( structDecl->get_name() == "__cfa ehm__cleanup_hook" ) {603 } else if ( structDecl->get_name() == "__cfaabi_ehm__cleanup_hook" ) { 606 604 assert( nullptr == hook_decl ); 607 605 hook_decl = structDecl; … … 646 644 // Generate a prefix for the function names? 647 645 648 CompoundStmt * block = new CompoundStmt( noLabels);646 CompoundStmt * block = new CompoundStmt(); 649 647 CompoundStmt * inner = take_try_block( tryStmt ); 650 648 -
src/ControlStruct/ForExprMutator.cc
r9c35431 rc13e8dc8 29 29 // Create compound statement, move initializers outside, 30 30 // the resut of the original stays as is. 31 CompoundStmt *block = new CompoundStmt( std::list< Label >());31 CompoundStmt *block = new CompoundStmt(); 32 32 std::list<Statement *> &stmts = block->get_kids(); 33 33 stmts.splice( stmts.end(), init ); -
src/ControlStruct/LabelFixer.cc
r9c35431 rc13e8dc8 37 37 } 38 38 39 void LabelFixer:: visit( FunctionDecl *functionDecl) {39 void LabelFixer::previsit( FunctionDecl * ) { 40 40 // need to go into a nested function in a fresh state 41 std::map < Label, Entry *> oldLabelTable = labelTable;41 GuardValue( labelTable ); 42 42 labelTable.clear(); 43 } 43 44 44 maybeAccept( functionDecl->get_statements(), *this ); 45 45 void LabelFixer::postvisit( FunctionDecl * functionDecl ) { 46 46 MLEMutator mlemut( resolveJumps(), generator ); 47 47 functionDecl->acceptMutator( mlemut ); 48 49 // and remember the outer function's labels when50 // returning to it51 labelTable = oldLabelTable;52 48 } 53 49 54 50 // prune to at most one label definition for each statement 55 void LabelFixer:: visit( Statement *stmt ) {51 void LabelFixer::previsit( Statement *stmt ) { 56 52 std::list< Label > &labels = stmt->get_labels(); 57 53 … … 62 58 } 63 59 64 void LabelFixer:: visit( BranchStmt *branchStmt ) {65 visit ( ( Statement *)branchStmt );60 void LabelFixer::previsit( BranchStmt *branchStmt ) { 61 previsit( ( Statement *)branchStmt ); 66 62 67 63 // for labeled branches, add an entry to the label table … … 72 68 } 73 69 74 void LabelFixer::visit( UntypedExpr *untyped ) { 75 if ( NameExpr * func = dynamic_cast< NameExpr * >( untyped->get_function() ) ) { 76 if ( func->get_name() == "&&" ) { 77 NameExpr * arg = dynamic_cast< NameExpr * >( untyped->get_args().front() ); 78 Label target = arg->get_name(); 79 assert( target != "" ); 80 setLabelsUsg( target, untyped ); 81 } else { 82 Visitor::visit( untyped ); 83 } 84 } 70 void LabelFixer::previsit( LabelAddressExpr * addrExpr ) { 71 Label & target = addrExpr->arg; 72 assert( target != "" ); 73 setLabelsUsg( target, addrExpr ); 85 74 } 86 75 -
src/ControlStruct/LabelFixer.h
r9c35431 rc13e8dc8 19 19 #include <map> // for map 20 20 21 #include "Common/PassVisitor.h" 21 22 #include "Common/SemanticError.h" // for SemanticError 22 23 #include "SynTree/Label.h" // for Label … … 26 27 namespace ControlStruct { 27 28 /// normalizes label definitions and generates multi-level exit labels 28 class LabelGenerator;29 class LabelGenerator; 29 30 30 class LabelFixer final : public Visitor { 31 typedef Visitor Parent; 31 class LabelFixer final : public WithGuards { 32 32 public: 33 33 LabelFixer( LabelGenerator *gen = 0 ); … … 35 35 std::map < Label, Statement * > *resolveJumps() throw ( SemanticError ); 36 36 37 using Visitor::visit;38 39 37 // Declarations 40 virtual void visit( FunctionDecl *functionDecl ) override; 38 void previsit( FunctionDecl *functionDecl ); 39 void postvisit( FunctionDecl *functionDecl ); 41 40 42 41 // Statements 43 void visit( Statement *stmt ); 42 void previsit( Statement *stmt ); 43 void previsit( BranchStmt *branchStmt ); 44 44 45 virtual void visit( CompoundStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); } 46 virtual void visit( NullStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); } 47 virtual void visit( ExprStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); } 48 virtual void visit( IfStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); } 49 virtual void visit( WhileStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); } 50 virtual void visit( ForStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); } 51 virtual void visit( SwitchStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); } 52 virtual void visit( CaseStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); } 53 virtual void visit( ReturnStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); } 54 virtual void visit( TryStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); } 55 virtual void visit( CatchStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); } 56 virtual void visit( DeclStmt *stmt ) override { visit( (Statement *)stmt ); return Parent::visit( stmt ); } 57 virtual void visit( BranchStmt *branchStmt ) override; 58 virtual void visit( UntypedExpr *untyped ) override; 45 // Expressions 46 void previsit( LabelAddressExpr *addrExpr ); 59 47 60 48 Label setLabelsDef( std::list< Label > &, Statement *definition ); -
src/ControlStruct/MLEMutator.cc
r9c35431 rc13e8dc8 149 149 150 150 if ( CaseStmt * c = dynamic_cast< CaseStmt * >( statements.back() ) ) { 151 std::list<Label> temp; temp.push_back( brkLabel ); 152 c->get_statements().push_back( new BranchStmt( temp, Label("brkLabel"), BranchStmt::Break ) ); 151 Statement * stmt = new BranchStmt( Label("brkLabel"), BranchStmt::Break ); 152 stmt->labels.push_back( brkLabel ); 153 c->get_statements().push_back( stmt ); 153 154 } else assert(0); // as of this point, all statements of a switch are still CaseStmts 154 155 } // if … … 232 233 // transform break/continue statements into goto to simplify later handling of branches 233 234 delete branchStmt; 234 return new BranchStmt( std::list<Label>(),exitLabel, BranchStmt::Goto );235 return new BranchStmt( exitLabel, BranchStmt::Goto ); 235 236 } 236 237 … … 239 240 CompoundStmt *newBody; 240 241 if ( ! (newBody = dynamic_cast<CompoundStmt *>( bodyLoop )) ) { 241 newBody = new CompoundStmt( std::list< Label >());242 newBody = new CompoundStmt(); 242 243 newBody->get_kids().push_back( bodyLoop ); 243 244 } // if -
src/ControlStruct/Mutate.cc
r9c35431 rc13e8dc8 24 24 #include "SynTree/Declaration.h" // for Declaration 25 25 #include "SynTree/Mutator.h" // for mutateAll 26 //#include "ExceptMutator.h"27 26 28 27 #include "Common/PassVisitor.h" // for PassVisitor … … 37 36 38 37 // normalizes label definitions and generates multi-level exit labels 39 LabelFixer lfix; 40 41 //ExceptMutator exc; 38 PassVisitor<LabelFixer> lfix; 42 39 43 40 mutateAll( translationUnit, formut ); 44 41 acceptAll( translationUnit, lfix ); 45 //mutateAll( translationUnit, exc );46 42 } 47 43 } // namespace CodeGen -
src/GenPoly/Box.cc
r9c35431 rc13e8dc8 49 49 #include "SynTree/Expression.h" // for ApplicationExpr, UntypedExpr 50 50 #include "SynTree/Initializer.h" // for SingleInit, Initializer, Lis... 51 #include "SynTree/Label.h" // for Label , noLabels51 #include "SynTree/Label.h" // for Label 52 52 #include "SynTree/Mutator.h" // for maybeMutate, Mutator, mutateAll 53 53 #include "SynTree/Statement.h" // for ExprStmt, DeclStmt, ReturnStmt … … 293 293 FunctionDecl *layoutDecl = new FunctionDecl( layoutofName( typeDecl ), 294 294 functionNesting > 0 ? Type::StorageClasses() : Type::StorageClasses( Type::Static ), 295 LinkageSpec::AutoGen, layoutFnType, new CompoundStmt( noLabels),295 LinkageSpec::AutoGen, layoutFnType, new CompoundStmt(), 296 296 std::list< Attribute * >(), Type::FuncSpecifiers( Type::Inline ) ); 297 297 layoutDecl->fixUniqueId(); … … 321 321 /// makes an if-statement with a single-expression if-block and no then block 322 322 Statement *makeCond( Expression *cond, Expression *ifPart ) { 323 return new IfStmt( noLabels, cond, new ExprStmt( noLabels,ifPart ), 0 );323 return new IfStmt( cond, new ExprStmt( ifPart ), 0 ); 324 324 } 325 325 … … 340 340 /// adds an expression to a compound statement 341 341 void addExpr( CompoundStmt *stmts, Expression *expr ) { 342 stmts->get_kids().push_back( new ExprStmt( noLabels,expr ) );342 stmts->get_kids().push_back( new ExprStmt( expr ) ); 343 343 } 344 344 … … 629 629 ObjectDecl *Pass1::makeTemporary( Type *type ) { 630 630 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, type, 0 ); 631 stmtsToAddBefore.push_back( new DeclStmt( n oLabels, newObj ) );631 stmtsToAddBefore.push_back( new DeclStmt( newObj ) ); 632 632 return newObj; 633 633 } … … 740 740 ObjectDecl *newObj = ObjectDecl::newObject( tempNamer.newName(), newType, nullptr ); 741 741 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right??? 742 stmtsToAddBefore.push_back( new DeclStmt( n oLabels, newObj ) );742 stmtsToAddBefore.push_back( new DeclStmt( newObj ) ); 743 743 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax? 744 744 assign->get_args().push_back( new VariableExpr( newObj ) ); 745 745 assign->get_args().push_back( arg ); 746 stmtsToAddBefore.push_back( new ExprStmt( noLabels,assign ) );746 stmtsToAddBefore.push_back( new ExprStmt( assign ) ); 747 747 arg = new AddressExpr( new VariableExpr( newObj ) ); 748 748 } // if … … 888 888 // void return 889 889 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars ); 890 bodyStmt = new ExprStmt( noLabels,adapteeApp );890 bodyStmt = new ExprStmt( adapteeApp ); 891 891 } else if ( isDynType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) { 892 892 // return type T … … 900 900 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars ); 901 901 assign->get_args().push_back( adapteeApp ); 902 bodyStmt = new ExprStmt( noLabels,assign );902 bodyStmt = new ExprStmt( assign ); 903 903 } else { 904 904 // adapter for a function that returns a monomorphic value 905 905 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars ); 906 bodyStmt = new ReturnStmt( noLabels,adapteeApp );906 bodyStmt = new ReturnStmt( adapteeApp ); 907 907 } // if 908 CompoundStmt *adapterBody = new CompoundStmt( noLabels);908 CompoundStmt *adapterBody = new CompoundStmt(); 909 909 adapterBody->get_kids().push_back( bodyStmt ); 910 910 std::string adapterName = makeAdapterName( mangleName ); … … 952 952 std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) ); 953 953 adapter = answer.first; 954 stmtsToAddBefore.push_back( new DeclStmt( n oLabels, newAdapter ) );954 stmtsToAddBefore.push_back( new DeclStmt( newAdapter ) ); 955 955 } // if 956 956 assert( adapter != adapters.end() ); … … 1279 1279 retval->set_name( "_retval" ); 1280 1280 } 1281 functionDecl->get_statements()->get_kids().push_front( new DeclStmt( noLabels,retval ) );1281 functionDecl->get_statements()->get_kids().push_front( new DeclStmt( retval ) ); 1282 1282 DeclarationWithType * newRet = retval->clone(); // for ownership purposes 1283 1283 ftype->get_returnVals().front() = newRet; … … 1519 1519 // (alloca was previously used, but can't be safely used in loops) 1520 1520 ObjectDecl *newBuf = ObjectDecl::newObject( bufNamer.newName(), polyToMonoType( objectDecl->type ), nullptr ); 1521 stmtsToAddBefore.push_back( new DeclStmt( n oLabels, newBuf ) );1521 stmtsToAddBefore.push_back( new DeclStmt( newBuf ) ); 1522 1522 1523 1523 delete objectDecl->get_init(); … … 1598 1598 ObjectDecl *PolyGenericCalculator::makeVar( const std::string &name, Type *type, Initializer *init ) { 1599 1599 ObjectDecl *newObj = new ObjectDecl( name, Type::StorageClasses(), LinkageSpec::C, 0, type, init ); 1600 stmtsToAddBefore.push_back( new DeclStmt( n oLabels, newObj ) );1600 stmtsToAddBefore.push_back( new DeclStmt( newObj ) ); 1601 1601 return newObj; 1602 1602 } … … 1677 1677 addOtypeParamsToLayoutCall( layoutCall, otypeParams ); 1678 1678 1679 stmtsToAddBefore.push_back( new ExprStmt( noLabels,layoutCall ) );1679 stmtsToAddBefore.push_back( new ExprStmt( layoutCall ) ); 1680 1680 } 1681 1681 … … 1703 1703 addOtypeParamsToLayoutCall( layoutCall, otypeParams ); 1704 1704 1705 stmtsToAddBefore.push_back( new ExprStmt( noLabels,layoutCall ) );1705 stmtsToAddBefore.push_back( new ExprStmt( layoutCall ) ); 1706 1706 1707 1707 return true; -
src/GenPoly/InstantiateGeneric.cc
r9c35431 rc13e8dc8 453 453 return false; 454 454 } 455 456 AggregateDecl * getAggr( Type * t ) {457 if ( StructInstType * inst = dynamic_cast< StructInstType * >( t ) ) {458 return inst->baseStruct;459 } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( t ) ) {460 return inst->baseUnion;461 }462 assertf( false, "Non-aggregate type: %s", toString( t ).c_str() );463 }464 455 } 465 456 … … 469 460 if ( isGenericType( memberExpr->aggregate->result ) ) { 470 461 // find the location of the member 471 AggregateDecl * aggr = getAggr( memberExpr->aggregate->result);462 AggregateDecl * aggr = memberExpr->aggregate->result->getAggr(); 472 463 std::list< Declaration * > & members = aggr->members; 473 464 memberIndex = std::distance( members.begin(), std::find( members.begin(), members.end(), memberExpr->member ) ); … … 479 470 if ( memberIndex != -1 ) { 480 471 // using the location from the generic type, find the member in the instantiation and rebuild the member expression 481 AggregateDecl * aggr = getAggr( memberExpr->aggregate->result);472 AggregateDecl * aggr = memberExpr->aggregate->result->getAggr(); 482 473 assertf( memberIndex < (int)aggr->members.size(), "Instantiation somehow has fewer members than the generic type." ); 483 474 Declaration * member = *std::next( aggr->members.begin(), memberIndex ); … … 526 517 Expression * init = new CastExpr( new AddressExpr( memberExpr ), new PointerType( Type::Qualifiers(), concType->clone() ) ); 527 518 ObjectDecl * tmp = ObjectDecl::newObject( tmpNamer.newName(), new ReferenceType( Type::Qualifiers(), concType ), new SingleInit( init ) ); 528 stmtsToAddBefore.push_back( new DeclStmt( noLabels,tmp ) );519 stmtsToAddBefore.push_back( new DeclStmt( tmp ) ); 529 520 return new VariableExpr( tmp ); 530 521 } else { -
src/GenPoly/Specialize.cc
r9c35431 rc13e8dc8 35 35 #include "SynTree/Declaration.h" // for FunctionDecl, DeclarationWit... 36 36 #include "SynTree/Expression.h" // for ApplicationExpr, Expression 37 #include "SynTree/Label.h" // for Label , noLabels37 #include "SynTree/Label.h" // for Label 38 38 #include "SynTree/Mutator.h" // for mutateAll 39 39 #include "SynTree/Statement.h" // for CompoundStmt, DeclStmt, Expr... … … 234 234 } // if 235 235 // create new thunk with same signature as formal type (C linkage, empty body) 236 FunctionDecl *thunkFunc = new FunctionDecl( thunkNamer.newName(), Type::StorageClasses(), LinkageSpec::C, newType, new CompoundStmt( noLabels) );236 FunctionDecl *thunkFunc = new FunctionDecl( thunkNamer.newName(), Type::StorageClasses(), LinkageSpec::C, newType, new CompoundStmt() ); 237 237 thunkFunc->fixUniqueId(); 238 238 … … 287 287 Statement *appStmt; 288 288 if ( funType->returnVals.empty() ) { 289 appStmt = new ExprStmt( noLabels,appExpr );290 } else { 291 appStmt = new ReturnStmt( noLabels,appExpr );289 appStmt = new ExprStmt( appExpr ); 290 } else { 291 appStmt = new ReturnStmt( appExpr ); 292 292 } // if 293 293 thunkFunc->statements->kids.push_back( appStmt ); 294 294 295 295 // add thunk definition to queue of statements to add 296 stmtsToAddBefore.push_back( new DeclStmt( noLabels,thunkFunc ) );296 stmtsToAddBefore.push_back( new DeclStmt( thunkFunc ) ); 297 297 // return address of thunk function as replacement expression 298 298 return new AddressExpr( new VariableExpr( thunkFunc ) ); -
src/InitTweak/FixGlobalInit.cc
r9c35431 rc13e8dc8 20 20 #include <algorithm> // for replace_if 21 21 22 #include "Common/PassVisitor.h" 22 23 #include "Common/SemanticError.h" // for SemanticError 23 24 #include "Common/UniqueName.h" // for UniqueName … … 29 30 #include "SynTree/Expression.h" // for ConstantExpr, Expression (ptr only) 30 31 #include "SynTree/Initializer.h" // for ConstructorInit, Initializer 31 #include "SynTree/Label.h" // for Label , noLabels32 #include "SynTree/Label.h" // for Label 32 33 #include "SynTree/Statement.h" // for CompoundStmt, Statement (ptr only) 33 34 #include "SynTree/Type.h" // for Type, Type::StorageClasses, Functi... … … 35 36 36 37 namespace InitTweak { 37 class GlobalFixer : public Visitor{38 class GlobalFixer : public WithShortCircuiting { 38 39 public: 39 40 GlobalFixer( const std::string & name, bool inLibrary ); 40 41 41 v irtual voidvisit( ObjectDecl *objDecl );42 v irtual voidvisit( FunctionDecl *functionDecl );43 v irtual voidvisit( StructDecl *aggregateDecl );44 v irtual voidvisit( UnionDecl *aggregateDecl );45 v irtual voidvisit( EnumDecl *aggregateDecl );46 v irtual voidvisit( TraitDecl *aggregateDecl );47 v irtual voidvisit( TypeDecl *typeDecl );42 void previsit( ObjectDecl *objDecl ); 43 void previsit( FunctionDecl *functionDecl ); 44 void previsit( StructDecl *aggregateDecl ); 45 void previsit( UnionDecl *aggregateDecl ); 46 void previsit( EnumDecl *aggregateDecl ); 47 void previsit( TraitDecl *aggregateDecl ); 48 void previsit( TypeDecl *typeDecl ); 48 49 49 50 UniqueName tempNamer; … … 53 54 54 55 void fixGlobalInit( std::list< Declaration * > & translationUnit, const std::string & name, bool inLibrary ) { 55 GlobalFixer fixer( name, inLibrary ); 56 acceptAll( translationUnit, fixer ); 56 PassVisitor<GlobalFixer> visitor( name, inLibrary ); 57 acceptAll( translationUnit, visitor ); 58 GlobalFixer & fixer = visitor.pass; 57 59 // don't need to include function if it's empty 58 60 if ( fixer.initFunction->get_statements()->get_kids().empty() ) { … … 92 94 dtorParameters.push_back( new ConstantExpr( Constant::from_int( 102 ) ) ); 93 95 } 94 initFunction = new FunctionDecl( "_init_" + fixedName, Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels) );96 initFunction = new FunctionDecl( "_init_" + fixedName, Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt() ); 95 97 initFunction->get_attributes().push_back( new Attribute( "constructor", ctorParameters ) ); 96 destroyFunction = new FunctionDecl( "_destroy_" + fixedName, Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels) );98 destroyFunction = new FunctionDecl( "_destroy_" + fixedName, Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt() ); 97 99 destroyFunction->get_attributes().push_back( new Attribute( "destructor", dtorParameters ) ); 98 100 } 99 101 100 void GlobalFixer:: visit( ObjectDecl *objDecl ) {102 void GlobalFixer::previsit( ObjectDecl *objDecl ) { 101 103 std::list< Statement * > & initStatements = initFunction->get_statements()->get_kids(); 102 104 std::list< Statement * > & destroyStatements = destroyFunction->get_statements()->get_kids(); … … 134 136 135 137 // only modify global variables 136 void GlobalFixer:: visit( __attribute__((unused)) FunctionDecl *functionDecl ) {}137 void GlobalFixer:: visit( __attribute__((unused)) StructDecl *aggregateDecl ) {}138 void GlobalFixer:: visit( __attribute__((unused)) UnionDecl *aggregateDecl ) {}139 void GlobalFixer:: visit( __attribute__((unused)) EnumDecl *aggregateDecl ) {}140 void GlobalFixer:: visit( __attribute__((unused)) TraitDecl *aggregateDecl ) {}141 void GlobalFixer:: visit( __attribute__((unused)) TypeDecl *typeDecl ) {}138 void GlobalFixer::previsit( FunctionDecl * ) { visit_children = false; } 139 void GlobalFixer::previsit( StructDecl * ) { visit_children = false; } 140 void GlobalFixer::previsit( UnionDecl * ) { visit_children = false; } 141 void GlobalFixer::previsit( EnumDecl * ) { visit_children = false; } 142 void GlobalFixer::previsit( TraitDecl * ) { visit_children = false; } 143 void GlobalFixer::previsit( TypeDecl * ) { visit_children = false; } 142 144 143 145 } // namespace InitTweak -
src/InitTweak/FixInit.cc
r9c35431 rc13e8dc8 49 49 #include "SynTree/Expression.h" // for UniqueExpr, VariableExpr, Unty... 50 50 #include "SynTree/Initializer.h" // for ConstructorInit, SingleInit 51 #include "SynTree/Label.h" // for Label, noLabels,operator<51 #include "SynTree/Label.h" // for Label, operator< 52 52 #include "SynTree/Mutator.h" // for mutateAll, Mutator, maybeMutate 53 53 #include "SynTree/Statement.h" // for ExprStmt, CompoundStmt, Branch... … … 547 547 // add all temporary declarations and their constructors 548 548 for ( ObjectDecl * obj : tempDecls ) { 549 stmtsToAddBefore.push_back( new DeclStmt( noLabels,obj ) );549 stmtsToAddBefore.push_back( new DeclStmt( obj ) ); 550 550 } // for 551 551 for ( ObjectDecl * obj : returnDecls ) { 552 stmtsToAddBefore.push_back( new DeclStmt( noLabels,obj ) );552 stmtsToAddBefore.push_back( new DeclStmt( obj ) ); 553 553 } // for 554 554 555 555 // add destructors after current statement 556 556 for ( Expression * dtor : dtors ) { 557 stmtsToAddAfter.push_back( new ExprStmt( noLabels,dtor ) );557 stmtsToAddAfter.push_back( new ExprStmt( dtor ) ); 558 558 } // for 559 559 … … 601 601 if ( ! result->isVoid() ) { 602 602 for ( ObjectDecl * obj : stmtExpr->get_returnDecls() ) { 603 stmtsToAddBefore.push_back( new DeclStmt( noLabels,obj ) );603 stmtsToAddBefore.push_back( new DeclStmt( obj ) ); 604 604 } // for 605 605 // add destructors after current statement 606 606 for ( Expression * dtor : stmtExpr->get_dtors() ) { 607 stmtsToAddAfter.push_back( new ExprStmt( noLabels,dtor ) );607 stmtsToAddAfter.push_back( new ExprStmt( dtor ) ); 608 608 } // for 609 609 // must have a non-empty body, otherwise it wouldn't have a result 610 610 assert( ! stmts.empty() ); 611 611 assert( ! stmtExpr->get_returnDecls().empty() ); 612 stmts.push_back( new ExprStmt( n oLabels, new VariableExpr( stmtExpr->get_returnDecls().front() ) ) );612 stmts.push_back( new ExprStmt( new VariableExpr( stmtExpr->get_returnDecls().front() ) ) ); 613 613 stmtExpr->get_returnDecls().clear(); 614 614 stmtExpr->get_dtors().clear(); … … 739 739 740 740 // generate body of if 741 CompoundStmt * initStmts = new CompoundStmt( noLabels);741 CompoundStmt * initStmts = new CompoundStmt(); 742 742 std::list< Statement * > & body = initStmts->get_kids(); 743 743 body.push_back( ctor ); 744 body.push_back( new ExprStmt( noLabels,setTrue ) );744 body.push_back( new ExprStmt( setTrue ) ); 745 745 746 746 // put it all together 747 IfStmt * ifStmt = new IfStmt( n oLabels, new VariableExpr( isUninitializedVar ), initStmts, 0 );748 stmtsToAddAfter.push_back( new DeclStmt( noLabels,isUninitializedVar ) );747 IfStmt * ifStmt = new IfStmt( new VariableExpr( isUninitializedVar ), initStmts, 0 ); 748 stmtsToAddAfter.push_back( new DeclStmt( isUninitializedVar ) ); 749 749 stmtsToAddAfter.push_back( ifStmt ); 750 750 … … 761 761 762 762 // void __objName_dtor_atexitN(...) {...} 763 FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + dtorCallerNamer.newName(), Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels) );763 FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + dtorCallerNamer.newName(), Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt() ); 764 764 dtorCaller->fixUniqueId(); 765 765 dtorCaller->get_statements()->push_back( dtorStmt ); … … 769 769 callAtexit->get_args().push_back( new VariableExpr( dtorCaller ) ); 770 770 771 body.push_back( new ExprStmt( noLabels,callAtexit ) );771 body.push_back( new ExprStmt( callAtexit ) ); 772 772 773 773 // hoist variable and dtor caller decls to list of decls that will be added into global scope -
src/InitTweak/InitTweak.cc
r9c35431 rc13e8dc8 5 5 #include <memory> // for __shared_ptr 6 6 7 #include "Common/PassVisitor.h" 7 8 #include "Common/SemanticError.h" // for SemanticError 8 9 #include "Common/UniqueName.h" // for UniqueName … … 19 20 #include "SynTree/Expression.h" // for Expression, UntypedExpr, Applicati... 20 21 #include "SynTree/Initializer.h" // for Initializer, ListInit, Designation 21 #include "SynTree/Label.h" // for Label , noLabels22 #include "SynTree/Label.h" // for Label 22 23 #include "SynTree/Statement.h" // for CompoundStmt, ExprStmt, BranchStmt 23 24 #include "SynTree/Type.h" // for FunctionType, ArrayType, PointerType … … 29 30 namespace InitTweak { 30 31 namespace { 31 class HasDesignations : public Visitor { 32 public: 32 struct HasDesignations : public WithShortCircuiting { 33 33 bool hasDesignations = false; 34 virtual void visit( Designation * des ) { 35 if ( ! des->get_designators().empty() ) hasDesignations = true; 36 else Visitor::visit( des ); 34 35 void previsit( BaseSyntaxNode * ) { 36 // short circuit if we already know there are designations 37 if ( hasDesignations ) visit_children = false; 38 } 39 40 void previsit( Designation * des ) { 41 // short circuit if we already know there are designations 42 if ( hasDesignations ) visit_children = false; 43 else if ( ! des->get_designators().empty() ) { 44 hasDesignations = true; 45 visit_children = false; 46 } 37 47 } 38 48 }; 39 49 40 class InitDepthChecker : public Visitor { 41 public: 50 struct InitDepthChecker : public WithGuards { 42 51 bool depthOkay = true; 43 52 Type * type; … … 51 60 maxDepth++; 52 61 } 53 v irtual void visit( ListInit * listInit) {62 void previsit( ListInit * ) { 54 63 curDepth++; 64 GuardAction( [this]() { curDepth--; } ); 55 65 if ( curDepth > maxDepth ) depthOkay = false; 56 Visitor::visit( listInit );57 curDepth--;58 66 } 59 67 }; 60 68 61 class InitFlattener : public Visitor { 62 public: 63 virtual void visit( SingleInit * singleInit ); 64 virtual void visit( ListInit * listInit ); 69 struct InitFlattener : public WithShortCircuiting { 70 void previsit( SingleInit * singleInit ) { 71 visit_children = false; 72 argList.push_back( singleInit->value->clone() ); 73 } 65 74 std::list< Expression * > argList; 66 75 }; 67 76 68 void InitFlattener::visit( SingleInit * singleInit ) {69 argList.push_back( singleInit->get_value()->clone() );70 }71 72 void InitFlattener::visit( ListInit * listInit ) {73 // flatten nested list inits74 std::list<Initializer*>::iterator it = listInit->begin();75 for ( ; it != listInit->end(); ++it ) {76 (*it)->accept( *this );77 }78 }79 77 } 80 78 81 79 std::list< Expression * > makeInitList( Initializer * init ) { 82 InitFlattenerflattener;80 PassVisitor<InitFlattener> flattener; 83 81 maybeAccept( init, flattener ); 84 return flattener. argList;82 return flattener.pass.argList; 85 83 } 86 84 87 85 bool isDesignated( Initializer * init ) { 88 HasDesignationsfinder;86 PassVisitor<HasDesignations> finder; 89 87 maybeAccept( init, finder ); 90 return finder. hasDesignations;88 return finder.pass.hasDesignations; 91 89 } 92 90 93 91 bool checkInitDepth( ObjectDecl * objDecl ) { 94 InitDepthChecker checker( objDecl->get_type());95 maybeAccept( objDecl-> get_init(), checker );96 return checker. depthOkay;92 PassVisitor<InitDepthChecker> checker( objDecl->type ); 93 maybeAccept( objDecl->init, checker ); 94 return checker.pass.depthOkay; 97 95 } 98 96 … … 195 193 callExpr->get_args().splice( callExpr->get_args().end(), args ); 196 194 197 *out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels,callExpr ), nullptr );195 *out++ = new IfStmt( cond, new ExprStmt( callExpr ), nullptr ); 198 196 199 197 UntypedExpr * increment = new UntypedExpr( new NameExpr( "++?" ) ); 200 198 increment->get_args().push_back( index->clone() ); 201 *out++ = new ExprStmt( noLabels,increment );199 *out++ = new ExprStmt( increment ); 202 200 } 203 201 … … 244 242 std::list< Statement * > stmts; 245 243 build( callExpr, idx, idxEnd, init, back_inserter( stmts ) ); 246 stmts.push_back( new BranchStmt( noLabels,switchLabel, BranchStmt::Break ) );247 CaseStmt * caseStmt = new CaseStmt( noLabels,condition, stmts );244 stmts.push_back( new BranchStmt( switchLabel, BranchStmt::Break ) ); 245 CaseStmt * caseStmt = new CaseStmt( condition, stmts ); 248 246 branches.push_back( caseStmt ); 249 247 } 250 *out++ = new SwitchStmt( noLabels,index->clone(), branches );251 *out++ = new NullStmt( std::list<Label>{ switchLabel } );248 *out++ = new SwitchStmt( index->clone(), branches ); 249 *out++ = new NullStmt( { switchLabel } ); 252 250 } 253 251 } … … 262 260 Statement * InitImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) { 263 261 if ( ! init ) return nullptr; 264 CompoundStmt * block = new CompoundStmt( noLabels);262 CompoundStmt * block = new CompoundStmt(); 265 263 build( dst, indices.begin(), indices.end(), init, back_inserter( block->get_kids() ) ); 266 264 if ( block->get_kids().empty() ) { … … 309 307 } 310 308 311 class CallFinder : public Visitor { 312 public: 313 typedef Visitor Parent; 309 struct CallFinder { 314 310 CallFinder( const std::list< std::string > & names ) : names( names ) {} 315 311 316 v irtual voidvisit( ApplicationExpr * appExpr ) {312 void postvisit( ApplicationExpr * appExpr ) { 317 313 handleCallExpr( appExpr ); 318 314 } 319 315 320 v irtual voidvisit( UntypedExpr * untypedExpr ) {316 void postvisit( UntypedExpr * untypedExpr ) { 321 317 handleCallExpr( untypedExpr ); 322 318 } … … 328 324 template< typename CallExpr > 329 325 void handleCallExpr( CallExpr * expr ) { 330 Parent::visit( expr );331 326 std::string fname = getFunctionName( expr ); 332 327 if ( std::find( names.begin(), names.end(), fname ) != names.end() ) { … … 337 332 338 333 void collectCtorDtorCalls( Statement * stmt, std::list< Expression * > & matches ) { 339 static CallFinderfinder( std::list< std::string >{ "?{}", "^?{}" } );340 finder. matches = &matches;334 static PassVisitor<CallFinder> finder( std::list< std::string >{ "?{}", "^?{}" } ); 335 finder.pass.matches = &matches; 341 336 maybeAccept( stmt, finder ); 342 337 } … … 544 539 } 545 540 546 class ConstExprChecker : public Visitor { 547 public: 548 ConstExprChecker() : isConstExpr( true ) {} 549 550 using Visitor::visit; 551 552 virtual void visit( ApplicationExpr * ) { isConstExpr = false; } 553 virtual void visit( UntypedExpr * ) { isConstExpr = false; } 554 virtual void visit( NameExpr * ) { isConstExpr = false; } 555 // virtual void visit( CastExpr *castExpr ) { isConstExpr = false; } 556 virtual void visit( AddressExpr *addressExpr ) { 541 struct ConstExprChecker : public WithShortCircuiting { 542 // most expressions are not const expr 543 void previsit( Expression * ) { isConstExpr = false; visit_children = false; } 544 545 void previsit( AddressExpr *addressExpr ) { 546 visit_children = false; 547 557 548 // address of a variable or member expression is constexpr 558 549 Expression * arg = addressExpr->get_arg(); 559 550 if ( ! dynamic_cast< NameExpr * >( arg) && ! dynamic_cast< VariableExpr * >( arg ) && ! dynamic_cast< MemberExpr * >( arg ) && ! dynamic_cast< UntypedMemberExpr * >( arg ) ) isConstExpr = false; 560 551 } 561 virtual void visit( UntypedMemberExpr * ) { isConstExpr = false; } 562 virtual void visit( MemberExpr * ) { isConstExpr = false; } 563 virtual void visit( VariableExpr * ) { isConstExpr = false; } 564 // these might be okay? 565 // virtual void visit( SizeofExpr *sizeofExpr ); 566 // virtual void visit( AlignofExpr *alignofExpr ); 567 // virtual void visit( UntypedOffsetofExpr *offsetofExpr ); 568 // virtual void visit( OffsetofExpr *offsetofExpr ); 569 // virtual void visit( OffsetPackExpr *offsetPackExpr ); 570 // virtual void visit( AttrExpr *attrExpr ); 571 // virtual void visit( CommaExpr *commaExpr ); 572 // virtual void visit( LogicalExpr *logicalExpr ); 573 // virtual void visit( ConditionalExpr *conditionalExpr ); 574 virtual void visit( TypeExpr * ) { isConstExpr = false; } 575 virtual void visit( AsmExpr * ) { isConstExpr = false; } 576 virtual void visit( UntypedValofExpr * ) { isConstExpr = false; } 577 virtual void visit( CompoundLiteralExpr * ) { isConstExpr = false; } 578 virtual void visit( UntypedTupleExpr * ) { isConstExpr = false; } 579 virtual void visit( TupleExpr * ) { isConstExpr = false; } 580 virtual void visit( TupleAssignExpr * ) { isConstExpr = false; } 581 582 bool isConstExpr; 552 553 // these expressions may be const expr, depending on their children 554 void previsit( SizeofExpr * ) {} 555 void previsit( AlignofExpr * ) {} 556 void previsit( UntypedOffsetofExpr * ) {} 557 void previsit( OffsetofExpr * ) {} 558 void previsit( OffsetPackExpr * ) {} 559 void previsit( AttrExpr * ) {} 560 void previsit( CommaExpr * ) {} 561 void previsit( LogicalExpr * ) {} 562 void previsit( ConditionalExpr * ) {} 563 void previsit( CastExpr * ) {} 564 void previsit( ConstantExpr * ) {} 565 566 bool isConstExpr = true; 583 567 }; 584 568 585 569 bool isConstExpr( Expression * expr ) { 586 570 if ( expr ) { 587 ConstExprCheckerchecker;571 PassVisitor<ConstExprChecker> checker; 588 572 expr->accept( checker ); 589 return checker. isConstExpr;573 return checker.pass.isConstExpr; 590 574 } 591 575 return true; … … 594 578 bool isConstExpr( Initializer * init ) { 595 579 if ( init ) { 596 ConstExprCheckerchecker;580 PassVisitor<ConstExprChecker> checker; 597 581 init->accept( checker ); 598 return checker. isConstExpr;582 return checker.pass.isConstExpr; 599 583 } // if 600 584 // for all intents and purposes, no initializer means const expr -
src/MakeLibCfa.cc
r9c35431 rc13e8dc8 116 116 } // for 117 117 118 funcDecl->set_statements( new CompoundStmt( std::list< Label >()) );118 funcDecl->set_statements( new CompoundStmt() ); 119 119 newDecls.push_back( funcDecl ); 120 120 … … 130 130 case CodeGen::OT_INFIXASSIGN: 131 131 // return the recursive call 132 stmt = new ReturnStmt( n oLabels, newExpr );132 stmt = new ReturnStmt( newExpr ); 133 133 break; 134 134 case CodeGen::OT_CTOR: 135 135 case CodeGen::OT_DTOR: 136 136 // execute the recursive call 137 stmt = new ExprStmt( n oLabels, newExpr );137 stmt = new ExprStmt( newExpr ); 138 138 break; 139 139 case CodeGen::OT_CONSTANT: -
src/Makefile.in
r9c35431 rc13e8dc8 215 215 SymTab/driver_cfa_cpp-Validate.$(OBJEXT) \ 216 216 SymTab/driver_cfa_cpp-FixFunction.$(OBJEXT) \ 217 SymTab/driver_cfa_cpp-ImplementationType.$(OBJEXT) \218 SymTab/driver_cfa_cpp-TypeEquality.$(OBJEXT) \219 217 SymTab/driver_cfa_cpp-Autogen.$(OBJEXT) \ 220 218 SynTree/driver_cfa_cpp-Type.$(OBJEXT) \ … … 514 512 ResolvExpr/CurrentObject.cc ResolvExpr/ExplodedActual.cc \ 515 513 SymTab/Indexer.cc SymTab/Mangler.cc SymTab/Validate.cc \ 516 SymTab/FixFunction.cc SymTab/ImplementationType.cc \ 517 SymTab/TypeEquality.cc SymTab/Autogen.cc SynTree/Type.cc \ 514 SymTab/FixFunction.cc SymTab/Autogen.cc SynTree/Type.cc \ 518 515 SynTree/VoidType.cc SynTree/BasicType.cc \ 519 516 SynTree/PointerType.cc SynTree/ArrayType.cc \ … … 844 841 SymTab/driver_cfa_cpp-FixFunction.$(OBJEXT): SymTab/$(am__dirstamp) \ 845 842 SymTab/$(DEPDIR)/$(am__dirstamp) 846 SymTab/driver_cfa_cpp-ImplementationType.$(OBJEXT): \847 SymTab/$(am__dirstamp) SymTab/$(DEPDIR)/$(am__dirstamp)848 SymTab/driver_cfa_cpp-TypeEquality.$(OBJEXT): SymTab/$(am__dirstamp) \849 SymTab/$(DEPDIR)/$(am__dirstamp)850 843 SymTab/driver_cfa_cpp-Autogen.$(OBJEXT): SymTab/$(am__dirstamp) \ 851 844 SymTab/$(DEPDIR)/$(am__dirstamp) … … 1040 1033 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Po@am__quote@ 1041 1034 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Po@am__quote@ 1042 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Po@am__quote@1043 1035 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Po@am__quote@ 1044 1036 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Mangler.Po@am__quote@ 1045 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-TypeEquality.Po@am__quote@1046 1037 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Validate.Po@am__quote@ 1047 1038 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Po@am__quote@ … … 2039 2030 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 2040 2031 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-FixFunction.obj `if test -f 'SymTab/FixFunction.cc'; then $(CYGPATH_W) 'SymTab/FixFunction.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/FixFunction.cc'; fi` 2041 2042 SymTab/driver_cfa_cpp-ImplementationType.o: SymTab/ImplementationType.cc2043 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-ImplementationType.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Tpo -c -o SymTab/driver_cfa_cpp-ImplementationType.o `test -f 'SymTab/ImplementationType.cc' || echo '$(srcdir)/'`SymTab/ImplementationType.cc2044 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Po2045 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SymTab/ImplementationType.cc' object='SymTab/driver_cfa_cpp-ImplementationType.o' libtool=no @AMDEPBACKSLASH@2046 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@2047 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-ImplementationType.o `test -f 'SymTab/ImplementationType.cc' || echo '$(srcdir)/'`SymTab/ImplementationType.cc2048 2049 SymTab/driver_cfa_cpp-ImplementationType.obj: SymTab/ImplementationType.cc2050 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-ImplementationType.obj -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Tpo -c -o SymTab/driver_cfa_cpp-ImplementationType.obj `if test -f 'SymTab/ImplementationType.cc'; then $(CYGPATH_W) 'SymTab/ImplementationType.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/ImplementationType.cc'; fi`2051 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Po2052 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SymTab/ImplementationType.cc' object='SymTab/driver_cfa_cpp-ImplementationType.obj' libtool=no @AMDEPBACKSLASH@2053 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@2054 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-ImplementationType.obj `if test -f 'SymTab/ImplementationType.cc'; then $(CYGPATH_W) 'SymTab/ImplementationType.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/ImplementationType.cc'; fi`2055 2056 SymTab/driver_cfa_cpp-TypeEquality.o: SymTab/TypeEquality.cc2057 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-TypeEquality.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-TypeEquality.Tpo -c -o SymTab/driver_cfa_cpp-TypeEquality.o `test -f 'SymTab/TypeEquality.cc' || echo '$(srcdir)/'`SymTab/TypeEquality.cc2058 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-TypeEquality.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-TypeEquality.Po2059 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SymTab/TypeEquality.cc' object='SymTab/driver_cfa_cpp-TypeEquality.o' libtool=no @AMDEPBACKSLASH@2060 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@2061 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-TypeEquality.o `test -f 'SymTab/TypeEquality.cc' || echo '$(srcdir)/'`SymTab/TypeEquality.cc2062 2063 SymTab/driver_cfa_cpp-TypeEquality.obj: SymTab/TypeEquality.cc2064 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-TypeEquality.obj -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-TypeEquality.Tpo -c -o SymTab/driver_cfa_cpp-TypeEquality.obj `if test -f 'SymTab/TypeEquality.cc'; then $(CYGPATH_W) 'SymTab/TypeEquality.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/TypeEquality.cc'; fi`2065 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-TypeEquality.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-TypeEquality.Po2066 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SymTab/TypeEquality.cc' object='SymTab/driver_cfa_cpp-TypeEquality.obj' libtool=no @AMDEPBACKSLASH@2067 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@2068 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-TypeEquality.obj `if test -f 'SymTab/TypeEquality.cc'; then $(CYGPATH_W) 'SymTab/TypeEquality.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/TypeEquality.cc'; fi`2069 2032 2070 2033 SymTab/driver_cfa_cpp-Autogen.o: SymTab/Autogen.cc -
src/Parser/DeclarationNode.cc
r9c35431 rc13e8dc8 717 717 } 718 718 719 DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body ) {719 DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body, StatementNode * with ) { 720 720 assert( type ); 721 721 assert( type->kind == TypeData::Function ); 722 722 assert( ! type->function.body ); 723 if ( with ) { 724 // convert 725 // void f(S s) with (s) { x = 0; } 726 // to 727 // void f(S s) { with(s) { x = 0; } } 728 WithStmt * withStmt = strict_dynamic_cast< WithStmt * >( with->build() ); 729 withStmt->stmt = body->build(); 730 delete body; 731 delete with; 732 body = new StatementNode( new CompoundStmt( { withStmt } ) ); 733 } 723 734 type->function.body = body; 724 735 return this; -
src/Parser/ParseNode.h
r9c35431 rc13e8dc8 69 69 70 70 virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {} 71 virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {} 71 virtual void printList( std::ostream &os, int indent = 0 ) const { 72 print( os, indent ); 73 if ( next ) next->print( os, indent ); 74 } 72 75 73 76 static int indent_by; … … 120 123 ExpressionNode * set_extension( bool exten ) { extension = exten; return this; } 121 124 122 virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {} 125 virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override { 126 os << expr.get() << std::endl; 127 } 123 128 void printOneLine( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {} 124 129 … … 257 262 DeclarationNode * addBitfield( ExpressionNode * size ); 258 263 DeclarationNode * addVarArgs(); 259 DeclarationNode * addFunctionBody( StatementNode * body );264 DeclarationNode * addFunctionBody( StatementNode * body, StatementNode * with = nullptr ); 260 265 DeclarationNode * addOldDeclList( DeclarationNode * list ); 261 266 DeclarationNode * setBase( TypeData * newType ); … … 359 364 virtual StatementNode * append_last_case( StatementNode * ); 360 365 361 virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {} 362 virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {} 366 virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override { 367 os << stmt.get() << std::endl; 368 } 363 369 private: 364 370 std::unique_ptr<Statement> stmt; … … 408 414 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when ); 409 415 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when ); 416 WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt ); 410 417 411 418 //############################################################################## -
src/Parser/StatementNode.cc
r9c35431 rc13e8dc8 37 37 DeclarationNode *agg = decl->extractAggregate(); 38 38 if ( agg ) { 39 StatementNode *nextStmt = new StatementNode( new DeclStmt( noLabels,maybeBuild< Declaration >( decl ) ) );39 StatementNode *nextStmt = new StatementNode( new DeclStmt( maybeBuild< Declaration >( decl ) ) ); 40 40 set_next( nextStmt ); 41 41 if ( decl->get_next() ) { … … 50 50 agg = decl; 51 51 } // if 52 stmt.reset( new DeclStmt( noLabels,maybeMoveBuild< Declaration >(agg) ) );52 stmt.reset( new DeclStmt( maybeMoveBuild< Declaration >(agg) ) ); 53 53 } // StatementNode::StatementNode 54 54 … … 75 75 76 76 if ( e ) 77 return new ExprStmt( noLabels,e );77 return new ExprStmt( e ); 78 78 else 79 return new NullStmt( noLabels);79 return new NullStmt(); 80 80 } 81 81 … … 113 113 } 114 114 delete ctl; 115 return new IfStmt( noLabels,cond, thenb, elseb, init );115 return new IfStmt( cond, thenb, elseb, init ); 116 116 } 117 117 … … 120 120 buildMoveList< Statement, StatementNode >( stmt, branches ); 121 121 // branches.size() == 0 for switch (...) {}, i.e., no declaration or statements 122 return new SwitchStmt( noLabels,maybeMoveBuild< Expression >(ctl), branches );122 return new SwitchStmt( maybeMoveBuild< Expression >(ctl), branches ); 123 123 } 124 124 Statement *build_case( ExpressionNode *ctl ) { 125 125 std::list< Statement * > branches; 126 return new CaseStmt( noLabels,maybeMoveBuild< Expression >(ctl), branches );126 return new CaseStmt( maybeMoveBuild< Expression >(ctl), branches ); 127 127 } 128 128 Statement *build_default() { 129 129 std::list< Statement * > branches; 130 return new CaseStmt( n oLabels, nullptr, branches, true );130 return new CaseStmt( nullptr, branches, true ); 131 131 } 132 132 … … 135 135 buildMoveList< Statement, StatementNode >( stmt, branches ); 136 136 assert( branches.size() == 1 ); 137 return new WhileStmt( no Labels, notZeroExpr( maybeMoveBuild< Expression >(ctl) ), branches.front(), kind );137 return new WhileStmt( notZeroExpr( maybeMoveBuild< Expression >(ctl) ), branches.front(), kind ); 138 138 } 139 139 … … 157 157 158 158 delete forctl; 159 return new ForStmt( noLabels,init, cond, incr, branches.front() );159 return new ForStmt( init, cond, incr, branches.front() ); 160 160 } 161 161 162 162 Statement *build_branch( BranchStmt::Type kind ) { 163 Statement * ret = new BranchStmt( noLabels,"", kind );163 Statement * ret = new BranchStmt( "", kind ); 164 164 return ret; 165 165 } 166 166 Statement *build_branch( std::string *identifier, BranchStmt::Type kind ) { 167 Statement * ret = new BranchStmt( noLabels,*identifier, kind );167 Statement * ret = new BranchStmt( *identifier, kind ); 168 168 delete identifier; // allocated by lexer 169 169 return ret; 170 170 } 171 171 Statement *build_computedgoto( ExpressionNode *ctl ) { 172 return new BranchStmt( noLabels,maybeMoveBuild< Expression >(ctl), BranchStmt::Goto );172 return new BranchStmt( maybeMoveBuild< Expression >(ctl), BranchStmt::Goto ); 173 173 } 174 174 … … 176 176 std::list< Expression * > exps; 177 177 buildMoveList( ctl, exps ); 178 return new ReturnStmt( noLabels,exps.size() > 0 ? exps.back() : nullptr );178 return new ReturnStmt( exps.size() > 0 ? exps.back() : nullptr ); 179 179 } 180 180 … … 183 183 buildMoveList( ctl, exps ); 184 184 assertf( exps.size() < 2, "This means we are leaking memory"); 185 return new ThrowStmt( noLabels,ThrowStmt::Terminate, !exps.empty() ? exps.back() : nullptr );185 return new ThrowStmt( ThrowStmt::Terminate, !exps.empty() ? exps.back() : nullptr ); 186 186 } 187 187 … … 190 190 buildMoveList( ctl, exps ); 191 191 assertf( exps.size() < 2, "This means we are leaking memory"); 192 return new ThrowStmt( noLabels,ThrowStmt::Resume, !exps.empty() ? exps.back() : nullptr );192 return new ThrowStmt( ThrowStmt::Resume, !exps.empty() ? exps.back() : nullptr ); 193 193 } 194 194 … … 204 204 CompoundStmt *tryBlock = strict_dynamic_cast< CompoundStmt * >(maybeMoveBuild< Statement >(try_stmt)); 205 205 FinallyStmt *finallyBlock = dynamic_cast< FinallyStmt * >(maybeMoveBuild< Statement >(finally_stmt) ); 206 return new TryStmt( noLabels,tryBlock, branches, finallyBlock );206 return new TryStmt( tryBlock, branches, finallyBlock ); 207 207 } 208 208 Statement *build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body ) { … … 210 210 buildMoveList< Statement, StatementNode >( body, branches ); 211 211 assert( branches.size() == 1 ); 212 return new CatchStmt( noLabels,kind, maybeMoveBuild< Declaration >(decl), maybeMoveBuild< Expression >(cond), branches.front() );212 return new CatchStmt( kind, maybeMoveBuild< Declaration >(decl), maybeMoveBuild< Expression >(cond), branches.front() ); 213 213 } 214 214 Statement *build_finally( StatementNode *stmt ) { … … 216 216 buildMoveList< Statement, StatementNode >( stmt, branches ); 217 217 assert( branches.size() == 1 ); 218 return new FinallyStmt( noLabels,dynamic_cast< CompoundStmt * >( branches.front() ) );218 return new FinallyStmt( dynamic_cast< CompoundStmt * >( branches.front() ) ); 219 219 } 220 220 … … 282 282 node->timeout.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) ); 283 283 284 node->orelse.statement = maybeMoveBuild<Statement >( else_stmt );284 node->orelse.statement = maybeMoveBuild<Statement >( else_stmt ); 285 285 node->orelse.condition = notZeroExpr( maybeMoveBuild<Expression>( else_when ) ); 286 286 … … 288 288 } 289 289 290 WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt ) { 291 std::list< Expression * > e; 292 buildMoveList( exprs, e ); 293 Statement * s = maybeMoveBuild<Statement>( stmt ); 294 return new WithStmt( e, s ); 295 } 296 290 297 Statement *build_compound( StatementNode *first ) { 291 CompoundStmt *cs = new CompoundStmt( noLabels);298 CompoundStmt *cs = new CompoundStmt(); 292 299 buildMoveList( first, cs->get_kids() ); 293 300 return cs; … … 301 308 buildMoveList( input, in ); 302 309 buildMoveList( clobber, clob ); 303 return new AsmStmt( noLabels,voltile, instruction, out, in, clob, gotolabels ? gotolabels->labels : noLabels );310 return new AsmStmt( voltile, instruction, out, in, clob, gotolabels ? gotolabels->labels : noLabels ); 304 311 } 305 312 -
src/Parser/parser.yy
r9c35431 rc13e8dc8 1058 1058 with_statement: 1059 1059 WITH '(' tuple_expression_list ')' statement 1060 { throw SemanticError("With clause is currently unimplemented."); $$ = nullptr; } // FIX ME 1060 { 1061 $$ = new StatementNode( build_with( $3, $5 ) ); 1062 } 1061 1063 ; 1062 1064 … … 2410 2412 { $$ = nullptr; } 2411 2413 | WITH '(' tuple_expression_list ')' 2412 { throw SemanticError("With clause is currently unimplemented."); $$ = nullptr; } // FIX ME2414 { $$ = new StatementNode( build_with( $3, nullptr ) ); } 2413 2415 ; 2414 2416 … … 2420 2422 // Add the function body to the last identifier in the function definition list, i.e., foo3: 2421 2423 // [const double] foo1(), foo2( int ), foo3( double ) { return 3.0; } 2422 $1->get_last()->addFunctionBody( $3 );2424 $1->get_last()->addFunctionBody( $3, $2 ); 2423 2425 $$ = $1; 2424 2426 } … … 2428 2430 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2429 2431 typedefTable.leaveScope(); 2430 $$ = $2->addFunctionBody( $4 )->addType( $1 );2432 $$ = $2->addFunctionBody( $4, $3 )->addType( $1 ); 2431 2433 } 2432 2434 // handles default int return type, OBSOLESCENT (see 1) … … 2435 2437 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2436 2438 typedefTable.leaveScope(); 2437 $$ = $2->addFunctionBody( $4 )->addQualifiers( $1 );2439 $$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 ); 2438 2440 } 2439 2441 // handles default int return type, OBSOLESCENT (see 1) … … 2442 2444 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2443 2445 typedefTable.leaveScope(); 2444 $$ = $2->addFunctionBody( $4 )->addQualifiers( $1 );2446 $$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 ); 2445 2447 } 2446 2448 // handles default int return type, OBSOLESCENT (see 1) … … 2449 2451 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2450 2452 typedefTable.leaveScope(); 2451 $$ = $3->addFunctionBody( $5 )->addQualifiers( $2 )->addQualifiers( $1 );2453 $$ = $3->addFunctionBody( $5, $4 )->addQualifiers( $2 )->addQualifiers( $1 ); 2452 2454 } 2453 2455 … … 2458 2460 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2459 2461 typedefTable.leaveScope(); 2460 $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5 )->addType( $1 );2462 $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addType( $1 ); 2461 2463 } 2462 2464 // handles default int return type, OBSOLESCENT (see 1) … … 2465 2467 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2466 2468 typedefTable.leaveScope(); 2467 $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5 )->addQualifiers( $1 );2469 $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 ); 2468 2470 } 2469 2471 // handles default int return type, OBSOLESCENT (see 1) … … 2472 2474 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2473 2475 typedefTable.leaveScope(); 2474 $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5 )->addQualifiers( $1 );2476 $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 ); 2475 2477 } 2476 2478 // handles default int return type, OBSOLESCENT (see 1) … … 2479 2481 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2480 2482 typedefTable.leaveScope(); 2481 $$ = $3->addOldDeclList( $4 )->addFunctionBody( $6 )->addQualifiers( $2 )->addQualifiers( $1 );2483 $$ = $3->addOldDeclList( $4 )->addFunctionBody( $6, $5 )->addQualifiers( $2 )->addQualifiers( $1 ); 2482 2484 } 2483 2485 ; -
src/ResolvExpr/AlternativeFinder.cc
r9c35431 rc13e8dc8 83 83 } 84 84 85 void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt ) { 86 Indenter indent = { Indenter::tabsize, indentAmt }; 87 for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) { 88 i->print( os, indent ); 89 os << std::endl; 90 } 91 } 92 85 93 namespace { 86 void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt = 0 ) {87 Indenter indent = { Indenter::tabsize, indentAmt };88 for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {89 i->print( os, indent );90 os << std::endl;91 }92 }93 94 94 void makeExprList( const AltList &in, std::list< Expression* > &out ) { 95 95 for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) { … … 469 469 std::cerr << std::endl; 470 470 ) 471 std::list< DeclarationWithType*> candidates;471 std::list< SymTab::Indexer::IdData > candidates; 472 472 decls.lookupId( curDecl->get_name(), candidates ); 473 473 /// if ( candidates.empty() ) { std::cerr << "no candidates!" << std::endl; } 474 for ( std::list< DeclarationWithType* >::const_iterator candidate = candidates.begin(); candidate != candidates.end(); ++candidate ) { 474 for ( const auto & data : candidates ) { 475 DeclarationWithType * candidate = data.id; 475 476 PRINT( 476 477 std::cerr << "inferRecursive: candidate is "; 477 (*candidate)->print( std::cerr );478 candidate->print( std::cerr ); 478 479 std::cerr << std::endl; 479 480 ) … … 482 483 TypeEnvironment newEnv( newAlt.env ); 483 484 OpenVarSet newOpenVars( openVars ); 484 Type *adjType = (*candidate)->get_type()->clone();485 Type *adjType = candidate->get_type()->clone(); 485 486 adjustExprType( adjType, newEnv, indexer ); 486 487 adjType->accept( global_renamer ); … … 500 501 Alternative newerAlt( newAlt ); 501 502 newerAlt.env = newEnv; 502 assertf( (*candidate)->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( *candidate ).c_str() ); 503 DeclarationWithType *candDecl = static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) ); 503 assertf( candidate->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() ); 504 504 505 505 // everything with an empty idChain was pulled in by the current assertion. … … 516 516 // DOESN'T WORK: grandchild nodes conflict with their cousins 517 517 //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue; 518 Expression *varExpr = new VariableExpr( candDecl);518 Expression *varExpr = data.combine(); 519 519 delete varExpr->get_result(); 520 520 varExpr->set_result( adjType->clone() ); … … 522 522 std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " "; 523 523 curDecl->print( std::cerr ); 524 std::cerr << " with declaration " << (*candidate)->get_uniqueId() << " ";525 (*candidate)->print( std::cerr );524 std::cerr << " with declaration " << candidate->get_uniqueId() << " "; 525 candidate->print( std::cerr ); 526 526 std::cerr << std::endl; 527 527 ) … … 532 532 } 533 533 // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions 534 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );534 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr ); 535 535 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out ); 536 536 } else { … … 1317 1317 1318 1318 void AlternativeFinder::visit( NameExpr *nameExpr ) { 1319 std::list< DeclarationWithType*> declList;1319 std::list< SymTab::Indexer::IdData > declList; 1320 1320 indexer.lookupId( nameExpr->get_name(), declList ); 1321 1321 PRINT( std::cerr << "nameExpr is " << nameExpr->get_name() << std::endl; ) 1322 for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) { 1323 VariableExpr newExpr( *i ); 1324 alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) ); 1322 for ( auto & data : declList ) { 1323 Expression * newExpr = data.combine(); 1324 // xxx - add in extra cost for with-statement exprs? 1325 alternatives.push_back( Alternative( newExpr, env, Cost::zero ) ); 1325 1326 PRINT( 1326 1327 std::cerr << "decl is "; 1327 (*i)->print( std::cerr );1328 data.id->print( std::cerr ); 1328 1329 std::cerr << std::endl; 1329 1330 std::cerr << "newExpr is "; 1330 newExpr .print( std::cerr );1331 newExpr->print( std::cerr ); 1331 1332 std::cerr << std::endl; 1332 1333 ) … … 1420 1421 } 1421 1422 1422 void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) { 1423 // assume no polymorphism 1424 // assume no implicit conversions 1425 assert( function->get_parameters().size() == 1 ); 1426 PRINT( 1427 std::cerr << "resolvAttr: funcDecl is "; 1428 funcDecl->print( std::cerr ); 1429 std::cerr << " argType is "; 1430 argType->print( std::cerr ); 1431 std::cerr << std::endl; 1432 ) 1433 if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) { 1434 alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) ); 1435 for ( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) { 1436 alternatives.back().expr->set_result( (*i)->get_type()->clone() ); 1437 } // for 1438 } // if 1423 namespace { 1424 void resolveAttr( SymTab::Indexer::IdData data, FunctionType *function, Type *argType, const TypeEnvironment &env, AlternativeFinder & finder ) { 1425 // assume no polymorphism 1426 // assume no implicit conversions 1427 assert( function->get_parameters().size() == 1 ); 1428 PRINT( 1429 std::cerr << "resolvAttr: funcDecl is "; 1430 data.id->print( std::cerr ); 1431 std::cerr << " argType is "; 1432 argType->print( std::cerr ); 1433 std::cerr << std::endl; 1434 ) 1435 const SymTab::Indexer & indexer = finder.get_indexer(); 1436 AltList & alternatives = finder.get_alternatives(); 1437 if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) { 1438 alternatives.push_back( Alternative( new AttrExpr( data.combine(), argType->clone() ), env, Cost::zero ) ); 1439 for ( DeclarationWithType * retVal : function->returnVals ) { 1440 alternatives.back().expr->result = retVal->get_type()->clone(); 1441 } // for 1442 } // if 1443 } 1439 1444 } 1440 1445 … … 1443 1448 NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() ); 1444 1449 assert( nameExpr ); 1445 std::list< DeclarationWithType*> attrList;1450 std::list< SymTab::Indexer::IdData > attrList; 1446 1451 indexer.lookupId( nameExpr->get_name(), attrList ); 1447 1452 if ( attrExpr->get_isType() || attrExpr->get_expr() ) { 1448 for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) { 1453 for ( auto & data : attrList ) { 1454 DeclarationWithType * id = data.id; 1449 1455 // check if the type is function 1450 if ( FunctionType *function = dynamic_cast< FunctionType* >( (*i)->get_type() ) ) {1456 if ( FunctionType *function = dynamic_cast< FunctionType* >( id->get_type() ) ) { 1451 1457 // assume exactly one parameter 1452 1458 if ( function->get_parameters().size() == 1 ) { 1453 1459 if ( attrExpr->get_isType() ) { 1454 resolveAttr( *i, function, attrExpr->get_type(), env);1460 resolveAttr( data, function, attrExpr->get_type(), env, *this ); 1455 1461 } else { 1456 1462 AlternativeFinder finder( indexer, env ); … … 1458 1464 for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) { 1459 1465 if ( choice->expr->get_result()->size() == 1 ) { 1460 resolveAttr( *i, function, choice->expr->get_result(), choice->env);1466 resolveAttr(data, function, choice->expr->get_result(), choice->env, *this ); 1461 1467 } // fi 1462 1468 } // for … … 1466 1472 } // for 1467 1473 } else { 1468 for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) { 1469 VariableExpr newExpr( *i ); 1470 alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) ); 1474 for ( auto & data : attrList ) { 1475 alternatives.push_back( Alternative( data.combine(), env, Cost::zero ) ); 1471 1476 renameTypes( alternatives.back().expr ); 1472 1477 } // for -
src/ResolvExpr/AlternativeFinder.h
r9c35431 rc13e8dc8 142 142 template< typename OutputIterator > 143 143 void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ); 144 void resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env );145 144 146 145 const SymTab::Indexer &indexer; … … 151 150 152 151 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env ); 153 void referenceToRvalueConversion( Expression *& expr );154 152 155 153 template< typename InputIterator, typename OutputIterator > … … 174 172 175 173 Cost sumCost( const AltList &in ); 174 void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt = 0 ); 176 175 177 176 template< typename InputIterator > … … 181 180 } 182 181 } 182 183 183 } // namespace ResolvExpr 184 184 -
src/ResolvExpr/Resolver.cc
r9c35431 rc13e8dc8 26 26 #include "Common/utility.h" // for ValueGuard, group_iterate 27 27 #include "CurrentObject.h" // for CurrentObject 28 #include "InitTweak/GenInit.h" 28 29 #include "InitTweak/InitTweak.h" // for isIntrinsicSingleArgCallStmt 29 30 #include "RenameVars.h" // for RenameVars, global_renamer … … 40 41 #include "SynTree/TypeSubstitution.h" // for TypeSubstitution 41 42 #include "SynTree/Visitor.h" // for acceptAll, maybeAccept 43 #include "Tuples/Tuples.h" 42 44 #include "typeops.h" // for extractResultType 43 45 #include "Unify.h" // for unify … … 46 48 47 49 namespace ResolvExpr { 48 struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting {50 struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting, public WithStmtsToAdd { 49 51 Resolver() {} 50 52 Resolver( const SymTab::Indexer & other ) { … … 74 76 void previsit( CatchStmt *catchStmt ); 75 77 void previsit( WaitForStmt * stmt ); 78 void previsit( WithStmt * withStmt ); 76 79 77 80 void previsit( SingleInit *singleInit ); … … 369 372 if ( throwStmt->get_expr() ) { 370 373 StructDecl * exception_decl = 371 indexer.lookupStruct( "__cfa ehm__base_exception_t" );374 indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" ); 372 375 assert( exception_decl ); 373 376 Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, exception_decl ) ); … … 568 571 findSingleExpression( stmt->orelse.condition, this->indexer ); 569 572 stmt->orelse.statement->accept( *visitor ); 573 } 574 } 575 576 bool isStructOrUnion( Type * t ) { 577 t = t->stripReferences(); 578 return dynamic_cast< StructInstType * >( t ) || dynamic_cast< UnionInstType * >( t ); 579 } 580 581 void Resolver::previsit( WithStmt * withStmt ) { 582 for ( Expression *& expr : withStmt->exprs ) { 583 TypeEnvironment env; 584 AlternativeFinder finder( indexer, env ); 585 finder.findWithAdjustment( expr ); 586 587 // only struct- and union-typed expressions are viable candidates 588 AltList candidates; 589 for ( Alternative & alt : finder.get_alternatives() ) { 590 if ( isStructOrUnion( alt.expr->result ) ) { 591 candidates.push_back( std::move( alt ) ); 592 } 593 } 594 595 // choose the lowest cost expression among the candidates 596 AltList winners; 597 findMinCost( candidates.begin(), candidates.end(), back_inserter( winners ) ); 598 if ( winners.size() == 0 ) { 599 throw SemanticError( "No reasonable alternatives for with statement expression: ", expr ); 600 } else if ( winners.size() != 1 ) { 601 std::ostringstream stream; 602 stream << "Cannot choose between " << winners.size() << " alternatives for with statement expression\n"; 603 expr->print( stream ); 604 stream << "Alternatives are:\n"; 605 printAlts( winners, stream, 1 ); 606 throw SemanticError( stream.str() ); 607 } 608 609 // there is one unambiguous interpretation - move the expression into the with statement 610 Alternative & alt = winners.front(); 611 finishExpr( alt.expr, alt.env, expr->env ); 612 delete expr; 613 expr = alt.expr; 614 alt.expr = nullptr; 615 616 // if with expression might be impure, create a temporary so that it is evaluated once 617 if ( Tuples::maybeImpure( expr ) ) { 618 static UniqueName tmpNamer( "_with_tmp_" ); 619 ObjectDecl * tmp = ObjectDecl::newObject( tmpNamer.newName(), expr->result->clone(), new SingleInit( expr ) ); 620 expr = new VariableExpr( tmp ); 621 stmtsToAddBefore.push_back( new DeclStmt( tmp ) ); 622 if ( InitTweak::isConstructable( tmp->type ) ) { 623 // generate ctor/dtor and resolve them 624 tmp->init = InitTweak::genCtorInit( tmp ); 625 tmp->accept( *visitor ); 626 } 627 } 570 628 } 571 629 } -
src/ResolvExpr/typeops.h
r9c35431 rc13e8dc8 102 102 bool occurs( Type *type, std::string varName, const TypeEnvironment &env ); 103 103 104 // in AlternativeFinder.cc 105 void referenceToRvalueConversion( Expression *& expr ); 106 104 107 // flatten tuple type into list of types 105 108 template< typename OutputIterator > -
src/SymTab/AddVisit.h
r9c35431 rc13e8dc8 24 24 // add any new declarations after the previous statement 25 25 for ( std::list< Declaration* >::iterator decl = visitor.declsToAddAfter.begin(); decl != visitor.declsToAddAfter.end(); ++decl ) { 26 DeclStmt *declStmt = new DeclStmt( noLabels,*decl );26 DeclStmt *declStmt = new DeclStmt( *decl ); 27 27 stmts.insert( stmt, declStmt ); 28 28 } … … 36 36 // add any new declarations before the statement 37 37 for ( std::list< Declaration* >::iterator decl = visitor.declsToAdd.begin(); decl != visitor.declsToAdd.end(); ++decl ) { 38 DeclStmt *declStmt = new DeclStmt( noLabels,*decl );38 DeclStmt *declStmt = new DeclStmt( *decl ); 39 39 stmts.insert( stmt, declStmt ); 40 40 } -
src/SymTab/Autogen.cc
r9c35431 rc13e8dc8 267 267 Type::StorageClasses scs = functionNesting > 0 ? Type::StorageClasses() : Type::StorageClasses( Type::Static ); 268 268 LinkageSpec::Spec spec = isIntrinsic ? LinkageSpec::Intrinsic : LinkageSpec::AutoGen; 269 FunctionDecl * decl = new FunctionDecl( fname, scs, spec, ftype, new CompoundStmt( noLabels),269 FunctionDecl * decl = new FunctionDecl( fname, scs, spec, ftype, new CompoundStmt(), 270 270 std::list< Attribute * >(), Type::FuncSpecifiers( Type::Inline ) ); 271 271 decl->fixUniqueId(); … … 302 302 assert( assignType->returnVals.size() == 1 ); 303 303 ObjectDecl * dstParam = strict_dynamic_cast< ObjectDecl * >( assignType->parameters.front() ); 304 dcl->statements->push_back( new ReturnStmt( n oLabels, new VariableExpr( dstParam ) ) );304 dcl->statements->push_back( new ReturnStmt( new VariableExpr( dstParam ) ) ); 305 305 } 306 306 resolve( dcl ); … … 471 471 copy->args.push_back( new AddressExpr( new VariableExpr( srcParam ) ) ); 472 472 copy->args.push_back( new SizeofExpr( srcParam->get_type()->clone() ) ); 473 *out++ = new ExprStmt( noLabels,copy );473 *out++ = new ExprStmt( copy ); 474 474 } 475 475 … … 547 547 callExpr->get_args().push_back( new VariableExpr( dstParam ) ); 548 548 callExpr->get_args().push_back( new VariableExpr( srcParam ) ); 549 funcDecl->statements->push_back( new ExprStmt( noLabels,callExpr ) );549 funcDecl->statements->push_back( new ExprStmt( callExpr ) ); 550 550 } else { 551 551 // default ctor/dtor body is empty - add unused attribute to parameter to silence warnings … … 572 572 expr->args.push_back( new CastExpr( new VariableExpr( dst ), new ReferenceType( Type::Qualifiers(), typeDecl->base->clone() ) ) ); 573 573 if ( src ) expr->args.push_back( new CastExpr( new VariableExpr( src ), typeDecl->base->clone() ) ); 574 dcl->statements->kids.push_back( new ExprStmt( noLabels,expr ) );574 dcl->statements->kids.push_back( new ExprStmt( expr ) ); 575 575 }; 576 576 … … 667 667 untyped->get_args().push_back( new VariableExpr( ftype->get_parameters().back() ) ); 668 668 } 669 function->get_statements()->get_kids().push_back( new ExprStmt( noLabels,untyped ) );670 function->get_statements()->get_kids().push_back( new ReturnStmt( noLabels,UntypedExpr::createDeref( new VariableExpr( ftype->get_parameters().front() ) ) ) );669 function->get_statements()->get_kids().push_back( new ExprStmt( untyped ) ); 670 function->get_statements()->get_kids().push_back( new ReturnStmt( UntypedExpr::createDeref( new VariableExpr( ftype->get_parameters().front() ) ) ) ); 671 671 } 672 672 -
src/SymTab/Autogen.h
r9c35431 rc13e8dc8 107 107 fExpr->args.splice( fExpr->args.end(), args ); 108 108 109 *out++ = new ExprStmt( noLabels,fExpr );109 *out++ = new ExprStmt( fExpr ); 110 110 111 111 srcParam.clearArrayIndices(); … … 165 165 166 166 // for stmt's body, eventually containing call 167 CompoundStmt * body = new CompoundStmt( noLabels);167 CompoundStmt * body = new CompoundStmt(); 168 168 Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->kids ), array->base, addCast, forward ); 169 169 170 170 // block containing for stmt and index variable 171 171 std::list<Statement *> initList; 172 CompoundStmt * block = new CompoundStmt( noLabels);173 block->push_back( new DeclStmt( noLabels,index ) );172 CompoundStmt * block = new CompoundStmt(); 173 block->push_back( new DeclStmt( index ) ); 174 174 if ( listInit ) block->get_kids().push_back( listInit ); 175 block->push_back( new ForStmt( noLabels,initList, cond, inc, body ) );175 block->push_back( new ForStmt( initList, cond, inc, body ) ); 176 176 177 177 *out++ = block; -
src/SymTab/Indexer.cc
r9c35431 rc13e8dc8 40 40 41 41 namespace SymTab { 42 typedef std::unordered_map< std::string, DeclarationWithType* > MangleTable; 42 std::ostream & operator<<( std::ostream & out, const Indexer::IdData & data ) { 43 return out << "(" << data.id << "," << data.baseExpr << ")"; 44 } 45 46 typedef std::unordered_map< std::string, Indexer::IdData > MangleTable; 43 47 typedef std::unordered_map< std::string, MangleTable > IdTable; 44 48 typedef std::unordered_map< std::string, NamedTypeDecl* > TypeTable; … … 97 101 } 98 102 99 void Indexer::removeSpecialOverrides( const std::string &id, std::list< DeclarationWithType *> & out ) const {103 void Indexer::removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const { 100 104 // only need to perform this step for constructors, destructors, and assignment functions 101 105 if ( ! CodeGen::isCtorDtorAssign( id ) ) return; … … 104 108 struct ValueType { 105 109 struct DeclBall { 106 FunctionDecl *decl;110 IdData decl; 107 111 bool isUserDefinedFunc; // properties for this particular decl 108 112 bool isDefaultCtor; … … 120 124 // another FunctionDecl for the current type was found - determine 121 125 // if it has special properties and update data structure accordingly 122 ValueType & operator+=( FunctionDecl * function ) { 126 ValueType & operator+=( IdData data ) { 127 DeclarationWithType * function = data.id; 123 128 bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->get_linkage() ); 124 129 bool isDefaultCtor = InitTweak::isDefaultConstructor( function ); 125 130 bool isDtor = InitTweak::isDestructor( function ); 126 131 bool isCopyFunc = InitTweak::isCopyFunction( function, function->get_name() ); 127 decls.push_back( DeclBall{ function, isUserDefinedFunc, isDefaultCtor, isDtor, isCopyFunc } );132 decls.push_back( DeclBall{ data, isUserDefinedFunc, isDefaultCtor, isDtor, isCopyFunc } ); 128 133 existsUserDefinedFunc = existsUserDefinedFunc || isUserDefinedFunc; 129 134 existsUserDefinedCtor = existsUserDefinedCtor || (isUserDefinedFunc && CodeGen::isConstructor( function->get_name() ) ); … … 135 140 }; // ValueType 136 141 137 std::list< DeclarationWithType *> copy;142 std::list< IdData > copy; 138 143 copy.splice( copy.end(), out ); 139 144 140 145 // organize discovered declarations by type 141 146 std::unordered_map< std::string, ValueType > funcMap; 142 for ( DeclarationWithType *decl : copy ) {143 if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl ) ) {147 for ( auto decl : copy ) { 148 if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl.id ) ) { 144 149 std::list< DeclarationWithType * > & params = function->get_functionType()->get_parameters(); 145 150 assert( ! params.empty() ); … … 147 152 Type * base = InitTweak::getPointerBase( params.front()->get_type() ); 148 153 assert( base ); 149 funcMap[ Mangler::mangle( base ) ] += function;154 funcMap[ Mangler::mangle( base ) ] += decl; 150 155 } else { 151 156 out.push_back( decl ); … … 164 169 bool noUserDefinedFunc = ! val.existsUserDefinedFunc; 165 170 bool isUserDefinedFunc = ball.isUserDefinedFunc; 166 bool isAcceptableDefaultCtor = (! val.existsUserDefinedCtor || (! val.existsUserDefinedDefaultCtor && ball.decl ->get_linkage() == LinkageSpec::Intrinsic)) && ball.isDefaultCtor; // allow default constructors only when no user-defined constructors exist, except in the case of intrinsics, which require exact overrides171 bool isAcceptableDefaultCtor = (! val.existsUserDefinedCtor || (! val.existsUserDefinedDefaultCtor && ball.decl.id->get_linkage() == LinkageSpec::Intrinsic)) && ball.isDefaultCtor; // allow default constructors only when no user-defined constructors exist, except in the case of intrinsics, which require exact overrides 167 172 bool isAcceptableCopyFunc = ! val.existsUserDefinedCopyFunc && ball.isCopyFunc; // handles copy ctor and assignment operator 168 173 bool isAcceptableDtor = ! val.existsUserDefinedDtor && ball.isDtor; … … 219 224 } 220 225 221 void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType*> &out ) const {226 void Indexer::lookupId( const std::string &id, std::list< IdData > &out ) const { 222 227 std::unordered_set< std::string > foundMangleNames; 223 228 … … 289 294 const MangleTable &mangleTable = decls->second; 290 295 MangleTable::const_iterator decl = mangleTable.find( mangleName ); 291 if ( decl != mangleTable.end() ) return decl->second ;296 if ( decl != mangleTable.end() ) return decl->second.id; 292 297 } 293 298 … … 304 309 for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) { 305 310 // check for C decls with the same name, skipping those with a compatible type (by mangleName) 306 if ( ! LinkageSpec::isMangled( decl->second ->get_linkage() ) && decl->first != mangleName ) return true;311 if ( ! LinkageSpec::isMangled( decl->second.id->get_linkage() ) && decl->first != mangleName ) return true; 307 312 } 308 313 } … … 321 326 // check for C decls with the same name, skipping 322 327 // those with an incompatible type (by mangleName) 323 if ( ! LinkageSpec::isMangled( decl->second ->get_linkage() ) && decl->first == mangleName ) return true;328 if ( ! LinkageSpec::isMangled( decl->second.id->get_linkage() ) && decl->first == mangleName ) return true; 324 329 } 325 330 } … … 403 408 } 404 409 405 void Indexer::addId( DeclarationWithType *decl ) {410 void Indexer::addId( DeclarationWithType *decl, Expression * baseExpr ) { 406 411 debugPrint( "Adding Id " << decl->name << std::endl ); 407 412 makeWritable(); … … 439 444 440 445 // add to indexer 441 tables->idTable[ name ][ mangleName ] = decl;446 tables->idTable[ name ][ mangleName ] = { decl, baseExpr }; 442 447 ++tables->size; 443 448 } … … 563 568 if ( ! addedDeclConflicts( existing->second, decl ) ) { 564 569 existing->second = decl; 570 } 571 } 572 } 573 574 void Indexer::addWith( WithStmt * stmt ) { 575 for ( Expression * expr : stmt->exprs ) { 576 if ( expr->result ) { 577 AggregateDecl * aggr = expr->result->stripReferences()->getAggr(); 578 assertf( aggr, "WithStmt expr has non-aggregate type: %s", toString( expr->result ).c_str() ); 579 580 for ( Declaration * decl : aggr->members ) { 581 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 582 addId( dwt, expr ); 583 } 584 } 565 585 } 566 586 } … … 645 665 646 666 } 667 668 Expression * Indexer::IdData::combine() const { 669 if ( baseExpr ) { 670 Expression * base = baseExpr->clone(); 671 ResolvExpr::referenceToRvalueConversion( base ); 672 Expression * ret = new MemberExpr( id, base ); 673 // xxx - this introduces hidden environments, for now remove them. 674 // std::swap( base->env, ret->env ); 675 delete base->env; 676 base->env = nullptr; 677 return ret; 678 } else { 679 return new VariableExpr( id ); 680 } 681 } 647 682 } // namespace SymTab 648 683 -
src/SymTab/Indexer.h
r9c35431 rc13e8dc8 39 39 void leaveScope(); 40 40 41 struct IdData { 42 DeclarationWithType * id; 43 Expression * baseExpr; // WithExpr 44 45 Expression * combine() const; 46 }; 47 41 48 /// Gets all declarations with the given ID 42 void lookupId( const std::string &id, std::list< DeclarationWithType*> &out ) const;49 void lookupId( const std::string &id, std::list< IdData > &out ) const; 43 50 /// Gets the top-most type declaration with the given ID 44 51 NamedTypeDecl *lookupType( const std::string &id ) const; … … 67 74 TraitDecl *lookupTraitAtScope( const std::string &id, unsigned long scope ) const; 68 75 69 void addId( DeclarationWithType *decl );76 void addId( DeclarationWithType *decl, Expression * baseExpr = nullptr ); 70 77 void addType( NamedTypeDecl *decl ); 71 78 void addStruct( const std::string &id ); … … 75 82 void addUnion( UnionDecl *decl ); 76 83 void addTrait( TraitDecl *decl ); 84 85 /// adds all of the IDs from WithStmt exprs 86 void addWith( WithStmt * ); 77 87 78 88 /// convenience function for adding a list of Ids to the indexer … … 100 110 // so that they will not be selected 101 111 // void removeSpecialOverrides( FunctionDecl *decl ); 102 void removeSpecialOverrides( const std::string &id, std::list< DeclarationWithType *> & out ) const;112 void removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const; 103 113 104 114 /// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope) -
src/SymTab/Validate.cc
r9c35431 rc13e8dc8 81 81 82 82 namespace SymTab { 83 class HoistStruct final : public Visitor { 84 template< typename Visitor > 85 friend void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor ); 86 template< typename Visitor > 87 friend void addVisitStatementList( std::list< Statement* > &stmts, Visitor &visitor ); 88 public: 83 struct HoistStruct final : public WithDeclsToAdd, public WithGuards { 89 84 /// Flattens nested struct types 90 85 static void hoistStruct( std::list< Declaration * > &translationUnit ); 91 86 92 std::list< Declaration * > &get_declsToAdd() { return declsToAdd; } 93 94 virtual void visit( EnumInstType *enumInstType ); 95 virtual void visit( StructInstType *structInstType ); 96 virtual void visit( UnionInstType *unionInstType ); 97 virtual void visit( StructDecl *aggregateDecl ); 98 virtual void visit( UnionDecl *aggregateDecl ); 99 100 virtual void visit( CompoundStmt *compoundStmt ); 101 virtual void visit( SwitchStmt *switchStmt ); 87 void previsit( EnumInstType * enumInstType ); 88 void previsit( StructInstType * structInstType ); 89 void previsit( UnionInstType * unionInstType ); 90 void previsit( StructDecl * aggregateDecl ); 91 void previsit( UnionDecl * aggregateDecl ); 92 102 93 private: 103 HoistStruct();104 105 94 template< typename AggDecl > void handleAggregate( AggDecl *aggregateDecl ); 106 95 107 std::list< Declaration * > declsToAdd, declsToAddAfter; 108 bool inStruct; 96 bool inStruct = false; 109 97 }; 110 98 … … 305 293 306 294 void HoistStruct::hoistStruct( std::list< Declaration * > &translationUnit ) { 307 HoistStruct hoister; 308 acceptAndAdd( translationUnit, hoister ); 309 } 310 311 HoistStruct::HoistStruct() : inStruct( false ) { 295 PassVisitor<HoistStruct> hoister; 296 acceptAll( translationUnit, hoister ); 312 297 } 313 298 … … 320 305 if ( inStruct ) { 321 306 // Add elements in stack order corresponding to nesting structure. 322 declsToAdd.push_front( aggregateDecl ); 323 Visitor::visit( aggregateDecl ); 307 declsToAddBefore.push_front( aggregateDecl ); 324 308 } else { 309 GuardValue( inStruct ); 325 310 inStruct = true; 326 Visitor::visit( aggregateDecl );327 inStruct = false;328 311 } // if 329 312 // Always remove the hoisted aggregate from the inner structure. 330 filter( aggregateDecl->get_members(), isStructOrUnion, false);331 } 332 333 void HoistStruct:: visit( EnumInstType *structInstType) {334 if ( structInstType->get_baseEnum()) {335 declsToAdd .push_front( structInstType->get_baseEnum());336 } 337 } 338 339 void HoistStruct:: visit( StructInstType *structInstType) {340 if ( structInstType->get_baseStruct()) {341 declsToAdd .push_front( structInstType->get_baseStruct());342 } 343 } 344 345 void HoistStruct:: visit( UnionInstType *structInstType) {346 if ( structInstType->get_baseUnion()) {347 declsToAdd .push_front( structInstType->get_baseUnion());348 } 349 } 350 351 void HoistStruct:: visit( StructDecl *aggregateDecl ) {313 GuardAction( [aggregateDecl]() { filter( aggregateDecl->members, isStructOrUnion, false ); } ); 314 } 315 316 void HoistStruct::previsit( EnumInstType * inst ) { 317 if ( inst->baseEnum ) { 318 declsToAddBefore.push_front( inst->baseEnum ); 319 } 320 } 321 322 void HoistStruct::previsit( StructInstType * inst ) { 323 if ( inst->baseStruct ) { 324 declsToAddBefore.push_front( inst->baseStruct ); 325 } 326 } 327 328 void HoistStruct::previsit( UnionInstType * inst ) { 329 if ( inst->baseUnion ) { 330 declsToAddBefore.push_front( inst->baseUnion ); 331 } 332 } 333 334 void HoistStruct::previsit( StructDecl * aggregateDecl ) { 352 335 handleAggregate( aggregateDecl ); 353 336 } 354 337 355 void HoistStruct:: visit( UnionDecl *aggregateDecl ) {338 void HoistStruct::previsit( UnionDecl * aggregateDecl ) { 356 339 handleAggregate( aggregateDecl ); 357 }358 359 void HoistStruct::visit( CompoundStmt *compoundStmt ) {360 addVisit( compoundStmt, *this );361 }362 363 void HoistStruct::visit( SwitchStmt *switchStmt ) {364 addVisit( switchStmt, *this );365 340 } 366 341 -
src/SymTab/module.mk
r9c35431 rc13e8dc8 19 19 SymTab/Validate.cc \ 20 20 SymTab/FixFunction.cc \ 21 SymTab/ImplementationType.cc \22 SymTab/TypeEquality.cc \23 21 SymTab/Autogen.cc -
src/SynTree/CompoundStmt.cc
r9c35431 rc13e8dc8 28 28 using std::endl; 29 29 30 CompoundStmt::CompoundStmt( std::list<Label> labels ) : Statement( labels) {30 CompoundStmt::CompoundStmt() : Statement() { 31 31 } 32 32 33 CompoundStmt::CompoundStmt( std::list<Statement *> stmts ) : Statement( noLabels), kids( stmts ) {33 CompoundStmt::CompoundStmt( std::list<Statement *> stmts ) : Statement(), kids( stmts ) { 34 34 } 35 35 -
src/SynTree/DeclStmt.cc
r9c35431 rc13e8dc8 23 23 #include "SynTree/Label.h" // for Label 24 24 25 DeclStmt::DeclStmt( std::list<Label> labels, Declaration *decl ) : Statement( labels), decl( decl ) {25 DeclStmt::DeclStmt( Declaration *decl ) : Statement(), decl( decl ) { 26 26 } 27 27 -
src/SynTree/Mutator.cc
r9c35431 rc13e8dc8 203 203 } 204 204 205 Statement * Mutator::mutate( WithStmt * withStmt ) { 206 mutateAll( withStmt->exprs, *this ); 207 withStmt->stmt = maybeMutate( withStmt->stmt, *this ); 208 return withStmt; 209 } 210 205 211 NullStmt * Mutator::mutate( NullStmt *nullStmt ) { 206 212 return nullStmt; -
src/SynTree/Mutator.h
r9c35431 rc13e8dc8 50 50 virtual Statement * mutate( FinallyStmt * catchStmt ); 51 51 virtual Statement * mutate( WaitForStmt * waitforStmt ); 52 virtual Statement * mutate( WithStmt * withStmt ); 52 53 virtual NullStmt * mutate( NullStmt * nullStmt ); 53 54 virtual Statement * mutate( DeclStmt * declStmt ); -
src/SynTree/ReferenceToType.cc
r9c35431 rc13e8dc8 70 70 bool StructInstType::isComplete() const { return baseStruct ? baseStruct->has_body() : false; } 71 71 72 AggregateDecl * StructInstType::getAggr() { return baseStruct; } 73 72 74 void StructInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const { 73 75 assert( baseStruct ); … … 101 103 102 104 bool UnionInstType::isComplete() const { return baseUnion ? baseUnion->has_body() : false; } 105 106 AggregateDecl * UnionInstType::getAggr() { return baseUnion; } 103 107 104 108 void UnionInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const { -
src/SynTree/Statement.cc
r9c35431 rc13e8dc8 32 32 using std::endl; 33 33 34 Statement::Statement( std::list<Label>labels ) : labels( labels ) {}34 Statement::Statement( const std::list<Label> & labels ) : labels( labels ) {} 35 35 36 36 void Statement::print( std::ostream & os, Indenter ) const { … … 46 46 Statement::~Statement() {} 47 47 48 ExprStmt::ExprStmt( std::list<Label> labels, Expression *expr ) : Statement( labels), expr( expr ) {}48 ExprStmt::ExprStmt( Expression *expr ) : Statement(), expr( expr ) {} 49 49 50 50 ExprStmt::ExprStmt( const ExprStmt &other ) : Statement( other ), expr( maybeClone( other.expr ) ) {} … … 60 60 61 61 62 AsmStmt::AsmStmt( std::list<Label> labels, bool voltile, Expression *instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels ) : Statement( labels), voltile( voltile ), instruction( instruction ), output( output ), input( input ), clobber( clobber ), gotolabels( gotolabels ) {}62 AsmStmt::AsmStmt( bool voltile, Expression *instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels ) : Statement(), voltile( voltile ), instruction( instruction ), output( output ), input( input ), clobber( clobber ), gotolabels( gotolabels ) {} 63 63 64 64 AsmStmt::AsmStmt( const AsmStmt & other ) : Statement( other ), voltile( other.voltile ), instruction( maybeClone( other.instruction ) ), gotolabels( other.gotolabels ) { … … 96 96 const char *BranchStmt::brType[] = { "Goto", "Break", "Continue" }; 97 97 98 BranchStmt::BranchStmt( std::list<Label> labels,Label target, Type type ) throw ( SemanticError ) :99 Statement( labels), originalTarget( target ), target( target ), computedTarget( nullptr ), type( type ) {98 BranchStmt::BranchStmt( Label target, Type type ) throw ( SemanticError ) : 99 Statement(), originalTarget( target ), target( target ), computedTarget( nullptr ), type( type ) { 100 100 //actually this is a syntactic error signaled by the parser 101 101 if ( type == BranchStmt::Goto && target.empty() ) { … … 104 104 } 105 105 106 BranchStmt::BranchStmt( std::list<Label> labels,Expression *computedTarget, Type type ) throw ( SemanticError ) :107 Statement( labels), computedTarget( computedTarget ), type( type ) {106 BranchStmt::BranchStmt( Expression *computedTarget, Type type ) throw ( SemanticError ) : 107 Statement(), computedTarget( computedTarget ), type( type ) { 108 108 if ( type != BranchStmt::Goto || computedTarget == nullptr ) { 109 109 throw SemanticError("Computed target not valid in branch statement"); … … 118 118 } 119 119 120 ReturnStmt::ReturnStmt( std::list<Label> labels, Expression *expr ) : Statement( labels), expr( expr ) {}120 ReturnStmt::ReturnStmt( Expression *expr ) : Statement(), expr( expr ) {} 121 121 122 122 ReturnStmt::ReturnStmt( const ReturnStmt & other ) : Statement( other ), expr( maybeClone( other.expr ) ) {} … … 135 135 } 136 136 137 IfStmt::IfStmt( std::list<Label> labels,Expression *condition, Statement *thenPart, Statement *elsePart, std::list<Statement *> initialization ):138 Statement( labels), condition( condition ), thenPart( thenPart ), elsePart( elsePart ), initialization( initialization ) {}137 IfStmt::IfStmt( Expression *condition, Statement *thenPart, Statement *elsePart, std::list<Statement *> initialization ): 138 Statement(), condition( condition ), thenPart( thenPart ), elsePart( elsePart ), initialization( initialization ) {} 139 139 140 140 IfStmt::IfStmt( const IfStmt & other ) : … … 176 176 } 177 177 178 SwitchStmt::SwitchStmt( std::list<Label> labels,Expression * condition, const std::list<Statement *> &statements ):179 Statement( labels), condition( condition ), statements( statements ) {178 SwitchStmt::SwitchStmt( Expression * condition, const std::list<Statement *> &statements ): 179 Statement(), condition( condition ), statements( statements ) { 180 180 } 181 181 … … 201 201 } 202 202 203 CaseStmt::CaseStmt( std::list<Label> labels,Expression *condition, const std::list<Statement *> &statements, bool deflt ) throw ( SemanticError ) :204 Statement( labels), condition( condition ), stmts( statements ), _isDefault( deflt ) {203 CaseStmt::CaseStmt( Expression *condition, const std::list<Statement *> &statements, bool deflt ) throw ( SemanticError ) : 204 Statement(), condition( condition ), stmts( statements ), _isDefault( deflt ) { 205 205 if ( isDefault() && condition != 0 ) throw SemanticError("default case with condition: ", condition); 206 206 } … … 216 216 } 217 217 218 CaseStmt * CaseStmt::makeDefault( std::list<Label> labels, std::list<Statement *> stmts ) { 219 return new CaseStmt( labels, 0, stmts, true ); 218 CaseStmt * CaseStmt::makeDefault( const std::list<Label> & labels, std::list<Statement *> stmts ) { 219 CaseStmt * stmt = new CaseStmt( nullptr, stmts, true ); 220 stmt->labels = labels; 221 return stmt; 220 222 } 221 223 … … 233 235 } 234 236 235 WhileStmt::WhileStmt( std::list<Label> labels,Expression *condition, Statement *body, bool isDoWhile ):236 Statement( labels), condition( condition), body( body), isDoWhile( isDoWhile) {237 WhileStmt::WhileStmt( Expression *condition, Statement *body, bool isDoWhile ): 238 Statement(), condition( condition), body( body), isDoWhile( isDoWhile) { 237 239 } 238 240 … … 255 257 } 256 258 257 ForStmt::ForStmt( std::list< Label> labels, std::list<Statement *> initialization, Expression *condition, Expression *increment, Statement *body ):258 Statement( labels), initialization( initialization ), condition( condition ), increment( increment ), body( body ) {259 ForStmt::ForStmt( std::list<Statement *> initialization, Expression *condition, Expression *increment, Statement *body ): 260 Statement(), initialization( initialization ), condition( condition ), increment( increment ), body( body ) { 259 261 } 260 262 … … 302 304 } 303 305 304 ThrowStmt::ThrowStmt( std::list<Label> labels,Kind kind, Expression * expr, Expression * target ) :305 Statement( labels), kind(kind), expr(expr), target(target) {306 ThrowStmt::ThrowStmt( Kind kind, Expression * expr, Expression * target ) : 307 Statement(), kind(kind), expr(expr), target(target) { 306 308 assertf(Resume == kind || nullptr == target, "Non-local termination throw is not accepted." ); 307 309 } … … 326 328 } 327 329 328 TryStmt::TryStmt( std::list<Label> labels,CompoundStmt *tryBlock, std::list<CatchStmt *> &handlers, FinallyStmt *finallyBlock ) :329 Statement( labels), block( tryBlock ), handlers( handlers ), finallyBlock( finallyBlock ) {330 TryStmt::TryStmt( CompoundStmt *tryBlock, std::list<CatchStmt *> &handlers, FinallyStmt *finallyBlock ) : 331 Statement(), block( tryBlock ), handlers( handlers ), finallyBlock( finallyBlock ) { 330 332 } 331 333 … … 359 361 } 360 362 361 CatchStmt::CatchStmt( std::list<Label> labels,Kind kind, Declaration *decl, Expression *cond, Statement *body ) :362 Statement( labels), kind ( kind ), decl ( decl ), cond ( cond ), body( body ) {363 CatchStmt::CatchStmt( Kind kind, Declaration *decl, Expression *cond, Statement *body ) : 364 Statement(), kind ( kind ), decl ( decl ), cond ( cond ), body( body ) { 363 365 assertf( decl, "Catch clause must have a declaration." ); 364 366 } … … 391 393 392 394 393 FinallyStmt::FinallyStmt( std::list<Label> labels, CompoundStmt *block ) : Statement( labels ), block( block ) { 394 assert( labels.empty() ); // finally statement cannot be labeled 395 FinallyStmt::FinallyStmt( CompoundStmt *block ) : Statement(), block( block ) { 395 396 } 396 397 … … 408 409 } 409 410 410 WaitForStmt::WaitForStmt( std::list<Label> labels ) : Statement( labels) {411 WaitForStmt::WaitForStmt() : Statement() { 411 412 timeout.time = nullptr; 412 413 timeout.statement = nullptr; … … 455 456 } 456 457 457 NullStmt::NullStmt( std::list<Label> labels ) : Statement( labels ) {} 458 NullStmt::NullStmt() : Statement( std::list<Label>() ) {} 458 459 WithStmt::WithStmt( const std::list< Expression * > & exprs, Statement * stmt ) : Statement(), exprs( exprs ), stmt( stmt ) {} 460 WithStmt::WithStmt( const WithStmt & other ) : Statement( other ), stmt( maybeClone( other.stmt ) ) { 461 cloneAll( other.exprs, exprs ); 462 } 463 WithStmt::~WithStmt() { 464 deleteAll( exprs ); 465 delete stmt; 466 } 467 468 void WithStmt::print( std::ostream & os, Indenter indent ) const { 469 os << "With statement" << endl; 470 os << indent << "... with statement:" << endl << indent+1; 471 stmt->print( os, indent+1 ); 472 } 473 474 475 NullStmt::NullStmt( const std::list<Label> & labels ) : Statement( labels ) { 476 } 459 477 460 478 void NullStmt::print( std::ostream &os, Indenter ) const { … … 462 480 } 463 481 464 ImplicitCtorDtorStmt::ImplicitCtorDtorStmt( Statement * callStmt ) : Statement( std::list<Label>()), callStmt( callStmt ) {482 ImplicitCtorDtorStmt::ImplicitCtorDtorStmt( Statement * callStmt ) : Statement(), callStmt( callStmt ) { 465 483 assert( callStmt ); 466 484 } -
src/SynTree/Statement.h
r9c35431 rc13e8dc8 37 37 std::list<Label> labels; 38 38 39 Statement( std::list<Label> labels);39 Statement( const std::list<Label> & labels = {} ); 40 40 virtual ~Statement(); 41 41 … … 53 53 std::list<Statement*> kids; 54 54 55 CompoundStmt( std::list<Label> labels);55 CompoundStmt(); 56 56 CompoundStmt( std::list<Statement *> stmts ); 57 57 CompoundStmt( const CompoundStmt &other ); … … 70 70 class NullStmt : public Statement { 71 71 public: 72 NullStmt(); 73 NullStmt( std::list<Label> labels ); 72 NullStmt( const std::list<Label> & labels = {} ); 74 73 75 74 virtual NullStmt *clone() const override { return new NullStmt( *this ); } … … 83 82 Expression *expr; 84 83 85 ExprStmt( std::list<Label> labels,Expression *expr );84 ExprStmt( Expression *expr ); 86 85 ExprStmt( const ExprStmt &other ); 87 86 virtual ~ExprStmt(); … … 104 103 std::list<Label> gotolabels; 105 104 106 AsmStmt( std::list<Label> labels,bool voltile, Expression *instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels );105 AsmStmt( bool voltile, Expression *instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels ); 107 106 AsmStmt( const AsmStmt &other ); 108 107 virtual ~AsmStmt(); … … 134 133 std::list<Statement *> initialization; 135 134 136 IfStmt( std::list<Label> labels,Expression *condition, Statement *thenPart, Statement *elsePart,135 IfStmt( Expression *condition, Statement *thenPart, Statement *elsePart, 137 136 std::list<Statement *> initialization = std::list<Statement *>() ); 138 137 IfStmt( const IfStmt &other ); … … 158 157 std::list<Statement *> statements; 159 158 160 SwitchStmt( std::list<Label> labels,Expression *condition, const std::list<Statement *> &statements );159 SwitchStmt( Expression *condition, const std::list<Statement *> &statements ); 161 160 SwitchStmt( const SwitchStmt &other ); 162 161 virtual ~SwitchStmt(); … … 180 179 std::list<Statement *> stmts; 181 180 182 CaseStmt( std::list<Label> labels,Expression *conditions, const std::list<Statement *> &stmts, bool isdef = false ) throw(SemanticError);181 CaseStmt( Expression *conditions, const std::list<Statement *> &stmts, bool isdef = false ) throw(SemanticError); 183 182 CaseStmt( const CaseStmt &other ); 184 183 virtual ~CaseStmt(); 185 184 186 static CaseStmt * makeDefault( std::list<Label> labels = std::list<Label>(), std::list<Statement *> stmts = std::list<Statement *>() );185 static CaseStmt * makeDefault( const std::list<Label> & labels = {}, std::list<Statement *> stmts = std::list<Statement *>() ); 187 186 188 187 bool isDefault() const { return _isDefault; } … … 210 209 bool isDoWhile; 211 210 212 WhileStmt( std::list<Label> labels,Expression *condition,211 WhileStmt( Expression *condition, 213 212 Statement *body, bool isDoWhile = false ); 214 213 WhileStmt( const WhileStmt &other ); … … 235 234 Statement *body; 236 235 237 ForStmt( std::list< Label> labels, std::list<Statement *> initialization,236 ForStmt( std::list<Statement *> initialization, 238 237 Expression *condition = 0, Expression *increment = 0, Statement *body = 0 ); 239 238 ForStmt( const ForStmt &other ); … … 264 263 Type type; 265 264 266 BranchStmt( std::list<Label> labels,Label target, Type ) throw (SemanticError);267 BranchStmt( std::list<Label> labels,Expression *computedTarget, Type ) throw (SemanticError);265 BranchStmt( Label target, Type ) throw (SemanticError); 266 BranchStmt( Expression *computedTarget, Type ) throw (SemanticError); 268 267 269 268 Label get_originalTarget() { return originalTarget; } … … 289 288 Expression *expr; 290 289 291 ReturnStmt( std::list<Label> labels,Expression *expr );290 ReturnStmt( Expression *expr ); 292 291 ReturnStmt( const ReturnStmt &other ); 293 292 virtual ~ReturnStmt(); … … 310 309 Expression * target; 311 310 312 ThrowStmt( std::list<Label> labels,Kind kind, Expression * expr, Expression * target = nullptr );311 ThrowStmt( Kind kind, Expression * expr, Expression * target = nullptr ); 313 312 ThrowStmt( const ThrowStmt &other ); 314 313 virtual ~ThrowStmt(); … … 332 331 FinallyStmt * finallyBlock; 333 332 334 TryStmt( std::list<Label> labels,CompoundStmt *tryBlock, std::list<CatchStmt *> &handlers, FinallyStmt *finallyBlock = 0 );333 TryStmt( CompoundStmt *tryBlock, std::list<CatchStmt *> &handlers, FinallyStmt *finallyBlock = 0 ); 335 334 TryStmt( const TryStmt &other ); 336 335 virtual ~TryStmt(); … … 358 357 Statement *body; 359 358 360 CatchStmt( std::list<Label> labels,Kind kind, Declaration *decl,359 CatchStmt( Kind kind, Declaration *decl, 361 360 Expression *cond, Statement *body ); 362 361 CatchStmt( const CatchStmt &other ); … … 381 380 CompoundStmt *block; 382 381 383 FinallyStmt( std::list<Label> labels,CompoundStmt *block );382 FinallyStmt( CompoundStmt *block ); 384 383 FinallyStmt( const FinallyStmt &other ); 385 384 virtual ~FinallyStmt(); … … 408 407 }; 409 408 410 WaitForStmt( std::list<Label> labels = noLabels);409 WaitForStmt(); 411 410 WaitForStmt( const WaitForStmt & ); 412 411 virtual ~WaitForStmt(); … … 432 431 }; 433 432 433 class WithStmt : public Statement { 434 public: 435 std::list< Expression * > exprs; 436 Statement * stmt; 437 438 WithStmt( const std::list< Expression * > & exprs, Statement * stmt ); 439 WithStmt( const WithStmt & other ); 440 virtual ~WithStmt(); 441 442 virtual WithStmt * clone() const override { return new WithStmt( *this ); } 443 virtual void accept( Visitor & v ) override { v.visit( this ); } 444 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 445 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 446 }; 447 434 448 435 449 // represents a declaration that occurs as part of a compound statement … … 438 452 Declaration *decl; 439 453 440 DeclStmt( std::list<Label> labels,Declaration *decl );454 DeclStmt( Declaration *decl ); 441 455 DeclStmt( const DeclStmt &other ); 442 456 virtual ~DeclStmt(); -
src/SynTree/SynTree.h
r9c35431 rc13e8dc8 55 55 class FinallyStmt; 56 56 class WaitForStmt; 57 class WithStmt; 57 58 class NullStmt; 58 59 class DeclStmt; -
src/SynTree/TupleExpr.cc
r9c35431 rc13e8dc8 23 23 #include "Declaration.h" // for ObjectDecl 24 24 #include "Expression.h" // for Expression, TupleExpr, TupleIndexExpr 25 #include "SynTree/Label.h" // for Label , noLabels25 #include "SynTree/Label.h" // for Label 26 26 #include "SynTree/Statement.h" // for CompoundStmt, DeclStmt, ExprStmt, Sta... 27 27 #include "Tuples/Tuples.h" // for makeTupleType … … 89 89 // convert internally into a StmtExpr which contains the declarations and produces the tuple of the assignments 90 90 set_result( Tuples::makeTupleType( assigns ) ); 91 CompoundStmt * compoundStmt = new CompoundStmt( noLabels);91 CompoundStmt * compoundStmt = new CompoundStmt(); 92 92 std::list< Statement * > & stmts = compoundStmt->get_kids(); 93 93 for ( ObjectDecl * obj : tempDecls ) { 94 stmts.push_back( new DeclStmt( noLabels,obj ) );94 stmts.push_back( new DeclStmt( obj ) ); 95 95 } 96 96 TupleExpr * tupleExpr = new TupleExpr( assigns ); 97 97 assert( tupleExpr->get_result() ); 98 stmts.push_back( new ExprStmt( noLabels,tupleExpr ) );98 stmts.push_back( new ExprStmt( tupleExpr ) ); 99 99 stmtExpr = new StmtExpr( compoundStmt ); 100 100 } -
src/SynTree/Type.h
r9c35431 rc13e8dc8 178 178 virtual bool isComplete() const { return true; } 179 179 180 virtual AggregateDecl * getAggr() { assertf( false, "Non-aggregate type: %s", toString( this ).c_str() ); } 181 180 182 virtual Type *clone() const = 0; 181 183 virtual void accept( Visitor & v ) = 0; … … 405 407 virtual bool isComplete() const override; 406 408 409 virtual AggregateDecl * getAggr() override; 410 407 411 /// Looks up the members of this struct named "name" and places them into "foundDecls". 408 412 /// Clones declarations into "foundDecls", caller responsible for freeing … … 436 440 437 441 virtual bool isComplete() const override; 442 443 virtual AggregateDecl * getAggr() override; 438 444 439 445 /// looks up the members of this union named "name" and places them into "foundDecls" -
src/SynTree/Visitor.cc
r9c35431 rc13e8dc8 174 174 } 175 175 176 void Visitor::visit( __attribute__((unused)) NullStmt *nullStmt ) { 176 void Visitor::visit( WithStmt * withStmt ) { 177 acceptAll( withStmt->exprs, *this ); 178 maybeAccept( withStmt->stmt, *this ); 179 } 180 181 void Visitor::visit( NullStmt * ) { 177 182 } 178 183 -
src/SynTree/Visitor.h
r9c35431 rc13e8dc8 52 52 virtual void visit( FinallyStmt * finallyStmt ); 53 53 virtual void visit( WaitForStmt * waitforStmt ); 54 virtual void visit( WithStmt * withStmt ); 54 55 virtual void visit( NullStmt * nullStmt ); 55 56 virtual void visit( DeclStmt * declStmt ); -
src/Tuples/TupleAssignment.cc
r9c35431 rc13e8dc8 23 23 24 24 #include "CodeGen/OperatorTable.h" 25 #include "Common/PassVisitor.h" 25 26 #include "Common/UniqueName.h" // for UniqueName 26 27 #include "Common/utility.h" // for zipWith … … 61 62 struct Matcher { 62 63 public: 63 Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, const 64 Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, const 64 65 ResolvExpr::AltList& rhs ); 65 66 virtual ~Matcher() {} … … 75 76 struct MassAssignMatcher : public Matcher { 76 77 public: 77 MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, 78 MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, 78 79 const ResolvExpr::AltList& rhs ) : Matcher(spotter, lhs, rhs) {} 79 80 virtual void match( std::list< Expression * > &out ); … … 82 83 struct MultipleAssignMatcher : public Matcher { 83 84 public: 84 MultipleAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, 85 MultipleAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, 85 86 const ResolvExpr::AltList& rhs ) : Matcher(spotter, lhs, rhs) {} 86 87 virtual void match( std::list< Expression * > &out ); … … 119 120 } 120 121 121 void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr, 122 void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr, 122 123 std::vector<ResolvExpr::AlternativeFinder> &args ) { 123 124 TupleAssignSpotter spotter( currentFinder ); … … 128 129 : currentFinder(f) {} 129 130 130 void TupleAssignSpotter::spot( UntypedExpr * expr, 131 void TupleAssignSpotter::spot( UntypedExpr * expr, 131 132 std::vector<ResolvExpr::AlternativeFinder> &args ) { 132 133 if ( NameExpr *op = dynamic_cast< NameExpr * >(expr->get_function()) ) { … … 137 138 if ( args.size() == 0 ) return; 138 139 139 // if an assignment only takes 1 argument, that's odd, but maybe someone wrote 140 // if an assignment only takes 1 argument, that's odd, but maybe someone wrote 140 141 // the function, in which case AlternativeFinder will handle it normally 141 142 if ( args.size() == 1 && CodeGen::isAssignment( fname ) ) return; … … 146 147 if ( ! refToTuple(lhsAlt.expr) ) continue; 147 148 148 // explode is aware of casts - ensure every LHS expression is sent into explode 149 // explode is aware of casts - ensure every LHS expression is sent into explode 149 150 // with a reference cast 150 // xxx - this seems to change the alternatives before the normal 151 // xxx - this seems to change the alternatives before the normal 151 152 // AlternativeFinder flow; maybe this is desired? 152 153 if ( ! dynamic_cast<CastExpr*>( lhsAlt.expr ) ) { 153 lhsAlt.expr = new CastExpr( lhsAlt.expr, 154 new ReferenceType( Type::Qualifiers(), 154 lhsAlt.expr = new CastExpr( lhsAlt.expr, 155 new ReferenceType( Type::Qualifiers(), 155 156 lhsAlt.expr->get_result()->clone() ) ); 156 157 } … … 160 161 explode( lhsAlt, currentFinder.get_indexer(), back_inserter(lhs), true ); 161 162 for ( ResolvExpr::Alternative& alt : lhs ) { 162 // each LHS value must be a reference - some come in with a cast expression, 163 // each LHS value must be a reference - some come in with a cast expression, 163 164 // if not just cast to reference here 164 165 if ( ! dynamic_cast<ReferenceType*>( alt.expr->get_result() ) ) { 165 alt.expr = new CastExpr( alt.expr, 166 new ReferenceType( Type::Qualifiers(), 166 alt.expr = new CastExpr( alt.expr, 167 new ReferenceType( Type::Qualifiers(), 167 168 alt.expr->get_result()->clone() ) ); 168 169 } … … 178 179 // TODO build iterative version of this instead of using combos 179 180 std::vector< ResolvExpr::AltList > rhsAlts; 180 combos( std::next(args.begin(), 1), args.end(), 181 combos( std::next(args.begin(), 1), args.end(), 181 182 std::back_inserter( rhsAlts ) ); 182 183 for ( const ResolvExpr::AltList& rhsAlt : rhsAlts ) { 183 184 // multiple assignment 184 185 ResolvExpr::AltList rhs; 185 explode( rhsAlt, currentFinder.get_indexer(), 186 explode( rhsAlt, currentFinder.get_indexer(), 186 187 std::back_inserter(rhs), true ); 187 188 matcher.reset( new MultipleAssignMatcher( *this, lhs, rhs ) ); … … 193 194 if ( isTuple(rhsAlt.expr) ) { 194 195 // multiple assignment 195 explode( rhsAlt, currentFinder.get_indexer(), 196 explode( rhsAlt, currentFinder.get_indexer(), 196 197 std::back_inserter(rhs), true ); 197 198 matcher.reset( new MultipleAssignMatcher( *this, lhs, rhs ) ); … … 222 223 ResolvExpr::AltList current; 223 224 // now resolve new assignments 224 for ( std::list< Expression * >::iterator i = new_assigns.begin(); 225 for ( std::list< Expression * >::iterator i = new_assigns.begin(); 225 226 i != new_assigns.end(); ++i ) { 226 227 PRINT( … … 229 230 ) 230 231 231 ResolvExpr::AlternativeFinder finder{ currentFinder.get_indexer(), 232 ResolvExpr::AlternativeFinder finder{ currentFinder.get_indexer(), 232 233 currentFinder.get_environ() }; 233 234 try { … … 253 254 // xxx -- was push_front 254 255 currentFinder.get_alternatives().push_back( ResolvExpr::Alternative( 255 new TupleAssignExpr(solved_assigns, matcher->tmpDecls), matcher->compositeEnv, 256 new TupleAssignExpr(solved_assigns, matcher->tmpDecls), matcher->compositeEnv, 256 257 ResolvExpr::sumCost( current ) + matcher->baseCost ) ); 257 258 } 258 259 259 TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, 260 const ResolvExpr::AltList &lhs, const ResolvExpr::AltList &rhs ) 261 : lhs(lhs), rhs(rhs), spotter(spotter), 260 TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, 261 const ResolvExpr::AltList &lhs, const ResolvExpr::AltList &rhs ) 262 : lhs(lhs), rhs(rhs), spotter(spotter), 262 263 baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ) { 263 264 simpleCombineEnvironments( lhs.begin(), lhs.end(), compositeEnv ); … … 277 278 // xxx - maybe this should happen in alternative finder for every StmtExpr? 278 279 // xxx - it's possible that these environments could contain some useful information. Maybe the right thing to do is aggregate the environments and pass the aggregate back to be added into the compositeEnv 279 struct EnvRemover : public Visitor { 280 virtual void visit( ExprStmt * stmt ) { 281 delete stmt->get_expr()->get_env(); 282 stmt->get_expr()->set_env( nullptr ); 283 Visitor::visit( stmt ); 280 struct EnvRemover { 281 void previsit( ExprStmt * stmt ) { 282 delete stmt->expr->env; 283 stmt->expr->env = nullptr; 284 284 } 285 285 }; … … 293 293 ret->set_init( ctorInit ); 294 294 ResolvExpr::resolveCtorInit( ctorInit, spotter.currentFinder.get_indexer() ); // resolve ctor/dtors for the new object 295 EnvRemoverrm; // remove environments from subexpressions of StmtExprs295 PassVisitor<EnvRemover> rm; // remove environments from subexpressions of StmtExprs 296 296 ctorInit->accept( rm ); 297 297 } -
src/Tuples/TupleExpansion.cc
r9c35431 rc13e8dc8 315 315 namespace { 316 316 /// determines if impurity (read: side-effects) may exist in a piece of code. Currently gives a very crude approximation, wherein any function call expression means the code may be impure 317 class ImpurityDetector : public Visitor { 318 public: 317 struct ImpurityDetector : public WithShortCircuiting { 319 318 ImpurityDetector( bool ignoreUnique ) : ignoreUnique( ignoreUnique ) {} 320 319 321 typedef Visitor Parent;322 virtual void visit( ApplicationExpr * appExpr ) {320 void previsit( ApplicationExpr * appExpr ) { 321 visit_children = false; 323 322 if ( DeclarationWithType * function = InitTweak::getFunction( appExpr ) ) { 324 323 if ( function->get_linkage() == LinkageSpec::Intrinsic ) { 325 324 if ( function->get_name() == "*?" || function->get_name() == "?[?]" ) { 326 325 // intrinsic dereference, subscript are pure, but need to recursively look for impurity 327 Parent::visit( appExpr );326 visit_children = true; 328 327 return; 329 328 } … … 332 331 maybeImpure = true; 333 332 } 334 v irtual void visit( UntypedExpr * ) { maybeImpure = true; }335 v irtual void visit( UniqueExpr * unq) {333 void previsit( UntypedExpr * ) { maybeImpure = true; visit_children = false; } 334 void previsit( UniqueExpr * ) { 336 335 if ( ignoreUnique ) { 337 336 // bottom out at unique expression. 338 337 // The existence of a unique expression doesn't change the purity of an expression. 339 338 // That is, even if the wrapped expression is impure, the wrapper protects the rest of the expression. 339 visit_children = false; 340 340 return; 341 341 } 342 maybeAccept( unq->expr, *this );343 342 } 344 343 … … 349 348 350 349 bool maybeImpure( Expression * expr ) { 351 ImpurityDetectordetector( false );350 PassVisitor<ImpurityDetector> detector( false ); 352 351 expr->accept( detector ); 353 return detector. maybeImpure;352 return detector.pass.maybeImpure; 354 353 } 355 354 356 355 bool maybeImpureIgnoreUnique( Expression * expr ) { 357 ImpurityDetectordetector( true );356 PassVisitor<ImpurityDetector> detector( true ); 358 357 expr->accept( detector ); 359 return detector. maybeImpure;358 return detector.pass.maybeImpure; 360 359 } 361 360 } // namespace Tuples -
src/driver/cfa.cc
r9c35431 rc13e8dc8 275 275 args[nargs] = "-Xlinker"; 276 276 nargs += 1; 277 args[nargs] = "--undefined=__ lib_debug_write";277 args[nargs] = "--undefined=__cfaabi_dbg_bits_write"; 278 278 nargs += 1; 279 279 -
src/libcfa/Makefile.am
r9c35431 rc13e8dc8 55 55 56 56 libobjs = ${headers:=.o} 57 libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c} \57 libsrc = libcfa-prelude.c interpose.c bits/debug.c ${headers:=.c} \ 58 58 assert.c exception.c virtual.c 59 59 … … 100 100 math \ 101 101 gmp \ 102 bits/align.h \ 102 103 bits/containers.h \ 103 104 bits/defs.h \ 105 bits/debug.h \ 104 106 bits/locks.h \ 105 concurrency/invoke.h \ 106 libhdr.h \ 107 libhdr/libalign.h \ 108 libhdr/libdebug.h \ 109 libhdr/libtools.h 107 concurrency/invoke.h 110 108 111 109 CLEANFILES = libcfa-prelude.c -
src/libcfa/Makefile.in
r9c35431 rc13e8dc8 149 149 libcfa_d_a_LIBADD = 150 150 am__libcfa_d_a_SOURCES_DIST = libcfa-prelude.c interpose.c \ 151 libhdr/libdebug.c fstream.c iostream.c iterator.c limits.c \151 bits/debug.c fstream.c iostream.c iterator.c limits.c \ 152 152 rational.c stdlib.c containers/maybe.c containers/pair.c \ 153 153 containers/result.c containers/vector.c \ … … 175 175 @BUILD_CONCURRENCY_TRUE@ concurrency/libcfa_d_a-preemption.$(OBJEXT) 176 176 am__objects_4 = libcfa_d_a-libcfa-prelude.$(OBJEXT) \ 177 libcfa_d_a-interpose.$(OBJEXT) \178 libhdr/libcfa_d_a-libdebug.$(OBJEXT) $(am__objects_2) \179 libcfa_d_a- assert.$(OBJEXT) libcfa_d_a-exception.$(OBJEXT) \180 libcfa_d_a-virtual.$(OBJEXT)$(am__objects_3)177 libcfa_d_a-interpose.$(OBJEXT) bits/libcfa_d_a-debug.$(OBJEXT) \ 178 $(am__objects_2) libcfa_d_a-assert.$(OBJEXT) \ 179 libcfa_d_a-exception.$(OBJEXT) libcfa_d_a-virtual.$(OBJEXT) \ 180 $(am__objects_3) 181 181 am_libcfa_d_a_OBJECTS = $(am__objects_4) 182 182 libcfa_d_a_OBJECTS = $(am_libcfa_d_a_OBJECTS) 183 183 libcfa_a_AR = $(AR) $(ARFLAGS) 184 184 libcfa_a_LIBADD = 185 am__libcfa_a_SOURCES_DIST = libcfa-prelude.c interpose.c \ 186 libhdr/libdebug.c fstream.c iostream.c iterator.c limits.c \ 187 rational.c stdlib.c containers/maybe.c containers/pair.c \ 188 containers/result.c containers/vector.c \ 189 concurrency/coroutine.c concurrency/thread.c \ 190 concurrency/kernel.c concurrency/monitor.c assert.c \ 191 exception.c virtual.c concurrency/CtxSwitch-@MACHINE_TYPE@.S \ 192 concurrency/alarm.c concurrency/invoke.c \ 193 concurrency/preemption.c 185 am__libcfa_a_SOURCES_DIST = libcfa-prelude.c interpose.c bits/debug.c \ 186 fstream.c iostream.c iterator.c limits.c rational.c stdlib.c \ 187 containers/maybe.c containers/pair.c containers/result.c \ 188 containers/vector.c concurrency/coroutine.c \ 189 concurrency/thread.c concurrency/kernel.c \ 190 concurrency/monitor.c assert.c exception.c virtual.c \ 191 concurrency/CtxSwitch-@MACHINE_TYPE@.S concurrency/alarm.c \ 192 concurrency/invoke.c concurrency/preemption.c 194 193 @BUILD_CONCURRENCY_TRUE@am__objects_5 = concurrency/libcfa_a-coroutine.$(OBJEXT) \ 195 194 @BUILD_CONCURRENCY_TRUE@ concurrency/libcfa_a-thread.$(OBJEXT) \ … … 208 207 @BUILD_CONCURRENCY_TRUE@ concurrency/libcfa_a-preemption.$(OBJEXT) 209 208 am__objects_8 = libcfa_a-libcfa-prelude.$(OBJEXT) \ 210 libcfa_a-interpose.$(OBJEXT) \211 libhdr/libcfa_a-libdebug.$(OBJEXT) $(am__objects_6) \212 libcfa_a- assert.$(OBJEXT) libcfa_a-exception.$(OBJEXT) \213 libcfa_a-virtual.$(OBJEXT)$(am__objects_7)209 libcfa_a-interpose.$(OBJEXT) bits/libcfa_a-debug.$(OBJEXT) \ 210 $(am__objects_6) libcfa_a-assert.$(OBJEXT) \ 211 libcfa_a-exception.$(OBJEXT) libcfa_a-virtual.$(OBJEXT) \ 212 $(am__objects_7) 214 213 am_libcfa_a_OBJECTS = $(am__objects_8) 215 214 libcfa_a_OBJECTS = $(am_libcfa_a_OBJECTS) … … 264 263 containers/result containers/vector concurrency/coroutine \ 265 264 concurrency/thread concurrency/kernel concurrency/monitor \ 266 ${shell echo stdhdr/*} math gmp bits/containers.h bits/defs.h \ 267 bits/locks.h concurrency/invoke.h libhdr.h libhdr/libalign.h \ 268 libhdr/libdebug.h libhdr/libtools.h 265 ${shell echo stdhdr/*} math gmp bits/align.h bits/containers.h \ 266 bits/defs.h bits/debug.h bits/locks.h concurrency/invoke.h 269 267 HEADERS = $(nobase_cfa_include_HEADERS) 270 268 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) … … 424 422 containers/vector $(am__append_3) 425 423 libobjs = ${headers:=.o} 426 libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c} \424 libsrc = libcfa-prelude.c interpose.c bits/debug.c ${headers:=.c} \ 427 425 assert.c exception.c virtual.c $(am__append_4) 428 426 libcfa_a_SOURCES = ${libsrc} … … 437 435 math \ 438 436 gmp \ 437 bits/align.h \ 439 438 bits/containers.h \ 440 439 bits/defs.h \ 440 bits/debug.h \ 441 441 bits/locks.h \ 442 concurrency/invoke.h \ 443 libhdr.h \ 444 libhdr/libalign.h \ 445 libhdr/libdebug.h \ 446 libhdr/libtools.h 442 concurrency/invoke.h 447 443 448 444 CLEANFILES = libcfa-prelude.c … … 511 507 clean-libLIBRARIES: 512 508 -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) 513 libhdr/$(am__dirstamp):514 @$(MKDIR_P) libhdr515 @: > libhdr/$(am__dirstamp)516 libhdr/$(DEPDIR)/$(am__dirstamp):517 @$(MKDIR_P) libhdr/$(DEPDIR)518 @: > libhdr/$(DEPDIR)/$(am__dirstamp)519 libhdr/libcfa_d_a-libdebug.$(OBJEXT): libhdr/$(am__dirstamp) \520 libhdr/$(DEPDIR)/$(am__dirstamp)509 bits/$(am__dirstamp): 510 @$(MKDIR_P) bits 511 @: > bits/$(am__dirstamp) 512 bits/$(DEPDIR)/$(am__dirstamp): 513 @$(MKDIR_P) bits/$(DEPDIR) 514 @: > bits/$(DEPDIR)/$(am__dirstamp) 515 bits/libcfa_d_a-debug.$(OBJEXT): bits/$(am__dirstamp) \ 516 bits/$(DEPDIR)/$(am__dirstamp) 521 517 containers/$(am__dirstamp): 522 518 @$(MKDIR_P) containers … … 563 559 $(AM_V_AR)$(libcfa_d_a_AR) libcfa-d.a $(libcfa_d_a_OBJECTS) $(libcfa_d_a_LIBADD) 564 560 $(AM_V_at)$(RANLIB) libcfa-d.a 565 libhdr/libcfa_a-libdebug.$(OBJEXT): libhdr/$(am__dirstamp) \566 libhdr/$(DEPDIR)/$(am__dirstamp)561 bits/libcfa_a-debug.$(OBJEXT): bits/$(am__dirstamp) \ 562 bits/$(DEPDIR)/$(am__dirstamp) 567 563 containers/libcfa_a-maybe.$(OBJEXT): containers/$(am__dirstamp) \ 568 564 containers/$(DEPDIR)/$(am__dirstamp) … … 596 592 mostlyclean-compile: 597 593 -rm -f *.$(OBJEXT) 594 -rm -f bits/*.$(OBJEXT) 598 595 -rm -f concurrency/*.$(OBJEXT) 599 596 -rm -f containers/*.$(OBJEXT) 600 -rm -f libhdr/*.$(OBJEXT)601 597 602 598 distclean-compile: … … 625 621 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-stdlib.Po@am__quote@ 626 622 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-virtual.Po@am__quote@ 623 @AMDEP_TRUE@@am__include@ @am__quote@bits/$(DEPDIR)/libcfa_a-debug.Po@am__quote@ 624 @AMDEP_TRUE@@am__include@ @am__quote@bits/$(DEPDIR)/libcfa_d_a-debug.Po@am__quote@ 627 625 @AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/CtxSwitch-@MACHINE_TYPE@.Po@am__quote@ 628 626 @AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_a-alarm.Po@am__quote@ … … 648 646 @AMDEP_TRUE@@am__include@ @am__quote@containers/$(DEPDIR)/libcfa_d_a-result.Po@am__quote@ 649 647 @AMDEP_TRUE@@am__include@ @am__quote@containers/$(DEPDIR)/libcfa_d_a-vector.Po@am__quote@ 650 @AMDEP_TRUE@@am__include@ @am__quote@libhdr/$(DEPDIR)/libcfa_a-libdebug.Po@am__quote@651 @AMDEP_TRUE@@am__include@ @am__quote@libhdr/$(DEPDIR)/libcfa_d_a-libdebug.Po@am__quote@652 648 653 649 .S.o: … … 704 700 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o libcfa_d_a-interpose.obj `if test -f 'interpose.c'; then $(CYGPATH_W) 'interpose.c'; else $(CYGPATH_W) '$(srcdir)/interpose.c'; fi` 705 701 706 libhdr/libcfa_d_a-libdebug.o: libhdr/libdebug.c707 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT libhdr/libcfa_d_a-libdebug.o -MD -MP -MF libhdr/$(DEPDIR)/libcfa_d_a-libdebug.Tpo -c -o libhdr/libcfa_d_a-libdebug.o `test -f 'libhdr/libdebug.c' || echo '$(srcdir)/'`libhdr/libdebug.c708 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libhdr/$(DEPDIR)/libcfa_d_a-libdebug.Tpo libhdr/$(DEPDIR)/libcfa_d_a-libdebug.Po709 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source=' libhdr/libdebug.c' object='libhdr/libcfa_d_a-libdebug.o' libtool=no @AMDEPBACKSLASH@710 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 711 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o libhdr/libcfa_d_a-libdebug.o `test -f 'libhdr/libdebug.c' || echo '$(srcdir)/'`libhdr/libdebug.c712 713 libhdr/libcfa_d_a-libdebug.obj: libhdr/libdebug.c714 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT libhdr/libcfa_d_a-libdebug.obj -MD -MP -MF libhdr/$(DEPDIR)/libcfa_d_a-libdebug.Tpo -c -o libhdr/libcfa_d_a-libdebug.obj `if test -f 'libhdr/libdebug.c'; then $(CYGPATH_W) 'libhdr/libdebug.c'; else $(CYGPATH_W) '$(srcdir)/libhdr/libdebug.c'; fi`715 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libhdr/$(DEPDIR)/libcfa_d_a-libdebug.Tpo libhdr/$(DEPDIR)/libcfa_d_a-libdebug.Po716 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source=' libhdr/libdebug.c' object='libhdr/libcfa_d_a-libdebug.obj' libtool=no @AMDEPBACKSLASH@717 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 718 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o libhdr/libcfa_d_a-libdebug.obj `if test -f 'libhdr/libdebug.c'; then $(CYGPATH_W) 'libhdr/libdebug.c'; else $(CYGPATH_W) '$(srcdir)/libhdr/libdebug.c'; fi`702 bits/libcfa_d_a-debug.o: bits/debug.c 703 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT bits/libcfa_d_a-debug.o -MD -MP -MF bits/$(DEPDIR)/libcfa_d_a-debug.Tpo -c -o bits/libcfa_d_a-debug.o `test -f 'bits/debug.c' || echo '$(srcdir)/'`bits/debug.c 704 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) bits/$(DEPDIR)/libcfa_d_a-debug.Tpo bits/$(DEPDIR)/libcfa_d_a-debug.Po 705 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bits/debug.c' object='bits/libcfa_d_a-debug.o' libtool=no @AMDEPBACKSLASH@ 706 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 707 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o bits/libcfa_d_a-debug.o `test -f 'bits/debug.c' || echo '$(srcdir)/'`bits/debug.c 708 709 bits/libcfa_d_a-debug.obj: bits/debug.c 710 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT bits/libcfa_d_a-debug.obj -MD -MP -MF bits/$(DEPDIR)/libcfa_d_a-debug.Tpo -c -o bits/libcfa_d_a-debug.obj `if test -f 'bits/debug.c'; then $(CYGPATH_W) 'bits/debug.c'; else $(CYGPATH_W) '$(srcdir)/bits/debug.c'; fi` 711 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) bits/$(DEPDIR)/libcfa_d_a-debug.Tpo bits/$(DEPDIR)/libcfa_d_a-debug.Po 712 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bits/debug.c' object='bits/libcfa_d_a-debug.obj' libtool=no @AMDEPBACKSLASH@ 713 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 714 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o bits/libcfa_d_a-debug.obj `if test -f 'bits/debug.c'; then $(CYGPATH_W) 'bits/debug.c'; else $(CYGPATH_W) '$(srcdir)/bits/debug.c'; fi` 719 715 720 716 libcfa_d_a-fstream.o: fstream.c … … 998 994 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o libcfa_a-interpose.obj `if test -f 'interpose.c'; then $(CYGPATH_W) 'interpose.c'; else $(CYGPATH_W) '$(srcdir)/interpose.c'; fi` 999 995 1000 libhdr/libcfa_a-libdebug.o: libhdr/libdebug.c1001 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT libhdr/libcfa_a-libdebug.o -MD -MP -MF libhdr/$(DEPDIR)/libcfa_a-libdebug.Tpo -c -o libhdr/libcfa_a-libdebug.o `test -f 'libhdr/libdebug.c' || echo '$(srcdir)/'`libhdr/libdebug.c1002 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libhdr/$(DEPDIR)/libcfa_a-libdebug.Tpo libhdr/$(DEPDIR)/libcfa_a-libdebug.Po1003 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source=' libhdr/libdebug.c' object='libhdr/libcfa_a-libdebug.o' libtool=no @AMDEPBACKSLASH@1004 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1005 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o libhdr/libcfa_a-libdebug.o `test -f 'libhdr/libdebug.c' || echo '$(srcdir)/'`libhdr/libdebug.c1006 1007 libhdr/libcfa_a-libdebug.obj: libhdr/libdebug.c1008 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT libhdr/libcfa_a-libdebug.obj -MD -MP -MF libhdr/$(DEPDIR)/libcfa_a-libdebug.Tpo -c -o libhdr/libcfa_a-libdebug.obj `if test -f 'libhdr/libdebug.c'; then $(CYGPATH_W) 'libhdr/libdebug.c'; else $(CYGPATH_W) '$(srcdir)/libhdr/libdebug.c'; fi`1009 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libhdr/$(DEPDIR)/libcfa_a-libdebug.Tpo libhdr/$(DEPDIR)/libcfa_a-libdebug.Po1010 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source=' libhdr/libdebug.c' object='libhdr/libcfa_a-libdebug.obj' libtool=no @AMDEPBACKSLASH@1011 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1012 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o libhdr/libcfa_a-libdebug.obj `if test -f 'libhdr/libdebug.c'; then $(CYGPATH_W) 'libhdr/libdebug.c'; else $(CYGPATH_W) '$(srcdir)/libhdr/libdebug.c'; fi`996 bits/libcfa_a-debug.o: bits/debug.c 997 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT bits/libcfa_a-debug.o -MD -MP -MF bits/$(DEPDIR)/libcfa_a-debug.Tpo -c -o bits/libcfa_a-debug.o `test -f 'bits/debug.c' || echo '$(srcdir)/'`bits/debug.c 998 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) bits/$(DEPDIR)/libcfa_a-debug.Tpo bits/$(DEPDIR)/libcfa_a-debug.Po 999 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bits/debug.c' object='bits/libcfa_a-debug.o' libtool=no @AMDEPBACKSLASH@ 1000 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1001 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o bits/libcfa_a-debug.o `test -f 'bits/debug.c' || echo '$(srcdir)/'`bits/debug.c 1002 1003 bits/libcfa_a-debug.obj: bits/debug.c 1004 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT bits/libcfa_a-debug.obj -MD -MP -MF bits/$(DEPDIR)/libcfa_a-debug.Tpo -c -o bits/libcfa_a-debug.obj `if test -f 'bits/debug.c'; then $(CYGPATH_W) 'bits/debug.c'; else $(CYGPATH_W) '$(srcdir)/bits/debug.c'; fi` 1005 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) bits/$(DEPDIR)/libcfa_a-debug.Tpo bits/$(DEPDIR)/libcfa_a-debug.Po 1006 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bits/debug.c' object='bits/libcfa_a-debug.obj' libtool=no @AMDEPBACKSLASH@ 1007 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1008 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o bits/libcfa_a-debug.obj `if test -f 'bits/debug.c'; then $(CYGPATH_W) 'bits/debug.c'; else $(CYGPATH_W) '$(srcdir)/bits/debug.c'; fi` 1013 1009 1014 1010 libcfa_a-fstream.o: fstream.c … … 1411 1407 -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) 1412 1408 -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) 1409 -rm -f bits/$(DEPDIR)/$(am__dirstamp) 1410 -rm -f bits/$(am__dirstamp) 1413 1411 -rm -f concurrency/$(DEPDIR)/$(am__dirstamp) 1414 1412 -rm -f concurrency/$(am__dirstamp) 1415 1413 -rm -f containers/$(DEPDIR)/$(am__dirstamp) 1416 1414 -rm -f containers/$(am__dirstamp) 1417 -rm -f libhdr/$(DEPDIR)/$(am__dirstamp)1418 -rm -f libhdr/$(am__dirstamp)1419 1415 1420 1416 maintainer-clean-generic: … … 1426 1422 1427 1423 distclean: distclean-am 1428 -rm -rf ./$(DEPDIR) concurrency/$(DEPDIR) containers/$(DEPDIR) libhdr/$(DEPDIR)1424 -rm -rf ./$(DEPDIR) bits/$(DEPDIR) concurrency/$(DEPDIR) containers/$(DEPDIR) 1429 1425 -rm -f Makefile 1430 1426 distclean-am: clean-am distclean-compile distclean-generic \ … … 1472 1468 1473 1469 maintainer-clean: maintainer-clean-am 1474 -rm -rf ./$(DEPDIR) concurrency/$(DEPDIR) containers/$(DEPDIR) libhdr/$(DEPDIR)1470 -rm -rf ./$(DEPDIR) bits/$(DEPDIR) concurrency/$(DEPDIR) containers/$(DEPDIR) 1475 1471 -rm -f Makefile 1476 1472 maintainer-clean-am: distclean-am maintainer-clean-generic \ -
src/libcfa/assert.c
r9c35431 rc13e8dc8 17 17 #include <stdarg.h> // varargs 18 18 #include <stdio.h> // fprintf 19 #include " libhdr/libdebug.h"19 #include "bits/debug.h" 20 20 21 21 extern "C" { … … 26 26 // called by macro assert in assert.h 27 27 void __assert_fail( const char *assertion, const char *file, unsigned int line, const char *function ) { 28 __ lib_debug_print_safe( CFA_ASSERT_FMT ".\n", __progname, function, line, file );28 __cfaabi_dbg_bits_print_safe( CFA_ASSERT_FMT ".\n", __progname, function, line, file ); 29 29 abort(); 30 30 } … … 32 32 // called by macro assertf 33 33 void __assert_fail_f( const char *assertion, const char *file, unsigned int line, const char *function, const char *fmt, ... ) { 34 __ lib_debug_acquire();35 __ lib_debug_print_nolock( CFA_ASSERT_FMT ": ", __progname, function, line, file );34 __cfaabi_dbg_bits_acquire(); 35 __cfaabi_dbg_bits_print_nolock( CFA_ASSERT_FMT ": ", __progname, function, line, file ); 36 36 37 37 va_list args; 38 38 va_start( args, fmt ); 39 __ lib_debug_print_vararg( fmt, args );39 __cfaabi_dbg_bits_print_vararg( fmt, args ); 40 40 va_end( args ); 41 41 42 __ lib_debug_print_nolock( "\n" );43 __ lib_debug_release();42 __cfaabi_dbg_bits_print_nolock( "\n" ); 43 __cfaabi_dbg_bits_release(); 44 44 abort(); 45 45 } -
src/libcfa/bits/align.h
r9c35431 rc13e8dc8 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // libdebug.h --7 // align.h -- 8 8 // 9 9 // Author : Thierry Delisle -
src/libcfa/bits/containers.h
r9c35431 rc13e8dc8 15 15 #pragma once 16 16 17 #include "bits/align.h" 17 18 #include "bits/defs.h" 18 #include "libhdr.h"19 19 20 20 //----------------------------------------------------------------------------- -
src/libcfa/bits/debug.c
r9c35431 rc13e8dc8 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // libdebug.c --7 // debug.c -- 8 8 // 9 9 // Author : Thierry Delisle … … 28 28 extern "C" { 29 29 30 void __ lib_debug_write( const char *in_buffer, int len ) {30 void __cfaabi_dbg_bits_write( const char *in_buffer, int len ) { 31 31 // ensure all data is written 32 32 for ( int count = 0, retcode; count < len; count += retcode ) { … … 44 44 } 45 45 46 void __ lib_debug_acquire() __attribute__((__weak__)) {}47 void __ lib_debug_release() __attribute__((__weak__)) {}46 void __cfaabi_dbg_bits_acquire() __attribute__((__weak__)) {} 47 void __cfaabi_dbg_bits_release() __attribute__((__weak__)) {} 48 48 49 void __ lib_debug_print_safe ( const char fmt[], ... ) __attribute__(( format (printf, 1, 2) )) {49 void __cfaabi_dbg_bits_print_safe ( const char fmt[], ... ) __attribute__(( format (printf, 1, 2) )) { 50 50 va_list args; 51 51 52 52 va_start( args, fmt ); 53 __ lib_debug_acquire();53 __cfaabi_dbg_bits_acquire(); 54 54 55 55 int len = vsnprintf( buffer, buffer_size, fmt, args ); 56 __ lib_debug_write( buffer, len );56 __cfaabi_dbg_bits_write( buffer, len ); 57 57 58 __ lib_debug_release();58 __cfaabi_dbg_bits_release(); 59 59 va_end( args ); 60 60 } 61 61 62 void __ lib_debug_print_nolock( const char fmt[], ... ) __attribute__(( format (printf, 1, 2) )) {62 void __cfaabi_dbg_bits_print_nolock( const char fmt[], ... ) __attribute__(( format (printf, 1, 2) )) { 63 63 va_list args; 64 64 … … 66 66 67 67 int len = vsnprintf( buffer, buffer_size, fmt, args ); 68 __ lib_debug_write( buffer, len );68 __cfaabi_dbg_bits_write( buffer, len ); 69 69 70 70 va_end( args ); 71 71 } 72 72 73 void __ lib_debug_print_vararg( const char fmt[], va_list args ) {73 void __cfaabi_dbg_bits_print_vararg( const char fmt[], va_list args ) { 74 74 int len = vsnprintf( buffer, buffer_size, fmt, args ); 75 __ lib_debug_write( buffer, len );75 __cfaabi_dbg_bits_write( buffer, len ); 76 76 } 77 77 78 void __ lib_debug_print_buffer( char in_buffer[], int in_buffer_size, const char fmt[], ... ) __attribute__(( format (printf, 3, 4) )) {78 void __cfaabi_dbg_bits_print_buffer( char in_buffer[], int in_buffer_size, const char fmt[], ... ) __attribute__(( format (printf, 3, 4) )) { 79 79 va_list args; 80 80 … … 82 82 83 83 int len = vsnprintf( in_buffer, in_buffer_size, fmt, args ); 84 __ lib_debug_write( in_buffer, len );84 __cfaabi_dbg_bits_write( in_buffer, len ); 85 85 86 86 va_end( args ); -
src/libcfa/bits/defs.h
r9c35431 rc13e8dc8 32 32 #define __cfa_anonymous_object __cfa_anonymous_object 33 33 #endif 34 35 #ifdef __cforall 36 extern "C" { 37 #endif 38 void abortf( const char fmt[], ... ) __attribute__ ((__nothrow__, __leaf__, __noreturn__)); 39 #ifdef __cforall 40 } 41 #endif -
src/libcfa/bits/locks.h
r9c35431 rc13e8dc8 16 16 #pragma once 17 17 18 #include "bits/debug.h" 18 19 #include "bits/defs.h" 19 20 #include "libhdr.h"21 20 22 21 // pause to prevent excess processor bus usage … … 65 64 66 65 // Lock the spinlock, return false if already acquired 67 static inline _Bool try_lock ( __spinlock_t & this DEBUG_CTX_PARAM2 ) {66 static inline _Bool try_lock ( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) { 68 67 _Bool result = __lock_test_and_test_and_set( this.lock ); 69 LIB_DEBUG_DO(68 __cfaabi_dbg_debug_do( 70 69 if( result ) { 71 70 this.prev_name = caller; … … 77 76 78 77 // Lock the spinlock, spin if already acquired 79 static inline void lock( __spinlock_t & this DEBUG_CTX_PARAM2 ) {78 static inline void lock( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) { 80 79 #ifndef NOEXPBACK 81 80 enum { SPIN_START = 4, SPIN_END = 64 * 1024, }; … … 98 97 #endif 99 98 } 100 LIB_DEBUG_DO(99 __cfaabi_dbg_debug_do( 101 100 this.prev_name = caller; 102 101 this.prev_thrd = this_thread; … … 105 104 106 105 // Lock the spinlock, spin if already acquired 107 static inline void lock_yield( __spinlock_t & this DEBUG_CTX_PARAM2 ) {106 static inline void lock_yield( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) { 108 107 for ( unsigned int i = 1;; i += 1 ) { 109 108 if ( __lock_test_and_test_and_set( this.lock ) ) break; 110 109 yield( i ); 111 110 } 112 LIB_DEBUG_DO(111 __cfaabi_dbg_debug_do( 113 112 this.prev_name = caller; 114 113 this.prev_thrd = this_thread; -
src/libcfa/concurrency/alarm.c
r9c35431 rc13e8dc8 23 23 } 24 24 25 #include "libhdr.h"26 27 25 #include "alarm.h" 28 26 #include "kernel_private.h" … … 110 108 } 111 109 112 LIB_DEBUG_DO( bool validate( alarm_list_t * this ) {110 __cfaabi_dbg_debug_do( bool validate( alarm_list_t * this ) { 113 111 alarm_node_t ** it = &this->head; 114 112 while( (*it) ) { … … 186 184 187 185 disable_interrupts(); 188 lock( event_kernel->lock DEBUG_CTX2 );186 lock( event_kernel->lock __cfaabi_dbg_ctx2 ); 189 187 { 190 188 verify( validate( alarms ) ); … … 198 196 unlock( event_kernel->lock ); 199 197 this->set = true; 200 enable_interrupts( DEBUG_CTX);198 enable_interrupts( __cfaabi_dbg_ctx ); 201 199 } 202 200 203 201 void unregister_self( alarm_node_t * this ) { 204 202 disable_interrupts(); 205 lock( event_kernel->lock DEBUG_CTX2 );203 lock( event_kernel->lock __cfaabi_dbg_ctx2 ); 206 204 { 207 205 verify( validate( &event_kernel->alarms ) ); … … 209 207 } 210 208 unlock( event_kernel->lock ); 211 enable_interrupts( DEBUG_CTX);209 enable_interrupts( __cfaabi_dbg_ctx ); 212 210 this->set = false; 213 211 } -
src/libcfa/concurrency/coroutine.c
r9c35431 rc13e8dc8 29 29 #define __CFA_INVOKE_PRIVATE__ 30 30 #include "invoke.h" 31 32 31 33 32 //----------------------------------------------------------------------------- … … 76 75 void ^?{}(coStack_t & this) { 77 76 if ( ! this.userStack && this.storage ) { 78 LIB_DEBUG_DO(77 __cfaabi_dbg_debug_do( 79 78 if ( mprotect( this.storage, pageSize, PROT_READ | PROT_WRITE ) == -1 ) { 80 79 abortf( "(coStack_t *)%p.^?{}() : internal error, mprotect failure, error(%d) %s.", &this, errno, strerror( errno ) ); … … 131 130 132 131 // assume malloc has 8 byte alignment so add 8 to allow rounding up to 16 byte alignment 133 LIB_DEBUG_DO( this->storage = memalign( pageSize, cxtSize + this->size + pageSize ) );134 LIB_NO_DEBUG_DO( this->storage = malloc( cxtSize + this->size + 8 ) );132 __cfaabi_dbg_debug_do( this->storage = memalign( pageSize, cxtSize + this->size + pageSize ) ); 133 __cfaabi_dbg_no_debug_do( this->storage = malloc( cxtSize + this->size + 8 ) ); 135 134 136 LIB_DEBUG_DO(135 __cfaabi_dbg_debug_do( 137 136 if ( mprotect( this->storage, pageSize, PROT_NONE ) == -1 ) { 138 137 abortf( "(uMachContext &)%p.createContext() : internal error, mprotect failure, error(%d) %s.", this, (int)errno, strerror( (int)errno ) ); … … 144 143 } // if 145 144 146 LIB_DEBUG_DO( this->limit = (char *)this->storage + pageSize );147 LIB_NO_DEBUG_DO( this->limit = (char *)libCeiling( (unsigned long)this->storage, 16 ) ); // minimum alignment145 __cfaabi_dbg_debug_do( this->limit = (char *)this->storage + pageSize ); 146 __cfaabi_dbg_no_debug_do( this->limit = (char *)libCeiling( (unsigned long)this->storage, 16 ) ); // minimum alignment 148 147 149 148 } else { -
src/libcfa/concurrency/invoke.c
r9c35431 rc13e8dc8 18 18 #include <stdio.h> 19 19 20 #include "libhdr.h"21 20 #include "invoke.h" 22 21 … … 31 30 extern void __leave_thread_monitor( struct thread_desc * this ); 32 31 extern void disable_interrupts(); 33 extern void enable_interrupts( DEBUG_CTX_PARAM);32 extern void enable_interrupts( __cfaabi_dbg_ctx_param ); 34 33 35 34 void CtxInvokeCoroutine( 36 37 38 35 void (*main)(void *), 36 struct coroutine_desc *(*get_coroutine)(void *), 37 void *this 39 38 ) { 40 // LIB_DEBUG_PRINTF("Invoke Coroutine : Received %p (main %p, get_c %p)\n", this, main, get_coroutine);39 struct coroutine_desc* cor = get_coroutine( this ); 41 40 42 struct coroutine_desc* cor = get_coroutine( this ); 41 if(cor->state == Primed) { 42 __suspend_internal(); 43 } 43 44 44 if(cor->state == Primed) { 45 __suspend_internal(); 46 } 45 cor->state = Active; 47 46 48 cor->state = Active;47 main( this ); 49 48 50 main( this );49 cor->state = Halted; 51 50 52 cor->state = Halted; 53 54 //Final suspend, should never return 55 __leave_coroutine(); 56 abortf("Resumed dead coroutine"); 51 //Final suspend, should never return 52 __leave_coroutine(); 53 abortf("Resumed dead coroutine"); 57 54 } 58 55 59 56 void CtxInvokeThread( 60 61 62 63 57 void (*dtor)(void *), 58 void (*main)(void *), 59 struct thread_desc *(*get_thread)(void *), 60 void *this 64 61 ) { 65 66 67 62 // First suspend, once the thread arrives here, 63 // the function pointer to main can be invalidated without risk 64 __suspend_internal(); 68 65 69 70 66 // Fetch the thread handle from the user defined thread structure 67 struct thread_desc* thrd = get_thread( this ); 71 68 72 73 enable_interrupts( DEBUG_CTX);69 // Officially start the thread by enabling preemption 70 enable_interrupts( __cfaabi_dbg_ctx ); 74 71 75 76 72 // Call the main of the thread 73 main( this ); 77 74 78 79 80 81 82 83 84 85 86 75 // To exit a thread we must : 76 // 1 - Mark it as halted 77 // 2 - Leave its monitor 78 // 3 - Disable the interupts 79 // 4 - Final suspend 80 // The order of these 4 operations is very important 81 //Final suspend, should never return 82 __leave_thread_monitor( thrd ); 83 abortf("Resumed dead thread"); 87 84 } 88 85 89 86 90 87 void CtxStart( 91 92 93 94 88 void (*main)(void *), 89 struct coroutine_desc *(*get_coroutine)(void *), 90 void *this, 91 void (*invoke)(void *) 95 92 ) { 96 // LIB_DEBUG_PRINTF("StartCoroutine : Passing in %p (main %p) to invoke (%p) from start (%p)\n", this, main, invoke, CtxStart); 97 98 struct coStack_t* stack = &get_coroutine( this )->stack; 93 struct coStack_t* stack = &get_coroutine( this )->stack; 99 94 100 95 #if defined( __i386__ ) … … 103 98 void *fixedRegisters[3]; // fixed registers ebx, edi, esi (popped on 1st uSwitch, values unimportant) 104 99 uint32_t mxcr; // SSE Status and Control bits (control bits are preserved across function calls) 105 100 uint16_t fcw; // X97 FPU control word (preserved across function calls) 106 101 void *rturn; // where to go on return from uSwitch 107 102 void *dummyReturn; // fake return compiler would have pushed on call to uInvoke … … 116 111 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->argument[0] = this; // argument to invoke 117 112 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = invoke; 118 119 113 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520 114 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7 120 115 121 116 #elif defined( __x86_64__ ) 122 117 123 124 125 126 127 128 129 118 struct FakeStack { 119 void *fixedRegisters[5]; // fixed registers rbx, r12, r13, r14, r15 120 uint32_t mxcr; // SSE Status and Control bits (control bits are preserved across function calls) 121 uint16_t fcw; // X97 FPU control word (preserved across function calls) 122 void *rturn; // where to go on return from uSwitch 123 void *dummyReturn; // NULL return address to provide proper alignment 124 }; 130 125 131 132 126 ((struct machine_context_t *)stack->context)->SP = (char *)stack->base - sizeof( struct FakeStack ); 127 ((struct machine_context_t *)stack->context)->FP = NULL; // terminate stack with NULL fp 133 128 134 135 136 137 138 139 129 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->dummyReturn = NULL; 130 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = CtxInvokeStub; 131 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[0] = this; 132 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[1] = invoke; 133 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520 134 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7 140 135 #else 141 136 #error Only __i386__ and __x86_64__ is supported for threads in cfa 142 137 #endif 143 138 } -
src/libcfa/concurrency/kernel.c
r9c35431 rc13e8dc8 14 14 // 15 15 16 #include "libhdr.h"17 18 16 //C Includes 19 17 #include <stddef.h> … … 150 148 151 149 this.runner = &runner; 152 LIB_DEBUG_PRINT_SAFE("Kernel : constructing main processor context %p\n", &runner);150 __cfaabi_dbg_print_safe("Kernel : constructing main processor context %p\n", &runner); 153 151 runner{ &this }; 154 152 } … … 156 154 void ^?{}(processor & this) { 157 155 if( ! this.do_terminate ) { 158 LIB_DEBUG_PRINT_SAFE("Kernel : core %p signaling termination\n", &this);156 __cfaabi_dbg_print_safe("Kernel : core %p signaling termination\n", &this); 159 157 this.do_terminate = true; 160 158 P( this.terminated ); … … 181 179 processor * this = runner.proc; 182 180 183 LIB_DEBUG_PRINT_SAFE("Kernel : core %p starting\n", this);181 __cfaabi_dbg_print_safe("Kernel : core %p starting\n", this); 184 182 185 183 { … … 187 185 preemption_scope scope = { this }; 188 186 189 LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this);187 __cfaabi_dbg_print_safe("Kernel : core %p started\n", this); 190 188 191 189 thread_desc * readyThread = NULL; … … 213 211 } 214 212 215 LIB_DEBUG_PRINT_SAFE("Kernel : core %p stopping\n", this);213 __cfaabi_dbg_print_safe("Kernel : core %p stopping\n", this); 216 214 } 217 215 218 216 V( this->terminated ); 219 217 220 LIB_DEBUG_PRINT_SAFE("Kernel : core %p terminated\n", this);218 __cfaabi_dbg_print_safe("Kernel : core %p terminated\n", this); 221 219 } 222 220 … … 292 290 processorCtx_t proc_cor_storage = { proc, &info }; 293 291 294 LIB_DEBUG_PRINT_SAFE("Coroutine : created stack %p\n", proc_cor_storage.__cor.stack.base);292 __cfaabi_dbg_print_safe("Coroutine : created stack %p\n", proc_cor_storage.__cor.stack.base); 295 293 296 294 //Set global state … … 299 297 300 298 //We now have a proper context from which to schedule threads 301 LIB_DEBUG_PRINT_SAFE("Kernel : core %p created (%p, %p)\n", proc, proc->runner, &ctx);299 __cfaabi_dbg_print_safe("Kernel : core %p created (%p, %p)\n", proc, proc->runner, &ctx); 302 300 303 301 // SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't … … 310 308 311 309 // Main routine of the core returned, the core is now fully terminated 312 LIB_DEBUG_PRINT_SAFE("Kernel : core %p main ended (%p)\n", proc, proc->runner);310 __cfaabi_dbg_print_safe("Kernel : core %p main ended (%p)\n", proc, proc->runner); 313 311 314 312 return NULL; … … 316 314 317 315 void start(processor * this) { 318 LIB_DEBUG_PRINT_SAFE("Kernel : Starting core %p\n", this);316 __cfaabi_dbg_print_safe("Kernel : Starting core %p\n", this); 319 317 320 318 pthread_create( &this->kernel_thread, NULL, CtxInvokeProcessor, (void*)this ); 321 319 322 LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this);320 __cfaabi_dbg_print_safe("Kernel : core %p started\n", this); 323 321 } 324 322 … … 334 332 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next ); 335 333 336 lock( this_processor->cltr->ready_queue_lock DEBUG_CTX2 );334 lock( this_processor->cltr->ready_queue_lock __cfaabi_dbg_ctx2 ); 337 335 append( this_processor->cltr->ready_queue, thrd ); 338 336 unlock( this_processor->cltr->ready_queue_lock ); … … 343 341 thread_desc * nextThread(cluster * this) { 344 342 verify( disable_preempt_count > 0 ); 345 lock( this->ready_queue_lock DEBUG_CTX2 );343 lock( this->ready_queue_lock __cfaabi_dbg_ctx2 ); 346 344 thread_desc * head = pop_head( this->ready_queue ); 347 345 unlock( this->ready_queue_lock ); … … 355 353 suspend(); 356 354 verify( disable_preempt_count > 0 ); 357 enable_interrupts( DEBUG_CTX);355 enable_interrupts( __cfaabi_dbg_ctx ); 358 356 } 359 357 … … 367 365 verify( disable_preempt_count > 0 ); 368 366 369 enable_interrupts( DEBUG_CTX);367 enable_interrupts( __cfaabi_dbg_ctx ); 370 368 } 371 369 … … 381 379 verify( disable_preempt_count > 0 ); 382 380 383 enable_interrupts( DEBUG_CTX);381 enable_interrupts( __cfaabi_dbg_ctx ); 384 382 } 385 383 … … 395 393 verify( disable_preempt_count > 0 ); 396 394 397 enable_interrupts( DEBUG_CTX);395 enable_interrupts( __cfaabi_dbg_ctx ); 398 396 } 399 397 … … 408 406 verify( disable_preempt_count > 0 ); 409 407 410 enable_interrupts( DEBUG_CTX);408 enable_interrupts( __cfaabi_dbg_ctx ); 411 409 } 412 410 … … 423 421 verify( disable_preempt_count > 0 ); 424 422 425 enable_interrupts( DEBUG_CTX);423 enable_interrupts( __cfaabi_dbg_ctx ); 426 424 } 427 425 … … 441 439 // Kernel boot procedures 442 440 void kernel_startup(void) { 443 LIB_DEBUG_PRINT_SAFE("Kernel : Starting\n");441 __cfaabi_dbg_print_safe("Kernel : Starting\n"); 444 442 445 443 // Start by initializing the main thread … … 450 448 (*mainThread){ &info }; 451 449 452 LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n");450 __cfaabi_dbg_print_safe("Kernel : Main thread ready\n"); 453 451 454 452 // Initialize the main cluster … … 456 454 (*mainCluster){}; 457 455 458 LIB_DEBUG_PRINT_SAFE("Kernel : main cluster ready\n");456 __cfaabi_dbg_print_safe("Kernel : main cluster ready\n"); 459 457 460 458 // Initialize the main processor and the main processor ctx … … 483 481 484 482 // THE SYSTEM IS NOW COMPLETELY RUNNING 485 LIB_DEBUG_PRINT_SAFE("Kernel : Started\n--------------------------------------------------\n\n");486 487 enable_interrupts( DEBUG_CTX);483 __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n"); 484 485 enable_interrupts( __cfaabi_dbg_ctx ); 488 486 } 489 487 490 488 void kernel_shutdown(void) { 491 LIB_DEBUG_PRINT_SAFE("\n--------------------------------------------------\nKernel : Shutting down\n");489 __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n"); 492 490 493 491 disable_interrupts(); … … 513 511 ^(mainThread){}; 514 512 515 LIB_DEBUG_PRINT_SAFE("Kernel : Shutdown complete\n");513 __cfaabi_dbg_print_safe("Kernel : Shutdown complete\n"); 516 514 } 517 515 … … 523 521 // abort cannot be recursively entered by the same or different processors because all signal handlers return when 524 522 // the globalAbort flag is true. 525 lock( kernel_abort_lock DEBUG_CTX2 );523 lock( kernel_abort_lock __cfaabi_dbg_ctx2 ); 526 524 527 525 // first task to abort ? … … 548 546 549 547 int len = snprintf( abort_text, abort_text_size, "Error occurred while executing task %.256s (%p)", thrd->self_cor.name, thrd ); 550 __ lib_debug_write( abort_text, len );548 __cfaabi_dbg_bits_write( abort_text, len ); 551 549 552 550 if ( thrd != this_coroutine ) { 553 551 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine->name, this_coroutine ); 554 __ lib_debug_write( abort_text, len );552 __cfaabi_dbg_bits_write( abort_text, len ); 555 553 } 556 554 else { 557 __ lib_debug_write( ".\n", 2 );555 __cfaabi_dbg_bits_write( ".\n", 2 ); 558 556 } 559 557 } 560 558 561 559 extern "C" { 562 void __ lib_debug_acquire() {563 lock( kernel_debug_lock DEBUG_CTX2 );564 } 565 566 void __ lib_debug_release() {560 void __cfaabi_dbg_bits_acquire() { 561 lock( kernel_debug_lock __cfaabi_dbg_ctx2 ); 562 } 563 564 void __cfaabi_dbg_bits_release() { 567 565 unlock( kernel_debug_lock ); 568 566 } … … 582 580 583 581 void P(semaphore & this) { 584 lock( this.lock DEBUG_CTX2 );582 lock( this.lock __cfaabi_dbg_ctx2 ); 585 583 this.count -= 1; 586 584 if ( this.count < 0 ) { … … 598 596 void V(semaphore & this) { 599 597 thread_desc * thrd = NULL; 600 lock( this.lock DEBUG_CTX2 );598 lock( this.lock __cfaabi_dbg_ctx2 ); 601 599 this.count += 1; 602 600 if ( this.count <= 0 ) { -
src/libcfa/concurrency/kernel_private.h
r9c35431 rc13e8dc8 16 16 #pragma once 17 17 18 #include "libhdr.h"19 20 18 #include "kernel" 21 19 #include "thread" … … 30 28 void disable_interrupts(); 31 29 void enable_interrupts_noPoll(); 32 void enable_interrupts( DEBUG_CTX_PARAM);30 void enable_interrupts( __cfaabi_dbg_ctx_param ); 33 31 } 34 32 … … 39 37 disable_interrupts(); 40 38 ScheduleThread( thrd ); 41 enable_interrupts( DEBUG_CTX);39 enable_interrupts( __cfaabi_dbg_ctx ); 42 40 } 43 41 thread_desc * nextThread(cluster * this); -
src/libcfa/concurrency/monitor.c
r9c35431 rc13e8dc8 19 19 #include <inttypes.h> 20 20 21 #include "libhdr.h"22 21 #include "kernel_private.h" 23 22 … … 91 90 static void __enter_monitor_desc( monitor_desc * this, const __monitor_group_t & group ) { 92 91 // Lock the monitor spinlock 93 DO_LOCK( this->lock DEBUG_CTX2 );92 DO_LOCK( this->lock __cfaabi_dbg_ctx2 ); 94 93 thread_desc * thrd = this_thread; 95 94 96 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);95 __cfaabi_dbg_print_safe("Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner); 97 96 98 97 if( !this->owner ) { … … 100 99 set_owner( this, thrd ); 101 100 102 LIB_DEBUG_PRINT_SAFE("Kernel : mon is free \n");101 __cfaabi_dbg_print_safe("Kernel : mon is free \n"); 103 102 } 104 103 else if( this->owner == thrd) { … … 106 105 this->recursion += 1; 107 106 108 LIB_DEBUG_PRINT_SAFE("Kernel : mon already owned \n");107 __cfaabi_dbg_print_safe("Kernel : mon already owned \n"); 109 108 } 110 109 else if( is_accepted( this, group) ) { … … 115 114 reset_mask( this ); 116 115 117 LIB_DEBUG_PRINT_SAFE("Kernel : mon accepts \n");116 __cfaabi_dbg_print_safe("Kernel : mon accepts \n"); 118 117 } 119 118 else { 120 LIB_DEBUG_PRINT_SAFE("Kernel : blocking \n");119 __cfaabi_dbg_print_safe("Kernel : blocking \n"); 121 120 122 121 // Some one else has the monitor, wait in line for it … … 124 123 BlockInternal( &this->lock ); 125 124 126 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entered mon %p\n", thrd, this);125 __cfaabi_dbg_print_safe("Kernel : %10p Entered mon %p\n", thrd, this); 127 126 128 127 // BlockInternal will unlock spinlock, no need to unlock ourselves … … 130 129 } 131 130 132 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entered mon %p\n", thrd, this);131 __cfaabi_dbg_print_safe("Kernel : %10p Entered mon %p\n", thrd, this); 133 132 134 133 // Release the lock and leave … … 139 138 static void __enter_monitor_dtor( monitor_desc * this, fptr_t func ) { 140 139 // Lock the monitor spinlock 141 DO_LOCK( this->lock DEBUG_CTX2 );140 DO_LOCK( this->lock __cfaabi_dbg_ctx2 ); 142 141 thread_desc * thrd = this_thread; 143 142 144 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entering dtor for mon %p (%p)\n", thrd, this, this->owner);143 __cfaabi_dbg_print_safe("Kernel : %10p Entering dtor for mon %p (%p)\n", thrd, this, this->owner); 145 144 146 145 147 146 if( !this->owner ) { 148 LIB_DEBUG_PRINT_SAFE("Kernel : Destroying free mon %p\n", this);147 __cfaabi_dbg_print_safe("Kernel : Destroying free mon %p\n", this); 149 148 150 149 // No one has the monitor, just take it … … 164 163 __monitor_group_t group = { &this, 1, func }; 165 164 if( is_accepted( this, group) ) { 166 LIB_DEBUG_PRINT_SAFE("Kernel : mon accepts dtor, block and signal it \n");165 __cfaabi_dbg_print_safe("Kernel : mon accepts dtor, block and signal it \n"); 167 166 168 167 // Wake the thread that is waiting for this … … 183 182 } 184 183 else { 185 LIB_DEBUG_PRINT_SAFE("Kernel : blocking \n");184 __cfaabi_dbg_print_safe("Kernel : blocking \n"); 186 185 187 186 wait_ctx( this_thread, 0 ) … … 196 195 } 197 196 198 LIB_DEBUG_PRINT_SAFE("Kernel : Destroying %p\n", this);197 __cfaabi_dbg_print_safe("Kernel : Destroying %p\n", this); 199 198 200 199 } … … 203 202 void __leave_monitor_desc( monitor_desc * this ) { 204 203 // Lock the monitor spinlock, DO_LOCK to reduce contention 205 DO_LOCK( this->lock DEBUG_CTX2 );206 207 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Leaving mon %p (%p)\n", this_thread, this, this->owner);204 DO_LOCK( this->lock __cfaabi_dbg_ctx2 ); 205 206 __cfaabi_dbg_print_safe("Kernel : %10p Leaving mon %p (%p)\n", this_thread, this, this->owner); 208 207 209 208 verifyf( this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", this_thread, this->owner, this->recursion, this ); … … 215 214 // it means we don't need to do anything 216 215 if( this->recursion != 0) { 217 LIB_DEBUG_PRINT_SAFE("Kernel : recursion still %d\n", this->recursion);216 __cfaabi_dbg_print_safe("Kernel : recursion still %d\n", this->recursion); 218 217 unlock( this->lock ); 219 218 return; … … 232 231 // Leave single monitor for the last time 233 232 void __leave_dtor_monitor_desc( monitor_desc * this ) { 234 LIB_DEBUG_DO(233 __cfaabi_dbg_debug_do( 235 234 if( this_thread != this->owner ) { 236 235 abortf("Destroyed monitor %p has inconsistent owner, expected %p got %p.\n", this, this_thread, this->owner); … … 249 248 250 249 // Lock the monitor now 251 DO_LOCK( this->lock DEBUG_CTX2 );250 DO_LOCK( this->lock __cfaabi_dbg_ctx2 ); 252 251 253 252 disable_interrupts(); … … 308 307 (this_thread->monitors){m, count, func}; 309 308 310 // LIB_DEBUG_PRINT_SAFE("MGUARD : enter %d\n", count);309 // __cfaabi_dbg_print_safe("MGUARD : enter %d\n", count); 311 310 312 311 // Enter the monitors in order … … 314 313 enter( group ); 315 314 316 // LIB_DEBUG_PRINT_SAFE("MGUARD : entered\n");315 // __cfaabi_dbg_print_safe("MGUARD : entered\n"); 317 316 } 318 317 … … 320 319 // Dtor for monitor guard 321 320 void ^?{}( monitor_guard_t & this ) { 322 // LIB_DEBUG_PRINT_SAFE("MGUARD : leaving %d\n", this.count);321 // __cfaabi_dbg_print_safe("MGUARD : leaving %d\n", this.count); 323 322 324 323 // Leave the monitors in order 325 324 leave( this.m, this.count ); 326 325 327 // LIB_DEBUG_PRINT_SAFE("MGUARD : left\n");326 // __cfaabi_dbg_print_safe("MGUARD : left\n"); 328 327 329 328 // Restore thread context … … 430 429 431 430 //Some more checking in debug 432 LIB_DEBUG_DO(431 __cfaabi_dbg_debug_do( 433 432 thread_desc * this_thrd = this_thread; 434 433 if ( this.monitor_count != this_thrd->monitors.size ) { … … 487 486 set_owner( monitors, count, signallee ); 488 487 489 LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : signal_block condition %p (s: %p)\n", &this, signallee );488 __cfaabi_dbg_print_buffer_decl( "Kernel : signal_block condition %p (s: %p)\n", &this, signallee ); 490 489 491 490 //Everything is ready to go to sleep … … 496 495 497 496 498 LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : signal_block returned\n" );497 __cfaabi_dbg_print_buffer_local( "Kernel : signal_block returned\n" ); 499 498 500 499 //We are back, restore the masks and recursions … … 535 534 __lock_size_t actual_count = aggregate( mon_storage, mask ); 536 535 537 LIB_DEBUG_PRINT_BUFFER_DECL( "Kernel : waitfor %d (s: %d, m: %d)\n", actual_count, mask.size, (__lock_size_t)max);536 __cfaabi_dbg_print_buffer_decl( "Kernel : waitfor %d (s: %d, m: %d)\n", actual_count, mask.size, (__lock_size_t)max); 538 537 539 538 if(actual_count == 0) return; 540 539 541 LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : waitfor internal proceeding\n");540 __cfaabi_dbg_print_buffer_local( "Kernel : waitfor internal proceeding\n"); 542 541 543 542 // Create storage for monitor context … … 556 555 __acceptable_t& accepted = mask[index]; 557 556 if( accepted.is_dtor ) { 558 LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : dtor already there\n");557 __cfaabi_dbg_print_buffer_local( "Kernel : dtor already there\n"); 559 558 verifyf( accepted.size == 1, "ERROR: Accepted dtor has more than 1 mutex parameter." ); 560 559 … … 568 567 } 569 568 else { 570 LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : thread present, baton-passing\n");569 __cfaabi_dbg_print_buffer_local( "Kernel : thread present, baton-passing\n"); 571 570 572 571 // Create the node specific to this wait operation … … 576 575 monitor_save; 577 576 578 LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : baton of %d monitors : ", count );577 __cfaabi_dbg_print_buffer_local( "Kernel : baton of %d monitors : ", count ); 579 578 #ifdef __CFA_DEBUG_PRINT__ 580 579 for( int i = 0; i < count; i++) { 581 LIB_DEBUG_PRINT_BUFFER_LOCAL( "%p %p ", monitors[i], monitors[i]->signal_stack.top );580 __cfaabi_dbg_print_buffer_local( "%p %p ", monitors[i], monitors[i]->signal_stack.top ); 582 581 } 583 582 #endif 584 LIB_DEBUG_PRINT_BUFFER_LOCAL( "\n");583 __cfaabi_dbg_print_buffer_local( "\n"); 585 584 586 585 // Set the owners to be the next thread … … 593 592 monitor_restore; 594 593 595 LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : thread present, returned\n");594 __cfaabi_dbg_print_buffer_local( "Kernel : thread present, returned\n"); 596 595 } 597 596 598 LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : accepted %d\n", *mask.accepted);597 __cfaabi_dbg_print_buffer_local( "Kernel : accepted %d\n", *mask.accepted); 599 598 return; 600 599 } … … 603 602 604 603 if( duration == 0 ) { 605 LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : non-blocking, exiting\n");604 __cfaabi_dbg_print_buffer_local( "Kernel : non-blocking, exiting\n"); 606 605 607 606 unlock_all( locks, count ); 608 607 609 LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : accepted %d\n", *mask.accepted);608 __cfaabi_dbg_print_buffer_local( "Kernel : accepted %d\n", *mask.accepted); 610 609 return; 611 610 } … … 614 613 verifyf( duration < 0, "Timeout on waitfor statments not supported yet."); 615 614 616 LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : blocking waitfor\n");615 __cfaabi_dbg_print_buffer_local( "Kernel : blocking waitfor\n"); 617 616 618 617 // Create the node specific to this wait operation … … 636 635 monitor_restore; 637 636 638 LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : exiting\n");639 640 LIB_DEBUG_PRINT_BUFFER_LOCAL( "Kernel : accepted %d\n", *mask.accepted);637 __cfaabi_dbg_print_buffer_local( "Kernel : exiting\n"); 638 639 __cfaabi_dbg_print_buffer_local( "Kernel : accepted %d\n", *mask.accepted); 641 640 } 642 641 … … 645 644 646 645 static inline void set_owner( monitor_desc * this, thread_desc * owner ) { 647 // LIB_DEBUG_PRINT_SAFE("Kernal : Setting owner of %p to %p ( was %p)\n", this, owner, this->owner );646 // __cfaabi_dbg_print_safe("Kernal : Setting owner of %p to %p ( was %p)\n", this, owner, this->owner ); 648 647 649 648 //Pass the monitor appropriately … … 677 676 static inline thread_desc * next_thread( monitor_desc * this ) { 678 677 //Check the signaller stack 679 LIB_DEBUG_PRINT_SAFE("Kernel : mon %p AS-stack top %p\n", this, this->signal_stack.top);678 __cfaabi_dbg_print_safe("Kernel : mon %p AS-stack top %p\n", this, this->signal_stack.top); 680 679 __condition_criterion_t * urgent = pop( this->signal_stack ); 681 680 if( urgent ) { … … 729 728 for( __lock_size_t i = 0; i < count; i++) { 730 729 (criteria[i]){ monitors[i], waiter }; 731 LIB_DEBUG_PRINT_SAFE( "Kernel : target %p = %p\n", criteria[i].target, &criteria[i] );730 __cfaabi_dbg_print_safe( "Kernel : target %p = %p\n", criteria[i].target, &criteria[i] ); 732 731 push( criteria[i].target->signal_stack, &criteria[i] ); 733 732 } … … 738 737 static inline void lock_all( __spinlock_t * locks [], __lock_size_t count ) { 739 738 for( __lock_size_t i = 0; i < count; i++ ) { 740 DO_LOCK( *locks[i] DEBUG_CTX2 );739 DO_LOCK( *locks[i] __cfaabi_dbg_ctx2 ); 741 740 } 742 741 } … … 745 744 for( __lock_size_t i = 0; i < count; i++ ) { 746 745 __spinlock_t * l = &source[i]->lock; 747 DO_LOCK( *l DEBUG_CTX2 );746 DO_LOCK( *l __cfaabi_dbg_ctx2 ); 748 747 if(locks) locks[i] = l; 749 748 } … … 803 802 for( int i = 0; i < count; i++ ) { 804 803 805 // LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target );804 // __cfaabi_dbg_print_safe( "Checking %p for %p\n", &criteria[i], target ); 806 805 if( &criteria[i] == target ) { 807 806 criteria[i].ready = true; 808 // LIB_DEBUG_PRINT_SAFE( "True\n" );807 // __cfaabi_dbg_print_safe( "True\n" ); 809 808 } 810 809 … … 812 811 } 813 812 814 LIB_DEBUG_PRINT_SAFE( "Kernel : Runing %i (%p)\n", ready2run, ready2run ? node->waiting_thread : NULL );813 __cfaabi_dbg_print_safe( "Kernel : Runing %i (%p)\n", ready2run, ready2run ? node->waiting_thread : NULL ); 815 814 return ready2run ? node->waiting_thread : NULL; 816 815 } … … 819 818 thread_desc * thrd = this_thread; 820 819 if( !this.monitors ) { 821 // LIB_DEBUG_PRINT_SAFE("Branding\n");820 // __cfaabi_dbg_print_safe("Branding\n"); 822 821 assertf( thrd->monitors.data != NULL, "No current monitor to brand condition %p", thrd->monitors.data ); 823 822 this.monitor_count = thrd->monitors.size; -
src/libcfa/concurrency/preemption.c
r9c35431 rc13e8dc8 14 14 // 15 15 16 #include "libhdr.h"17 16 #include "preemption.h" 18 17 … … 148 147 //============================================================================================= 149 148 150 LIB_DEBUG_DO( static thread_local void * last_interrupt = 0; )149 __cfaabi_dbg_debug_do( static thread_local void * last_interrupt = 0; ) 151 150 152 151 extern "C" { … … 159 158 // Enable interrupts by decrementing the counter 160 159 // If counter reaches 0, execute any pending CtxSwitch 161 void enable_interrupts( DEBUG_CTX_PARAM) {160 void enable_interrupts( __cfaabi_dbg_ctx_param ) { 162 161 processor * proc = this_processor; // Cache the processor now since interrupts can start happening after the atomic add 163 162 thread_desc * thrd = this_thread; // Cache the thread now since interrupts can start happening after the atomic add … … 173 172 174 173 // For debugging purposes : keep track of the last person to enable the interrupts 175 LIB_DEBUG_DO( proc->last_enable = caller; )174 __cfaabi_dbg_debug_do( proc->last_enable = caller; ) 176 175 } 177 176 … … 233 232 // Called from kernel_startup 234 233 void kernel_start_preemption() { 235 LIB_DEBUG_PRINT_SAFE("Kernel : Starting preemption\n");234 __cfaabi_dbg_print_safe("Kernel : Starting preemption\n"); 236 235 237 236 // Start with preemption disabled until ready … … 255 254 // Called from kernel_shutdown 256 255 void kernel_stop_preemption() { 257 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopping\n");256 __cfaabi_dbg_print_safe("Kernel : Preemption stopping\n"); 258 257 259 258 // Block all signals since we are already shutting down … … 271 270 // Preemption is now fully stopped 272 271 273 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopped\n");272 __cfaabi_dbg_print_safe("Kernel : Preemption stopped\n"); 274 273 } 275 274 … … 297 296 // Receives SIGUSR1 signal and causes the current thread to yield 298 297 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) { 299 LIB_DEBUG_DO( last_interrupt = (void *)(cxt->uc_mcontext.gregs[CFA_REG_IP]); )298 __cfaabi_dbg_debug_do( last_interrupt = (void *)(cxt->uc_mcontext.gregs[CFA_REG_IP]); ) 300 299 301 300 // Check if it is safe to preempt here … … 346 345 assertf(sig == SIGALRM, "Kernel Internal Error, sigwait: Unexpected signal %d (%d : %d)\n", sig, info.si_code, info.si_value.sival_int); 347 346 348 // LIB_DEBUG_PRINT_SAFE("Kernel : Caught alarm from %d with %d\n", info.si_code, info.si_value.sival_int );347 // __cfaabi_dbg_print_safe("Kernel : Caught alarm from %d with %d\n", info.si_code, info.si_value.sival_int ); 349 348 // Switch on the code (a.k.a. the sender) to 350 349 switch( info.si_code ) … … 354 353 case SI_TIMER: 355 354 case SI_KERNEL: 356 // LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n");357 lock( event_kernel->lock DEBUG_CTX2 );355 // __cfaabi_dbg_print_safe("Kernel : Preemption thread tick\n"); 356 lock( event_kernel->lock __cfaabi_dbg_ctx2 ); 358 357 tick_preemption(); 359 358 unlock( event_kernel->lock ); … … 368 367 369 368 EXIT: 370 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread stopping\n");369 __cfaabi_dbg_print_safe("Kernel : Preemption thread stopping\n"); 371 370 return NULL; 372 371 } … … 380 379 381 380 if ( sigaction( sig, &act, NULL ) == -1 ) { 382 LIB_DEBUG_PRINT_BUFFER_DECL(381 __cfaabi_dbg_print_buffer_decl( 383 382 " __kernel_sigaction( sig:%d, handler:%p, flags:%d ), problem installing signal handler, error(%d) %s.\n", 384 383 sig, handler, flags, errno, strerror( errno ) … … 397 396 398 397 if ( sigaction( sig, &act, NULL ) == -1 ) { 399 LIB_DEBUG_PRINT_BUFFER_DECL(398 __cfaabi_dbg_print_buffer_decl( 400 399 " __kernel_sigdefault( sig:%d ), problem reseting signal handler, error(%d) %s.\n", 401 400 sig, errno, strerror( errno ) … … 409 408 //============================================================================================= 410 409 411 LIB_DEBUG_DO(410 __cfaabi_dbg_debug_do( 412 411 static void __kernel_backtrace( int start ) { 413 412 // skip first N stack frames … … 476 475 477 476 // void sigHandler_segv( __CFA_SIGPARMS__ ) { 478 // LIB_DEBUG_DO(477 // __cfaabi_dbg_debug_do( 479 478 // #ifdef __USE_STREAM__ 480 479 // serr | "*CFA runtime error* program cfa-cpp terminated with" … … 493 492 // void sigHandler_abort( __CFA_SIGPARMS__ ) { 494 493 // // skip first 6 stack frames 495 // LIB_DEBUG_DO( __kernel_backtrace( 6 ); )494 // __cfaabi_dbg_debug_do( __kernel_backtrace( 6 ); ) 496 495 497 496 // // reset default signal handler -
src/libcfa/concurrency/thread.c
r9c35431 rc13e8dc8 17 17 18 18 #include "kernel_private.h" 19 #include "libhdr.h"20 19 21 20 #define __CFA_INVOKE_PRIVATE__ … … 72 71 thrd_c->last = this_coroutine; 73 72 74 // LIB_DEBUG_PRINT_SAFE("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h);73 // __cfaabi_dbg_print_safe("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h); 75 74 76 75 disable_interrupts(); … … 82 81 83 82 ScheduleThread(thrd_h); 84 enable_interrupts( DEBUG_CTX);83 enable_interrupts( __cfaabi_dbg_ctx ); 85 84 } 86 85 -
src/libcfa/exception.c
r9c35431 rc13e8dc8 23 23 #include <stdio.h> 24 24 #include <unwind.h> 25 #include < libhdr/libdebug.h>25 #include <bits/debug.h> 26 26 27 27 // FIX ME: temporary hack to keep ARM build working … … 37 37 38 38 // Base exception vtable is abstract, you should not have base exceptions. 39 struct __cfa ehm__base_exception_t_vtable40 ___cfa ehm__base_exception_t_vtable_instance = {39 struct __cfaabi_ehm__base_exception_t_vtable 40 ___cfaabi_ehm__base_exception_t_vtable_instance = { 41 41 .parent = NULL, 42 42 .size = 0, … … 49 49 // Temperary global exception context. Does not work with concurency. 50 50 struct exception_context_t { 51 struct __cfa ehm__try_resume_node * top_resume;52 struct __cfa ehm__try_resume_node * current_resume;51 struct __cfaabi_ehm__try_resume_node * top_resume; 52 struct __cfaabi_ehm__try_resume_node * current_resume; 53 53 54 54 exception * current_exception; … … 78 78 // RESUMPTION ================================================================ 79 79 80 void __cfa ehm__throw_resume(exception * except) {81 82 LIB_DEBUG_PRINT_SAFE("Throwing resumption exception\n");83 84 struct __cfa ehm__try_resume_node * original_head = shared_stack.current_resume;85 struct __cfa ehm__try_resume_node * current =80 void __cfaabi_ehm__throw_resume(exception * except) { 81 82 __cfaabi_dbg_print_safe("Throwing resumption exception\n"); 83 84 struct __cfaabi_ehm__try_resume_node * original_head = shared_stack.current_resume; 85 struct __cfaabi_ehm__try_resume_node * current = 86 86 (original_head) ? original_head->next : shared_stack.top_resume; 87 87 … … 94 94 } 95 95 96 LIB_DEBUG_PRINT_SAFE("Unhandled exception\n");96 __cfaabi_dbg_print_safe("Unhandled exception\n"); 97 97 shared_stack.current_resume = original_head; 98 98 99 99 // Fall back to termination: 100 __cfa ehm__throw_terminate(except);100 __cfaabi_ehm__throw_terminate(except); 101 101 // TODO: Default handler for resumption. 102 102 } … … 105 105 // hook has to be added after the node is built but before it is made the top node. 106 106 107 void __cfa ehm__try_resume_setup(struct __cfaehm__try_resume_node * node,107 void __cfaabi_ehm__try_resume_setup(struct __cfaabi_ehm__try_resume_node * node, 108 108 _Bool (*handler)(exception * except)) { 109 109 node->next = shared_stack.top_resume; … … 112 112 } 113 113 114 void __cfa ehm__try_resume_cleanup(struct __cfaehm__try_resume_node * node) {114 void __cfaabi_ehm__try_resume_cleanup(struct __cfaabi_ehm__try_resume_node * node) { 115 115 shared_stack.top_resume = node->next; 116 116 } … … 122 122 // May have to move to cfa for constructors and destructors (references). 123 123 124 struct __cfa ehm__node {125 struct __cfa ehm__node * next;124 struct __cfaabi_ehm__node { 125 struct __cfaabi_ehm__node * next; 126 126 }; 127 127 128 128 #define NODE_TO_EXCEPT(node) ((exception *)(1 + (node))) 129 #define EXCEPT_TO_NODE(except) ((struct __cfa ehm__node *)(except) - 1)129 #define EXCEPT_TO_NODE(except) ((struct __cfaabi_ehm__node *)(except) - 1) 130 130 131 131 // Creates a copy of the indicated exception and sets current_exception to it. 132 static void __cfa ehm__allocate_exception( exception * except ) {132 static void __cfaabi_ehm__allocate_exception( exception * except ) { 133 133 struct exception_context_t * context = this_exception_context(); 134 134 135 135 // Allocate memory for the exception. 136 struct __cfa ehm__node * store = malloc(137 sizeof( struct __cfa ehm__node ) + except->virtual_table->size );136 struct __cfaabi_ehm__node * store = malloc( 137 sizeof( struct __cfaabi_ehm__node ) + except->virtual_table->size ); 138 138 139 139 if ( ! store ) { … … 151 151 152 152 // Delete the provided exception, unsetting current_exception if relivant. 153 static void __cfa ehm__delete_exception( exception * except ) {153 static void __cfaabi_ehm__delete_exception( exception * except ) { 154 154 struct exception_context_t * context = this_exception_context(); 155 155 156 LIB_DEBUG_PRINT_SAFE("Deleting Exception\n");156 __cfaabi_dbg_print_safe("Deleting Exception\n"); 157 157 158 158 // Remove the exception from the list. 159 struct __cfa ehm__node * to_free = EXCEPT_TO_NODE(except);160 struct __cfa ehm__node * node;159 struct __cfaabi_ehm__node * to_free = EXCEPT_TO_NODE(except); 160 struct __cfaabi_ehm__node * node; 161 161 162 162 if ( context->current_exception == except ) { … … 178 178 179 179 // If this isn't a rethrow (*except==0), delete the provided exception. 180 void __cfa ehm__cleanup_terminate( void * except ) {181 if ( *(void**)except ) __cfa ehm__delete_exception( *(exception**)except );180 void __cfaabi_ehm__cleanup_terminate( void * except ) { 181 if ( *(void**)except ) __cfaabi_ehm__delete_exception( *(exception**)except ); 182 182 } 183 183 … … 202 202 203 203 // The exception that is being thrown must already be stored. 204 __attribute__((noreturn)) void __cfa ehm__begin_unwind(void) {204 __attribute__((noreturn)) void __cfaabi_ehm__begin_unwind(void) { 205 205 if ( ! this_exception_context()->current_exception ) { 206 206 printf("UNWIND ERROR missing exception in begin unwind\n"); … … 233 233 } 234 234 235 void __cfa ehm__throw_terminate( exception * val ) {236 LIB_DEBUG_PRINT_SAFE("Throwing termination exception\n");237 238 __cfa ehm__allocate_exception( val );239 __cfa ehm__begin_unwind();240 } 241 242 void __cfa ehm__rethrow_terminate(void) {243 LIB_DEBUG_PRINT_SAFE("Rethrowing termination exception\n");244 245 __cfa ehm__begin_unwind();235 void __cfaabi_ehm__throw_terminate( exception * val ) { 236 __cfaabi_dbg_print_safe("Throwing termination exception\n"); 237 238 __cfaabi_ehm__allocate_exception( val ); 239 __cfaabi_ehm__begin_unwind(); 240 } 241 242 void __cfaabi_ehm__rethrow_terminate(void) { 243 __cfaabi_dbg_print_safe("Rethrowing termination exception\n"); 244 245 __cfaabi_ehm__begin_unwind(); 246 246 } 247 247 … … 254 254 { 255 255 256 // LIB_DEBUG_PRINT_SAFE("CFA: 0x%lx\n", _Unwind_GetCFA(context));257 LIB_DEBUG_PRINT_SAFE("Personality function (%d, %x, %llu, %p, %p):", version, actions, exceptionClass, unwind_exception, context);256 //__cfaabi_dbg_print_safe("CFA: 0x%lx\n", _Unwind_GetCFA(context)); 257 __cfaabi_dbg_print_safe("Personality function (%d, %x, %llu, %p, %p):", version, actions, exceptionClass, unwind_exception, context); 258 258 259 259 // If we've reached the end of the stack then there is nothing much we can do... … … 261 261 262 262 if (actions & _UA_SEARCH_PHASE) { 263 LIB_DEBUG_PRINT_SAFE(" lookup phase");263 __cfaabi_dbg_print_safe(" lookup phase"); 264 264 } 265 265 else if (actions & _UA_CLEANUP_PHASE) { 266 LIB_DEBUG_PRINT_SAFE(" cleanup phase");266 __cfaabi_dbg_print_safe(" cleanup phase"); 267 267 } 268 268 // Just in case, probably can't actually happen … … 307 307 void * ep = (void*)lsd_info.Start + callsite_start + callsite_len; 308 308 void * ip = (void*)instruction_ptr; 309 LIB_DEBUG_PRINT_SAFE("\nfound %p - %p (%p, %p, %p), looking for %p\n", bp, ep, ls, cs, cl, ip);309 __cfaabi_dbg_print_safe("\nfound %p - %p (%p, %p, %p), looking for %p\n", bp, ep, ls, cs, cl, ip); 310 310 #endif // __CFA_DEBUG_PRINT__ 311 311 continue; … … 346 346 347 347 // Get a function pointer from the relative offset and call it 348 // _Unwind_Reason_Code (*matcher)() = (_Unwind_Reason_Code (*)())lsd_info.LPStart + imatcher; 348 // _Unwind_Reason_Code (*matcher)() = (_Unwind_Reason_Code (*)())lsd_info.LPStart + imatcher; 349 349 350 350 _Unwind_Reason_Code (*matcher)(exception *) = … … 357 357 // Based on the return value, check if we matched the exception 358 358 if( ret == _URC_HANDLER_FOUND) { 359 LIB_DEBUG_PRINT_SAFE(" handler found\n");359 __cfaabi_dbg_print_safe(" handler found\n"); 360 360 } else { 361 LIB_DEBUG_PRINT_SAFE(" no handler\n");361 __cfaabi_dbg_print_safe(" no handler\n"); 362 362 } 363 363 return ret; … … 365 365 366 366 // This is only a cleanup handler, ignore it 367 LIB_DEBUG_PRINT_SAFE(" no action");367 __cfaabi_dbg_print_safe(" no action"); 368 368 } 369 369 else if (actions & _UA_CLEANUP_PHASE) { … … 385 385 _Unwind_SetIP( context, ((lsd_info.LPStart) + (callsite_landing_pad)) ); 386 386 387 LIB_DEBUG_PRINT_SAFE(" action\n");387 __cfaabi_dbg_print_safe(" action\n"); 388 388 389 389 // Return have some action to run … … 393 393 394 394 // Nothing to do, move along 395 LIB_DEBUG_PRINT_SAFE(" no landing pad");395 __cfaabi_dbg_print_safe(" no landing pad"); 396 396 } 397 397 // No handling found 398 LIB_DEBUG_PRINT_SAFE(" table end reached\n");398 __cfaabi_dbg_print_safe(" table end reached\n"); 399 399 400 400 UNWIND: 401 LIB_DEBUG_PRINT_SAFE(" unwind\n");401 __cfaabi_dbg_print_safe(" unwind\n"); 402 402 403 403 // Keep unwinding the stack … … 408 408 // libcfa but there is one problem left, see the exception table for details 409 409 __attribute__((noinline)) 410 void __cfa ehm__try_terminate(void (*try_block)(),410 void __cfaabi_ehm__try_terminate(void (*try_block)(), 411 411 void (*catch_block)(int index, exception * except), 412 412 __attribute__((unused)) int (*match_block)(exception * except)) { … … 466 466 // Body uses language specific data and therefore could be modified arbitrarily 467 467 ".LLSDACSBCFA2:\n" // BODY start 468 " .uleb128 .TRYSTART-__cfa ehm__try_terminate\n" // Handled area start (relative to start of function)468 " .uleb128 .TRYSTART-__cfaabi_ehm__try_terminate\n" // Handled area start (relative to start of function) 469 469 " .uleb128 .TRYEND-.TRYSTART\n" // Handled area length 470 " .uleb128 .CATCH-__cfa ehm__try_terminate\n" // Hanlder landing pad adress (relative to start of function)470 " .uleb128 .CATCH-__cfaabi_ehm__try_terminate\n" // Hanlder landing pad adress (relative to start of function) 471 471 " .uleb128 1\n" // Action code, gcc seems to use always 0 472 472 ".LLSDACSECFA2:\n" // BODY end 473 473 " .text\n" // TABLE footer 474 " .size __cfa ehm__try_terminate, .-__cfaehm__try_terminate\n"474 " .size __cfaabi_ehm__try_terminate, .-__cfaabi_ehm__try_terminate\n" 475 475 " .ident \"GCC: (Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901\"\n" 476 476 // " .section .note.GNU-stack,\"x\",@progbits\n" -
src/libcfa/exception.h
r9c35431 rc13e8dc8 21 21 #endif 22 22 23 struct __cfa ehm__base_exception_t;24 typedef struct __cfa ehm__base_exception_t exception;25 struct __cfa ehm__base_exception_t_vtable {26 const struct __cfa ehm__base_exception_t_vtable * parent;23 struct __cfaabi_ehm__base_exception_t; 24 typedef struct __cfaabi_ehm__base_exception_t exception; 25 struct __cfaabi_ehm__base_exception_t_vtable { 26 const struct __cfaabi_ehm__base_exception_t_vtable * parent; 27 27 size_t size; 28 void (*copy)(struct __cfa ehm__base_exception_t *this,29 struct __cfa ehm__base_exception_t * other);30 void (*free)(struct __cfa ehm__base_exception_t *this);31 const char * (*msg)(struct __cfa ehm__base_exception_t *this);28 void (*copy)(struct __cfaabi_ehm__base_exception_t *this, 29 struct __cfaabi_ehm__base_exception_t * other); 30 void (*free)(struct __cfaabi_ehm__base_exception_t *this); 31 const char * (*msg)(struct __cfaabi_ehm__base_exception_t *this); 32 32 }; 33 struct __cfa ehm__base_exception_t {34 struct __cfa ehm__base_exception_t_vtable const * virtual_table;33 struct __cfaabi_ehm__base_exception_t { 34 struct __cfaabi_ehm__base_exception_t_vtable const * virtual_table; 35 35 }; 36 extern struct __cfa ehm__base_exception_t_vtable37 ___cfa ehm__base_exception_t_vtable_instance;36 extern struct __cfaabi_ehm__base_exception_t_vtable 37 ___cfaabi_ehm__base_exception_t_vtable_instance; 38 38 39 39 40 40 // Used in throw statement translation. 41 void __cfa ehm__throw_terminate(exception * except) __attribute__((noreturn));42 void __cfa ehm__rethrow_terminate() __attribute__((noreturn));43 void __cfa ehm__throw_resume(exception * except);41 void __cfaabi_ehm__throw_terminate(exception * except) __attribute__((noreturn)); 42 void __cfaabi_ehm__rethrow_terminate() __attribute__((noreturn)); 43 void __cfaabi_ehm__throw_resume(exception * except); 44 44 45 45 // Function catches termination exceptions. 46 void __cfa ehm__try_terminate(46 void __cfaabi_ehm__try_terminate( 47 47 void (*try_block)(), 48 48 void (*catch_block)(int index, exception * except), … … 50 50 51 51 // Clean-up the exception in catch blocks. 52 void __cfa ehm__cleanup_terminate(void * except);52 void __cfaabi_ehm__cleanup_terminate(void * except); 53 53 54 54 // Data structure creates a list of resume handlers. 55 struct __cfa ehm__try_resume_node {56 struct __cfa ehm__try_resume_node * next;55 struct __cfaabi_ehm__try_resume_node { 56 struct __cfaabi_ehm__try_resume_node * next; 57 57 _Bool (*handler)(exception * except); 58 58 }; 59 59 60 60 // These act as constructor and destructor for the resume node. 61 void __cfa ehm__try_resume_setup(62 struct __cfa ehm__try_resume_node * node,61 void __cfaabi_ehm__try_resume_setup( 62 struct __cfaabi_ehm__try_resume_node * node, 63 63 _Bool (*handler)(exception * except)); 64 void __cfa ehm__try_resume_cleanup(65 struct __cfa ehm__try_resume_node * node);64 void __cfaabi_ehm__try_resume_cleanup( 65 struct __cfaabi_ehm__try_resume_node * node); 66 66 67 67 // Check for a standard way to call fake deconstructors. 68 struct __cfa ehm__cleanup_hook {};68 struct __cfaabi_ehm__cleanup_hook {}; 69 69 70 70 #ifdef __cforall -
src/libcfa/interpose.c
r9c35431 rc13e8dc8 24 24 } 25 25 26 #include " libhdr/libdebug.h"27 #include " libhdr/libtools.h"26 #include "bits/debug.h" 27 #include "bits/defs.h" 28 28 #include "startup.h" 29 29 … … 69 69 __typeof__( exit ) libc_exit __attribute__(( noreturn )); 70 70 __typeof__( abort ) libc_abort __attribute__(( noreturn )); 71 72 // #define INIT_REALRTN( x, ver ) libc_##x = (__typeof__(libc_##x))interpose_symbol( #x, ver )73 71 74 72 forall(dtype T) … … 127 125 va_end( args ); 128 126 129 __ lib_debug_write( abort_text, len );130 __ lib_debug_write( "\n", 1 );127 __cfaabi_dbg_bits_write( abort_text, len ); 128 __cfaabi_dbg_bits_write( "\n", 1 ); 131 129 } 132 130 133 131 len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld)\n", (long int)getpid() ); // use UNIX pid (versus getPid) 134 __ lib_debug_write( abort_text, len );132 __cfaabi_dbg_bits_write( abort_text, len ); 135 133 136 134 -
src/libcfa/stdhdr/assert.h
r9c35431 rc13e8dc8 30 30 #endif 31 31 32 #if !defined(NDEBUG) && (defined(__CFA_DEBUG__) || defined(__CFA_VERIFY__)) 33 #define verify(x) assert(x) 34 #define verifyf(x, ...) assertf(x, __VA_ARGS__) 35 #else 36 #define verify(x) 37 #define verifyf(x, ...) 38 #endif 39 32 40 #ifdef __cforall 33 41 } // extern "C" -
src/prelude/builtins.c
r9c35431 rc13e8dc8 16 16 // exception implementation 17 17 18 typedef unsigned long long __cfaabi_ exception_type_t;18 typedef unsigned long long __cfaabi_abi_exception_type_t; 19 19 20 20 #include "../libcfa/virtual.h" … … 80 80 } // ?\? 81 81 82 // FIXME (x \ (unsigned long int)y) relies on X ?\?(T, unsigned long) a function that is neither 83 // defined, nor passed as an assertion parameter. Without user-defined conversions, cannot specify 84 // X as a type that casts to double, yet it doesn't make sense to write functions with that type 82 // FIXME (x \ (unsigned long int)y) relies on X ?\?(T, unsigned long) a function that is neither 83 // defined, nor passed as an assertion parameter. Without user-defined conversions, cannot specify 84 // X as a type that casts to double, yet it doesn't make sense to write functions with that type 85 85 // signature where X is double. 86 86 -
src/tests/.expect/declarationErrors.txt
r9c35431 rc13e8dc8 7 7 declarationErrors.c:19:1 error: duplicate static in declaration of x4: static const volatile instance of const volatile struct __anonymous0 8 8 with members 9 i: int 9 10 with body 10 11 … … 12 13 declarationErrors.c:20:1 error: duplicate const, duplicate static, duplicate volatile in declaration of x5: static const volatile instance of const volatile struct __anonymous1 13 14 with members 15 i: int 14 16 with body 15 17 -
src/tests/Makefile.am
r9c35431 rc13e8dc8 20 20 21 21 if BUILD_CONCURRENCY 22 concurrent = yes 23 quick_test += coroutine thread monitor 24 concurrent_test = \ 25 coroutine \ 26 fmtLines \ 27 pingpong \ 28 prodcons \ 29 thread \ 30 matrixSum \ 31 monitor \ 32 multi-monitor \ 33 boundedBuffer \ 34 preempt \ 35 sched-int-block \ 36 sched-int-disjoint \ 37 sched-int-wait \ 38 sched-ext-barge \ 39 sched-ext-dtor \ 40 sched-ext-else \ 41 sched-ext-parse \ 42 sched-ext-recurse \ 43 sched-ext-statment \ 44 sched-ext-when 22 concurrent= 45 23 else 46 concurrent=no 47 concurrent_test= 24 concurrent='-Econcurrent' 48 25 endif 49 26 … … 62 39 endif 63 40 64 TEST_FLAGS = $(if $(test), 2> .err/${@}.log, )41 TEST_FLAGS = $(if $(test), 2> $(test), ) 65 42 AM_CFLAGS = ${TEST_FLAGS} ${BUILD_FLAGS} 66 43 CC = @CFA_BINDIR@/@CFA_NAME@ … … 70 47 71 48 fstream_test_SOURCES = fstream_test.c 72 fstream_test_CFLAGS = $(if $(test), 2>> .err/fstream_test.log, ) ${BUILD_FLAGS}49 fstream_test_CFLAGS = $(if $(test), 2>> $(test), ) ${BUILD_FLAGS} 73 50 74 51 vector_test_SOURCES = vector/vector_int.c vector/array.c vector/vector_test.c 75 vector_test_CFLAGS = $(if $(test), 2>> .err/vector_test.log, ) ${BUILD_FLAGS}52 vector_test_CFLAGS = $(if $(test), 2>> $(test), ) ${BUILD_FLAGS} 76 53 77 54 avl_test_SOURCES = avltree/avl_test.c avltree/avl0.c avltree/avl1.c avltree/avl2.c avltree/avl3.c avltree/avl4.c avltree/avl-private.c 78 avl_test_CFLAGS = $(if $(test), 2>> .err/avl_test.log, ) ${BUILD_FLAGS}55 avl_test_CFLAGS = $(if $(test), 2>> $(test), ) ${BUILD_FLAGS} 79 56 80 57 all-local : 81 @+python test.py --debug=${debug} --concurrent=${concurrent} ${quick_test}58 @+python test.py --debug=${debug} ${concurrent} ${quick_test} 82 59 83 60 all-tests : 84 @+python test.py --all --debug=${debug} --concurrent=${concurrent} # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program61 @+python test.py --all --debug=${debug} ${concurrent} # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program 85 62 86 63 clean-local : … … 88 65 89 66 list : 90 @+python test.py --list --concurrent=${concurrent}67 @+python test.py --list ${concurrent} 91 68 92 69 concurrency : 93 @+python test.py --debug=${debug} --concurrent=${concurrent} ${concurrent_test}70 @+python test.py --debug=${debug} ${concurrent} ${concurrent_test} 94 71 95 72 .dummy : .dummy.c @CFA_BINDIR@/@CFA_NAME@ -
src/tests/Makefile.in
r9c35431 rc13e8dc8 91 91 build_triplet = @build@ 92 92 host_triplet = @host@ 93 @BUILD_CONCURRENCY_TRUE@am__append_1 = coroutine thread monitor 94 @BUILD_DEBUG_FALSE@am__append_2 = -nodebug 95 @BUILD_DEBUG_TRUE@@BUILD_RELEASE_FALSE@am__append_3 = -debug 96 @BUILD_DEBUG_TRUE@@BUILD_RELEASE_TRUE@am__append_4 = ${DEBUG_FLAGS} 93 @BUILD_DEBUG_FALSE@am__append_1 = -nodebug 94 @BUILD_DEBUG_TRUE@@BUILD_RELEASE_FALSE@am__append_2 = -debug 95 @BUILD_DEBUG_TRUE@@BUILD_RELEASE_TRUE@am__append_3 = ${DEBUG_FLAGS} 97 96 EXTRA_PROGRAMS = fstream_test$(EXEEXT) vector_test$(EXEEXT) \ 98 97 avl_test$(EXEEXT) … … 314 313 top_srcdir = @top_srcdir@ 315 314 debug = yes 316 quick_test = vector_test avl_test operators numericConstants \ 317 expression enum array typeof cast dtor-early-exit init_once \ 318 attributes $(am__append_1) 319 @BUILD_CONCURRENCY_FALSE@concurrent = no 320 @BUILD_CONCURRENCY_TRUE@concurrent = yes 321 @BUILD_CONCURRENCY_FALSE@concurrent_test = 322 @BUILD_CONCURRENCY_TRUE@concurrent_test = \ 323 @BUILD_CONCURRENCY_TRUE@ coroutine \ 324 @BUILD_CONCURRENCY_TRUE@ fmtLines \ 325 @BUILD_CONCURRENCY_TRUE@ pingpong \ 326 @BUILD_CONCURRENCY_TRUE@ prodcons \ 327 @BUILD_CONCURRENCY_TRUE@ thread \ 328 @BUILD_CONCURRENCY_TRUE@ matrixSum \ 329 @BUILD_CONCURRENCY_TRUE@ monitor \ 330 @BUILD_CONCURRENCY_TRUE@ multi-monitor \ 331 @BUILD_CONCURRENCY_TRUE@ boundedBuffer \ 332 @BUILD_CONCURRENCY_TRUE@ preempt \ 333 @BUILD_CONCURRENCY_TRUE@ sched-int-block \ 334 @BUILD_CONCURRENCY_TRUE@ sched-int-disjoint \ 335 @BUILD_CONCURRENCY_TRUE@ sched-int-wait \ 336 @BUILD_CONCURRENCY_TRUE@ sched-ext-barge \ 337 @BUILD_CONCURRENCY_TRUE@ sched-ext-dtor \ 338 @BUILD_CONCURRENCY_TRUE@ sched-ext-else \ 339 @BUILD_CONCURRENCY_TRUE@ sched-ext-parse \ 340 @BUILD_CONCURRENCY_TRUE@ sched-ext-recurse \ 341 @BUILD_CONCURRENCY_TRUE@ sched-ext-statment \ 342 @BUILD_CONCURRENCY_TRUE@ sched-ext-when 343 315 quick_test = vector_test avl_test operators numericConstants expression enum array typeof cast dtor-early-exit init_once attributes 316 @BUILD_CONCURRENCY_FALSE@concurrent = '-Econcurrent' 317 @BUILD_CONCURRENCY_TRUE@concurrent = 344 318 345 319 # applies to both programs 346 320 DEBUG_FLAGS = 347 321 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ \ 348 $(am__append_ 2) $(am__append_3) $(am__append_4)349 TEST_FLAGS = $(if $(test), 2> .err/${@}.log, )322 $(am__append_1) $(am__append_2) $(am__append_3) 323 TEST_FLAGS = $(if $(test), 2> $(test), ) 350 324 AM_CFLAGS = ${TEST_FLAGS} ${BUILD_FLAGS} 351 325 fstream_test_SOURCES = fstream_test.c 352 fstream_test_CFLAGS = $(if $(test), 2>> .err/fstream_test.log, ) ${BUILD_FLAGS}326 fstream_test_CFLAGS = $(if $(test), 2>> $(test), ) ${BUILD_FLAGS} 353 327 vector_test_SOURCES = vector/vector_int.c vector/array.c vector/vector_test.c 354 vector_test_CFLAGS = $(if $(test), 2>> .err/vector_test.log, ) ${BUILD_FLAGS}328 vector_test_CFLAGS = $(if $(test), 2>> $(test), ) ${BUILD_FLAGS} 355 329 avl_test_SOURCES = avltree/avl_test.c avltree/avl0.c avltree/avl1.c avltree/avl2.c avltree/avl3.c avltree/avl4.c avltree/avl-private.c 356 avl_test_CFLAGS = $(if $(test), 2>> .err/avl_test.log, ) ${BUILD_FLAGS}330 avl_test_CFLAGS = $(if $(test), 2>> $(test), ) ${BUILD_FLAGS} 357 331 all: all-am 358 332 … … 833 807 834 808 all-local : 835 @+python test.py --debug=${debug} --concurrent=${concurrent} ${quick_test}809 @+python test.py --debug=${debug} ${concurrent} ${quick_test} 836 810 837 811 all-tests : 838 @+python test.py --all --debug=${debug} --concurrent=${concurrent} # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program812 @+python test.py --all --debug=${debug} ${concurrent} # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program 839 813 840 814 clean-local : … … 842 816 843 817 list : 844 @+python test.py --list --concurrent=${concurrent}818 @+python test.py --list ${concurrent} 845 819 846 820 concurrency : 847 @+python test.py --debug=${debug} --concurrent=${concurrent} ${concurrent_test}821 @+python test.py --debug=${debug} ${concurrent} ${concurrent_test} 848 822 849 823 .dummy : .dummy.c @CFA_BINDIR@/@CFA_NAME@ -
src/tests/concurrent/preempt.c
r9c35431 rc13e8dc8 24 24 if( (counter % 7) == this.value ) { 25 25 int next = __atomic_add_fetch_4(&counter, 1, __ATOMIC_SEQ_CST); 26 if( (next % 100) == 0 ) printf("%d\n", next);26 if( (next % 100) == 0 ) printf("%d\n", (int)next); 27 27 } 28 28 } -
src/tests/except-mac.h
r9c35431 rc13e8dc8 7 7 8 8 // The fully (perhaps overly) qualified name of the base exception type: 9 #define BASE_EXCEPT __cfa ehm__base_exception_t9 #define BASE_EXCEPT __cfaabi_ehm__base_exception_t 10 10 11 11 // Get the name of the vtable type and vtable instance for an exception type: … … 30 30 size_t size; \ 31 31 void (*copy)(except_name *this, except_name * other); \ 32 void (*free)(except_name *this); \32 void (*free)(except_name &this); \ 33 33 const char * (*msg)(except_name *this); \ 34 34 __VA_ARGS__ \ … … 42 42 // In each constructor the vtable must be initialized. 43 43 #define VTABLE_INIT(this_name,except_name) \ 44 this_name ->virtual_table = &INSTANCE(except_name)44 this_name.virtual_table = &INSTANCE(except_name) 45 45 46 46 // Declare the vtable instance. This should end an exception declaration. … … 73 73 this->virtual_table = other->virtual_table; \ 74 74 } \ 75 void ?{}(name *this) { \75 void ?{}(name & this) { \ 76 76 VTABLE_INIT(this,name); \ 77 77 } \ -
src/tests/pybin/tools.py
r9c35431 rc13e8dc8 1 from __future__ import print_function 2 1 3 import __main__ 2 4 import argparse 5 import multiprocessing 3 6 import os 4 7 import re 8 import signal 5 9 import stat 6 10 import sys 11 12 from pybin import settings 7 13 from subprocess import Popen, PIPE, STDOUT 8 14 15 ################################################################################ 16 # shell helpers 17 ################################################################################ 18 9 19 # helper functions to run terminal commands 10 def sh(cmd, dry_run = False, print2stdout = True): 11 if dry_run : # if this is a dry_run, only print the commands that would be ran 20 def sh(cmd, print2stdout = True, input = None): 21 # add input redirection if needed 22 if input and os.path.isfile(input): 23 cmd += " < %s" % input 24 25 # if this is a dry_run, only print the commands that would be ran 26 if settings.dry_run : 12 27 print("cmd: %s" % cmd) 13 28 return 0, None 14 else : # otherwise create a pipe and run the desired command 29 30 # otherwise create a pipe and run the desired command 31 else : 15 32 proc = Popen(cmd, stdout=None if print2stdout else PIPE, stderr=STDOUT, shell=True) 16 33 out, err = proc.communicate() … … 18 35 19 36 # Remove 1 or more files silently 20 def rm( files , dry_run = False):37 def rm( files ): 21 38 try: 22 39 for file in files: 23 sh("rm -f %s > /dev/null 2>&1" % file , dry_run)40 sh("rm -f %s > /dev/null 2>&1" % file ) 24 41 except TypeError: 25 sh("rm -f %s > /dev/null 2>&1" % files , dry_run)42 sh("rm -f %s > /dev/null 2>&1" % files ) 26 43 27 44 def chdir( dest = __main__.__file__ ): … … 30 47 os.chdir(dname) 31 48 32 # helper function to replace patterns in a file33 def file_replace(fname, pat, s_after):34 # first, see if the pattern is even in the file.35 with open(fname) as f:36 if not any(re.search(pat, line) for line in f):37 return # pattern does not occur in file so we are done.38 39 # pattern is in the file, so perform replace operation.40 with open(fname) as f:41 out_fname = fname + ".tmp"42 out = open(out_fname, "w")43 for line in f:44 out.write(re.sub(pat, s_after, line))45 out.close()46 os.rename(out_fname, fname)47 48 # helper function to check if a files contains only a spacific string49 def fileContainsOnly(file, text) :50 with open(file) as f:51 ff = f.read().strip()52 result = ff == text.strip()53 54 return result;55 56 # check whether or not a file is executable57 def fileIsExecutable(file) :58 try :59 fileinfo = os.stat(file)60 return bool(fileinfo.st_mode & stat.S_IXUSR)61 except Exception as inst:62 print(type(inst)) # the exception instance63 print(inst.args) # arguments stored in .args64 print(inst)65 return False66 67 # check if arguments is yes or no68 def yes_no(string):69 if string == "yes" :70 return True71 if string == "no" :72 return False73 raise argparse.ArgumentTypeError(msg)74 return False75 76 49 # diff two files 77 def diff( lhs, rhs , dry_run):50 def diff( lhs, rhs ): 78 51 # diff the output of the files 79 52 diff_cmd = ("diff --ignore-all-space " … … 94 67 95 68 # fetch return code and error from the diff command 96 return sh(diff_cmd % (lhs, rhs), dry_run, False) 69 return sh(diff_cmd % (lhs, rhs), False) 70 71 # call make 72 def make(target, flags = '', redirects = '', error_file = None, silent = False): 73 test_param = """test="%s" """ % (error_file) if error_file else '' 74 cmd = ' '.join([ 75 settings.make, 76 '-s' if silent else '', 77 test_param, 78 settings.debug.flags, 79 flags, 80 target, 81 redirects 82 ]) 83 return sh(cmd) 84 85 ################################################################################ 86 # file handling 87 ################################################################################ 88 89 # helper function to replace patterns in a file 90 def file_replace(fname, pat, s_after): 91 # first, see if the pattern is even in the file. 92 with open(fname) as f: 93 if not any(re.search(pat, line) for line in f): 94 return # pattern does not occur in file so we are done. 95 96 # pattern is in the file, so perform replace operation. 97 with open(fname) as f: 98 out_fname = fname + ".tmp" 99 out = open(out_fname, "w") 100 for line in f: 101 out.write(re.sub(pat, s_after, line)) 102 out.close() 103 os.rename(out_fname, fname) 104 105 # helper function to check if a files contains only a specific string 106 def fileContainsOnly(file, text) : 107 with open(file) as f: 108 ff = f.read().strip() 109 result = ff == text.strip() 110 111 return result; 112 113 # check whether or not a file is executable 114 def fileIsExecutable(file) : 115 try : 116 fileinfo = os.stat(file) 117 return bool(fileinfo.st_mode & stat.S_IXUSR) 118 except Exception as inst: 119 print(type(inst)) # the exception instance 120 print(inst.args) # arguments stored in .args 121 print(inst) 122 return False 123 124 # transform path to canonical form 125 def canonicalPath(path): 126 return os.path.join('.', os.path.normpath(path) ) 127 128 # compare path even if form is different 129 def pathCmp(lhs, rhs): 130 return canonicalPath( lhs ) == canonicalPath( rhs ) 131 132 # walk all files in a path 133 def pathWalk( op ): 134 def step(_, dirname, names): 135 for name in names: 136 path = os.path.join(dirname, name) 137 138 op( path ) 139 140 # Start the walk 141 os.path.walk('.', step, '') 142 143 ################################################################################ 144 # system 145 ################################################################################ 146 147 # parses the Makefile to find the machine type (32-bit / 64-bit) 148 def getMachineType(): 149 sh('echo "void ?{}(int&a,int b){}int main(){return 0;}" > .dummy.c') 150 ret, out = make('.dummy', silent = True) 151 152 if ret != 0: 153 print("Failed to identify architecture:") 154 print(out) 155 print("Stopping") 156 rm( (".dummy.c",".dummy") ) 157 sys.exit(1) 158 159 _, out = sh("file .dummy", print2stdout=False) 160 rm( (".dummy.c",".dummy") ) 161 162 if settings.dry_run : 163 return 'x64' 164 165 return re.search(r"[^,]+,([^,]+),", out).group(1).strip() 166 167 # count number of jobs to create 168 def jobCount( options, tests ): 169 # check if the user already passed in a number of jobs for multi-threading 170 make_flags = os.environ.get('MAKEFLAGS') 171 make_jobs_fds = re.search("--jobserver-(auth|fds)=\s*([0-9]+),([0-9]+)", make_flags) if make_flags else None 172 if make_jobs_fds : 173 tokens = os.read(int(make_jobs_fds.group(2)), 1024) 174 options.jobs = len(tokens) 175 os.write(int(make_jobs_fds.group(3)), tokens) 176 else : 177 options.jobs = multiprocessing.cpu_count() 178 179 # make sure we have a valid number of jobs that corresponds to user input 180 if options.jobs <= 0 : 181 print('ERROR: Invalid number of jobs', file=sys.stderr) 182 sys.exit(1) 183 184 return min( options.jobs, len(tests) ), True if make_flags else False 185 186 # setup a proper processor pool with correct signal handling 187 def setupPool(jobs): 188 original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN) 189 pool = multiprocessing.Pool(jobs) 190 signal.signal(signal.SIGINT, original_sigint_handler) 191 192 return pool 193 194 # handle signals in scope 195 class SignalHandling(): 196 def __enter__(self): 197 # enable signal handling 198 signal.signal(signal.SIGINT, signal.SIG_DFL) 199 200 def __exit__(self, type, value, traceback): 201 # disable signal handling 202 signal.signal(signal.SIGINT, signal.SIG_IGN) 203 204 ################################################################################ 205 # misc 206 ################################################################################ 207 208 # check if arguments is yes or no 209 def yes_no(string): 210 if string == "yes" : 211 return True 212 if string == "no" : 213 return False 214 raise argparse.ArgumentTypeError(msg) 215 return False 216 217 218 settings.set_machine_default( getMachineType ) -
src/tests/test.py
r9c35431 rc13e8dc8 2 2 from __future__ import print_function 3 3 4 from functools import partial5 from multiprocessing import Pool6 from os import listdir, environ7 from os.path import isfile, join, splitext8 4 from pybin.tools import * 5 from pybin.test_run import * 6 from pybin import settings 9 7 10 8 import argparse 11 import multiprocessing12 import os13 9 import re 14 import signal15 10 import sys 16 11 … … 19 14 ################################################################################ 20 15 21 # Test class that defines what a test is 22 class Test: 23 def __init__(self, name, path): 24 self.name, self.path = name, path 25 26 class TestResult: 27 SUCCESS = 0 28 FAILURE = 1 29 TIMEOUT = 124 30 31 # parses the Makefile to find the machine type (32-bit / 64-bit) 32 def getMachineType(): 33 sh('echo "void ?{}(int&a,int b){}int main(){return 0;}" > .dummy.c') 34 ret, out = sh("make .dummy -s", print2stdout=True) 35 36 if ret != 0: 37 print("Failed to identify architecture:") 38 print(out) 39 print("Stopping") 40 rm( (".dummy.c",".dummy") ) 41 sys.exit(1) 42 43 _, out = sh("file .dummy", print2stdout=False) 44 rm( (".dummy.c",".dummy") ) 45 46 return re.search("ELF\s([0-9]+)-bit", out).group(1) 47 48 def listTestsFolder(folder) : 49 path = ('./.expect/%s/' % folder) if folder else './.expect/' 50 subpath = "%s/" % folder if folder else "" 16 def findTests(): 17 expected = [] 18 19 def matchTest(path): 20 match = re.search("(\.[\w\/\-_]*)\/.expect\/([\w\-_]+)(\.[\w\-_]+)?\.txt", path) 21 if match : 22 test = Test() 23 test.name = match.group(2) 24 test.path = match.group(1) 25 test.arch = match.group(3)[1:] if match.group(3) else None 26 if settings.arch.match(test.arch): 27 expected.append(test) 28 29 pathWalk( matchTest ) 30 31 return expected 32 33 # reads the directory ./.expect and indentifies the tests 34 def listTests( includes, excludes ): 35 includes = [canonicalPath( i ) for i in includes] if includes else None 36 excludes = [canonicalPath( i ) for i in excludes] if excludes else None 51 37 52 38 # tests directly in the .expect folder will always be processed 53 return map(lambda fname: Test(fname, subpath + fname), 54 [splitext(f)[0] for f in listdir( path ) 55 if not f.startswith('.') and f.endswith('.txt') 56 ]) 57 58 # reads the directory ./.expect and indentifies the tests 59 def listTests( concurrent ): 60 machineType = getMachineType() 61 62 # tests directly in the .expect folder will always be processed 63 generic_list = listTestsFolder( "" ) 64 65 # tests in the machineType folder will be ran only for the corresponding compiler 66 typed_list = listTestsFolder( machineType ) 67 68 # tests in the concurrent folder will be ran only if concurrency is enabled 69 concurrent_list = listTestsFolder( "concurrent" ) if concurrent else [] 70 71 # append both lists to get 72 return generic_list + typed_list + concurrent_list; 39 test_list = findTests() 40 41 # if we have a limited number of includes, filter by them 42 if includes: 43 test_list = [x for x in test_list if 44 x.path.startswith( tuple(includes) ) 45 ] 46 47 # # if we have a folders to excludes, filter by them 48 if excludes: 49 test_list = [x for x in test_list if not 50 x.path.startswith( tuple(excludes) ) 51 ] 52 53 return test_list 73 54 74 55 # from the found tests, filter all the valid tests/desired tests … … 80 61 if options.regenerate_expected : 81 62 for testname in options.tests : 82 if testname.endswith( (".c", ".cc", ".cpp") ): 63 if Test.valid_name(testname): 64 found = [test for test in allTests if test.target() == testname] 65 tests.append( found[0] if len(found) == 1 else Test.from_target(testname) ) 66 else : 83 67 print('ERROR: "%s", tests are not allowed to end with a C/C++/CFA extension, ignoring it' % testname, file=sys.stderr) 84 else :85 found = [test for test in allTests if test.name == testname]86 tests.append( found[0] if len(found) == 1 else Test(testname, testname) )87 68 88 69 else : 89 70 # otherwise we only need to validate that all tests are present in the complete list 90 71 for testname in options.tests: 91 test = [t for t in allTests if t.name == testname]92 93 if len(test) != 0:72 test = [t for t in allTests if pathCmp( t.target(), testname )] 73 74 if test : 94 75 tests.append( test[0] ) 95 76 else : … … 97 78 98 79 # make sure we have at least some test to run 99 if len(tests) == 0:80 if not tests : 100 81 print('ERROR: No valid test to run', file=sys.stderr) 101 82 sys.exit(1) … … 108 89 parser = argparse.ArgumentParser(description='Script which runs cforall tests') 109 90 parser.add_argument('--debug', help='Run all tests in debug or release', type=yes_no, default='no') 110 parser.add_argument('-- concurrent', help='Run concurrent tests', type=yes_no, default='yes')91 parser.add_argument('--arch', help='Test for specific architecture', type=str, default='') 111 92 parser.add_argument('--dry-run', help='Don\'t run the tests, only output the commands', action='store_true') 112 93 parser.add_argument('--list', help='List all test available', action='store_true') … … 115 96 parser.add_argument('-j', '--jobs', help='Number of tests to run simultaneously', type=int, default='8') 116 97 parser.add_argument('--list-comp', help='List all valide arguments', action='store_true') 98 parser.add_argument('-I','--include', help='Directory of test to include, can be used multiple time, All if omitted', action='append') 99 parser.add_argument('-E','--exclude', help='Directory of test to exclude, can be used multiple time, None if omitted', action='append') 117 100 parser.add_argument('tests', metavar='test', type=str, nargs='*', help='a list of tests to run') 118 101 … … 123 106 all_tests = options.all 124 107 some_tests = len(options.tests) > 0 108 some_dirs = len(options.include) > 0 if options.include else 0 125 109 126 110 # check that exactly one of the booleans is set to true 127 if not sum( (listing, all_tests, some_tests ) ) == 1:128 print('ERROR: must have option \'--all\', \'--list\' or non-empty test list', file=sys.stderr)111 if not sum( (listing, all_tests, some_tests, some_dirs) ) > 0 : 112 print('ERROR: must have option \'--all\', \'--list\', \'--include\', \'-I\' or non-empty test list', file=sys.stderr) 129 113 parser.print_help() 130 114 sys.exit(1) … … 132 116 return options 133 117 134 def jobCount( options ):135 # check if the user already passed in a number of jobs for multi-threading136 make_flags = environ.get('MAKEFLAGS')137 make_jobs_fds = re.search("--jobserver-(auth|fds)=\s*([0-9]+),([0-9]+)", make_flags) if make_flags else None138 if make_jobs_fds :139 tokens = os.read(int(make_jobs_fds.group(2)), 1024)140 options.jobs = len(tokens)141 os.write(int(make_jobs_fds.group(3)), tokens)142 else :143 options.jobs = multiprocessing.cpu_count()144 145 # make sure we have a valid number of jobs that corresponds to user input146 if options.jobs <= 0 :147 print('ERROR: Invalid number of jobs', file=sys.stderr)148 sys.exit(1)149 150 return min( options.jobs, len(tests) ), True if make_flags else False151 152 118 ################################################################################ 153 119 # running test functions 154 120 ################################################################################ 155 121 # logic to run a single test and return the result (No handling of printing or other test framework logic) 156 def run_single_test(test , generate, dry_run, debug):122 def run_single_test(test): 157 123 158 124 # find the output file based on the test name and options flag 159 out_file = (".out/%s.log" % test.name) if not generate else (".expect/%s.txt" % test.path) 160 err_file = ".err/%s.log" % test.name 125 out_file = test.target_output() 126 err_file = test.error_log() 127 cmp_file = test.expect() 128 in_file = test.input() 129 130 # prepare the proper directories 131 test.prepare() 161 132 162 133 # remove any outputs from the previous tests to prevent side effects 163 rm( (out_file, err_file, test.name), dry_run ) 164 165 options = "-debug" if debug else "-nodebug" 134 rm( (out_file, err_file, test.target()) ) 166 135 167 136 # build, skipping to next test on error 168 make_ret, _ = sh("""%s test=yes DEBUG_FLAGS="%s" %s 2> %s 1> /dev/null""" % (make_cmd, options, test.name, out_file), dry_run)169 170 retcode = 0171 error = None137 make_ret, _ = make( test.target(), 138 redirects = "2> %s 1> /dev/null" % out_file, 139 error_file = err_file 140 ) 172 141 173 142 # if the make command succeds continue otherwise skip to diff 174 if make_ret == 0 : 175 # fetch optional input 176 stdinput = "< .in/%s.txt" % test.name if isfile(".in/%s.txt" % test.name) else "" 177 178 if fileIsExecutable(test.name) : 143 if make_ret == 0 or settings.dry_run: 144 if settings.dry_run or fileIsExecutable(test.target()) : 179 145 # run test 180 retcode, _ = sh("timeout 60 ./%s %s > %s 2>&1" % (test.name, stdinput, out_file), dry_run)146 retcode, _ = sh("timeout 60 %s > %s 2>&1" % (test.target(), out_file), input = in_file) 181 147 else : 182 148 # simply cat the result into the output 183 sh("cat %s > %s" % (test.name, out_file), dry_run) 184 185 else : 186 # command failed save the log to less temporary file 187 sh("mv %s %s" % (err_file, out_file), dry_run) 149 retcode, _ = sh("cat %s > %s" % (test.target(), out_file)) 150 else: 151 retcode, _ = sh("mv %s %s" % (err_file, out_file)) 152 188 153 189 154 if retcode == 0: 190 if generate:155 if settings.generating : 191 156 # if we are ounly generating the output we still need to check that the test actually exists 192 if not dry_run and fileContainsOnly(out_file, "make: *** No rule to make target `%s'. Stop." % test.name) :157 if not settings.dry_run and fileContainsOnly(out_file, "make: *** No rule to make target `%s'. Stop." % test.target()) : 193 158 retcode = 1; 194 error = "\t\tNo make target for test %s!" % test. name159 error = "\t\tNo make target for test %s!" % test.target() 195 160 sh("rm %s" % out_file, False) 161 else: 162 error = None 196 163 else : 197 164 # fetch return code and error from the diff command 198 retcode, error = diff( ".expect/%s.txt" % test.path, ".out/%s.log" % test.name, dry_run)165 retcode, error = diff(cmp_file, out_file) 199 166 200 167 else: … … 204 171 205 172 # clean the executable 206 sh("rm -f %s > /dev/null 2>&1" % test. name, dry_run)173 sh("rm -f %s > /dev/null 2>&1" % test.target()) 207 174 208 175 return retcode, error 209 176 210 177 # run a single test and handle the errors, outputs, printing, exception handling, etc. 211 def run_test_worker(t, generate, dry_run, debug) : 212 213 signal.signal(signal.SIGINT, signal.SIG_DFL) 214 # print formated name 215 name_txt = "%20s " % t.name 216 217 retcode, error = run_single_test(t, generate, dry_run, debug) 218 219 # update output based on current action 220 if generate : 221 if retcode == TestResult.SUCCESS: result_txt = "Done" 222 elif retcode == TestResult.TIMEOUT: result_txt = "TIMEOUT" 223 else : result_txt = "ERROR code %d" % retcode 224 else : 225 if retcode == TestResult.SUCCESS: result_txt = "PASSED" 226 elif retcode == TestResult.TIMEOUT: result_txt = "TIMEOUT" 227 else : result_txt = "FAILED with code %d" % retcode 228 229 #print result with error if needed 230 text = name_txt + result_txt 231 out = sys.stdout 232 if error : 233 text = text + "\n" + error 234 out = sys.stderr 235 236 print(text, file = out) 237 sys.stdout.flush() 238 sys.stderr.flush() 239 signal.signal(signal.SIGINT, signal.SIG_IGN) 178 def run_test_worker(t) : 179 180 with SignalHandling(): 181 # print formated name 182 name_txt = "%20s " % t.name 183 184 retcode, error = run_single_test(t) 185 186 # update output based on current action 187 result_txt = TestResult.toString( retcode ) 188 189 #print result with error if needed 190 text = name_txt + result_txt 191 out = sys.stdout 192 if error : 193 text = text + "\n" + error 194 out = sys.stderr 195 196 print(text, file = out) 197 sys.stdout.flush() 198 sys.stderr.flush() 240 199 241 200 return retcode != TestResult.SUCCESS 242 201 243 202 # run the given list of tests with the given parameters 244 def run_tests(tests, generate, dry_run, jobs, debug) :203 def run_tests(tests, jobs) : 245 204 # clean the sandbox from previous commands 246 sh("%s clean > /dev/null 2>&1" % make_cmd, dry_run) 247 248 # make sure the required folder are present 249 sh('mkdir -p .out .expect .err', dry_run) 250 251 if generate : 252 print( "Regenerate tests for: " ) 205 make('clean', redirects = '> /dev/null 2>&1') 253 206 254 207 # create the executor for our jobs and handle the signal properly 255 original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN) 256 pool = Pool(jobs) 257 signal.signal(signal.SIGINT, original_sigint_handler) 208 pool = setupPool(jobs) 258 209 259 210 # for each test to run 260 211 try : 261 results = pool.map_async(partial(run_test_worker, generate=generate, dry_run=dry_run, debug=debug), tests, chunksize = 1 ).get(7200) 212 results = pool.map_async( 213 run_test_worker, 214 tests, 215 chunksize = 1 216 ).get(7200) 262 217 except KeyboardInterrupt: 263 218 pool.terminate() … … 266 221 267 222 # clean the workspace 268 sh("%s clean > /dev/null 2>&1" % make_cmd, dry_run)223 make('clean', redirects = '> /dev/null 2>&1') 269 224 270 225 for failed in results: … … 285 240 options = getOptions() 286 241 242 # init global settings 243 settings.init( options ) 244 287 245 # fetch the liest of all valid tests 288 allTests = listTests( options. concurrent)246 allTests = listTests( options.include, options.exclude ) 289 247 290 248 # if user wants all tests than no other treatement of the test list is required 291 if options.all or options.list or options.list_comp :249 if options.all or options.list or options.list_comp or options.include : 292 250 tests = allTests 293 251 252 #otherwise we need to validate that the test list that was entered is valid 294 253 else : 295 #otherwise we need to validate that the test list that was entered is valid296 254 tests = validTests( options ) 297 255 298 256 # sort the test alphabetically for convenience 299 tests.sort(key=lambda t: t.name)257 tests.sort(key=lambda t: (t.arch if t.arch else '') + t.target()) 300 258 301 259 # users may want to simply list the tests 302 260 if options.list_comp : 303 print("-h --help --debug -- concurrent --dry-run --list--all --regenerate-expected -j --jobs ", end='')304 print(" ".join(map(lambda t: "%s" % (t. name), tests)))261 print("-h --help --debug --dry-run --list --arch --all --regenerate-expected -j --jobs ", end='') 262 print(" ".join(map(lambda t: "%s" % (t.target()), tests))) 305 263 306 264 elif options.list : 307 print("\n".join(map(lambda t: "%s (%s)" % (t.name, t.path), tests))) 265 print("Listing for %s:%s"% (settings.arch.string, settings.debug.string)) 266 print("\n".join(map(lambda t: "%s" % (t.toString()), tests))) 308 267 309 268 else : 310 options.jobs, forceJobs = jobCount( options ) 311 312 print('Running (%s) on %i cores' % ("debug" if options.debug else "no debug", options.jobs)) 313 make_cmd = "make" if forceJobs else ("make -j%i" % options.jobs) 269 options.jobs, forceJobs = jobCount( options, tests ) 270 settings.updateMakeCmd(forceJobs, options.jobs) 271 272 print('%s (%s:%s) on %i cores' % ( 273 'Regenerate tests' if settings.generating else 'Running', 274 settings.arch.string, 275 settings.debug.string, 276 options.jobs 277 )) 314 278 315 279 # otherwise run all tests and make sure to return the correct error code 316 sys.exit( run_tests(tests, options. regenerate_expected, options.dry_run, options.jobs, options.debug) )280 sys.exit( run_tests(tests, options.jobs) )
Note:
See TracChangeset
for help on using the changeset viewer.