]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/ada/scn.adb
[Ada] Bump copyright year
[thirdparty/gcc.git] / gcc / ada / scn.adb
index 52a9fac407627c9d3bb99b21775fa7b9ec5956e8..b16caeb871654e0181d971bcbaab587085951423 100644 (file)
@@ -6,18 +6,17 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2006, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2020, 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.      --
@@ -26,7 +25,6 @@
 
 with Atree;    use Atree;
 with Csets;    use Csets;
-with Hostparm; use Hostparm;
 with Namet;    use Namet;
 with Opt;      use Opt;
 with Restrict; use Restrict;
@@ -45,71 +43,11 @@ package body Scn is
    --  make sure that we only post an error message for incorrect use of a
    --  keyword as an identifier once for a given keyword).
 
-   procedure Check_End_Of_Line;
-   --  Called when end of line encountered. Checks that line is not too long,
-   --  and that other style checks for the end of line are met.
-
    function Determine_License return License_Type;
    --  Scan header of file and check that it has an appropriate GNAT-style
    --  header with a proper license statement. Returns GPL, Unrestricted,
    --  or Modified_GPL depending on header. If none of these, returns Unknown.
 
-   procedure Error_Long_Line;
-   --  Signal error of excessively long line
-
-   ---------------
-   -- Post_Scan --
-   ---------------
-
-   procedure Post_Scan is
-   begin
-      case Token is
-         when Tok_Char_Literal =>
-            Token_Node := New_Node (N_Character_Literal, Token_Ptr);
-            Set_Char_Literal_Value (Token_Node, UI_From_CC (Character_Code));
-            Set_Chars (Token_Node, Token_Name);
-
-         when Tok_Identifier =>
-            Token_Node := New_Node (N_Identifier, Token_Ptr);
-            Set_Chars (Token_Node, Token_Name);
-
-         when Tok_Real_Literal =>
-            Token_Node := New_Node (N_Real_Literal, Token_Ptr);
-            Set_Realval (Token_Node, Real_Literal_Value);
-
-         when Tok_Integer_Literal =>
-            Token_Node := New_Node (N_Integer_Literal, Token_Ptr);
-            Set_Intval (Token_Node, Int_Literal_Value);
-
-         when Tok_String_Literal =>
-            Token_Node := New_Node (N_String_Literal, Token_Ptr);
-            Set_Has_Wide_Character (Token_Node, Wide_Character_Found);
-            Set_Strval (Token_Node, String_Literal_Id);
-
-         when Tok_Operator_Symbol =>
-            Token_Node := New_Node (N_Operator_Symbol, Token_Ptr);
-            Set_Chars (Token_Node, Token_Name);
-            Set_Strval (Token_Node, String_Literal_Id);
-
-         when others =>
-            null;
-      end case;
-   end Post_Scan;
-
-   -----------------------
-   -- Check_End_Of_Line --
-   -----------------------
-
-   procedure Check_End_Of_Line is
-      Len : constant Int := Int (Scan_Ptr) - Int (Current_Line_Start);
-   begin
-      if Style_Check then
-         Style.Check_Line_Terminator (Len);
-      elsif Len > Max_Line_Length then
-         Error_Long_Line;
-      end if;
-   end Check_End_Of_Line;
-
    -----------------------
    -- Determine_License --
    -----------------------
@@ -222,7 +160,7 @@ package body Scn is
 
          Skip_EOL;
 
-         Check_End_Of_Line;
+         Scanner.Check_End_Of_Line;
 
          if Source (Scan_Ptr) /= EOF then
 
@@ -259,17 +197,6 @@ package body Scn is
       return Scanner.Determine_Token_Casing;
    end Determine_Token_Casing;
 
-   ---------------------
-   -- Error_Long_Line --
-   ---------------------
-
-   procedure Error_Long_Line is
-   begin
-      Error_Msg
-        ("this line is too long",
-         Current_Line_Start + Source_Ptr (Max_Line_Length));
-   end Error_Long_Line;
-
    ------------------------
    -- Initialize_Scanner --
    ------------------------
@@ -282,21 +209,14 @@ package body Scn is
 
    begin
       Scanner.Initialize_Scanner (Index);
-
-      if Index /= Internal_Source_File then
-         Set_Unit (Index, Unit);
-      end if;
+      Set_Unit (Index, Unit);
 
       Current_Source_Unit := Unit;
 
-      --  Set default for Comes_From_Source (except if we are going to process
-      --  an artificial string internally created within the compiler and
-      --  placed into internal source duffer). All nodes built now until we
+      --  Set default for Comes_From_Source. All nodes built now until we
       --  reenter the analyzer will have Comes_From_Source set to True
 
-      if Index /= Internal_Source_File then
-         Set_Comes_From_Source_Default (True);
-      end if;
+      Set_Comes_From_Source_Default (True);
 
       --  Check license if GNAT type header possibly present
 
@@ -306,66 +226,172 @@ package body Scn is
          Set_License (Current_Source_File, Determine_License);
       end if;
 
+      Check_For_BOM;
+
       --  Because of the License stuff above, Scng.Initialize_Scanner cannot
       --  call Scan. Scan initial token (note this initializes Prev_Token,
       --  Prev_Token_Ptr).
 
-      --  There are two reasons not to do the Scan step in case if we
-      --  initialize the scanner for the internal source buffer:
+      Scan;
 
-      --  - The artificial string may not be created by the compiler in this
-      --    buffer when we call Initialize_Scanner
+      --  Clear flags for reserved words used as identifiers
 
-      --  - For these artificial strings a special way of scanning is used, so
-      --    the standard step of the scanner may just break the algorithm of
-      --    processing these strings.
+      Used_As_Identifier := (others => False);
+   end Initialize_Scanner;
 
-      if Index /= Internal_Source_File then
-         Scan;
-      end if;
+   ---------------
+   -- Post_Scan --
+   ---------------
 
-      --  Clear flags for reserved words used as indentifiers
+   procedure Post_Scan is
+      procedure Check_Obsolescent_Features_Restriction (S : Source_Ptr);
+      --  This checks for Obsolescent_Features restriction being active, and
+      --  if so, flags the restriction as occurring at the given scan location.
 
-      for J in Token_Type loop
-         Used_As_Identifier (J) := False;
-      end loop;
-   end Initialize_Scanner;
+      procedure Check_Obsolete_Base_Char;
+      --  Check for numeric literal using ':' instead of '#' for based case
 
-   -----------------------
-   -- Obsolescent_Check --
-   -----------------------
+      --------------------------------------------
+      -- Check_Obsolescent_Features_Restriction --
+      --------------------------------------------
+
+      procedure Check_Obsolescent_Features_Restriction (S : Source_Ptr) is
+      begin
+         --  Normally we have a node handy for posting restrictions. We don't
+         --  have such a node here, so construct a dummy one with the right
+         --  scan pointer. This is only used to get the Sloc value anyway.
+
+         Check_Restriction (No_Obsolescent_Features, New_Node (N_Empty, S));
+      end Check_Obsolescent_Features_Restriction;
+
+      ------------------------------
+      -- Check_Obsolete_Base_Char --
+      ------------------------------
+
+      procedure Check_Obsolete_Base_Char is
+         S : Source_Ptr;
+
+      begin
+         if Based_Literal_Uses_Colon then
+
+            --  Find the : for the restriction or warning message
+
+            S := Token_Ptr;
+            while Source (S) /= ':' loop
+               S := S + 1;
+            end loop;
+
+            Check_Obsolescent_Features_Restriction (S);
+
+            if Warn_On_Obsolescent_Feature then
+               Error_Msg
+                 ("?j?use of "":"" is an obsolescent feature (RM J.2(3))", S);
+               Error_Msg
+                 ("\?j?use ""'#"" instead", S);
+            end if;
+         end if;
+      end Check_Obsolete_Base_Char;
+
+   --  Start of processing for Post_Scan
 
-   procedure Obsolescent_Check (S : Source_Ptr) is
    begin
-      --  This is a pain in the neck case, since we normally need a node to
-      --  call Check_Restrictions, and all we have is a source pointer. The
-      --  easiest thing is to construct a dummy node. A bit kludgy, but this
-      --  is a marginal case. It's not worth trying to do things more cleanly.
+      case Token is
+         when Tok_Char_Literal =>
+            Token_Node := New_Node (N_Character_Literal, Token_Ptr);
+            Set_Char_Literal_Value (Token_Node, UI_From_CC (Character_Code));
+            Set_Chars (Token_Node, Token_Name);
+
+         when Tok_Identifier =>
+            Token_Node := New_Node (N_Identifier, Token_Ptr);
+            Set_Chars (Token_Node, Token_Name);
+
+         when Tok_Real_Literal =>
+            Token_Node := New_Node (N_Real_Literal, Token_Ptr);
+            Set_Realval (Token_Node, Real_Literal_Value);
+            Check_Obsolete_Base_Char;
+
+         when Tok_Integer_Literal =>
+            Token_Node := New_Node (N_Integer_Literal, Token_Ptr);
+            Set_Intval (Token_Node, Int_Literal_Value);
+            Check_Obsolete_Base_Char;
+
+         when Tok_String_Literal =>
+            Token_Node := New_Node (N_String_Literal, Token_Ptr);
+            Set_Has_Wide_Character
+              (Token_Node, Wide_Character_Found);
+            Set_Has_Wide_Wide_Character
+              (Token_Node, Wide_Wide_Character_Found);
+            Set_Strval (Token_Node, String_Literal_Id);
+
+            if Source (Token_Ptr) = '%' then
+               Check_Obsolescent_Features_Restriction (Token_Ptr);
+
+               if Warn_On_Obsolescent_Feature then
+                  Error_Msg_SC
+                    ("?j?use of ""'%"" is an obsolescent feature (RM J.2(4))");
+                  Error_Msg_SC ("\?j?use """""" instead");
+               end if;
+            end if;
+
+         when Tok_Operator_Symbol =>
+            Token_Node := New_Node (N_Operator_Symbol, Token_Ptr);
+            Set_Chars (Token_Node, Token_Name);
+            Set_Strval (Token_Node, String_Literal_Id);
+
+         when Tok_Vertical_Bar =>
+            if Source (Token_Ptr) = '!' then
+               Check_Obsolescent_Features_Restriction (Token_Ptr);
 
-      Check_Restriction (No_Obsolescent_Features, New_Node (N_Empty, S));
-   end Obsolescent_Check;
+               if Warn_On_Obsolescent_Feature then
+                  Error_Msg_SC
+                    ("?j?use of ""'!"" is an obsolescent feature (RM J.2(2))");
+                  Error_Msg_SC ("\?j?use ""'|"" instead");
+               end if;
+            end if;
+
+         when others =>
+            null;
+      end case;
+   end Post_Scan;
 
    ------------------------------
    -- Scan_Reserved_Identifier --
    ------------------------------
 
    procedure Scan_Reserved_Identifier (Force_Msg : Boolean) is
-      Token_Chars : constant String := Token_Type'Image (Token);
+      Token_Chars : String  := Token_Type'Image (Token);
+      Len         : Natural := 0;
 
    begin
+      --  AI12-0125 : '@' denotes the target_name, i.e. serves as an
+      --  abbreviation for the LHS of an assignment.
+
+      if Token = Tok_At_Sign then
+         Token_Node := New_Node (N_Target_Name, Token_Ptr);
+         return;
+      end if;
+
       --  We have in Token_Chars the image of the Token name, i.e. Tok_xxx.
       --  This code extracts the xxx and makes an identifier out of it.
 
-      Name_Len := 0;
-
       for J in 5 .. Token_Chars'Length loop
-         Name_Len := Name_Len + 1;
-         Name_Buffer (Name_Len) := Fold_Lower (Token_Chars (J));
+         Len := Len + 1;
+         Token_Chars (Len) := Fold_Lower (Token_Chars (J));
       end loop;
 
-      Token_Name := Name_Find;
+      Token_Name := Name_Find (Token_Chars (1 .. Len));
+
+      --  If Inside_Pragma is True, we don't give an error. This is to allow
+      --  things like "pragma Ignore_Pragma (Interface)", where "Interface" is
+      --  a reserved word. There is no danger of missing errors, because any
+      --  misuse must have been preceded by an illegal declaration. For
+      --  example, in "pragma Pack (Begin);", either Begin is not declared,
+      --  which is an error, or it is declared, which will be an error on that
+      --  declaration.
 
-      if not Used_As_Identifier (Token) or else Force_Msg then
+      if (not Used_As_Identifier (Token) or else Force_Msg)
+        and then not Inside_Pragma
+      then
          Error_Msg_Name_1 := Token_Name;
          Error_Msg_SC ("reserved word* cannot be used as identifier!");
          Used_As_Identifier (Token) := True;