OSDN Git Service

Add Fariborz to my last change.
[pf3gnuchains/gcc-fork.git] / gcc / ada / par-endh.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                             P A R . E N D H                              --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 1992-2002, 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 2,  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 COPYING.  If not, write --
19 -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
20 -- MA 02111-1307, USA.                                                      --
21 --                                                                          --
22 -- GNAT was originally developed  by the GNAT team at  New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
24 --                                                                          --
25 ------------------------------------------------------------------------------
26
27 with Stringt; use Stringt;
28 with Uintp;   use Uintp;
29
30 with GNAT.Spelling_Checker; use GNAT.Spelling_Checker;
31
32 separate (Par)
33 package body Endh is
34
35    ----------------
36    -- Local Data --
37    ----------------
38
39    type End_Action_Type is (
40    --  Type used to describe the result of the Pop_End_Context call
41
42       Accept_As_Scanned,
43       --  Current end sequence is entirely c correct. In this case Token and
44       --  the scan pointer are left pointing past the end sequence (i.e. they
45       --  are unchanged from the values set on entry to Pop_End_Context).
46
47       Insert_And_Accept,
48       --  Current end sequence is to be left in place to satisfy some outer
49       --  scope. Token and the scan pointer are set to point to the end
50       --  token, and should be left there. A message has been generated
51       --  indicating a missing end sequence. This status is also used for
52       --  the case when no end token is present.
53
54       Skip_And_Accept,
55       --  The end sequence is incorrect (and an error message has been
56       --  posted), but it will still be accepted. In this case Token and
57       --  the scan pointer point back to the end token, and the caller
58       --  should skip past the end sequence before proceeding.
59
60       Skip_And_Reject);
61       --  The end sequence is judged to belong to an unrecognized inner
62       --  scope. An appropriate message has been issued and the caller
63       --  should skip past the end sequence and then proceed as though
64       --  no end sequence had been encountered.
65
66    End_Action : End_Action_Type;
67    --  The variable set by Pop_End_Context call showing which of the four
68    --  decisions described above is judged the best.
69
70    End_Sloc : Source_Ptr;
71    --  Source location of END token
72
73    End_OK : Boolean;
74    --  Set False if error is found in END line
75
76    End_Column : Column_Number;
77    --  Column of END line
78
79    End_Type : SS_End_Type;
80    --  Type of END expected. The special value E_Dummy is set to indicate that
81    --  no END token was present (so a missing END inserted message is needed)
82
83    End_Labl : Node_Id;
84    --  Node_Id value for explicit name on END line, or for compiler supplied
85    --  name in the case where an optional name is not given. Empty if no name
86    --  appears. If non-empty, then it is either an N_Designator node for a
87    --  child unit or a node with a Chars field identifying the actual label.
88
89    End_Labl_Present : Boolean;
90    --  Indicates that the value in End_Labl was for an explicit label.
91
92    Syntax_OK : Boolean;
93    --  Set True if the entry is syntactically correct
94
95    Token_OK : Boolean;
96    --  Set True if the keyword in the END sequence matches, or if neither
97    --  the END sequence nor the END stack entry has a keyword.
98
99    Label_OK : Boolean;
100    --  Set True if both the END sequence and the END stack entry contained
101    --  labels (other than No_Name or Error_Name) and the labels matched.
102    --  This is a stronger condition than SYNTAX_OK, since it means that a
103    --  label was present, even in a case where it was optional. Note that
104    --  the case of no label required, and no label present does NOT set
105    --  Label_OK to True, it is True only if a positive label match is found.
106
107    Column_OK : Boolean;
108    --  Column_OK is set True if the END sequence appears in the expected column
109
110    Scan_State : Saved_Scan_State;
111    --  Save state at start of END sequence, in case we decide not to eat it up
112
113    -----------------------
114    -- Local Subprograms --
115    -----------------------
116
117    procedure Evaluate_End_Entry (SS_Index : Nat);
118    --  Compare scanned END entry (as recorded by a prior call to P_End_Scan)
119    --  with a specified entry in the scope stack (the single parameter is the
120    --  entry index in the scope stack). Note that Scan is not called. The above
121    --  variables xxx_OK are set to indicate the result of the evaluation.
122
123    function Explicit_Start_Label (SS_Index : Nat) return Boolean;
124    --  Determines whether the specified entry in the scope stack has an
125    --  explicit start label (i.e. one other than one that was created by
126    --  the parser when no explicit label was present)
127
128    procedure Output_End_Deleted;
129    --  Output a message complaining that the current END structure does not
130    --  match anything and is being deleted.
131
132    procedure Output_End_Expected (Ins : Boolean);
133    --  Output a message at the start of the current token which is always an
134    --  END, complaining that the END is not of the right form. The message
135    --  indicates the expected form. The information for the message is taken
136    --  from the top entry in the scope stack. The Ins parameter is True if
137    --  an end is being inserted, and false if an existing end is being
138    --  replaced. Note that in the case of a suspicious IS for the Ins case,
139    --  we do not output the message, but instead simply mark the scope stack
140    --  entry as being a case of a bad IS.
141
142    procedure Output_End_Missing;
143    --  Output a message just before the current token, complaining that the
144    --  END is not of the right form. The message indicates the expected form.
145    --  The information for the message is taken from the top entry in the
146    --  scope stack. Note that in the case of a suspicious IS, we do not output
147    --  the message, but instead simply mark the scope stack entry as a bad IS.
148
149    procedure Pop_End_Context;
150    --  Pop_End_Context is called after processing a construct, to pop the
151    --  top entry off the end stack. It decides on the appropriate action to
152    --  to take, signalling the result by setting End_Action as described in
153    --  the global variable section.
154
155    function Same_Label (Label1, Label2 : Node_Id) return Boolean;
156    --  This function compares the two names associated with the given nodes.
157    --  If they are both simple (i.e. have Chars fields), then they have to
158    --  be the same name. Otherwise they must both be N_Selected_Component
159    --  nodes, referring to the same set of names, or Label1 is an N_Designator
160    --  referring to the same set of names as the N_Defining_Program_Unit_Name
161    --  in Label2. Any other combination returns False. This routine is used
162    --  to compare the End_Labl scanned from the End line with the saved label
163    --  value in the scope stack.
164
165    ---------------
166    -- Check_End --
167    ---------------
168
169    function Check_End return Boolean is
170       Name_On_Separate_Line : Boolean;
171       --  Set True if the name on an END line is on a separate source line
172       --  from the END. This is highly suspicious, but is allowed. The point
173       --  is that we want to make sure that we don't just have a missing
174       --  semicolon misleading us into swallowing an identifier from the
175       --  following line.
176
177       Name_Scan_State : Saved_Scan_State;
178       --  Save state at start of name if Name_On_Separate_Line is TRUE
179
180       Span_Node : constant Node_Id := Scope.Table (Scope.Last).Node;
181
182    begin
183       End_Labl_Present := False;
184       End_Labl := Empty;
185
186       --  Our first task is to scan out the END sequence if one is present.
187       --  If none is present, signal by setting End_Type to E_Dummy.
188
189       if Token /= Tok_End then
190          End_Type := E_Dummy;
191
192       else
193          Save_Scan_State (Scan_State); -- at END
194          End_Sloc := Token_Ptr;
195          End_Column := Start_Column;
196          End_OK := True;
197          Scan; -- past END
198
199          --  Set End_Span if expected. note that this will be useless
200          --  if we do not have the right ending keyword, but in this
201          --  case we have a malformed program anyway, and the setting
202          --  of End_Span will simply be unreliable in this case anyway.
203
204          if Present (Span_Node) then
205             Set_End_Location (Span_Node, Token_Ptr);
206          end if;
207
208          --  Cases of keywords where no label is allowed
209
210          if Token = Tok_Case then
211             End_Type := E_Case;
212             Scan; -- past CASE
213
214          elsif Token = Tok_If then
215             End_Type := E_If;
216             Scan; -- past IF
217
218          elsif Token = Tok_Record then
219             End_Type := E_Record;
220             Scan; -- past RECORD
221
222          elsif Token = Tok_Select then
223             End_Type := E_Select;
224             Scan; -- past SELECT
225
226          --  Cases which do allow labels
227
228          else
229             --  LOOP
230
231             if Token = Tok_Loop then
232                Scan; -- past LOOP
233                End_Type := E_Loop;
234
235             --  FOR or WHILE allowed (signalling error) to substitute for LOOP
236             --  if on the same line as the END
237
238             elsif (Token = Tok_For or else Token = Tok_While)
239               and then not Token_Is_At_Start_Of_Line
240             then
241                Scan; -- past FOR or WHILE
242                End_Type := E_Loop;
243                End_OK := False;
244
245             --  Cases with no keyword
246
247             else
248                End_Type := E_Name;
249             end if;
250
251             --  Now see if a name is present
252
253             if Token = Tok_Identifier or else
254                Token = Tok_String_Literal or else
255                Token = Tok_Operator_Symbol
256             then
257                if Token_Is_At_Start_Of_Line then
258                   Name_On_Separate_Line := True;
259                   Save_Scan_State (Name_Scan_State);
260                else
261                   Name_On_Separate_Line := False;
262                end if;
263
264                End_Labl := P_Designator;
265                End_Labl_Present := True;
266
267                --  We have now scanned out a name. Here is where we do a check
268                --  to catch the cases like:
269                --
270                --    end loop
271                --    X := 3;
272                --
273                --  where the missing semicolon might make us swallow up the X
274                --  as a bogus end label. In a situation like this, where the
275                --  apparent name is on a separate line, we accept it only if
276                --  it matches the label and is followed by a semicolon.
277
278                if Name_On_Separate_Line then
279                   if Token /= Tok_Semicolon or else
280                     not Same_Label (End_Labl, Scope.Table (Scope.Last).Labl)
281                   then
282                      Restore_Scan_State (Name_Scan_State);
283                      End_Labl := Empty;
284                      End_Labl_Present := False;
285                   end if;
286                end if;
287
288             --  Here for case of name allowed, but no name present. We will
289             --  supply an implicit matching name, with source location set
290             --  to the scan location past the END token.
291
292             else
293                End_Labl := Scope.Table (Scope.Last).Labl;
294
295                if End_Labl > Empty_Or_Error then
296
297                   --  The task here is to construct a designator from the
298                   --  opening label, with the components all marked as not
299                   --  from source, and Is_End_Label set in the identifier
300                   --  or operator symbol. The location for all components
301                   --  is the curent token location.
302
303                   --  Case of child unit name
304
305                   if Nkind (End_Labl) = N_Defining_Program_Unit_Name then
306                      Child_End : declare
307                         Eref : constant Node_Id :=
308                                  Make_Identifier (Token_Ptr,
309                                    Chars =>
310                                      Chars (Defining_Identifier (End_Labl)));
311
312                         function Copy_Name (N : Node_Id) return Node_Id;
313                         --  Copies a selected component or identifier
314
315                         ---------------
316                         -- Copy_Name --
317                         ---------------
318
319                         function Copy_Name (N : Node_Id) return Node_Id is
320                            R : Node_Id;
321
322                         begin
323                            if Nkind (N) = N_Selected_Component then
324                               return
325                                 Make_Selected_Component (Token_Ptr,
326                                   Prefix        =>
327                                     Copy_Name (Prefix (N)),
328                                   Selector_Name =>
329                                     Copy_Name (Selector_Name (N)));
330
331                            else
332                               R :=
333                                 Make_Identifier (Token_Ptr,
334                                   Chars => Chars (N));
335                               Set_Comes_From_Source (N, False);
336                               return R;
337                            end if;
338                         end Copy_Name;
339
340                      --  Start of processing for Child_End
341
342                      begin
343                         Set_Comes_From_Source (Eref, False);
344
345                         End_Labl :=
346                           Make_Designator (Token_Ptr,
347                             Name       => Copy_Name (Name (End_Labl)),
348                             Identifier => Eref);
349                      end Child_End;
350
351                   --  Simple identifier case
352
353                   elsif Nkind (End_Labl) = N_Defining_Identifier
354                     or else Nkind (End_Labl) = N_Identifier
355                   then
356                      End_Labl :=
357                        Make_Identifier (Token_Ptr,
358                          Chars => Chars (End_Labl));
359
360                   elsif Nkind (End_Labl) = N_Defining_Operator_Symbol
361                     or else Nkind (End_Labl) = N_Operator_Symbol
362                   then
363                      Get_Decoded_Name_String (Chars (End_Labl));
364
365                      End_Labl :=
366                        Make_Operator_Symbol (Token_Ptr,
367                          Chars  => Chars (End_Labl),
368                          Strval => String_From_Name_Buffer);
369                   end if;
370
371                   Set_Comes_From_Source (End_Labl, False);
372                   End_Labl_Present := False;
373
374                   --  Do style check for missing label
375
376                   if Style_Check
377                     and then End_Type = E_Name
378                     and then Explicit_Start_Label (Scope.Last)
379                   then
380                      Style.No_End_Name (Scope.Table (Scope.Last).Labl);
381                   end if;
382                end if;
383             end if;
384          end if;
385
386          --  Except in case of END RECORD, semicolon must follow. For END
387          --  RECORD, a semicolon does follow, but it is part of a higher level
388          --  construct. In any case, a missing semicolon is not serious enough
389          --  to consider the END statement to be bad in the sense that we
390          --  are dealing with (i.e. to be suspicious that it is not in fact
391          --  the END statement we are looking for!)
392
393          if End_Type /= E_Record then
394             if Token = Tok_Semicolon then
395                T_Semicolon;
396
397             --  Semicolon is missing. If the missing semicolon is at the end
398             --  of the line, i.e. we are at the start of the line now, then
399             --  a missing semicolon gets flagged, but is not serious enough
400             --  to consider the END statement to be bad in the sense that we
401             --  are dealing with (i.e. to be suspicious that this END is not
402             --  the END statement we are looking for).
403
404             --  Similarly, if we are at a colon, we flag it but a colon for
405             --  a semicolon is not serious enough to consider the END to be
406             --  incorrect. Same thing for a period in place of a semicolon.
407
408             elsif Token_Is_At_Start_Of_Line
409               or else Token = Tok_Colon
410               or else Token = Tok_Dot
411             then
412                T_Semicolon;
413
414             --  If the missing semicolon is not at the start of the line,
415             --  then we do consider the END line to be dubious in this sense.
416
417             else
418                End_OK := False;
419             end if;
420          end if;
421       end if;
422
423       --  Now we call the Pop_End_Context routine to get a recommendation
424       --  as to what should be done with the END sequence we have scanned.
425
426       Pop_End_Context;
427
428       --  Remaining action depends on End_Action set by Pop_End_Context
429
430       case End_Action is
431
432          --  Accept_As_Scanned. In this case, Pop_End_Context left Token
433          --  pointing past the last token of a syntactically correct END
434
435          when Accept_As_Scanned =>
436
437             --  Syntactically correct included the possibility of a missing
438             --  semicolon. If we do have a missing semicolon, then we have
439             --  already given a message, but now we scan out possible rubbish
440             --  on the same line as the END
441
442             while not Token_Is_At_Start_Of_Line
443               and then Prev_Token /= Tok_Record
444               and then Prev_Token /= Tok_Semicolon
445               and then Token /= Tok_End
446               and then Token /= Tok_EOF
447             loop
448                Scan; -- past junk
449             end loop;
450
451             return True;
452
453          --  Insert_And_Accept. In this case, Pop_End_Context has reset Token
454          --  to point to the start of the END sequence, and recommends that it
455          --  be left in place to satisfy an outer scope level END. This means
456          --  that we proceed as though an END were present, and leave the scan
457          --  pointer unchanged.
458
459          when Insert_And_Accept =>
460             return True;
461
462          --  Skip_And_Accept. In this case, Pop_End_Context has reset Token
463          --  to point to the start of the END sequence. This END sequence is
464          --  syntactically incorrect, and an appropriate error message has
465          --  already been posted. Pop_End_Context recommends accepting the
466          --  END sequence as the one we want, so we skip past it and then
467          --  proceed as though an END were present.
468
469          when Skip_And_Accept =>
470             End_Skip;
471             return True;
472
473          --  Skip_And_Reject. In this case, Pop_End_Context has reset Token
474          --  to point to the start of the END sequence. This END sequence is
475          --  syntactically incorrect, and an appropriate error message has
476          --  already been posted. Pop_End_Context recommends entirely ignoring
477          --  this END sequence, so we skip past it and then return False, since
478          --  as far as the caller is concerned, no END sequence is present.
479
480          when Skip_And_Reject =>
481             End_Skip;
482             return False;
483       end case;
484    end Check_End;
485
486    --------------
487    -- End Skip --
488    --------------
489
490    --  This procedure skips past an END sequence. On entry Token contains
491    --  Tok_End, and we know that the END sequence is syntactically incorrect,
492    --  and that an appropriate error message has already been posted. The
493    --  mission is simply to position the scan pointer to be the best guess of
494    --  the position after the END sequence. We do not issue any additional
495    --  error messages while carrying this out.
496
497    --  Error recovery: does not raise Error_Resync
498
499    procedure End_Skip is
500    begin
501       Scan; -- past END
502
503       --  If the scan past the END leaves us on the next line, that's probably
504       --  where we should quit the scan, since it is likely that what we have
505       --  is a missing semicolon. Consider the following:
506
507       --       END
508       --       Process_Input;
509
510       --  This will have looked like a syntactically valid END sequence to the
511       --  initial scan of the END, but subsequent checking will have determined
512       --  that the label Process_Input is not an appropriate label. The real
513       --  error is a missing semicolon after the END, and by leaving the scan
514       --  pointer just past the END, we will improve the error recovery.
515
516       if Token_Is_At_Start_Of_Line then
517          return;
518       end if;
519
520       --  If there is a semicolon after the END, scan it out and we are done
521
522       if Token = Tok_Semicolon then
523          T_Semicolon;
524          return;
525       end if;
526
527       --  Otherwise skip past a token after the END on the same line. Note
528       --  that we do not eat a token on the following line since it seems
529       --  very unlikely in any case that the END gets separated from its
530       --  token, and we do not want to swallow up a keyword that starts a
531       --  legitimate construct following the bad END.
532
533       if not Token_Is_At_Start_Of_Line
534         and then
535
536          --  Cases of normal tokens following an END
537
538           (Token = Tok_Case   or else
539            Token = Tok_For    or else
540            Token = Tok_If     or else
541            Token = Tok_Loop   or else
542            Token = Tok_Record or else
543            Token = Tok_Select or else
544
545          --  Cases of bogus keywords ending loops
546
547            Token = Tok_For    or else
548            Token = Tok_While  or else
549
550          --  Cases of operator symbol names without quotes
551
552            Token = Tok_Abs    or else
553            Token = Tok_And    or else
554            Token = Tok_Mod    or else
555            Token = Tok_Not    or else
556            Token = Tok_Or     or else
557            Token = Tok_Xor)
558
559       then
560          Scan; -- past token after END
561
562          --  If that leaves us on the next line, then we are done. This is the
563          --  same principle described above for the case of END at line end
564
565          if Token_Is_At_Start_Of_Line then
566             return;
567
568          --  If we just scanned out record, then we are done, since the
569          --  semicolon after END RECORD is not part of the END sequence
570
571          elsif Prev_Token = Tok_Record then
572             return;
573
574          --  If we have a semicolon, scan it out and we are done
575
576          elsif Token = Tok_Semicolon then
577             T_Semicolon;
578             return;
579          end if;
580       end if;
581
582       --  Check for a label present on the same line
583
584       loop
585          if Token_Is_At_Start_Of_Line then
586             return;
587          end if;
588
589          if Token /= Tok_Identifier
590            and then Token /= Tok_Operator_Symbol
591            and then Token /= Tok_String_Literal
592          then
593             exit;
594          end if;
595
596          Scan; -- past identifier, operator symbol or string literal
597
598          if Token_Is_At_Start_Of_Line then
599             return;
600          elsif Token = Tok_Dot then
601             Scan; -- past dot
602          end if;
603       end loop;
604
605       --  Skip final semicolon
606
607       if Token = Tok_Semicolon then
608          T_Semicolon;
609
610       --  If we don't have a final semicolon, skip until we either encounter
611       --  an END token, or a semicolon or the start of the next line. This
612       --  allows general junk to follow the end line (normally it is hard to
613       --  think that anyone will put anything deliberate here, and remember
614       --  that we know there is a missing semicolon in any case). We also
615       --  quite on an EOF (or else we would get stuck in an infinite loop
616       --  if there is no line end at the end of the last line of the file)
617
618       else
619          while Token /= Tok_End
620            and then Token /= Tok_EOF
621            and then Token /= Tok_Semicolon
622            and then not Token_Is_At_Start_Of_Line
623          loop
624             Scan; -- past junk token on same line
625          end loop;
626       end if;
627
628       return;
629    end End_Skip;
630
631    --------------------
632    -- End Statements --
633    --------------------
634
635    --  This procedure is called when END is required or expected to terminate
636    --  a sequence of statements. The caller has already made an appropriate
637    --  entry on the scope stack to describe the expected form of the END.
638    --  End_Statements should only be used in cases where the only appropriate
639    --  terminator is END.
640
641    --  Error recovery: cannot raise Error_Resync;
642
643    procedure End_Statements (Parent : Node_Id := Empty) is
644    begin
645       --  This loop runs more than once in the case where Check_End rejects
646       --  the END sequence, as indicated by Check_End returning False.
647
648       loop
649          if Check_End then
650             if Present (Parent) then
651                Set_End_Label (Parent, End_Labl);
652             end if;
653
654             return;
655          end if;
656
657          --  Extra statements past the bogus END are discarded. This is not
658          --  ideal for maximum error recovery, but it's too much trouble to
659          --  find an appropriate place to put them!
660
661          Discard_Junk_List (P_Sequence_Of_Statements (SS_None));
662       end loop;
663    end End_Statements;
664
665    ------------------------
666    -- Evaluate End Entry --
667    ------------------------
668
669    procedure Evaluate_End_Entry (SS_Index : Nat) is
670    begin
671       Column_OK := (End_Column = Scope.Table (SS_Index).Ecol);
672
673       Token_OK  := (End_Type = Scope.Table (SS_Index).Etyp or else
674                      (End_Type = E_Name and then
675                        Scope.Table (SS_Index).Etyp >= E_Name));
676
677       Label_OK := End_Labl_Present
678                     and then
679                       (Same_Label (End_Labl, Scope.Table (SS_Index).Labl)
680                         or else Scope.Table (SS_Index).Labl = Error);
681
682       --  Compute setting of Syntax_OK. We definitely have a syntax error
683       --  if the Token does not match properly or if P_End_Scan detected
684       --  a syntax error such as a missing semicolon.
685
686       if not Token_OK or not End_OK then
687          Syntax_OK := False;
688
689       --  Final check is that label is OK. Certainly it is OK if there
690       --  was an exact match on the label (the END label = the stack label)
691
692       elsif Label_OK then
693          Syntax_OK := True;
694
695       --  Case of label present
696
697       elsif End_Labl_Present then
698
699          --  If probably misspelling, then complain, and pretend it is OK
700
701          declare
702             Nam : constant Node_Or_Entity_Id := Scope.Table (SS_Index).Labl;
703
704          begin
705             if Nkind (End_Labl) in N_Has_Chars
706               and then Comes_From_Source (Nam)
707               and then Nkind (Nam) in N_Has_Chars
708               and then Chars (End_Labl) > Error_Name
709               and then Chars (Nam) > Error_Name
710             then
711                Get_Name_String (Chars (End_Labl));
712                Error_Msg_Name_1 := Chars (Nam);
713
714                if Error_Msg_Name_1 > Error_Name then
715                   declare
716                      S : constant String (1 .. Name_Len) :=
717                            Name_Buffer (1 .. Name_Len);
718
719                   begin
720                      Get_Name_String (Error_Msg_Name_1);
721
722                      if Is_Bad_Spelling_Of
723                          (Name_Buffer (1 .. Name_Len), S)
724                      then
725                         Error_Msg_N ("misspelling of %", End_Labl);
726                         Syntax_OK := True;
727                         return;
728                      end if;
729                   end;
730                end if;
731             end if;
732          end;
733
734          Syntax_OK := False;
735
736       --  Otherwise we have cases of no label on the END line. For the loop
737       --  case, this is acceptable only if the loop is unlabeled.
738
739       elsif End_Type = E_Loop then
740          Syntax_OK := not Explicit_Start_Label (SS_Index);
741
742       --  Cases where a label is definitely allowed on the END line
743
744       elsif End_Type = E_Name then
745          Syntax_OK := (not Explicit_Start_Label (SS_Index))
746                          or else
747                       (not Scope.Table (SS_Index).Lreq);
748
749       --  Otherwise we have cases which don't allow labels anyway, so we
750       --  certainly accept an END which does not have a label.
751
752       else
753          Syntax_OK := True;
754       end if;
755    end Evaluate_End_Entry;
756
757    --------------------------
758    -- Explicit_Start_Label --
759    --------------------------
760
761    function Explicit_Start_Label (SS_Index : Nat) return Boolean is
762       L : constant Node_Id := Scope.Table (SS_Index).Labl;
763
764    begin
765       if No (L) then
766          return False;
767       elsif Comes_From_Source (L) then
768          return True;
769       else
770          return False;
771       end if;
772    end Explicit_Start_Label;
773
774    ------------------------
775    -- Output End Deleted --
776    ------------------------
777
778    procedure Output_End_Deleted is
779    begin
780
781       if End_Type = E_Loop then
782          Error_Msg_SC ("no LOOP for this `END LOOP`!");
783
784       elsif End_Type = E_Case then
785          Error_Msg_SC ("no CASE for this `END CASE`");
786
787       elsif End_Type = E_If then
788          Error_Msg_SC ("no IF for this `END IF`!");
789
790       elsif End_Type = E_Record then
791          Error_Msg_SC ("no RECORD for this `END RECORD`!");
792
793       elsif End_Type = E_Select then
794          Error_Msg_SC ("no SELECT for this `END SELECT`!");
795
796       else
797          Error_Msg_SC ("no BEGIN for this END!");
798       end if;
799    end Output_End_Deleted;
800
801    -------------------------
802    -- Output End Expected --
803    -------------------------
804
805    procedure Output_End_Expected (Ins : Boolean) is
806       End_Type : SS_End_Type;
807
808    begin
809       --  Suppress message if this was a potentially junk entry (e.g. a
810       --  record entry where no record keyword was present.
811
812       if Scope.Table (Scope.Last).Junk then
813          return;
814       end if;
815
816       End_Type := Scope.Table (Scope.Last).Etyp;
817       Error_Msg_Col    := Scope.Table (Scope.Last).Ecol;
818       Error_Msg_Sloc   := Scope.Table (Scope.Last).Sloc;
819
820       if Explicit_Start_Label (Scope.Last) then
821          Error_Msg_Node_1 := Scope.Table (Scope.Last).Labl;
822       else
823          Error_Msg_Node_1 := Empty;
824       end if;
825
826       --  Suppress message if error was posted on opening label
827
828       if Error_Msg_Node_1 > Empty_Or_Error
829         and then Error_Posted (Error_Msg_Node_1)
830       then
831          return;
832       end if;
833
834       if End_Type = E_Case then
835          Error_Msg_SC ("`END CASE;` expected@ for CASE#!");
836
837       elsif End_Type = E_If then
838          Error_Msg_SC ("`END IF;` expected@ for IF#!");
839
840       elsif End_Type = E_Loop then
841          if Error_Msg_Node_1 = Empty then
842             Error_Msg_SC
843               ("`END LOOP;` expected@ for LOOP#!");
844          else
845             Error_Msg_SC ("`END LOOP &;` expected@!");
846          end if;
847
848       elsif End_Type = E_Record then
849          Error_Msg_SC
850            ("`END RECORD;` expected@ for RECORD#!");
851
852       elsif End_Type = E_Select then
853          Error_Msg_SC
854            ("`END SELECT;` expected@ for SELECT#!");
855
856       --  All remaining cases are cases with a name (we do not treat
857       --  the suspicious is cases specially for a replaced end, only
858       --  for an inserted end).
859
860       elsif End_Type = E_Name or else (not Ins) then
861          if Error_Msg_Node_1 = Empty then
862             Error_Msg_SC ("`END;` expected@ for BEGIN#!");
863          else
864             Error_Msg_SC ("`END &;` expected@!");
865          end if;
866
867       --  The other possibility is a missing END for a subprogram with a
868       --  suspicious IS (that probably should have been a semicolon). The
869       --  Missing IS confirms the suspicion!
870
871       else -- End_Type = E_Suspicious_Is or E_Bad_Is
872          Scope.Table (Scope.Last).Etyp := E_Bad_Is;
873       end if;
874    end Output_End_Expected;
875
876    ------------------------
877    -- Output End Missing --
878    ------------------------
879
880    procedure Output_End_Missing is
881       End_Type : SS_End_Type;
882
883    begin
884       --  Suppress message if this was a potentially junk entry (e.g. a
885       --  record entry where no record keyword was present.
886
887       if Scope.Table (Scope.Last).Junk then
888          return;
889       end if;
890
891       End_Type := Scope.Table (Scope.Last).Etyp;
892       Error_Msg_Sloc   := Scope.Table (Scope.Last).Sloc;
893
894       if Explicit_Start_Label (Scope.Last) then
895          Error_Msg_Node_1 := Scope.Table (Scope.Last).Labl;
896       else
897          Error_Msg_Node_1 := Empty;
898       end if;
899
900       if End_Type = E_Case then
901          Error_Msg_BC ("missing `END CASE;` for CASE#!");
902
903       elsif End_Type = E_If then
904          Error_Msg_BC ("missing `END IF;` for IF#!");
905
906       elsif End_Type = E_Loop then
907          if Error_Msg_Node_1 = Empty then
908             Error_Msg_BC ("missing `END LOOP;` for LOOP#!");
909          else
910             Error_Msg_BC ("missing `END LOOP &;`!");
911          end if;
912
913       elsif End_Type = E_Record then
914          Error_Msg_SC
915            ("missing `END RECORD;` for RECORD#!");
916
917       elsif End_Type = E_Select then
918          Error_Msg_BC
919            ("missing `END SELECT;` for SELECT#!");
920
921       elsif End_Type = E_Name then
922          if Error_Msg_Node_1 = Empty then
923             Error_Msg_BC ("missing `END;` for BEGIN#!");
924          else
925             Error_Msg_BC ("missing `END &;`!");
926          end if;
927
928       else -- End_Type = E_Suspicious_Is or E_Bad_Is
929          Scope.Table (Scope.Last).Etyp := E_Bad_Is;
930       end if;
931    end Output_End_Missing;
932
933    ---------------------
934    -- Pop End Context --
935    ---------------------
936
937    procedure Pop_End_Context is
938
939       Pretty_Good : Boolean;
940       --  This flag is set True if the END sequence is syntactically incorrect,
941       --  but is (from a heuristic point of view), pretty likely to be simply
942       --  a misspelling of the intended END.
943
944       Outer_Match : Boolean;
945       --  This flag is set True if we decide that the current END sequence
946       --  belongs to some outer level entry in the scope stack, and thus
947       --  we will NOT eat it up in matching the current expected END.
948
949    begin
950       --  If not at END, then output END expected message
951
952       if End_Type = E_Dummy then
953          Output_End_Missing;
954          Pop_Scope_Stack;
955          End_Action := Insert_And_Accept;
956          return;
957
958       --  Otherwise we do have an END present
959
960       else
961          --  A special check. If we have END; followed by an end of file,
962          --  WITH or SEPARATE, then if we are not at the outer level, then
963          --  we have a sytax error. Consider the example:
964
965          --   ...
966          --      declare
967          --         X : Integer;
968          --      begin
969          --         X := Father (A);
970          --         Process (X, X);
971          --   end;
972          --   with Package1;
973          --   ...
974
975          --  Now the END; here is a syntactically correct closer for the
976          --  declare block, but if we eat it up, then we obviously have
977          --  a missing END for the outer context (since WITH can only appear
978          --  at the outer level.
979
980          --  In this situation, we always reserve the END; for the outer level,
981          --  even if it is in the wrong column. This is because it's much more
982          --  useful to have the error message point to the DECLARE than to the
983          --  package header in this case.
984
985          --  We also reserve an end with a name before the end of file if the
986          --  name is the one we expect at the outer level.
987
988          if (Token = Tok_EOF or else
989              Token = Tok_With or else
990              Token = Tok_Separate)
991            and then End_Type >= E_Name
992            and then (not End_Labl_Present
993                       or else Same_Label (End_Labl, Scope.Table (1).Labl))
994            and then Scope.Last > 1
995          then
996             Restore_Scan_State (Scan_State); -- to END
997             Output_End_Expected (Ins => True);
998             Pop_Scope_Stack;
999             End_Action := Insert_And_Accept;
1000             return;
1001          end if;
1002
1003          --  Otherwise we go through the normal END evaluation procedure
1004
1005          Evaluate_End_Entry (Scope.Last);
1006
1007          --  If top entry in stack is syntactically correct, then we have
1008          --  scanned it out and everything is fine. This is the required
1009          --  action to properly process correct Ada programs.
1010
1011          if Syntax_OK then
1012
1013             --  Complain if checking columns and END is not in right column.
1014             --  Right in this context means exactly right, or on the same
1015             --  line as the opener.
1016
1017             if Style.RM_Column_Check then
1018                if End_Column /= Scope.Table (Scope.Last).Ecol
1019                  and then Current_Line_Start > Scope.Table (Scope.Last).Sloc
1020                then
1021                   Error_Msg_Col := Scope.Table (Scope.Last).Ecol;
1022                   Error_Msg
1023                     ("(style) END in wrong column, should be@", End_Sloc);
1024                end if;
1025             end if;
1026
1027             --  One final check. If the end had a label, check for an exact
1028             --  duplicate of this end sequence, and if so, skip it with an
1029             --  appropriate message.
1030
1031             if End_Labl_Present and then Token = Tok_End then
1032                declare
1033                   Scan_State : Saved_Scan_State;
1034                   End_Loc    : constant Source_Ptr := Token_Ptr;
1035                   Nxt_Labl   : Node_Id;
1036                   Dup_Found  : Boolean := False;
1037
1038                begin
1039                   Save_Scan_State (Scan_State);
1040
1041                   Scan; -- past END
1042
1043                   if Token = Tok_Identifier
1044                     or else Token = Tok_Operator_Symbol
1045                   then
1046                      Nxt_Labl := P_Designator;
1047
1048                      --  We only consider it an error if the label is a match
1049                      --  and would be wrong for the level one above us, and
1050                      --  the indentation is the same.
1051
1052                      if Token = Tok_Semicolon
1053                        and then Same_Label (End_Labl, Nxt_Labl)
1054                        and then End_Column = Start_Column
1055                        and then
1056                          (Scope.Last = 1
1057                             or else
1058                               (not Explicit_Start_Label (Scope.Last - 1))
1059                                  or else
1060                               (not Same_Label
1061                                      (End_Labl,
1062                                       Scope.Table (Scope.Last - 1).Labl)))
1063                      then
1064                         T_Semicolon;
1065                         Error_Msg ("duplicate end line ignored", End_Loc);
1066                         Dup_Found := True;
1067                      end if;
1068                   end if;
1069
1070                   if not Dup_Found then
1071                      Restore_Scan_State (Scan_State);
1072                   end if;
1073                end;
1074             end if;
1075
1076             --  All OK, so return to caller indicating END is OK
1077
1078             Pop_Scope_Stack;
1079             End_Action := Accept_As_Scanned;
1080             return;
1081          end if;
1082
1083          --  If that check failed, then we definitely have an error. The issue
1084          --  is how to choose among three possible courses of action:
1085
1086          --   1. Ignore the current END text completely, scanning past it,
1087          --      deciding that it belongs neither to the current context,
1088          --      nor to any outer context.
1089
1090          --   2. Accept the current END text, scanning past it, and issuing
1091          --      an error message that it does not have the right form.
1092
1093          --   3. Leave the current END text in place, NOT scanning past it,
1094          --      issuing an error message indicating the END expected for the
1095          --      current context. In this case, the END is available to match
1096          --      some outer END context.
1097
1098          --  From a correct functioning point of view, it does not make any
1099          --  difference which of these three approaches we take, the program
1100          --  will work correctly in any case. However, making an accurate
1101          --  choice among these alternatives, i.e. choosing the one that
1102          --  corresponds to what the programmer had in mind, does make a
1103          --  significant difference in the quality of error recovery.
1104
1105          Restore_Scan_State (Scan_State); -- to END
1106
1107          --  First we see how good the current END entry is with respect to
1108          --  what we expect. It is considered pretty good if the token is OK,
1109          --  and either the label or the column matches. an END for RECORD is
1110          --  always considered to be pretty good in the record case. This is
1111          --  because not only does a record disallow a nested structure, but
1112          --  also it is unlikely that such nesting could occur by accident.
1113
1114          Pretty_Good := (Token_OK and (Column_OK or Label_OK))
1115                           or else Scope.Table (Scope.Last).Etyp = E_Record;
1116
1117          --  Next check, if there is a deeper entry in the stack which
1118          --  has a very high probability of being acceptable, then insert
1119          --  the END entry we want, leaving the higher level entry for later
1120
1121          for J in reverse 1 .. Scope.Last - 1 loop
1122             Evaluate_End_Entry (J);
1123
1124             --  To even consider the deeper entry to be immediately acceptable,
1125             --  it must be syntactically correct. Furthermore it must either
1126             --  have a correct label, or the correct column. If the current
1127             --  entry was a close match (Pretty_Good set), then we are even
1128             --  more strict in accepting the outer level one: even if it has
1129             --  the right label, it must have the right column as well.
1130
1131             if Syntax_OK then
1132                if Pretty_Good then
1133                   Outer_Match := Label_OK and Column_OK;
1134                else
1135                   Outer_Match := Label_OK or Column_OK;
1136                end if;
1137             else
1138                Outer_Match := False;
1139             end if;
1140
1141             --  If the outer entry does convincingly match the END text, then
1142             --  back up the scan to the start of the END sequence, issue an
1143             --  error message indicating the END we expected, and return with
1144             --  Token pointing to the END (case 3 from above discussion).
1145
1146             if Outer_Match then
1147                Output_End_Missing;
1148                Pop_Scope_Stack;
1149                End_Action := Insert_And_Accept;
1150                return;
1151             end if;
1152          end loop;
1153
1154          --  Here we have a situation in which the current END entry is
1155          --  syntactically incorrect, but there is no deeper entry in the
1156          --  END stack which convincingly matches it.
1157
1158          --  If the END text was judged to be a Pretty_Good match for the
1159          --  expected token or if it appears left of the expected column,
1160          --  then we will accept it as the one we want, scanning past it, even
1161          --  though it is not completely right (we issue a message showing what
1162          --  we expected it to be). This is action 2 from the discussion above.
1163          --  There is one other special case to consider: the LOOP case.
1164          --  Consider the example:
1165
1166          --     Lbl: loop
1167          --             null;
1168          --          end loop;
1169
1170          --  Here the column lines up with Lbl, so END LOOP is to the right,
1171          --  but it is still acceptable. LOOP is the one case where alignment
1172          --  practices vary substantially in practice.
1173
1174          if Pretty_Good
1175             or else End_Column <= Scope.Table (Scope.Last).Ecol
1176             or else (End_Type = Scope.Table (Scope.Last).Etyp
1177                         and then End_Type = E_Loop)
1178          then
1179             Output_End_Expected (Ins => False);
1180             Pop_Scope_Stack;
1181             End_Action := Skip_And_Accept;
1182             return;
1183
1184          --  Here we have the case where the END is to the right of the
1185          --  expected column and does not have a correct label to convince
1186          --  us that it nevertheless belongs to the current scope. For this
1187          --  we consider that it probably belongs not to the current context,
1188          --  but to some inner context that was not properly recognized (due to
1189          --  other syntax errors), and for which no proper scope stack entry
1190          --  was made. The proper action in this case is to delete the END text
1191          --  and return False to the caller as a signal to keep on looking for
1192          --  an acceptable END. This is action 1 from the discussion above.
1193
1194          else
1195             Output_End_Deleted;
1196             End_Action := Skip_And_Reject;
1197             return;
1198          end if;
1199       end if;
1200    end Pop_End_Context;
1201
1202    ----------------
1203    -- Same_Label --
1204    ----------------
1205
1206    function Same_Label (Label1, Label2 : Node_Id) return Boolean is
1207    begin
1208       if Nkind (Label1) in N_Has_Chars
1209         and then Nkind (Label2) in N_Has_Chars
1210       then
1211          return Chars (Label1) = Chars (Label2);
1212
1213       elsif Nkind (Label1) = N_Selected_Component
1214         and then Nkind (Label2) = N_Selected_Component
1215       then
1216          return Same_Label (Prefix (Label1), Prefix (Label2)) and then
1217            Same_Label (Selector_Name (Label1), Selector_Name (Label2));
1218
1219       elsif Nkind (Label1) = N_Designator
1220         and then Nkind (Label2) = N_Defining_Program_Unit_Name
1221       then
1222          return Same_Label (Name (Label1), Name (Label2)) and then
1223            Same_Label (Identifier (Label1), Defining_Identifier (Label2));
1224
1225       else
1226          return False;
1227       end if;
1228    end Same_Label;
1229
1230 end Endh;