aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@adacore.com>2012-10-29 09:50:53 +0000
committerArnaud Charlet <charlet@gcc.gnu.org>2012-10-29 10:50:53 +0100
commite63f29e814a7b2d9e4dbac86a8a3780f1bd50f80 (patch)
treed9304b5967c4c289db26282bf7af9d38f8b3c69d
parent6e58a0b759bbf4521ffe01406365c74262f56b0e (diff)
downloadgcc-e63f29e814a7b2d9e4dbac86a8a3780f1bd50f80.zip
gcc-e63f29e814a7b2d9e4dbac86a8a3780f1bd50f80.tar.gz
gcc-e63f29e814a7b2d9e4dbac86a8a3780f1bd50f80.tar.bz2
* adabkend.ads, adabkend.adb, aa_util.ads, aa_util.adb: New.
From-SVN: r192913
-rw-r--r--gcc/ada/ChangeLog3
-rw-r--r--gcc/ada/aa_util.adb458
-rw-r--r--gcc/ada/aa_util.ads145
-rw-r--r--gcc/ada/adabkend.adb282
-rw-r--r--gcc/ada/adabkend.ads52
5 files changed, 939 insertions, 1 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 9058c98..2fb2753 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,6 +1,7 @@
2012-10-29 Arnaud Charlet <charlet@adacore.com>
- * pprint.ads, pprint.adb: New.
+ * pprint.ads, pprint.adb, adabkend.ads, adabkend.adb,
+ aa_util.ads, aa_util.adb: New.
2012-10-23 Eric Botcazou <ebotcazou@adacore.com>
diff --git a/gcc/ada/aa_util.adb b/gcc/ada/aa_util.adb
new file mode 100644
index 0000000..6ea4421
--- /dev/null
+++ b/gcc/ada/aa_util.adb
@@ -0,0 +1,458 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAAMP COMPILER COMPONENTS --
+-- --
+-- A A _ U T I L --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2001-2012, AdaCore --
+-- --
+-- 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 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 COPYING3. If not, go to --
+-- http://www.gnu.org/licenses for a complete copy of the license. --
+-- --
+------------------------------------------------------------------------------
+
+with Sem_Aux; use Sem_Aux;
+with Sinput; use Sinput;
+with Stand; use Stand;
+with Stringt; use Stringt;
+
+with GNAT.Case_Util; use GNAT.Case_Util;
+
+package body AA_Util is
+
+ ----------------------
+ -- Is_Global_Entity --
+ ----------------------
+
+ function Is_Global_Entity (E : Entity_Id) return Boolean is
+ begin
+ return Enclosing_Dynamic_Scope (E) = Standard_Standard;
+ end Is_Global_Entity;
+
+ -----------------
+ -- New_Name_Id --
+ -----------------
+
+ function New_Name_Id (Name : String) return Name_Id is
+ begin
+ for J in 1 .. Name'Length loop
+ Name_Buffer (J) := Name (Name'First + (J - 1));
+ end loop;
+
+ Name_Len := Name'Length;
+ return Name_Find;
+ end New_Name_Id;
+
+ -----------------
+ -- Name_String --
+ -----------------
+
+ function Name_String (Name : Name_Id) return String is
+ begin
+ pragma Assert (Name /= No_Name);
+ return Get_Name_String (Name);
+ end Name_String;
+
+ -------------------
+ -- New_String_Id --
+ -------------------
+
+ function New_String_Id (S : String) return String_Id is
+ begin
+ for J in 1 .. S'Length loop
+ Name_Buffer (J) := S (S'First + (J - 1));
+ end loop;
+
+ Name_Len := S'Length;
+ return String_From_Name_Buffer;
+ end New_String_Id;
+
+ ------------------
+ -- String_Value --
+ ------------------
+
+ function String_Value (Str_Id : String_Id) return String is
+ begin
+ -- ??? pragma Assert (Str_Id /= No_String);
+
+ if Str_Id = No_String then
+ return "";
+ end if;
+
+ String_To_Name_Buffer (Str_Id);
+
+ return Name_Buffer (1 .. Name_Len);
+ end String_Value;
+
+ ---------------
+ -- Next_Name --
+ ---------------
+
+ function Next_Name
+ (Name_Seq : not null access Name_Sequencer;
+ Name_Prefix : String) return Name_Id
+ is
+ begin
+ Name_Seq.Sequence_Number := Name_Seq.Sequence_Number + 1;
+
+ declare
+ Number_Image : constant String := Name_Seq.Sequence_Number'Img;
+ begin
+ return New_Name_Id
+ (Name_Prefix & "__" & Number_Image (2 .. Number_Image'Last));
+ end;
+ end Next_Name;
+
+ --------------------
+ -- Elab_Spec_Name --
+ --------------------
+
+ function Elab_Spec_Name (Module_Name : Name_Id) return Name_Id is
+ begin
+ return New_Name_Id (Name_String (Module_Name) & "___elabs");
+ end Elab_Spec_Name;
+
+ --------------------
+ -- Elab_Spec_Name --
+ --------------------
+
+ function Elab_Body_Name (Module_Name : Name_Id) return Name_Id is
+ begin
+ return New_Name_Id (Name_String (Module_Name) & "___elabb");
+ end Elab_Body_Name;
+
+ --------------------------------
+ -- Source_Name_Without_Suffix --
+ --------------------------------
+
+ function File_Name_Without_Suffix (File_Name : String) return String is
+ Name_Index : Natural := File_Name'Last;
+
+ begin
+ pragma Assert (File_Name'Length > 0);
+
+ -- We loop in reverse to ensure that file names that follow nonstandard
+ -- naming conventions that include additional dots are handled properly,
+ -- preserving dots in front of the main file suffix (for example,
+ -- main.2.ada => main.2).
+
+ while Name_Index >= File_Name'First
+ and then File_Name (Name_Index) /= '.'
+ loop
+ Name_Index := Name_Index - 1;
+ end loop;
+
+ -- Return the part of the file name up to but not including the last dot
+ -- in the name, or return the whole name as is if no dot character was
+ -- found.
+
+ if Name_Index >= File_Name'First then
+ return File_Name (File_Name'First .. Name_Index - 1);
+
+ else
+ return File_Name;
+ end if;
+ end File_Name_Without_Suffix;
+
+ -----------------
+ -- Source_Name --
+ -----------------
+
+ function Source_Name (Sloc : Source_Ptr) return File_Name_Type is
+ begin
+ if Sloc = No_Location or Sloc = Standard_Location then
+ return No_File;
+ else
+ return File_Name (Get_Source_File_Index (Sloc));
+ end if;
+ end Source_Name;
+
+ --------------------------------
+ -- Source_Name_Without_Suffix --
+ --------------------------------
+
+ function Source_Name_Without_Suffix (Sloc : Source_Ptr) return String is
+ Src_Name : constant String :=
+ Name_String (Name_Id (Source_Name (Sloc)));
+ Src_Index : Natural := Src_Name'Last;
+
+ begin
+ pragma Assert (Src_Name'Length > 0);
+
+ -- Treat the presence of a ".dg" suffix specially, stripping it off
+ -- in addition to any suffix preceding it.
+
+ if Src_Name'Length >= 4
+ and then Src_Name (Src_Name'Last - 2 .. Src_Name'Last) = ".dg"
+ then
+ Src_Index := Src_Index - 3;
+ end if;
+
+ return File_Name_Without_Suffix (Src_Name (Src_Name'First .. Src_Index));
+ end Source_Name_Without_Suffix;
+
+ ----------------------
+ -- Source_Id_String --
+ ----------------------
+
+ function Source_Id_String (Unit_Name : Name_Id) return String is
+ Unit_String : String := Name_String (Unit_Name);
+ Name_Last : Positive := Unit_String'Last;
+ Name_Index : Positive := Unit_String'First;
+
+ begin
+ To_Mixed (Unit_String);
+
+ -- Replace any embedded sequences of two or more '_' characters
+ -- with a single '.' character. Note that this will leave any
+ -- leading or trailing single '_' characters untouched, but those
+ -- should normally not occur in compilation unit names (and if
+ -- they do then it's better to leave them as is).
+
+ while Name_Index <= Name_Last loop
+ if Unit_String (Name_Index) = '_'
+ and then Name_Index /= Name_Last
+ and then Unit_String (Name_Index + 1) = '_'
+ then
+ Unit_String (Name_Index) := '.';
+ Name_Index := Name_Index + 1;
+
+ while Unit_String (Name_Index) = '_'
+ and then Name_Index <= Name_Last
+ loop
+ Unit_String (Name_Index .. Name_Last - 1)
+ := Unit_String (Name_Index + 1 .. Name_Last);
+ Name_Last := Name_Last - 1;
+ end loop;
+
+ else
+ Name_Index := Name_Index + 1;
+ end if;
+ end loop;
+
+ return Unit_String (Unit_String'First .. Name_Last);
+ end Source_Id_String;
+
+ -- This version of Source_Id_String is obsolescent and is being
+ -- replaced with the above function.
+
+ function Source_Id_String (Sloc : Source_Ptr) return String is
+ File_Index : Source_File_Index;
+
+ begin
+ -- Use an arbitrary artificial 22-character value for package Standard,
+ -- since Standard doesn't have an associated source file.
+
+ if Sloc <= Standard_Location then
+ return "20010101010101standard";
+
+ -- Return the concatentation of the source file's timestamp and
+ -- its 8-digit hex checksum.
+
+ else
+ File_Index := Get_Source_File_Index (Sloc);
+
+ return String (Time_Stamp (File_Index))
+ & Get_Hex_String (Source_Checksum (File_Index));
+ end if;
+ end Source_Id_String;
+
+ ---------------
+ -- Source_Id --
+ ---------------
+
+ function Source_Id (Unit_Name : Name_Id) return String_Id is
+ begin
+ return New_String_Id (Source_Id_String (Unit_Name));
+ end Source_Id;
+
+ -- This version of Source_Id is obsolescent and is being
+ -- replaced with the above function.
+
+ function Source_Id (Sloc : Source_Ptr) return String_Id is
+ begin
+ return New_String_Id (Source_Id_String (Sloc));
+ end Source_Id;
+
+ -----------
+ -- Image --
+ -----------
+
+ function Image (I : Int) return String is
+ Image_String : constant String := Pos'Image (I);
+ begin
+ if Image_String (1) = ' ' then
+ return Image_String (2 .. Image_String'Last);
+ else
+ return Image_String;
+ end if;
+ end Image;
+
+ --------------
+ -- UI_Image --
+ --------------
+
+ function UI_Image (I : Uint; Format : Integer_Image_Format) return String is
+ begin
+ if Format = Decimal then
+ UI_Image (I, Format => Decimal);
+ return UI_Image_Buffer (1 .. UI_Image_Length);
+
+ elsif Format = Ada_Hex then
+ UI_Image (I, Format => Hex);
+ return UI_Image_Buffer (1 .. UI_Image_Length);
+
+ else
+ pragma Assert (I >= Uint_0);
+
+ UI_Image (I, Format => Hex);
+
+ pragma Assert (UI_Image_Buffer (1 .. 3) = "16#"
+ and then UI_Image_Buffer (UI_Image_Length) = '#');
+
+ -- Declare a string where we will copy the digits from the UI_Image,
+ -- interspersing '_' characters as 4-digit group separators. The
+ -- underscores in UI_Image's result are not always at the places
+ -- where we want them, which is why we do the following copy
+ -- (e.g., we map "16#ABCD_EF#" to "^AB_CDEF^").
+
+ declare
+ Hex_String : String (1 .. UI_Image_Max);
+ Last_Index : Natural;
+ Digit_Count : Natural := 0;
+ UI_Image_Index : Natural := 4; -- Skip past the "16#" bracket
+ Sep_Count : Natural := 0;
+
+ begin
+ -- Count up the number of non-underscore characters in the
+ -- literal value portion of the UI_Image string.
+
+ while UI_Image_Buffer (UI_Image_Index) /= '#' loop
+ if UI_Image_Buffer (UI_Image_Index) /= '_' then
+ Digit_Count := Digit_Count + 1;
+ end if;
+
+ UI_Image_Index := UI_Image_Index + 1;
+ end loop;
+
+ UI_Image_Index := 4; -- Reset the index past the "16#" bracket
+
+ Last_Index := 1;
+
+ Hex_String (Last_Index) := '^';
+ Last_Index := Last_Index + 1;
+
+ -- Copy digits from UI_Image_Buffer to Hex_String, adding
+ -- underscore separators as appropriate. The initial value
+ -- of Sep_Count accounts for the leading '^' and being one
+ -- character ahead after inserting a digit.
+
+ Sep_Count := 2;
+
+ while UI_Image_Buffer (UI_Image_Index) /= '#' loop
+ if UI_Image_Buffer (UI_Image_Index) /= '_' then
+ Hex_String (Last_Index) := UI_Image_Buffer (UI_Image_Index);
+
+ Last_Index := Last_Index + 1;
+
+ -- Add '_' characters to separate groups of four hex
+ -- digits for readability (grouping from right to left).
+
+ if (Digit_Count - (Last_Index - Sep_Count)) mod 4 = 0 then
+ Hex_String (Last_Index) := '_';
+ Last_Index := Last_Index + 1;
+ Sep_Count := Sep_Count + 1;
+ end if;
+ end if;
+
+ UI_Image_Index := UI_Image_Index + 1;
+ end loop;
+
+ -- Back up before any trailing underscore
+
+ if Hex_String (Last_Index - 1) = '_' then
+ Last_Index := Last_Index - 1;
+ end if;
+
+ Hex_String (Last_Index) := '^';
+
+ return Hex_String (1 .. Last_Index);
+ end;
+ end if;
+ end UI_Image;
+
+ --------------
+ -- UR_Image --
+ --------------
+
+ -- Shouldn't this be added to Urealp???
+
+ function UR_Image (R : Ureal) return String is
+
+ -- The algorithm used here for conversion of Ureal values
+ -- is taken from the JGNAT back end.
+
+ Num : Long_Long_Float := 0.0;
+ Den : Long_Long_Float := 0.0;
+ Sign : Long_Long_Float := 1.0;
+ Result : Long_Long_Float;
+ Tmp : Uint;
+ Index : Integer;
+
+ begin
+ if UR_Is_Negative (R) then
+ Sign := -1.0;
+ end if;
+
+ -- In the following calculus, we consider numbers modulo 2 ** 31,
+ -- so that we don't have problems with signed Int...
+
+ Tmp := abs (Numerator (R));
+ Index := 0;
+ while Tmp > 0 loop
+ Num := Num
+ + Long_Long_Float (UI_To_Int (Tmp mod (Uint_2 ** 31)))
+ * (2.0 ** Index);
+ Tmp := Tmp / Uint_2 ** 31;
+ Index := Index + 31;
+ end loop;
+
+ Tmp := abs (Denominator (R));
+ if Rbase (R) /= 0 then
+ Tmp := Rbase (R) ** Tmp;
+ end if;
+
+ Index := 0;
+ while Tmp > 0 loop
+ Den := Den
+ + Long_Long_Float (UI_To_Int (Tmp mod (Uint_2 ** 31)))
+ * (2.0 ** Index);
+ Tmp := Tmp / Uint_2 ** 31;
+ Index := Index + 31;
+ end loop;
+
+ -- If the denominator denotes a negative power of Rbase,
+ -- then multiply by the denominator.
+
+ if Rbase (R) /= 0 and then Denominator (R) < 0 then
+ Result := Sign * Num * Den;
+
+ -- Otherwise compute the quotient
+
+ else
+ Result := Sign * Num / Den;
+ end if;
+
+ return Long_Long_Float'Image (Result);
+ end UR_Image;
+
+end AA_Util;
diff --git a/gcc/ada/aa_util.ads b/gcc/ada/aa_util.ads
new file mode 100644
index 0000000..27b6183
--- /dev/null
+++ b/gcc/ada/aa_util.ads
@@ -0,0 +1,145 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAAMP COMPILER COMPONENTS --
+-- --
+-- A A _ U T I L --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2001-2011, AdaCore --
+-- --
+-- 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 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 COPYING3. If not, go to --
+-- http://www.gnu.org/licenses for a complete copy of the license. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides various utility operations used by GNAT back-ends
+-- (e.g. AAMP).
+
+-- This package is a messy grab bag of stuff. These routines should be moved
+-- to appropriate units (sem_util,sem_aux,exp_util,namet,uintp,urealp). ???
+
+with Namet; use Namet;
+with Types; use Types;
+with Uintp; use Uintp;
+with Urealp; use Urealp;
+
+package AA_Util is
+
+ function Is_Global_Entity (E : Entity_Id) return Boolean;
+ -- Returns true if and only if E is a library-level entity (excludes
+ -- entities declared within blocks at the outer level of library packages).
+
+ function New_Name_Id (Name : String) return Name_Id;
+ -- Returns a Name_Id corresponding to the given name string
+
+ function Name_String (Name : Name_Id) return String;
+ -- Returns the name string associated with Name
+
+ function New_String_Id (S : String) return String_Id;
+ -- Returns a String_Id corresponding to the given string
+
+ function String_Value (Str_Id : String_Id) return String;
+ -- Returns the string associated with Str_Id
+
+ -- Name-generation utilities
+
+ type Name_Sequencer is private;
+ -- This type is used to support back-end generation of unique symbol
+ -- (e.g., for string literal objects or labels). By declaring an
+ -- aliased object of type Name_Sequence and passing that object
+ -- to the function Next_Name, a series of names with suffixes
+ -- of the form "__n" will be produced, where n is a string denoting
+ -- a positive integer. The sequence starts with "__1", and increases
+ -- by one on each successive call to Next_Name for a given Name_Sequencer.
+
+ function Next_Name
+ (Name_Seq : not null access Name_Sequencer;
+ Name_Prefix : String) return Name_Id;
+ -- Returns the Name_Id for a name composed of the given Name_Prefix
+ -- concatentated with a unique number suffix of the form "__n",
+ -- as detemined by the current state of Name_Seq.
+
+ function Elab_Spec_Name (Module_Name : Name_Id) return Name_Id;
+ -- Returns a name id for the elaboration subprogram to be associated with
+ -- the specification of the named module. The denoted name is of the form
+ -- "modulename___elabs".
+
+ function Elab_Body_Name (Module_Name : Name_Id) return Name_Id;
+ -- Returns a name id for the elaboration subprogram to be associated
+ -- with the body of the named module. The denoted name is of the form
+ -- "modulename___elabb".
+
+ function File_Name_Without_Suffix (File_Name : String) return String;
+ -- Removes the suffix ('.' followed by other characters), if present, from
+ -- the end of File_Name and returns the shortened name (otherwise simply
+ -- returns File_Name).
+
+ function Source_Name (Sloc : Source_Ptr) return File_Name_Type;
+ -- Returns file name corresponding to the source file name associated with
+ -- the given source position Sloc.
+
+ function Source_Name_Without_Suffix (Sloc : Source_Ptr) return String;
+ -- Returns a string corresponding to the source file name associated with
+ -- the given source position Sloc, with its dot-preceded suffix, if any,
+ -- removed. As examples, the name "main.adb" is mapped to "main" and the
+ -- name "main.2.ada" is mapped to "main.2". As a special case, file names
+ -- with a ".dg" suffix will also strip off the ".dg", so "main.adb.dg"
+ -- becomes simply "main".
+
+ function Source_Id_String (Unit_Name : Name_Id) return String;
+ -- Returns a string that uniquely identifies the unit with the given
+ -- Unit_Name. This string is derived from Unit_Name by replacing any
+ -- multiple underscores with dot ('.') characters and normalizing the
+ -- casing to mixed case (e.g., "ada__strings" is mapped to ("Ada.Strings").
+
+ function Source_Id (Unit_Name : Name_Id) return String_Id;
+ -- Returns a String_Id reference to a string that uniquely identifies
+ -- the program unit having the given name (as defined for function
+ -- Source_Id_String).
+
+ function Source_Id_String (Sloc : Source_Ptr) return String;
+ -- Returns a string that uniquely identifies the source file containing
+ -- the given source location. This string is constructed from the
+ -- concatentation of the date and time stamp of the file with a
+ -- hexadecimal check sum (e.g., "020425143059ABCDEF01").
+
+ function Source_Id (Sloc : Source_Ptr) return String_Id;
+ -- Returns a String_Id reference to a string that uniquely identifies the
+ -- source file containing the given source location (as defined for
+ -- function Source_Id_String).
+
+ function Image (I : Int) return String;
+ -- Returns Int'Image (I), but without a leading space in the case where
+ -- I is nonnegative. Useful for concatenating integers onto other names.
+
+ type Integer_Image_Format is (Decimal, Ada_Hex, AAMP_Hex);
+
+ function UI_Image (I : Uint; Format : Integer_Image_Format) return String;
+ -- Returns the image of the universal integer I, with no leading spaces
+ -- and in the format specified. The Format parameter specifies whether
+ -- the integer representation should be decimal (the default), or Ada
+ -- hexadecimal (Ada_Hex => "16#xxxxx#" format), or AAMP hexadecimal.
+ -- In the latter case, the integer will have the form of a sequence of
+ -- hexadecimal digits bracketed by '^' characters, and will contain '_'
+ -- characters as separators for groups of four hexadecimal digits
+ -- (e.g., ^1C_A3CD^). If the format AAMP_Hex is selected, the universal
+ -- integer must have a nonnegative value.
+
+ function UR_Image (R : Ureal) return String;
+ -- Returns a decimal image of the universal real value R
+
+private
+
+ type Name_Sequencer is record
+ Sequence_Number : Natural := 0;
+ end record;
+
+end AA_Util;
diff --git a/gcc/ada/adabkend.adb b/gcc/ada/adabkend.adb
new file mode 100644
index 0000000..96bd00d
--- /dev/null
+++ b/gcc/ada/adabkend.adb
@@ -0,0 +1,282 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAAMP COMPILER COMPONENTS --
+-- --
+-- A D A B K E N D --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2001-2011, AdaCore --
+-- --
+-- 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 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 COPYING3. If not, go to --
+-- http://www.gnu.org/licenses for a complete copy of the license. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the version of the Back_End package for back ends written in Ada
+
+with Debug;
+with Lib;
+with Opt; use Opt;
+with Output; use Output;
+with Osint; use Osint;
+with Osint.C; use Osint.C;
+with Switch.C; use Switch.C;
+with Types; use Types;
+
+with System.OS_Lib; use System.OS_Lib;
+
+package body Adabkend is
+
+ use Switch;
+
+ -------------------
+ -- Call_Back_End --
+ -------------------
+
+ procedure Call_Back_End is
+ begin
+ if (Opt.Verbose_Mode or Opt.Full_List)
+ and then not Debug.Debug_Flag_7
+ then
+ Write_Eol;
+ Write_Str (Product_Name);
+ Write_Str (", Copyright ");
+ Write_Str (Copyright_Years);
+ Write_Str (" Ada Core Technologies, Inc.");
+ Write_Str (" (http://www.adacore.com)");
+ Write_Eol;
+ Write_Eol;
+ end if;
+
+ Driver (Lib.Cunit (Types.Main_Unit));
+ end Call_Back_End;
+
+ ------------------------
+ -- Scan_Compiler_Args --
+ ------------------------
+
+ procedure Scan_Compiler_Arguments is
+ Output_File_Name_Seen : Boolean := False;
+ -- Set to True after having scanned the file_name for switch
+ -- "-gnatO file_name"
+
+ Argument_Count : constant Integer := Arg_Count - 1;
+ -- Number of arguments (excluding program name)
+
+ Args : Argument_List (1 .. Argument_Count);
+ Next_Arg : Positive := 1;
+
+ procedure Scan_Back_End_Switches (Switch_Chars : String);
+ -- Procedure to scan out switches stored in Switch_Chars. The first
+ -- character is known to be a valid switch character, and there are no
+ -- blanks or other switch terminator characters in the string, so the
+ -- entire string should consist of valid switch characters, except that
+ -- an optional terminating NUL character is allowed.
+ --
+ -- If the switch is not valid, control will not return. The switches
+ -- must still be scanned to skip the "-o" arguments, or internal GCC
+ -- switches, which may be safely ignored by other back-ends.
+
+ ----------------------------
+ -- Scan_Back_End_Switches --
+ ----------------------------
+
+ procedure Scan_Back_End_Switches (Switch_Chars : String) is
+ First : constant Positive := Switch_Chars'First + 1;
+ Last : constant Natural := Switch_Last (Switch_Chars);
+
+ begin
+ -- Process any back end switches, returning if the switch does not
+ -- affect code generation or falling through if it does, so the
+ -- switch will get stored.
+
+ if Is_Internal_GCC_Switch (Switch_Chars) then
+ Next_Arg := Next_Arg + 1;
+ return; -- ignore this switch
+
+ -- Record that an object file name has been specified. The actual
+ -- file name argument is picked up and saved below by the main body
+ -- of Scan_Compiler_Arguments.
+
+ elsif Switch_Chars (First .. Last) = "o" then
+ if First = Last then
+ Opt.Output_File_Name_Present := True;
+ return;
+ else
+ Fail ("invalid switch: " & Switch_Chars);
+ end if;
+
+ -- Set optimization indicators appropriately. In gcc-based GNAT this
+ -- is picked up from imported variables set by the gcc driver, but
+ -- for compilers with non-gcc back ends we do it here to allow use
+ -- of these switches by the front end. Allowed optimization switches
+ -- are -Os (optimize for size), -O[0123], and -O (same as -O1).
+
+ elsif Switch_Chars (First) = 'O' then
+ if First = Last then
+ Optimization_Level := 1;
+
+ elsif Last - First = 1 then
+ if Switch_Chars (Last) = 's' then
+ Optimize_Size := 1;
+ Optimization_Level := 2; -- Consistent with gcc setting
+
+ elsif Switch_Chars (Last) in '0' .. '3' then
+ Optimization_Level :=
+ Character'Pos (Switch_Chars (Last)) - Character'Pos ('0');
+
+ else
+ Fail ("invalid switch: " & Switch_Chars);
+ end if;
+
+ else
+ Fail ("invalid switch: " & Switch_Chars);
+ end if;
+
+ elsif Switch_Chars (First .. Last) = "quiet" then
+ return; -- ignore this switch
+
+ elsif Switch_Chars (First .. Last) = "c" then
+ return; -- ignore this switch
+
+ -- The -x switch and its language name argument will generally be
+ -- ignored by non-gcc back ends (e.g. the GNAAMP back end). In any
+ -- case, we save the switch and argument in the compilation switches.
+
+ elsif Switch_Chars (First .. Last) = "x" then
+ Lib.Store_Compilation_Switch (Switch_Chars);
+ Next_Arg := Next_Arg + 1;
+
+ declare
+ Argv : constant String := Args (Next_Arg).all;
+
+ begin
+ if Is_Switch (Argv) then
+ Fail ("language name missing after -x");
+ else
+ Lib.Store_Compilation_Switch (Argv);
+ end if;
+ end;
+
+ return;
+
+ -- Special check, the back end switch -fno-inline also sets the
+ -- front end flag to entirely inhibit all inlining. So we store it
+ -- and set the appropriate flag.
+
+ elsif Switch_Chars (First .. Last) = "fno-inline" then
+ Lib.Store_Compilation_Switch (Switch_Chars);
+ Opt.Suppress_All_Inlining := True;
+ return;
+
+ -- Similar processing for -fpreserve-control-flow
+
+ elsif Switch_Chars (First .. Last) = "fpreserve-control-flow" then
+ Lib.Store_Compilation_Switch (Switch_Chars);
+ Opt.Suppress_Control_Flow_Optimizations := True;
+ return;
+
+ -- Ignore all other back end switches
+
+ elsif Is_Back_End_Switch (Switch_Chars) then
+ null;
+
+ -- Give error for junk switch
+
+ else
+ Fail ("invalid switch: " & Switch_Chars);
+ end if;
+
+ -- Store any other GCC switches
+
+ Lib.Store_Compilation_Switch (Switch_Chars);
+ end Scan_Back_End_Switches;
+
+ -- Start of processing for Scan_Compiler_Args
+
+ begin
+ -- Put all the arguments in argument list Args
+
+ for Arg in 1 .. Argument_Count loop
+ declare
+ Argv : String (1 .. Len_Arg (Arg));
+ begin
+ Fill_Arg (Argv'Address, Arg);
+ Args (Arg) := new String'(Argv);
+ end;
+ end loop;
+
+ -- Loop through command line arguments, storing them for later access
+
+ while Next_Arg <= Argument_Count loop
+ Look_At_Arg : declare
+ Argv : constant String := Args (Next_Arg).all;
+
+ begin
+ if Argv'Length = 0 then
+ Fail ("Empty argument");
+ end if;
+
+ -- If the previous switch has set the Output_File_Name_Present
+ -- flag (that is we have seen a -gnatO), then the next argument
+ -- is the name of the output object file.
+
+ if Opt.Output_File_Name_Present
+ and then not Output_File_Name_Seen
+ then
+ if Is_Switch (Argv) then
+ Fail ("Object file name missing after -gnatO");
+ else
+ Set_Output_Object_File_Name (Argv);
+ Output_File_Name_Seen := True;
+ end if;
+
+ -- If the previous switch has set the Search_Directory_Present
+ -- flag (that is if we have just seen -I), then the next
+ -- argument is a search directory path.
+
+ elsif Search_Directory_Present then
+ if Is_Switch (Argv) then
+ Fail ("search directory missing after -I");
+ else
+ Add_Src_Search_Dir (Argv);
+
+ -- Add directory to lib search so that back-end can take as
+ -- input ALI files if needed. Otherwise this won't have any
+ -- impact on the compiler.
+
+ Add_Lib_Search_Dir (Argv);
+
+ Search_Directory_Present := False;
+ end if;
+
+ -- If not a switch, must be a file name
+
+ elsif not Is_Switch (Argv) then
+ Add_File (Argv);
+
+ -- Front end switch
+
+ elsif Is_Front_End_Switch (Argv) then
+ Scan_Front_End_Switches (Argv, Args, Next_Arg);
+
+ -- All non-front-end switches are back-end switches
+
+ else
+ Scan_Back_End_Switches (Argv);
+ end if;
+ end Look_At_Arg;
+
+ Next_Arg := Next_Arg + 1;
+ end loop;
+ end Scan_Compiler_Arguments;
+
+end Adabkend;
diff --git a/gcc/ada/adabkend.ads b/gcc/ada/adabkend.ads
new file mode 100644
index 0000000..877422c
--- /dev/null
+++ b/gcc/ada/adabkend.ads
@@ -0,0 +1,52 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- A D A B K E N D --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1992-2012, 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 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 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. --
+-- --
+------------------------------------------------------------------------------
+
+-- Generic package implementing the common parts of back_end.adb for back ends
+-- written in Ada, thereby reducing code duplication.
+
+with Types;
+
+generic
+ Product_Name : String;
+ Copyright_Years : String;
+
+ with procedure Driver (Root : Types.Node_Id);
+ -- Main driver procedure for back end
+
+ with function Is_Back_End_Switch (Switch : String) return Boolean;
+ -- Back-end specific function to determine validity of switches
+
+package Adabkend is
+
+ procedure Call_Back_End;
+ -- Call back end, i.e. make call to the Driver passing the root
+ -- node for this compilation unit.
+
+ procedure Scan_Compiler_Arguments;
+ -- Acquires command-line parameters passed to the compiler and processes
+ -- them. Calls Scan_Front_End_Switches for any front-end switches
+ -- encountered. See spec of Back_End for more details.
+
+end Adabkend;