OSDN Git Service

gcc/ada/
[pf3gnuchains/gcc-fork.git] / gcc / ada / par-ch2.adb
index 0eeacea..c778ac9 100644 (file)
@@ -6,23 +6,20 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---                            $Revision: 1.35 $                             --
---                                                                          --
---          Copyright (C) 1992-2001 Free Software Foundation, Inc.          --
+--          Copyright (C) 1992-2007, 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. --
--- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
 --                                                                          --
 ------------------------------------------------------------------------------
 
@@ -35,7 +32,14 @@ package body Ch2 is
 
    --  Local functions, used only in this chapter
 
-   function P_Pragma_Argument_Association return Node_Id;
+   procedure Scan_Pragma_Argument_Association
+     (Identifier_Seen : in out Boolean;
+      Association     : out Node_Id);
+   --  Scans out a pragma argument association. Identifier_Seen is true on
+   --  entry if a previous association had an identifier, and gets set True if
+   --  the scanned association has an identifier (this is used to check the
+   --  rule that no associations without identifiers can follow an association
+   --  which has an identifier). The result is returned in Association.
 
    ---------------------
    -- 2.3  Identifier --
@@ -49,13 +53,29 @@ package body Ch2 is
 
    --  Error recovery: can raise Error_Resync (cannot return Error)
 
-   function P_Identifier return Node_Id is
+   function P_Identifier (C : Id_Check := None) return Node_Id is
       Ident_Node : Node_Id;
 
    begin
       --  All set if we do indeed have an identifier
 
       if Token = Tok_Identifier then
+
+         --  Ada 2005 (AI-284): Compiling in Ada95 mode we warn that INTERFACE,
+         --  OVERRIDING, and SYNCHRONIZED are new reserved words.
+
+         if Ada_Version = Ada_95
+           and then Warn_On_Ada_2005_Compatibility
+         then
+            if Token_Name = Name_Overriding
+              or else Token_Name = Name_Synchronized
+              or else (Token_Name = Name_Interface
+                        and then Prev_Token /= Tok_Pragma)
+            then
+               Error_Msg_N ("& is a reserved word in Ada 2005?", Token_Node);
+            end if;
+         end if;
+
          Ident_Node := Token_Node;
          Scan; -- past Identifier
          return Ident_Node;
@@ -63,7 +83,7 @@ package body Ch2 is
       --  If we have a reserved identifier, manufacture an identifier with
       --  a corresponding name after posting an appropriate error message
 
-      elsif Is_Reserved_Identifier then
+      elsif Is_Reserved_Identifier (C) then
          Scan_Reserved_Identifier (Force_Msg => False);
          Ident_Node := Token_Node;
          Scan; -- past the node
@@ -156,7 +176,7 @@ package body Ch2 is
 
    --  CHARACTER_LITERAL ::= ' GRAPHIC_CHARACTER '
 
-   --  Handled by the scanner and returned as Tok_Character_Literal
+   --  Handled by the scanner and returned as Tok_Char_Literal
 
    -------------------------
    -- 2.6  String Literal --
@@ -164,7 +184,7 @@ package body Ch2 is
 
    --  STRING LITERAL ::= "{STRING_ELEMENT}"
 
-   --  Handled by the scanner and returned as Tok_Character_Literal
+   --  Handled by the scanner and returned as Tok_String_Literal
    --  or if the string looks like an operator as Tok_Operator_Symbol.
 
    -------------------------
@@ -218,11 +238,35 @@ package body Ch2 is
       Arg_Count : Int := 0;
       --  Number of argument associations processed
 
+      Identifier_Seen : Boolean := False;
+      --  Set True if an identifier is encountered for a pragma argument. Used
+      --  to check that there are no more arguments without identifiers.
+
       Pragma_Node   : Node_Id;
       Pragma_Name   : Name_Id;
       Semicolon_Loc : Source_Ptr;
       Ident_Node    : Node_Id;
       Assoc_Node    : Node_Id;
+      Result        : Node_Id;
+
+      procedure Skip_Pragma_Semicolon;
+      --  Skip past semicolon at end of pragma
+
+      ---------------------------
+      -- Skip_Pragma_Semicolon --
+      ---------------------------
+
+      procedure Skip_Pragma_Semicolon is
+      begin
+         if Token /= Tok_Semicolon then
+            T_Semicolon;
+            Resync_Past_Semicolon;
+         else
+            Scan; -- past semicolon
+         end if;
+      end Skip_Pragma_Semicolon;
+
+   --  Start of processing for P_Pragma
 
    begin
       Pragma_Node := New_Node (N_Pragma, Token_Ptr);
@@ -233,9 +277,21 @@ package body Ch2 is
          Style.Check_Pragma_Name;
       end if;
 
-      Ident_Node := P_Identifier;
+      --  Ada 2005 (AI-284): INTERFACE is a new reserved word but it is
+      --  allowed as a pragma name.
+
+      if Ada_Version >= Ada_05
+        and then Token = Tok_Interface
+      then
+         Pragma_Name := Name_Interface;
+         Ident_Node  := Token_Node;
+         Scan; -- past INTERFACE
+      else
+         Ident_Node := P_Identifier;
+         Delete_Node (Ident_Node);
+      end if;
+
       Set_Chars (Pragma_Node, Pragma_Name);
-      Delete_Node (Ident_Node);
 
       --  See if special INTERFACE/IMPORT check is required
 
@@ -260,7 +316,7 @@ package body Ch2 is
 
          loop
             Arg_Count := Arg_Count + 1;
-            Assoc_Node := P_Pragma_Argument_Association;
+            Scan_Pragma_Argument_Association (Identifier_Seen, Assoc_Node);
 
             if Arg_Count = 2
               and then (Interface_Check_Required or else Import_Check_Required)
@@ -280,25 +336,44 @@ package body Ch2 is
             Scan; -- past comma
          end loop;
 
-         T_Right_Paren;
-      end if;
+         --  If we have := for pragma Debug, it is worth special casing
+         --  the error message (it is easy to think of pragma Debug as
+         --  taking a statement, and an assignment statement is the most
+         --  likely candidate for this error)
 
-      Semicolon_Loc := Token_Ptr;
+         if Token = Tok_Colon_Equal and then Pragma_Name = Name_Debug then
+            Error_Msg_SC ("argument for pragma Debug must be procedure call");
+            Resync_To_Semicolon;
 
-      if Token /= Tok_Semicolon then
-         T_Semicolon;
-         Resync_Past_Semicolon;
-      else
-         Scan; -- past semicolon
+         --  Normal case, we expect a right paren here
+
+         else
+            T_Right_Paren;
+         end if;
       end if;
 
-      if Is_Pragma_Name (Chars (Pragma_Node)) then
-         return Par.Prag (Pragma_Node, Semicolon_Loc);
+      Semicolon_Loc := Token_Ptr;
 
+      --  Now we have two tasks left, we need to scan out the semicolon
+      --  following the pragma, and we have to call Par.Prag to process
+      --  the pragma. Normally we do them in this order, however, there
+      --  is one exception namely pragma Style_Checks where we like to
+      --  skip the semicolon after processing the pragma, since that way
+      --  the style checks for the scanning of the semicolon follow the
+      --  settings of the pragma.
+
+      --  You might think we could just unconditionally do things in
+      --  the opposite order, but there are other pragmas, notably the
+      --  case of pragma Source_File_Name, which assume the semicolon
+      --  is already scanned out.
+
+      if Chars (Pragma_Node) = Name_Style_Checks then
+         Result := Par.Prag (Pragma_Node, Semicolon_Loc);
+         Skip_Pragma_Semicolon;
+         return Result;
       else
-         --  Unrecognized pragma, warning generated in Sem_Prag
-
-         return Pragma_Node;
+         Skip_Pragma_Semicolon;
+         return Par.Prag (Pragma_Node, Semicolon_Loc);
       end if;
 
    exception
@@ -374,14 +449,16 @@ package body Ch2 is
 
    --  Error recovery: cannot raise Error_Resync
 
-   function P_Pragma_Argument_Association return Node_Id is
+   procedure Scan_Pragma_Argument_Association
+     (Identifier_Seen : in out Boolean;
+      Association     : out Node_Id)
+   is
       Scan_State      : Saved_Scan_State;
-      Pragma_Arg_Node : Node_Id;
       Identifier_Node : Node_Id;
 
    begin
-      Pragma_Arg_Node := New_Node (N_Pragma_Argument_Association, Token_Ptr);
-      Set_Chars (Pragma_Arg_Node, No_Name);
+      Association := New_Node (N_Pragma_Argument_Association, Token_Ptr);
+      Set_Chars (Association, No_Name);
 
       if Token = Tok_Identifier then
          Identifier_Node := Token_Node;
@@ -389,17 +466,24 @@ package body Ch2 is
          Scan; -- past Identifier
 
          if Token = Tok_Arrow then
+            Identifier_Seen := True;
             Scan; -- past arrow
-            Set_Chars (Pragma_Arg_Node, Chars (Identifier_Node));
+            Set_Chars (Association, Chars (Identifier_Node));
             Delete_Node (Identifier_Node);
+
+            --  Case of argument with no identifier
+
          else
             Restore_Scan_State (Scan_State); -- to Identifier
+
+            if Identifier_Seen then
+               Error_Msg_SC
+                 ("|pragma argument identifier required here (RM 2.8(4))");
+            end if;
          end if;
       end if;
 
-      Set_Expression (Pragma_Arg_Node, P_Expression);
-      return Pragma_Arg_Node;
-
-   end P_Pragma_Argument_Association;
+      Set_Expression (Association, P_Expression);
+   end Scan_Pragma_Argument_Association;
 
 end Ch2;