------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                            B A C K _ E N D                               --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2019, 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.      --
--                                                                          --
------------------------------------------------------------------------------

--  This is the version of the Back_End package for GCC back ends

with Atree;    use Atree;
with Debug;    use Debug;
with Elists;   use Elists;
with Errout;   use Errout;
with Lib;      use Lib;
with Osint;    use Osint;
with Opt;      use Opt;
with Osint.C;  use Osint.C;
with Namet;    use Namet;
with Nlists;   use Nlists;
with Stand;    use Stand;
with Sinput;   use Sinput;
with Stringt;  use Stringt;
with Switch;   use Switch;
with Switch.C; use Switch.C;
with System;   use System;
with Types;    use Types;

with System.OS_Lib; use System.OS_Lib;

package body Back_End is

   type Arg_Array is array (Nat) of Big_String_Ptr;
   type Arg_Array_Ptr is access Arg_Array;
   --  Types to access compiler arguments

   flag_stack_check : Int;
   pragma Import (C, flag_stack_check);
   --  Indicates if stack checking is enabled, imported from misc.c

   save_argc : Nat;
   pragma Import (C, save_argc);
   --  Saved value of argc (number of arguments), imported from misc.c

   save_argv : Arg_Array_Ptr;
   pragma Import (C, save_argv);
   --  Saved value of argv (argument pointers), imported from misc.c

   function Len_Arg (Arg : Pos) return Nat;
   --  Determine length of argument number Arg on original gnat1 command line

   -------------------
   -- Call_Back_End --
   -------------------

   procedure Call_Back_End (Mode : Back_End_Mode_Type) is

      --  The Source_File_Record type has a lot of components that are
      --  meaningless to the back end, so a new record type is created
      --  here to contain the needed information for each file.

      type File_Info_Type is record
         File_Name        : File_Name_Type;
         Instance         : Instance_Id;
         Num_Source_Lines : Nat;
      end record;

      File_Info_Array : array (1 .. Last_Source_File) of File_Info_Type;

      procedure gigi
        (gnat_root                     : Int;
         max_gnat_node                 : Int;
         number_name                   : Nat;
         nodes_ptr                     : Address;
         flags_ptr                     : Address;

         next_node_ptr                 : Address;
         prev_node_ptr                 : Address;
         elists_ptr                    : Address;
         elmts_ptr                     : Address;

         strings_ptr                   : Address;
         string_chars_ptr              : Address;
         list_headers_ptr              : Address;
         number_file                   : Nat;

         file_info_ptr                 : Address;
         gigi_standard_boolean         : Entity_Id;
         gigi_standard_integer         : Entity_Id;
         gigi_standard_character       : Entity_Id;
         gigi_standard_long_long_float : Entity_Id;
         gigi_standard_exception_type  : Entity_Id;
         gigi_operating_mode           : Back_End_Mode_Type);

      pragma Import (C, gigi);

   begin
      --  Skip call if in -gnatdH mode

      if Debug_Flag_HH then
         return;
      end if;

      --  The back end needs to know the maximum line number that can appear
      --  in a Sloc, in other words the maximum logical line number.

      for J in 1 .. Last_Source_File loop
         File_Info_Array (J).File_Name        := Full_Debug_Name (J);
         File_Info_Array (J).Instance         := Instance (J);
         File_Info_Array (J).Num_Source_Lines :=
           Nat (Physical_To_Logical (Last_Source_Line (J), J));
      end loop;

      --  Deal with case of generating SCIL, we should not be here unless
      --  debugging CodePeer mode in GNAT.

      if Generate_SCIL then
         Error_Msg_N ("'S'C'I'L generation not available", Cunit (Main_Unit));

         if CodePeer_Mode
           or else (Mode /= Generate_Object
                     and then not Back_Annotate_Rep_Info)
         then
            return;
         end if;
      end if;

      --  We should be here in GNATprove mode only when debugging GNAT. Do not
      --  call gigi in that case, as it is not prepared to handle the special
      --  form of the tree obtained in GNATprove mode.

      if GNATprove_Mode then
         return;
      end if;

      --  The actual call to the back end

      gigi
        (gnat_root          => Int (Cunit (Main_Unit)),
         max_gnat_node      => Int (Last_Node_Id - First_Node_Id + 1),
         number_name        => Name_Entries_Count,
         nodes_ptr          => Nodes_Address,
         flags_ptr          => Flags_Address,

         next_node_ptr      => Next_Node_Address,
         prev_node_ptr      => Prev_Node_Address,
         elists_ptr         => Elists_Address,
         elmts_ptr          => Elmts_Address,

         strings_ptr        => Strings_Address,
         string_chars_ptr   => String_Chars_Address,
         list_headers_ptr   => Lists_Address,
         number_file        => Num_Source_Files,

         file_info_ptr                 => File_Info_Array'Address,
         gigi_standard_boolean         => Standard_Boolean,
         gigi_standard_integer         => Standard_Integer,
         gigi_standard_character       => Standard_Character,
         gigi_standard_long_long_float => Standard_Long_Long_Float,
         gigi_standard_exception_type  => Standard_Exception_Type,
         gigi_operating_mode           => Mode);
   end Call_Back_End;

   -------------------------------
   -- Gen_Or_Update_Object_File --
   -------------------------------

   procedure Gen_Or_Update_Object_File is
   begin
      null;
   end Gen_Or_Update_Object_File;

   -------------
   -- Len_Arg --
   -------------

   function Len_Arg (Arg : Pos) return Nat is
   begin
      for J in 1 .. Nat'Last loop
         if save_argv (Arg).all (Natural (J)) = ASCII.NUL then
            return J - 1;
         end if;
      end loop;

      raise Program_Error;
   end Len_Arg;

   -----------------------------
   -- Scan_Compiler_Arguments --
   -----------------------------

   procedure Scan_Compiler_Arguments is
      Next_Arg : Positive;
      --  Next argument to be scanned

      Arg_Count : constant Natural := Natural (save_argc - 1);
      Args      : Argument_List (1 .. Arg_Count);

      Output_File_Name_Seen : Boolean := False;
      --  Set to True after having scanned file_name for switch "-gnatO file"

      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.
      --
      --  Back end switches have already been checked and processed by GCC in
      --  toplev.c, so no errors can occur and control will always return. The
      --  switches must still be scanned to skip "-o" or internal GCC switches
      --  with their argument.

      ----------------------------
      -- 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
         --  Skip -o or internal GCC switches together with their argument

         if Switch_Chars (First .. Last) = "o"
           or else Is_Internal_GCC_Switch (Switch_Chars)
         then
            Next_Arg := Next_Arg + 1;

         --  Store -G xxx as -Gxxx and go directly to the next argument

         elsif Switch_Chars (First .. Last) = "G" then
            Next_Arg := Next_Arg + 1;

            --  Should never get there with -G not followed by an argument,
            --  but use defensive code nonetheless. Store as -Gxxx to avoid
            --  storing parameters in ALI files that might create confusion.

            if Next_Arg <= Args'Last then
               Store_Compilation_Switch (Switch_Chars & Args (Next_Arg).all);
            end if;

         --  Do not record -quiet switch

         elsif Switch_Chars (First .. Last) = "quiet" then
            null;

         --  Store any other GCC switches. Also do special processing for some
         --  specific switches that the Ada front-end knows about.

         else
            Store_Compilation_Switch (Switch_Chars);

            --  For gcc back ends, -fno-inline disables Inline pragmas only,
            --  not Inline_Always to remain consistent with the always_inline
            --  attribute behavior.

            if Switch_Chars (First .. Last) = "fno-inline" then
               Opt.Disable_FE_Inline := True;

            --  Back end switch -fpreserve-control-flow also sets the front end
            --  flag that inhibits improper control flow transformations.

            elsif Switch_Chars (First .. Last) = "fpreserve-control-flow" then
               Opt.Suppress_Control_Flow_Optimizations := True;

            --  Back end switch -fdump-scos, which exists primarily for C, is
            --  also accepted for Ada as a synonym of -gnateS.

            elsif Switch_Chars (First .. Last) = "fdump-scos" then
               Opt.Generate_SCO := True;
               Opt.Generate_SCO_Instance_Table := True;

            elsif Switch_Chars (First) = 'g' then
               Debugger_Level := 2;

               if First < Last then
                  case Switch_Chars (First + 1) is
                     when '0' =>
                        Debugger_Level := 0;
                     when '1' =>
                        Debugger_Level := 1;
                     when '2' =>
                        Debugger_Level := 2;
                     when '3' =>
                        Debugger_Level := 3;
                     when others =>
                        null;
                  end case;
               end if;
            end if;
         end if;
      end Scan_Back_End_Switches;

   --  Start of processing for Scan_Compiler_Arguments

   begin
      --  Acquire stack checking mode directly from GCC. The reason we do this
      --  is to make sure that the indication of stack checking being enabled
      --  is the same in the front end and the back end. This status obtained
      --  from gcc is affected by more than just the switch -fstack-check.

      Opt.Stack_Checking_Enabled := (flag_stack_check /= 0);

      --  Put the arguments in Args

      for Arg in Pos range 1 .. save_argc - 1 loop
         declare
            Argv_Ptr : constant Big_String_Ptr := save_argv (Arg);
            Argv_Len : constant Nat            := Len_Arg (Arg);
            Argv     : constant String         :=
                         Argv_Ptr (1 .. Natural (Argv_Len));
         begin
            Args (Positive (Arg)) := new String'(Argv);
         end;
      end loop;

      --  Loop through command line arguments, storing them for later access

      Next_Arg := 1;
      while Next_Arg <= Args'Last loop
         Look_At_Arg : declare
            Argv : constant String := Args (Next_Arg).all;

         begin
            --  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 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);
                  Search_Directory_Present := False;
               end if;

            --  If not a switch, must be a file name

            elsif not Is_Switch (Argv) then
               Add_File (Argv);

            --  We must recognize -nostdinc to suppress visibility on the
            --  standard GNAT RTL sources. This is also a gcc switch.

            elsif Argv (Argv'First + 1 .. Argv'Last) = "nostdinc" then
               Opt.No_Stdinc := True;
               Scan_Back_End_Switches (Argv);

            --  We must recognize -nostdlib to suppress visibility on the
            --  standard GNAT RTL objects.

            elsif Argv (Argv'First + 1 .. Argv'Last) = "nostdlib" then
               Opt.No_Stdlib := True;

            elsif Is_Front_End_Switch (Argv) then
               Scan_Front_End_Switches (Argv, Args, Next_Arg);

            elsif Argv (Argv'First + 1 .. Argv'Last) = "fopenacc" then
               Opt.OpenAcc_Enabled := True;

            --  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 Back_End;
