Changes in src/Concurrency/Keywords.cc [43cedfb1:09f357ec]
- File:
-
- 1 edited
-
src/Concurrency/Keywords.cc (modified) (36 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Concurrency/Keywords.cc
r43cedfb1 r09f357ec 16 16 #include "Concurrency/Keywords.h" 17 17 18 #include <cassert> // for assert 19 #include <string> // for string, operator== 20 21 #include <iostream> 22 23 #include "Common/Examine.h" // for isMainFor 24 #include "Common/PassVisitor.h" // for PassVisitor 25 #include "Common/SemanticError.h" // for SemanticError 26 #include "Common/utility.h" // for deleteAll, map_range 27 #include "CodeGen/OperatorTable.h" // for isConstructor 28 #include "ControlStruct/LabelGenerator.h" // for LebelGenerator 29 #include "InitTweak/InitTweak.h" // for getPointerBase 30 #include "SynTree/LinkageSpec.h" // for Cforall 31 #include "SynTree/Constant.h" // for Constant 32 #include "SynTree/Declaration.h" // for StructDecl, FunctionDecl, ObjectDecl 33 #include "SynTree/Expression.h" // for VariableExpr, ConstantExpr, Untype... 34 #include "SynTree/Initializer.h" // for SingleInit, ListInit, Initializer ... 35 #include "SynTree/Label.h" // for Label 36 #include "SynTree/Statement.h" // for CompoundStmt, DeclStmt, ExprStmt 37 #include "SynTree/Type.h" // for StructInstType, Type, PointerType 38 #include "SynTree/Visitor.h" // for Visitor, acceptAll 39 #include "Virtual/Tables.h" 18 #include <cassert> // for assert 19 #include <string> // for string, operator== 20 21 #include "Common/PassVisitor.h" // for PassVisitor 22 #include "Common/SemanticError.h" // for SemanticError 23 #include "Common/utility.h" // for deleteAll, map_range 24 #include "CodeGen/OperatorTable.h" // for isConstructor 25 #include "InitTweak/InitTweak.h" // for getPointerBase 26 #include "SynTree/LinkageSpec.h" // for Cforall 27 #include "SynTree/Constant.h" // for Constant 28 #include "SynTree/Declaration.h" // for StructDecl, FunctionDecl, ObjectDecl 29 #include "SynTree/Expression.h" // for VariableExpr, ConstantExpr, Untype... 30 #include "SynTree/Initializer.h" // for SingleInit, ListInit, Initializer ... 31 #include "SynTree/Label.h" // for Label 32 #include "SynTree/Statement.h" // for CompoundStmt, DeclStmt, ExprStmt 33 #include "SynTree/Type.h" // for StructInstType, Type, PointerType 34 #include "SynTree/Visitor.h" // for Visitor, acceptAll 40 35 41 36 class Attribute; 42 37 43 38 namespace Concurrency { 44 inline static std::string getVTableName( std::string const & exception_name ) {45 return exception_name.empty() ? std::string() : Virtual::vtableTypeName(exception_name);46 }47 48 // Only detects threads constructed with the keyword thread.49 inline static bool isThread( DeclarationWithType * decl ) {50 Type * baseType = decl->get_type()->stripDeclarator();51 StructInstType * instType = dynamic_cast<StructInstType *>( baseType );52 if ( nullptr == instType ) { return false; }53 return instType->baseStruct->is_thread();54 }55 56 39 //============================================================================================= 57 40 // Pass declarations … … 70 53 public: 71 54 72 ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name, 73 std::string&& getter_name, std::string&& context_error, std::string&& exception_name, 74 bool needs_main, AggregateDecl::Aggregate cast_target ) : 75 type_name( type_name ), field_name( field_name ), getter_name( getter_name ), 76 context_error( context_error ), exception_name( exception_name ), 77 vtable_name( getVTableName( exception_name ) ), 78 needs_main( needs_main ), cast_target( cast_target ) {} 55 ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name, std::string&& getter_name, std::string&& context_error, bool needs_main, AggregateDecl::Aggregate cast_target ) : 56 type_name( type_name ), field_name( field_name ), getter_name( getter_name ), context_error( context_error ), needs_main( needs_main ), cast_target( cast_target ) {} 79 57 80 58 virtual ~ConcurrentSueKeyword() {} … … 84 62 85 63 void handle( StructDecl * ); 86 void addVtableForward( StructDecl * );87 64 FunctionDecl * forwardDeclare( StructDecl * ); 88 65 ObjectDecl * addField( StructDecl * ); … … 98 75 const std::string getter_name; 99 76 const std::string context_error; 100 const std::string exception_name;101 const std::string vtable_name;102 77 bool needs_main; 103 78 AggregateDecl::Aggregate cast_target; … … 105 80 StructDecl * type_decl = nullptr; 106 81 FunctionDecl * dtor_decl = nullptr; 107 StructDecl * except_decl = nullptr;108 StructDecl * vtable_decl = nullptr;109 82 }; 110 83 … … 115 88 // int data; int data; 116 89 // a_struct_t more_data; a_struct_t more_data; 117 // => $thread__thrd_d;90 // => thread_desc __thrd_d; 118 91 // }; }; 119 // static inline $thread* get_thread( MyThread * this ) { return &this->__thrd_d; }92 // static inline thread_desc * get_thread( MyThread * this ) { return &this->__thrd_d; } 120 93 // 121 94 class ThreadKeyword final : public ConcurrentSueKeyword { … … 123 96 124 97 ThreadKeyword() : ConcurrentSueKeyword( 125 " $thread",98 "thread_desc", 126 99 "__thrd", 127 100 "get_thread", 128 101 "thread keyword requires threads to be in scope, add #include <thread.hfa>\n", 129 "ThreadCancelled",130 102 true, 131 103 AggregateDecl::Thread … … 148 120 // int data; int data; 149 121 // a_struct_t more_data; a_struct_t more_data; 150 // => $coroutine__cor_d;122 // => coroutine_desc __cor_d; 151 123 // }; }; 152 // static inline $coroutine* get_coroutine( MyCoroutine * this ) { return &this->__cor_d; }124 // static inline coroutine_desc * get_coroutine( MyCoroutine * this ) { return &this->__cor_d; } 153 125 // 154 126 class CoroutineKeyword final : public ConcurrentSueKeyword { … … 156 128 157 129 CoroutineKeyword() : ConcurrentSueKeyword( 158 " $coroutine",130 "coroutine_desc", 159 131 "__cor", 160 132 "get_coroutine", 161 133 "coroutine keyword requires coroutines to be in scope, add #include <coroutine.hfa>\n", 162 "CoroutineCancelled",163 134 true, 164 135 AggregateDecl::Coroutine … … 175 146 } 176 147 }; 177 178 179 148 180 149 //----------------------------------------------------------------------------- … … 183 152 // int data; int data; 184 153 // a_struct_t more_data; a_struct_t more_data; 185 // => $monitor__mon_d;154 // => monitor_desc __mon_d; 186 155 // }; }; 187 // static inline $monitor* get_coroutine( MyMonitor * this ) { return &this->__cor_d; }156 // static inline monitor_desc * get_coroutine( MyMonitor * this ) { return &this->__cor_d; } 188 157 // 189 158 class MonitorKeyword final : public ConcurrentSueKeyword { … … 191 160 192 161 MonitorKeyword() : ConcurrentSueKeyword( 193 " $monitor",162 "monitor_desc", 194 163 "__mon", 195 164 "get_monitor", 196 165 "monitor keyword requires monitors to be in scope, add #include <monitor.hfa>\n", 197 "",198 166 false, 199 167 AggregateDecl::Monitor … … 212 180 213 181 //----------------------------------------------------------------------------- 214 //Handles generator type declarations :215 // generator MyGenerator { struct MyGenerator {216 // int data; int data;217 // a_struct_t more_data; a_struct_t more_data;218 // => int __gen_next;219 // }; };220 //221 class GeneratorKeyword final : public ConcurrentSueKeyword {222 public:223 224 GeneratorKeyword() : ConcurrentSueKeyword(225 "$generator",226 "__generator_state",227 "get_generator",228 "Unable to find builtin type $generator\n",229 "",230 true,231 AggregateDecl::Generator232 )233 {}234 235 virtual ~GeneratorKeyword() {}236 237 virtual bool is_target( StructDecl * decl ) override final { return decl->is_generator(); }238 239 static void implement( std::list< Declaration * > & translationUnit ) {240 PassVisitor< GeneratorKeyword > impl;241 mutateAll( translationUnit, impl );242 }243 };244 245 246 //-----------------------------------------------------------------------------247 class SuspendKeyword final : public WithStmtsToAdd, public WithGuards {248 public:249 SuspendKeyword() = default;250 virtual ~SuspendKeyword() = default;251 252 void premutate( FunctionDecl * );253 DeclarationWithType * postmutate( FunctionDecl * );254 255 Statement * postmutate( SuspendStmt * );256 257 static void implement( std::list< Declaration * > & translationUnit ) {258 PassVisitor< SuspendKeyword > impl;259 mutateAll( translationUnit, impl );260 }261 262 private:263 bool is_real_suspend( FunctionDecl * );264 265 Statement * make_generator_suspend( SuspendStmt * );266 Statement * make_coroutine_suspend( SuspendStmt * );267 268 struct LabelPair {269 Label obj;270 int idx;271 };272 273 LabelPair make_label() {274 labels.push_back( gen.newLabel("generator") );275 return { labels.back(), int(labels.size()) };276 }277 278 DeclarationWithType * in_generator = nullptr;279 FunctionDecl * decl_suspend = nullptr;280 std::vector<Label> labels;281 ControlStruct::LabelGenerator & gen = *ControlStruct::LabelGenerator::getGenerator();282 };283 284 //-----------------------------------------------------------------------------285 182 //Handles mutex routines definitions : 286 183 // void foo( A * mutex a, B * mutex b, int i ) { void foo( A * a, B * b, int i ) { 287 // $monitor* __monitors[] = { get_monitor(a), get_monitor(b) };184 // monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) }; 288 185 // monitor_guard_t __guard = { __monitors, 2 }; 289 186 // /*Some code*/ => /*Some code*/ … … 298 195 std::list<DeclarationWithType*> findMutexArgs( FunctionDecl*, bool & first ); 299 196 void validate( DeclarationWithType * ); 300 void addDtorStatements( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &); 301 void addStatements( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &); 302 void addThreadDtorStatements( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ); 197 void addDtorStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &); 198 void addStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &); 303 199 304 200 static void implement( std::list< Declaration * > & translationUnit ) { … … 311 207 StructDecl* guard_decl = nullptr; 312 208 StructDecl* dtor_guard_decl = nullptr; 313 StructDecl* thread_guard_decl = nullptr;314 209 315 210 static std::unique_ptr< Type > generic_func; … … 326 221 //Handles mutex routines definitions : 327 222 // void foo( A * mutex a, B * mutex b, int i ) { void foo( A * a, B * b, int i ) { 328 // $monitor* __monitors[] = { get_monitor(a), get_monitor(b) };223 // monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) }; 329 224 // monitor_guard_t __guard = { __monitors, 2 }; 330 225 // /*Some code*/ => /*Some code*/ … … 356 251 CoroutineKeyword ::implement( translationUnit ); 357 252 MonitorKeyword ::implement( translationUnit ); 358 GeneratorKeyword ::implement( translationUnit );359 SuspendKeyword ::implement( translationUnit );360 253 } 361 254 … … 390 283 handle( decl ); 391 284 } 392 else if ( !except_decl && exception_name == decl->name && decl->body ) {393 except_decl = decl;394 }395 else if ( !vtable_decl && vtable_name == decl->name && decl->body ) {396 vtable_decl = decl;397 }398 // Might be able to get ride of is target.399 assert( is_target(decl) == (cast_target == decl->kind) );400 285 return decl; 401 286 } 402 287 403 288 DeclarationWithType * ConcurrentSueKeyword::postmutate( FunctionDecl * decl ) { 404 if ( type_decl && isDestructorFor( decl, type_decl ) ) 405 dtor_decl = decl; 406 else if ( vtable_name.empty() ) 407 ; 408 else if( !decl->has_body() ) 409 ; 410 else if ( auto param = isMainFor( decl, cast_target ) ) { 411 // This should never trigger. 412 assert( vtable_decl ); 413 // Should be safe because of isMainFor. 414 StructInstType * struct_type = static_cast<StructInstType *>( 415 static_cast<ReferenceType *>( param->get_type() )->base ); 416 assert( struct_type ); 417 418 std::list< Expression * > poly_args = { new TypeExpr( struct_type->clone() ) }; 419 ObjectDecl * vtable_object = Virtual::makeVtableInstance( 420 vtable_decl->makeInst( poly_args ), struct_type, nullptr ); 421 declsToAddAfter.push_back( vtable_object ); 422 declsToAddAfter.push_back( Virtual::makeGetExceptionFunction( 423 vtable_object, except_decl->makeInst( std::move( poly_args ) ) 424 ) ); 425 } 426 289 if( !type_decl ) return decl; 290 if( !CodeGen::isDestructor( decl->name ) ) return decl; 291 292 auto params = decl->type->parameters; 293 if( params.size() != 1 ) return decl; 294 295 auto type = dynamic_cast<ReferenceType*>( params.front()->get_type() ); 296 if( !type ) return decl; 297 298 auto stype = dynamic_cast<StructInstType*>( type->base ); 299 if( !stype ) return decl; 300 if( stype->baseStruct != type_decl ) return decl; 301 302 if( !dtor_decl ) dtor_decl = decl; 427 303 return decl; 428 304 } … … 430 306 Expression * ConcurrentSueKeyword::postmutate( KeywordCastExpr * cast ) { 431 307 if ( cast_target == cast->target ) { 432 // convert (thread &)t to ( $thread&)*get_thread(t), etc.308 // convert (thread &)t to (thread_desc &)*get_thread(t), etc. 433 309 if( !type_decl ) SemanticError( cast, context_error ); 434 310 if( !dtor_decl ) SemanticError( cast, context_error ); … … 448 324 if( !dtor_decl ) SemanticError( decl, context_error ); 449 325 450 addVtableForward( decl );451 326 FunctionDecl * func = forwardDeclare( decl ); 452 327 ObjectDecl * field = addField( decl ); 453 328 addRoutines( field, func ); 454 }455 456 void ConcurrentSueKeyword::addVtableForward( StructDecl * decl ) {457 if ( vtable_decl ) {458 std::list< Expression * > poly_args = {459 new TypeExpr( new StructInstType( noQualifiers, decl ) ),460 };461 declsToAddBefore.push_back( Virtual::makeGetExceptionForward(462 vtable_decl->makeInst( poly_args ),463 except_decl->makeInst( poly_args )464 ) );465 declsToAddBefore.push_back( Virtual::makeVtableForward(466 vtable_decl->makeInst( move( poly_args ) ) ) );467 // Its only an error if we want a vtable and don't have one.468 } else if ( ! vtable_name.empty() ) {469 SemanticError( decl, context_error );470 }471 329 } 472 330 … … 519 377 get_type, 520 378 nullptr, 521 { new Attribute("const") },379 noAttributes, 522 380 Type::Inline 523 381 ); … … 576 434 new CastExpr( 577 435 new VariableExpr( func->get_functionType()->get_parameters().front() ), 578 func->get_functionType()->get_parameters().front()->get_type()->stripReferences()->clone(), 579 false 436 func->get_functionType()->get_parameters().front()->get_type()->stripReferences()->clone() 580 437 ) 581 438 ) … … 589 446 590 447 declsToAddAfter.push_back( get_decl ); 591 } 592 593 //============================================================================================= 594 // Suspend keyword implementation 595 //============================================================================================= 596 bool SuspendKeyword::is_real_suspend( FunctionDecl * func ) { 597 if(isMangled(func->linkage)) return false; // the real suspend isn't mangled 598 if(func->name != "__cfactx_suspend") return false; // the real suspend has a specific name 599 if(func->type->parameters.size() != 0) return false; // Too many parameters 600 if(func->type->returnVals.size() != 0) return false; // Too many return values 601 602 return true; 603 } 604 605 void SuspendKeyword::premutate( FunctionDecl * func ) { 606 GuardValue(in_generator); 607 in_generator = nullptr; 608 609 // Is this the real suspend? 610 if(is_real_suspend(func)) { 611 decl_suspend = decl_suspend ? decl_suspend : func; 612 return; 613 } 614 615 // Is this the main of a generator? 616 auto param = isMainFor( func, AggregateDecl::Aggregate::Generator ); 617 if(!param) return; 618 619 if(func->type->returnVals.size() != 0) SemanticError(func->location, "Generator main must return void"); 620 621 in_generator = param; 622 GuardValue(labels); 623 labels.clear(); 624 } 625 626 DeclarationWithType * SuspendKeyword::postmutate( FunctionDecl * func ) { 627 if( !func->statements ) return func; // Not the actual definition, don't do anything 628 if( !in_generator ) return func; // Not in a generator, don't do anything 629 if( labels.empty() ) return func; // Generator has no states, nothing to do, could throw a warning 630 631 // This is a generator main, we need to add the following code to the top 632 // static void * __generator_labels[] = {&&s0, &&s1, ...}; 633 // goto * __generator_labels[gen.__generator_state]; 634 const auto & loc = func->location; 635 636 const auto first_label = gen.newLabel("generator"); 637 638 // for each label add to declaration 639 std::list<Initializer*> inits = { new SingleInit( new LabelAddressExpr( first_label ) ) }; 640 for(const auto & label : labels) { 641 inits.push_back( 642 new SingleInit( 643 new LabelAddressExpr( label ) 644 ) 645 ); 646 } 647 auto init = new ListInit(std::move(inits), noDesignators, true); 648 labels.clear(); 649 650 // create decl 651 auto decl = new ObjectDecl( 652 "__generator_labels", 653 Type::StorageClasses( Type::Static ), 654 LinkageSpec::AutoGen, 655 nullptr, 656 new ArrayType( 657 Type::Qualifiers(), 658 new PointerType( 659 Type::Qualifiers(), 660 new VoidType( Type::Qualifiers() ) 661 ), 662 nullptr, 663 false, false 664 ), 665 init 666 ); 667 668 // create the goto 669 assert(in_generator); 670 671 auto go_decl = new ObjectDecl( 672 "__generator_label", 673 noStorageClasses, 674 LinkageSpec::AutoGen, 675 nullptr, 676 new PointerType( 677 Type::Qualifiers(), 678 new VoidType( Type::Qualifiers() ) 679 ), 680 new SingleInit( 681 new UntypedExpr( 682 new NameExpr("?[?]"), 683 { 684 new NameExpr("__generator_labels"), 685 new UntypedMemberExpr( 686 new NameExpr("__generator_state"), 687 new VariableExpr( in_generator ) 688 ) 689 } 690 ) 691 ) 692 ); 693 go_decl->location = loc; 694 695 auto go = new BranchStmt( 696 new VariableExpr( go_decl ), 697 BranchStmt::Goto 698 ); 699 go->location = loc; 700 go->computedTarget->location = loc; 701 702 auto noop = new NullStmt({ first_label }); 703 noop->location = loc; 704 705 // wrap everything in a nice compound 706 auto body = new CompoundStmt({ 707 new DeclStmt( decl ), 708 new DeclStmt( go_decl ), 709 go, 710 noop, 711 func->statements 712 }); 713 body->location = loc; 714 func->statements = body; 715 716 return func; 717 } 718 719 Statement * SuspendKeyword::postmutate( SuspendStmt * stmt ) { 720 SuspendStmt::Type type = stmt->type; 721 if(type == SuspendStmt::None) { 722 // This suspend has a implicit target, find it 723 type = in_generator ? SuspendStmt::Generator : SuspendStmt::Coroutine; 724 } 725 726 // Check that the target makes sense 727 if(!in_generator && type == SuspendStmt::Generator) SemanticError( stmt->location, "'suspend generator' must be used inside main of generator type."); 728 729 // Act appropriately 730 switch(type) { 731 case SuspendStmt::Generator: return make_generator_suspend(stmt); 732 case SuspendStmt::Coroutine: return make_coroutine_suspend(stmt); 733 default: abort(); 734 } 735 } 736 737 Statement * SuspendKeyword::make_generator_suspend( SuspendStmt * stmt ) { 738 assert(in_generator); 739 // Target code is : 740 // gen.__generator_state = X; 741 // { THEN } 742 // return; 743 // __gen_X:; 744 745 // Save the location and delete the old statement, we only need the location from this point on 746 auto loc = stmt->location; 747 748 // Build the label and get its index 749 auto label = make_label(); 750 751 // Create the context saving statement 752 auto save = new ExprStmt( new UntypedExpr( 753 new NameExpr( "?=?" ), 754 { 755 new UntypedMemberExpr( 756 new NameExpr("__generator_state"), 757 new VariableExpr( in_generator ) 758 ), 759 new ConstantExpr( 760 Constant::from_int( label.idx ) 761 ) 762 } 763 )); 764 assert(save->expr); 765 save->location = loc; 766 stmtsToAddBefore.push_back( save ); 767 768 // if we have a then add it here 769 auto then = stmt->then; 770 stmt->then = nullptr; 771 delete stmt; 772 if(then) stmtsToAddBefore.push_back( then ); 773 774 // Create the return statement 775 auto ret = new ReturnStmt( nullptr ); 776 ret->location = loc; 777 stmtsToAddBefore.push_back( ret ); 778 779 // Create the null statement with the created label 780 auto noop = new NullStmt({ label.obj }); 781 noop->location = loc; 782 783 // Return the null statement to take the place of the previous statement 784 return noop; 785 } 786 787 Statement * SuspendKeyword::make_coroutine_suspend( SuspendStmt * stmt ) { 788 if(stmt->then) SemanticError( stmt->location, "Compound statement following coroutines is not implemented."); 789 790 // Save the location and delete the old statement, we only need the location from this point on 791 auto loc = stmt->location; 792 delete stmt; 793 794 // Create the call expression 795 if(!decl_suspend) SemanticError( loc, "suspend keyword applied to coroutines requires coroutines to be in scope, add #include <coroutine.hfa>\n"); 796 auto expr = new UntypedExpr( VariableExpr::functionPointer( decl_suspend ) ); 797 expr->location = loc; 798 799 // Change this statement into a regular expr 800 assert(expr); 801 auto nstmt = new ExprStmt( expr ); 802 nstmt->location = loc; 803 return nstmt; 804 } 805 448 449 // get_decl->fixUniqueId(); 450 } 806 451 807 452 //============================================================================================= … … 813 458 bool first = false; 814 459 std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl, first ); 815 bool constisDtor = CodeGen::isDestructor( decl->name );460 bool isDtor = CodeGen::isDestructor( decl->name ); 816 461 817 462 // Is this function relevant to monitors … … 861 506 862 507 // Instrument the body 863 if ( isDtor && isThread( mutexArgs.front() ) ) { 864 if( !thread_guard_decl ) { 865 SemanticError( decl, "thread destructor requires threads to be in scope, add #include <thread.hfa>\n" ); 866 } 867 addThreadDtorStatements( decl, body, mutexArgs ); 868 } 869 else if ( isDtor ) { 870 addDtorStatements( decl, body, mutexArgs ); 508 if( isDtor ) { 509 addDtorStatments( decl, body, mutexArgs ); 871 510 } 872 511 else { 873 addStat ements( decl, body, mutexArgs );512 addStatments( decl, body, mutexArgs ); 874 513 } 875 514 } … … 877 516 void MutexKeyword::postvisit(StructDecl* decl) { 878 517 879 if( decl->name == " $monitor" && decl->body ) {518 if( decl->name == "monitor_desc" && decl->body ) { 880 519 assert( !monitor_decl ); 881 520 monitor_decl = decl; … … 888 527 assert( !dtor_guard_decl ); 889 528 dtor_guard_decl = decl; 890 }891 else if( decl->name == "thread_dtor_guard_t" && decl->body ) {892 assert( !thread_guard_decl );893 thread_guard_decl = decl;894 529 } 895 530 } … … 930 565 } 931 566 932 void MutexKeyword::addDtorStat ements( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {567 void MutexKeyword::addDtorStatments( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) { 933 568 Type * arg_type = args.front()->get_type()->clone(); 934 569 arg_type->set_mutex( false ); … … 948 583 new SingleInit( new UntypedExpr( 949 584 new NameExpr( "get_monitor" ), 950 { new CastExpr( new VariableExpr( args.front() ), arg_type , false) }585 { new CastExpr( new VariableExpr( args.front() ), arg_type ) } 951 586 )) 952 587 ); … … 969 604 { 970 605 new SingleInit( new AddressExpr( new VariableExpr( monitors ) ) ), 971 new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone(), false ) ), 972 new SingleInit( new ConstantExpr( Constant::from_bool( false ) ) ) 606 new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone() ) ) 973 607 }, 974 608 noDesignators, … … 978 612 ); 979 613 980 //$monitor * __monitors[] = { get_monitor(a), get_monitor(b) }; 981 body->push_front( new DeclStmt( monitors ) ); 982 } 983 984 void MutexKeyword::addThreadDtorStatements( 985 FunctionDecl*, CompoundStmt * body, 986 const std::list<DeclarationWithType * > & args ) { 987 assert( args.size() == 1 ); 988 DeclarationWithType * arg = args.front(); 989 Type * arg_type = arg->get_type()->clone(); 990 assert( arg_type->get_mutex() ); 991 arg_type->set_mutex( false ); 992 993 // thread_dtor_guard_t __guard = { this, intptr( 0 ) }; 994 body->push_front( 995 new DeclStmt( new ObjectDecl( 996 "__guard", 997 noStorageClasses, 998 LinkageSpec::Cforall, 999 nullptr, 1000 new StructInstType( 1001 noQualifiers, 1002 thread_guard_decl 1003 ), 1004 new ListInit( 1005 { 1006 new SingleInit( new CastExpr( new VariableExpr( arg ), arg_type ) ), 1007 new SingleInit( new UntypedExpr( 1008 new NameExpr( "intptr" ), { 1009 new ConstantExpr( Constant::from_int( 0 ) ), 1010 } 1011 ) ), 1012 }, 1013 noDesignators, 1014 true 1015 ) 1016 )) 1017 ); 1018 } 1019 1020 void MutexKeyword::addStatements( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) { 614 //monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) }; 615 body->push_front( new DeclStmt( monitors) ); 616 } 617 618 void MutexKeyword::addStatments( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) { 1021 619 ObjectDecl * monitors = new ObjectDecl( 1022 620 "__monitors", … … 1043 641 return new SingleInit( new UntypedExpr( 1044 642 new NameExpr( "get_monitor" ), 1045 { new CastExpr( new VariableExpr( var ), type , false) }643 { new CastExpr( new VariableExpr( var ), type ) } 1046 644 ) ); 1047 645 }) … … 1067 665 new SingleInit( new VariableExpr( monitors ) ), 1068 666 new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) ), 1069 new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone() , false) )667 new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone() ) ) 1070 668 }, 1071 669 noDesignators, … … 1075 673 ); 1076 674 1077 // $monitor* __monitors[] = { get_monitor(a), get_monitor(b) };675 //monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) }; 1078 676 body->push_front( new DeclStmt( monitors) ); 1079 677 } … … 1083 681 //============================================================================================= 1084 682 void ThreadStarter::previsit( StructDecl * decl ) { 1085 if( decl->name == " $thread" && decl->body ) {683 if( decl->name == "thread_desc" && decl->body ) { 1086 684 assert( !thread_decl ); 1087 685 thread_decl = decl; … … 1129 727 // tab-width: 4 // 1130 728 // End: // 1131
Note:
See TracChangeset
for help on using the changeset viewer.