OSDN Git Service

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