1------------------------------------------------------------------------------ 2-- -- 3-- GNAT COMPILER COMPONENTS -- 4-- -- 5-- P A R . C H 9 -- 6-- -- 7-- B o d y -- 8-- -- 9-- Copyright (C) 1992-2021, Free Software Foundation, Inc. -- 10-- -- 11-- GNAT is free software; you can redistribute it and/or modify it under -- 12-- terms of the GNU General Public License as published by the Free Soft- -- 13-- ware Foundation; either version 3, or (at your option) any later ver- -- 14-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- 15-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- 16-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- 17-- for more details. You should have received a copy of the GNU General -- 18-- Public License distributed with GNAT; see file COPYING3. If not, go to -- 19-- http://www.gnu.org/licenses for a complete copy of the license. -- 20-- -- 21-- GNAT was originally developed by the GNAT team at New York University. -- 22-- Extensive contributions were provided by Ada Core Technologies Inc. -- 23-- -- 24------------------------------------------------------------------------------ 25 26pragma Style_Checks (All_Checks); 27-- Turn off subprogram body ordering check. Subprograms are in order by RM 28-- section rather than alphabetical. 29 30separate (Par) 31package body Ch9 is 32 33 -- Local subprograms, used only in this chapter 34 35 function P_Accept_Alternative return Node_Id; 36 function P_Delay_Alternative return Node_Id; 37 function P_Delay_Relative_Statement return Node_Id; 38 function P_Delay_Until_Statement return Node_Id; 39 function P_Entry_Barrier return Node_Id; 40 function P_Entry_Body_Formal_Part return Node_Id; 41 function P_Entry_Declaration return Node_Id; 42 function P_Entry_Index_Specification return Node_Id; 43 function P_Protected_Definition return Node_Id; 44 function P_Protected_Operation_Declaration_Opt return Node_Id; 45 function P_Protected_Operation_Items return List_Id; 46 function P_Task_Items return List_Id; 47 function P_Task_Definition return Node_Id; 48 49 ----------------------------- 50 -- 9.1 Task (also 10.1.3) -- 51 ----------------------------- 52 53 -- TASK_TYPE_DECLARATION ::= 54 -- task type DEFINING_IDENTIFIER [KNOWN_DISCRIMINANT_PART] 55 -- [ASPECT_SPECIFICATIONS] 56 -- [is [new INTERFACE_LIST with] TASK_DEFINITION]; 57 58 -- SINGLE_TASK_DECLARATION ::= 59 -- task DEFINING_IDENTIFIER 60 -- [ASPECT_SPECIFICATIONS] 61 -- [is [new INTERFACE_LIST with] TASK_DEFINITION]; 62 63 -- TASK_BODY ::= 64 -- task body DEFINING_IDENTIFIER [ASPECT_SPECIFICATIONS] is 65 -- DECLARATIVE_PART 66 -- begin 67 -- HANDLED_SEQUENCE_OF_STATEMENTS 68 -- end [task_IDENTIFIER] 69 70 -- TASK_BODY_STUB ::= 71 -- task body DEFINING_IDENTIFIER is separate 72 -- [ASPECT_SPECIFICATIONS]; 73 74 -- This routine scans out a task declaration, task body, or task stub 75 76 -- The caller has checked that the initial token is TASK and scanned 77 -- past it, so that Token is set to the token after TASK 78 79 -- Error recovery: cannot raise Error_Resync 80 81 function P_Task return Node_Id is 82 Aspect_Sloc : Source_Ptr := No_Location; 83 Name_Node : Node_Id; 84 Task_Node : Node_Id; 85 Task_Sloc : Source_Ptr; 86 87 Dummy_Node : constant Node_Id := New_Node (N_Task_Body, Token_Ptr); 88 -- Placeholder node used to hold legal or prematurely declared aspect 89 -- specifications. Depending on the context, the aspect specifications 90 -- may be moved to a new node. 91 92 begin 93 Push_Scope_Stack; 94 Scopes (Scope.Last).Etyp := E_Name; 95 Scopes (Scope.Last).Ecol := Start_Column; 96 Scopes (Scope.Last).Sloc := Token_Ptr; 97 Scopes (Scope.Last).Lreq := False; 98 Task_Sloc := Prev_Token_Ptr; 99 100 if Token = Tok_Body then 101 Scan; -- past BODY 102 Name_Node := P_Defining_Identifier (C_Is); 103 Scopes (Scope.Last).Labl := Name_Node; 104 Current_Node := Name_Node; 105 106 if Token = Tok_Left_Paren then 107 Error_Msg_SC ("discriminant part not allowed in task body"); 108 Discard_Junk_List (P_Known_Discriminant_Part_Opt); 109 end if; 110 111 if Aspect_Specifications_Present then 112 Aspect_Sloc := Token_Ptr; 113 P_Aspect_Specifications (Dummy_Node, Semicolon => False); 114 end if; 115 116 TF_Is; 117 118 -- Task stub 119 120 if Token = Tok_Separate then 121 Scan; -- past SEPARATE 122 Task_Node := New_Node (N_Task_Body_Stub, Task_Sloc); 123 Set_Defining_Identifier (Task_Node, Name_Node); 124 125 if Has_Aspects (Dummy_Node) then 126 Error_Msg 127 ("aspect specifications must come after SEPARATE", 128 Aspect_Sloc); 129 end if; 130 131 P_Aspect_Specifications (Task_Node, Semicolon => False); 132 TF_Semicolon; 133 Pop_Scope_Stack; -- remove unused entry 134 135 -- Task body 136 137 else 138 Task_Node := New_Node (N_Task_Body, Task_Sloc); 139 Set_Defining_Identifier (Task_Node, Name_Node); 140 141 -- Move the aspect specifications to the body node 142 143 if Has_Aspects (Dummy_Node) then 144 Move_Aspects (From => Dummy_Node, To => Task_Node); 145 end if; 146 147 Parse_Decls_Begin_End (Task_Node); 148 149 -- The statement list of a task body needs to include at least a 150 -- null statement, so if a parsing error produces an empty list, 151 -- patch it now. 152 153 if No (First (Statements 154 (Handled_Statement_Sequence (Task_Node)))) 155 then 156 Set_Statements (Handled_Statement_Sequence (Task_Node), 157 New_List (Make_Null_Statement (Token_Ptr))); 158 end if; 159 end if; 160 161 return Task_Node; 162 163 -- Otherwise we must have a task declaration 164 165 else 166 if Token = Tok_Type then 167 Scan; -- past TYPE 168 Task_Node := New_Node (N_Task_Type_Declaration, Task_Sloc); 169 Name_Node := P_Defining_Identifier; 170 Set_Defining_Identifier (Task_Node, Name_Node); 171 Scopes (Scope.Last).Labl := Name_Node; 172 Current_Node := Name_Node; 173 Set_Discriminant_Specifications 174 (Task_Node, P_Known_Discriminant_Part_Opt); 175 176 else 177 Task_Node := New_Node (N_Single_Task_Declaration, Task_Sloc); 178 Name_Node := P_Defining_Identifier (C_Is); 179 Set_Defining_Identifier (Task_Node, Name_Node); 180 Scopes (Scope.Last).Labl := Name_Node; 181 Current_Node := Name_Node; 182 183 if Token = Tok_Left_Paren then 184 Error_Msg_SC ("discriminant part not allowed for single task"); 185 Discard_Junk_List (P_Known_Discriminant_Part_Opt); 186 end if; 187 end if; 188 189 -- Scan aspect specifications, don't eat the semicolon, since it 190 -- might not be there if we have an IS. 191 192 P_Aspect_Specifications (Task_Node, Semicolon => False); 193 194 -- Parse optional task definition. Note that P_Task_Definition scans 195 -- out the semicolon and possible aspect specifications as well as 196 -- the task definition itself. 197 198 if Token = Tok_Semicolon then 199 200 -- A little check, if the next token after semicolon is Entry, 201 -- then surely the semicolon should really be IS 202 203 Scan; -- past semicolon 204 205 if Token = Tok_Entry then 206 Error_Msg_SP -- CODEFIX 207 ("|"";"" should be IS"); 208 Set_Task_Definition (Task_Node, P_Task_Definition); 209 else 210 Pop_Scope_Stack; -- Remove unused entry 211 end if; 212 213 -- Here we have a task definition 214 215 else 216 TF_Is; -- must have IS if no semicolon 217 218 -- Ada 2005 (AI-345) 219 220 if Token = Tok_New then 221 Scan; -- past NEW 222 223 Error_Msg_Ada_2005_Extension ("task interface"); 224 225 Set_Interface_List (Task_Node, New_List); 226 227 loop 228 Append (P_Qualified_Simple_Name, Interface_List (Task_Node)); 229 exit when Token /= Tok_And; 230 Scan; -- past AND 231 end loop; 232 233 if Token /= Tok_With then 234 Error_Msg_SC -- CODEFIX 235 ("WITH expected"); 236 end if; 237 238 Scan; -- past WITH 239 240 if Token = Tok_Private then 241 Error_Msg_SP -- CODEFIX 242 ("PRIVATE not allowed in task type declaration"); 243 end if; 244 end if; 245 246 Set_Task_Definition (Task_Node, P_Task_Definition); 247 end if; 248 249 return Task_Node; 250 end if; 251 end P_Task; 252 253 -------------------------------- 254 -- 9.1 Task Type Declaration -- 255 -------------------------------- 256 257 -- Parsed by P_Task (9.1) 258 259 ---------------------------------- 260 -- 9.1 Single Task Declaration -- 261 ---------------------------------- 262 263 -- Parsed by P_Task (9.1) 264 265 -------------------------- 266 -- 9.1 Task Definition -- 267 -------------------------- 268 269 -- TASK_DEFINITION ::= 270 -- {TASK_ITEM} 271 -- [private 272 -- {TASK_ITEM}] 273 -- end [task_IDENTIFIER]; 274 275 -- The caller has already made the scope stack entry 276 277 -- Note: there is a small deviation from official syntax here in that we 278 -- regard the semicolon after end as part of the Task_Definition, and in 279 -- the official syntax, it's part of the enclosing declaration. The reason 280 -- for this deviation is that otherwise the end processing would have to 281 -- be special cased, which would be a nuisance. 282 283 -- Error recovery: cannot raise Error_Resync 284 285 function P_Task_Definition return Node_Id is 286 Def_Node : Node_Id; 287 288 begin 289 Def_Node := New_Node (N_Task_Definition, Token_Ptr); 290 Set_Visible_Declarations (Def_Node, P_Task_Items); 291 292 if Token = Tok_Private then 293 Scan; -- past PRIVATE 294 Set_Private_Declarations (Def_Node, P_Task_Items); 295 296 -- Deal gracefully with multiple PRIVATE parts 297 298 while Token = Tok_Private loop 299 Error_Msg_SC ("only one private part allowed per task"); 300 Scan; -- past PRIVATE 301 Append_List (P_Task_Items, Private_Declarations (Def_Node)); 302 end loop; 303 end if; 304 305 End_Statements (Def_Node); 306 return Def_Node; 307 end P_Task_Definition; 308 309 -------------------- 310 -- 9.1 Task Item -- 311 -------------------- 312 313 -- TASK_ITEM ::= ENTRY_DECLARATION | REPRESENTATION_CLAUSE 314 315 -- This subprogram scans a (possibly empty) list of task items and pragmas 316 317 -- Error recovery: cannot raise Error_Resync 318 319 -- Note: a pragma can also be returned in this position 320 321 function P_Task_Items return List_Id is 322 Items : List_Id; 323 Item_Node : Node_Id; 324 Decl_Sloc : Source_Ptr; 325 326 begin 327 -- Get rid of active SIS entry from outer scope. This means we will 328 -- miss some nested cases, but it doesn't seem worth the effort. See 329 -- discussion in Par for further details 330 331 SIS_Entry_Active := False; 332 333 -- Loop to scan out task items 334 335 Items := New_List; 336 337 Decl_Loop : loop 338 Decl_Sloc := Token_Ptr; 339 340 if Token = Tok_Pragma then 341 P_Pragmas_Opt (Items); 342 343 -- Ada 2005 (AI-397): Reserved words NOT and OVERRIDING may begin an 344 -- entry declaration. 345 346 elsif Token = Tok_Entry 347 or else Token = Tok_Not 348 or else Token = Tok_Overriding 349 then 350 Append (P_Entry_Declaration, Items); 351 352 elsif Token = Tok_For then 353 354 -- Representation clause in task declaration. The only rep clause 355 -- which is legal in a protected declaration is an address clause, 356 -- so that is what we try to scan out. 357 358 Item_Node := P_Representation_Clause; 359 360 if Nkind (Item_Node) = N_At_Clause then 361 Append (Item_Node, Items); 362 363 elsif Nkind (Item_Node) = N_Attribute_Definition_Clause 364 and then Chars (Item_Node) = Name_Address 365 then 366 Append (Item_Node, Items); 367 368 else 369 Error_Msg 370 ("the only representation clause " & 371 "allowed here is an address clause!", Decl_Sloc); 372 end if; 373 374 elsif Token = Tok_Identifier 375 or else Token in Token_Class_Declk 376 then 377 Error_Msg_SC ("illegal declaration in task definition"); 378 Resync_Past_Semicolon; 379 380 else 381 exit Decl_Loop; 382 end if; 383 end loop Decl_Loop; 384 385 return Items; 386 end P_Task_Items; 387 388 -------------------- 389 -- 9.1 Task Body -- 390 -------------------- 391 392 -- Parsed by P_Task (9.1) 393 394 ---------------------------------- 395 -- 9.4 Protected (also 10.1.3) -- 396 ---------------------------------- 397 398 -- PROTECTED_TYPE_DECLARATION ::= 399 -- protected type DEFINING_IDENTIFIER [KNOWN_DISCRIMINANT_PART] 400 -- [ASPECT_SPECIFICATIONS] 401 -- is [new INTERFACE_LIST with] PROTECTED_DEFINITION; 402 403 -- SINGLE_PROTECTED_DECLARATION ::= 404 -- protected DEFINING_IDENTIFIER 405 -- [ASPECT_SPECIFICATIONS] 406 -- is [new INTERFACE_LIST with] PROTECTED_DEFINITION; 407 408 -- PROTECTED_BODY ::= 409 -- protected body DEFINING_IDENTIFIER 410 -- [ASPECT_SPECIFICATIONS] 411 -- is 412 -- {PROTECTED_OPERATION_ITEM} 413 -- end [protected_IDENTIFIER]; 414 415 -- PROTECTED_BODY_STUB ::= 416 -- protected body DEFINING_IDENTIFIER is separate 417 -- [ASPECT_SPECIFICATIONS]; 418 419 -- This routine scans out a protected declaration, protected body 420 -- or a protected stub. 421 422 -- The caller has checked that the initial token is PROTECTED and 423 -- scanned past it, so Token is set to the following token. 424 425 -- Error recovery: cannot raise Error_Resync 426 427 function P_Protected return Node_Id is 428 Aspect_Sloc : Source_Ptr := No_Location; 429 Name_Node : Node_Id; 430 Protected_Node : Node_Id; 431 Protected_Sloc : Source_Ptr; 432 Scan_State : Saved_Scan_State; 433 434 Dummy_Node : constant Node_Id := New_Node (N_Protected_Body, Token_Ptr); 435 -- Placeholder node used to hold legal or prematurely declared aspect 436 -- specifications. Depending on the context, the aspect specifications 437 -- may be moved to a new node. 438 439 begin 440 Push_Scope_Stack; 441 Scopes (Scope.Last).Etyp := E_Name; 442 Scopes (Scope.Last).Ecol := Start_Column; 443 Scopes (Scope.Last).Lreq := False; 444 Protected_Sloc := Prev_Token_Ptr; 445 446 if Token = Tok_Body then 447 Scan; -- past BODY 448 Name_Node := P_Defining_Identifier (C_Is); 449 Scopes (Scope.Last).Labl := Name_Node; 450 Current_Node := Name_Node; 451 452 if Token = Tok_Left_Paren then 453 Error_Msg_SC ("discriminant part not allowed in protected body"); 454 Discard_Junk_List (P_Known_Discriminant_Part_Opt); 455 end if; 456 457 if Aspect_Specifications_Present then 458 Aspect_Sloc := Token_Ptr; 459 P_Aspect_Specifications (Dummy_Node, Semicolon => False); 460 end if; 461 462 TF_Is; 463 464 -- Protected stub 465 466 if Token = Tok_Separate then 467 Scan; -- past SEPARATE 468 469 Protected_Node := New_Node (N_Protected_Body_Stub, Protected_Sloc); 470 Set_Defining_Identifier (Protected_Node, Name_Node); 471 472 if Has_Aspects (Dummy_Node) then 473 Error_Msg 474 ("aspect specifications must come after SEPARATE", 475 Aspect_Sloc); 476 end if; 477 478 P_Aspect_Specifications (Protected_Node, Semicolon => False); 479 TF_Semicolon; 480 Pop_Scope_Stack; -- remove unused entry 481 482 -- Protected body 483 484 else 485 Protected_Node := New_Node (N_Protected_Body, Protected_Sloc); 486 Set_Defining_Identifier (Protected_Node, Name_Node); 487 488 Move_Aspects (From => Dummy_Node, To => Protected_Node); 489 Set_Declarations (Protected_Node, P_Protected_Operation_Items); 490 End_Statements (Protected_Node); 491 end if; 492 493 return Protected_Node; 494 495 -- Otherwise we must have a protected declaration 496 497 else 498 if Token = Tok_Type then 499 Scan; -- past TYPE 500 Protected_Node := 501 New_Node (N_Protected_Type_Declaration, Protected_Sloc); 502 Name_Node := P_Defining_Identifier (C_Is); 503 Set_Defining_Identifier (Protected_Node, Name_Node); 504 Scopes (Scope.Last).Labl := Name_Node; 505 Current_Node := Name_Node; 506 Set_Discriminant_Specifications 507 (Protected_Node, P_Known_Discriminant_Part_Opt); 508 509 else 510 Protected_Node := 511 New_Node (N_Single_Protected_Declaration, Protected_Sloc); 512 Name_Node := P_Defining_Identifier (C_Is); 513 Set_Defining_Identifier (Protected_Node, Name_Node); 514 515 if Token = Tok_Left_Paren then 516 Error_Msg_SC 517 ("discriminant part not allowed for single protected"); 518 Discard_Junk_List (P_Known_Discriminant_Part_Opt); 519 end if; 520 521 Scopes (Scope.Last).Labl := Name_Node; 522 Current_Node := Name_Node; 523 end if; 524 525 P_Aspect_Specifications (Protected_Node, Semicolon => False); 526 527 -- Check for semicolon not followed by IS, this is something like 528 529 -- protected type r; 530 531 -- where we want 532 533 -- protected type r IS END; 534 535 if Token = Tok_Semicolon then 536 Save_Scan_State (Scan_State); -- at semicolon 537 Scan; -- past semicolon 538 539 if Token /= Tok_Is then 540 Restore_Scan_State (Scan_State); 541 Error_Msg_SC -- CODEFIX 542 ("missing IS"); 543 Set_Protected_Definition (Protected_Node, 544 Make_Protected_Definition (Token_Ptr, 545 Visible_Declarations => Empty_List, 546 End_Label => Empty)); 547 548 SIS_Entry_Active := False; 549 End_Statements 550 (Protected_Definition (Protected_Node), Protected_Node); 551 return Protected_Node; 552 end if; 553 554 Error_Msg_SP -- CODEFIX 555 ("|extra ""("" ignored"); 556 end if; 557 558 T_Is; 559 560 -- Ada 2005 (AI-345) 561 562 if Token = Tok_New then 563 Scan; -- past NEW 564 565 Error_Msg_Ada_2005_Extension ("protected interface"); 566 567 Set_Interface_List (Protected_Node, New_List); 568 569 loop 570 Append (P_Qualified_Simple_Name, 571 Interface_List (Protected_Node)); 572 573 exit when Token /= Tok_And; 574 Scan; -- past AND 575 end loop; 576 577 if Token /= Tok_With then 578 Error_Msg_SC -- CODEFIX 579 ("WITH expected"); 580 end if; 581 582 Scan; -- past WITH 583 end if; 584 585 Set_Protected_Definition (Protected_Node, P_Protected_Definition); 586 return Protected_Node; 587 end if; 588 end P_Protected; 589 590 ------------------------------------- 591 -- 9.4 Protected Type Declaration -- 592 ------------------------------------- 593 594 -- Parsed by P_Protected (9.4) 595 596 --------------------------------------- 597 -- 9.4 Single Protected Declaration -- 598 --------------------------------------- 599 600 -- Parsed by P_Protected (9.4) 601 602 ------------------------------- 603 -- 9.4 Protected Definition -- 604 ------------------------------- 605 606 -- PROTECTED_DEFINITION ::= 607 -- {PROTECTED_OPERATION_DECLARATION} 608 -- [private 609 -- {PROTECTED_ELEMENT_DECLARATION}] 610 -- end [protected_IDENTIFIER] 611 612 -- PROTECTED_ELEMENT_DECLARATION ::= 613 -- PROTECTED_OPERATION_DECLARATION 614 -- | COMPONENT_DECLARATION 615 616 -- The caller has already established the scope stack entry 617 618 -- Error recovery: cannot raise Error_Resync 619 620 function P_Protected_Definition return Node_Id is 621 Def_Node : Node_Id; 622 Item_Node : Node_Id; 623 Priv_Decls : List_Id; 624 Vis_Decls : List_Id; 625 626 begin 627 Def_Node := New_Node (N_Protected_Definition, Token_Ptr); 628 629 -- Get rid of active SIS entry from outer scope. This means we will 630 -- miss some nested cases, but it doesn't seem worth the effort. See 631 -- discussion in Par for further details 632 633 SIS_Entry_Active := False; 634 635 -- Loop to scan visible declarations (protected operation declarations) 636 637 Vis_Decls := New_List; 638 Set_Visible_Declarations (Def_Node, Vis_Decls); 639 640 -- Flag and discard all pragmas which cannot appear in the protected 641 -- definition. Note that certain pragmas are still allowed as long as 642 -- they apply to entries, entry families, or protected subprograms. 643 644 P_Pragmas_Opt (Vis_Decls); 645 646 loop 647 Item_Node := P_Protected_Operation_Declaration_Opt; 648 649 if Present (Item_Node) then 650 Append (Item_Node, Vis_Decls); 651 end if; 652 653 P_Pragmas_Opt (Vis_Decls); 654 655 exit when No (Item_Node); 656 end loop; 657 658 -- Deal with PRIVATE part (including graceful handling of multiple 659 -- PRIVATE parts). 660 661 Private_Loop : while Token = Tok_Private loop 662 Priv_Decls := Private_Declarations (Def_Node); 663 664 if Present (Priv_Decls) then 665 Error_Msg_SC ("duplicate private part"); 666 else 667 Priv_Decls := New_List; 668 Set_Private_Declarations (Def_Node, Priv_Decls); 669 end if; 670 671 Scan; -- past PRIVATE 672 673 -- Flag and discard all pragmas which cannot appear in the protected 674 -- definition. Note that certain pragmas are still allowed as long as 675 -- they apply to entries, entry families, or protected subprograms. 676 677 P_Pragmas_Opt (Priv_Decls); 678 679 Declaration_Loop : loop 680 if Token = Tok_Identifier then 681 P_Component_Items (Priv_Decls); 682 P_Pragmas_Opt (Priv_Decls); 683 684 else 685 Item_Node := P_Protected_Operation_Declaration_Opt; 686 687 if Present (Item_Node) then 688 Append (Item_Node, Priv_Decls); 689 end if; 690 691 P_Pragmas_Opt (Priv_Decls); 692 693 exit Declaration_Loop when No (Item_Node); 694 end if; 695 end loop Declaration_Loop; 696 end loop Private_Loop; 697 698 End_Statements (Def_Node); 699 return Def_Node; 700 end P_Protected_Definition; 701 702 ------------------------------------------ 703 -- 9.4 Protected Operation Declaration -- 704 ------------------------------------------ 705 706 -- PROTECTED_OPERATION_DECLARATION ::= 707 -- SUBPROGRAM_DECLARATION 708 -- | ENTRY_DECLARATION 709 -- | REPRESENTATION_CLAUSE 710 711 -- Error recovery: cannot raise Error_Resync 712 713 -- Note: a pragma can also be returned in this position 714 715 -- We are not currently permitting representation clauses to appear as 716 -- protected operation declarations, do we have to rethink this??? 717 718 function P_Protected_Operation_Declaration_Opt return Node_Id is 719 L : List_Id; 720 P : Source_Ptr; 721 722 function P_Entry_Or_Subprogram_With_Indicator return Node_Id; 723 -- Ada 2005 (AI-397): Parse an entry or a subprogram with an overriding 724 -- indicator. The caller has checked that the initial token is NOT or 725 -- OVERRIDING. 726 727 ------------------------------------------ 728 -- P_Entry_Or_Subprogram_With_Indicator -- 729 ------------------------------------------ 730 731 function P_Entry_Or_Subprogram_With_Indicator return Node_Id is 732 Decl : Node_Id := Error; 733 Is_Overriding : Boolean := False; 734 Not_Overriding : Boolean := False; 735 736 begin 737 if Token = Tok_Not then 738 Scan; -- past NOT 739 740 if Token = Tok_Overriding then 741 Scan; -- past OVERRIDING 742 Not_Overriding := True; 743 else 744 Error_Msg_SC -- CODEFIX 745 ("OVERRIDING expected!"); 746 end if; 747 748 else 749 Scan; -- past OVERRIDING 750 Is_Overriding := True; 751 end if; 752 753 if Is_Overriding or else Not_Overriding then 754 if Ada_Version < Ada_2005 then 755 Error_Msg_Ada_2005_Extension ("overriding indicator"); 756 757 elsif Token = Tok_Entry then 758 Decl := P_Entry_Declaration; 759 760 Set_Must_Override (Decl, Is_Overriding); 761 Set_Must_Not_Override (Decl, Not_Overriding); 762 763 elsif Token = Tok_Function or else Token = Tok_Procedure then 764 Decl := P_Subprogram (Pf_Decl_Pexp); 765 766 Set_Must_Override (Specification (Decl), Is_Overriding); 767 Set_Must_Not_Override (Specification (Decl), Not_Overriding); 768 769 else 770 Error_Msg_SC -- CODEFIX 771 ("ENTRY, FUNCTION or PROCEDURE expected!"); 772 end if; 773 end if; 774 775 return Decl; 776 end P_Entry_Or_Subprogram_With_Indicator; 777 778 Result : Node_Id := Empty; 779 780 -- Start of processing for P_Protected_Operation_Declaration_Opt 781 782 begin 783 -- This loop runs more than once only when a junk declaration is skipped 784 785 loop 786 case Token is 787 when Tok_Pragma => 788 Result := P_Pragma; 789 exit; 790 791 when Tok_Not 792 | Tok_Overriding 793 => 794 Result := P_Entry_Or_Subprogram_With_Indicator; 795 exit; 796 797 when Tok_Entry => 798 Result := P_Entry_Declaration; 799 exit; 800 801 when Tok_Function 802 | Tok_Procedure 803 => 804 Result := P_Subprogram (Pf_Decl_Pexp); 805 exit; 806 807 when Tok_Identifier => 808 L := New_List; 809 P := Token_Ptr; 810 Skip_Declaration (L); 811 812 if Nkind (First (L)) = N_Object_Declaration then 813 Error_Msg 814 ("component must be declared in private part of " & 815 "protected type", P); 816 else 817 Error_Msg 818 ("illegal declaration in protected definition", P); 819 end if; 820 -- Continue looping 821 822 when Tok_For => 823 Error_Msg_SC 824 ("representation clause not allowed in protected definition"); 825 Resync_Past_Semicolon; 826 -- Continue looping 827 828 when others => 829 if Token in Token_Class_Declk then 830 Error_Msg_SC ("illegal declaration in protected definition"); 831 Resync_Past_Semicolon; 832 833 -- Return now to avoid cascaded messages if next declaration 834 -- is a valid component declaration. 835 836 Result := Error; 837 end if; 838 839 exit; 840 end case; 841 end loop; 842 843 if Nkind (Result) = N_Subprogram_Declaration 844 and then Nkind (Specification (Result)) = 845 N_Procedure_Specification 846 and then Null_Present (Specification (Result)) 847 then 848 Error_Msg_N 849 ("protected operation cannot be a null procedure", 850 Null_Statement (Specification (Result))); 851 end if; 852 853 return Result; 854 end P_Protected_Operation_Declaration_Opt; 855 856 ----------------------------------- 857 -- 9.4 Protected Operation Item -- 858 ----------------------------------- 859 860 -- PROTECTED_OPERATION_ITEM ::= 861 -- SUBPROGRAM_DECLARATION 862 -- | SUBPROGRAM_BODY 863 -- | ENTRY_BODY 864 -- | REPRESENTATION_CLAUSE 865 866 -- This procedure parses and returns a list of protected operation items 867 868 -- We are not currently permitting representation clauses to appear 869 -- as protected operation items, do we have to rethink this??? 870 871 function P_Protected_Operation_Items return List_Id is 872 Item_List : List_Id; 873 874 begin 875 Item_List := New_List; 876 877 loop 878 if Token = Tok_Entry or else Bad_Spelling_Of (Tok_Entry) then 879 Append (P_Entry_Body, Item_List); 880 881 -- If the operation starts with procedure, function, or an overriding 882 -- indicator ("overriding" or "not overriding"), parse a subprogram. 883 884 elsif Token = Tok_Function or else Bad_Spelling_Of (Tok_Function) 885 or else 886 Token = Tok_Procedure or else Bad_Spelling_Of (Tok_Procedure) 887 or else 888 Token = Tok_Overriding or else Bad_Spelling_Of (Tok_Overriding) 889 or else 890 Token = Tok_Not or else Bad_Spelling_Of (Tok_Not) 891 then 892 Append (P_Subprogram (Pf_Decl_Pbod_Pexp), Item_List); 893 894 elsif Token = Tok_Pragma or else Bad_Spelling_Of (Tok_Pragma) then 895 P_Pragmas_Opt (Item_List); 896 897 elsif Token = Tok_Private or else Bad_Spelling_Of (Tok_Private) then 898 Error_Msg_SC ("PRIVATE not allowed in protected body"); 899 Scan; -- past PRIVATE 900 901 elsif Token = Tok_Identifier then 902 Error_Msg_SC ("all components must be declared in spec!"); 903 Resync_Past_Semicolon; 904 905 elsif Token in Token_Class_Declk then 906 Error_Msg_SC ("declaration not allowed in protected body"); 907 Resync_Past_Semicolon; 908 909 else 910 exit; 911 end if; 912 end loop; 913 914 return Item_List; 915 end P_Protected_Operation_Items; 916 917 ------------------------------ 918 -- 9.5.2 Entry Declaration -- 919 ------------------------------ 920 921 -- ENTRY_DECLARATION ::= 922 -- [OVERRIDING_INDICATOR] 923 -- entry DEFINING_IDENTIFIER 924 -- [(DISCRETE_SUBTYPE_DEFINITION)] PARAMETER_PROFILE 925 -- [ASPECT_SPECIFICATIONS]; 926 927 -- The caller has checked that the initial token is ENTRY, NOT or 928 -- OVERRIDING. 929 930 -- Error recovery: cannot raise Error_Resync 931 932 function P_Entry_Declaration return Node_Id is 933 Decl_Node : Node_Id; 934 Scan_State : Saved_Scan_State; 935 936 -- Flags for optional overriding indication. Two flags are needed, 937 -- to distinguish positive and negative overriding indicators from 938 -- the absence of any indicator. 939 940 Is_Overriding : Boolean := False; 941 Not_Overriding : Boolean := False; 942 943 begin 944 -- Ada 2005 (AI-397): Scan leading overriding indicator 945 946 if Token = Tok_Not then 947 Scan; -- past NOT 948 949 if Token = Tok_Overriding then 950 Scan; -- part OVERRIDING 951 Not_Overriding := True; 952 else 953 Error_Msg_SC -- CODEFIX 954 ("OVERRIDING expected!"); 955 end if; 956 957 elsif Token = Tok_Overriding then 958 Scan; -- part OVERRIDING 959 Is_Overriding := True; 960 end if; 961 962 if Is_Overriding or else Not_Overriding then 963 if Ada_Version < Ada_2005 then 964 Error_Msg_Ada_2005_Extension ("overriding indicator"); 965 elsif Token /= Tok_Entry then 966 Error_Msg_SC -- CODEFIX 967 ("ENTRY expected!"); 968 end if; 969 end if; 970 971 Decl_Node := New_Node (N_Entry_Declaration, Token_Ptr); 972 Scan; -- past ENTRY 973 974 Set_Defining_Identifier 975 (Decl_Node, P_Defining_Identifier (C_Left_Paren_Semicolon)); 976 977 -- If left paren, could be (Discrete_Subtype_Definition) or Formal_Part 978 979 if Token = Tok_Left_Paren then 980 Scan; -- past ( 981 982 -- If identifier after left paren, could still be either 983 984 if Token = Tok_Identifier then 985 Save_Scan_State (Scan_State); -- at Id 986 Scan; -- past Id 987 988 -- If comma or colon after Id, must be Formal_Part 989 990 if Token = Tok_Comma or else Token = Tok_Colon then 991 Restore_Scan_State (Scan_State); -- to Id 992 Set_Parameter_Specifications (Decl_Node, P_Formal_Part); 993 994 -- Else if Id without comma or colon, must be discrete subtype 995 -- defn 996 997 else 998 Restore_Scan_State (Scan_State); -- to Id 999 Set_Discrete_Subtype_Definition 1000 (Decl_Node, P_Discrete_Subtype_Definition); 1001 T_Right_Paren; 1002 Set_Parameter_Specifications (Decl_Node, P_Parameter_Profile); 1003 end if; 1004 1005 -- If no Id, must be discrete subtype definition 1006 1007 else 1008 Set_Discrete_Subtype_Definition 1009 (Decl_Node, P_Discrete_Subtype_Definition); 1010 T_Right_Paren; 1011 Set_Parameter_Specifications (Decl_Node, P_Parameter_Profile); 1012 end if; 1013 end if; 1014 1015 if Is_Overriding then 1016 Set_Must_Override (Decl_Node); 1017 elsif Not_Overriding then 1018 Set_Must_Not_Override (Decl_Node); 1019 end if; 1020 1021 -- Error recovery check for illegal return 1022 1023 if Token = Tok_Return then 1024 Error_Msg_SC ("entry cannot have return value!"); 1025 Scan; 1026 Discard_Junk_Node (P_Subtype_Indication); 1027 end if; 1028 1029 -- Error recovery check for improper use of entry barrier in spec 1030 1031 if Token = Tok_When then 1032 Error_Msg_SC ("barrier not allowed here (belongs in body)"); 1033 Scan; -- past WHEN; 1034 Discard_Junk_Node (P_Expression_No_Right_Paren); 1035 end if; 1036 1037 P_Aspect_Specifications (Decl_Node); 1038 return Decl_Node; 1039 1040 exception 1041 when Error_Resync => 1042 Resync_Past_Semicolon; 1043 return Error; 1044 end P_Entry_Declaration; 1045 1046 ----------------------------- 1047 -- 9.5.2 Accept Statement -- 1048 ----------------------------- 1049 1050 -- ACCEPT_STATEMENT ::= 1051 -- accept entry_DIRECT_NAME 1052 -- [(ENTRY_INDEX)] PARAMETER_PROFILE [do 1053 -- HANDLED_SEQUENCE_OF_STATEMENTS 1054 -- end [entry_IDENTIFIER]]; 1055 1056 -- The caller has checked that the initial token is ACCEPT 1057 1058 -- Error recovery: cannot raise Error_Resync. If an error occurs, the 1059 -- scan is resynchronized past the next semicolon and control returns. 1060 1061 function P_Accept_Statement return Node_Id is 1062 Scan_State : Saved_Scan_State; 1063 Accept_Node : Node_Id; 1064 Hand_Seq : Node_Id; 1065 1066 begin 1067 Push_Scope_Stack; 1068 Scopes (Scope.Last).Sloc := Token_Ptr; 1069 Scopes (Scope.Last).Ecol := Start_Column; 1070 1071 Accept_Node := New_Node (N_Accept_Statement, Token_Ptr); 1072 Scan; -- past ACCEPT 1073 Scopes (Scope.Last).Labl := Token_Node; 1074 Current_Node := Token_Node; 1075 1076 Set_Entry_Direct_Name (Accept_Node, P_Identifier (C_Do)); 1077 1078 -- Left paren could be (Entry_Index) or Formal_Part, determine which 1079 1080 if Token = Tok_Left_Paren then 1081 Save_Scan_State (Scan_State); -- at left paren 1082 Scan; -- past left paren 1083 1084 -- If first token after left paren not identifier, then Entry_Index 1085 1086 if Token /= Tok_Identifier then 1087 Set_Entry_Index (Accept_Node, P_Expression); 1088 T_Right_Paren; 1089 Set_Parameter_Specifications (Accept_Node, P_Parameter_Profile); 1090 1091 -- First token after left paren is identifier, could be either case 1092 1093 else -- Token = Tok_Identifier 1094 Scan; -- past identifier 1095 1096 -- If identifier followed by comma or colon, must be Formal_Part 1097 1098 if Token = Tok_Comma or else Token = Tok_Colon then 1099 Restore_Scan_State (Scan_State); -- to left paren 1100 Set_Parameter_Specifications (Accept_Node, P_Parameter_Profile); 1101 1102 -- If identifier not followed by comma/colon, must be entry index 1103 1104 else 1105 Restore_Scan_State (Scan_State); -- to left paren 1106 Scan; -- past left paren (again) 1107 Set_Entry_Index (Accept_Node, P_Expression); 1108 T_Right_Paren; 1109 Set_Parameter_Specifications (Accept_Node, P_Parameter_Profile); 1110 end if; 1111 end if; 1112 end if; 1113 1114 -- Scan out DO if present 1115 1116 if Token = Tok_Do then 1117 Scopes (Scope.Last).Etyp := E_Name; 1118 Scopes (Scope.Last).Lreq := False; 1119 Scan; -- past DO 1120 Hand_Seq := P_Handled_Sequence_Of_Statements; 1121 Set_Handled_Statement_Sequence (Accept_Node, Hand_Seq); 1122 End_Statements (Handled_Statement_Sequence (Accept_Node)); 1123 1124 -- Exception handlers not allowed in Ada 95 node 1125 1126 if Present (Exception_Handlers (Hand_Seq)) then 1127 if Ada_Version = Ada_83 then 1128 Error_Msg_N 1129 ("(Ada 83) exception handlers in accept not allowed", 1130 First_Non_Pragma (Exception_Handlers (Hand_Seq))); 1131 end if; 1132 end if; 1133 1134 else 1135 Pop_Scope_Stack; -- discard unused entry 1136 TF_Semicolon; 1137 end if; 1138 1139 return Accept_Node; 1140 1141 -- If error, resynchronize past semicolon 1142 1143 exception 1144 when Error_Resync => 1145 Resync_Past_Semicolon; 1146 Pop_Scope_Stack; -- discard unused entry 1147 return Error; 1148 end P_Accept_Statement; 1149 1150 ------------------------ 1151 -- 9.5.2 Entry Index -- 1152 ------------------------ 1153 1154 -- Parsed by P_Expression (4.4) 1155 1156 -------------------------- 1157 -- 9.5.2 Entry Barrier -- 1158 -------------------------- 1159 1160 -- ENTRY_BARRIER ::= when CONDITION 1161 1162 -- Error_Recovery: cannot raise Error_Resync 1163 1164 function P_Entry_Barrier return Node_Id is 1165 Bnode : Node_Id; 1166 1167 begin 1168 if Token = Tok_When then 1169 Scan; -- past WHEN; 1170 Bnode := P_Expression_No_Right_Paren; 1171 1172 if Token = Tok_Colon_Equal then 1173 Error_Msg_SC -- CODEFIX 1174 ("|"":="" should be ""="""); 1175 Scan; 1176 Bnode := P_Expression_No_Right_Paren; 1177 end if; 1178 1179 else 1180 T_When; -- to give error message 1181 Bnode := Error; 1182 end if; 1183 1184 return Bnode; 1185 end P_Entry_Barrier; 1186 1187 ----------------------- 1188 -- 9.5.2 Entry Body -- 1189 ----------------------- 1190 1191 -- ENTRY_BODY ::= 1192 -- entry DEFINING_IDENTIFIER ENTRY_BODY_FORMAL_PART 1193 -- [ASPECT_SPECIFICATIONS] ENTRY_BARRIER 1194 -- is 1195 -- DECLARATIVE_PART 1196 -- begin 1197 -- HANDLED_SEQUENCE_OF_STATEMENTS 1198 -- end [entry_IDENTIFIER]; 1199 1200 -- The caller has checked that the initial token is ENTRY 1201 1202 -- Error_Recovery: cannot raise Error_Resync 1203 1204 function P_Entry_Body return Node_Id is 1205 Dummy_Node : Node_Id; 1206 Entry_Node : Node_Id; 1207 Formal_Part_Node : Node_Id; 1208 Name_Node : Node_Id; 1209 1210 begin 1211 Push_Scope_Stack; 1212 Entry_Node := New_Node (N_Entry_Body, Token_Ptr); 1213 Scan; -- past ENTRY 1214 1215 Scopes (Scope.Last).Ecol := Start_Column; 1216 Scopes (Scope.Last).Lreq := False; 1217 Scopes (Scope.Last).Etyp := E_Name; 1218 Scopes (Scope.Last).Sloc := Token_Ptr; 1219 1220 Name_Node := P_Defining_Identifier; 1221 Set_Defining_Identifier (Entry_Node, Name_Node); 1222 Scopes (Scope.Last).Labl := Name_Node; 1223 Current_Node := Name_Node; 1224 1225 Formal_Part_Node := P_Entry_Body_Formal_Part; 1226 Set_Entry_Body_Formal_Part (Entry_Node, Formal_Part_Node); 1227 1228 -- Ada 2012 (AI12-0169): Aspect specifications may appear on an entry 1229 -- body immediately after the formal part. Do not parse the aspect 1230 -- specifications directly because the "when" of the entry barrier may 1231 -- be interpreted as a misused "with". 1232 1233 if Token = Tok_With then 1234 P_Aspect_Specifications (Entry_Node, Semicolon => False); 1235 end if; 1236 1237 Set_Condition (Formal_Part_Node, P_Entry_Barrier); 1238 1239 -- Detect an illegal placement of aspect specifications following the 1240 -- entry barrier. 1241 1242 -- entry E ... when Barrier with Aspect is 1243 1244 if Token = Tok_With then 1245 Error_Msg_SC ("aspect specifications must come before entry barrier"); 1246 1247 -- Consume the illegal aspects to allow for parsing to continue 1248 1249 Dummy_Node := New_Node (N_Entry_Body, Sloc (Entry_Node)); 1250 P_Aspect_Specifications (Dummy_Node, Semicolon => False); 1251 end if; 1252 1253 TF_Is; 1254 Parse_Decls_Begin_End (Entry_Node); 1255 1256 return Entry_Node; 1257 end P_Entry_Body; 1258 1259 ----------------------------------- 1260 -- 9.5.2 Entry Body Formal Part -- 1261 ----------------------------------- 1262 1263 -- ENTRY_BODY_FORMAL_PART ::= 1264 -- [(ENTRY_INDEX_SPECIFICATION)] [PARAMETER_PART] 1265 1266 -- Error_Recovery: cannot raise Error_Resync 1267 1268 function P_Entry_Body_Formal_Part return Node_Id is 1269 Fpart_Node : Node_Id; 1270 Scan_State : Saved_Scan_State; 1271 1272 begin 1273 Fpart_Node := New_Node (N_Entry_Body_Formal_Part, Token_Ptr); 1274 1275 -- See if entry index specification present, and if so parse it 1276 1277 if Token = Tok_Left_Paren then 1278 Save_Scan_State (Scan_State); -- at left paren 1279 Scan; -- past left paren 1280 1281 if Token = Tok_For then 1282 Set_Entry_Index_Specification 1283 (Fpart_Node, P_Entry_Index_Specification); 1284 T_Right_Paren; 1285 else 1286 Restore_Scan_State (Scan_State); -- to left paren 1287 end if; 1288 1289 -- Check for (common?) case of left paren omitted before FOR. This 1290 -- is a tricky case, because the corresponding missing left paren 1291 -- can cause real havoc if a formal part is present which gets 1292 -- treated as part of the discrete subtype definition of the 1293 -- entry index specification, so just give error and resynchronize 1294 1295 elsif Token = Tok_For then 1296 T_Left_Paren; -- to give error message 1297 Resync_To_When; 1298 end if; 1299 1300 Set_Parameter_Specifications (Fpart_Node, P_Parameter_Profile); 1301 return Fpart_Node; 1302 end P_Entry_Body_Formal_Part; 1303 1304 -------------------------------------- 1305 -- 9.5.2 Entry Index Specification -- 1306 -------------------------------------- 1307 1308 -- ENTRY_INDEX_SPECIFICATION ::= 1309 -- for DEFINING_IDENTIFIER in DISCRETE_SUBTYPE_DEFINITION 1310 -- [ASPECT_SPECIFICATION] 1311 1312 -- Error recovery: can raise Error_Resync 1313 1314 function P_Entry_Index_Specification return Node_Id is 1315 Iterator_Node : Node_Id; 1316 1317 begin 1318 Iterator_Node := New_Node (N_Entry_Index_Specification, Token_Ptr); 1319 T_For; -- past FOR 1320 Set_Defining_Identifier (Iterator_Node, P_Defining_Identifier (C_In)); 1321 T_In; 1322 Set_Discrete_Subtype_Definition 1323 (Iterator_Node, P_Discrete_Subtype_Definition); 1324 1325 if Token = Tok_With then 1326 P_Aspect_Specifications (Iterator_Node, False); 1327 end if; 1328 1329 return Iterator_Node; 1330 end P_Entry_Index_Specification; 1331 1332 --------------------------------- 1333 -- 9.5.3 Entry Call Statement -- 1334 --------------------------------- 1335 1336 -- Parsed by P_Name (4.1). Within a select, an entry call is parsed 1337 -- by P_Select_Statement (9.7) 1338 1339 ------------------------------ 1340 -- 9.5.4 Requeue Statement -- 1341 ------------------------------ 1342 1343 -- REQUEUE_STATEMENT ::= requeue entry_NAME [with abort]; 1344 1345 -- The caller has checked that the initial token is requeue 1346 1347 -- Error recovery: can raise Error_Resync 1348 1349 function P_Requeue_Statement return Node_Id is 1350 Requeue_Node : Node_Id; 1351 1352 begin 1353 Requeue_Node := New_Node (N_Requeue_Statement, Token_Ptr); 1354 Scan; -- past REQUEUE 1355 Set_Name (Requeue_Node, P_Name); 1356 1357 if Token = Tok_With then 1358 Scan; -- past WITH 1359 T_Abort; 1360 Set_Abort_Present (Requeue_Node, True); 1361 end if; 1362 1363 TF_Semicolon; 1364 return Requeue_Node; 1365 end P_Requeue_Statement; 1366 1367 -------------------------- 1368 -- 9.6 Delay Statement -- 1369 -------------------------- 1370 1371 -- DELAY_STATEMENT ::= 1372 -- DELAY_UNTIL_STATEMENT 1373 -- | DELAY_RELATIVE_STATEMENT 1374 1375 -- The caller has checked that the initial token is DELAY 1376 1377 -- Error recovery: cannot raise Error_Resync 1378 1379 function P_Delay_Statement return Node_Id is 1380 begin 1381 Scan; -- past DELAY 1382 1383 -- The following check for delay until misused in Ada 83 doesn't catch 1384 -- all cases, but it's good enough to catch most of them. 1385 1386 if Token_Name = Name_Until then 1387 Check_95_Keyword (Tok_Until, Tok_Left_Paren); 1388 Check_95_Keyword (Tok_Until, Tok_Identifier); 1389 end if; 1390 1391 if Token = Tok_Until then 1392 return P_Delay_Until_Statement; 1393 else 1394 return P_Delay_Relative_Statement; 1395 end if; 1396 end P_Delay_Statement; 1397 1398 -------------------------------- 1399 -- 9.6 Delay Until Statement -- 1400 -------------------------------- 1401 1402 -- DELAY_UNTIL_STATEMENT ::= delay until delay_EXPRESSION; 1403 1404 -- The caller has checked that the initial token is DELAY, scanned it 1405 -- out and checked that the current token is UNTIL 1406 1407 -- Error recovery: cannot raise Error_Resync 1408 1409 function P_Delay_Until_Statement return Node_Id is 1410 Delay_Node : Node_Id; 1411 1412 begin 1413 Delay_Node := New_Node (N_Delay_Until_Statement, Prev_Token_Ptr); 1414 Scan; -- past UNTIL 1415 Set_Expression (Delay_Node, P_Expression_No_Right_Paren); 1416 TF_Semicolon; 1417 return Delay_Node; 1418 end P_Delay_Until_Statement; 1419 1420 ----------------------------------- 1421 -- 9.6 Delay Relative Statement -- 1422 ----------------------------------- 1423 1424 -- DELAY_RELATIVE_STATEMENT ::= delay delay_EXPRESSION; 1425 1426 -- The caller has checked that the initial token is DELAY, scanned it 1427 -- out and determined that the current token is not UNTIL 1428 1429 -- Error recovery: cannot raise Error_Resync 1430 1431 function P_Delay_Relative_Statement return Node_Id is 1432 Delay_Node : Node_Id; 1433 1434 begin 1435 Delay_Node := New_Node (N_Delay_Relative_Statement, Prev_Token_Ptr); 1436 Set_Expression (Delay_Node, P_Expression_No_Right_Paren); 1437 Check_Simple_Expression_In_Ada_83 (Expression (Delay_Node)); 1438 TF_Semicolon; 1439 return Delay_Node; 1440 end P_Delay_Relative_Statement; 1441 1442 --------------------------- 1443 -- 9.7 Select Statement -- 1444 --------------------------- 1445 1446 -- SELECT_STATEMENT ::= 1447 -- SELECTIVE_ACCEPT 1448 -- | TIMED_ENTRY_CALL 1449 -- | CONDITIONAL_ENTRY_CALL 1450 -- | ASYNCHRONOUS_SELECT 1451 1452 -- SELECTIVE_ACCEPT ::= 1453 -- select 1454 -- [GUARD] 1455 -- SELECT_ALTERNATIVE 1456 -- {or 1457 -- [GUARD] 1458 -- SELECT_ALTERNATIVE 1459 -- [else 1460 -- SEQUENCE_OF_STATEMENTS] 1461 -- end select; 1462 1463 -- GUARD ::= when CONDITION => 1464 1465 -- Note: the guard preceding a select alternative is included as part 1466 -- of the node generated for a selective accept alternative. 1467 1468 -- SELECT_ALTERNATIVE ::= 1469 -- ACCEPT_ALTERNATIVE 1470 -- | DELAY_ALTERNATIVE 1471 -- | TERMINATE_ALTERNATIVE 1472 1473 -- TIMED_ENTRY_CALL ::= 1474 -- select 1475 -- ENTRY_CALL_ALTERNATIVE 1476 -- or 1477 -- DELAY_ALTERNATIVE 1478 -- end select; 1479 1480 -- CONDITIONAL_ENTRY_CALL ::= 1481 -- select 1482 -- ENTRY_CALL_ALTERNATIVE 1483 -- else 1484 -- SEQUENCE_OF_STATEMENTS 1485 -- end select; 1486 1487 -- ENTRY_CALL_ALTERNATIVE ::= 1488 -- ENTRY_CALL_STATEMENT [SEQUENCE_OF_STATEMENTS] 1489 1490 -- ASYNCHRONOUS_SELECT ::= 1491 -- select 1492 -- TRIGGERING_ALTERNATIVE 1493 -- then abort 1494 -- ABORTABLE_PART 1495 -- end select; 1496 1497 -- TRIGGERING_ALTERNATIVE ::= 1498 -- TRIGGERING_STATEMENT [SEQUENCE_OF_STATEMENTS] 1499 1500 -- TRIGGERING_STATEMENT ::= ENTRY_CALL_STATEMENT | DELAY_STATEMENT 1501 1502 -- The caller has checked that the initial token is SELECT 1503 1504 -- Error recovery: can raise Error_Resync 1505 1506 function P_Select_Statement return Node_Id is 1507 Select_Node : Node_Id; 1508 Select_Sloc : Source_Ptr; 1509 Stmnt_Sloc : Source_Ptr; 1510 Ecall_Node : Node_Id; 1511 Alternative : Node_Id; 1512 Select_Pragmas : List_Id; 1513 Alt_Pragmas : List_Id; 1514 Statement_List : List_Id; 1515 Alt_List : List_Id; 1516 Cond_Expr : Node_Id; 1517 Delay_Stmnt : Node_Id; 1518 1519 begin 1520 Push_Scope_Stack; 1521 Scopes (Scope.Last).Etyp := E_Select; 1522 Scopes (Scope.Last).Ecol := Start_Column; 1523 Scopes (Scope.Last).Sloc := Token_Ptr; 1524 Scopes (Scope.Last).Labl := Error; 1525 1526 Select_Sloc := Token_Ptr; 1527 Scan; -- past SELECT 1528 Stmnt_Sloc := Token_Ptr; 1529 Select_Pragmas := P_Pragmas_Opt; 1530 1531 -- If first token after select is designator, then we have an entry 1532 -- call, which must be the start of a conditional entry call, timed 1533 -- entry call or asynchronous select 1534 1535 if Token in Token_Class_Desig then 1536 1537 -- Scan entry call statement 1538 1539 begin 1540 Ecall_Node := P_Name; 1541 1542 -- ?? The following two clauses exactly parallel code in ch5 1543 -- and should be combined sometime 1544 1545 if Nkind (Ecall_Node) = N_Indexed_Component then 1546 declare 1547 Prefix_Node : constant Node_Id := Prefix (Ecall_Node); 1548 Exprs_Node : constant List_Id := Expressions (Ecall_Node); 1549 1550 begin 1551 Change_Node (Ecall_Node, N_Procedure_Call_Statement); 1552 Set_Name (Ecall_Node, Prefix_Node); 1553 Set_Parameter_Associations (Ecall_Node, Exprs_Node); 1554 end; 1555 1556 elsif Nkind (Ecall_Node) = N_Function_Call then 1557 declare 1558 Fname_Node : constant Node_Id := Name (Ecall_Node); 1559 Params_List : constant List_Id := 1560 Parameter_Associations (Ecall_Node); 1561 1562 begin 1563 Change_Node (Ecall_Node, N_Procedure_Call_Statement); 1564 Set_Name (Ecall_Node, Fname_Node); 1565 Set_Parameter_Associations (Ecall_Node, Params_List); 1566 end; 1567 1568 elsif Nkind (Ecall_Node) = N_Identifier 1569 or else Nkind (Ecall_Node) = N_Selected_Component 1570 then 1571 -- Case of a call to a parameterless entry 1572 1573 declare 1574 C_Node : constant Node_Id := 1575 New_Node (N_Procedure_Call_Statement, Stmnt_Sloc); 1576 begin 1577 Set_Name (C_Node, Ecall_Node); 1578 Set_Parameter_Associations (C_Node, No_List); 1579 Ecall_Node := C_Node; 1580 end; 1581 end if; 1582 1583 TF_Semicolon; 1584 1585 exception 1586 when Error_Resync => 1587 Resync_Past_Semicolon; 1588 return Error; 1589 end; 1590 1591 Statement_List := P_Sequence_Of_Statements (SS_Eltm_Ortm_Tatm); 1592 1593 -- OR follows, we have a timed entry call 1594 1595 if Token = Tok_Or then 1596 Scan; -- past OR 1597 Alt_Pragmas := P_Pragmas_Opt; 1598 1599 Select_Node := New_Node (N_Timed_Entry_Call, Select_Sloc); 1600 Set_Entry_Call_Alternative (Select_Node, 1601 Make_Entry_Call_Alternative (Stmnt_Sloc, 1602 Entry_Call_Statement => Ecall_Node, 1603 Pragmas_Before => Select_Pragmas, 1604 Statements => Statement_List)); 1605 1606 -- Only possibility is delay alternative. If we have anything 1607 -- else, give message, and treat as conditional entry call. 1608 1609 if Token /= Tok_Delay then 1610 Error_Msg_SC 1611 ("only allowed alternative in timed entry call is delay!"); 1612 Discard_Junk_List (P_Sequence_Of_Statements (SS_Sreq)); 1613 Set_Delay_Alternative (Select_Node, Error); 1614 1615 else 1616 Set_Delay_Alternative (Select_Node, P_Delay_Alternative); 1617 Set_Pragmas_Before 1618 (Delay_Alternative (Select_Node), Alt_Pragmas); 1619 end if; 1620 1621 -- ELSE follows, we have a conditional entry call 1622 1623 elsif Token = Tok_Else then 1624 Scan; -- past ELSE 1625 Select_Node := New_Node (N_Conditional_Entry_Call, Select_Sloc); 1626 1627 Set_Entry_Call_Alternative (Select_Node, 1628 Make_Entry_Call_Alternative (Stmnt_Sloc, 1629 Entry_Call_Statement => Ecall_Node, 1630 Pragmas_Before => Select_Pragmas, 1631 Statements => Statement_List)); 1632 1633 Set_Else_Statements 1634 (Select_Node, P_Sequence_Of_Statements (SS_Sreq)); 1635 1636 -- Only remaining case is THEN ABORT (asynchronous select) 1637 1638 elsif Token = Tok_Abort then 1639 Select_Node := 1640 Make_Asynchronous_Select (Select_Sloc, 1641 Triggering_Alternative => 1642 Make_Triggering_Alternative (Stmnt_Sloc, 1643 Triggering_Statement => Ecall_Node, 1644 Pragmas_Before => Select_Pragmas, 1645 Statements => Statement_List), 1646 Abortable_Part => P_Abortable_Part); 1647 1648 -- Else error 1649 1650 else 1651 if Ada_Version = Ada_83 then 1652 Error_Msg_BC ("OR or ELSE expected"); 1653 else 1654 Error_Msg_BC ("OR or ELSE or `THEN ABORT` expected"); 1655 end if; 1656 1657 Select_Node := Error; 1658 end if; 1659 1660 End_Statements; 1661 1662 -- Here we have a selective accept or an asynchronous select (first 1663 -- token after SELECT is other than a designator token). 1664 1665 else 1666 -- If we have delay with no guard, could be asynchronous select 1667 1668 if Token = Tok_Delay then 1669 Delay_Stmnt := P_Delay_Statement; 1670 Statement_List := P_Sequence_Of_Statements (SS_Eltm_Ortm_Tatm); 1671 1672 -- Asynchronous select 1673 1674 if Token = Tok_Abort then 1675 Select_Node := 1676 Make_Asynchronous_Select (Select_Sloc, 1677 Triggering_Alternative => 1678 Make_Triggering_Alternative (Stmnt_Sloc, 1679 Triggering_Statement => Delay_Stmnt, 1680 Pragmas_Before => Select_Pragmas, 1681 Statements => Statement_List), 1682 Abortable_Part => P_Abortable_Part); 1683 1684 End_Statements; 1685 return Select_Node; 1686 1687 -- Delay which was not an asynchronous select. Must be a selective 1688 -- accept, and since at least one accept statement is required, 1689 -- we must have at least one OR phrase present. 1690 1691 else 1692 Alt_List := New_List ( 1693 Make_Delay_Alternative (Stmnt_Sloc, 1694 Delay_Statement => Delay_Stmnt, 1695 Pragmas_Before => Select_Pragmas, 1696 Statements => Statement_List)); 1697 T_Or; 1698 Alt_Pragmas := P_Pragmas_Opt; 1699 end if; 1700 1701 -- If not a delay statement, then must be another possibility for 1702 -- a selective accept alternative, or perhaps a guard is present 1703 1704 else 1705 Alt_List := New_List; 1706 Alt_Pragmas := Select_Pragmas; 1707 end if; 1708 1709 Select_Node := New_Node (N_Selective_Accept, Select_Sloc); 1710 Set_Select_Alternatives (Select_Node, Alt_List); 1711 1712 -- Scan out selective accept alternatives. On entry to this loop, 1713 -- we are just past a SELECT or OR token, and any pragmas that 1714 -- immediately follow the SELECT or OR are in Alt_Pragmas. 1715 1716 loop 1717 if Token = Tok_When then 1718 1719 if Present (Alt_Pragmas) then 1720 Error_Msg_SC ("pragmas may not precede guard"); 1721 end if; 1722 1723 Scan; -- past WHEN 1724 Cond_Expr := P_Expression_No_Right_Paren; 1725 T_Arrow; 1726 Alt_Pragmas := P_Pragmas_Opt; 1727 1728 else 1729 Cond_Expr := Empty; 1730 end if; 1731 1732 if Token = Tok_Accept then 1733 Alternative := P_Accept_Alternative; 1734 1735 -- Check for junk attempt at asynchronous select using 1736 -- an Accept alternative as the triggering statement 1737 1738 if Token = Tok_Abort 1739 and then Is_Empty_List (Alt_List) 1740 and then No (Cond_Expr) 1741 then 1742 Error_Msg 1743 ("triggering statement must be entry call or delay", 1744 Sloc (Alternative)); 1745 Scan; -- past junk ABORT 1746 Discard_Junk_List (P_Sequence_Of_Statements (SS_Sreq)); 1747 End_Statements; 1748 return Error; 1749 end if; 1750 1751 elsif Token = Tok_Delay then 1752 Alternative := P_Delay_Alternative; 1753 1754 elsif Token = Tok_Terminate then 1755 Alternative := P_Terminate_Alternative; 1756 1757 else 1758 Error_Msg_SC 1759 ("select alternative (ACCEPT, ABORT, DELAY) expected"); 1760 Alternative := Error; 1761 1762 if Token = Tok_Semicolon then 1763 Scan; -- past junk semicolon 1764 end if; 1765 end if; 1766 1767 -- THEN ABORT at this stage is just junk 1768 1769 if Token = Tok_Abort then 1770 Error_Msg_SP ("misplaced `THEN ABORT`"); 1771 Scan; -- past junk ABORT 1772 Discard_Junk_List (P_Sequence_Of_Statements (SS_Sreq)); 1773 End_Statements; 1774 return Error; 1775 1776 else 1777 if Alternative /= Error then 1778 Set_Condition (Alternative, Cond_Expr); 1779 Set_Pragmas_Before (Alternative, Alt_Pragmas); 1780 Append (Alternative, Alt_List); 1781 end if; 1782 1783 exit when Token /= Tok_Or; 1784 end if; 1785 1786 T_Or; 1787 Alt_Pragmas := P_Pragmas_Opt; 1788 end loop; 1789 1790 if Token = Tok_Else then 1791 Scan; -- past ELSE 1792 Set_Else_Statements 1793 (Select_Node, P_Sequence_Of_Statements (SS_Ortm_Sreq)); 1794 1795 if Token = Tok_Or then 1796 Error_Msg_SC ("select alternative cannot follow else part!"); 1797 end if; 1798 end if; 1799 1800 End_Statements; 1801 end if; 1802 1803 return Select_Node; 1804 end P_Select_Statement; 1805 1806 ----------------------------- 1807 -- 9.7.1 Selective Accept -- 1808 ----------------------------- 1809 1810 -- Parsed by P_Select_Statement (9.7) 1811 1812 ------------------ 1813 -- 9.7.1 Guard -- 1814 ------------------ 1815 1816 -- Parsed by P_Select_Statement (9.7) 1817 1818 ------------------------------- 1819 -- 9.7.1 Select Alternative -- 1820 ------------------------------- 1821 1822 -- SELECT_ALTERNATIVE ::= 1823 -- ACCEPT_ALTERNATIVE 1824 -- | DELAY_ALTERNATIVE 1825 -- | TERMINATE_ALTERNATIVE 1826 1827 -- Note: the guard preceding a select alternative is included as part 1828 -- of the node generated for a selective accept alternative. 1829 1830 -- Error recovery: cannot raise Error_Resync 1831 1832 ------------------------------- 1833 -- 9.7.1 Accept Alternative -- 1834 ------------------------------- 1835 1836 -- ACCEPT_ALTERNATIVE ::= 1837 -- ACCEPT_STATEMENT [SEQUENCE_OF_STATEMENTS] 1838 1839 -- Error_Recovery: Cannot raise Error_Resync 1840 1841 -- Note: the caller is responsible for setting the Pragmas_Before 1842 -- field of the returned N_Terminate_Alternative node. 1843 1844 function P_Accept_Alternative return Node_Id is 1845 Accept_Alt_Node : Node_Id; 1846 1847 begin 1848 Accept_Alt_Node := New_Node (N_Accept_Alternative, Token_Ptr); 1849 Set_Accept_Statement (Accept_Alt_Node, P_Accept_Statement); 1850 1851 -- Note: the reason that we accept THEN ABORT as a terminator for 1852 -- the sequence of statements is for error recovery which allows 1853 -- for misuse of an accept statement as a triggering statement. 1854 1855 Set_Statements 1856 (Accept_Alt_Node, P_Sequence_Of_Statements (SS_Eltm_Ortm_Tatm)); 1857 return Accept_Alt_Node; 1858 end P_Accept_Alternative; 1859 1860 ------------------------------ 1861 -- 9.7.1 Delay Alternative -- 1862 ------------------------------ 1863 1864 -- DELAY_ALTERNATIVE ::= 1865 -- DELAY_STATEMENT [SEQUENCE_OF_STATEMENTS] 1866 1867 -- Error_Recovery: Cannot raise Error_Resync 1868 1869 -- Note: the caller is responsible for setting the Pragmas_Before 1870 -- field of the returned N_Terminate_Alternative node. 1871 1872 function P_Delay_Alternative return Node_Id is 1873 Delay_Alt_Node : Node_Id; 1874 1875 begin 1876 Delay_Alt_Node := New_Node (N_Delay_Alternative, Token_Ptr); 1877 Set_Delay_Statement (Delay_Alt_Node, P_Delay_Statement); 1878 1879 -- Note: the reason that we accept THEN ABORT as a terminator for 1880 -- the sequence of statements is for error recovery which allows 1881 -- for misuse of an accept statement as a triggering statement. 1882 1883 Set_Statements 1884 (Delay_Alt_Node, P_Sequence_Of_Statements (SS_Eltm_Ortm_Tatm)); 1885 return Delay_Alt_Node; 1886 end P_Delay_Alternative; 1887 1888 ---------------------------------- 1889 -- 9.7.1 Terminate Alternative -- 1890 ---------------------------------- 1891 1892 -- TERMINATE_ALTERNATIVE ::= terminate; 1893 1894 -- Error_Recovery: Cannot raise Error_Resync 1895 1896 -- Note: the caller is responsible for setting the Pragmas_Before 1897 -- field of the returned N_Terminate_Alternative node. 1898 1899 function P_Terminate_Alternative return Node_Id is 1900 Terminate_Alt_Node : Node_Id; 1901 1902 begin 1903 Terminate_Alt_Node := New_Node (N_Terminate_Alternative, Token_Ptr); 1904 Scan; -- past TERMINATE 1905 TF_Semicolon; 1906 1907 -- For all other select alternatives, the sequence of statements 1908 -- after the alternative statement will swallow up any pragmas 1909 -- coming in this position. But the terminate alternative has no 1910 -- sequence of statements, so the pragmas here must be treated 1911 -- specially. 1912 1913 Set_Pragmas_After (Terminate_Alt_Node, P_Pragmas_Opt); 1914 return Terminate_Alt_Node; 1915 end P_Terminate_Alternative; 1916 1917 ----------------------------- 1918 -- 9.7.2 Timed Entry Call -- 1919 ----------------------------- 1920 1921 -- Parsed by P_Select_Statement (9.7) 1922 1923 ----------------------------------- 1924 -- 9.7.2 Entry Call Alternative -- 1925 ----------------------------------- 1926 1927 -- Parsed by P_Select_Statement (9.7) 1928 1929 ----------------------------------- 1930 -- 9.7.3 Conditional Entry Call -- 1931 ----------------------------------- 1932 1933 -- Parsed by P_Select_Statement (9.7) 1934 1935 -------------------------------- 1936 -- 9.7.4 Asynchronous Select -- 1937 -------------------------------- 1938 1939 -- Parsed by P_Select_Statement (9.7) 1940 1941 ----------------------------------- 1942 -- 9.7.4 Triggering Alternative -- 1943 ----------------------------------- 1944 1945 -- Parsed by P_Select_Statement (9.7) 1946 1947 --------------------------------- 1948 -- 9.7.4 Triggering Statement -- 1949 --------------------------------- 1950 1951 -- Parsed by P_Select_Statement (9.7) 1952 1953 --------------------------- 1954 -- 9.7.4 Abortable Part -- 1955 --------------------------- 1956 1957 -- ABORTABLE_PART ::= SEQUENCE_OF_STATEMENTS 1958 1959 -- The caller has verified that THEN ABORT is present, and Token is 1960 -- pointing to the ABORT on entry (or if not, then we have an error) 1961 1962 -- Error recovery: cannot raise Error_Resync 1963 1964 function P_Abortable_Part return Node_Id is 1965 Abortable_Part_Node : Node_Id; 1966 1967 begin 1968 Abortable_Part_Node := New_Node (N_Abortable_Part, Token_Ptr); 1969 T_Abort; -- scan past ABORT 1970 1971 if Ada_Version = Ada_83 then 1972 Error_Msg_SP ("(Ada 83) asynchronous select not allowed!"); 1973 end if; 1974 1975 Set_Statements (Abortable_Part_Node, P_Sequence_Of_Statements (SS_Sreq)); 1976 return Abortable_Part_Node; 1977 end P_Abortable_Part; 1978 1979 -------------------------- 1980 -- 9.8 Abort Statement -- 1981 -------------------------- 1982 1983 -- ABORT_STATEMENT ::= abort task_NAME {, task_NAME}; 1984 1985 -- The caller has checked that the initial token is ABORT 1986 1987 -- Error recovery: cannot raise Error_Resync 1988 1989 function P_Abort_Statement return Node_Id is 1990 Abort_Node : Node_Id; 1991 1992 begin 1993 Abort_Node := New_Node (N_Abort_Statement, Token_Ptr); 1994 Scan; -- past ABORT 1995 Set_Names (Abort_Node, New_List); 1996 1997 loop 1998 Append (P_Name, Names (Abort_Node)); 1999 exit when Token /= Tok_Comma; 2000 Scan; -- past comma 2001 end loop; 2002 2003 TF_Semicolon; 2004 return Abort_Node; 2005 end P_Abort_Statement; 2006 2007end Ch9; 2008