OSDN Git Service

d91b2d9f15dceb2c035bf0d702dc1e25d729381e
[pf3gnuchains/gcc-fork.git] / gcc / ada / par-ch6.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                              P A R . C H 6                               --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 1992-2008, Free Software Foundation, Inc.         --
10 --                                                                          --
11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
12 -- terms of the  GNU General Public License as published  by the Free Soft- --
13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
17 -- for  more details.  You should have  received  a copy of the GNU General --
18 -- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license.          --
20 --                                                                          --
21 -- GNAT was originally developed  by the GNAT team at  New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
23 --                                                                          --
24 ------------------------------------------------------------------------------
25
26 pragma Style_Checks (All_Checks);
27 --  Turn off subprogram body ordering check. Subprograms are in order
28 --  by RM section rather than alphabetical
29
30 with Sinfo.CN; use Sinfo.CN;
31
32 separate (Par)
33 package body Ch6 is
34
35    --  Local subprograms, used only in this chapter
36
37    function P_Defining_Designator        return Node_Id;
38    function P_Defining_Operator_Symbol   return Node_Id;
39    function P_Return_Object_Declaration  return Node_Id;
40
41    procedure P_Return_Subtype_Indication (Decl_Node : Node_Id);
42    --  Decl_Node is a N_Object_Declaration.
43    --  Set the Null_Exclusion_Present and Object_Definition fields of
44    --  Decl_Node.
45
46    procedure Check_Junk_Semicolon_Before_Return;
47
48    --  Check for common error of junk semicolon before RETURN keyword of
49    --  function specification. If present, skip over it with appropriate
50    --  error message, leaving Scan_Ptr pointing to the RETURN after. This
51    --  routine also deals with a possibly misspelled version of Return.
52
53    ----------------------------------------
54    -- Check_Junk_Semicolon_Before_Return --
55    ----------------------------------------
56
57    procedure Check_Junk_Semicolon_Before_Return is
58       Scan_State : Saved_Scan_State;
59
60    begin
61       if Token = Tok_Semicolon then
62          Save_Scan_State (Scan_State);
63          Scan; -- past the semicolon
64
65          if Token = Tok_Return then
66             Restore_Scan_State (Scan_State);
67             Error_Msg_SC ("|extra "";"" ignored");
68             Scan; -- rescan past junk semicolon
69          else
70             Restore_Scan_State (Scan_State);
71          end if;
72
73       elsif Bad_Spelling_Of (Tok_Return) then
74          null;
75       end if;
76    end Check_Junk_Semicolon_Before_Return;
77
78    -----------------------------------------------------
79    -- 6.1  Subprogram (Also 6.3, 8.5.4, 10.1.3, 12.3) --
80    -----------------------------------------------------
81
82    --  This routine scans out a subprogram declaration, subprogram body,
83    --  subprogram renaming declaration or subprogram generic instantiation.
84
85    --  SUBPROGRAM_DECLARATION ::= SUBPROGRAM_SPECIFICATION;
86
87    --  ABSTRACT_SUBPROGRAM_DECLARATION ::=
88    --    SUBPROGRAM_SPECIFICATION is abstract;
89
90    --  SUBPROGRAM_SPECIFICATION ::=
91    --      procedure DEFINING_PROGRAM_UNIT_NAME PARAMETER_PROFILE
92    --    | function DEFINING_DESIGNATOR PARAMETER_AND_RESULT_PROFILE
93
94    --  PARAMETER_PROFILE ::= [FORMAL_PART]
95
96    --  PARAMETER_AND_RESULT_PROFILE ::= [FORMAL_PART] return SUBTYPE_MARK
97
98    --  SUBPROGRAM_BODY ::=
99    --    SUBPROGRAM_SPECIFICATION is
100    --      DECLARATIVE_PART
101    --    begin
102    --      HANDLED_SEQUENCE_OF_STATEMENTS
103    --    end [DESIGNATOR];
104
105    --  SUBPROGRAM_RENAMING_DECLARATION ::=
106    --    SUBPROGRAM_SPECIFICATION renames callable_entity_NAME;
107
108    --  SUBPROGRAM_BODY_STUB ::=
109    --    SUBPROGRAM_SPECIFICATION is separate;
110
111    --  GENERIC_INSTANTIATION ::=
112    --    procedure DEFINING_PROGRAM_UNIT_NAME is
113    --      new generic_procedure_NAME [GENERIC_ACTUAL_PART];
114    --  | function DEFINING_DESIGNATOR is
115    --      new generic_function_NAME [GENERIC_ACTUAL_PART];
116
117    --  NULL_PROCEDURE_DECLARATION ::=
118    --    SUBPROGRAM_SPECIFICATION is null;
119
120    --  Null procedures are an Ada 2005 feature. A null procedure declaration
121    --  is classified as a basic declarative item, but it is parsed here, with
122    --  other subprogram constructs.
123
124    --  The value in Pf_Flags indicates which of these possible declarations
125    --  is acceptable to the caller:
126
127    --    Pf_Flags.Decl                 Set if declaration OK
128    --    Pf_Flags.Gins                 Set if generic instantiation OK
129    --    Pf_Flags.Pbod                 Set if proper body OK
130    --    Pf_Flags.Rnam                 Set if renaming declaration OK
131    --    Pf_Flags.Stub                 Set if body stub OK
132
133    --  If an inappropriate form is encountered, it is scanned out but an
134    --  error message indicating that it is appearing in an inappropriate
135    --  context is issued. The only possible values for Pf_Flags are those
136    --  defined as constants in the Par package.
137
138    --  The caller has checked that the initial token is FUNCTION, PROCEDURE,
139    --  NOT or OVERRIDING.
140
141    --  Error recovery: cannot raise Error_Resync
142
143    function P_Subprogram (Pf_Flags : Pf_Rec) return Node_Id is
144       Specification_Node : Node_Id;
145       Name_Node          : Node_Id;
146       Fpart_List         : List_Id;
147       Fpart_Sloc         : Source_Ptr;
148       Result_Not_Null    : Boolean := False;
149       Result_Node        : Node_Id;
150       Inst_Node          : Node_Id;
151       Body_Node          : Node_Id;
152       Decl_Node          : Node_Id;
153       Rename_Node        : Node_Id;
154       Absdec_Node        : Node_Id;
155       Stub_Node          : Node_Id;
156       Fproc_Sloc         : Source_Ptr;
157       Func               : Boolean;
158       Scan_State         : Saved_Scan_State;
159
160       --  Flags for optional overriding indication. Two flags are needed,
161       --  to distinguish positive and negative overriding indicators from
162       --  the absence of any indicator.
163
164       Is_Overriding  : Boolean := False;
165       Not_Overriding : Boolean := False;
166
167    begin
168       --  Set up scope stack entry. Note that the Labl field will be set later
169
170       SIS_Entry_Active := False;
171       SIS_Missing_Semicolon_Message := No_Error_Msg;
172       Push_Scope_Stack;
173       Scope.Table (Scope.Last).Sloc := Token_Ptr;
174       Scope.Table (Scope.Last).Etyp := E_Name;
175       Scope.Table (Scope.Last).Ecol := Start_Column;
176       Scope.Table (Scope.Last).Lreq := False;
177
178       --  Ada2005: scan leading NOT OVERRIDING indicator
179
180       if Token = Tok_Not then
181          Scan;  -- past NOT
182
183          if Token = Tok_Overriding then
184             Scan;  --  past OVERRIDING
185             Not_Overriding := True;
186
187          --  Overriding keyword used in non Ada 2005 mode
188
189          elsif Token = Tok_Identifier
190            and then Token_Name = Name_Overriding
191          then
192             Error_Msg_SC ("overriding indicator is an Ada 2005 extension");
193             Error_Msg_SC ("\unit must be compiled with -gnat05 switch");
194             Scan;  --  past Overriding
195             Not_Overriding := True;
196
197          else
198             Error_Msg_SC ("OVERRIDING expected!");
199          end if;
200
201       --  Ada 2005: scan leading OVERRIDING indicator
202
203       --  Note: in the case of OVERRIDING keyword used in Ada 95 mode, the
204       --  declaration circuit already gave an error message and changed the
205       --  token to Tok_Overriding.
206
207       elsif Token = Tok_Overriding then
208          Scan;  --  past OVERRIDING
209          Is_Overriding := True;
210       end if;
211
212       if (Is_Overriding or else Not_Overriding) then
213
214          --  Note that if we are not in Ada_05 mode, error messages have
215          --  already been given, so no need to give another message here.
216
217          --  An overriding indicator is allowed for subprogram declarations,
218          --  bodies, renamings, stubs, and instantiations. The test against
219          --  Pf_Decl_Pbod is added to account for the case of subprograms
220          --  declared in a protected type, where only subprogram declarations
221          --  and bodies can occur.
222
223          if Pf_Flags /= Pf_Decl_Gins_Pbod_Rnam_Stub
224               and then
225             Pf_Flags /= Pf_Decl_Pbod
226          then
227             Error_Msg_SC ("overriding indicator not allowed here!");
228
229          elsif Token /= Tok_Function and then Token /= Tok_Procedure then
230             Error_Msg_SC ("FUNCTION or PROCEDURE expected!");
231          end if;
232       end if;
233
234       Func := (Token = Tok_Function);
235       Fproc_Sloc := Token_Ptr;
236       Scan; -- past FUNCTION or PROCEDURE
237       Ignore (Tok_Type);
238       Ignore (Tok_Body);
239
240       if Func then
241          Name_Node := P_Defining_Designator;
242
243          if Nkind (Name_Node) = N_Defining_Operator_Symbol
244            and then Scope.Last = 1
245          then
246             Error_Msg_SP ("operator symbol not allowed at library level");
247             Name_Node := New_Entity (N_Defining_Identifier, Sloc (Name_Node));
248
249             --  Set name from file name, we need some junk name, and that's
250             --  as good as anything. This is only approximate, since we do
251             --  not do anything with non-standard name translations.
252
253             Get_Name_String (File_Name (Current_Source_File));
254
255             for J in 1 .. Name_Len loop
256                if Name_Buffer (J) = '.' then
257                   Name_Len := J - 1;
258                   exit;
259                end if;
260             end loop;
261
262             Set_Chars (Name_Node, Name_Find);
263             Set_Error_Posted (Name_Node);
264          end if;
265
266       else
267          Name_Node := P_Defining_Program_Unit_Name;
268       end if;
269
270       Scope.Table (Scope.Last).Labl := Name_Node;
271       Ignore (Tok_Colon);
272
273       --  Deal with generic instantiation, the one case in which we do not
274       --  have a subprogram specification as part of whatever we are parsing
275
276       if Token = Tok_Is then
277          Save_Scan_State (Scan_State); -- at the IS
278          T_Is; -- checks for redundant IS
279
280          if Token = Tok_New then
281             if not Pf_Flags.Gins then
282                Error_Msg_SC ("generic instantiation not allowed here!");
283             end if;
284
285             Scan; -- past NEW
286
287             if Func then
288                Inst_Node := New_Node (N_Function_Instantiation, Fproc_Sloc);
289                Set_Name (Inst_Node, P_Function_Name);
290             else
291                Inst_Node := New_Node (N_Procedure_Instantiation, Fproc_Sloc);
292                Set_Name (Inst_Node, P_Qualified_Simple_Name);
293             end if;
294
295             Set_Defining_Unit_Name (Inst_Node, Name_Node);
296             Set_Generic_Associations (Inst_Node, P_Generic_Actual_Part_Opt);
297             TF_Semicolon;
298             Pop_Scope_Stack; -- Don't need scope stack entry in this case
299
300             if Is_Overriding then
301                Set_Must_Override (Inst_Node);
302
303             elsif Not_Overriding then
304                Set_Must_Not_Override (Inst_Node);
305             end if;
306
307             return Inst_Node;
308
309          else
310             Restore_Scan_State (Scan_State); -- to the IS
311          end if;
312       end if;
313
314       --  If not a generic instantiation, then we definitely have a subprogram
315       --  specification (all possibilities at this stage include one here)
316
317       Fpart_Sloc := Token_Ptr;
318
319       Check_Misspelling_Of (Tok_Return);
320
321       --  Scan formal part. First a special error check. If we have an
322       --  identifier here, then we have a definite error. If this identifier
323       --  is on the same line as the designator, then we assume it is the
324       --  first formal after a missing left parenthesis
325
326       if Token = Tok_Identifier
327         and then not Token_Is_At_Start_Of_Line
328       then
329             T_Left_Paren; -- to generate message
330             Fpart_List := P_Formal_Part;
331
332       --  Otherwise scan out an optional formal part in the usual manner
333
334       else
335          Fpart_List := P_Parameter_Profile;
336       end if;
337
338       --  We treat what we have as a function specification if FUNCTION was
339       --  used, or if a RETURN is present. This gives better error recovery
340       --  since later RETURN statements will be valid in either case.
341
342       Check_Junk_Semicolon_Before_Return;
343       Result_Node := Error;
344
345       if Token = Tok_Return then
346          if not Func then
347             Error_Msg ("PROCEDURE should be FUNCTION", Fproc_Sloc);
348             Func := True;
349          end if;
350
351          Scan; -- past RETURN
352
353          Result_Not_Null := P_Null_Exclusion;     --  Ada 2005 (AI-231)
354
355          --  Ada 2005 (AI-318-02)
356
357          if Token = Tok_Access then
358             if Ada_Version < Ada_05 then
359                Error_Msg_SC
360                  ("anonymous access result type is an Ada 2005 extension");
361                Error_Msg_SC ("\unit must be compiled with -gnat05 switch");
362             end if;
363
364             Result_Node := P_Access_Definition (Result_Not_Null);
365
366          else
367             Result_Node := P_Subtype_Mark;
368             No_Constraint;
369          end if;
370
371       else
372          if Func then
373             Ignore (Tok_Right_Paren);
374             TF_Return;
375          end if;
376       end if;
377
378       if Func then
379          Specification_Node :=
380            New_Node (N_Function_Specification, Fproc_Sloc);
381
382          Set_Null_Exclusion_Present (Specification_Node, Result_Not_Null);
383          Set_Result_Definition (Specification_Node, Result_Node);
384
385       else
386          Specification_Node :=
387            New_Node (N_Procedure_Specification, Fproc_Sloc);
388       end if;
389
390       Set_Defining_Unit_Name (Specification_Node, Name_Node);
391       Set_Parameter_Specifications (Specification_Node, Fpart_List);
392
393       if Is_Overriding then
394          Set_Must_Override (Specification_Node);
395
396       elsif Not_Overriding then
397          Set_Must_Not_Override (Specification_Node);
398       end if;
399
400       --  Error check: barriers not allowed on protected functions/procedures
401
402       if Token = Tok_When then
403          if Func then
404             Error_Msg_SC ("barrier not allowed on function, only on entry");
405          else
406             Error_Msg_SC ("barrier not allowed on procedure, only on entry");
407          end if;
408
409          Scan; -- past WHEN
410          Discard_Junk_Node (P_Expression);
411       end if;
412
413       --  Deal with semicolon followed by IS. We want to treat this as IS
414
415       if Token = Tok_Semicolon then
416          Save_Scan_State (Scan_State);
417          Scan; -- past semicolon
418
419          if Token = Tok_Is then
420             Error_Msg_SP ("extra "";"" ignored");
421          else
422             Restore_Scan_State (Scan_State);
423          end if;
424       end if;
425
426       --  Deal with case of semicolon ending a subprogram declaration
427
428       if Token = Tok_Semicolon then
429          if not Pf_Flags.Decl then
430             T_Is;
431          end if;
432
433          Scan; -- past semicolon
434
435          --  If semicolon is immediately followed by IS, then ignore the
436          --  semicolon, and go process the body.
437
438          if Token = Tok_Is then
439             Error_Msg_SP ("|extra "";"" ignored");
440             T_Is; -- scan past IS
441             goto Subprogram_Body;
442
443          --  If BEGIN follows in an appropriate column, we immediately
444          --  commence the error action of assuming that the previous
445          --  subprogram declaration should have been a subprogram body,
446          --  i.e. that the terminating semicolon should have been IS.
447
448          elsif Token = Tok_Begin
449             and then Start_Column >= Scope.Table (Scope.Last).Ecol
450          then
451             Error_Msg_SP ("|"";"" should be IS!");
452             goto Subprogram_Body;
453
454          else
455             goto Subprogram_Declaration;
456          end if;
457
458       --  Case of not followed by semicolon
459
460       else
461          --  Subprogram renaming declaration case
462
463          Check_Misspelling_Of (Tok_Renames);
464
465          if Token = Tok_Renames then
466             if not Pf_Flags.Rnam then
467                Error_Msg_SC ("renaming declaration not allowed here!");
468             end if;
469
470             Rename_Node :=
471               New_Node (N_Subprogram_Renaming_Declaration, Token_Ptr);
472             Scan; -- past RENAMES
473             Set_Name (Rename_Node, P_Name);
474             Set_Specification (Rename_Node, Specification_Node);
475             TF_Semicolon;
476             Pop_Scope_Stack;
477             return Rename_Node;
478
479          --  Case of IS following subprogram specification
480
481          elsif Token = Tok_Is then
482             T_Is; -- ignore redundant Is's
483
484             if Token_Name = Name_Abstract then
485                Check_95_Keyword (Tok_Abstract, Tok_Semicolon);
486             end if;
487
488             --  Deal nicely with (now obsolete) use of <> in place of abstract
489
490             if Token = Tok_Box then
491                Error_Msg_SC ("ABSTRACT expected");
492                Token := Tok_Abstract;
493             end if;
494
495             --  Abstract subprogram declaration case
496
497             if Token = Tok_Abstract then
498                Absdec_Node :=
499                  New_Node (N_Abstract_Subprogram_Declaration, Token_Ptr);
500                Set_Specification (Absdec_Node, Specification_Node);
501                Pop_Scope_Stack; -- discard unneeded entry
502                Scan; -- past ABSTRACT
503                TF_Semicolon;
504                return Absdec_Node;
505
506             --  Ada 2005 (AI-248): Parse a null procedure declaration
507
508             elsif Token = Tok_Null then
509                if Ada_Version < Ada_05 then
510                   Error_Msg_SP ("null procedures are an Ada 2005 extension");
511                   Error_Msg_SP ("\unit must be compiled with -gnat05 switch");
512                end if;
513
514                Scan; -- past NULL
515
516                if Func then
517                   Error_Msg_SP ("only procedures can be null");
518                else
519                   Set_Null_Present (Specification_Node);
520                end if;
521
522                TF_Semicolon;
523                goto Subprogram_Declaration;
524
525             --  Check for IS NEW with Formal_Part present and handle nicely
526
527             elsif Token = Tok_New then
528                Error_Msg
529                  ("formal part not allowed in instantiation", Fpart_Sloc);
530                Scan; -- past NEW
531
532                if Func then
533                   Inst_Node := New_Node (N_Function_Instantiation, Fproc_Sloc);
534                else
535                   Inst_Node :=
536                     New_Node (N_Procedure_Instantiation, Fproc_Sloc);
537                end if;
538
539                Set_Defining_Unit_Name (Inst_Node, Name_Node);
540                Set_Name (Inst_Node, P_Name);
541                Set_Generic_Associations (Inst_Node, P_Generic_Actual_Part_Opt);
542                TF_Semicolon;
543                Pop_Scope_Stack; -- Don't need scope stack entry in this case
544                return Inst_Node;
545
546             else
547                goto Subprogram_Body;
548             end if;
549
550          --  Here we have a missing IS or missing semicolon, we always guess
551          --  a missing semicolon, since we are pretty good at fixing up a
552          --  semicolon which should really be an IS
553
554          else
555             Error_Msg_AP ("|missing "";""");
556             SIS_Missing_Semicolon_Message := Get_Msg_Id;
557             goto Subprogram_Declaration;
558          end if;
559       end if;
560
561       --  Processing for subprogram body
562
563       <<Subprogram_Body>>
564          if not Pf_Flags.Pbod then
565             Error_Msg_SP ("subprogram body not allowed here!");
566          end if;
567
568          --  Subprogram body stub case
569
570          if Separate_Present then
571             if not Pf_Flags.Stub then
572                Error_Msg_SC ("body stub not allowed here!");
573             end if;
574
575             if Nkind (Name_Node) = N_Defining_Operator_Symbol then
576                Error_Msg
577                  ("operator symbol cannot be used as subunit name",
578                   Sloc (Name_Node));
579             end if;
580
581             Stub_Node :=
582               New_Node (N_Subprogram_Body_Stub, Sloc (Specification_Node));
583             Set_Specification (Stub_Node, Specification_Node);
584             Scan; -- past SEPARATE
585             Pop_Scope_Stack;
586             TF_Semicolon;
587             return Stub_Node;
588
589          --  Subprogram body case
590
591          else
592             --  Here is the test for a suspicious IS (i.e. one that looks
593             --  like it might more properly be a semicolon). See separate
594             --  section discussing use of IS instead of semicolon in
595             --  package Parse.
596
597             if (Token in Token_Class_Declk
598                   or else
599                 Token = Tok_Identifier)
600               and then Start_Column <= Scope.Table (Scope.Last).Ecol
601               and then Scope.Last /= 1
602             then
603                Scope.Table (Scope.Last).Etyp := E_Suspicious_Is;
604                Scope.Table (Scope.Last).S_Is := Prev_Token_Ptr;
605             end if;
606
607             Body_Node :=
608               New_Node (N_Subprogram_Body, Sloc (Specification_Node));
609             Set_Specification (Body_Node, Specification_Node);
610             Parse_Decls_Begin_End (Body_Node);
611             return Body_Node;
612          end if;
613
614       --  Processing for subprogram declaration
615
616       <<Subprogram_Declaration>>
617          Decl_Node :=
618            New_Node (N_Subprogram_Declaration, Sloc (Specification_Node));
619          Set_Specification (Decl_Node, Specification_Node);
620
621          --  If this is a context in which a subprogram body is permitted,
622          --  set active SIS entry in case (see section titled "Handling
623          --  Semicolon Used in Place of IS" in body of Parser package)
624          --  Note that SIS_Missing_Semicolon_Message is already set properly.
625
626          if Pf_Flags.Pbod then
627             SIS_Labl := Scope.Table (Scope.Last).Labl;
628             SIS_Sloc := Scope.Table (Scope.Last).Sloc;
629             SIS_Ecol := Scope.Table (Scope.Last).Ecol;
630             SIS_Declaration_Node := Decl_Node;
631             SIS_Semicolon_Sloc := Prev_Token_Ptr;
632             SIS_Entry_Active := True;
633          end if;
634
635          Pop_Scope_Stack;
636          return Decl_Node;
637
638    end P_Subprogram;
639
640    ---------------------------------
641    -- 6.1  Subprogram Declaration --
642    ---------------------------------
643
644    --  Parsed by P_Subprogram (6.1)
645
646    ------------------------------------------
647    -- 6.1  Abstract Subprogram Declaration --
648    ------------------------------------------
649
650    --  Parsed by P_Subprogram (6.1)
651
652    -----------------------------------
653    -- 6.1  Subprogram Specification --
654    -----------------------------------
655
656    --  SUBPROGRAM_SPECIFICATION ::=
657    --      procedure DEFINING_PROGRAM_UNIT_NAME PARAMETER_PROFILE
658    --    | function DEFINING_DESIGNATOR PARAMETER_AND_RESULT_PROFILE
659
660    --  PARAMETER_PROFILE ::= [FORMAL_PART]
661
662    --  PARAMETER_AND_RESULT_PROFILE ::= [FORMAL_PART] return SUBTYPE_MARK
663
664    --  Subprogram specifications that appear in subprogram declarations
665    --  are parsed by P_Subprogram (6.1). This routine is used in other
666    --  contexts where subprogram specifications occur.
667
668    --  Note: this routine does not affect the scope stack in any way
669
670    --  Error recovery: can raise Error_Resync
671
672    function P_Subprogram_Specification return Node_Id is
673       Specification_Node : Node_Id;
674       Result_Not_Null    : Boolean;
675       Result_Node        : Node_Id;
676
677    begin
678       if Token = Tok_Function then
679          Specification_Node := New_Node (N_Function_Specification, Token_Ptr);
680          Scan; -- past FUNCTION
681          Ignore (Tok_Body);
682          Set_Defining_Unit_Name (Specification_Node, P_Defining_Designator);
683          Set_Parameter_Specifications
684            (Specification_Node, P_Parameter_Profile);
685          Check_Junk_Semicolon_Before_Return;
686          TF_Return;
687
688          Result_Not_Null := P_Null_Exclusion;     --  Ada 2005 (AI-231)
689
690          --  Ada 2005 (AI-318-02)
691
692          if Token = Tok_Access then
693             if Ada_Version < Ada_05 then
694                Error_Msg_SC
695                  ("anonymous access result type is an Ada 2005 extension");
696                Error_Msg_SC ("\unit must be compiled with -gnat05 switch");
697             end if;
698
699             Result_Node := P_Access_Definition (Result_Not_Null);
700
701          else
702             Result_Node := P_Subtype_Mark;
703             No_Constraint;
704          end if;
705
706          Set_Null_Exclusion_Present (Specification_Node, Result_Not_Null);
707          Set_Result_Definition (Specification_Node, Result_Node);
708          return Specification_Node;
709
710       elsif Token = Tok_Procedure then
711          Specification_Node := New_Node (N_Procedure_Specification, Token_Ptr);
712          Scan; -- past PROCEDURE
713          Ignore (Tok_Body);
714          Set_Defining_Unit_Name
715            (Specification_Node, P_Defining_Program_Unit_Name);
716          Set_Parameter_Specifications
717            (Specification_Node, P_Parameter_Profile);
718          return Specification_Node;
719
720       else
721          Error_Msg_SC ("subprogram specification expected");
722          raise Error_Resync;
723       end if;
724    end P_Subprogram_Specification;
725
726    ---------------------
727    -- 6.1  Designator --
728    ---------------------
729
730    --  DESIGNATOR ::=
731    --    [PARENT_UNIT_NAME .] IDENTIFIER | OPERATOR_SYMBOL
732
733    --  The caller has checked that the initial token is an identifier,
734    --  operator symbol, or string literal. Note that we don't bother to
735    --  do much error diagnosis in this routine, since it is only used for
736    --  the label on END lines, and the routines in package Par.Endh will
737    --  check that the label is appropriate.
738
739    --  Error recovery: cannot raise Error_Resync
740
741    function P_Designator return Node_Id is
742       Ident_Node  : Node_Id;
743       Name_Node   : Node_Id;
744       Prefix_Node : Node_Id;
745
746       function Real_Dot return Boolean;
747       --  Tests if a current token is an interesting period, i.e. is followed
748       --  by an identifier or operator symbol or string literal. If not, it is
749       --  probably just incorrect punctuation to be caught by our caller. Note
750       --  that the case of an operator symbol or string literal is also an
751       --  error, but that is an error that we catch here. If the result is
752       --  True, a real dot has been scanned and we are positioned past it,
753       --  if the result is False, the scan position is unchanged.
754
755       --------------
756       -- Real_Dot --
757       --------------
758
759       function Real_Dot return Boolean is
760          Scan_State  : Saved_Scan_State;
761
762       begin
763          if Token /= Tok_Dot then
764             return False;
765
766          else
767             Save_Scan_State (Scan_State);
768             Scan; -- past dot
769
770             if Token = Tok_Identifier
771               or else Token = Tok_Operator_Symbol
772               or else Token = Tok_String_Literal
773             then
774                return True;
775
776             else
777                Restore_Scan_State (Scan_State);
778                return False;
779             end if;
780          end if;
781       end Real_Dot;
782
783    --  Start of processing for P_Designator
784
785    begin
786       Ident_Node := Token_Node;
787       Scan; -- past initial token
788
789       if Prev_Token = Tok_Operator_Symbol
790         or else Prev_Token = Tok_String_Literal
791         or else not Real_Dot
792       then
793          return Ident_Node;
794
795       --  Child name case
796
797       else
798          Prefix_Node := Ident_Node;
799
800          --  Loop through child names, on entry to this loop, Prefix contains
801          --  the name scanned so far, and Ident_Node is the last identifier.
802
803          loop
804             Name_Node := New_Node (N_Selected_Component, Prev_Token_Ptr);
805             Set_Prefix (Name_Node, Prefix_Node);
806             Ident_Node := P_Identifier;
807             Set_Selector_Name (Name_Node, Ident_Node);
808             Prefix_Node := Name_Node;
809             exit when not Real_Dot;
810          end loop;
811
812          --  On exit from the loop, Ident_Node is the last identifier scanned,
813          --  i.e. the defining identifier, and Prefix_Node is a node for the
814          --  entire name, structured (incorrectly!) as a selected component.
815
816          Name_Node := Prefix (Prefix_Node);
817          Change_Node (Prefix_Node, N_Designator);
818          Set_Name (Prefix_Node, Name_Node);
819          Set_Identifier (Prefix_Node, Ident_Node);
820          return Prefix_Node;
821       end if;
822
823    exception
824       when Error_Resync =>
825          while Token = Tok_Dot or else Token = Tok_Identifier loop
826             Scan;
827          end loop;
828
829          return Error;
830    end P_Designator;
831
832    ------------------------------
833    -- 6.1  Defining Designator --
834    ------------------------------
835
836    --  DEFINING_DESIGNATOR ::=
837    --    DEFINING_PROGRAM_UNIT_NAME | DEFINING_OPERATOR_SYMBOL
838
839    --  Error recovery: cannot raise Error_Resync
840
841    function P_Defining_Designator return Node_Id is
842    begin
843       if Token = Tok_Operator_Symbol then
844          return P_Defining_Operator_Symbol;
845
846       elsif Token = Tok_String_Literal then
847          Error_Msg_SC ("invalid operator name");
848          Scan; -- past junk string
849          return Error;
850
851       else
852          return P_Defining_Program_Unit_Name;
853       end if;
854    end P_Defining_Designator;
855
856    -------------------------------------
857    -- 6.1  Defining Program Unit Name --
858    -------------------------------------
859
860    --  DEFINING_PROGRAM_UNIT_NAME ::=
861    --    [PARENT_UNIT_NAME .] DEFINING_IDENTIFIER
862
863    --  Note: PARENT_UNIT_NAME may be present only in 95 mode at the outer level
864
865    --  Error recovery: cannot raise Error_Resync
866
867    function P_Defining_Program_Unit_Name return Node_Id is
868       Ident_Node  : Node_Id;
869       Name_Node   : Node_Id;
870       Prefix_Node : Node_Id;
871
872    begin
873       --  Set identifier casing if not already set and scan initial identifier
874
875       if Token = Tok_Identifier
876         and then Identifier_Casing (Current_Source_File) = Unknown
877       then
878          Set_Identifier_Casing (Current_Source_File, Determine_Token_Casing);
879       end if;
880
881       Ident_Node := P_Identifier (C_Dot);
882       Merge_Identifier (Ident_Node, Tok_Return);
883
884       --  Normal case (not child library unit name)
885
886       if Token /= Tok_Dot then
887          Change_Identifier_To_Defining_Identifier (Ident_Node);
888          return Ident_Node;
889
890       --  Child library unit name case
891
892       else
893          if Scope.Last > 1 then
894             Error_Msg_SP ("child unit allowed only at library level");
895             raise Error_Resync;
896
897          elsif Ada_Version = Ada_83 then
898             Error_Msg_SP ("(Ada 83) child unit not allowed!");
899
900          end if;
901
902          Prefix_Node := Ident_Node;
903
904          --  Loop through child names, on entry to this loop, Prefix contains
905          --  the name scanned so far, and Ident_Node is the last identifier.
906
907          loop
908             exit when Token /= Tok_Dot;
909             Name_Node := New_Node (N_Selected_Component, Token_Ptr);
910             Scan; -- past period
911             Set_Prefix (Name_Node, Prefix_Node);
912             Ident_Node := P_Identifier (C_Dot);
913             Set_Selector_Name (Name_Node, Ident_Node);
914             Prefix_Node := Name_Node;
915          end loop;
916
917          --  On exit from the loop, Ident_Node is the last identifier scanned,
918          --  i.e. the defining identifier, and Prefix_Node is a node for the
919          --  entire name, structured (incorrectly!) as a selected component.
920
921          Name_Node := Prefix (Prefix_Node);
922          Change_Node (Prefix_Node, N_Defining_Program_Unit_Name);
923          Set_Name (Prefix_Node, Name_Node);
924          Change_Identifier_To_Defining_Identifier (Ident_Node);
925          Set_Defining_Identifier (Prefix_Node, Ident_Node);
926
927          --  All set with unit name parsed
928
929          return Prefix_Node;
930       end if;
931
932    exception
933       when Error_Resync =>
934          while Token = Tok_Dot or else Token = Tok_Identifier loop
935             Scan;
936          end loop;
937
938          return Error;
939    end P_Defining_Program_Unit_Name;
940
941    --------------------------
942    -- 6.1  Operator Symbol --
943    --------------------------
944
945    --  OPERATOR_SYMBOL ::= STRING_LITERAL
946
947    --  Operator symbol is returned by the scanner as Tok_Operator_Symbol
948
949    -----------------------------------
950    -- 6.1  Defining Operator Symbol --
951    -----------------------------------
952
953    --  DEFINING_OPERATOR_SYMBOL ::= OPERATOR_SYMBOL
954
955    --  The caller has checked that the initial symbol is an operator symbol
956
957    function P_Defining_Operator_Symbol return Node_Id is
958       Op_Node : Node_Id;
959
960    begin
961       Op_Node := Token_Node;
962       Change_Operator_Symbol_To_Defining_Operator_Symbol (Op_Node);
963       Scan; -- past operator symbol
964       return Op_Node;
965    end P_Defining_Operator_Symbol;
966
967    ----------------------------
968    -- 6.1  Parameter_Profile --
969    ----------------------------
970
971    --  PARAMETER_PROFILE ::= [FORMAL_PART]
972
973    --  Empty is returned if no formal part is present
974
975    --  Error recovery: cannot raise Error_Resync
976
977    function P_Parameter_Profile return List_Id is
978    begin
979       if Token = Tok_Left_Paren then
980          Scan; -- part left paren
981          return P_Formal_Part;
982       else
983          return No_List;
984       end if;
985    end P_Parameter_Profile;
986
987    ---------------------------------------
988    -- 6.1  Parameter And Result Profile --
989    ---------------------------------------
990
991    --  Parsed by its parent construct, which uses P_Parameter_Profile to
992    --  parse the parameters, and P_Subtype_Mark to parse the return type.
993
994    ----------------------
995    -- 6.1  Formal part --
996    ----------------------
997
998    --  FORMAL_PART ::= (PARAMETER_SPECIFICATION {; PARAMETER_SPECIFICATION})
999
1000    --  PARAMETER_SPECIFICATION ::=
1001    --    DEFINING_IDENTIFIER_LIST : MODE [NULL_EXCLUSION] SUBTYPE_MARK
1002    --      [:= DEFAULT_EXPRESSION]
1003    --  | DEFINING_IDENTIFIER_LIST : ACCESS_DEFINITION
1004    --      [:= DEFAULT_EXPRESSION]
1005
1006    --  This scans the construct Formal_Part. The caller has already checked
1007    --  that the initial token is a left parenthesis, and skipped past it, so
1008    --  that on entry Token is the first token following the left parenthesis.
1009
1010    --  Error recovery: cannot raise Error_Resync
1011
1012    function P_Formal_Part return List_Id is
1013       Specification_List : List_Id;
1014       Specification_Node : Node_Id;
1015       Scan_State         : Saved_Scan_State;
1016       Num_Idents         : Nat;
1017       Ident              : Nat;
1018       Ident_Sloc         : Source_Ptr;
1019       Not_Null_Present   : Boolean := False;
1020       Not_Null_Sloc      : Source_Ptr;
1021
1022       Idents : array (Int range 1 .. 4096) of Entity_Id;
1023       --  This array holds the list of defining identifiers. The upper bound
1024       --  of 4096 is intended to be essentially infinite, and we do not even
1025       --  bother to check for it being exceeded.
1026
1027    begin
1028       Specification_List := New_List;
1029       Specification_Loop : loop
1030          begin
1031             if Token = Tok_Pragma then
1032                Error_Msg_SC ("pragma not allowed in formal part");
1033                Discard_Junk_Node (P_Pragma (Skipping => True));
1034             end if;
1035
1036             Ignore (Tok_Left_Paren);
1037             Ident_Sloc := Token_Ptr;
1038             Idents (1) := P_Defining_Identifier (C_Comma_Colon);
1039             Num_Idents := 1;
1040
1041             Ident_Loop : loop
1042                exit Ident_Loop when Token = Tok_Colon;
1043
1044                --  The only valid tokens are colon and comma, so if we have
1045                --  neither do a bit of investigation to see which is the
1046                --  better choice for insertion.
1047
1048                if Token /= Tok_Comma then
1049
1050                   --  Assume colon if IN or OUT keyword found
1051
1052                   exit Ident_Loop when Token = Tok_In or else Token = Tok_Out;
1053
1054                   --  Otherwise scan ahead
1055
1056                   Save_Scan_State (Scan_State);
1057                   Look_Ahead : loop
1058
1059                      --  If we run into a semicolon, then assume that a
1060                      --  colon was missing, e.g.  Parms (X Y; ...). Also
1061                      --  assume missing colon on EOF (a real disaster!)
1062                      --  and on a right paren, e.g. Parms (X Y), and also
1063                      --  on an assignment symbol, e.g. Parms (X Y := ..)
1064
1065                      if Token = Tok_Semicolon
1066                        or else Token = Tok_Right_Paren
1067                        or else Token = Tok_EOF
1068                        or else Token = Tok_Colon_Equal
1069                      then
1070                         Restore_Scan_State (Scan_State);
1071                         exit Ident_Loop;
1072
1073                      --  If we run into a colon, assume that we had a missing
1074                      --  comma, e.g. Parms (A B : ...). Also assume a missing
1075                      --  comma if we hit another comma, e.g. Parms (A B, C ..)
1076
1077                      elsif Token = Tok_Colon
1078                        or else Token = Tok_Comma
1079                      then
1080                         Restore_Scan_State (Scan_State);
1081                         exit Look_Ahead;
1082                      end if;
1083
1084                      Scan;
1085                   end loop Look_Ahead;
1086                end if;
1087
1088                --  Here if a comma is present, or to be assumed
1089
1090                T_Comma;
1091                Num_Idents := Num_Idents + 1;
1092                Idents (Num_Idents) := P_Defining_Identifier (C_Comma_Colon);
1093             end loop Ident_Loop;
1094
1095             --  Fall through the loop on encountering a colon, or deciding
1096             --  that there is a missing colon.
1097
1098             T_Colon;
1099
1100             --  If there are multiple identifiers, we repeatedly scan the
1101             --  type and initialization expression information by resetting
1102             --  the scan pointer (so that we get completely separate trees
1103             --  for each occurrence).
1104
1105             if Num_Idents > 1 then
1106                Save_Scan_State (Scan_State);
1107             end if;
1108
1109             --  Loop through defining identifiers in list
1110
1111             Ident := 1;
1112
1113             Ident_List_Loop : loop
1114                Specification_Node :=
1115                  New_Node (N_Parameter_Specification, Ident_Sloc);
1116                Set_Defining_Identifier (Specification_Node, Idents (Ident));
1117
1118                --  Scan possible NOT NULL for Ada 2005 (AI-231, AI-447)
1119
1120                Not_Null_Sloc := Token_Ptr;
1121                Not_Null_Present :=
1122                  P_Null_Exclusion (Allow_Anonymous_In_95 => True);
1123
1124                --  Case of ACCESS keyword present
1125
1126                if Token = Tok_Access then
1127                   Set_Null_Exclusion_Present
1128                     (Specification_Node, Not_Null_Present);
1129
1130                   if Ada_Version = Ada_83 then
1131                      Error_Msg_SC ("(Ada 83) access parameters not allowed");
1132                   end if;
1133
1134                   Set_Parameter_Type
1135                     (Specification_Node,
1136                      P_Access_Definition (Not_Null_Present));
1137
1138                --  Case of IN or OUT present
1139
1140                else
1141                   if Token = Tok_In or else Token = Tok_Out then
1142                      if Not_Null_Present then
1143                         Error_Msg
1144                           ("`NOT NULL` can only be used with `ACCESS`",
1145                            Not_Null_Sloc);
1146
1147                         if Token = Tok_In then
1148                            Error_Msg
1149                              ("\`IN` not allowed together with `ACCESS`",
1150                               Not_Null_Sloc);
1151                         else
1152                            Error_Msg
1153                              ("\`OUT` not allowed together with `ACCESS`",
1154                               Not_Null_Sloc);
1155                         end if;
1156                      end if;
1157
1158                      P_Mode (Specification_Node);
1159                      Not_Null_Present := P_Null_Exclusion; -- Ada 2005 (AI-231)
1160                   end if;
1161
1162                   Set_Null_Exclusion_Present
1163                     (Specification_Node, Not_Null_Present);
1164
1165                   if Token = Tok_Procedure
1166                        or else
1167                      Token = Tok_Function
1168                   then
1169                      Error_Msg_SC ("formal subprogram parameter not allowed");
1170                      Scan;
1171
1172                      if Token = Tok_Left_Paren then
1173                         Discard_Junk_List (P_Formal_Part);
1174                      end if;
1175
1176                      if Token = Tok_Return then
1177                         Scan;
1178                         Discard_Junk_Node (P_Subtype_Mark);
1179                      end if;
1180
1181                      Set_Parameter_Type (Specification_Node, Error);
1182
1183                   else
1184                      Set_Parameter_Type (Specification_Node, P_Subtype_Mark);
1185                      No_Constraint;
1186                   end if;
1187                end if;
1188
1189                Set_Expression (Specification_Node, Init_Expr_Opt (True));
1190
1191                if Ident > 1 then
1192                   Set_Prev_Ids (Specification_Node, True);
1193                end if;
1194
1195                if Ident < Num_Idents then
1196                   Set_More_Ids (Specification_Node, True);
1197                end if;
1198
1199                Append (Specification_Node, Specification_List);
1200                exit Ident_List_Loop when Ident = Num_Idents;
1201                Ident := Ident + 1;
1202                Restore_Scan_State (Scan_State);
1203             end loop Ident_List_Loop;
1204
1205          exception
1206             when Error_Resync =>
1207                Resync_Semicolon_List;
1208          end;
1209
1210          if Token = Tok_Semicolon then
1211             Save_Scan_State (Scan_State);
1212             Scan; -- past semicolon
1213
1214             --  If we have RETURN or IS after the semicolon, then assume
1215             --  that semicolon should have been a right parenthesis and exit
1216
1217             if Token = Tok_Is or else Token = Tok_Return then
1218                Error_Msg_SP ("|"";"" should be "")""");
1219                exit Specification_Loop;
1220             end if;
1221
1222             --  If we have a declaration keyword after the semicolon, then
1223             --  assume we had a missing right parenthesis and terminate list
1224
1225             if Token in Token_Class_Declk then
1226                Error_Msg_AP ("missing "")""");
1227                Restore_Scan_State (Scan_State);
1228                exit Specification_Loop;
1229             end if;
1230
1231          elsif Token = Tok_Right_Paren then
1232             Scan; -- past right paren
1233             exit Specification_Loop;
1234
1235          --  Special check for common error of using comma instead of semicolon
1236
1237          elsif Token = Tok_Comma then
1238             T_Semicolon;
1239             Scan; -- past comma
1240
1241          --  Special check for omitted separator
1242
1243          elsif Token = Tok_Identifier then
1244             T_Semicolon;
1245
1246          --  If nothing sensible, skip to next semicolon or right paren
1247
1248          else
1249             T_Semicolon;
1250             Resync_Semicolon_List;
1251
1252             if Token = Tok_Semicolon then
1253                Scan; -- past semicolon
1254             else
1255                T_Right_Paren;
1256                exit Specification_Loop;
1257             end if;
1258          end if;
1259       end loop Specification_Loop;
1260
1261       return Specification_List;
1262    end P_Formal_Part;
1263
1264    ----------------------------------
1265    -- 6.1  Parameter Specification --
1266    ----------------------------------
1267
1268    --  Parsed by P_Formal_Part (6.1)
1269
1270    ---------------
1271    -- 6.1  Mode --
1272    ---------------
1273
1274    --  MODE ::= [in] | in out | out
1275
1276    --  There is no explicit node in the tree for the Mode. Instead the
1277    --  In_Present and Out_Present flags are set in the parent node to
1278    --  record the presence of keywords specifying the mode.
1279
1280    --  Error_Recovery: cannot raise Error_Resync
1281
1282    procedure P_Mode (Node : Node_Id) is
1283    begin
1284       if Token = Tok_In then
1285          Scan; -- past IN
1286          Set_In_Present (Node, True);
1287
1288          if Style.Mode_In_Check and then Token /= Tok_Out then
1289             Error_Msg_SP ("(style) IN should be omitted");
1290          end if;
1291
1292          if Token = Tok_Access then
1293             Error_Msg_SP ("IN not allowed together with ACCESS");
1294             Scan; -- past ACCESS
1295          end if;
1296       end if;
1297
1298       if Token = Tok_Out then
1299          Scan; -- past OUT
1300          Set_Out_Present (Node, True);
1301       end if;
1302
1303       if Token = Tok_In then
1304          Error_Msg_SC ("IN must precede OUT in parameter mode");
1305          Scan; -- past IN
1306          Set_In_Present (Node, True);
1307       end if;
1308    end P_Mode;
1309
1310    --------------------------
1311    -- 6.3  Subprogram Body --
1312    --------------------------
1313
1314    --  Parsed by P_Subprogram (6.1)
1315
1316    -----------------------------------
1317    -- 6.4  Procedure Call Statement --
1318    -----------------------------------
1319
1320    --  Parsed by P_Sequence_Of_Statements (5.1)
1321
1322    ------------------------
1323    -- 6.4  Function Call --
1324    ------------------------
1325
1326    --  Parsed by P_Call_Or_Name (4.1)
1327
1328    --------------------------------
1329    -- 6.4  Actual Parameter Part --
1330    --------------------------------
1331
1332    --  Parsed by P_Call_Or_Name (4.1)
1333
1334    --------------------------------
1335    -- 6.4  Parameter Association --
1336    --------------------------------
1337
1338    --  Parsed by P_Call_Or_Name (4.1)
1339
1340    ------------------------------------
1341    -- 6.4  Explicit Actual Parameter --
1342    ------------------------------------
1343
1344    --  Parsed by P_Call_Or_Name (4.1)
1345
1346    ---------------------------
1347    -- 6.5  Return Statement --
1348    ---------------------------
1349
1350    --  SIMPLE_RETURN_STATEMENT ::= return [EXPRESSION];
1351    --
1352    --  EXTENDED_RETURN_STATEMENT ::=
1353    --    return DEFINING_IDENTIFIER : [aliased] RETURN_SUBTYPE_INDICATION
1354    --                                           [:= EXPRESSION] [do
1355    --      HANDLED_SEQUENCE_OF_STATEMENTS
1356    --    end return];
1357    --
1358    --  RETURN_SUBTYPE_INDICATION ::= SUBTYPE_INDICATION | ACCESS_DEFINITION
1359
1360    --  RETURN_STATEMENT ::= return [EXPRESSION];
1361
1362    --  Error recovery: can raise Error_Resync
1363
1364    procedure P_Return_Subtype_Indication (Decl_Node : Node_Id) is
1365
1366       --  Note: We don't need to check Ada_Version here, because this is
1367       --  only called in >= Ada 2005 cases anyway.
1368
1369       Not_Null_Present : constant Boolean := P_Null_Exclusion;
1370
1371    begin
1372       Set_Null_Exclusion_Present (Decl_Node, Not_Null_Present);
1373
1374       if Token = Tok_Access then
1375          Set_Object_Definition
1376            (Decl_Node, P_Access_Definition (Not_Null_Present));
1377       else
1378          Set_Object_Definition
1379            (Decl_Node, P_Subtype_Indication (Not_Null_Present));
1380       end if;
1381    end P_Return_Subtype_Indication;
1382
1383    --  Error recovery: can raise Error_Resync
1384
1385    function P_Return_Object_Declaration return Node_Id is
1386       Return_Obj : Node_Id;
1387       Decl_Node  : Node_Id;
1388
1389    begin
1390       Return_Obj := Token_Node;
1391       Change_Identifier_To_Defining_Identifier (Return_Obj);
1392       Decl_Node := New_Node (N_Object_Declaration, Token_Ptr);
1393       Set_Defining_Identifier (Decl_Node, Return_Obj);
1394
1395       Scan; -- past identifier
1396       Scan; -- past :
1397
1398       --  First an error check, if we have two identifiers in a row, a likely
1399       --  possibility is that the first of the identifiers is an incorrectly
1400       --  spelled keyword. See similar check in P_Identifier_Declarations.
1401
1402       if Token = Tok_Identifier then
1403          declare
1404             SS : Saved_Scan_State;
1405             I2 : Boolean;
1406
1407          begin
1408             Save_Scan_State (SS);
1409             Scan; -- past initial identifier
1410             I2 := (Token = Tok_Identifier);
1411             Restore_Scan_State (SS);
1412
1413             if I2
1414               and then
1415                 (Bad_Spelling_Of (Tok_Access)   or else
1416                  Bad_Spelling_Of (Tok_Aliased)  or else
1417                  Bad_Spelling_Of (Tok_Constant))
1418             then
1419                null;
1420             end if;
1421          end;
1422       end if;
1423
1424       --  We allow "constant" here (as in "return Result : constant
1425       --  T..."). This is not in the latest RM, but the ARG is considering an
1426       --  AI on the subject (see AI05-0015-1), which we expect to be approved.
1427
1428       if Token = Tok_Constant then
1429          Scan; -- past CONSTANT
1430          Set_Constant_Present (Decl_Node);
1431
1432          if Token = Tok_Aliased then
1433             Error_Msg_SC ("ALIASED should be before CONSTANT");
1434             Scan; -- past ALIASED
1435             Set_Aliased_Present (Decl_Node);
1436          end if;
1437
1438       elsif Token = Tok_Aliased then
1439          Scan; -- past ALIASED
1440          Set_Aliased_Present (Decl_Node);
1441
1442          if Token = Tok_Constant then
1443             Scan; -- past CONSTANT
1444             Set_Constant_Present (Decl_Node);
1445          end if;
1446       end if;
1447
1448       P_Return_Subtype_Indication (Decl_Node);
1449
1450       if Token = Tok_Colon_Equal then
1451          Scan; -- past :=
1452          Set_Expression (Decl_Node, P_Expression_No_Right_Paren);
1453       end if;
1454
1455       return Decl_Node;
1456    end P_Return_Object_Declaration;
1457
1458    --  Error recovery: can raise Error_Resync
1459
1460    function P_Return_Statement return Node_Id is
1461       --  The caller has checked that the initial token is RETURN
1462
1463       function Is_Simple return Boolean;
1464       --  Scan state is just after RETURN (and is left that way).
1465       --  Determine whether this is a simple or extended return statement
1466       --  by looking ahead for "identifier :", which implies extended.
1467
1468       ---------------
1469       -- Is_Simple --
1470       ---------------
1471
1472       function Is_Simple return Boolean is
1473          Scan_State : Saved_Scan_State;
1474          Result     : Boolean := True;
1475
1476       begin
1477          if Token = Tok_Identifier then
1478             Save_Scan_State (Scan_State); -- at identifier
1479             Scan; -- past identifier
1480
1481             if Token = Tok_Colon then
1482                Result := False; -- It's an extended_return_statement.
1483             end if;
1484
1485             Restore_Scan_State (Scan_State); -- to identifier
1486          end if;
1487
1488          return Result;
1489       end Is_Simple;
1490
1491       Return_Sloc : constant Source_Ptr := Token_Ptr;
1492       Return_Node : Node_Id;
1493
1494    --  Start of processing for P_Return_Statement
1495
1496    begin
1497       Scan; -- past RETURN
1498
1499       --  Simple_return_statement, no expression, return an
1500       --  N_Simple_Return_Statement node with the expression field left Empty.
1501
1502       if Token = Tok_Semicolon then
1503          Scan; -- past ;
1504          Return_Node := New_Node (N_Simple_Return_Statement, Return_Sloc);
1505
1506       --  Non-trivial case
1507
1508       else
1509          --  Simple_return_statement with expression
1510
1511          --  We avoid trying to scan an expression if we are at an
1512          --  expression terminator since in that case the best error
1513          --  message is probably that we have a missing semicolon.
1514
1515          if Is_Simple then
1516             Return_Node := New_Node (N_Simple_Return_Statement, Return_Sloc);
1517
1518             if Token not in Token_Class_Eterm then
1519                Set_Expression (Return_Node, P_Expression_No_Right_Paren);
1520             end if;
1521
1522          --  Extended_return_statement (Ada 2005 only -- AI-318):
1523
1524          else
1525             if Ada_Version < Ada_05 then
1526                Error_Msg_SP
1527                  (" extended_return_statement is an Ada 2005 extension");
1528                Error_Msg_SP ("\unit must be compiled with -gnat05 switch");
1529             end if;
1530
1531             Return_Node := New_Node (N_Extended_Return_Statement, Return_Sloc);
1532             Set_Return_Object_Declarations
1533               (Return_Node, New_List (P_Return_Object_Declaration));
1534
1535             if Token = Tok_Do then
1536                Push_Scope_Stack;
1537                Scope.Table (Scope.Last).Etyp := E_Return;
1538                Scope.Table (Scope.Last).Ecol := Start_Column;
1539                Scope.Table (Scope.Last).Sloc := Return_Sloc;
1540
1541                Scan; -- past DO
1542                Set_Handled_Statement_Sequence
1543                  (Return_Node, P_Handled_Sequence_Of_Statements);
1544                End_Statements;
1545
1546                --  Do we need to handle Error_Resync here???
1547             end if;
1548          end if;
1549
1550          TF_Semicolon;
1551       end if;
1552
1553       return Return_Node;
1554    end P_Return_Statement;
1555
1556 end Ch6;