OSDN Git Service

* c-decl.c (grokfield): Allow typedefs for anonymous structs and
[pf3gnuchains/gcc-fork.git] / gcc / ada / par-ch6.adb
index 3d7e270..ea5df6d 100644 (file)
@@ -6,18 +6,17 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2004 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,  59 Temple Place - Suite 330,  Boston, --
--- MA 02111-1307, 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,8 +36,15 @@ 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;
+
    --  Check for common error of junk semicolon before RETURN keyword of
    --  function specification. If present, skip over it with appropriate
    --  error message, leaving Scan_Ptr pointing to the RETURN after. This
@@ -58,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;
@@ -109,6 +114,13 @@ package body Ch6 is
    --  | function DEFINING_DESIGNATOR is
    --      new generic_function_NAME [GENERIC_ACTUAL_PART];
 
+   --  NULL_PROCEDURE_DECLARATION ::=
+   --    SUBPROGRAM_SPECIFICATION is null;
+
+   --  Null procedures are an Ada 2005 feature. A null procedure declaration
+   --  is classified as a basic declarative item, but it is parsed here, with
+   --  other subprogram constructs.
+
    --  The value in Pf_Flags indicates which of these possible declarations
    --  is acceptable to the caller:
 
@@ -123,25 +135,34 @@ package body Ch6 is
    --  context is issued. The only possible values for Pf_Flags are those
    --  defined as constants in the Par package.
 
-   --  The caller has checked that the initial token is FUNCTION or PROCEDURE
+   --  The caller has checked that the initial token is FUNCTION, PROCEDURE,
+   --  NOT or OVERRIDING.
 
    --  Error recovery: cannot raise Error_Resync
 
    function P_Subprogram (Pf_Flags : Pf_Rec) return Node_Id is
       Specification_Node : Node_Id;
-      Name_Node   : Node_Id;
-      Fpart_List  : List_Id;
-      Fpart_Sloc  : Source_Ptr;
-      Return_Node : Node_Id;
-      Inst_Node   : Node_Id;
-      Body_Node   : Node_Id;
-      Decl_Node   : Node_Id;
-      Rename_Node : Node_Id;
-      Absdec_Node : Node_Id;
-      Stub_Node   : Node_Id;
-      Fproc_Sloc  : Source_Ptr;
-      Func        : Boolean;
-      Scan_State  : Saved_Scan_State;
+      Name_Node          : Node_Id;
+      Fpart_List         : List_Id;
+      Fpart_Sloc         : Source_Ptr;
+      Result_Not_Null    : Boolean := False;
+      Result_Node        : Node_Id;
+      Inst_Node          : Node_Id;
+      Body_Node          : Node_Id;
+      Decl_Node          : Node_Id;
+      Rename_Node        : Node_Id;
+      Absdec_Node        : Node_Id;
+      Stub_Node          : Node_Id;
+      Fproc_Sloc         : Source_Ptr;
+      Func               : Boolean;
+      Scan_State         : Saved_Scan_State;
+
+      --  Flags for optional overriding indication. Two flags are needed,
+      --  to distinguish positive and negative overriding indicators from
+      --  the absence of any indicator.
+
+      Is_Overriding  : Boolean := False;
+      Not_Overriding : Boolean := False;
 
    begin
       --  Set up scope stack entry. Note that the Labl field will be set later
@@ -154,6 +175,63 @@ package body Ch6 is
       Scope.Table (Scope.Last).Ecol := Start_Column;
       Scope.Table (Scope.Last).Lreq := False;
 
+      --  Ada2005: scan leading NOT OVERRIDING indicator
+
+      if Token = Tok_Not then
+         Scan;  -- past NOT
+
+         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
+
+         --  Note that if we are not in Ada_05 mode, error messages have
+         --  already been given, so no need to give another message here.
+
+         --  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 -- CODEFIX
+              ("FUNCTION or PROCEDURE expected!");
+         end if;
+      end if;
+
       Func := (Token = Tok_Function);
       Fproc_Sloc := Token_Ptr;
       Scan; -- past FUNCTION or PROCEDURE
@@ -191,22 +269,18 @@ 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
 
       if Token = Tok_Is then
          Save_Scan_State (Scan_State); -- at the IS
-         T_Is; -- checks for redundant IS's
+         T_Is; -- checks for redundant 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
@@ -223,6 +297,14 @@ package body Ch6 is
             Set_Generic_Associations (Inst_Node, P_Generic_Actual_Part_Opt);
             TF_Semicolon;
             Pop_Scope_Stack; -- Don't need scope stack entry in this case
+
+            if Is_Overriding then
+               Set_Must_Override (Inst_Node);
+
+            elsif Not_Overriding then
+               Set_Must_Not_Override (Inst_Node);
+            end if;
+
             return Inst_Node;
 
          else
@@ -259,7 +341,7 @@ package body Ch6 is
       --  since later RETURN statements will be valid in either case.
 
       Check_Junk_Semicolon_Before_Return;
-      Return_Node := Error;
+      Result_Node := Error;
 
       if Token = Tok_Return then
          if not Func then
@@ -268,8 +350,24 @@ package body Ch6 is
          end if;
 
          Scan; -- past RETURN
-         Return_Node := P_Subtype_Mark;
-         No_Constraint;
+
+         Result_Not_Null := P_Null_Exclusion;     --  Ada 2005 (AI-231)
+
+         --  Ada 2005 (AI-318-02)
+
+         if Token = Tok_Access then
+            if Ada_Version < Ada_05 then
+               Error_Msg_SC
+                 ("anonymous access result type is an Ada 2005 extension");
+               Error_Msg_SC ("\unit must be compiled with -gnat05 switch");
+            end if;
+
+            Result_Node := P_Access_Definition (Result_Not_Null);
+
+         else
+            Result_Node := P_Subtype_Mark;
+            No_Constraint;
+         end if;
 
       else
          if Func then
@@ -281,7 +379,9 @@ package body Ch6 is
       if Func then
          Specification_Node :=
            New_Node (N_Function_Specification, Fproc_Sloc);
-         Set_Subtype_Mark (Specification_Node, Return_Node);
+
+         Set_Null_Exclusion_Present (Specification_Node, Result_Not_Null);
+         Set_Result_Definition (Specification_Node, Result_Node);
 
       else
          Specification_Node :=
@@ -291,6 +391,13 @@ package body Ch6 is
       Set_Defining_Unit_Name (Specification_Node, Name_Node);
       Set_Parameter_Specifications (Specification_Node, Fpart_List);
 
+      if Is_Overriding then
+         Set_Must_Override (Specification_Node);
+
+      elsif Not_Overriding then
+         Set_Must_Not_Override (Specification_Node);
+      end if;
+
       --  Error check: barriers not allowed on protected functions/procedures
 
       if Token = Tok_When then
@@ -304,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
@@ -317,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
@@ -329,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
@@ -384,6 +504,25 @@ package body Ch6 is
                TF_Semicolon;
                return Absdec_Node;
 
+            --  Ada 2005 (AI-248): Parse a null procedure declaration
+
+            elsif Token = Tok_Null then
+               if Ada_Version < Ada_05 then
+                  Error_Msg_SP ("null procedures are an Ada 2005 extension");
+                  Error_Msg_SP ("\unit must be compiled with -gnat05 switch");
+               end if;
+
+               Scan; -- past NULL
+
+               if Func then
+                  Error_Msg_SP ("only procedures can be null");
+               else
+                  Set_Null_Present (Specification_Node);
+               end if;
+
+               TF_Semicolon;
+               goto Subprogram_Declaration;
+
             --  Check for IS NEW with Formal_Part present and handle nicely
 
             elsif Token = Tok_New then
@@ -414,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;
@@ -533,6 +672,8 @@ package body Ch6 is
 
    function P_Subprogram_Specification return Node_Id is
       Specification_Node : Node_Id;
+      Result_Not_Null    : Boolean;
+      Result_Node        : Node_Id;
 
    begin
       if Token = Tok_Function then
@@ -544,8 +685,27 @@ package body Ch6 is
            (Specification_Node, P_Parameter_Profile);
          Check_Junk_Semicolon_Before_Return;
          TF_Return;
-         Set_Subtype_Mark (Specification_Node, P_Subtype_Mark);
-         No_Constraint;
+
+         Result_Not_Null := P_Null_Exclusion;     --  Ada 2005 (AI-231)
+
+         --  Ada 2005 (AI-318-02)
+
+         if Token = Tok_Access then
+            if Ada_Version < Ada_05 then
+               Error_Msg_SC
+                 ("anonymous access result type is an Ada 2005 extension");
+               Error_Msg_SC ("\unit must be compiled with -gnat05 switch");
+            end if;
+
+            Result_Node := P_Access_Definition (Result_Not_Null);
+
+         else
+            Result_Node := P_Subtype_Mark;
+            No_Constraint;
+         end if;
+
+         Set_Null_Exclusion_Present (Specification_Node, Result_Not_Null);
+         Set_Result_Definition (Specification_Node, Result_Node);
          return Specification_Node;
 
       elsif Token = Tok_Procedure then
@@ -735,7 +895,7 @@ package body Ch6 is
             Error_Msg_SP ("child unit allowed only at library level");
             raise Error_Resync;
 
-         elsif Ada_83 then
+         elsif Ada_Version = Ada_83 then
             Error_Msg_SP ("(Ada 83) child unit not allowed!");
 
          end if;
@@ -858,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
@@ -869,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);
@@ -953,28 +1115,49 @@ 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 0Y (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
                     (Specification_Node, Not_Null_Present);
 
-                  if Ada_83 then
+                  if Ada_Version = Ada_83 then
                      Error_Msg_SC ("(Ada 83) access parameters not allowed");
                   end if;
 
                   Set_Parameter_Type
-                    (Specification_Node, P_Access_Definition);
+                    (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);
-                     Not_Null_Present := P_Null_Exclusion; --  Ada 0Y (AI-231)
+                     Not_Null_Present := P_Null_Exclusion; -- Ada 2005 (AI-231)
                   end if;
 
                   Set_Null_Exclusion_Present
@@ -1033,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;
 
@@ -1102,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
@@ -1110,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;
@@ -1156,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;