OSDN Git Service

Regenerate gcc/configure.
[pf3gnuchains/gcc-fork.git] / gcc / ada / par-ch6.adb
index 72855f9..ea5df6d 100644 (file)
@@ -6,18 +6,17 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2005, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2009, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
--- ware  Foundation;  either version 2,  or (at your option) any later ver- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
 -- for  more details.  You should have  received  a copy of the GNU General --
--- Public License  distributed with GNAT;  see file COPYING.  If not, write --
--- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
--- Boston, MA 02110-1301, USA.                                              --
+-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
+-- http://www.gnu.org/licenses for a complete copy of the license.          --
 --                                                                          --
 -- GNAT was originally developed  by the GNAT team at  New York University. --
 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
@@ -37,6 +36,12 @@ package body Ch6 is
 
    function P_Defining_Designator        return Node_Id;
    function P_Defining_Operator_Symbol   return Node_Id;
+   function P_Return_Object_Declaration  return Node_Id;
+
+   procedure P_Return_Subtype_Indication (Decl_Node : Node_Id);
+   --  Decl_Node is a N_Object_Declaration.
+   --  Set the Null_Exclusion_Present and Object_Definition fields of
+   --  Decl_Node.
 
    procedure Check_Junk_Semicolon_Before_Return;
 
@@ -59,9 +64,8 @@ package body Ch6 is
 
          if Token = Tok_Return then
             Restore_Scan_State (Scan_State);
-            Error_Msg_SC ("unexpected semicolon ignored");
+            Error_Msg_SC ("|extra "";"" ignored");
             Scan; -- rescan past junk semicolon
-
          else
             Restore_Scan_State (Scan_State);
          end if;
@@ -171,7 +175,7 @@ package body Ch6 is
       Scope.Table (Scope.Last).Ecol := Start_Column;
       Scope.Table (Scope.Last).Lreq := False;
 
-      --  Ada2005: scan leading overriding indicator
+      --  Ada2005: scan leading NOT OVERRIDING indicator
 
       if Token = Tok_Not then
          Scan;  -- past NOT
@@ -179,30 +183,52 @@ package body Ch6 is
          if Token = Tok_Overriding then
             Scan;  --  past OVERRIDING
             Not_Overriding := True;
+
+         --  Overriding keyword used in non Ada 2005 mode
+
+         elsif Token = Tok_Identifier
+           and then Token_Name = Name_Overriding
+         then
+            Error_Msg_SC ("overriding indicator is an Ada 2005 extension");
+            Error_Msg_SC ("\unit must be compiled with -gnat05 switch");
+            Scan;  --  past Overriding
+            Not_Overriding := True;
+
          else
             Error_Msg_SC ("OVERRIDING expected!");
          end if;
 
+      --  Ada 2005: scan leading OVERRIDING indicator
+
+      --  Note: in the case of OVERRIDING keyword used in Ada 95 mode, the
+      --  declaration circuit already gave an error message and changed the
+      --  token to Tok_Overriding.
+
       elsif Token = Tok_Overriding then
          Scan;  --  past OVERRIDING
          Is_Overriding := True;
       end if;
 
       if (Is_Overriding or else Not_Overriding) then
-         if Ada_Version < Ada_05 then
-            Error_Msg_SP (" overriding indicator is an Ada 2005 extension");
-            Error_Msg_SP ("\unit must be compiled with -gnat05 switch");
 
-         --  An overriding indicator is allowed for subprogram declarations,
-         --  bodies, renamings, stubs, and instantiations.
+         --  Note that if we are not in Ada_05 mode, error messages have
+         --  already been given, so no need to give another message here.
 
-         elsif Pf_Flags /= Pf_Decl_Gins_Pbod_Rnam_Stub then
+         --  An overriding indicator is allowed for subprogram declarations,
+         --  bodies, renamings, stubs, and instantiations. The test against
+         --  Pf_Decl_Pbod is added to account for the case of subprograms
+         --  declared in a protected type, where only subprogram declarations
+         --  and bodies can occur.
+
+         if Pf_Flags /= Pf_Decl_Gins_Pbod_Rnam_Stub
+              and then
+            Pf_Flags /= Pf_Decl_Pbod
+         then
             Error_Msg_SC ("overriding indicator not allowed here!");
 
-         elsif Token /= Tok_Function
-           and then Token /= Tok_Procedure
-         then
-            Error_Msg_SC ("FUNCTION or PROCEDURE expected!");
+         elsif Token /= Tok_Function and then Token /= Tok_Procedure then
+            Error_Msg_SC -- CODEFIX
+              ("FUNCTION or PROCEDURE expected!");
          end if;
       end if;
 
@@ -243,11 +269,7 @@ package body Ch6 is
       end if;
 
       Scope.Table (Scope.Last).Labl := Name_Node;
-
-      if Token = Tok_Colon then
-         Error_Msg_SC ("redundant colon ignored");
-         Scan; -- past colon
-      end if;
+      Ignore (Tok_Colon);
 
       --  Deal with generic instantiation, the one case in which we do not
       --  have a subprogram specification as part of whatever we are parsing
@@ -258,7 +280,7 @@ package body Ch6 is
 
          if Token = Tok_New then
             if not Pf_Flags.Gins then
-               Error_Msg_SC ("generic instantation not allowed here!");
+               Error_Msg_SC ("generic instantiation not allowed here!");
             end if;
 
             Scan; -- past NEW
@@ -389,6 +411,19 @@ package body Ch6 is
          Discard_Junk_Node (P_Expression);
       end if;
 
+      --  Deal with semicolon followed by IS. We want to treat this as IS
+
+      if Token = Tok_Semicolon then
+         Save_Scan_State (Scan_State);
+         Scan; -- past semicolon
+
+         if Token = Tok_Is then
+            Error_Msg_SP ("extra "";"" ignored");
+         else
+            Restore_Scan_State (Scan_State);
+         end if;
+      end if;
+
       --  Deal with case of semicolon ending a subprogram declaration
 
       if Token = Tok_Semicolon then
@@ -402,8 +437,8 @@ package body Ch6 is
          --  semicolon, and go process the body.
 
          if Token = Tok_Is then
-            Error_Msg_SP ("unexpected semicolon ignored");
-            T_Is; -- ignroe redundant IS's
+            Error_Msg_SP ("|extra "";"" ignored");
+            T_Is; -- scan past IS
             goto Subprogram_Body;
 
          --  If BEGIN follows in an appropriate column, we immediately
@@ -414,7 +449,7 @@ package body Ch6 is
          elsif Token = Tok_Begin
             and then Start_Column >= Scope.Table (Scope.Last).Ecol
          then
-            Error_Msg_SP (""";"" should be IS!");
+            Error_Msg_SP ("|"";"" should be IS!");
             goto Subprogram_Body;
 
          else
@@ -518,7 +553,7 @@ package body Ch6 is
          --  semicolon which should really be an IS
 
          else
-            Error_Msg_AP ("missing "";""");
+            Error_Msg_AP ("|missing "";""");
             SIS_Missing_Semicolon_Message := Get_Msg_Id;
             goto Subprogram_Declaration;
          end if;
@@ -983,6 +1018,7 @@ package body Ch6 is
       Ident              : Nat;
       Ident_Sloc         : Source_Ptr;
       Not_Null_Present   : Boolean := False;
+      Not_Null_Sloc      : Source_Ptr;
 
       Idents : array (Int range 1 .. 4096) of Entity_Id;
       --  This array holds the list of defining identifiers. The upper bound
@@ -994,7 +1030,8 @@ package body Ch6 is
       Specification_Loop : loop
          begin
             if Token = Tok_Pragma then
-               P_Pragmas_Misplaced;
+               Error_Msg_SC ("pragma not allowed in formal part");
+               Discard_Junk_Node (P_Pragma (Skipping => True));
             end if;
 
             Ignore (Tok_Left_Paren);
@@ -1078,7 +1115,14 @@ package body Ch6 is
                Specification_Node :=
                  New_Node (N_Parameter_Specification, Ident_Sloc);
                Set_Defining_Identifier (Specification_Node, Idents (Ident));
-               Not_Null_Present := P_Null_Exclusion;     --  Ada 2005 (AI-231)
+
+               --  Scan possible NOT NULL for Ada 2005 (AI-231, AI-447)
+
+               Not_Null_Sloc := Token_Ptr;
+               Not_Null_Present :=
+                 P_Null_Exclusion (Allow_Anonymous_In_95 => True);
+
+               --  Case of ACCESS keyword present
 
                if Token = Tok_Access then
                   Set_Null_Exclusion_Present
@@ -1088,14 +1132,28 @@ package body Ch6 is
                      Error_Msg_SC ("(Ada 83) access parameters not allowed");
                   end if;
 
-                  Set_Parameter_Type (Specification_Node,
-                    P_Access_Definition (Not_Null_Present));
+                  Set_Parameter_Type
+                    (Specification_Node,
+                     P_Access_Definition (Not_Null_Present));
+
+               --  Case of IN or OUT present
 
                else
                   if Token = Tok_In or else Token = Tok_Out then
                      if Not_Null_Present then
-                        Error_Msg_SC
-                          ("ACCESS must be placed after the parameter mode");
+                        Error_Msg
+                          ("`NOT NULL` can only be used with `ACCESS`",
+                           Not_Null_Sloc);
+
+                        if Token = Tok_In then
+                           Error_Msg
+                             ("\`IN` not allowed together with `ACCESS`",
+                              Not_Null_Sloc);
+                        else
+                           Error_Msg
+                             ("\`OUT` not allowed together with `ACCESS`",
+                              Not_Null_Sloc);
+                        end if;
                      end if;
 
                      P_Mode (Specification_Node);
@@ -1158,7 +1216,7 @@ package body Ch6 is
             --  that semicolon should have been a right parenthesis and exit
 
             if Token = Tok_Is or else Token = Tok_Return then
-               Error_Msg_SP ("expected "")"" in place of "";""");
+               Error_Msg_SP ("|"";"" should be "")""");
                exit Specification_Loop;
             end if;
 
@@ -1227,6 +1285,15 @@ package body Ch6 is
       if Token = Tok_In then
          Scan; -- past IN
          Set_In_Present (Node, True);
+
+         if Style.Mode_In_Check and then Token /= Tok_Out then
+            Error_Msg_SP ("(style) IN should be omitted");
+         end if;
+
+         if Token = Tok_Access then
+            Error_Msg_SP ("IN not allowed together with ACCESS");
+            Scan; -- past ACCESS
+         end if;
       end if;
 
       if Token = Tok_Out then
@@ -1235,7 +1302,8 @@ package body Ch6 is
       end if;
 
       if Token = Tok_In then
-         Error_Msg_SC ("IN must preceed OUT in parameter mode");
+         Error_Msg_SC -- CODEFIX ???
+           ("IN must precede OUT in parameter mode");
          Scan; -- past IN
          Set_In_Present (Node, True);
       end if;
@@ -1281,36 +1349,210 @@ package body Ch6 is
    -- 6.5  Return Statement --
    ---------------------------
 
+   --  SIMPLE_RETURN_STATEMENT ::= return [EXPRESSION];
+   --
+   --  EXTENDED_RETURN_STATEMENT ::=
+   --    return DEFINING_IDENTIFIER : [aliased] RETURN_SUBTYPE_INDICATION
+   --                                           [:= EXPRESSION] [do
+   --      HANDLED_SEQUENCE_OF_STATEMENTS
+   --    end return];
+   --
+   --  RETURN_SUBTYPE_INDICATION ::= SUBTYPE_INDICATION | ACCESS_DEFINITION
+
    --  RETURN_STATEMENT ::= return [EXPRESSION];
 
-   --  The caller has checked that the initial token is RETURN
+   --  Error recovery: can raise Error_Resync
+
+   procedure P_Return_Subtype_Indication (Decl_Node : Node_Id) is
+
+      --  Note: We don't need to check Ada_Version here, because this is
+      --  only called in >= Ada 2005 cases anyway.
+
+      Not_Null_Present : constant Boolean := P_Null_Exclusion;
+
+   begin
+      Set_Null_Exclusion_Present (Decl_Node, Not_Null_Present);
+
+      if Token = Tok_Access then
+         Set_Object_Definition
+           (Decl_Node, P_Access_Definition (Not_Null_Present));
+      else
+         Set_Object_Definition
+           (Decl_Node, P_Subtype_Indication (Not_Null_Present));
+      end if;
+   end P_Return_Subtype_Indication;
+
+   --  Error recovery: can raise Error_Resync
+
+   function P_Return_Object_Declaration return Node_Id is
+      Return_Obj : Node_Id;
+      Decl_Node  : Node_Id;
+
+   begin
+      Return_Obj := Token_Node;
+      Change_Identifier_To_Defining_Identifier (Return_Obj);
+      Decl_Node := New_Node (N_Object_Declaration, Token_Ptr);
+      Set_Defining_Identifier (Decl_Node, Return_Obj);
+
+      Scan; -- past identifier
+      Scan; -- past :
+
+      --  First an error check, if we have two identifiers in a row, a likely
+      --  possibility is that the first of the identifiers is an incorrectly
+      --  spelled keyword. See similar check in P_Identifier_Declarations.
+
+      if Token = Tok_Identifier then
+         declare
+            SS : Saved_Scan_State;
+            I2 : Boolean;
+
+         begin
+            Save_Scan_State (SS);
+            Scan; -- past initial identifier
+            I2 := (Token = Tok_Identifier);
+            Restore_Scan_State (SS);
+
+            if I2
+              and then
+                (Bad_Spelling_Of (Tok_Access)   or else
+                 Bad_Spelling_Of (Tok_Aliased)  or else
+                 Bad_Spelling_Of (Tok_Constant))
+            then
+               null;
+            end if;
+         end;
+      end if;
+
+      --  We allow "constant" here (as in "return Result : constant
+      --  T..."). This is not in the latest RM, but the ARG is considering an
+      --  AI on the subject (see AI05-0015-1), which we expect to be approved.
+
+      if Token = Tok_Constant then
+         Scan; -- past CONSTANT
+         Set_Constant_Present (Decl_Node);
+
+         if Token = Tok_Aliased then
+            Error_Msg_SC -- CODEFIX
+              ("ALIASED should be before CONSTANT");
+            Scan; -- past ALIASED
+            Set_Aliased_Present (Decl_Node);
+         end if;
+
+      elsif Token = Tok_Aliased then
+         Scan; -- past ALIASED
+         Set_Aliased_Present (Decl_Node);
+
+         if Token = Tok_Constant then
+            Scan; -- past CONSTANT
+            Set_Constant_Present (Decl_Node);
+         end if;
+      end if;
+
+      P_Return_Subtype_Indication (Decl_Node);
+
+      if Token = Tok_Colon_Equal then
+         Scan; -- past :=
+         Set_Expression (Decl_Node, P_Expression_No_Right_Paren);
+      end if;
+
+      return Decl_Node;
+   end P_Return_Object_Declaration;
 
    --  Error recovery: can raise Error_Resync
 
    function P_Return_Statement return Node_Id is
+      --  The caller has checked that the initial token is RETURN
+
+      function Is_Simple return Boolean;
+      --  Scan state is just after RETURN (and is left that way).
+      --  Determine whether this is a simple or extended return statement
+      --  by looking ahead for "identifier :", which implies extended.
+
+      ---------------
+      -- Is_Simple --
+      ---------------
+
+      function Is_Simple return Boolean is
+         Scan_State : Saved_Scan_State;
+         Result     : Boolean := True;
+
+      begin
+         if Token = Tok_Identifier then
+            Save_Scan_State (Scan_State); -- at identifier
+            Scan; -- past identifier
+
+            if Token = Tok_Colon then
+               Result := False; -- It's an extended_return_statement.
+            end if;
+
+            Restore_Scan_State (Scan_State); -- to identifier
+         end if;
+
+         return Result;
+      end Is_Simple;
+
+      Return_Sloc : constant Source_Ptr := Token_Ptr;
       Return_Node : Node_Id;
 
+   --  Start of processing for P_Return_Statement
+
    begin
-      Return_Node := New_Node (N_Return_Statement, Token_Ptr);
+      Scan; -- past RETURN
 
-      --  Sloc points to RETURN
-      --  Expression (Op3)
+      --  Simple_return_statement, no expression, return an
+      --  N_Simple_Return_Statement node with the expression field left Empty.
 
-      Scan; -- past RETURN
+      if Token = Tok_Semicolon then
+         Scan; -- past ;
+         Return_Node := New_Node (N_Simple_Return_Statement, Return_Sloc);
 
-      if Token /= Tok_Semicolon then
+      --  Non-trivial case
 
-         --  If no semicolon, then scan an expression, except that
-         --  we avoid trying to scan an expression if we are at an
+      else
+         --  Simple_return_statement with expression
+
+         --  We avoid trying to scan an expression if we are at an
          --  expression terminator since in that case the best error
          --  message is probably that we have a missing semicolon.
 
-         if Token not in Token_Class_Eterm then
-            Set_Expression (Return_Node, P_Expression_No_Right_Paren);
+         if Is_Simple then
+            Return_Node := New_Node (N_Simple_Return_Statement, Return_Sloc);
+
+            if Token not in Token_Class_Eterm then
+               Set_Expression (Return_Node, P_Expression_No_Right_Paren);
+            end if;
+
+         --  Extended_return_statement (Ada 2005 only -- AI-318):
+
+         else
+            if Ada_Version < Ada_05 then
+               Error_Msg_SP
+                 (" extended_return_statement is an Ada 2005 extension");
+               Error_Msg_SP ("\unit must be compiled with -gnat05 switch");
+            end if;
+
+            Return_Node := New_Node (N_Extended_Return_Statement, Return_Sloc);
+            Set_Return_Object_Declarations
+              (Return_Node, New_List (P_Return_Object_Declaration));
+
+            if Token = Tok_Do then
+               Push_Scope_Stack;
+               Scope.Table (Scope.Last).Etyp := E_Return;
+               Scope.Table (Scope.Last).Ecol := Start_Column;
+               Scope.Table (Scope.Last).Sloc := Return_Sloc;
+
+               Scan; -- past DO
+               Set_Handled_Statement_Sequence
+                 (Return_Node, P_Handled_Sequence_Of_Statements);
+               End_Statements;
+
+               --  Do we need to handle Error_Resync here???
+            end if;
          end if;
+
+         TF_Semicolon;
       end if;
 
-      TF_Semicolon;
       return Return_Node;
    end P_Return_Statement;