home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gnat-2.06-src.tgz / tar.out / fsf / gnat / ada / par-ch6.adb < prev    next >
Text File  |  1996-09-28  |  36KB  |  1,069 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT COMPILER COMPONENTS                         --
  4. --                                                                          --
  5. --                              P A R . C H 6                               --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.62 $                             --
  10. --                                                                          --
  11. --        Copyright (c) 1992,1993,1994,1995 NYU, All Rights Reserved        --
  12. --                                                                          --
  13. -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  14. -- terms of the  GNU General Public License as published  by the Free Soft- --
  15. -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
  16. -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  17. -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  18. -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
  19. -- for  more details.  You should have  received  a copy of the GNU General --
  20. -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
  21. -- to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. --
  22. --                                                                          --
  23. ------------------------------------------------------------------------------
  24.  
  25. with Sinfo.CN; use Sinfo.CN;
  26.  
  27. separate (Par)
  28. package body Ch6 is
  29.  
  30.    --  Local subprograms, used only in this chapter
  31.  
  32.    function P_Defining_Designator        return Node_Id;
  33.    function P_Defining_Operator_Symbol   return Node_Id;
  34.  
  35.    procedure Check_Junk_Semicolon_Before_Return;
  36.    --  Check for common error of junk semicolon before RETURN keyword of
  37.    --  function specification. If present, skip over it with appropriate
  38.    --  error message, leaving Scan_Ptr pointing to the RETURN after. This
  39.    --  routine also deals with a possibly misspelled version of Return.
  40.  
  41.    ----------------------------------------
  42.    -- Check_Junk_Semicolon_Before_Return --
  43.    ----------------------------------------
  44.  
  45.    procedure Check_Junk_Semicolon_Before_Return is
  46.       Scan_State : Saved_Scan_State;
  47.  
  48.    begin
  49.       if Token = Tok_Semicolon then
  50.          Save_Scan_State (Scan_State);
  51.          Scan; -- past the semicolon
  52.  
  53.          if Token = Tok_Return then
  54.             Restore_Scan_State (Scan_State);
  55.             Error_Msg_SC ("Unexpected semicolon ignored");
  56.             Scan; -- rescan past junk semicolon
  57.  
  58.          else
  59.             Restore_Scan_State (Scan_State);
  60.          end if;
  61.  
  62.       elsif Bad_Spelling_Of (Tok_Return) then
  63.          null;
  64.       end if;
  65.    end Check_Junk_Semicolon_Before_Return;
  66.  
  67.    -----------------------------------------------------
  68.    -- 6.1  Subprogram (Also 6.3, 8.5.4, 10.1.3, 12.3) --
  69.    -----------------------------------------------------
  70.  
  71.    --  This routine scans out a subprogram declaration, subprogram body,
  72.    --  subprogram renaming declaration or subprogram generic instantiation.
  73.  
  74.    --  SUBPROGRAM_DECLARATION ::= SUBPROGRAM_SPECIFICATION;
  75.  
  76.    --  ABSTRACT_SUBPROGRAM_DECLARATION ::=
  77.    --    SUBPROGRAM_SPECIFICATION is abstract;
  78.  
  79.    --  SUBPROGRAM_SPECIFICATION ::=
  80.    --      procedure DEFINING_PROGRAM_UNIT_NAME PARAMETER_PROFILE
  81.    --    | function DEFINING_DESIGNATOR PARAMETER_AND_RESULT_PROFILE
  82.  
  83.    --  PARAMETER_PROFILE ::= [FORMAL_PART]
  84.  
  85.    --  PARAMETER_AND_RESULT_PROFILE ::= [FORMAL_PART] return SUBTYPE_MARK
  86.  
  87.    --  SUBPROGRAM_BODY ::=
  88.    --    SUBPROGRAM_SPECIFICATION is
  89.    --      DECLARATIVE_PART
  90.    --    begin
  91.    --      HANDLED_SEQUENCE_OF_STATEMENTS
  92.    --    end [DESIGNATOR];
  93.  
  94.    --  SUBPROGRAM_RENAMING_DECLARATION ::=
  95.    --    SUBPROGRAM_SPECIFICATION renames callable_entity_NAME;
  96.  
  97.    --  SUBPROGRAM_BODY_STUB ::=
  98.    --    SUBPROGRAM_SPECIFICATION is separate;
  99.  
  100.    --  GENERIC_INSTANTIATION ::=
  101.    --    procedure DEFINING_PROGRAM_UNIT_NAME is
  102.    --      new generic_procedure_NAME [GENERIC_ACTUAL_PART];
  103.    --  | function DEFINING_DESIGNATOR is
  104.    --      new generic_function_NAME [GENERIC_ACTUAL_PART];
  105.  
  106.    --  The value in Pf_Flags indicates which of these possible declarations
  107.    --  is acceptable to the caller:
  108.  
  109.    --    Pf_Flags.Decl                 Set if declaration OK
  110.    --    Pf_Flags.Gins                 Set if generic instantiation OK
  111.    --    Pf_Flags.Pbod                 Set if proper body OK
  112.    --    Pf_Flags.Rnam                 Set if renaming declaration OK
  113.    --    Pf_Flags.Stub                 Set if body stub OK
  114.  
  115.    --  If an inappropriate form is encountered, it is scanned out but an
  116.    --  error message indicating that it is appearing in an inappropriate
  117.    --  context is issued. The only possible values for Pf_Flags are those
  118.    --  defined as constants in the Par package.
  119.  
  120.    --  The caller has checked that the initial token is FUNCTION or PROCEDURE
  121.  
  122.    --  Error recovery: cannot raise Error_Resync
  123.  
  124.    function P_Subprogram (Pf_Flags : Pf_Rec) return Node_Id is
  125.       Specification_Node : Node_Id;
  126.       Name_Node   : Node_Id;
  127.       Fpart_List  : List_Id;
  128.       Fpart_Sloc  : Source_Ptr;
  129.       Return_Node : Node_Id;
  130.       Inst_Node   : Node_Id;
  131.       Body_Node   : Node_Id;
  132.       Decl_Node   : Node_Id;
  133.       Rename_Node : Node_Id;
  134.       Absdec_Node : Node_Id;
  135.       Stub_Node   : Node_Id;
  136.       Fproc_Sloc  : Source_Ptr;
  137.       Func        : Boolean;
  138.       Scan_State  : Saved_Scan_State;
  139.  
  140.    begin
  141.       --  Set up scope stack entry. Note that the Labl field will be set later
  142.  
  143.       SIS_Entry_Active := False;
  144.       SIS_Missing_Semicolon_Message := No_Error_Msg;
  145.       Push_Scope_Stack;
  146.       Scope.Table (Scope.Last).Sloc := Token_Ptr;
  147.       Scope.Table (Scope.Last).Etyp := E_Name;
  148.       Scope.Table (Scope.Last).Ecol := Start_Column;
  149.       Scope.Table (Scope.Last).Lreq := False;
  150.  
  151.       Func := Token = Tok_Function;
  152.       Fproc_Sloc := Token_Ptr;
  153.       Scan; -- past FUNCTION or PROCEDURE
  154.       Ignore (Tok_Type);
  155.       Ignore (Tok_Body);
  156.  
  157.       if Func then
  158.          Name_Node := P_Defining_Designator;
  159.       else
  160.          Name_Node := P_Defining_Program_Unit_Name;
  161.       end if;
  162.  
  163.       Scope.Table (Scope.Last).Labl := Name_Node;
  164.  
  165.       if Token = Tok_Colon then
  166.          Error_Msg_SC ("redundant colon ignored");
  167.          Scan; -- past colon
  168.       end if;
  169.  
  170.       --  Deal with generic instantiation, the one case in which we do not
  171.       --  have a subprogram specification as part of whatever we are parsing
  172.  
  173.       if Token = Tok_Is then
  174.          Save_Scan_State (Scan_State); -- at the IS
  175.          T_Is; -- checks for redundant IS's
  176.  
  177.          if Token = Tok_New then
  178.             if not Pf_Flags.Gins then
  179.                Error_Msg_SC ("generic instantation not allowed here!");
  180.             end if;
  181.  
  182.             Scan; -- past NEW
  183.  
  184.             if Func then
  185.                Inst_Node := New_Node (N_Function_Instantiation, Fproc_Sloc);
  186.                Set_Name (Inst_Node, P_Function_Name);
  187.             else
  188.                Inst_Node := New_Node (N_Procedure_Instantiation, Fproc_Sloc);
  189.                Set_Name (Inst_Node, P_Qualified_Simple_Name);
  190.             end if;
  191.  
  192.             Set_Defining_Unit_Name (Inst_Node, Name_Node);
  193.             Set_Generic_Associations (Inst_Node, P_Generic_Actual_Part_Opt);
  194.             TF_Semicolon;
  195.             Pop_Scope_Stack; -- Don't need scope stack entry in this case
  196.             return Inst_Node;
  197.  
  198.          else
  199.             Restore_Scan_State (Scan_State); -- to the IS
  200.          end if;
  201.       end if;
  202.  
  203.       --  If not a generic instantiation, then we definitely have a subprogram
  204.       --  specification (all possibilities at this stage include one here)
  205.  
  206.       Fpart_Sloc := Token_Ptr;
  207.  
  208.       --  Before scanning the formal part, check for a misspelled return
  209.  
  210.       if Bad_Spelling_Of (Tok_Return) then
  211.          null;
  212.       end if;
  213.  
  214.       --  Scan formal part. First a special error check. If we have an
  215.       --  identifier here, then we have a definite error. If this identifier
  216.       --  is on the same line as the designator, or if it starts a new line
  217.       --  that is more indented than the FUNCTION/PROCEDURE keyword, then we
  218.       --  assume it is the first formal after a missing left parenthesis.
  219.  
  220.       if Token = Tok_Identifier
  221.         and then
  222.           (not Token_Is_At_Start_Of_Line
  223.              or else Start_Column > Scope.Table (Scope.Last).Ecol)
  224.       then
  225.          T_Left_Paren; -- to generate message
  226.          Fpart_List := P_Formal_Part;
  227.  
  228.       --  Otherwise scan out an optional formal part in the usual manner
  229.  
  230.       else
  231.          Fpart_List := P_Parameter_Profile;
  232.       end if;
  233.  
  234.       --  We treat what we have as a function specification if FUNCTION was
  235.       --  used, or if a RETURN is present. This gives better error recovery
  236.       --  since later RETURN statements will be valid in either case.
  237.  
  238.       Check_Junk_Semicolon_Before_Return;
  239.  
  240.       if Token = Tok_Return then
  241.          if not Func then
  242.             Error_Msg ("PROCEDURE should be FUNCTION", Fproc_Sloc);
  243.             Func := True;
  244.          end if;
  245.  
  246.          Scan; -- past RETURN
  247.          Return_Node := P_Subtype_Mark;
  248.          No_Constraint;
  249.  
  250.       else
  251.          if Func then
  252.             TF_Return;
  253.             Return_Node := Error;
  254.          end if;
  255.       end if;
  256.  
  257.       if Func then
  258.          Specification_Node :=
  259.            New_Node (N_Function_Specification, Fproc_Sloc);
  260.          Set_Subtype_Mark (Specification_Node, Return_Node);
  261.       else
  262.          Specification_Node :=
  263.            New_Node (N_Procedure_Specification, Fproc_Sloc);
  264.       end if;
  265.  
  266.       Set_Defining_Unit_Name (Specification_Node, Name_Node);
  267.       Set_Parameter_Specifications (Specification_Node, Fpart_List);
  268.  
  269.       --  Error check: barriers not allowed on protected functions/procedures
  270.  
  271.       if Token = Tok_When then
  272.          if Func then
  273.             Error_Msg_SC ("barrier not allowed on function, only on entry");
  274.          else
  275.             Error_Msg_SC ("barrier not allowed on procedure, only on entry");
  276.          end if;
  277.  
  278.          Scan; -- past WHEN
  279.          Discard_Junk_Node (P_Expression);
  280.       end if;
  281.  
  282.       --  Deal with case of semicolon ending a subprogram declaration
  283.  
  284.       if Token = Tok_Semicolon then
  285.          if not Pf_Flags.Decl then
  286.             T_Is;
  287.          end if;
  288.  
  289.          Scan; -- past semicolon
  290.  
  291.          --  If semicolon is immediately followed by IS, then ignore the
  292.          --  semicolon, and go process the body.
  293.  
  294.          if Token = Tok_Is then
  295.             Error_Msg_SP ("unexpected semicolon ignored");
  296.             T_Is; -- ignroe redundant IS's
  297.             goto Subprogram_Body;
  298.  
  299.          --  If BEGIN follows in an appropriate column, we immediately
  300.          --  commence the error action of assuming that the previous
  301.          --  subprogram declaration should have been a subprogram body,
  302.          --  i.e. that the terminating semicolon should have been IS.
  303.  
  304.          elsif Token = Tok_Begin
  305.             and then Start_Column >= Scope.Table (Scope.Last).Ecol
  306.          then
  307.             Error_Msg_SP (""";"" should be IS!");
  308.             goto Subprogram_Body;
  309.  
  310.          else
  311.             goto Subprogram_Declaration;
  312.          end if;
  313.  
  314.       --  Subprogram renaming declaration case
  315.  
  316.       elsif Token = Tok_Renames then
  317.          if not Pf_Flags.Rnam then
  318.             Error_Msg_SC ("renaming declaration not allowed here!");
  319.          end if;
  320.  
  321.          Rename_Node :=
  322.            New_Node (N_Subprogram_Renaming_Declaration, Token_Ptr);
  323.          Scan; -- past RENAMES
  324.          Set_Name (Rename_Node, P_Name);
  325.          Set_Specification (Rename_Node, Specification_Node);
  326.          TF_Semicolon;
  327.          Pop_Scope_Stack;
  328.          return Rename_Node;
  329.  
  330.       --  Case of IS following subprogram specification
  331.  
  332.       elsif Token = Tok_Is then
  333.          T_Is; -- ignore redundant Is's
  334.  
  335.          if Token_Name = Name_Abstract then
  336.             Check_95_Keyword (Tok_Abstract, Tok_Semicolon);
  337.          end if;
  338.  
  339.          --  Deal nicely with (now obsolete) use of <> in place of abstract
  340.  
  341.          if Token = Tok_Box then
  342.             Error_Msg_SC ("ABSTRACT expected");
  343.             Token := Tok_Abstract;
  344.          end if;
  345.  
  346.          --  Abstract subprogram declaration case
  347.  
  348.          if Token = Tok_Abstract then
  349.             Note_Feature (Abstract_Subprograms, Token_Ptr);
  350.             Absdec_Node :=
  351.               New_Node (N_Abstract_Subprogram_Declaration, Token_Ptr);
  352.             Set_Specification (Absdec_Node, Specification_Node);
  353.             Pop_Scope_Stack; -- discard unneeded entry
  354.             Scan; -- past ABSTRACT
  355.             TF_Semicolon;
  356.             return Absdec_Node;
  357.  
  358.          --  Check for IS NEW with Formal_Part present and handle nicely
  359.  
  360.          elsif Token = Tok_New then
  361.             Error_Msg ("formal part not allowed in instantiation", Fpart_Sloc);
  362.             Scan; -- past NEW
  363.  
  364.             if Func then
  365.                Inst_Node := New_Node (N_Function_Instantiation, Fproc_Sloc);
  366.             else
  367.                Inst_Node :=
  368.                  New_Node (N_Procedure_Instantiation, Fproc_Sloc);
  369.             end if;
  370.  
  371.             Set_Defining_Unit_Name (Inst_Node, Name_Node);
  372.             Set_Name (Inst_Node, P_Name);
  373.             Set_Generic_Associations (Inst_Node, P_Generic_Actual_Part_Opt);
  374.             TF_Semicolon;
  375.             Pop_Scope_Stack; -- Don't need scope stack entry in this case
  376.             return Inst_Node;
  377.  
  378.          else
  379.             goto Subprogram_Body;
  380.          end if;
  381.  
  382.       --  Here we have a missing IS or missing semicolon, we always guess a
  383.       --  missing semicolon, since we are pretty good at fixing up a semicolon
  384.       --  which should really be an IS
  385.  
  386.       else
  387.          Error_Msg_AP ("missing "";""");
  388.          SIS_Missing_Semicolon_Message := Get_Msg_Id;
  389.          goto Subprogram_Declaration;
  390.       end if;
  391.  
  392.       --  Processing for subprogram body
  393.  
  394.       <<Subprogram_Body>>
  395.          if not Pf_Flags.Pbod then
  396.             Error_Msg_SP ("subprogram body not allowed here!");
  397.          end if;
  398.  
  399.          --  Subprogram body stub case
  400.  
  401.          if Separate_Present then
  402.             if not Pf_Flags.Stub then
  403.                Error_Msg_SC ("body stub not allowed here!");
  404.             end if;
  405.  
  406.             Stub_Node :=
  407.               New_Node (N_Subprogram_Body_Stub, Sloc (Specification_Node));
  408.             Set_Specification (Stub_Node, Specification_Node);
  409.             Scan; -- past SEPARATE
  410.             Pop_Scope_Stack;
  411.             TF_Semicolon;
  412.             return Stub_Node;
  413.  
  414.          --  Subprogram body case
  415.  
  416.          else
  417.             --  Here is the test for a suspicious IS (i.e. one that looks
  418.             --  like it might more properly be a semicolon). See separate
  419.             --  section discussing use of IS instead of semicolon in
  420.             --  package Parse.
  421.  
  422.             if (Token in Token_Class_Declk or else
  423.               Token = Tok_Identifier) and then
  424.               Start_Column <= Scope.Table (Scope.Last).Ecol
  425.             then
  426.                Scope.Table (Scope.Last).Etyp := E_Suspicious_Is;
  427.                Scope.Table (Scope.Last).S_Is := Prev_Token_Ptr;
  428.             end if;
  429.  
  430.             Body_Node :=
  431.               New_Node (N_Subprogram_Body, Sloc (Specification_Node));
  432.             Set_Specification (Body_Node, Specification_Node);
  433.             Parse_Decls_Begin_End (Body_Node);
  434.             return Body_Node;
  435.          end if;
  436.  
  437.       --  Processing for subprogram declaration
  438.  
  439.       <<Subprogram_Declaration>>
  440.          Decl_Node :=
  441.            New_Node (N_Subprogram_Declaration, Sloc (Specification_Node));
  442.          Set_Specification (Decl_Node, Specification_Node);
  443.  
  444.          --  If this is a context in which a subprogram body is permitted,
  445.          --  set active SIS entry in case (see section titled "Handling
  446.          --  Semicolon Used in Place of IS" in body of Parser package)
  447.          --  Note that SIS_Missing_Semicolon_Message is already set properly.
  448.  
  449.          if Pf_Flags.Pbod then
  450.             SIS_Labl := Scope.Table (Scope.Last).Labl;
  451.             SIS_Sloc := Scope.Table (Scope.Last).Sloc;
  452.             SIS_Ecol := Scope.Table (Scope.Last).Ecol;
  453.             SIS_Declaration_Node := Decl_Node;
  454.             SIS_Semicolon_Sloc := Prev_Token_Ptr;
  455.             SIS_Entry_Active := True;
  456.          end if;
  457.  
  458.          Pop_Scope_Stack;
  459.          return Decl_Node;
  460.  
  461.    end P_Subprogram;
  462.  
  463.    ---------------------------------
  464.    -- 6.1  Subprogram Declaration --
  465.    ---------------------------------
  466.  
  467.    --  Parsed by P_Subprogram (6.1)
  468.  
  469.    ------------------------------------------
  470.    -- 6.1  Abstract Subprogram Declaration --
  471.    ------------------------------------------
  472.  
  473.    --  Parsed by P_Subprogram (6.1)
  474.  
  475.    -----------------------------------
  476.    -- 6.1  Subprogram Specification --
  477.    -----------------------------------
  478.  
  479.    --  SUBPROGRAM_SPECIFICATION ::=
  480.    --      procedure DEFINING_PROGRAM_UNIT_NAME PARAMETER_PROFILE
  481.    --    | function DEFINING_DESIGNATOR PARAMETER_AND_RESULT_PROFILE
  482.  
  483.    --  PARAMETER_PROFILE ::= [FORMAL_PART]
  484.  
  485.    --  PARAMETER_AND_RESULT_PROFILE ::= [FORMAL_PART] return SUBTYPE_MARK
  486.  
  487.    --  Subprogram specifications that appear in subprogram declarations
  488.    --  are parsed by P_Subprogram (6.1). This routine is used in other
  489.    --  contexts where subprogram specifications occur.
  490.  
  491.    --  Note: this routine does not affect the scope stack in any way
  492.  
  493.    --  Error recovery: can raise Error_Resync
  494.  
  495.    function P_Subprogram_Specification return Node_Id is
  496.       Specification_Node : Node_Id;
  497.  
  498.    begin
  499.       if Token = Tok_Function then
  500.          Specification_Node := New_Node (N_Function_Specification, Token_Ptr);
  501.          Scan; -- past FUNCTION
  502.          Ignore (Tok_Body);
  503.          Set_Defining_Unit_Name (Specification_Node, P_Defining_Designator);
  504.          Set_Parameter_Specifications
  505.            (Specification_Node, P_Parameter_Profile);
  506.          Check_Junk_Semicolon_Before_Return;
  507.          TF_Return;
  508.          Set_Subtype_Mark (Specification_Node, P_Subtype_Mark);
  509.          No_Constraint;
  510.          return Specification_Node;
  511.  
  512.       elsif Token = Tok_Procedure then
  513.          Specification_Node := New_Node (N_Procedure_Specification, Token_Ptr);
  514.          Scan; -- past PROCEDURE
  515.          Ignore (Tok_Body);
  516.          Set_Defining_Unit_Name
  517.            (Specification_Node, P_Defining_Program_Unit_Name);
  518.          Set_Parameter_Specifications
  519.            (Specification_Node, P_Parameter_Profile);
  520.          return Specification_Node;
  521.  
  522.       else
  523.          Error_Msg_SC ("subprogram specification expected");
  524.          raise Error_Resync;
  525.       end if;
  526.    end P_Subprogram_Specification;
  527.  
  528.    ---------------------
  529.    -- 6.1  Designator --
  530.    ---------------------
  531.  
  532.    --  DESIGNATOR ::=
  533.    --    [PARENT_UNIT_NAME .] IDENTIFIER | OPERATOR_SYMBOL
  534.  
  535.    --  The caller has checked that the initial token is an identifier,
  536.    --  operator symbol, or string literal. Note that we don't bother to
  537.    --  do much error diagnosis in this routine, since it is only used for
  538.    --  the label on END lines, and the routines in package Par.Endh will
  539.    --  check that the label is appropriate.
  540.  
  541.    --  Error recovery: cannot raise Error_Resync
  542.  
  543.    function P_Designator return Node_Id is
  544.       Ident_Node  : Node_Id;
  545.       Name_Node   : Node_Id;
  546.       Prefix_Node : Node_Id;
  547.  
  548.    begin
  549.       Ident_Node := Token_Node;
  550.       Scan; -- past initial token
  551.  
  552.       if Prev_Token = Tok_Operator_Symbol
  553.         or else Prev_Token = Tok_String_Literal
  554.         or else Token /= Tok_Dot
  555.       then
  556.          return Ident_Node;
  557.  
  558.       --  Child name case
  559.  
  560.       else
  561.          Prefix_Node := Ident_Node;
  562.  
  563.          --  Loop through child names, on entry to this loop, Prefix contains
  564.          --  the name scanned so far, and Ident_Node is the last identifier.
  565.  
  566.          loop
  567.             exit when Token /= Tok_Dot;
  568.             Name_Node := New_Node (N_Selected_Component, Token_Ptr);
  569.             Scan; -- past period
  570.             Set_Prefix (Name_Node, Prefix_Node);
  571.             Ident_Node := P_Identifier;
  572.             Set_Selector_Name (Name_Node, Ident_Node);
  573.             Prefix_Node := Name_Node;
  574.          end loop;
  575.  
  576.          --  On exit from the loop, Ident_Node is the last identifier scanned,
  577.          --  i.e. the defining identifier, and Prefix_Node is a node for the
  578.          --  entire name, structured (incorrectly!) as a selected component.
  579.  
  580.          Name_Node := Prefix (Prefix_Node);
  581.          Change_Node (Prefix_Node, N_Designator);
  582.          Set_Name (Prefix_Node, Name_Node);
  583.          Set_Identifier (Prefix_Node, Ident_Node);
  584.          return Prefix_Node;
  585.       end if;
  586.  
  587.    exception
  588.       when Error_Resync =>
  589.          while Token = Tok_Dot or else Token = Tok_Identifier loop
  590.             Scan;
  591.          end loop;
  592.  
  593.          return Error;
  594.    end P_Designator;
  595.  
  596.    ------------------------------
  597.    -- 6.1  Defining Designator --
  598.    ------------------------------
  599.  
  600.    --  DEFINING_DESIGNATOR ::=
  601.    --    DEFINING_PROGRAM_UNIT_NAME | DEFINING_OPERATOR_SYMBOL
  602.  
  603.    --  Error recovery: cannot raise Error_Resync
  604.  
  605.    function P_Defining_Designator return Node_Id is
  606.    begin
  607.       if Token = Tok_Operator_Symbol then
  608.          return P_Defining_Operator_Symbol;
  609.  
  610.       elsif Token = Tok_String_Literal then
  611.          Error_Msg_SC ("invalid operator name");
  612.          Scan; -- past junk string
  613.          return Error;
  614.  
  615.       else
  616.          return P_Defining_Program_Unit_Name;
  617.       end if;
  618.    end P_Defining_Designator;
  619.  
  620.    -------------------------------------
  621.    -- 6.1  Defining Program Unit Name --
  622.    -------------------------------------
  623.  
  624.    --  DEFINING_PROGRAM_UNIT_NAME ::=
  625.    --    [PARENT_UNIT_NAME .] DEFINING_IDENTIFIER
  626.  
  627.    --  Note: PARENT_UNIT_NAME may be present only in 95 mode at the outer level
  628.  
  629.    --  Error recovery: cannot raise Error_Resync
  630.  
  631.    function P_Defining_Program_Unit_Name return Node_Id is
  632.       Ident_Node  : Node_Id;
  633.       Name_Node   : Node_Id;
  634.       Prefix_Node : Node_Id;
  635.  
  636.    begin
  637.       --  Set identifier casing if not already set and scan initial identifier
  638.  
  639.       if Token = Tok_Identifier
  640.         and then Identifier_Casing (Current_Source_File) = Unknown
  641.       then
  642.          Set_Identifier_Casing (Current_Source_File, Determine_Token_Casing);
  643.       end if;
  644.  
  645.       Ident_Node := P_Identifier;
  646.  
  647.       --  Normal case (not child library unit name)
  648.  
  649.       if Token /= Tok_Dot then
  650.          Change_Identifier_To_Defining_Identifier (Ident_Node);
  651.          return Ident_Node;
  652.  
  653.       --  Child library unit name case
  654.  
  655.       else
  656.          Note_Feature (Child_Units, Token_Ptr);
  657.  
  658.          if Scope.Last > 1 then
  659.             Error_Msg_SP ("child unit allowed only at library level");
  660.             raise Error_Resync;
  661.  
  662.          elsif Ada_83 then
  663.             Error_Msg_SP ("(Ada 83) child unit not allowed!");
  664.  
  665.          end if;
  666.  
  667.          Prefix_Node := Ident_Node;
  668.  
  669.          --  Loop through child names, on entry to this loop, Prefix contains
  670.          --  the name scanned so far, and Ident_Node is the last identifier.
  671.  
  672.          loop
  673.             exit when Token /= Tok_Dot;
  674.             Name_Node := New_Node (N_Selected_Component, Token_Ptr);
  675.             Scan; -- past period
  676.             Set_Prefix (Name_Node, Prefix_Node);
  677.             Ident_Node := P_Identifier;
  678.             Set_Selector_Name (Name_Node, Ident_Node);
  679.             Prefix_Node := Name_Node;
  680.          end loop;
  681.  
  682.          --  On exit from the loop, Ident_Node is the last identifier scanned,
  683.          --  i.e. the defining identifier, and Prefix_Node is a node for the
  684.          --  entire name, structured (incorrectly!) as a selected component.
  685.  
  686.          Name_Node := Prefix (Prefix_Node);
  687.          Change_Node (Prefix_Node, N_Defining_Program_Unit_Name);
  688.          Set_Name (Prefix_Node, Name_Node);
  689.          Change_Identifier_To_Defining_Identifier (Ident_Node);
  690.          Set_Defining_Identifier (Prefix_Node, Ident_Node);
  691.  
  692.          --  All set with unit name parsed
  693.  
  694.          return Prefix_Node;
  695.       end if;
  696.  
  697.    exception
  698.       when Error_Resync =>
  699.          while Token = Tok_Dot or else Token = Tok_Identifier loop
  700.             Scan;
  701.          end loop;
  702.  
  703.          return Error;
  704.    end P_Defining_Program_Unit_Name;
  705.  
  706.    --------------------------
  707.    -- 6.1  Operator Symbol --
  708.    --------------------------
  709.  
  710.    --  OPERATOR_SYMBOL ::= STRING_LITERAL
  711.  
  712.    --  Operator symbol is returned by the scanner as Tok_Operator_Symbol
  713.  
  714.    -----------------------------------
  715.    -- 6.1  Defining Operator Symbol --
  716.    -----------------------------------
  717.  
  718.    --  DEFINING_OPERATOR_SYMBOL ::= OPERATOR_SYMBOL
  719.  
  720.    --  The caller has checked that the initial symbol is an operator symbol
  721.  
  722.    function P_Defining_Operator_Symbol return Node_Id is
  723.       Op_Node : Node_Id;
  724.  
  725.    begin
  726.       Op_Node := Token_Node;
  727.       Change_Operator_Symbol_To_Defining_Operator_Symbol (Op_Node);
  728.       Scan; -- past operator symbol
  729.       return Op_Node;
  730.    end P_Defining_Operator_Symbol;
  731.  
  732.    ----------------------------
  733.    -- 6.1  Parameter_Profile --
  734.    ----------------------------
  735.  
  736.    --  PARAMETER_PROFILE ::= [FORMAL_PART]
  737.  
  738.    --  Empty is returned if no formal part is present
  739.  
  740.    --  Error recovery: cannot raise Error_Resync
  741.  
  742.    function P_Parameter_Profile return List_Id is
  743.    begin
  744.       if Token = Tok_Left_Paren then
  745.          Scan; -- part left paren
  746.          return P_Formal_Part;
  747.       else
  748.          return No_List;
  749.       end if;
  750.    end P_Parameter_Profile;
  751.  
  752.    ---------------------------------------
  753.    -- 6.1  Parameter And Result Profile --
  754.    ---------------------------------------
  755.  
  756.    --  Parsed by its parent construct, which uses P_Parameter_Profile to
  757.    --  parse the parameters, and P_Subtype_Mark to parse the return type.
  758.  
  759.    ----------------------
  760.    -- 6.1  Formal part --
  761.    ----------------------
  762.  
  763.    --  FORMAL_PART ::= (PARAMETER_SPECIFICATION {; PARAMETER_SPECIFICATION})
  764.  
  765.    --  PARAMETER_SPECIFICATION ::=
  766.    --    DEFINING_IDENTIFIER_LIST : MODE SUBTYPE_MARK
  767.    --      [:= DEFAULT_EXPRESSION]
  768.    --  | DEFINING_IDENTIFIER_LIST : ACCESS_DEFINITION
  769.    --      [:= DEFAULT_EXPRESSION]
  770.  
  771.    --  This scans the construct Formal_Part. The caller has already checked
  772.    --  that the initial token is a left parenthesis, and skipped past it, so
  773.    --  that on entry Token is the first token following the left parenthesis.
  774.  
  775.    --  Error recovery: cannot raise Error_Resync
  776.  
  777.    function P_Formal_Part return List_Id is
  778.       Specification_List : List_Id;
  779.       Specification_Node : Node_Id;
  780.       Scan_State         : Saved_Scan_State;
  781.       Num_Idents         : Nat;
  782.       Ident              : Nat;
  783.  
  784.       Idents : array (Int range 1 .. 4096) of Entity_Id;
  785.       --  This array holds the list of defining identifiers. The upper bound
  786.       --  of 4096 is intended to be essentially infinite, and we do not even
  787.       --  bother to check for it being exceeded.
  788.  
  789.    begin
  790.       Specification_List := New_List;
  791.  
  792.       Specification_Loop : loop
  793.          begin
  794.             if Token = Tok_Pragma then
  795.                P_Pragmas_Misplaced;
  796.             end if;
  797.  
  798.             Idents (1) := P_Defining_Identifier;
  799.             Num_Idents := 1;
  800.  
  801.             Ident_Loop : loop
  802.                exit Ident_Loop when Token = Tok_Colon;
  803.  
  804.                --  The only valid tokens are colon and comma, so if we have
  805.                --  neither do a bit of investigation to see which is the
  806.                --  better choice for insertion.
  807.  
  808.                if Token /= Tok_Comma then
  809.  
  810.                   --  Assume colon if IN or OUT keyword found
  811.  
  812.                   exit Ident_Loop when Token = Tok_In or else Token = Tok_Out;
  813.  
  814.                   --  Otherwise scan ahead
  815.  
  816.                   Save_Scan_State (Scan_State);
  817.                   Look_Ahead : loop
  818.  
  819.                      --  If we run into a semicolon, then assume that a
  820.                      --  colon was missing, e.g.  Parms (X Y; ...). Also
  821.                      --  assume missing colon on EOF (a real disaster!)
  822.                      --  and on a right paren, e.g. Parms (X Y), and also
  823.                      --  on an assignment symbol, e.g. Parms (X Y := ..)
  824.  
  825.                      if Token = Tok_Semicolon
  826.                        or else Token = Tok_Right_Paren
  827.                        or else Token = Tok_EOF
  828.                        or else Token = Tok_Colon_Equal
  829.                      then
  830.                         Restore_Scan_State (Scan_State);
  831.                         exit Ident_Loop;
  832.  
  833.                      --  If we run into a colon, assume that we had a missing
  834.                      --  comma, e.g. Parms (A B : ...). Also assume a missing
  835.                      --  comma if we hit another comma, e.g. Parms (A B, C ..)
  836.  
  837.                      elsif Token = Tok_Colon
  838.                        or else Token = Tok_Comma
  839.                      then
  840.                         Restore_Scan_State (Scan_State);
  841.                         exit Look_Ahead;
  842.                      end if;
  843.  
  844.                      Scan;
  845.                   end loop Look_Ahead;
  846.                end if;
  847.  
  848.                --  Here if a comma is present, or to be assumed
  849.  
  850.                T_Comma;
  851.                Num_Idents := Num_Idents + 1;
  852.                Idents (Num_Idents) := P_Defining_Identifier;
  853.             end loop Ident_Loop;
  854.  
  855.             --  Fall through the loop on encountering a colon, or deciding
  856.             --  that there is a missing colon.
  857.  
  858.             T_Colon;
  859.  
  860.             --  If there are multiple identifiers, we repeatedly scan the
  861.             --  type and initialization expression information by resetting
  862.             --  the scan pointer (so that we get completely separate trees
  863.             --  for each occurrence).
  864.  
  865.             if Num_Idents > 1 then
  866.                Save_Scan_State (Scan_State);
  867.             end if;
  868.  
  869.             --  Loop through defining identifiers in list
  870.  
  871.             Ident := 1;
  872.  
  873.             Ident_List_Loop : loop
  874.                Specification_Node :=
  875.                  New_Node (N_Parameter_Specification, Token_Ptr);
  876.                Set_Defining_Identifier (Specification_Node, Idents (Ident));
  877.  
  878.                if Token = Tok_Access then
  879.                   if Ada_83 then
  880.                      Error_Msg_SC ("(Ada 83) access parameters not allowed");
  881.                   end if;
  882.  
  883.                   Note_Feature (Access_Parameters, Token_Ptr);
  884.                   Set_Parameter_Type
  885.                     (Specification_Node, P_Access_Definition);
  886.  
  887.                else
  888.                   P_Mode (Specification_Node);
  889.                   Set_Parameter_Type (Specification_Node, P_Subtype_Mark);
  890.                   No_Constraint;
  891.                end if;
  892.  
  893.                Set_Expression (Specification_Node, Init_Expr_Opt (True));
  894.  
  895.                if Ident > 1 then
  896.                   Set_Prev_Ids (Specification_Node, True);
  897.                end if;
  898.  
  899.                if Ident < Num_Idents then
  900.                   Set_More_Ids (Specification_Node, True);
  901.                end if;
  902.  
  903.                Append (Specification_Node, Specification_List);
  904.                exit Ident_List_Loop when Ident = Num_Idents;
  905.                Ident := Ident + 1;
  906.                Restore_Scan_State (Scan_State);
  907.             end loop Ident_List_Loop;
  908.  
  909.          exception
  910.             when Error_Resync =>
  911.                Resync_Semicolon_List;
  912.          end;
  913.  
  914.          if Token = Tok_Semicolon then
  915.             Scan; -- past semicolon
  916.  
  917.             --  If we have RETURN or IS after the semicolon, then assume
  918.             --  that semicolon should have been a right parenthesis and exit
  919.  
  920.             if Token = Tok_Is or else Token = Tok_Return then
  921.                Error_Msg_SP ("expected "")"" in place of "";""");
  922.                exit Specification_Loop;
  923.             end if;
  924.  
  925.          elsif Token = Tok_Right_Paren then
  926.             Scan; -- past right paren
  927.             exit Specification_Loop;
  928.  
  929.          --  Special check for common error of using comma instead of semicolon
  930.  
  931.          elsif Token = Tok_Comma then
  932.             T_Semicolon;
  933.             Scan; -- past comma
  934.  
  935.          --  Special check for omitted separator
  936.  
  937.          elsif Token = Tok_Identifier then
  938.             T_Semicolon;
  939.  
  940.          --  If nothing sensible, skip to next semicolon or right paren
  941.  
  942.          else
  943.             T_Semicolon;
  944.             Resync_Semicolon_List;
  945.  
  946.             if Token = Tok_Semicolon then
  947.                Scan; -- past semicolon
  948.             else
  949.                T_Right_Paren;
  950.                exit Specification_Loop;
  951.             end if;
  952.          end if;
  953.       end loop Specification_Loop;
  954.  
  955.       return Specification_List;
  956.    end P_Formal_Part;
  957.  
  958.    ----------------------------------
  959.    -- 6.1  Parameter Specification --
  960.    ----------------------------------
  961.  
  962.    --  Parsed by P_Formal_Part (6.1)
  963.  
  964.    ---------------
  965.    -- 6.1  Mode --
  966.    ---------------
  967.  
  968.    --  MODE ::= [in] | in out | out
  969.  
  970.    --  There is no explicit node in the tree for the Mode. Instead the
  971.    --  In_Present and Out_Present flags are set in the parent node to
  972.    --  record the presence of keywords specifying the mode.
  973.  
  974.    --  Error_Recovery: cannot raise Error_Resync
  975.  
  976.    procedure P_Mode (Node : Node_Id) is
  977.    begin
  978.       if Token = Tok_In then
  979.          Scan; -- past IN
  980.          Set_In_Present (Node, True);
  981.       end if;
  982.  
  983.       if Token = Tok_Out then
  984.          Scan; -- past OUT
  985.          Set_Out_Present (Node, True);
  986.       end if;
  987.  
  988.       if Token = Tok_In then
  989.          Error_Msg_SC ("IN must preceed OUT in parameter mode");
  990.          Scan; -- past IN
  991.          Set_In_Present (Node, True);
  992.       end if;
  993.    end P_Mode;
  994.  
  995.    --------------------------
  996.    -- 6.3  Subprogram Body --
  997.    --------------------------
  998.  
  999.    --  Parsed by P_Subprogram (6.1)
  1000.  
  1001.    -----------------------------------
  1002.    -- 6.4  Procedure Call Statement --
  1003.    -----------------------------------
  1004.  
  1005.    --  Parsed by P_Sequence_Of_Statements (5.1)
  1006.  
  1007.    ------------------------
  1008.    -- 6.4  Function Call --
  1009.    ------------------------
  1010.  
  1011.    --  Parsed by P_Call_Or_Name (4.1)
  1012.  
  1013.    --------------------------------
  1014.    -- 6.4  Actual Parameter Part --
  1015.    --------------------------------
  1016.  
  1017.    --  Parsed by P_Call_Or_Name (4.1)
  1018.  
  1019.    --------------------------------
  1020.    -- 6.4  Parameter Association --
  1021.    --------------------------------
  1022.  
  1023.    --  Parsed by P_Call_Or_Name (4.1)
  1024.  
  1025.    ------------------------------------
  1026.    -- 6.4  Explicit Actual Parameter --
  1027.    ------------------------------------
  1028.  
  1029.    --  Parsed by P_Call_Or_Name (4.1)
  1030.  
  1031.    ---------------------------
  1032.    -- 6.5  Return Statement --
  1033.    ---------------------------
  1034.  
  1035.    --  RETURN_STATEMENT ::= return [EXPRESSION];
  1036.  
  1037.    --  The caller has checked that the initial token is RETURN
  1038.  
  1039.    --  Error recovery: can raise Error_Resync
  1040.  
  1041.    function P_Return_Statement return Node_Id is
  1042.       Return_Node : Node_Id;
  1043.  
  1044.    begin
  1045.       Return_Node := New_Node (N_Return_Statement, Token_Ptr);
  1046.  
  1047.       --  Sloc points to RETURN
  1048.       --  Expression (Op3)
  1049.  
  1050.       Scan; -- past RETURN
  1051.  
  1052.       if Token /= Tok_Semicolon then
  1053.  
  1054.          --  If no semicolon, then scan an expression, except that
  1055.          --  we avoid trying to scan an expression if we are at an
  1056.          --  expression terminator since in that case the best error
  1057.          --  message is probably that we have a missing semicolon.
  1058.  
  1059.          if Token not in Token_Class_Eterm then
  1060.             Set_Expression (Return_Node, P_Expression_No_Right_Paren);
  1061.          end if;
  1062.       end if;
  1063.  
  1064.       TF_Semicolon;
  1065.       return Return_Node;
  1066.    end P_Return_Statement;
  1067.  
  1068. end Ch6;
  1069.