Changeset 90152a4 for src/Concurrency/Keywords.cc
- Timestamp:
- Aug 27, 2018, 4:40:34 PM (7 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:
- b7c89aa
- Parents:
- f9feab8 (diff), 305581d (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. - File:
-
- 1 edited
-
src/Concurrency/Keywords.cc (modified) (23 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Concurrency/Keywords.cc
rf9feab8 r90152a4 25 25 #include "InitTweak/InitTweak.h" // for getPointerBase 26 26 #include "Parser/LinkageSpec.h" // for Cforall 27 #include "SymTab/AddVisit.h" // for acceptAndAdd28 27 #include "SynTree/Constant.h" // for Constant 29 28 #include "SynTree/Declaration.h" // for StructDecl, FunctionDecl, ObjectDecl … … 54 53 public: 55 54 56 ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name, std::string&& getter_name, std::string&& context_error, bool needs_main ) :57 type_name( type_name ), field_name( field_name ), getter_name( getter_name ), context_error( context_error ), needs_main( needs_main ) {}55 ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name, std::string&& getter_name, std::string&& context_error, bool needs_main, KeywordCastExpr::Target 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 ) {} 58 57 59 58 virtual ~ConcurrentSueKeyword() {} 60 59 61 void postvisit( StructDecl * decl );60 Declaration * postmutate( StructDecl * decl ); 62 61 63 62 void handle( StructDecl * ); … … 67 66 68 67 virtual bool is_target( StructDecl * decl ) = 0; 68 69 Expression * postmutate( KeywordCastExpr * cast ); 69 70 70 71 private: … … 74 75 const std::string context_error; 75 76 bool needs_main; 77 KeywordCastExpr::Target cast_target; 76 78 77 79 StructDecl* type_decl = nullptr; … … 95 97 "__thrd", 96 98 "get_thread", 97 "thread keyword requires threads to be in scope, add #include <thread>", 98 true 99 "thread keyword requires threads to be in scope, add #include <thread.hfa>", 100 true, 101 KeywordCastExpr::Thread 99 102 ) 100 103 {} … … 106 109 static void implement( std::list< Declaration * > & translationUnit ) { 107 110 PassVisitor< ThreadKeyword > impl; 108 acceptAll( translationUnit, impl );111 mutateAll( translationUnit, impl ); 109 112 } 110 113 }; … … 126 129 "__cor", 127 130 "get_coroutine", 128 "coroutine keyword requires coroutines to be in scope, add #include <coroutine>", 129 true 131 "coroutine keyword requires coroutines to be in scope, add #include <coroutine.hfa>", 132 true, 133 KeywordCastExpr::Coroutine 130 134 ) 131 135 {} … … 137 141 static void implement( std::list< Declaration * > & translationUnit ) { 138 142 PassVisitor< CoroutineKeyword > impl; 139 acceptAll( translationUnit, impl );143 mutateAll( translationUnit, impl ); 140 144 } 141 145 }; … … 157 161 "__mon", 158 162 "get_monitor", 159 "monitor keyword requires monitors to be in scope, add #include <monitor>", 160 false 163 "monitor keyword requires monitors to be in scope, add #include <monitor.hfa>", 164 false, 165 KeywordCastExpr::Monitor 161 166 ) 162 167 {} … … 168 173 static void implement( std::list< Declaration * > & translationUnit ) { 169 174 PassVisitor< MonitorKeyword > impl; 170 acceptAll( translationUnit, impl );175 mutateAll( translationUnit, impl ); 171 176 } 172 177 }; … … 186 191 void postvisit( StructDecl * decl ); 187 192 188 std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );193 std::list<DeclarationWithType*> findMutexArgs( FunctionDecl*, bool & first ); 189 194 void validate( DeclarationWithType * ); 190 195 void addDtorStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &); … … 257 262 // Generic keyword implementation 258 263 //============================================================================================= 259 void ConcurrentSueKeyword::postvisit(StructDecl * decl) { 264 void fixupGenerics(FunctionType * func, StructDecl * decl) { 265 cloneAll(decl->parameters, func->forall); 266 for ( TypeDecl * td : func->forall ) { 267 strict_dynamic_cast<StructInstType*>( 268 func->parameters.front()->get_type()->stripReferences() 269 )->parameters.push_back( 270 new TypeExpr( new TypeInstType( noQualifiers, td->name, td ) ) 271 ); 272 } 273 } 274 275 Declaration * ConcurrentSueKeyword::postmutate(StructDecl * decl) { 260 276 if( decl->name == type_name && decl->body ) { 261 277 assert( !type_decl ); … … 265 281 handle( decl ); 266 282 } 267 268 } 283 return decl; 284 } 285 286 Expression * ConcurrentSueKeyword::postmutate( KeywordCastExpr * cast ) { 287 if ( cast_target == cast->target ) { 288 // convert (thread &)t to (thread_desc &)*get_thread(t), etc. 289 if( !type_decl ) SemanticError( cast, context_error ); 290 Expression * arg = cast->arg; 291 cast->arg = nullptr; 292 delete cast; 293 return new CastExpr( 294 UntypedExpr::createDeref( 295 new UntypedExpr( new NameExpr( getter_name ), { arg } ) 296 ), 297 new ReferenceType( 298 noQualifiers, 299 new StructInstType( noQualifiers, type_decl ) ) 300 ); 301 } 302 return cast; 303 } 304 269 305 270 306 void ConcurrentSueKeyword::handle( StructDecl * decl ) { 271 307 if( ! decl->body ) return; 272 308 273 if( !type_decl ) throw SemanticError( context_error, decl);309 if( !type_decl ) SemanticError( decl, context_error ); 274 310 275 311 FunctionDecl * func = forwardDeclare( decl ); … … 301 337 ); 302 338 303 get_type->get_parameters().push_back( this_decl );339 get_type->get_parameters().push_back( this_decl->clone() ); 304 340 get_type->get_returnVals().push_back( 305 341 new ObjectDecl( … … 318 354 ) 319 355 ); 356 fixupGenerics(get_type, decl); 320 357 321 358 FunctionDecl * get_decl = new FunctionDecl( … … 343 380 nullptr 344 381 ); 345 } 382 fixupGenerics(main_type, decl); 383 } 384 385 delete this_decl; 346 386 347 387 declsToAddBefore.push_back( forward ); … … 377 417 new MemberExpr( 378 418 field, 379 UntypedExpr::createDeref( new VariableExpr( func->get_functionType()->get_parameters().front() ) ) 419 new CastExpr( 420 new VariableExpr( func->get_functionType()->get_parameters().front() ), 421 func->get_functionType()->get_parameters().front()->get_type()->stripReferences()->clone() 422 ) 380 423 ) 381 424 ) … … 398 441 void MutexKeyword::postvisit(FunctionDecl* decl) { 399 442 400 std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl ); 401 if( mutexArgs.empty() ) return; 402 403 if( CodeGen::isConstructor(decl->name) ) throw SemanticError( "constructors cannot have mutex parameters", decl ); 404 443 bool first = false; 444 std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl, first ); 405 445 bool isDtor = CodeGen::isDestructor( decl->name ); 406 446 407 if( isDtor && mutexArgs.size() != 1 ) throw SemanticError( "destructors can only have 1 mutex argument", decl ); 408 447 // Is this function relevant to monitors 448 if( mutexArgs.empty() ) { 449 // If this is the destructor for a monitor it must be mutex 450 if(isDtor) { 451 Type* ty = decl->get_functionType()->get_parameters().front()->get_type(); 452 453 // If it's a copy, it's not a mutex 454 ReferenceType* rty = dynamic_cast< ReferenceType * >( ty ); 455 if( ! rty ) return; 456 457 // If we are not pointing directly to a type, it's not a mutex 458 Type* base = rty->get_base(); 459 if( dynamic_cast< ReferenceType * >( base ) ) return; 460 if( dynamic_cast< PointerType * >( base ) ) return; 461 462 // Check if its a struct 463 StructInstType * baseStruct = dynamic_cast< StructInstType * >( base ); 464 if( !baseStruct ) return; 465 466 // Check if its a monitor 467 if(baseStruct->baseStruct->is_monitor() || baseStruct->baseStruct->is_thread()) 468 SemanticError( decl, "destructors for structures declared as \"monitor\" must use mutex parameters\n" ); 469 } 470 return; 471 } 472 473 // Monitors can't be constructed with mutual exclusion 474 if( CodeGen::isConstructor(decl->name) && !first ) SemanticError( decl, "constructors cannot have mutex parameters" ); 475 476 // It makes no sense to have multiple mutex parameters for the destructor 477 if( isDtor && mutexArgs.size() != 1 ) SemanticError( decl, "destructors can only have 1 mutex argument" ); 478 479 // Make sure all the mutex arguments are monitors 409 480 for(auto arg : mutexArgs) { 410 481 validate( arg ); 411 482 } 412 483 484 // Check if we need to instrument the body 413 485 CompoundStmt* body = decl->get_statements(); 414 486 if( ! body ) return; 415 487 416 if( !monitor_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl ); 417 if( !guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl ); 418 if( !dtor_guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl ); 419 488 // Do we have the required headers 489 if( !monitor_decl || !guard_decl || !dtor_guard_decl ) 490 SemanticError( decl, "mutex keyword requires monitors to be in scope, add #include <monitor.hfa>\n" ); 491 492 // Instrument the body 420 493 if( isDtor ) { 421 494 addDtorStatments( decl, body, mutexArgs ); … … 428 501 void MutexKeyword::postvisit(StructDecl* decl) { 429 502 430 if( decl->name == "monitor_desc" ) {503 if( decl->name == "monitor_desc" && decl->body ) { 431 504 assert( !monitor_decl ); 432 505 monitor_decl = decl; 433 506 } 434 else if( decl->name == "monitor_guard_t" ) {507 else if( decl->name == "monitor_guard_t" && decl->body ) { 435 508 assert( !guard_decl ); 436 509 guard_decl = decl; 437 510 } 438 else if( decl->name == "monitor_dtor_guard_t" ) {511 else if( decl->name == "monitor_dtor_guard_t" && decl->body ) { 439 512 assert( !dtor_guard_decl ); 440 513 dtor_guard_decl = decl; … … 442 515 } 443 516 444 std::list<DeclarationWithType*> MutexKeyword::findMutexArgs( FunctionDecl* decl ) {517 std::list<DeclarationWithType*> MutexKeyword::findMutexArgs( FunctionDecl* decl, bool & first ) { 445 518 std::list<DeclarationWithType*> mutexArgs; 446 519 520 bool once = true; 447 521 for( auto arg : decl->get_functionType()->get_parameters()) { 448 522 //Find mutex arguments … … 450 524 if( ! ty->get_mutex() ) continue; 451 525 526 if(once) {first = true;} 527 once = false; 528 452 529 //Append it to the list 453 530 mutexArgs.push_back( arg ); … … 462 539 //Makes sure it's not a copy 463 540 ReferenceType* rty = dynamic_cast< ReferenceType * >( ty ); 464 if( ! rty ) throw SemanticError( "Mutex argument must be of reference type ", arg);541 if( ! rty ) SemanticError( arg, "Mutex argument must be of reference type " ); 465 542 466 543 //Make sure the we are pointing directly to a type 467 544 Type* base = rty->get_base(); 468 if( dynamic_cast< ReferenceType * >( base ) ) throw SemanticError( "Mutex argument have exactly one level of indirection ", arg);469 if( dynamic_cast< PointerType * >( base ) ) throw SemanticError( "Mutex argument have exactly one level of indirection ", arg);545 if( dynamic_cast< ReferenceType * >( base ) ) SemanticError( arg, "Mutex argument have exactly one level of indirection " ); 546 if( dynamic_cast< PointerType * >( base ) ) SemanticError( arg, "Mutex argument have exactly one level of indirection " ); 470 547 471 548 //Make sure that typed isn't mutex 472 if( base->get_mutex() ) throw SemanticError( "mutex keyword may only appear once per argument ", arg);549 if( base->get_mutex() ) SemanticError( arg, "mutex keyword may only appear once per argument " ); 473 550 } 474 551 … … 608 685 if( type && type->get_baseStruct()->is_thread() ) { 609 686 if( !thread_decl || !thread_ctor_seen ) { 610 throw SemanticError("thread keyword requires threads to be in scope, add #include <thread>");687 SemanticError( type->get_baseStruct()->location, "thread keyword requires threads to be in scope, add #include <thread.hfa>"); 611 688 } 612 689
Note:
See TracChangeset
for help on using the changeset viewer.