- Timestamp:
- Aug 11, 2020, 4:40:15 PM (3 years ago)
- Branches:
- ADT, arm-eh, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 0d070ca
- Parents:
- 07d867b (diff), 129674b (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:
-
- 1 deleted
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Common/PassVisitor.proto.h
r07d867b r22f94a4 38 38 }; 39 39 40 std::stack< cleanup_t, std::vector< cleanup_t> > cleanups;40 std::stack< cleanup_t, std::vector< cleanup_t > > cleanups; 41 41 }; 42 42 -
src/Common/ScopedMap.h
r07d867b r22f94a4 93 93 94 94 reference operator* () { return *it; } 95 pointer operator-> () { return it.operator->(); }95 pointer operator-> () const { return it.operator->(); } 96 96 97 97 iterator& operator++ () { -
src/Concurrency/Keywords.cc
r07d867b r22f94a4 510 510 new CastExpr( 511 511 new VariableExpr( func->get_functionType()->get_parameters().front() ), 512 func->get_functionType()->get_parameters().front()->get_type()->stripReferences()->clone() 512 func->get_functionType()->get_parameters().front()->get_type()->stripReferences()->clone(), 513 false 513 514 ) 514 515 ) … … 888 889 new SingleInit( new UntypedExpr( 889 890 new NameExpr( "get_monitor" ), 890 { new CastExpr( new VariableExpr( args.front() ), arg_type ) }891 { new CastExpr( new VariableExpr( args.front() ), arg_type, false ) } 891 892 )) 892 893 ); … … 909 910 { 910 911 new SingleInit( new AddressExpr( new VariableExpr( monitors ) ) ), 911 new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone() ) )912 new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone(), false ) ) 912 913 }, 913 914 noDesignators, … … 946 947 return new SingleInit( new UntypedExpr( 947 948 new NameExpr( "get_monitor" ), 948 { new CastExpr( new VariableExpr( var ), type ) }949 { new CastExpr( new VariableExpr( var ), type, false ) } 949 950 ) ); 950 951 }) … … 970 971 new SingleInit( new VariableExpr( monitors ) ), 971 972 new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) ), 972 new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone() ) )973 new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone(), false ) ) 973 974 }, 974 975 noDesignators, -
src/Concurrency/Waitfor.cc
r07d867b r22f94a4 384 384 decl_monitor 385 385 ) 386 ) 386 ), 387 false 387 388 ); 388 389 … … 408 409 new CompoundStmt({ 409 410 makeAccStatement( acceptables, index, "is_dtor", detectIsDtor( clause.target.function ) , indexer ), 410 makeAccStatement( acceptables, index, "func" , new CastExpr( clause.target.function, fptr_t ), indexer ),411 makeAccStatement( acceptables, index, "func" , new CastExpr( clause.target.function, fptr_t, false ) , indexer ), 411 412 makeAccStatement( acceptables, index, "data" , new VariableExpr( monitors ) , indexer ), 412 413 makeAccStatement( acceptables, index, "size" , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ), indexer ), … … 531 532 decl_mask 532 533 ) 533 ) 534 ), 535 false 534 536 ), 535 537 timeout -
src/ControlStruct/ExceptTranslate.cc
r07d867b r22f94a4 10 10 // Created On : Wed Jun 14 16:49:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Mar 27 11:58:00 202013 // Update Count : 1 312 // Last Modified On : Wed Jun 24 11:18:00 2020 13 // Update Count : 17 14 14 // 15 15 … … 64 64 } 65 65 66 class ExceptionMutatorCore : public WithGuards { 67 enum Context { NoHandler, TerHandler, ResHandler }; 68 69 // Also need to handle goto, break & continue. 70 // They need to be cut off in a ResHandler, until we enter another 71 // loop, switch or the goto stays within the function. 72 73 Context cur_context; 74 75 // The current (innermost) termination handler exception declaration. 76 ObjectDecl * handler_except_decl; 77 66 class ThrowMutatorCore : public WithGuards { 67 ObjectDecl * terminate_handler_except; 68 enum Context { NoHandler, TerHandler, ResHandler } cur_context; 69 70 // The helper functions for code/syntree generation. 71 Statement * create_either_throw( 72 ThrowStmt * throwStmt, const char * throwFunc ); 73 Statement * create_terminate_rethrow( ThrowStmt * throwStmt ); 74 75 public: 76 ThrowMutatorCore() : 77 terminate_handler_except( nullptr ), 78 cur_context( NoHandler ) 79 {} 80 81 void premutate( CatchStmt *catchStmt ); 82 Statement * postmutate( ThrowStmt *throwStmt ); 83 }; 84 85 // ThrowStmt Mutation Helpers 86 87 Statement * ThrowMutatorCore::create_either_throw( 88 ThrowStmt * throwStmt, const char * throwFunc ) { 89 // `throwFunc`( `throwStmt->get_name()` ); 90 UntypedExpr * call = new UntypedExpr( new NameExpr( throwFunc ) ); 91 call->get_args().push_back( throwStmt->get_expr() ); 92 throwStmt->set_expr( nullptr ); 93 delete throwStmt; 94 return new ExprStmt( call ); 95 } 96 97 Statement * ThrowMutatorCore::create_terminate_rethrow( 98 ThrowStmt *throwStmt ) { 99 // { `terminate_handler_except` = 0p; __rethrow_terminate(); } 100 assert( nullptr == throwStmt->get_expr() ); 101 assert( terminate_handler_except ); 102 103 CompoundStmt * result = new CompoundStmt(); 104 result->labels = throwStmt->labels; 105 result->push_back( new ExprStmt( UntypedExpr::createAssign( 106 nameOf( terminate_handler_except ), 107 new ConstantExpr( Constant::null( 108 terminate_handler_except->get_type()->clone() 109 ) ) 110 ) ) ); 111 result->push_back( new ExprStmt( 112 new UntypedExpr( new NameExpr( "__cfaehm_rethrow_terminate" ) ) 113 ) ); 114 delete throwStmt; 115 return result; 116 } 117 118 // Visiting/Mutating Functions 119 120 void ThrowMutatorCore::premutate( CatchStmt *catchStmt ) { 121 // Validate the statement's form. 122 ObjectDecl * decl = dynamic_cast<ObjectDecl *>( catchStmt->get_decl() ); 123 // Also checking the type would be nice. 124 if ( !decl || !dynamic_cast<PointerType *>( decl->type ) ) { 125 std::string kind = (CatchStmt::Terminate == catchStmt->kind) ? "catch" : "catchResume"; 126 SemanticError( catchStmt->location, kind + " must have pointer to an exception type" ); 127 } 128 129 // Track the handler context. 130 GuardValue( cur_context ); 131 if ( CatchStmt::Terminate == catchStmt->get_kind() ) { 132 cur_context = TerHandler; 133 134 GuardValue( terminate_handler_except ); 135 terminate_handler_except = decl; 136 } else { 137 cur_context = ResHandler; 138 } 139 } 140 141 Statement * ThrowMutatorCore::postmutate( ThrowStmt *throwStmt ) { 142 // Ignoring throwStmt->get_target() for now. 143 if ( ThrowStmt::Terminate == throwStmt->get_kind() ) { 144 if ( throwStmt->get_expr() ) { 145 return create_either_throw( throwStmt, "$throw" ); 146 } else if ( TerHandler == cur_context ) { 147 return create_terminate_rethrow( throwStmt ); 148 } else { 149 abort("Invalid throw in %s at %i\n", 150 throwStmt->location.filename.c_str(), 151 throwStmt->location.first_line); 152 } 153 } else { 154 if ( throwStmt->get_expr() ) { 155 return create_either_throw( throwStmt, "$throwResume" ); 156 } else if ( ResHandler == cur_context ) { 157 // This has to be handled later. 158 return throwStmt; 159 } else { 160 abort("Invalid throwResume in %s at %i\n", 161 throwStmt->location.filename.c_str(), 162 throwStmt->location.first_line); 163 } 164 } 165 } 166 167 class TryMutatorCore { 78 168 // The built in types used in translation. 79 169 StructDecl * except_decl; … … 82 172 83 173 // The many helper functions for code/syntree generation. 84 Statement * create_given_throw(85 const char * throwFunc, ThrowStmt * throwStmt );86 Statement * create_terminate_throw( ThrowStmt * throwStmt );87 Statement * create_terminate_rethrow( ThrowStmt * throwStmt );88 Statement * create_resume_throw( ThrowStmt * throwStmt );89 Statement * create_resume_rethrow( ThrowStmt * throwStmt );90 174 CompoundStmt * take_try_block( TryStmt * tryStmt ); 91 175 FunctionDecl * create_try_wrapper( CompoundStmt * body ); … … 101 185 FunctionDecl * create_finally_wrapper( TryStmt * tryStmt ); 102 186 ObjectDecl * create_finally_hook( FunctionDecl * finally_wrapper ); 187 Statement * create_resume_rethrow( ThrowStmt * throwStmt ); 103 188 104 189 // Types used in translation, make sure to use clone. … … 121 206 122 207 public: 123 ExceptionMutatorCore() : 124 cur_context( NoHandler ), 125 handler_except_decl( nullptr ), 208 TryMutatorCore() : 126 209 except_decl( nullptr ), node_decl( nullptr ), hook_decl( nullptr ), 127 210 try_func_t( noQualifiers, false ), … … 132 215 {} 133 216 134 void premutate( CatchStmt *catchStmt );135 217 void premutate( StructDecl *structDecl ); 218 Statement * postmutate( TryStmt *tryStmt ); 136 219 Statement * postmutate( ThrowStmt *throwStmt ); 137 Statement * postmutate( TryStmt *tryStmt );138 220 }; 139 221 140 void ExceptionMutatorCore::init_func_types() {222 void TryMutatorCore::init_func_types() { 141 223 assert( except_decl ); 142 224 … … 196 278 } 197 279 198 // ThrowStmt Mutation Helpers199 200 Statement * ExceptionMutatorCore::create_given_throw(201 const char * throwFunc, ThrowStmt * throwStmt ) {202 // `throwFunc`( `throwStmt->get_name` );203 UntypedExpr * call = new UntypedExpr( new NameExpr( throwFunc ) );204 call->get_args().push_back( throwStmt->get_expr() );205 throwStmt->set_expr( nullptr );206 delete throwStmt;207 return new ExprStmt( call );208 }209 210 Statement * ExceptionMutatorCore::create_terminate_throw(211 ThrowStmt *throwStmt ) {212 // __throw_terminate( `throwStmt->get_name()` ); }213 return create_given_throw( "__cfaehm_throw_terminate", throwStmt );214 }215 216 Statement * ExceptionMutatorCore::create_terminate_rethrow(217 ThrowStmt *throwStmt ) {218 // { `handler_except_decl` = NULL; __rethrow_terminate(); }219 assert( nullptr == throwStmt->get_expr() );220 assert( handler_except_decl );221 222 CompoundStmt * result = new CompoundStmt();223 result->labels = throwStmt->labels;224 result->push_back( new ExprStmt( UntypedExpr::createAssign(225 nameOf( handler_except_decl ),226 new ConstantExpr( Constant::null(227 new PointerType(228 noQualifiers,229 handler_except_decl->get_type()->clone()230 )231 ) )232 ) ) );233 result->push_back( new ExprStmt(234 new UntypedExpr( new NameExpr( "__cfaehm_rethrow_terminate" ) )235 ) );236 delete throwStmt;237 return result;238 }239 240 Statement * ExceptionMutatorCore::create_resume_throw(241 ThrowStmt *throwStmt ) {242 // __throw_resume( `throwStmt->get_name` );243 return create_given_throw( "__cfaehm_throw_resume", throwStmt );244 }245 246 Statement * ExceptionMutatorCore::create_resume_rethrow(247 ThrowStmt *throwStmt ) {248 // return false;249 Statement * result = new ReturnStmt(250 new ConstantExpr( Constant::from_bool( false ) )251 );252 result->labels = throwStmt->labels;253 delete throwStmt;254 return result;255 }256 257 280 // TryStmt Mutation Helpers 258 281 259 CompoundStmt * ExceptionMutatorCore::take_try_block( TryStmt *tryStmt ) {282 CompoundStmt * TryMutatorCore::take_try_block( TryStmt *tryStmt ) { 260 283 CompoundStmt * block = tryStmt->get_block(); 261 284 tryStmt->set_block( nullptr ); … … 263 286 } 264 287 265 FunctionDecl * ExceptionMutatorCore::create_try_wrapper(288 FunctionDecl * TryMutatorCore::create_try_wrapper( 266 289 CompoundStmt *body ) { 267 290 … … 270 293 } 271 294 272 FunctionDecl * ExceptionMutatorCore::create_terminate_catch(295 FunctionDecl * TryMutatorCore::create_terminate_catch( 273 296 CatchList &handlers ) { 274 297 std::list<CaseStmt *> handler_wrappers; … … 350 373 // Create a single check from a moddified handler. 351 374 // except_obj is referenced, modded_handler will be freed. 352 CompoundStmt * ExceptionMutatorCore::create_single_matcher(375 CompoundStmt * TryMutatorCore::create_single_matcher( 353 376 DeclarationWithType * except_obj, CatchStmt * modded_handler ) { 354 377 // { … … 388 411 } 389 412 390 FunctionDecl * ExceptionMutatorCore::create_terminate_match(413 FunctionDecl * TryMutatorCore::create_terminate_match( 391 414 CatchList &handlers ) { 392 415 // int match(exception * except) { … … 425 448 } 426 449 427 CompoundStmt * ExceptionMutatorCore::create_terminate_caller(450 CompoundStmt * TryMutatorCore::create_terminate_caller( 428 451 FunctionDecl * try_wrapper, 429 452 FunctionDecl * terminate_catch, … … 443 466 } 444 467 445 FunctionDecl * ExceptionMutatorCore::create_resume_handler(468 FunctionDecl * TryMutatorCore::create_resume_handler( 446 469 CatchList &handlers ) { 447 470 // bool handle(exception * except) { … … 480 503 } 481 504 482 CompoundStmt * ExceptionMutatorCore::create_resume_wrapper(505 CompoundStmt * TryMutatorCore::create_resume_wrapper( 483 506 Statement * wraps, 484 507 FunctionDecl * resume_handler ) { … … 524 547 } 525 548 526 FunctionDecl * ExceptionMutatorCore::create_finally_wrapper(549 FunctionDecl * TryMutatorCore::create_finally_wrapper( 527 550 TryStmt * tryStmt ) { 528 // void finally() { <finally code>}551 // void finally() { `finally->block` } 529 552 FinallyStmt * finally = tryStmt->get_finally(); 530 553 CompoundStmt * body = finally->get_block(); … … 537 560 } 538 561 539 ObjectDecl * ExceptionMutatorCore::create_finally_hook(562 ObjectDecl * TryMutatorCore::create_finally_hook( 540 563 FunctionDecl * finally_wrapper ) { 541 564 // struct __cfaehm_cleanup_hook __finally_hook 542 // __attribute__((cleanup( finally_wrapper)));565 // __attribute__((cleanup( `finally_wrapper` ))); 543 566 544 567 // Make Cleanup Attribute. … … 564 587 } 565 588 589 Statement * TryMutatorCore::create_resume_rethrow( ThrowStmt *throwStmt ) { 590 // return false; 591 Statement * result = new ReturnStmt( 592 new ConstantExpr( Constant::from_bool( false ) ) 593 ); 594 result->labels = throwStmt->labels; 595 delete throwStmt; 596 return result; 597 } 598 566 599 // Visiting/Mutating Functions 567 void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) { 568 // Validate the Statement's form. 569 ObjectDecl * decl = 570 dynamic_cast<ObjectDecl *>( catchStmt->get_decl() ); 571 if ( decl && true /* check decl->get_type() */ ) { 572 // Pass. 573 } else if ( CatchStmt::Terminate == catchStmt->get_kind() ) { 574 SemanticError(catchStmt->location, "catch must have exception type"); 575 } else { 576 SemanticError(catchStmt->location, "catchResume must have exception type"); 577 } 578 579 // Track the handler context. 580 GuardValue( cur_context ); 581 if ( CatchStmt::Terminate == catchStmt->get_kind() ) { 582 cur_context = TerHandler; 583 584 GuardValue( handler_except_decl ); 585 handler_except_decl = decl; 586 } else { 587 cur_context = ResHandler; 588 } 589 } 590 591 void ExceptionMutatorCore::premutate( StructDecl *structDecl ) { 600 void TryMutatorCore::premutate( StructDecl *structDecl ) { 592 601 if ( !structDecl->has_body() ) { 593 602 // Skip children? … … 604 613 hook_decl = structDecl; 605 614 } 606 // Later we might get the exception type as well. 607 } 608 609 Statement * ExceptionMutatorCore::postmutate( ThrowStmt *throwStmt ) { 610 assert( except_decl ); 611 612 // Ignoring throwStmt->get_target() for now. 613 if ( ThrowStmt::Terminate == throwStmt->get_kind() ) { 614 if ( throwStmt->get_expr() ) { 615 return create_terminate_throw( throwStmt ); 616 } else if ( TerHandler == cur_context ) { 617 return create_terminate_rethrow( throwStmt ); 618 } else { 619 abort("Invalid throw in %s at %i\n", 620 throwStmt->location.filename.c_str(), 621 throwStmt->location.first_line); 622 } 623 } else { 624 if ( throwStmt->get_expr() ) { 625 return create_resume_throw( throwStmt ); 626 } else if ( ResHandler == cur_context ) { 627 return create_resume_rethrow( throwStmt ); 628 } else { 629 abort("Invalid throwResume in %s at %i\n", 630 throwStmt->location.filename.c_str(), 631 throwStmt->location.first_line); 632 } 633 } 634 } 635 636 Statement * ExceptionMutatorCore::postmutate( TryStmt *tryStmt ) { 615 } 616 617 Statement * TryMutatorCore::postmutate( TryStmt *tryStmt ) { 637 618 assert( except_decl ); 638 619 assert( node_decl ); … … 688 669 } 689 670 690 void translateEHM( std::list< Declaration *> & translationUnit ) { 691 PassVisitor<ExceptionMutatorCore> translator; 671 Statement * TryMutatorCore::postmutate( ThrowStmt *throwStmt ) { 672 // Only valid `throwResume;` statements should remain. (2/3 checks) 673 assert( ThrowStmt::Resume == throwStmt->kind && ! throwStmt->expr ); 674 return create_resume_rethrow( throwStmt ); 675 } 676 677 void translateThrows( std::list< Declaration *> & translationUnit ) { 678 PassVisitor<ThrowMutatorCore> translator; 692 679 mutateAll( translationUnit, translator ); 693 680 } 681 682 void translateTries( std::list< Declaration *> & translationUnit ) { 683 PassVisitor<TryMutatorCore> translator; 684 mutateAll( translationUnit, translator ); 685 } 694 686 } -
src/ControlStruct/ExceptTranslate.h
r07d867b r22f94a4 9 9 // Author : Andrew Beach 10 10 // Created On : Tus Jun 06 10:13:00 2017 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 22 09:19:23 201713 // Update Count : 411 // Last Modified By : Andrew Beach 12 // Last Modified On : Tus May 19 11:47:00 2020 13 // Update Count : 5 14 14 // 15 15 … … 21 21 22 22 namespace ControlStruct { 23 void translateEHM( std::list< Declaration *> & translationUnit ); 24 // Converts exception handling structures into their underlying C code. Translation does use the exception 25 // handling header, make sure it is visible wherever translation occurs. 23 void translateThrows( std::list< Declaration *> & translationUnit ); 24 /* Replaces all throw & throwResume statements with function calls. 25 * These still need to be resolved, so call this before the reslover. 26 */ 27 28 void translateTries( std::list< Declaration *> & translationUnit ); 29 /* Replaces all try blocks (and their many clauses) with function definitions and calls. 30 * This uses the exception built-ins to produce typed output and should take place after 31 * the resolver. It also produces virtual casts and should happen before they are expanded. 32 */ 26 33 } 27 34 -
src/GenPoly/InstantiateGeneric.cc
r07d867b r22f94a4 9 9 // Author : Aaron B. Moss 10 10 // Created On : Thu Aug 04 18:33:00 2016 11 // Last Modified By : A aron B. Moss12 // Last Modified On : Thu Aug 04 18:33:00 201613 // Update Count : 111 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Jul 16 10:17:00 2020 13 // Update Count : 2 14 14 // 15 15 #include "InstantiateGeneric.h" … … 297 297 } 298 298 299 template< typename AggrInst > 300 static AggrInst * asForward( AggrInst * decl ) { 301 if ( !decl->body ) { 302 return nullptr; 303 } 304 decl = decl->clone(); 305 decl->body = false; 306 deleteAll( decl->members ); 307 decl->members.clear(); 308 return decl; 309 } 310 299 311 void GenericInstantiator::stripDtypeParams( AggregateDecl *base, std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs ) { 300 312 substituteMembers( base->get_members(), baseParams, typeSubs ); … … 373 385 concDecl->set_body( inst->get_baseStruct()->has_body() ); 374 386 substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() ); 375 insert( inst, typeSubs, concDecl ); // must insert before recursion 387 // Forward declare before recursion. (TODO: Only when needed, #199.) 388 insert( inst, typeSubs, concDecl ); 389 if ( StructDecl *forwardDecl = asForward( concDecl ) ) { 390 declsToAddBefore.push_back( forwardDecl ); 391 } 376 392 concDecl->acceptMutator( *visitor ); // recursively instantiate members 377 393 declsToAddBefore.push_back( concDecl ); // must occur before declaration is added so that member instantiations appear first … … 423 439 concDecl->set_body( inst->get_baseUnion()->has_body() ); 424 440 substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() ); 425 insert( inst, typeSubs, concDecl ); // must insert before recursion 441 // Forward declare before recursion. (TODO: Only when needed, #199.) 442 insert( inst, typeSubs, concDecl ); 443 if ( UnionDecl *forwardDecl = asForward( concDecl ) ) { 444 declsToAddBefore.push_back( forwardDecl ); 445 } 426 446 concDecl->acceptMutator( *visitor ); // recursively instantiate members 427 447 declsToAddBefore.push_back( concDecl ); // must occur before declaration is added so that member instantiations appear first -
src/GenPoly/Specialize.cc
r07d867b r22f94a4 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Dec 13 23:40:49 201913 // Update Count : 3 211 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Jul 2 17:42:00 2020 13 // Update Count : 33 14 14 // 15 15 … … 42 42 43 43 namespace GenPoly { 44 struct Specialize final : public WithConstTypeSubstitution, public WithStmtsToAdd, public WithVisitorRef<Specialize> { 44 struct Specialize final : public WithConstTypeSubstitution, 45 public WithDeclsToAdd, public WithVisitorRef<Specialize> { 45 46 Expression * postmutate( ApplicationExpr *applicationExpr ); 46 47 Expression * postmutate( CastExpr *castExpr ); … … 248 249 } // if 249 250 250 // handle any specializations that may still be present 251 std::string oldParamPrefix = paramPrefix; 252 paramPrefix += "p"; 253 // save stmtsToAddBefore in oldStmts 254 std::list< Statement* > oldStmts; 255 oldStmts.splice( oldStmts.end(), stmtsToAddBefore ); 256 appExpr->acceptMutator( *visitor ); 257 paramPrefix = oldParamPrefix; 258 // write any statements added for recursive specializations into the thunk body 259 thunkFunc->statements->kids.splice( thunkFunc->statements->kids.end(), stmtsToAddBefore ); 260 // restore oldStmts into stmtsToAddBefore 261 stmtsToAddBefore.splice( stmtsToAddBefore.end(), oldStmts ); 251 // Handle any specializations that may still be present. 252 { 253 std::string oldParamPrefix = paramPrefix; 254 paramPrefix += "p"; 255 std::list< Declaration * > oldDecls; 256 oldDecls.splice( oldDecls.end(), declsToAddBefore ); 257 258 appExpr->acceptMutator( *visitor ); 259 // Write recursive specializations into the thunk body. 260 for ( Declaration * decl : declsToAddBefore ) { 261 thunkFunc->statements->kids.push_back( new DeclStmt( decl ) ); 262 } 263 264 declsToAddBefore = std::move( oldDecls ); 265 paramPrefix = oldParamPrefix; 266 } 262 267 263 268 // add return (or valueless expression) to the thunk … … 270 275 thunkFunc->statements->kids.push_back( appStmt ); 271 276 272 // add thunk definition to queue of statements to add273 stmtsToAddBefore.push_back( new DeclStmt( thunkFunc ));277 // Add the thunk definition (converted to DeclStmt if appproprate). 278 declsToAddBefore.push_back( thunkFunc ); 274 279 // return address of thunk function as replacement expression 275 280 return new AddressExpr( new VariableExpr( thunkFunc ) ); -
src/Parser/DeclarationNode.cc
r07d867b r22f94a4 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Dec 16 15:32:22 201913 // Update Count : 113 312 // Last Modified On : Tue Jun 9 20:26:55 2020 13 // Update Count : 1134 14 14 // 15 15 … … 1115 1115 // SUE's cannot have function specifiers, either 1116 1116 // 1117 // inl ne _Noreturn struct S { ... }; // disallowed1118 // inl ne _Noreturn enum E { ... }; // disallowed1117 // inline _Noreturn struct S { ... }; // disallowed 1118 // inline _Noreturn enum E { ... }; // disallowed 1119 1119 if ( funcSpecs.any() ) { 1120 1120 SemanticError( this, "invalid function specifier for " ); -
src/Parser/ExpressionNode.cc
r07d867b r22f94a4 10 10 // Created On : Sat May 16 13:17:07 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Dec 18 21:14:58 201913 // Update Count : 98112 // Last Modified On : Wed Jul 15 08:24:08 2020 13 // Update Count : 1046 14 14 // 15 15 … … 85 85 } // if 86 86 // remove "lL" for these cases because it may not imply long 87 str.erase( posn ); // remove length 87 str.erase( posn ); // remove length suffix and "uU" 88 88 } // lnthSuffix 89 89 … … 108 108 } // valueToType 109 109 110 static void scanbin( string & str, unsigned long long int & v ) { 111 v = 0; 112 size_t last = str.length() - 1; // last subscript of constant 113 for ( unsigned int i = 2;; ) { // ignore prefix 114 if ( str[i] == '1' ) v |= 1; 115 i += 1; 116 if ( i == last - 1 || (str[i] != '0' && str[i] != '1') ) break; 117 v <<= 1; 118 } // for 119 } // scanbin 120 110 121 Expression * build_constantInteger( string & str ) { 111 122 static const BasicType::Kind kind[2][6] = { 112 123 // short (h) must be before char (hh) because shorter type has the longer suffix 113 { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt128, },114 { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt128, },124 { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, /* BasicType::SignedInt128 */ BasicType::LongLongSignedInt, }, 125 { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, /* BasicType::UnsignedInt128 */ BasicType::LongLongUnsignedInt, }, 115 126 }; 116 127 … … 120 131 }; // lnthsInt 121 132 122 unsigned long long int v; // converted integral value 123 size_t last = str.length() - 1; // last subscript of constant 124 Expression * ret; 125 //string fred( str ); 133 string str2( "0x0" ); 134 unsigned long long int v, v2 = 0; // converted integral value 135 Expression * ret, * ret2; 126 136 127 137 int type = -1; // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128 … … 139 149 } // if 140 150 151 string::size_type posn; 152 153 // 'u' can appear before or after length suffix 154 if ( str.find_last_of( "uU" ) != string::npos ) Unsigned = true; 155 156 if ( isdigit( str[str.length() - 1] ) ) { // no suffix ? 157 lnthSuffix( str, type, ltype ); // could have length suffix 158 if ( type == 5 && Unsigned ) str.erase( str.length() - 1 ); // L128 and terminating "uU" ? 159 } else { 160 // At least one digit in integer constant, so safe to backup while looking for suffix. 161 162 posn = str.find_last_of( "pP" ); // pointer value 163 if ( posn != string::npos ) { ltype = 5; str.erase( posn, 1 ); goto FINI; } 164 165 posn = str.find_last_of( "zZ" ); // size_t 166 if ( posn != string::npos ) { Unsigned = true; type = 2; ltype = 4; str.erase( posn, 1 ); goto FINI; } 167 168 posn = str.rfind( "hh" ); // char 169 if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; } 170 171 posn = str.rfind( "HH" ); // char 172 if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; } 173 174 posn = str.find_last_of( "hH" ); // short 175 if ( posn != string::npos ) { type = 0; str.erase( posn, 1 ); goto FINI; } 176 177 posn = str.find_last_of( "nN" ); // int (natural number) 178 if ( posn != string::npos ) { type = 2; str.erase( posn, 1 ); goto FINI; } 179 180 if ( str.rfind( "ll" ) != string::npos || str.rfind( "LL" ) != string::npos ) { type = 4; goto FINI; } 181 182 lnthSuffix( str, type, ltype ); // must be after check for "ll" 183 FINI: ; 184 } // if 185 141 186 // Cannot be just "0"/"1"; sscanf stops at the suffix, if any; value goes over the wall => always generate 142 187 188 #if ! defined(__SIZEOF_INT128__) 189 if ( type == 5 ) SemanticError( yylloc, "int128 constant is not supported on this target " + str ); 190 #endif // ! __SIZEOF_INT128__ 191 143 192 if ( str[0] == '0' ) { // radix character ? 144 193 dec = false; 145 194 if ( checkX( str[1] ) ) { // hex constant ? 146 sscanf( (char *)str.c_str(), "%llx", &v ); 195 if ( type < 5 ) { // not L128 ? 196 sscanf( (char *)str.c_str(), "%llx", &v ); 197 } else { // hex int128 constant 198 unsigned int len = str.length(); 199 if ( len > (2 + 16 + 16) ) SemanticError( yylloc, "128-bit hexadecimal constant to large " + str ); 200 if ( len <= (2 + 16) ) goto FHEX1; // hex digits < 2^64 201 str2 = "0x" + str.substr( len - 16 ); 202 sscanf( (char *)str2.c_str(), "%llx", &v2 ); 203 str = str.substr( 0, len - 16 ); 204 FHEX1: ; 205 sscanf( (char *)str.c_str(), "%llx", &v ); 206 } // if 147 207 //printf( "%llx %llu\n", v, v ); 148 208 } else if ( checkB( str[1] ) ) { // binary constant ? 149 v = 0; // compute value 150 for ( unsigned int i = 2;; ) { // ignore prefix 151 if ( str[i] == '1' ) v |= 1; 152 i += 1; 153 if ( i == last - 1 || (str[i] != '0' && str[i] != '1') ) break; 154 v <<= 1; 155 } // for 209 unsigned int len = str.length(); 210 if ( type == 5 && len > 2 + 64 ) { 211 if ( len > 2 + 64 + 64 ) SemanticError( yylloc, "128-bit binary constant to large " + str ); 212 str2 = "0b" + str.substr( len - 64 ); 213 str = str.substr( 0, len - 64 ); 214 scanbin( str2, v2 ); 215 } // if 216 scanbin( str, v ); 156 217 //printf( "%#llx %llu\n", v, v ); 157 218 } else { // octal constant 158 sscanf( (char *)str.c_str(), "%llo", &v ); 219 if ( type < 5 ) { // not L128 ? 220 sscanf( (char *)str.c_str(), "%llo", &v ); 221 #if defined(__SIZEOF_INT128__) 222 } else { // octal int128 constant 223 unsigned int len = str.length(); 224 if ( len > 1 + 43 || (len == 1 + 43 && str[0] > '3') ) SemanticError( yylloc, "128-bit octal constant to large " + str ); 225 if ( len <= 1 + 21 ) { // value < 21 octal digitis 226 sscanf( (char *)str.c_str(), "%llo", &v ); // leave value in octal 227 } else { 228 sscanf( &str[len - 21], "%llo", &v ); 229 __int128 val = v; // accumulate bits 230 str[len - 21] ='\0'; // shorten string 231 sscanf( &str[len == 43 ? 1 : 0], "%llo", &v ); 232 val |= (__int128)v << 63; // store bits 233 if ( len == 1 + 43 ) { // most significant 2 bits ? 234 str[2] = '\0'; // shorten string 235 sscanf( &str[1], "%llo", &v ); // process most significant 2 bits 236 val |= (__int128)v << 126; // store bits 237 } // if 238 v = val >> 64; v2 = (uint64_t)val; // replace octal constant with 2 hex constants 239 char buf[32]; 240 sprintf( buf, "%#llx", v2 ); 241 str2 = buf; 242 sprintf( buf, "%#llx", v ); 243 str = buf; 244 } // if 245 #endif // __SIZEOF_INT128__ 246 } // if 159 247 //printf( "%#llo %llu\n", v, v ); 160 248 } // if 161 249 } else { // decimal constant ? 162 sscanf( (char *)str.c_str(), "%llu", &v ); 250 if ( type < 5 ) { // not L128 ? 251 sscanf( (char *)str.c_str(), "%llu", &v ); 252 #if defined(__SIZEOF_INT128__) 253 } else { // decimal int128 constant 254 #define P10_UINT64 10'000'000'000'000'000'000ULL // 19 zeroes 255 unsigned int len = str.length(); 256 if ( str.length() == 39 && str > (Unsigned ? "340282366920938463463374607431768211455" : "170141183460469231731687303715884105727") ) 257 SemanticError( yylloc, "128-bit decimal constant to large " + str ); 258 if ( len <= 19 ) { // value < 19 decimal digitis 259 sscanf( (char *)str.c_str(), "%llu", &v ); // leave value in decimal 260 } else { 261 sscanf( &str[len - 19], "%llu", &v ); 262 __int128 val = v; // accumulate bits 263 str[len - 19] ='\0'; // shorten string 264 sscanf( &str[len == 39 ? 1 : 0], "%llu", &v ); 265 val += (__int128)v * (__int128)P10_UINT64; // store bits 266 if ( len == 39 ) { // most significant 2 bits ? 267 str[1] = '\0'; // shorten string 268 sscanf( &str[0], "%llu", &v ); // process most significant 2 bits 269 val += (__int128)v * (__int128)P10_UINT64 * (__int128)P10_UINT64; // store bits 270 } // if 271 v = val >> 64; v2 = (uint64_t)val; // replace decimal constant with 2 hex constants 272 char buf[32]; 273 sprintf( buf, "%#llx", v2 ); 274 str2 = buf; 275 sprintf( buf, "%#llx", v ); 276 str = buf; 277 } // if 278 #endif // __SIZEOF_INT128__ 279 } // if 163 280 //printf( "%llu\n", v ); 164 281 } // if 165 282 166 string::size_type posn; 167 168 if ( isdigit( str[last] ) ) { // no suffix ? 169 lnthSuffix( str, type, ltype ); // could have length suffix 170 if ( type == -1 ) { // no suffix 171 valueToType( v, dec, type, Unsigned ); 172 } // if 173 } else { 174 // At least one digit in integer constant, so safe to backup while looking for suffix. 175 176 posn = str.find_last_of( "pP" ); 177 if ( posn != string::npos ) { valueToType( v, dec, type, Unsigned ); ltype = 5; str.erase( posn, 1 ); goto FINI; } 178 179 posn = str.find_last_of( "zZ" ); 180 if ( posn != string::npos ) { Unsigned = true; type = 2; ltype = 4; str.erase( posn, 1 ); goto FINI; } 181 182 // 'u' can appear before or after length suffix 183 if ( str.find_last_of( "uU" ) != string::npos ) Unsigned = true; 184 185 posn = str.rfind( "hh" ); 186 if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; } 187 188 posn = str.rfind( "HH" ); 189 if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; } 190 191 posn = str.find_last_of( "hH" ); 192 if ( posn != string::npos ) { type = 0; str.erase( posn, 1 ); goto FINI; } 193 194 posn = str.find_last_of( "nN" ); 195 if ( posn != string::npos ) { type = 2; str.erase( posn, 1 ); goto FINI; } 196 197 if ( str.rfind( "ll" ) != string::npos || str.rfind( "LL" ) != string::npos ) { type = 4; goto FINI; } 198 199 lnthSuffix( str, type, ltype ); // must be after check for "ll" 200 if ( type == -1 ) { // only 'u' suffix ? 201 valueToType( v, dec, type, Unsigned ); 202 } // if 203 FINI: ; 204 } // if 283 if ( type == -1 ) { // no suffix => determine type from value size 284 valueToType( v, dec, type, Unsigned ); 285 } // if 286 /* printf( "%s %llo %s %llo\n", str.c_str(), v, str2.c_str(), v2 ); */ 205 287 206 288 //if ( !( 0 <= type && type <= 6 ) ) { printf( "%s %lu %d %s\n", fred.c_str(), fred.length(), type, str.c_str() ); } … … 214 296 } else if ( ltype != -1 ) { // explicit length ? 215 297 if ( ltype == 6 ) { // int128, (int128)constant 216 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false ); 298 // ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false ); 299 ret2 = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::LongLongSignedInt ), str2, v2 ) ); 300 ret = build_compoundLiteral( DeclarationNode::newBasicType( DeclarationNode::Int128 )->addType( DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ), 301 new InitializerNode( (InitializerNode *)(new InitializerNode( new ExpressionNode( v2 == 0 ? ret2 : ret ) ))->set_last( new InitializerNode( new ExpressionNode( v2 == 0 ? ret : ret2 ) ) ), true ) ); 217 302 } else { // explicit length, (length_type)constant 218 303 ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][ltype], false ), false ); … … 342 427 if ( str[1] == '8' ) goto Default; // utf-8 characters => array of char 343 428 // lookup type of associated typedef 344 strtype = new TypeInstType( Type::Qualifiers( Type::Const), "char16_t", false );429 strtype = new TypeInstType( Type::Qualifiers( ), "char16_t", false ); 345 430 break; 346 431 case 'U': 347 strtype = new TypeInstType( Type::Qualifiers( Type::Const), "char32_t", false );432 strtype = new TypeInstType( Type::Qualifiers( ), "char32_t", false ); 348 433 break; 349 434 case 'L': 350 strtype = new TypeInstType( Type::Qualifiers( Type::Const), "wchar_t", false );435 strtype = new TypeInstType( Type::Qualifiers( ), "wchar_t", false ); 351 436 break; 352 437 Default: // char default string type 353 438 default: 354 strtype = new BasicType( Type::Qualifiers( Type::Const), BasicType::Char );439 strtype = new BasicType( Type::Qualifiers( ), BasicType::Char ); 355 440 } // switch 356 441 ArrayType * at = new ArrayType( noQualifiers, strtype, -
src/Parser/ParseNode.h
r07d867b r22f94a4 10 10 // Created On : Sat May 16 13:28:16 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Feb 7 17:56:02 202013 // Update Count : 89 112 // Last Modified On : Mon Jul 6 09:33:32 2020 13 // Update Count : 892 14 14 // 15 15 … … 86 86 class InitializerNode : public ParseNode { 87 87 public: 88 InitializerNode( ExpressionNode *, bool aggrp = false, 88 InitializerNode( ExpressionNode *, bool aggrp = false, ExpressionNode * des = nullptr ); 89 89 InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr ); 90 90 InitializerNode( bool isDelete ); -
src/Parser/module.mk
r07d867b r22f94a4 17 17 BUILT_SOURCES = Parser/parser.hh 18 18 19 AM_YFLAGS = -d -t -v 19 AM_YFLAGS = -d -t -v -Wno-yacc 20 20 21 21 SRC += \ -
src/Parser/parser.yy
r07d867b r22f94a4 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Apr 27 12:25:42202013 // Update Count : 4 48312 // Last Modified On : Thu May 28 12:11:45 2020 13 // Update Count : 4500 14 14 // 15 15 … … 329 329 %type<en> conditional_expression constant_expression assignment_expression assignment_expression_opt 330 330 %type<en> comma_expression comma_expression_opt 331 %type<en> argument_expression_list argument_expression default_initialize_opt331 %type<en> argument_expression_list_opt argument_expression default_initialize_opt 332 332 %type<ifctl> if_control_expression 333 333 %type<fctl> for_control_expression for_control_expression_list … … 624 624 // equivalent to the old x[i,j]. 625 625 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); } 626 | postfix_expression '{' argument_expression_list '}' // CFA, constructor call626 | postfix_expression '{' argument_expression_list_opt '}' // CFA, constructor call 627 627 { 628 628 Token fn; … … 630 630 $$ = new ExpressionNode( new ConstructorExpr( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) ); 631 631 } 632 | postfix_expression '(' argument_expression_list ')'632 | postfix_expression '(' argument_expression_list_opt ')' 633 633 { $$ = new ExpressionNode( build_func( $1, $3 ) ); } 634 634 | postfix_expression '`' identifier // CFA, postfix call … … 662 662 | '(' type_no_function ')' '@' '{' initializer_list_opt comma_opt '}' // CFA, explicit C compound-literal 663 663 { $$ = new ExpressionNode( build_compoundLiteral( $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); } 664 | '^' primary_expression '{' argument_expression_list '}' // CFA, destructor call664 | '^' primary_expression '{' argument_expression_list_opt '}' // CFA, destructor call 665 665 { 666 666 Token fn; … … 670 670 ; 671 671 672 argument_expression_list :672 argument_expression_list_opt: 673 673 // empty 674 674 { $$ = nullptr; } 675 675 | argument_expression 676 | argument_expression_list ',' argument_expression676 | argument_expression_list_opt ',' argument_expression 677 677 { $$ = (ExpressionNode *)($1->set_last( $3 )); } 678 678 ; … … 1196 1196 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), 1197 1197 OperKinds::LThan, $1->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1198 | '=' comma_expression 1198 | '=' comma_expression // CFA 1199 1199 { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), 1200 1200 OperKinds::LEThan, $2->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } … … 1203 1203 | comma_expression inclexcl comma_expression '~' comma_expression // CFA 1204 1204 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, $5 ); } 1205 | comma_expression ';' // CFA 1206 { $$ = forCtrl( new ExpressionNode( build_constantInteger( *new string( "0u" ) ) ), $1, nullptr, OperKinds::LThan, nullptr, nullptr ); } 1205 1207 | comma_expression ';' comma_expression // CFA 1206 1208 { $$ = forCtrl( $3, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), 1207 1209 OperKinds::LThan, $3->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1208 | comma_expression ';' '=' comma_expression 1210 | comma_expression ';' '=' comma_expression // CFA 1209 1211 { $$ = forCtrl( $4, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), 1210 1212 OperKinds::LEThan, $4->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } … … 1304 1306 // If MUTEX becomes a general qualifier, there are shift/reduce conflicts, so change syntax to "with mutex". 1305 1307 mutex_statement: 1306 MUTEX '(' argument_expression_list ')' statement1308 MUTEX '(' argument_expression_list_opt ')' statement 1307 1309 { SemanticError( yylloc, "Mutex statement is currently unimplemented." ); $$ = nullptr; } 1308 1310 ; … … 1321 1323 WAITFOR '(' cast_expression ')' 1322 1324 { $$ = $3; } 1323 // | WAITFOR '(' cast_expression ',' argument_expression_list ')'1325 // | WAITFOR '(' cast_expression ',' argument_expression_list_opt ')' 1324 1326 // { $$ = (ExpressionNode *)$3->set_last( $5 ); } 1325 | WAITFOR '(' cast_expression_list ':' argument_expression_list ')'1327 | WAITFOR '(' cast_expression_list ':' argument_expression_list_opt ')' 1326 1328 { $$ = (ExpressionNode *)($3->set_last( $5 )); } 1327 1329 ; … … 1330 1332 cast_expression 1331 1333 | cast_expression_list ',' cast_expression 1332 { $$ = (ExpressionNode *)($1->set_last( $3 )); } 1334 // { $$ = (ExpressionNode *)($1->set_last( $3 )); } 1335 { SemanticError( yylloc, "List of mutex member is currently unimplemented." ); $$ = nullptr; } 1333 1336 ; 1334 1337 … … 2095 2098 2096 2099 aggregate_control: // CFA 2097 GENERATOR 2100 MONITOR 2101 { yyy = true; $$ = AggregateDecl::Monitor; } 2102 | MUTEX STRUCT 2103 { yyy = true; $$ = AggregateDecl::Monitor; } 2104 | GENERATOR 2098 2105 { yyy = true; $$ = AggregateDecl::Generator; } 2099 | M ONITORGENERATOR2106 | MUTEX GENERATOR 2100 2107 { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2101 2108 | COROUTINE 2102 2109 { yyy = true; $$ = AggregateDecl::Coroutine; } 2103 | MONITOR 2104 { yyy = true; $$ = AggregateDecl::Monitor; } 2105 | MONITOR COROUTINE 2110 | MUTEX COROUTINE 2106 2111 { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2107 2112 | THREAD 2108 2113 { yyy = true; $$ = AggregateDecl::Thread; } 2109 | M ONITORTHREAD2114 | MUTEX THREAD 2110 2115 { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2111 2116 ; … … 2774 2779 | attr_name 2775 2780 { $$ = DeclarationNode::newAttribute( $1 ); } 2776 | attr_name '(' argument_expression_list ')'2781 | attr_name '(' argument_expression_list_opt ')' 2777 2782 { $$ = DeclarationNode::newAttribute( $1, $3 ); } 2778 2783 ; -
src/ResolvExpr/AlternativeFinder.cc
r07d867b r22f94a4 1216 1216 unify( castExpr->result, alt.expr->result, alt.env, needAssertions, 1217 1217 haveAssertions, openVars, indexer ); 1218 Cost thisCost = castCost( alt.expr->result, castExpr->result, alt.expr->get_lvalue(), 1219 indexer, alt.env ); 1218 Cost thisCost = 1219 castExpr->isGenerated 1220 ? conversionCost( alt.expr->result, castExpr->result, alt.expr->get_lvalue(), indexer, alt.env ) 1221 : castCost( alt.expr->result, castExpr->result, alt.expr->get_lvalue(), indexer, alt.env ); 1220 1222 PRINT( 1221 1223 std::cerr << "working on cast with result: " << castExpr->result << std::endl; … … 1698 1700 1699 1701 // unification run for side-effects 1700 unify( toType, alt.expr->result, newEnv, need, have, openVars, indexer ); 1702 bool canUnify = unify( toType, alt.expr->result, newEnv, need, have, openVars, indexer ); 1703 (void) canUnify; 1701 1704 // xxx - do some inspecting on this line... why isn't result bound to initAlt.type? 1702 1705 1703 Cost thisCost = c astCost( alt.expr->result, toType, alt.expr->get_lvalue(),1706 Cost thisCost = computeConversionCost( alt.expr->result, toType, alt.expr->get_lvalue(), 1704 1707 indexer, newEnv ); 1708 1709 PRINT( 1710 Cost legacyCost = castCost( alt.expr->result, toType, alt.expr->get_lvalue(), 1711 indexer, newEnv ); 1712 std::cerr << "Considering initialization:"; 1713 std::cerr << std::endl << " FROM: "; alt.expr->result->print(std::cerr); 1714 std::cerr << std::endl << " TO: "; toType ->print(std::cerr); 1715 std::cerr << std::endl << " Unification " << (canUnify ? "succeeded" : "failed"); 1716 std::cerr << std::endl << " Legacy cost " << legacyCost; 1717 std::cerr << std::endl << " New cost " << thisCost; 1718 std::cerr << std::endl; 1719 ) 1720 1705 1721 if ( thisCost != Cost::infinity ) { 1706 1722 // count one safe conversion for each value that is thrown away -
src/ResolvExpr/ConversionCost.cc
r07d867b r22f94a4 10 10 // Created On : Sun May 17 07:06:19 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Oct 4 14:45:00 201912 // Last Modified On : Wed Jul 29 16:11:00 2020 13 13 // Update Count : 28 14 14 // … … 392 392 void ConversionCost::postvisit( const FunctionType * ) {} 393 393 394 void ConversionCost::postvisit( const StructInstType * inst ) {395 /*396 if ( const StructInstType * destAsInst = dynamic_cast< const StructInstType * >( dest ) ) {397 if ( inst->name == destAsInst->name ) {398 cost = Cost::zero;399 } // if400 } // if401 */402 }403 404 void ConversionCost::postvisit( const UnionInstType * inst ) {405 /*406 if ( const UnionInstType * destAsInst = dynamic_cast< const UnionInstType * >( dest ) ) {407 if ( inst->name == destAsInst->name ) {408 cost = Cost::zero;409 } // if410 } // if411 */412 }413 414 394 void ConversionCost::postvisit( const EnumInstType * ) { 415 395 static Type::Qualifiers q; … … 685 665 } 686 666 687 void ConversionCost_new::postvisit( const ast::StructInstType * structInstType ) {688 /*689 if ( const ast::StructInstType * dstAsInst =690 dynamic_cast< const ast::StructInstType * >( dst ) ) {691 if ( structInstType->name == dstAsInst->name ) {692 cost = Cost::zero;693 }694 }695 */696 }697 698 void ConversionCost_new::postvisit( const ast::UnionInstType * unionInstType ) {699 /*700 if ( const ast::UnionInstType * dstAsInst =701 dynamic_cast< const ast::UnionInstType * >( dst ) ) {702 if ( unionInstType->name == dstAsInst->name ) {703 cost = Cost::zero;704 }705 }706 */707 }708 709 667 void ConversionCost_new::postvisit( const ast::EnumInstType * enumInstType ) { 710 668 (void)enumInstType; -
src/ResolvExpr/ConversionCost.h
r07d867b r22f94a4 10 10 // Created On : Sun May 17 09:37:28 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Oct 4 14:59:00 201912 // Last Modified On : Wed Jul 29 16:12:00 2020 13 13 // Update Count : 7 14 14 // … … 51 51 void postvisit( const ReferenceType * refType ); 52 52 void postvisit( const FunctionType * functionType ); 53 void postvisit( const StructInstType * aggregateUseType );54 void postvisit( const UnionInstType * aggregateUseType );55 53 void postvisit( const EnumInstType * aggregateUseType ); 56 54 void postvisit( const TraitInstType * aggregateUseType ); … … 105 103 void postvisit( const ast::ReferenceType * refType ); 106 104 void postvisit( const ast::FunctionType * functionType ); 107 void postvisit( const ast::StructInstType * structInstType );108 void postvisit( const ast::UnionInstType * unionInstType );109 105 void postvisit( const ast::EnumInstType * enumInstType ); 110 106 void postvisit( const ast::TraitInstType * traitInstType ); -
src/SynTree/Expression.h
r07d867b r22f94a4 206 206 public: 207 207 Expression * arg; 208 bool isGenerated = true; // cast generated implicitly by code generation or explicit in program 208 209 // Inidicates cast is introduced by the CFA type system. 210 // true for casts that the resolver introduces to force a return type 211 // false for casts from user code 212 // false for casts from desugaring advanced CFA features into simpler CFA 213 // example 214 // int * p; // declaration 215 // (float *) p; // use, with subject cast 216 // subject cast isGenerated means we are considering an interpretation with a type mismatch 217 // subject cast not isGenerated means someone in charge wants it that way 218 bool isGenerated = true; 209 219 210 220 CastExpr( Expression * arg, bool isGenerated = true ); -
src/Virtual/ExpandCasts.cc
r07d867b r22f94a4 10 10 // Created On : Mon Jul 24 13:59:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tus Aug 2 14:59:00 201713 // Update Count : 112 // Last Modified On : Fri Jul 31 10:29:00 2020 13 // Update Count : 4 14 14 // 15 15 … … 18 18 #include <cassert> // for assert, assertf 19 19 #include <iterator> // for back_inserter, inserter 20 #include <map> // for map, _Rb_tree_iterator, map<>::ite...21 20 #include <string> // for string, allocator, operator==, ope... 22 #include <utility> // for pair23 21 24 22 #include "Common/PassVisitor.h" // for PassVisitor 23 #include "Common/ScopedMap.h" // for ScopedMap 25 24 #include "Common/SemanticError.h" // for SemanticError 25 #include "SymTab/Mangler.h" // for mangleType 26 26 #include "SynTree/Declaration.h" // for ObjectDecl, StructDecl, FunctionDecl 27 27 #include "SynTree/Expression.h" // for VirtualCastExpr, CastExpr, Address... … … 31 31 32 32 namespace Virtual { 33 34 // Indented until the new ast code gets added. 35 36 /// Maps virtual table types the instance for that type. 37 class VirtualTableMap final { 38 ScopedMap<std::string, ObjectDecl *> vtable_instances; 39 public: 40 void enterScope() { 41 vtable_instances.beginScope(); 42 } 43 void leaveScope() { 44 vtable_instances.endScope(); 45 } 46 47 ObjectDecl * insert( ObjectDecl * vtableDecl ) { 48 std::string const & mangledName = SymTab::Mangler::mangleType( vtableDecl->type ); 49 ObjectDecl *& value = vtable_instances[ mangledName ]; 50 if ( value ) { 51 if ( vtableDecl->storageClasses.is_extern ) { 52 return nullptr; 53 } else if ( ! value->storageClasses.is_extern ) { 54 return value; 55 } 56 } 57 value = vtableDecl; 58 return nullptr; 59 } 60 61 ObjectDecl * lookup( const Type * vtableType ) { 62 std::string const & mangledName = SymTab::Mangler::mangleType( vtableType ); 63 const auto it = vtable_instances.find( mangledName ); 64 return ( vtable_instances.end() == it ) ? nullptr : it->second; 65 } 66 }; 33 67 34 68 /* Currently virtual depends on the rather brittle name matching between … … 39 73 */ 40 74 75 namespace { 76 41 77 std::string get_vtable_name( std::string const & name ) { 42 78 return name + "_vtable"; … … 53 89 std::string get_vtable_inst_name_root( std::string const & name ) { 54 90 return get_vtable_name_root( name.substr(1, name.size() - 10 ) ); 55 }56 57 bool is_vtable_name( std::string const & name ) {58 return (name.substr( name.size() - 7 ) == "_vtable" );59 91 } 60 92 … … 64 96 } 65 97 98 } // namespace 99 66 100 class VirtualCastCore { 67 std::map<std::string, ObjectDecl *> vtable_instances;68 FunctionDecl *vcast_decl;69 StructDecl *pvt_decl;70 71 101 Type * pointer_to_pvt(int level_of_indirection) { 72 102 Type * type = new StructInstType( … … 80 110 public: 81 111 VirtualCastCore() : 82 vtable_instances(), vcast_decl( nullptr ), pvt_decl( nullptr )112 indexer(), vcast_decl( nullptr ), pvt_decl( nullptr ) 83 113 {} 84 114 … … 88 118 89 119 Expression * postmutate( VirtualCastExpr * castExpr ); 120 121 VirtualTableMap indexer; 122 private: 123 FunctionDecl *vcast_decl; 124 StructDecl *pvt_decl; 90 125 }; 91 126 … … 107 142 void VirtualCastCore::premutate( ObjectDecl * objectDecl ) { 108 143 if ( is_vtable_inst_name( objectDecl->get_name() ) ) { 109 vtable_instances[objectDecl->get_name()] = objectDecl; 110 } 111 } 144 if ( ObjectDecl * existing = indexer.insert( objectDecl ) ) { 145 std::string msg = "Repeated instance of virtual table, original found at: "; 146 msg += existing->location.filename; 147 msg += ":" + toString( existing->location.first_line ); 148 SemanticError( objectDecl->location, msg ); 149 } 150 } 151 } 152 153 namespace { 154 155 /// Better error locations for generated casts. 156 CodeLocation castLocation( const VirtualCastExpr * castExpr ) { 157 if ( castExpr->location.isSet() ) { 158 return castExpr->location; 159 } else if ( castExpr->arg->location.isSet() ) { 160 return castExpr->arg->location; 161 } else if ( castExpr->result->location.isSet() ) { 162 return castExpr->result->location; 163 } else { 164 return CodeLocation(); 165 } 166 } 167 168 [[noreturn]] void castError( const VirtualCastExpr * castExpr, std::string const & message ) { 169 SemanticError( castLocation( castExpr ), message ); 170 } 171 172 /// Get the virtual table type used in a virtual cast. 173 Type * getVirtualTableType( const VirtualCastExpr * castExpr ) { 174 const Type * objectType; 175 if ( auto target = dynamic_cast<const PointerType *>( castExpr->result ) ) { 176 objectType = target->base; 177 } else if ( auto target = dynamic_cast<const ReferenceType *>( castExpr->result ) ) { 178 objectType = target->base; 179 } else { 180 castError( castExpr, "Virtual cast type must be a pointer or reference type." ); 181 } 182 assert( objectType ); 183 184 const StructInstType * structType = dynamic_cast<const StructInstType *>( objectType ); 185 if ( nullptr == structType ) { 186 castError( castExpr, "Virtual cast type must refer to a structure type." ); 187 } 188 const StructDecl * structDecl = structType->baseStruct; 189 assert( structDecl ); 190 191 const ObjectDecl * fieldDecl = nullptr; 192 if ( 0 < structDecl->members.size() ) { 193 const Declaration * memberDecl = structDecl->members.front(); 194 assert( memberDecl ); 195 fieldDecl = dynamic_cast<const ObjectDecl *>( memberDecl ); 196 if ( fieldDecl && fieldDecl->name != "virtual_table" ) { 197 fieldDecl = nullptr; 198 } 199 } 200 if ( nullptr == fieldDecl ) { 201 castError( castExpr, "Virtual cast type must have a leading virtual_table field." ); 202 } 203 const PointerType * fieldType = dynamic_cast<const PointerType *>( fieldDecl->type ); 204 if ( nullptr == fieldType ) { 205 castError( castExpr, "Virtual cast type virtual_table field is not a pointer." ); 206 } 207 assert( fieldType->base ); 208 auto virtualStructType = dynamic_cast<const StructInstType *>( fieldType->base ); 209 assert( virtualStructType ); 210 211 // Here is the type, but if it is polymorphic it will have lost information. 212 // (Always a clone so that it may always be deleted.) 213 StructInstType * virtualType = virtualStructType->clone(); 214 if ( ! structType->parameters.empty() ) { 215 deleteAll( virtualType->parameters ); 216 virtualType->parameters.clear(); 217 cloneAll( structType->parameters, virtualType->parameters ); 218 } 219 return virtualType; 220 } 221 222 } // namespace 112 223 113 224 Expression * VirtualCastCore::postmutate( VirtualCastExpr * castExpr ) { 114 assertf( castExpr-> get_result(), "Virtual Cast target not found before expansion." );225 assertf( castExpr->result, "Virtual Cast target not found before expansion." ); 115 226 116 227 assert( vcast_decl ); 117 228 assert( pvt_decl ); 118 229 119 // May only cast to a pointer or reference type. 120 // A earlier validation should give a syntax error, this is 121 // just to make sure errors don't creep during translation. 122 // Move to helper with more detailed error messages. 123 PointerType * target_type = 124 dynamic_cast<PointerType *>( castExpr->get_result() ); 125 assert( target_type ); 126 127 StructInstType * target_struct = 128 dynamic_cast<StructInstType *>( target_type->get_base() ); 129 assert( target_struct ); 130 131 StructDecl * target_decl = target_struct->get_baseStruct(); 132 133 std::map<std::string, ObjectDecl *>::iterator found = 134 vtable_instances.find( 135 get_vtable_inst_name( target_decl->get_name() ) ); 136 if ( vtable_instances.end() == found ) { 137 assertf( false, "virtual table instance not found." ); 138 } 139 ObjectDecl * table = found->second; 230 const Type * vtable_type = getVirtualTableType( castExpr ); 231 ObjectDecl * table = indexer.lookup( vtable_type ); 232 if ( nullptr == table ) { 233 SemanticError( castLocation( castExpr ), 234 "Could not find virtual table instance." ); 235 } 140 236 141 237 Expression * result = new CastExpr( 142 //new ApplicationExpr(143 //new AddressExpr( new VariableExpr( vcast_decl ) ),144 //new CastExpr( new VariableExpr( vcast_decl ),145 // new PointerType( noQualifiers,146 // vcast_decl->get_type()->clone()147 // )148 // ),149 238 new ApplicationExpr( VariableExpr::functionPointer( vcast_decl ), { 150 239 new CastExpr( … … 163 252 castExpr->set_result( nullptr ); 164 253 delete castExpr; 254 delete vtable_type; 165 255 return result; 166 256 } -
src/main.cc
r07d867b r22f94a4 9 9 // Author : Peter Buhr and Rob Schluntz 10 10 // Created On : Fri May 15 23:12:02 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Feb 8 08:33:50 202013 // Update Count : 63 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue May 19 12:03:00 2020 13 // Update Count : 634 14 14 // 15 15 … … 312 312 } // if 313 313 314 PASS( "Translate Throws", ControlStruct::translateThrows( translationUnit ) ); 314 315 PASS( "Fix Labels", ControlStruct::fixLabels( translationUnit ) ); 315 316 PASS( "Fix Names", CodeGen::fixNames( translationUnit ) ); … … 360 361 PASS( "Expand Unique Expr", Tuples::expandUniqueExpr( translationUnit ) ); // xxx - is this the right place for this? want to expand ASAP so tha, sequent passes don't need to worry about double-visiting a unique expr - needs to go after InitTweak::fix so that copy constructed return declarations are reused 361 362 362 PASS( "Translate EHM" , ControlStruct::translateEHM( translationUnit ) );363 PASS( "Translate Tries" , ControlStruct::translateTries( translationUnit ) ); 363 364 364 365 PASS( "Gen Waitfor" , Concurrency::generateWaitFor( translationUnit ) );
Note: See TracChangeset
for help on using the changeset viewer.