OSDN Git Service

2008-03-26 Robert Dewar <dewar@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / par-ch5.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                              P A R . C H 5                               --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 1992-2007, 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
26 pragma Style_Checks (All_Checks);
27 --  Turn off subprogram body ordering check. Subprograms are in order
28 --  by RM section rather than alphabetical
29
30 separate (Par)
31 package body Ch5 is
32
33    --  Local functions, used only in this chapter
34
35    function P_Case_Statement                     return Node_Id;
36    function P_Case_Statement_Alternative         return Node_Id;
37    function P_Condition                          return Node_Id;
38    function P_Exit_Statement                     return Node_Id;
39    function P_Goto_Statement                     return Node_Id;
40    function P_If_Statement                       return Node_Id;
41    function P_Label                              return Node_Id;
42    function P_Loop_Parameter_Specification       return Node_Id;
43    function P_Null_Statement                     return Node_Id;
44
45    function P_Assignment_Statement (LHS : Node_Id)  return Node_Id;
46    --  Parse assignment statement. On entry, the caller has scanned the left
47    --  hand side (passed in as Lhs), and the colon-equal (or some symbol
48    --  taken to be an error equivalent such as equal).
49
50    function P_Begin_Statement (Block_Name : Node_Id := Empty) return Node_Id;
51    --  Parse begin-end statement. If Block_Name is non-Empty on entry, it is
52    --  the N_Identifier node for the label on the block. If Block_Name is
53    --  Empty on entry (the default), then the block statement is unlabeled.
54
55    function P_Declare_Statement (Block_Name : Node_Id := Empty) return Node_Id;
56    --  Parse declare block. If Block_Name is non-Empty on entry, it is
57    --  the N_Identifier node for the label on the block. If Block_Name is
58    --  Empty on entry (the default), then the block statement is unlabeled.
59
60    function P_For_Statement (Loop_Name : Node_Id := Empty) return Node_Id;
61    --  Parse for statement. If Loop_Name is non-Empty on entry, it is
62    --  the N_Identifier node for the label on the loop. If Loop_Name is
63    --  Empty on entry (the default), then the for statement is unlabeled.
64
65    function P_Loop_Statement (Loop_Name : Node_Id := Empty) return Node_Id;
66    --  Parse loop statement. If Loop_Name is non-Empty on entry, it is
67    --  the N_Identifier node for the label on the loop. If Loop_Name is
68    --  Empty on entry (the default), then the loop statement is unlabeled.
69
70    function P_While_Statement (Loop_Name : Node_Id := Empty) return Node_Id;
71    --  Parse while statement. If Loop_Name is non-Empty on entry, it is
72    --  the N_Identifier node for the label on the loop. If Loop_Name is
73    --  Empty on entry (the default), then the while statement is unlabeled.
74
75    function Set_Loop_Block_Name (L : Character) return Name_Id;
76    --  Given a letter 'L' for a loop or 'B' for a block, returns a name
77    --  of the form L_nn or B_nn where nn is a serial number obtained by
78    --  incrementing the variable Loop_Block_Count.
79
80    procedure Then_Scan;
81    --  Scan past THEN token, testing for illegal junk after it
82
83    ---------------------------------
84    -- 5.1  Sequence of Statements --
85    ---------------------------------
86
87    --  SEQUENCE_OF_STATEMENTS ::= STATEMENT {STATEMENT}
88
89    --  STATEMENT ::=
90    --    {LABEL} SIMPLE_STATEMENT | {LABEL} COMPOUND_STATEMENT
91
92    --  SIMPLE_STATEMENT ::=      NULL_STATEMENT
93    --  | ASSIGNMENT_STATEMENT  | EXIT_STATEMENT
94    --  | GOTO_STATEMENT        | PROCEDURE_CALL_STATEMENT
95    --  | RETURN_STATEMENT      | ENTRY_CALL_STATEMENT
96    --  | REQUEUE_STATEMENT     | DELAY_STATEMENT
97    --  | ABORT_STATEMENT       | RAISE_STATEMENT
98    --  | CODE_STATEMENT
99
100    --  COMPOUND_STATEMENT ::=
101    --    IF_STATEMENT         | CASE_STATEMENT
102    --  | LOOP_STATEMENT       | BLOCK_STATEMENT
103    --  | ACCEPT_STATEMENT     | SELECT_STATEMENT
104
105    --  This procedure scans a sequence of statements. The caller sets SS_Flags
106    --  to indicate acceptable termination conditions for the sequence:
107
108    --    SS_Flags.Eftm Terminate on ELSIF
109    --    SS_Flags.Eltm Terminate on ELSE
110    --    SS_Flags.Extm Terminate on EXCEPTION
111    --    SS_Flags.Ortm Terminate on OR
112    --    SS_Flags.Tatm Terminate on THEN ABORT (Token = ABORT on return)
113    --    SS_Flags.Whtm Terminate on WHEN
114    --    SS_Flags.Unco Unconditional terminate after scanning one statement
115
116    --  In addition, the scan is always terminated by encountering END or the
117    --  end of file (EOF) condition. If one of the six above terminators is
118    --  encountered with the corresponding SS_Flags flag not set, then the
119    --  action taken is as follows:
120
121    --    If the keyword occurs to the left of the expected column of the end
122    --    for the current sequence (as recorded in the current end context),
123    --    then it is assumed to belong to an outer context, and is considered
124    --    to terminate the sequence of statements.
125
126    --    If the keyword occurs to the right of, or in the expected column of
127    --    the end for the current sequence, then an error message is output,
128    --    the keyword together with its associated context is skipped, and
129    --    the statement scan continues until another terminator is found.
130
131    --  Note that the first action means that control can return to the caller
132    --  with Token set to a terminator other than one of those specified by the
133    --  SS parameter. The caller should treat such a case as equivalent to END.
134
135    --  In addition, the flag SS_Flags.Sreq is set to True to indicate that at
136    --  least one real statement (other than a pragma) is required in the
137    --  statement sequence. During the processing of the sequence, this
138    --  flag is manipulated to indicate the current status of the requirement
139    --  for a statement. For example, it is turned off by the occurrence of a
140    --  statement, and back on by a label (which requires a following statement)
141
142    --  Error recovery: cannot raise Error_Resync. If an error occurs during
143    --  parsing a statement, then the scan pointer is advanced past the next
144    --  semicolon and the parse continues.
145
146    function P_Sequence_Of_Statements (SS_Flags : SS_Rec) return List_Id is
147
148       Statement_Required : Boolean;
149       --  This flag indicates if a subsequent statement (other than a pragma)
150       --  is required. It is initialized from the Sreq flag, and modified as
151       --  statements are scanned (a statement turns it off, and a label turns
152       --  it back on again since a statement must follow a label).
153
154       Declaration_Found : Boolean := False;
155       --  This flag is set True if a declaration is encountered, so that the
156       --  error message about declarations in the statement part is only
157       --  given once for a given sequence of statements.
158
159       Scan_State_Label : Saved_Scan_State;
160       Scan_State       : Saved_Scan_State;
161
162       Statement_List : List_Id;
163       Block_Label    : Name_Id;
164       Id_Node        : Node_Id;
165       Name_Node      : Node_Id;
166
167       procedure Junk_Declaration;
168       --  Procedure called to handle error of declaration encountered in
169       --  statement sequence.
170
171       procedure Test_Statement_Required;
172       --  Flag error if Statement_Required flag set
173
174       ----------------------
175       -- Junk_Declaration --
176       ----------------------
177
178       procedure Junk_Declaration is
179       begin
180          if (not Declaration_Found) or All_Errors_Mode then
181             Error_Msg_SC ("declarations must come before BEGIN");
182             Declaration_Found := True;
183          end if;
184
185          Skip_Declaration (Statement_List);
186       end Junk_Declaration;
187
188       -----------------------------
189       -- Test_Statement_Required --
190       -----------------------------
191
192       procedure Test_Statement_Required is
193       begin
194          if Statement_Required then
195             Error_Msg_BC ("statement expected");
196          end if;
197       end Test_Statement_Required;
198
199    --  Start of processing for P_Sequence_Of_Statements
200
201    begin
202       Statement_List := New_List;
203       Statement_Required := SS_Flags.Sreq;
204
205       loop
206          Ignore (Tok_Semicolon);
207
208          begin
209             if Style_Check then
210                Style.Check_Indentation;
211             end if;
212
213             --  Deal with reserved identifier (in assignment or call)
214
215             if Is_Reserved_Identifier then
216                Save_Scan_State (Scan_State); -- at possible bad identifier
217                Scan; -- and scan past it
218
219                --  We have an reserved word which is spelled in identifier
220                --  style, so the question is whether it really is intended
221                --  to be an identifier.
222
223                if
224                   --  If followed by a semicolon, then it is an identifier,
225                   --  with the exception of the cases tested for below.
226
227                   (Token = Tok_Semicolon
228                     and then Prev_Token /= Tok_Return
229                     and then Prev_Token /= Tok_Null
230                     and then Prev_Token /= Tok_Raise
231                     and then Prev_Token /= Tok_End
232                     and then Prev_Token /= Tok_Exit)
233
234                   --  If followed by colon, colon-equal, or dot, then we
235                   --  definitely  have an identifier (could not be reserved)
236
237                   or else Token = Tok_Colon
238                   or else Token = Tok_Colon_Equal
239                   or else Token = Tok_Dot
240
241                   --  Left paren means we have an identifier except for those
242                   --  reserved words that can legitimately be followed by a
243                   --  left paren.
244
245                   or else
246                     (Token = Tok_Left_Paren
247                       and then Prev_Token /= Tok_Case
248                       and then Prev_Token /= Tok_Delay
249                       and then Prev_Token /= Tok_If
250                       and then Prev_Token /= Tok_Elsif
251                       and then Prev_Token /= Tok_Return
252                       and then Prev_Token /= Tok_When
253                       and then Prev_Token /= Tok_While
254                       and then Prev_Token /= Tok_Separate)
255                then
256                   --  Here we have an apparent reserved identifier and the
257                   --  token past it is appropriate to this usage (and would
258                   --  be a definite error if this is not an identifier). What
259                   --  we do is to use P_Identifier to fix up the identifier,
260                   --  and then fall into the normal processing.
261
262                   Restore_Scan_State (Scan_State); -- back to the ID
263                   Scan_Reserved_Identifier (Force_Msg => False);
264
265                   --  Not a reserved identifier after all (or at least we can't
266                   --  be sure that it is), so reset the scan and continue.
267
268                else
269                   Restore_Scan_State (Scan_State); -- back to the reserved word
270                end if;
271             end if;
272
273             --  Now look to see what kind of statement we have
274
275             case Token is
276
277                --  Case of end or EOF
278
279                when Tok_End | Tok_EOF =>
280
281                   --  These tokens always terminate the statement sequence
282
283                   Test_Statement_Required;
284                   exit;
285
286                --  Case of ELSIF
287
288                when Tok_Elsif =>
289
290                   --  Terminate if Eftm set or if the ELSIF is to the left
291                   --  of the expected column of the end for this sequence
292
293                   if SS_Flags.Eftm
294                      or else Start_Column < Scope.Table (Scope.Last).Ecol
295                   then
296                      Test_Statement_Required;
297                      exit;
298
299                   --  Otherwise complain and skip past ELSIF Condition then
300
301                   else
302                      Error_Msg_SC ("ELSIF not allowed here");
303                      Scan; -- past ELSIF
304                      Discard_Junk_Node (P_Expression_No_Right_Paren);
305                      Then_Scan;
306                      Statement_Required := False;
307                   end if;
308
309                --  Case of ELSE
310
311                when Tok_Else =>
312
313                   --  Terminate if Eltm set or if the else is to the left
314                   --  of the expected column of the end for this sequence
315
316                   if SS_Flags.Eltm
317                      or else Start_Column < Scope.Table (Scope.Last).Ecol
318                   then
319                      Test_Statement_Required;
320                      exit;
321
322                   --  Otherwise complain and skip past else
323
324                   else
325                      Error_Msg_SC ("ELSE not allowed here");
326                      Scan; -- past ELSE
327                      Statement_Required := False;
328                   end if;
329
330                --  Case of exception
331
332                when Tok_Exception =>
333                   Test_Statement_Required;
334
335                   --  If Extm not set and the exception is not to the left
336                   --  of the expected column of the end for this sequence, then
337                   --  we assume it belongs to the current sequence, even though
338                   --  it is not permitted.
339
340                   if not SS_Flags.Extm and then
341                      Start_Column >= Scope.Table (Scope.Last).Ecol
342
343                   then
344                      Error_Msg_SC ("exception handler not permitted here");
345                      Scan; -- past EXCEPTION
346                      Discard_Junk_List (Parse_Exception_Handlers);
347                   end if;
348
349                   --  Always return, in the case where we scanned out handlers
350                   --  that we did not expect, Parse_Exception_Handlers returned
351                   --  with Token being either end or EOF, so we are OK
352
353                   exit;
354
355                --  Case of OR
356
357                when Tok_Or =>
358
359                   --  Terminate if Ortm set or if the or is to the left
360                   --  of the expected column of the end for this sequence
361
362                   if SS_Flags.Ortm
363                      or else Start_Column < Scope.Table (Scope.Last).Ecol
364                   then
365                      Test_Statement_Required;
366                      exit;
367
368                   --  Otherwise complain and skip past or
369
370                   else
371                      Error_Msg_SC ("OR not allowed here");
372                      Scan; -- past or
373                      Statement_Required := False;
374                   end if;
375
376                --  Case of THEN (deal also with THEN ABORT)
377
378                when Tok_Then =>
379                   Save_Scan_State (Scan_State); -- at THEN
380                   Scan; -- past THEN
381
382                   --  Terminate if THEN ABORT allowed (ATC case)
383
384                   exit when SS_Flags.Tatm and then Token = Tok_Abort;
385
386                   --  Otherwise we treat THEN as some kind of mess where we
387                   --  did not see the associated IF, but we pick up assuming
388                   --  it had been there!
389
390                   Restore_Scan_State (Scan_State); -- to THEN
391                   Append_To (Statement_List, P_If_Statement);
392                   Statement_Required := False;
393
394                --  Case of WHEN (error because we are not in a case)
395
396                when Tok_When | Tok_Others =>
397
398                   --  Terminate if Whtm set or if the WHEN is to the left
399                   --  of the expected column of the end for this sequence
400
401                   if SS_Flags.Whtm
402                      or else Start_Column < Scope.Table (Scope.Last).Ecol
403                   then
404                      Test_Statement_Required;
405                      exit;
406
407                   --  Otherwise complain and skip when Choice {| Choice} =>
408
409                   else
410                      Error_Msg_SC ("WHEN not allowed here");
411                      Scan; -- past when
412                      Discard_Junk_List (P_Discrete_Choice_List);
413                      TF_Arrow;
414                      Statement_Required := False;
415                   end if;
416
417                --  Cases of statements starting with an identifier
418
419                when Tok_Identifier =>
420                   Check_Bad_Layout;
421
422                   --  Save scan pointers and line number in case block label
423
424                   Id_Node := Token_Node;
425                   Block_Label := Token_Name;
426                   Save_Scan_State (Scan_State_Label); -- at possible label
427                   Scan; -- past Id
428
429                   --  Check for common case of assignment, since it occurs
430                   --  frequently, and we want to process it efficiently.
431
432                   if Token = Tok_Colon_Equal then
433                      Scan; -- past the colon-equal
434                      Append_To (Statement_List,
435                        P_Assignment_Statement (Id_Node));
436                      Statement_Required := False;
437
438                   --  Check common case of procedure call, another case that
439                   --  we want to speed up as much as possible.
440
441                   elsif Token = Tok_Semicolon then
442                      Append_To (Statement_List,
443                        P_Statement_Name (Id_Node));
444                      Scan; -- past semicolon
445                      Statement_Required := False;
446
447                   --  Check for case of "go to" in place of "goto"
448
449                   elsif Token = Tok_Identifier
450                     and then Block_Label = Name_Go
451                     and then Token_Name = Name_To
452                   then
453                      Error_Msg_SP ("goto is one word");
454                      Append_To (Statement_List, P_Goto_Statement);
455                      Statement_Required := False;
456
457                   --  Check common case of = used instead of :=, just so we
458                   --  give a better error message for this special misuse.
459
460                   elsif Token = Tok_Equal then
461                      T_Colon_Equal; -- give := expected message
462                      Append_To (Statement_List,
463                        P_Assignment_Statement (Id_Node));
464                      Statement_Required := False;
465
466                   --  Check case of loop label or block label
467
468                   elsif Token = Tok_Colon
469                     or else (Token in Token_Class_Labeled_Stmt
470                               and then not Token_Is_At_Start_Of_Line)
471                   then
472                      T_Colon; -- past colon (if there, or msg for missing one)
473
474                      --  Test for more than one label
475
476                      loop
477                         exit when Token /= Tok_Identifier;
478                         Save_Scan_State (Scan_State); -- at second Id
479                         Scan; -- past Id
480
481                         if Token = Tok_Colon then
482                            Error_Msg_SP
483                               ("only one label allowed on block or loop");
484                            Scan; -- past colon on extra label
485
486                            --  Use the second label as the "real" label
487
488                            Scan_State_Label := Scan_State;
489
490                            --  We will set Error_name as the Block_Label since
491                            --  we really don't know which of the labels might
492                            --  be used at the end of the loop or block!
493
494                            Block_Label := Error_Name;
495
496                         --  If Id with no colon, then backup to point to the
497                         --  Id and we will issue the message below when we try
498                         --  to scan out the statement as some other form.
499
500                         else
501                            Restore_Scan_State (Scan_State); -- to second Id
502                            exit;
503                         end if;
504                      end loop;
505
506                      --  Loop_Statement (labeled Loop_Statement)
507
508                      if Token = Tok_Loop then
509                         Append_To (Statement_List,
510                           P_Loop_Statement (Id_Node));
511
512                      --  While statement (labeled loop statement with WHILE)
513
514                      elsif Token = Tok_While then
515                         Append_To (Statement_List,
516                           P_While_Statement (Id_Node));
517
518                      --  Declare statement (labeled block statement with
519                      --  DECLARE part)
520
521                      elsif Token = Tok_Declare then
522                         Append_To (Statement_List,
523                           P_Declare_Statement (Id_Node));
524
525                      --  Begin statement (labeled block statement with no
526                      --  DECLARE part)
527
528                      elsif Token = Tok_Begin then
529                         Append_To (Statement_List,
530                           P_Begin_Statement (Id_Node));
531
532                      --  For statement (labeled loop statement with FOR)
533
534                      elsif Token = Tok_For then
535                         Append_To (Statement_List,
536                           P_For_Statement (Id_Node));
537
538                      --  Improper statement follows label. If we have an
539                      --  expression token, then assume the colon was part
540                      --  of a misplaced declaration.
541
542                      elsif Token not in Token_Class_Eterm then
543                         Restore_Scan_State (Scan_State_Label);
544                         Junk_Declaration;
545
546                      --  Otherwise complain we have inappropriate statement
547
548                      else
549                         Error_Msg_AP
550                           ("loop or block statement must follow label");
551                      end if;
552
553                      Statement_Required := False;
554
555                   --  Here we have an identifier followed by something
556                   --  other than a colon, semicolon or assignment symbol.
557                   --  The only valid possibility is a name extension symbol
558
559                   elsif Token in Token_Class_Namext then
560                      Restore_Scan_State (Scan_State_Label); -- to Id
561                      Name_Node := P_Name;
562
563                      --  Skip junk right parens in this context
564
565                      Ignore (Tok_Right_Paren);
566
567                      --  Check context following call
568
569                      if Token = Tok_Colon_Equal then
570                         Scan; -- past colon equal
571                         Append_To (Statement_List,
572                           P_Assignment_Statement (Name_Node));
573                         Statement_Required := False;
574
575                      --  Check common case of = used instead of :=
576
577                      elsif Token = Tok_Equal then
578                         T_Colon_Equal; -- give := expected message
579                         Append_To (Statement_List,
580                           P_Assignment_Statement (Name_Node));
581                         Statement_Required := False;
582
583                      --  Check apostrophe cases
584
585                      elsif Token = Tok_Apostrophe then
586                         Append_To (Statement_List,
587                           P_Code_Statement (Name_Node));
588                         Statement_Required := False;
589
590                      --  The only other valid item after a name is ; which
591                      --  means that the item we just scanned was a call.
592
593                      elsif Token = Tok_Semicolon then
594                         Append_To (Statement_List,
595                           P_Statement_Name (Name_Node));
596                         Scan; -- past semicolon
597                         Statement_Required := False;
598
599                      --  A slash following an identifier or a selected
600                      --  component in this situation is most likely a period
601                      --  (see location of keys on keyboard).
602
603                      elsif Token = Tok_Slash
604                        and then (Nkind (Name_Node) = N_Identifier
605                                    or else
606                                  Nkind (Name_Node) = N_Selected_Component)
607                      then
608                         Error_Msg_SC ("""/"" should be "".""");
609                         Statement_Required := False;
610                         raise Error_Resync;
611
612                      --  Else we have a missing semicolon
613
614                      else
615                         TF_Semicolon;
616                         Statement_Required := False;
617                      end if;
618
619                   --  If junk after identifier, check if identifier is an
620                   --  instance of an incorrectly spelled keyword. If so, we
621                   --  do nothing. The Bad_Spelling_Of will have reset Token
622                   --  to the appropriate keyword, so the next time round the
623                   --  loop we will process the modified token. Note that we
624                   --  check for ELSIF before ELSE here. That's not accidental.
625                   --  We don't want to identify a misspelling of ELSE as
626                   --  ELSIF, and in particular we do not want to treat ELSEIF
627                   --  as ELSE IF.
628
629                   else
630                      Restore_Scan_State (Scan_State_Label); -- to identifier
631
632                      if Bad_Spelling_Of (Tok_Abort)
633                        or else Bad_Spelling_Of (Tok_Accept)
634                        or else Bad_Spelling_Of (Tok_Case)
635                        or else Bad_Spelling_Of (Tok_Declare)
636                        or else Bad_Spelling_Of (Tok_Delay)
637                        or else Bad_Spelling_Of (Tok_Elsif)
638                        or else Bad_Spelling_Of (Tok_Else)
639                        or else Bad_Spelling_Of (Tok_End)
640                        or else Bad_Spelling_Of (Tok_Exception)
641                        or else Bad_Spelling_Of (Tok_Exit)
642                        or else Bad_Spelling_Of (Tok_For)
643                        or else Bad_Spelling_Of (Tok_Goto)
644                        or else Bad_Spelling_Of (Tok_If)
645                        or else Bad_Spelling_Of (Tok_Loop)
646                        or else Bad_Spelling_Of (Tok_Or)
647                        or else Bad_Spelling_Of (Tok_Pragma)
648                        or else Bad_Spelling_Of (Tok_Raise)
649                        or else Bad_Spelling_Of (Tok_Requeue)
650                        or else Bad_Spelling_Of (Tok_Return)
651                        or else Bad_Spelling_Of (Tok_Select)
652                        or else Bad_Spelling_Of (Tok_When)
653                        or else Bad_Spelling_Of (Tok_While)
654                      then
655                         null;
656
657                      --  If not a bad spelling, then we really have junk
658
659                      else
660                         Scan; -- past identifier again
661
662                         --  If next token is first token on line, then we
663                         --  consider that we were missing a semicolon after
664                         --  the identifier, and process it as a procedure
665                         --  call with no parameters.
666
667                         if Token_Is_At_Start_Of_Line then
668                            Append_To (Statement_List,
669                              P_Statement_Name (Id_Node));
670                            T_Semicolon; -- to give error message
671                            Statement_Required := False;
672
673                         --  Otherwise we give a missing := message and
674                         --  simply abandon the junk that is there now.
675
676                         else
677                            T_Colon_Equal; -- give := expected message
678                            raise Error_Resync;
679                         end if;
680
681                      end if;
682                   end if;
683
684                --  Statement starting with operator symbol. This could be
685                --  a call, a name starting an assignment, or a qualified
686                --  expression.
687
688                when Tok_Operator_Symbol =>
689                   Check_Bad_Layout;
690                   Name_Node := P_Name;
691
692                   --  An attempt at a range attribute or a qualified expression
693                   --  must be illegal here (a code statement cannot possibly
694                   --  allow qualification by a function name).
695
696                   if Token = Tok_Apostrophe then
697                      Error_Msg_SC ("apostrophe illegal here");
698                      raise Error_Resync;
699                   end if;
700
701                   --  Scan possible assignment if we have a name
702
703                   if Expr_Form = EF_Name
704                     and then Token = Tok_Colon_Equal
705                   then
706                      Scan; -- past colon equal
707                      Append_To (Statement_List,
708                        P_Assignment_Statement (Name_Node));
709                   else
710                      Append_To (Statement_List,
711                        P_Statement_Name (Name_Node));
712                   end if;
713
714                   TF_Semicolon;
715                   Statement_Required := False;
716
717                --  Label starting with << which must precede real statement
718
719                when Tok_Less_Less =>
720                   Append_To (Statement_List, P_Label);
721                   Statement_Required := True;
722
723                --  Pragma appearing as a statement in a statement sequence
724
725                when Tok_Pragma =>
726                   Check_Bad_Layout;
727                   Append_To (Statement_List, P_Pragma);
728
729                --  Abort_Statement
730
731                when Tok_Abort =>
732                   Check_Bad_Layout;
733                   Append_To (Statement_List, P_Abort_Statement);
734                   Statement_Required := False;
735
736                --  Accept_Statement
737
738                when Tok_Accept =>
739                   Check_Bad_Layout;
740                   Append_To (Statement_List, P_Accept_Statement);
741                   Statement_Required := False;
742
743                --  Begin_Statement (Block_Statement with no declare, no label)
744
745                when Tok_Begin =>
746                   Check_Bad_Layout;
747                   Append_To (Statement_List, P_Begin_Statement);
748                   Statement_Required := False;
749
750                --  Case_Statement
751
752                when Tok_Case =>
753                   Check_Bad_Layout;
754                   Append_To (Statement_List, P_Case_Statement);
755                   Statement_Required := False;
756
757                --  Block_Statement with DECLARE and no label
758
759                when Tok_Declare =>
760                   Check_Bad_Layout;
761                   Append_To (Statement_List, P_Declare_Statement);
762                   Statement_Required := False;
763
764                --  Delay_Statement
765
766                when Tok_Delay =>
767                   Check_Bad_Layout;
768                   Append_To (Statement_List, P_Delay_Statement);
769                   Statement_Required := False;
770
771                --  Exit_Statement
772
773                when Tok_Exit =>
774                   Check_Bad_Layout;
775                   Append_To (Statement_List, P_Exit_Statement);
776                   Statement_Required := False;
777
778                --  Loop_Statement with FOR and no label
779
780                when Tok_For =>
781                   Check_Bad_Layout;
782                   Append_To (Statement_List, P_For_Statement);
783                   Statement_Required := False;
784
785                --  Goto_Statement
786
787                when Tok_Goto =>
788                   Check_Bad_Layout;
789                   Append_To (Statement_List, P_Goto_Statement);
790                   Statement_Required := False;
791
792                --  If_Statement
793
794                when Tok_If =>
795                   Check_Bad_Layout;
796                   Append_To (Statement_List, P_If_Statement);
797                   Statement_Required := False;
798
799                --  Loop_Statement
800
801                when Tok_Loop =>
802                   Check_Bad_Layout;
803                   Append_To (Statement_List, P_Loop_Statement);
804                   Statement_Required := False;
805
806                --  Null_Statement
807
808                when Tok_Null =>
809                   Check_Bad_Layout;
810                   Append_To (Statement_List, P_Null_Statement);
811                   Statement_Required := False;
812
813                --  Raise_Statement
814
815                when Tok_Raise =>
816                   Check_Bad_Layout;
817                   Append_To (Statement_List, P_Raise_Statement);
818                   Statement_Required := False;
819
820                --  Requeue_Statement
821
822                when Tok_Requeue =>
823                   Check_Bad_Layout;
824                   Append_To (Statement_List, P_Requeue_Statement);
825                   Statement_Required := False;
826
827                --  Return_Statement
828
829                when Tok_Return =>
830                   Check_Bad_Layout;
831                   Append_To (Statement_List, P_Return_Statement);
832                   Statement_Required := False;
833
834                --  Select_Statement
835
836                when Tok_Select =>
837                   Check_Bad_Layout;
838                   Append_To (Statement_List, P_Select_Statement);
839                   Statement_Required := False;
840
841                --  While_Statement (Block_Statement with while and no loop)
842
843                when Tok_While =>
844                   Check_Bad_Layout;
845                   Append_To (Statement_List, P_While_Statement);
846                   Statement_Required := False;
847
848                --  Anything else is some kind of junk, signal an error message
849                --  and then raise Error_Resync, to merge with the normal
850                --  handling of a bad statement.
851
852                when others =>
853
854                   if Token in Token_Class_Declk then
855                      Junk_Declaration;
856
857                   else
858                      Error_Msg_BC ("statement expected");
859                      raise Error_Resync;
860                   end if;
861             end case;
862
863          --  On error resynchronization, skip past next semicolon, and, since
864          --  we are still in the statement loop, look for next statement. We
865          --  set Statement_Required False to avoid an unnecessary error message
866          --  complaining that no statement was found (i.e. we consider the
867          --  junk to satisfy the requirement for a statement being present).
868
869          exception
870             when Error_Resync =>
871                Resync_Past_Semicolon_Or_To_Loop_Or_Then;
872                Statement_Required := False;
873          end;
874
875          exit when SS_Flags.Unco;
876
877       end loop;
878
879       return Statement_List;
880
881    end P_Sequence_Of_Statements;
882
883    --------------------
884    -- 5.1  Statement --
885    --------------------
886
887    --  Parsed by P_Sequence_Of_Statements (5.1), except for the case
888    --  of a statement of the form of a name, which is handled here. The
889    --  argument passed in is the tree for the name which has been scanned
890    --  The returned value is the corresponding statement form.
891
892    --  This routine is also used by Par.Prag for processing the procedure
893    --  call that appears as the second argument of a pragma Assert.
894
895    --  Error recovery: cannot raise Error_Resync
896
897    function P_Statement_Name (Name_Node : Node_Id) return Node_Id is
898       Stmt_Node : Node_Id;
899
900    begin
901       --  Case of Indexed component, which is a procedure call with arguments
902
903       if Nkind (Name_Node) = N_Indexed_Component then
904          declare
905             Prefix_Node : constant Node_Id := Prefix (Name_Node);
906             Exprs_Node  : constant List_Id := Expressions (Name_Node);
907
908          begin
909             Change_Node (Name_Node, N_Procedure_Call_Statement);
910             Set_Name (Name_Node, Prefix_Node);
911             Set_Parameter_Associations (Name_Node, Exprs_Node);
912             return Name_Node;
913          end;
914
915       --  Case of function call node, which is a really a procedure call
916
917       elsif Nkind (Name_Node) = N_Function_Call then
918          declare
919             Fname_Node  : constant Node_Id := Name (Name_Node);
920             Params_List : constant List_Id :=
921                             Parameter_Associations (Name_Node);
922
923          begin
924             Change_Node (Name_Node, N_Procedure_Call_Statement);
925             Set_Name (Name_Node, Fname_Node);
926             Set_Parameter_Associations (Name_Node, Params_List);
927             return Name_Node;
928          end;
929
930       --  Case of call to attribute that denotes a procedure. Here we
931       --  just leave the attribute reference unchanged.
932
933       elsif Nkind (Name_Node) = N_Attribute_Reference
934         and then Is_Procedure_Attribute_Name (Attribute_Name (Name_Node))
935       then
936          return Name_Node;
937
938       --  All other cases of names are parameterless procedure calls
939
940       else
941          Stmt_Node :=
942            New_Node (N_Procedure_Call_Statement, Sloc (Name_Node));
943          Set_Name (Stmt_Node, Name_Node);
944          return Stmt_Node;
945       end if;
946
947    end P_Statement_Name;
948
949    ---------------------------
950    -- 5.1  Simple Statement --
951    ---------------------------
952
953    --  Parsed by P_Sequence_Of_Statements (5.1)
954
955    -----------------------------
956    -- 5.1  Compound Statement --
957    -----------------------------
958
959    --  Parsed by P_Sequence_Of_Statements (5.1)
960
961    -------------------------
962    -- 5.1  Null Statement --
963    -------------------------
964
965    --  NULL_STATEMENT ::= null;
966
967    --  The caller has already checked that the current token is null
968
969    --  Error recovery: cannot raise Error_Resync
970
971    function P_Null_Statement return Node_Id is
972       Null_Stmt_Node : Node_Id;
973
974    begin
975       Null_Stmt_Node := New_Node (N_Null_Statement, Token_Ptr);
976       Scan; -- past NULL
977       TF_Semicolon;
978       return Null_Stmt_Node;
979    end P_Null_Statement;
980
981    ----------------
982    -- 5.1  Label --
983    ----------------
984
985    --  LABEL ::= <<label_STATEMENT_IDENTIFIER>>
986
987    --  STATEMENT_INDENTIFIER ::= DIRECT_NAME
988
989    --  The IDENTIFIER of a STATEMENT_IDENTIFIER shall be an identifier
990    --  (not an OPERATOR_SYMBOL)
991
992    --  The caller has already checked that the current token is <<
993
994    --  Error recovery: can raise Error_Resync
995
996    function P_Label return Node_Id is
997       Label_Node : Node_Id;
998
999    begin
1000       Label_Node := New_Node (N_Label, Token_Ptr);
1001       Scan; -- past <<
1002       Set_Identifier (Label_Node, P_Identifier (C_Greater_Greater));
1003       T_Greater_Greater;
1004       Append_Elmt (Label_Node, Label_List);
1005       return Label_Node;
1006    end P_Label;
1007
1008    -------------------------------
1009    -- 5.1  Statement Identifier --
1010    -------------------------------
1011
1012    --  Statement label is parsed by P_Label (5.1)
1013
1014    --  Loop label is parsed by P_Loop_Statement (5.5), P_For_Statement (5.5)
1015    --   or P_While_Statement (5.5)
1016
1017    --  Block label is parsed by P_Begin_Statement (5.6) or
1018    --   P_Declare_Statement (5.6)
1019
1020    -------------------------------
1021    -- 5.2  Assignment Statement --
1022    -------------------------------
1023
1024    --  ASSIGNMENT_STATEMENT ::=
1025    --    variable_NAME := EXPRESSION;
1026
1027    --  Error recovery: can raise Error_Resync
1028
1029    function P_Assignment_Statement (LHS : Node_Id) return Node_Id is
1030       Assign_Node : Node_Id;
1031
1032    begin
1033       Assign_Node := New_Node (N_Assignment_Statement, Prev_Token_Ptr);
1034       Set_Name (Assign_Node, LHS);
1035       Set_Expression (Assign_Node, P_Expression_No_Right_Paren);
1036       TF_Semicolon;
1037       return Assign_Node;
1038    end P_Assignment_Statement;
1039
1040    -----------------------
1041    -- 5.3  If Statement --
1042    -----------------------
1043
1044    --  IF_STATEMENT ::=
1045    --    if CONDITION then
1046    --      SEQUENCE_OF_STATEMENTS
1047    --    {elsif CONDITION then
1048    --      SEQUENCE_OF_STATEMENTS}
1049    --    [else
1050    --      SEQUENCE_OF_STATEMENTS]
1051    --    end if;
1052
1053    --  The caller has checked that the initial token is IF (or in the error
1054    --  case of a mysterious THEN, the initial token may simply be THEN, in
1055    --  which case, no condition (or IF) was scanned).
1056
1057    --  Error recovery: can raise Error_Resync
1058
1059    function P_If_Statement return Node_Id is
1060       If_Node    : Node_Id;
1061       Elsif_Node : Node_Id;
1062       Loc        : Source_Ptr;
1063
1064       procedure Add_Elsif_Part;
1065       --  An internal procedure used to scan out a single ELSIF part. On entry
1066       --  the ELSIF (or an ELSE which has been determined should be ELSIF) is
1067       --  scanned out and is in Prev_Token.
1068
1069       procedure Check_If_Column;
1070       --  An internal procedure used to check that THEN, ELSE ELSE, or ELSIF
1071       --  appear in the right place if column checking is enabled (i.e. if
1072       --  they are the first token on the line, then they must appear in
1073       --  the same column as the opening IF).
1074
1075       procedure Check_Then_Column;
1076       --  This procedure carries out the style checks for a THEN token
1077       --  Note that the caller has set Loc to the Source_Ptr value for
1078       --  the previous IF or ELSIF token. These checks apply only to a
1079       --  THEN at the start of a line.
1080
1081       function Else_Should_Be_Elsif return Boolean;
1082       --  An internal routine used to do a special error recovery check when
1083       --  an ELSE is encountered. It determines if the ELSE should be treated
1084       --  as an ELSIF. A positive decision (TRUE returned, is made if the ELSE
1085       --  is followed by a sequence of tokens, starting on the same line as
1086       --  the ELSE, which are not expression terminators, followed by a THEN.
1087       --  On entry, the ELSE has been scanned out.
1088
1089       procedure Add_Elsif_Part is
1090       begin
1091          if No (Elsif_Parts (If_Node)) then
1092             Set_Elsif_Parts (If_Node, New_List);
1093          end if;
1094
1095          Elsif_Node := New_Node (N_Elsif_Part, Prev_Token_Ptr);
1096          Loc := Prev_Token_Ptr;
1097          Set_Condition (Elsif_Node, P_Condition);
1098          Check_Then_Column;
1099          Then_Scan;
1100          Set_Then_Statements
1101            (Elsif_Node, P_Sequence_Of_Statements (SS_Eftm_Eltm_Sreq));
1102          Append (Elsif_Node, Elsif_Parts (If_Node));
1103       end Add_Elsif_Part;
1104
1105       procedure Check_If_Column is
1106       begin
1107          if Style.RM_Column_Check and then Token_Is_At_Start_Of_Line
1108            and then Start_Column /= Scope.Table (Scope.Last).Ecol
1109          then
1110             Error_Msg_Col := Scope.Table (Scope.Last).Ecol;
1111             Error_Msg_SC ("(style) this token should be@");
1112          end if;
1113       end Check_If_Column;
1114
1115       procedure Check_Then_Column is
1116       begin
1117          if Token_Is_At_Start_Of_Line and then Token = Tok_Then then
1118             Check_If_Column;
1119
1120             if Style_Check then
1121                Style.Check_Then (Loc);
1122             end if;
1123          end if;
1124       end Check_Then_Column;
1125
1126       function Else_Should_Be_Elsif return Boolean is
1127          Scan_State : Saved_Scan_State;
1128
1129       begin
1130          if Token_Is_At_Start_Of_Line then
1131             return False;
1132
1133          else
1134             Save_Scan_State (Scan_State);
1135
1136             loop
1137                if Token in Token_Class_Eterm then
1138                   Restore_Scan_State (Scan_State);
1139                   return False;
1140                else
1141                   Scan; -- past non-expression terminating token
1142
1143                   if Token = Tok_Then then
1144                      Restore_Scan_State (Scan_State);
1145                      return True;
1146                   end if;
1147                end if;
1148             end loop;
1149          end if;
1150       end Else_Should_Be_Elsif;
1151
1152    --  Start of processing for P_If_Statement
1153
1154    begin
1155       If_Node := New_Node (N_If_Statement, Token_Ptr);
1156
1157       Push_Scope_Stack;
1158       Scope.Table (Scope.Last).Etyp := E_If;
1159       Scope.Table (Scope.Last).Ecol := Start_Column;
1160       Scope.Table (Scope.Last).Sloc := Token_Ptr;
1161       Scope.Table (Scope.Last).Labl := Error;
1162       Scope.Table (Scope.Last).Node := If_Node;
1163
1164       if Token = Tok_If then
1165          Loc := Token_Ptr;
1166          Scan; -- past IF
1167          Set_Condition (If_Node, P_Condition);
1168
1169          --  Deal with misuse of IF expression => used instead
1170          --  of WHEN expression =>
1171
1172          if Token = Tok_Arrow then
1173             Error_Msg_SC ("THEN expected");
1174             Scan; -- past the arrow
1175             Pop_Scope_Stack; -- remove unneeded entry
1176             raise Error_Resync;
1177          end if;
1178
1179          Check_Then_Column;
1180
1181       else
1182          Error_Msg_SC ("no IF for this THEN");
1183          Set_Condition (If_Node, Error);
1184       end if;
1185
1186       Then_Scan;
1187
1188       Set_Then_Statements
1189         (If_Node, P_Sequence_Of_Statements (SS_Eftm_Eltm_Sreq));
1190
1191       --  This loop scans out else and elsif parts
1192
1193       loop
1194          if Token = Tok_Elsif then
1195             Check_If_Column;
1196
1197             if Present (Else_Statements (If_Node)) then
1198                Error_Msg_SP ("ELSIF cannot appear after ELSE");
1199             end if;
1200
1201             Scan; -- past ELSIF
1202             Add_Elsif_Part;
1203
1204          elsif Token = Tok_Else then
1205             Check_If_Column;
1206             Scan; -- past ELSE
1207
1208             if Else_Should_Be_Elsif then
1209                Error_Msg_SP ("ELSE should be ELSIF");
1210                Add_Elsif_Part;
1211
1212             else
1213                --  Here we have an else that really is an else
1214
1215                if Present (Else_Statements (If_Node)) then
1216                   Error_Msg_SP ("only one ELSE part allowed");
1217                   Append_List
1218                     (P_Sequence_Of_Statements (SS_Eftm_Eltm_Sreq),
1219                      Else_Statements (If_Node));
1220                else
1221                   Set_Else_Statements
1222                     (If_Node, P_Sequence_Of_Statements (SS_Eftm_Eltm_Sreq));
1223                end if;
1224             end if;
1225
1226          --  If anything other than ELSE or ELSIF, exit the loop. The token
1227          --  had better be END (and in fact it had better be END IF), but
1228          --  we will let End_Statements take care of checking that.
1229
1230          else
1231             exit;
1232          end if;
1233       end loop;
1234
1235       End_Statements;
1236       return If_Node;
1237
1238    end P_If_Statement;
1239
1240    --------------------
1241    -- 5.3  Condition --
1242    --------------------
1243
1244    --  CONDITION ::= boolean_EXPRESSION
1245
1246    function P_Condition return Node_Id is
1247       Cond : Node_Id;
1248
1249    begin
1250       Cond := P_Expression_No_Right_Paren;
1251
1252       --  It is never possible for := to follow a condition, so if we get
1253       --  a := we assume it is a mistyped equality. Note that we do not try
1254       --  to reconstruct the tree correctly in this case, but we do at least
1255       --  give an accurate error message.
1256
1257       if Token = Tok_Colon_Equal then
1258          while Token = Tok_Colon_Equal loop
1259             Error_Msg_SC (""":="" should be ""=""");
1260             Scan; -- past junk :=
1261             Discard_Junk_Node (P_Expression_No_Right_Paren);
1262          end loop;
1263
1264          return Cond;
1265
1266       --  Otherwise check for redundant parens
1267
1268       else
1269          if Style_Check
1270            and then Paren_Count (Cond) > 0
1271          then
1272             Style.Check_Xtra_Parens (First_Sloc (Cond));
1273          end if;
1274
1275          --  And return the result
1276
1277          return Cond;
1278       end if;
1279    end P_Condition;
1280
1281    -------------------------
1282    -- 5.4  Case Statement --
1283    -------------------------
1284
1285    --  CASE_STATEMENT ::=
1286    --    case EXPRESSION is
1287    --      CASE_STATEMENT_ALTERNATIVE
1288    --      {CASE_STATEMENT_ALTERNATIVE}
1289    --    end case;
1290
1291    --  The caller has checked that the first token is CASE
1292
1293    --  Can raise Error_Resync
1294
1295    function P_Case_Statement return Node_Id is
1296       Case_Node         : Node_Id;
1297       Alternatives_List : List_Id;
1298       First_When_Loc    : Source_Ptr;
1299
1300    begin
1301       Case_Node := New_Node (N_Case_Statement, Token_Ptr);
1302
1303       Push_Scope_Stack;
1304       Scope.Table (Scope.Last).Etyp := E_Case;
1305       Scope.Table (Scope.Last).Ecol := Start_Column;
1306       Scope.Table (Scope.Last).Sloc := Token_Ptr;
1307       Scope.Table (Scope.Last).Labl := Error;
1308       Scope.Table (Scope.Last).Node := Case_Node;
1309
1310       Scan; -- past CASE
1311       Set_Expression (Case_Node, P_Expression_No_Right_Paren);
1312       TF_Is;
1313
1314       --  Prepare to parse case statement alternatives
1315
1316       Alternatives_List := New_List;
1317       P_Pragmas_Opt (Alternatives_List);
1318       First_When_Loc := Token_Ptr;
1319
1320       --  Loop through case statement alternatives
1321
1322       loop
1323          --  If we have a WHEN or OTHERS, then that's fine keep going. Note
1324          --  that it is a semantic check to ensure the proper use of OTHERS
1325
1326          if Token = Tok_When or else Token = Tok_Others then
1327             Append (P_Case_Statement_Alternative, Alternatives_List);
1328
1329          --  If we have an END, then probably we are at the end of the case
1330          --  but we only exit if Check_End thinks the END was reasonable.
1331
1332          elsif Token = Tok_End then
1333             exit when Check_End;
1334
1335          --  Here if token is other than WHEN, OTHERS or END. We definitely
1336          --  have an error, but the question is whether or not to get out of
1337          --  the case statement. We don't want to get out early, or we will
1338          --  get a slew of junk error messages for subsequent when tokens.
1339
1340          --  If the token is not at the start of the line, or if it is indented
1341          --  with respect to the current case statement, then the best guess is
1342          --  that we are still supposed to be inside the case statement. We
1343          --  complain about the missing WHEN, and discard the junk statements.
1344
1345          elsif not Token_Is_At_Start_Of_Line
1346            or else Start_Column > Scope.Table (Scope.Last).Ecol
1347          then
1348             Error_Msg_BC ("WHEN (case statement alternative) expected");
1349
1350             --  Here is a possibility for infinite looping if we don't make
1351             --  progress. So try to process statements, otherwise exit
1352
1353             declare
1354                Error_Ptr : constant Source_Ptr := Scan_Ptr;
1355             begin
1356                Discard_Junk_List (P_Sequence_Of_Statements (SS_Whtm));
1357                exit when Scan_Ptr = Error_Ptr and then Check_End;
1358             end;
1359
1360          --  Here we have a junk token at the start of the line and it is
1361          --  not indented. If Check_End thinks there is a missing END, then
1362          --  we will get out of the case, otherwise we keep going.
1363
1364          else
1365             exit when Check_End;
1366          end if;
1367       end loop;
1368
1369       --  Make sure we have at least one alternative
1370
1371       if No (First_Non_Pragma (Alternatives_List)) then
1372          Error_Msg
1373             ("WHEN expected, must have at least one alternative in case",
1374              First_When_Loc);
1375          return Error;
1376
1377       else
1378          Set_Alternatives (Case_Node, Alternatives_List);
1379          return Case_Node;
1380       end if;
1381    end P_Case_Statement;
1382
1383    -------------------------------------
1384    -- 5.4  Case Statement Alternative --
1385    -------------------------------------
1386
1387    --  CASE_STATEMENT_ALTERNATIVE ::=
1388    --    when DISCRETE_CHOICE_LIST =>
1389    --      SEQUENCE_OF_STATEMENTS
1390
1391    --  The caller has checked that the initial token is WHEN or OTHERS
1392    --  Error recovery: can raise Error_Resync
1393
1394    function P_Case_Statement_Alternative return Node_Id is
1395       Case_Alt_Node : Node_Id;
1396
1397    begin
1398       if Style_Check then
1399          Style.Check_Indentation;
1400       end if;
1401
1402       Case_Alt_Node := New_Node (N_Case_Statement_Alternative, Token_Ptr);
1403       T_When; -- past WHEN (or give error in OTHERS case)
1404       Set_Discrete_Choices (Case_Alt_Node, P_Discrete_Choice_List);
1405       TF_Arrow;
1406       Set_Statements (Case_Alt_Node, P_Sequence_Of_Statements (SS_Sreq_Whtm));
1407       return Case_Alt_Node;
1408    end P_Case_Statement_Alternative;
1409
1410    -------------------------
1411    -- 5.5  Loop Statement --
1412    -------------------------
1413
1414    --  LOOP_STATEMENT ::=
1415    --    [LOOP_STATEMENT_IDENTIFIER:]
1416    --      [ITERATION_SCHEME] loop
1417    --        SEQUENCE_OF_STATEMENTS
1418    --      end loop [loop_IDENTIFIER];
1419
1420    --  ITERATION_SCHEME ::=
1421    --    while CONDITION
1422    --  | for LOOP_PARAMETER_SPECIFICATION
1423
1424    --  The parsing of loop statements is handled by one of three functions
1425    --  P_Loop_Statement, P_For_Statement or P_While_Statement depending
1426    --  on the initial keyword in the construct (excluding the identifier)
1427
1428    --  P_Loop_Statement
1429
1430    --  This function parses the case where no iteration scheme is present
1431
1432    --  The caller has checked that the initial token is LOOP. The parameter
1433    --  is the node identifiers for the loop label if any (or is set to Empty
1434    --  if there is no loop label).
1435
1436    --  Error recovery : cannot raise Error_Resync
1437
1438    function P_Loop_Statement (Loop_Name : Node_Id := Empty) return Node_Id is
1439       Loop_Node    : Node_Id;
1440       Created_Name : Node_Id;
1441
1442    begin
1443       Push_Scope_Stack;
1444       Scope.Table (Scope.Last).Labl := Loop_Name;
1445       Scope.Table (Scope.Last).Ecol := Start_Column;
1446       Scope.Table (Scope.Last).Sloc := Token_Ptr;
1447       Scope.Table (Scope.Last).Etyp := E_Loop;
1448
1449       Loop_Node := New_Node (N_Loop_Statement, Token_Ptr);
1450       TF_Loop;
1451
1452       if No (Loop_Name) then
1453          Created_Name :=
1454            Make_Identifier (Sloc (Loop_Node),
1455              Chars => Set_Loop_Block_Name ('L'));
1456          Set_Comes_From_Source (Created_Name, False);
1457          Set_Has_Created_Identifier (Loop_Node, True);
1458          Set_Identifier (Loop_Node, Created_Name);
1459          Scope.Table (Scope.Last).Labl := Created_Name;
1460       else
1461          Set_Identifier (Loop_Node, Loop_Name);
1462       end if;
1463
1464       Append_Elmt (Loop_Node, Label_List);
1465       Set_Statements (Loop_Node, P_Sequence_Of_Statements (SS_Sreq));
1466       End_Statements (Loop_Node);
1467       return Loop_Node;
1468    end P_Loop_Statement;
1469
1470    --  P_For_Statement
1471
1472    --  This function parses a loop statement with a FOR iteration scheme
1473
1474    --  The caller has checked that the initial token is FOR. The parameter
1475    --  is the node identifier for the block label if any (or is set to Empty
1476    --  if there is no block label).
1477
1478    --  Note: the caller fills in the Identifier field if a label was present
1479
1480    --  Error recovery: can raise Error_Resync
1481
1482    function P_For_Statement (Loop_Name : Node_Id := Empty) return Node_Id is
1483       Loop_Node        : Node_Id;
1484       Iter_Scheme_Node : Node_Id;
1485       Loop_For_Flag    : Boolean;
1486       Created_Name     : Node_Id;
1487
1488    begin
1489       Push_Scope_Stack;
1490       Scope.Table (Scope.Last).Labl := Loop_Name;
1491       Scope.Table (Scope.Last).Ecol := Start_Column;
1492       Scope.Table (Scope.Last).Sloc := Token_Ptr;
1493       Scope.Table (Scope.Last).Etyp := E_Loop;
1494
1495       Loop_For_Flag := (Prev_Token = Tok_Loop);
1496       Scan; -- past FOR
1497       Iter_Scheme_Node := New_Node (N_Iteration_Scheme, Token_Ptr);
1498       Set_Loop_Parameter_Specification
1499          (Iter_Scheme_Node, P_Loop_Parameter_Specification);
1500
1501       --  The following is a special test so that a miswritten for loop such
1502       --  as "loop for I in 1..10;" is handled nicely, without making an extra
1503       --  entry in the scope stack. We don't bother to actually fix up the
1504       --  tree in this case since it's not worth the effort. Instead we just
1505       --  eat up the loop junk, leaving the entry for what now looks like an
1506       --  unmodified loop intact.
1507
1508       if Loop_For_Flag and then Token = Tok_Semicolon then
1509          Error_Msg_SC ("LOOP belongs here, not before FOR");
1510          Pop_Scope_Stack;
1511          return Error;
1512
1513       --  Normal case
1514
1515       else
1516          Loop_Node := New_Node (N_Loop_Statement, Token_Ptr);
1517
1518          if No (Loop_Name) then
1519             Created_Name :=
1520               Make_Identifier (Sloc (Loop_Node),
1521                 Chars => Set_Loop_Block_Name ('L'));
1522             Set_Comes_From_Source (Created_Name, False);
1523             Set_Has_Created_Identifier (Loop_Node, True);
1524             Set_Identifier (Loop_Node, Created_Name);
1525             Scope.Table (Scope.Last).Labl := Created_Name;
1526          else
1527             Set_Identifier (Loop_Node, Loop_Name);
1528          end if;
1529
1530          TF_Loop;
1531          Set_Statements (Loop_Node, P_Sequence_Of_Statements (SS_Sreq));
1532          End_Statements (Loop_Node);
1533          Set_Iteration_Scheme (Loop_Node, Iter_Scheme_Node);
1534          Append_Elmt (Loop_Node, Label_List);
1535          return Loop_Node;
1536       end if;
1537    end P_For_Statement;
1538
1539    --  P_While_Statement
1540
1541    --  This procedure scans a loop statement with a WHILE iteration scheme
1542
1543    --  The caller has checked that the initial token is WHILE. The parameter
1544    --  is the node identifier for the block label if any (or is set to Empty
1545    --  if there is no block label).
1546
1547    --  Error recovery: cannot raise Error_Resync
1548
1549    function P_While_Statement (Loop_Name : Node_Id := Empty) return Node_Id is
1550       Loop_Node        : Node_Id;
1551       Iter_Scheme_Node : Node_Id;
1552       Loop_While_Flag  : Boolean;
1553       Created_Name     : Node_Id;
1554
1555    begin
1556       Push_Scope_Stack;
1557       Scope.Table (Scope.Last).Labl := Loop_Name;
1558       Scope.Table (Scope.Last).Ecol := Start_Column;
1559       Scope.Table (Scope.Last).Sloc := Token_Ptr;
1560       Scope.Table (Scope.Last).Etyp := E_Loop;
1561
1562       Loop_While_Flag := (Prev_Token = Tok_Loop);
1563       Iter_Scheme_Node := New_Node (N_Iteration_Scheme, Token_Ptr);
1564       Scan; -- past WHILE
1565       Set_Condition (Iter_Scheme_Node, P_Condition);
1566
1567       --  The following is a special test so that a miswritten for loop such
1568       --  as "loop while I > 10;" is handled nicely, without making an extra
1569       --  entry in the scope stack. We don't bother to actually fix up the
1570       --  tree in this case since it's not worth the effort. Instead we just
1571       --  eat up the loop junk, leaving the entry for what now looks like an
1572       --  unmodified loop intact.
1573
1574       if Loop_While_Flag and then Token = Tok_Semicolon then
1575          Error_Msg_SC ("LOOP belongs here, not before WHILE");
1576          Pop_Scope_Stack;
1577          return Error;
1578
1579       --  Normal case
1580
1581       else
1582          Loop_Node := New_Node (N_Loop_Statement, Token_Ptr);
1583          TF_Loop;
1584
1585          if No (Loop_Name) then
1586             Created_Name :=
1587               Make_Identifier (Sloc (Loop_Node),
1588                 Chars => Set_Loop_Block_Name ('L'));
1589             Set_Comes_From_Source (Created_Name, False);
1590             Set_Has_Created_Identifier (Loop_Node, True);
1591             Set_Identifier (Loop_Node, Created_Name);
1592             Scope.Table (Scope.Last).Labl := Created_Name;
1593          else
1594             Set_Identifier (Loop_Node, Loop_Name);
1595          end if;
1596
1597          Set_Statements (Loop_Node, P_Sequence_Of_Statements (SS_Sreq));
1598          End_Statements (Loop_Node);
1599          Set_Iteration_Scheme (Loop_Node, Iter_Scheme_Node);
1600          Append_Elmt (Loop_Node, Label_List);
1601          return Loop_Node;
1602       end if;
1603    end P_While_Statement;
1604
1605    ---------------------------------------
1606    -- 5.5  Loop Parameter Specification --
1607    ---------------------------------------
1608
1609    --  LOOP_PARAMETER_SPECIFICATION ::=
1610    --    DEFINING_IDENTIFIER in [reverse] DISCRETE_SUBTYPE_DEFINITION
1611
1612    --  Error recovery: cannot raise Error_Resync
1613
1614    function P_Loop_Parameter_Specification return Node_Id is
1615       Loop_Param_Specification_Node : Node_Id;
1616
1617       ID_Node    : Node_Id;
1618       Scan_State : Saved_Scan_State;
1619
1620    begin
1621       Loop_Param_Specification_Node :=
1622         New_Node (N_Loop_Parameter_Specification, Token_Ptr);
1623
1624       Save_Scan_State (Scan_State);
1625       ID_Node := P_Defining_Identifier (C_In);
1626       Set_Defining_Identifier (Loop_Param_Specification_Node, ID_Node);
1627
1628       if Token = Tok_Left_Paren then
1629          Error_Msg_SC ("subscripted loop parameter not allowed");
1630          Restore_Scan_State (Scan_State);
1631          Discard_Junk_Node (P_Name);
1632
1633       elsif Token = Tok_Dot then
1634          Error_Msg_SC ("selected loop parameter not allowed");
1635          Restore_Scan_State (Scan_State);
1636          Discard_Junk_Node (P_Name);
1637       end if;
1638
1639       T_In;
1640
1641       if Token = Tok_Reverse then
1642          Scan; -- past REVERSE
1643          Set_Reverse_Present (Loop_Param_Specification_Node, True);
1644       end if;
1645
1646       Set_Discrete_Subtype_Definition
1647         (Loop_Param_Specification_Node, P_Discrete_Subtype_Definition);
1648       return Loop_Param_Specification_Node;
1649
1650    exception
1651       when Error_Resync =>
1652          return Error;
1653    end P_Loop_Parameter_Specification;
1654
1655    --------------------------
1656    -- 5.6  Block Statement --
1657    --------------------------
1658
1659    --  BLOCK_STATEMENT ::=
1660    --    [block_STATEMENT_IDENTIFIER:]
1661    --      [declare
1662    --        DECLARATIVE_PART]
1663    --      begin
1664    --        HANDLED_SEQUENCE_OF_STATEMENTS
1665    --      end [block_IDENTIFIER];
1666
1667    --  The parsing of block statements is handled by one of the two functions
1668    --  P_Declare_Statement or P_Begin_Statement depending on whether or not
1669    --  a declare section is present
1670
1671    --  P_Declare_Statement
1672
1673    --  This function parses a block statement with DECLARE present
1674
1675    --  The caller has checked that the initial token is DECLARE
1676
1677    --  Error recovery: cannot raise Error_Resync
1678
1679    function P_Declare_Statement
1680      (Block_Name : Node_Id := Empty)
1681       return       Node_Id
1682    is
1683       Block_Node   : Node_Id;
1684       Created_Name : Node_Id;
1685
1686    begin
1687       Block_Node := New_Node (N_Block_Statement, Token_Ptr);
1688
1689       Push_Scope_Stack;
1690       Scope.Table (Scope.Last).Etyp := E_Name;
1691       Scope.Table (Scope.Last).Lreq := Present (Block_Name);
1692       Scope.Table (Scope.Last).Ecol := Start_Column;
1693       Scope.Table (Scope.Last).Labl := Block_Name;
1694       Scope.Table (Scope.Last).Sloc := Token_Ptr;
1695
1696       Scan; -- past DECLARE
1697
1698       if No (Block_Name) then
1699          Created_Name :=
1700            Make_Identifier (Sloc (Block_Node),
1701              Chars => Set_Loop_Block_Name ('B'));
1702          Set_Comes_From_Source (Created_Name, False);
1703          Set_Has_Created_Identifier (Block_Node, True);
1704          Set_Identifier (Block_Node, Created_Name);
1705          Scope.Table (Scope.Last).Labl := Created_Name;
1706       else
1707          Set_Identifier (Block_Node, Block_Name);
1708       end if;
1709
1710       Append_Elmt (Block_Node, Label_List);
1711       Parse_Decls_Begin_End (Block_Node);
1712       return Block_Node;
1713    end P_Declare_Statement;
1714
1715    --  P_Begin_Statement
1716
1717    --  This function parses a block statement with no DECLARE present
1718
1719    --  The caller has checked that the initial token is BEGIN
1720
1721    --  Error recovery: cannot raise Error_Resync
1722
1723    function P_Begin_Statement
1724      (Block_Name : Node_Id := Empty)
1725       return       Node_Id
1726    is
1727       Block_Node   : Node_Id;
1728       Created_Name : Node_Id;
1729
1730    begin
1731       Block_Node := New_Node (N_Block_Statement, Token_Ptr);
1732
1733       Push_Scope_Stack;
1734       Scope.Table (Scope.Last).Etyp := E_Name;
1735       Scope.Table (Scope.Last).Lreq := Present (Block_Name);
1736       Scope.Table (Scope.Last).Ecol := Start_Column;
1737       Scope.Table (Scope.Last).Labl := Block_Name;
1738       Scope.Table (Scope.Last).Sloc := Token_Ptr;
1739
1740       if No (Block_Name) then
1741          Created_Name :=
1742            Make_Identifier (Sloc (Block_Node),
1743              Chars => Set_Loop_Block_Name ('B'));
1744          Set_Comes_From_Source (Created_Name, False);
1745          Set_Has_Created_Identifier (Block_Node, True);
1746          Set_Identifier (Block_Node, Created_Name);
1747          Scope.Table (Scope.Last).Labl := Created_Name;
1748       else
1749          Set_Identifier (Block_Node, Block_Name);
1750       end if;
1751
1752       Append_Elmt (Block_Node, Label_List);
1753
1754       Scope.Table (Scope.Last).Ecol := Start_Column;
1755       Scope.Table (Scope.Last).Sloc := Token_Ptr;
1756       Scan; -- past BEGIN
1757       Set_Handled_Statement_Sequence
1758         (Block_Node, P_Handled_Sequence_Of_Statements);
1759       End_Statements (Handled_Statement_Sequence (Block_Node));
1760       return Block_Node;
1761    end P_Begin_Statement;
1762
1763    -------------------------
1764    -- 5.7  Exit Statement --
1765    -------------------------
1766
1767    --  EXIT_STATEMENT ::=
1768    --    exit [loop_NAME] [when CONDITION];
1769
1770    --  The caller has checked that the initial token is EXIT
1771
1772    --  Error recovery: can raise Error_Resync
1773
1774    function P_Exit_Statement return Node_Id is
1775       Exit_Node : Node_Id;
1776
1777       function Missing_Semicolon_On_Exit return Boolean;
1778       --  This function deals with the following specialized situation
1779       --
1780       --    when 'x' =>
1781       --       exit [identifier]
1782       --    when 'y' =>
1783       --
1784       --  This looks like a messed up EXIT WHEN, when in fact the problem
1785       --  is a missing semicolon. It is called with Token pointing to the
1786       --  WHEN token, and returns True if a semicolon is missing before
1787       --  the WHEN as in the above example.
1788
1789       -------------------------------
1790       -- Missing_Semicolon_On_Exit --
1791       -------------------------------
1792
1793       function Missing_Semicolon_On_Exit return Boolean is
1794          State : Saved_Scan_State;
1795
1796       begin
1797          if not Token_Is_At_Start_Of_Line then
1798             return False;
1799
1800          elsif Scope.Table (Scope.Last).Etyp /= E_Case then
1801             return False;
1802
1803          else
1804             Save_Scan_State (State);
1805             Scan; -- past WHEN
1806             Scan; -- past token after WHEN
1807
1808             if Token = Tok_Arrow then
1809                Restore_Scan_State (State);
1810                return True;
1811             else
1812                Restore_Scan_State (State);
1813                return False;
1814             end if;
1815          end if;
1816       end Missing_Semicolon_On_Exit;
1817
1818    --  Start of processing for P_Exit_Statement
1819
1820    begin
1821       Exit_Node := New_Node (N_Exit_Statement, Token_Ptr);
1822       Scan; -- past EXIT
1823
1824       if Token = Tok_Identifier then
1825          Set_Name (Exit_Node, P_Qualified_Simple_Name);
1826
1827       elsif Style_Check then
1828          --  This EXIT has no name, so check that
1829          --  the innermost loop is unnamed too.
1830
1831          Check_No_Exit_Name :
1832          for J in reverse 1 .. Scope.Last loop
1833             if Scope.Table (J).Etyp = E_Loop then
1834                if Present (Scope.Table (J).Labl)
1835                  and then Comes_From_Source (Scope.Table (J).Labl)
1836                then
1837                   --  Innermost loop in fact had a name, style check fails
1838
1839                   Style.No_Exit_Name (Scope.Table (J).Labl);
1840                end if;
1841
1842                exit Check_No_Exit_Name;
1843             end if;
1844          end loop Check_No_Exit_Name;
1845       end if;
1846
1847       if Token = Tok_When and then not Missing_Semicolon_On_Exit then
1848          Scan; -- past WHEN
1849          Set_Condition (Exit_Node, P_Condition);
1850
1851       --  Allow IF instead of WHEN, giving error message
1852
1853       elsif Token = Tok_If then
1854          T_When;
1855          Scan; -- past IF used in place of WHEN
1856          Set_Condition (Exit_Node, P_Expression_No_Right_Paren);
1857       end if;
1858
1859       TF_Semicolon;
1860       return Exit_Node;
1861    end P_Exit_Statement;
1862
1863    -------------------------
1864    -- 5.8  Goto Statement --
1865    -------------------------
1866
1867    --  GOTO_STATEMENT ::= goto label_NAME;
1868
1869    --  The caller has checked that the initial token is GOTO  (or TO in the
1870    --  error case where GO and TO were incorrectly separated).
1871
1872    --  Error recovery: can raise Error_Resync
1873
1874    function P_Goto_Statement return Node_Id is
1875       Goto_Node : Node_Id;
1876
1877    begin
1878       Goto_Node := New_Node (N_Goto_Statement, Token_Ptr);
1879       Scan; -- past GOTO (or TO)
1880       Set_Name (Goto_Node, P_Qualified_Simple_Name_Resync);
1881       Append_Elmt (Goto_Node, Goto_List);
1882       No_Constraint;
1883       TF_Semicolon;
1884       return Goto_Node;
1885    end P_Goto_Statement;
1886
1887    ---------------------------
1888    -- Parse_Decls_Begin_End --
1889    ---------------------------
1890
1891    --  This function parses the construct:
1892
1893    --      DECLARATIVE_PART
1894    --    begin
1895    --      HANDLED_SEQUENCE_OF_STATEMENTS
1896    --    end [NAME];
1897
1898    --  The caller has built the scope stack entry, and created the node to
1899    --  whose Declarations and Handled_Statement_Sequence fields are to be
1900    --  set. On return these fields are filled in (except in the case of a
1901    --  task body, where the handled statement sequence is optional, and may
1902    --  thus be Empty), and the scan is positioned past the End sequence.
1903
1904    --  If the BEGIN is missing, then the parent node is used to help construct
1905    --  an appropriate missing BEGIN message. Possibilities for the parent are:
1906
1907    --    N_Block_Statement     declare block
1908    --    N_Entry_Body          entry body
1909    --    N_Package_Body        package body (begin part optional)
1910    --    N_Subprogram_Body     procedure or function body
1911    --    N_Task_Body           task body
1912
1913    --  Note: in the case of a block statement, there is definitely a DECLARE
1914    --  present (because a Begin statement without a DECLARE is handled by the
1915    --  P_Begin_Statement procedure, which does not call Parse_Decls_Begin_End.
1916
1917    --  Error recovery: cannot raise Error_Resync
1918
1919    procedure Parse_Decls_Begin_End (Parent : Node_Id) is
1920       Body_Decl    : Node_Id;
1921       Body_Sloc    : Source_Ptr;
1922       Decls        : List_Id;
1923       Decl         : Node_Id;
1924       Parent_Nkind : Node_Kind;
1925       Spec_Node    : Node_Id;
1926       HSS          : Node_Id;
1927
1928       procedure Missing_Begin (Msg : String);
1929       --  Called to post a missing begin message. In the normal case this is
1930       --  posted at the start of the current token. A special case arises when
1931       --  P_Declarative_Items has previously found a missing begin, in which
1932       --  case we replace the original error message.
1933
1934       procedure Set_Null_HSS (Parent : Node_Id);
1935       --  Construct an empty handled statement sequence and install in Parent
1936       --  Leaves HSS set to reference the newly constructed statement sequence.
1937
1938       -------------------
1939       -- Missing_Begin --
1940       -------------------
1941
1942       procedure Missing_Begin (Msg : String) is
1943       begin
1944          if Missing_Begin_Msg = No_Error_Msg then
1945             Error_Msg_BC (Msg);
1946          else
1947             Change_Error_Text (Missing_Begin_Msg, Msg);
1948
1949             --  Purge any messages issued after than, since a missing begin
1950             --  can cause a lot of havoc, and it is better not to dump these
1951             --  cascaded messages on the user.
1952
1953             Purge_Messages (Get_Location (Missing_Begin_Msg), Prev_Token_Ptr);
1954          end if;
1955       end Missing_Begin;
1956
1957       ------------------
1958       -- Set_Null_HSS --
1959       ------------------
1960
1961       procedure Set_Null_HSS (Parent : Node_Id) is
1962          Null_Stm : Node_Id;
1963
1964       begin
1965          Null_Stm :=
1966            Make_Null_Statement (Token_Ptr);
1967          Set_Comes_From_Source (Null_Stm, False);
1968
1969          HSS :=
1970            Make_Handled_Sequence_Of_Statements (Token_Ptr,
1971              Statements => New_List (Null_Stm));
1972          Set_Comes_From_Source (HSS, False);
1973
1974          Set_Handled_Statement_Sequence (Parent, HSS);
1975       end Set_Null_HSS;
1976
1977    --  Start of processing for Parse_Decls_Begin_End
1978
1979    begin
1980       Decls := P_Declarative_Part;
1981
1982       --  Check for misplacement of later vs basic declarations in Ada 83
1983
1984       if Ada_Version = Ada_83 then
1985          Decl := First (Decls);
1986
1987          --  Loop through sequence of basic declarative items
1988
1989          Outer : while Present (Decl) loop
1990             if Nkind (Decl) /= N_Subprogram_Body
1991               and then Nkind (Decl) /= N_Package_Body
1992               and then Nkind (Decl) /= N_Task_Body
1993               and then Nkind (Decl) not in  N_Body_Stub
1994             then
1995                Next (Decl);
1996
1997             --  Once a body is encountered, we only allow later declarative
1998             --  items. The inner loop checks the rest of the list.
1999
2000             else
2001                Body_Sloc := Sloc (Decl);
2002
2003                Inner : while Present (Decl) loop
2004                   if Nkind (Decl) not in N_Later_Decl_Item
2005                     and then Nkind (Decl) /= N_Pragma
2006                   then
2007                      if Ada_Version = Ada_83 then
2008                         Error_Msg_Sloc := Body_Sloc;
2009                         Error_Msg_N
2010                           ("(Ada 83) decl cannot appear after body#", Decl);
2011                      end if;
2012                   end if;
2013
2014                   Next (Decl);
2015                end loop Inner;
2016             end if;
2017          end loop Outer;
2018       end if;
2019
2020       --  Here is where we deal with the case of IS used instead of semicolon.
2021       --  Specifically, if the last declaration in the declarative part is a
2022       --  subprogram body still marked as having a bad IS, then this is where
2023       --  we decide that the IS should really have been a semicolon and that
2024       --  the body should have been a declaration. Note that if the bad IS
2025       --  had turned out to be OK (i.e. a decent begin/end was found for it),
2026       --  then the Bad_Is_Detected flag would have been reset by now.
2027
2028       Body_Decl := Last (Decls);
2029
2030       if Present (Body_Decl)
2031         and then Nkind (Body_Decl) = N_Subprogram_Body
2032         and then Bad_Is_Detected (Body_Decl)
2033       then
2034          --  OK, we have the case of a bad IS, so we need to fix up the tree.
2035          --  What we have now is a subprogram body with attached declarations
2036          --  and a possible statement sequence.
2037
2038          --  First step is to take the declarations that were part of the bogus
2039          --  subprogram body and append them to the outer declaration chain.
2040          --  In other words we append them past the body (which we will later
2041          --  convert into a declaration).
2042
2043          Append_List (Declarations (Body_Decl), Decls);
2044
2045          --  Now take the handled statement sequence of the bogus body and
2046          --  set it as the statement sequence for the outer construct. Note
2047          --  that it may be empty (we specially allowed a missing BEGIN for
2048          --  a subprogram body marked as having a bad IS -- see below).
2049
2050          Set_Handled_Statement_Sequence (Parent,
2051            Handled_Statement_Sequence (Body_Decl));
2052
2053          --  Next step is to convert the old body node to a declaration node
2054
2055          Spec_Node := Specification (Body_Decl);
2056          Change_Node (Body_Decl, N_Subprogram_Declaration);
2057          Set_Specification (Body_Decl, Spec_Node);
2058
2059          --  Final step is to put the declarations for the parent where
2060          --  they belong, and then fall through the IF to scan out the
2061          --  END statements.
2062
2063          Set_Declarations (Parent, Decls);
2064
2065       --  This is the normal case (i.e. any case except the bad IS case)
2066       --  If we have a BEGIN, then scan out the sequence of statements, and
2067       --  also reset the expected column for the END to match the BEGIN.
2068
2069       else
2070          Set_Declarations (Parent, Decls);
2071
2072          if Token = Tok_Begin then
2073             if Style_Check then
2074                Style.Check_Indentation;
2075             end if;
2076
2077             Error_Msg_Col := Scope.Table (Scope.Last).Ecol;
2078
2079             if Style.RM_Column_Check
2080               and then Token_Is_At_Start_Of_Line
2081               and then Start_Column /= Error_Msg_Col
2082             then
2083                Error_Msg_SC ("(style) BEGIN in wrong column, should be@");
2084
2085             else
2086                Scope.Table (Scope.Last).Ecol := Start_Column;
2087             end if;
2088
2089             Scope.Table (Scope.Last).Sloc := Token_Ptr;
2090             Scan; -- past BEGIN
2091             Set_Handled_Statement_Sequence (Parent,
2092               P_Handled_Sequence_Of_Statements);
2093
2094          --  No BEGIN present
2095
2096          else
2097             Parent_Nkind := Nkind (Parent);
2098
2099             --  A special check for the missing IS case. If we have a
2100             --  subprogram body that was marked as having a suspicious
2101             --  IS, and the current token is END, then we simply confirm
2102             --  the suspicion, and do not require a BEGIN to be present
2103
2104             if Parent_Nkind = N_Subprogram_Body
2105               and then Token  = Tok_End
2106               and then Scope.Table (Scope.Last).Etyp = E_Suspicious_Is
2107             then
2108                Scope.Table (Scope.Last).Etyp := E_Bad_Is;
2109
2110             --  Otherwise BEGIN is not required for a package body, so we
2111             --  don't mind if it is missing, but we do construct a dummy
2112             --  one (so that we have somewhere to set End_Label).
2113
2114             --  However if we have something other than a BEGIN which
2115             --  looks like it might be statements, then we signal a missing
2116             --  BEGIN for these cases as well. We define "something which
2117             --  looks like it might be statements" as a token other than
2118             --  END, EOF, or a token which starts declarations.
2119
2120             elsif Parent_Nkind = N_Package_Body
2121               and then (Token = Tok_End
2122                           or else Token = Tok_EOF
2123                           or else Token in Token_Class_Declk)
2124             then
2125                Set_Null_HSS (Parent);
2126
2127             --  These are cases in which a BEGIN is required and not present
2128
2129             else
2130                Set_Null_HSS (Parent);
2131
2132                --  Prepare to issue error message
2133
2134                Error_Msg_Sloc := Scope.Table (Scope.Last).Sloc;
2135                Error_Msg_Node_1 := Scope.Table (Scope.Last).Labl;
2136
2137                --  Now issue appropriate message
2138
2139                if Parent_Nkind = N_Block_Statement then
2140                   Missing_Begin ("missing BEGIN for DECLARE#!");
2141
2142                elsif Parent_Nkind = N_Entry_Body then
2143                   Missing_Begin ("missing BEGIN for ENTRY#!");
2144
2145                elsif Parent_Nkind = N_Subprogram_Body then
2146                   if Nkind (Specification (Parent))
2147                                = N_Function_Specification
2148                   then
2149                      Missing_Begin ("missing BEGIN for function&#!");
2150                   else
2151                      Missing_Begin ("missing BEGIN for procedure&#!");
2152                   end if;
2153
2154                --  The case for package body arises only when
2155                --  we have possible statement junk present.
2156
2157                elsif Parent_Nkind = N_Package_Body then
2158                   Missing_Begin ("missing BEGIN for package body&#!");
2159
2160                else
2161                   pragma Assert (Parent_Nkind = N_Task_Body);
2162                   Missing_Begin ("missing BEGIN for task body&#!");
2163                end if;
2164
2165                --  Here we pick up the statements after the BEGIN that
2166                --  should have been present but was not. We don't insist
2167                --  on statements being present if P_Declarative_Part had
2168                --  already found a missing BEGIN, since it might have
2169                --  swallowed a lone statement into the declarative part.
2170
2171                if Missing_Begin_Msg /= No_Error_Msg
2172                  and then Token = Tok_End
2173                then
2174                   null;
2175                else
2176                   Set_Handled_Statement_Sequence (Parent,
2177                     P_Handled_Sequence_Of_Statements);
2178                end if;
2179             end if;
2180          end if;
2181       end if;
2182
2183       --  Here with declarations and handled statement sequence scanned
2184
2185       if Present (Handled_Statement_Sequence (Parent)) then
2186          End_Statements (Handled_Statement_Sequence (Parent));
2187       else
2188          End_Statements;
2189       end if;
2190
2191       --  We know that End_Statements removed an entry from the scope stack
2192       --  (because it is required to do so under all circumstances). We can
2193       --  therefore reference the entry it removed one past the stack top.
2194       --  What we are interested in is whether it was a case of a bad IS.
2195
2196       if Scope.Table (Scope.Last + 1).Etyp = E_Bad_Is then
2197          Error_Msg ("|IS should be "";""", Scope.Table (Scope.Last + 1).S_Is);
2198          Set_Bad_Is_Detected (Parent, True);
2199       end if;
2200
2201    end Parse_Decls_Begin_End;
2202
2203    -------------------------
2204    -- Set_Loop_Block_Name --
2205    -------------------------
2206
2207    function Set_Loop_Block_Name (L : Character) return Name_Id is
2208    begin
2209       Name_Buffer (1) := L;
2210       Name_Buffer (2) := '_';
2211       Name_Len := 2;
2212       Loop_Block_Count := Loop_Block_Count + 1;
2213       Add_Nat_To_Name_Buffer (Loop_Block_Count);
2214       return Name_Find;
2215    end Set_Loop_Block_Name;
2216
2217    ---------------
2218    -- Then_Scan --
2219    ---------------
2220
2221    procedure Then_Scan is
2222    begin
2223       TF_Then;
2224
2225       while Token = Tok_Then loop
2226          Error_Msg_SC ("redundant THEN");
2227          TF_Then;
2228       end loop;
2229
2230       if Token = Tok_And or else Token = Tok_Or then
2231          Error_Msg_SC ("unexpected logical operator");
2232          Scan; -- past logical operator
2233
2234          if (Prev_Token = Tok_And and then Token = Tok_Then)
2235               or else
2236             (Prev_Token = Tok_Or  and then Token = Tok_Else)
2237          then
2238             Scan;
2239          end if;
2240
2241          Discard_Junk_Node (P_Expression);
2242       end if;
2243
2244       if Token = Tok_Then then
2245          Scan;
2246       end if;
2247    end Then_Scan;
2248
2249 end Ch5;