------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             F R O N T E N D                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2023, 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.      --
--                                                                          --
------------------------------------------------------------------------------

with System.Strings; use System.Strings;

with Atree;          use Atree;
with Checks;
with CStand;
with Debug;          use Debug;
with Elists;
with Exp_Ch6;
with Exp_Dbug;
with Exp_Unst;
with Fmap;
with Fname.UF;
with Ghost;          use Ghost;
with Inline;         use Inline;
with Lib;            use Lib;
with Lib.Load;       use Lib.Load;
with Live;           use Live;
with Namet;          use Namet;
with Nlists;         use Nlists;
with Opt;            use Opt;
with Osint;
with Par;
with Prep;
with Prepcomp;
with Restrict;       use Restrict;
with Rident;         use Rident;
with Rtsfind;
with Snames;         use Snames;
with Sprint;
with Scn;            use Scn;
with Sem;            use Sem;
with Sem_Aux;
with Sem_Ch8;
with Sem_SCIL;
with Sem_Elab;       use Sem_Elab;
with Sem_Prag;       use Sem_Prag;
with Sem_Warn;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Sinput;         use Sinput;
with Sinput.L;       use Sinput.L;
with SCIL_LL;
with Tbuild;         use Tbuild;
with Types;          use Types;
with VAST;
with Warnsw;         use Warnsw;

procedure Frontend is
begin
   --  Carry out package initializations. These are initializations which might
   --  logically be performed at elaboration time, were it not for the fact
   --  that we may be doing things more than once in the big loop over files.
   --  Like elaboration, the order in which these calls are made is in some
   --  cases important. For example, Lib cannot be initialized before Namet,
   --  since it uses names table entries.

   Rtsfind.Initialize;
   Nlists.Initialize;
   Elists.Initialize;
   Lib.Load.Initialize;
   Sem_Aux.Initialize;
   Sem_Ch8.Initialize;
   Sem_Prag.Initialize;
   Fname.UF.Initialize;
   Checks.Initialize;
   Sem_Warn.Initialize;
   Prep.Initialize;
   Sem_Elab.Initialize;

   if Generate_SCIL then
      SCIL_LL.Initialize;
   end if;

   --  Create package Standard

   CStand.Create_Standard;

   --  Check possible symbol definitions specified by -gnateD switches

   Prepcomp.Process_Command_Line_Symbol_Definitions;

   --  If -gnatep= was specified, parse the preprocessing data file

   if Preprocessing_Data_File /= null then
      Name_Len := Preprocessing_Data_File'Length;
      Name_Buffer (1 .. Name_Len) := Preprocessing_Data_File.all;
      Prepcomp.Parse_Preprocessing_Data_File (Name_Find);

   --  Otherwise, check if there were preprocessing symbols on the command
   --  line and set preprocessing if there are.

   else
      Prepcomp.Check_Symbols;
   end if;

   --  We set Parsing_Main_Extended_Source true here to cover processing of all
   --  the configuration pragma files, as well as the main source unit itself.

   Parsing_Main_Extended_Source := True;

   --  Now that the preprocessing situation is established, we are able to
   --  load the main source (this is no longer done by Lib.Load.Initialize).

   Lib.Load.Load_Main_Source;

   --  Return immediately if the main source could not be found

   if Sinput.Main_Source_File <= No_Source_File then
      return;
   end if;

   --  Read and process configuration pragma files if present

   declare
      Dot_Gnat_Adc : constant File_Name_Type := Name_Find ("./gnat.adc");
      Gnat_Adc     : constant File_Name_Type := Name_Find ("gnat.adc");

      Save_Style_Check : constant Boolean := Opt.Style_Check;
      --  Save style check mode so it can be restored later

      Config_Pragmas : List_Id := Empty_List;
      --  Gather configuration pragmas

      Source_Config_File : Source_File_Index;
      --  Source reference for -gnatec configuration file

      Prag : Node_Id;

   begin
      --  We always analyze config files with style checks off, since we
      --  don't want a miscellaneous gnat.adc that is around to discombobulate
      --  intended -gnatg or -gnaty compilations. We also disconnect checking
      --  for maximum line length.

      Opt.Style_Check := False;
      Style_Check := False;

      --  Capture current suppress options, which may get modified

      Scope_Suppress := Opt.Suppress_Options;

      --  First deal with gnat.adc file

      if Opt.Config_File then
         Source_gnat_adc := Load_Config_File (Gnat_Adc);

         --  Case of gnat.adc file present

         if Source_gnat_adc > No_Source_File then

            --  Parse the gnat.adc file for configuration pragmas

            Initialize_Scanner (No_Unit, Source_gnat_adc);
            Config_Pragmas := Par (Configuration_Pragmas => True);

            --  We add a compilation dependency for gnat.adc so that if it
            --  changes, we force a recompilation.

            Prepcomp.Add_Dependency (Source_gnat_adc);
         end if;
      end if;

      --  Now deal with specified config pragmas files if there are any

      if Opt.Config_File_Names /= null then

         --  Loop through config pragmas files

         for Index in Opt.Config_File_Names'Range loop
            declare
               Len : constant Natural := Config_File_Names (Index)'Length;
               Str : constant String (1 .. Len) :=
                       Config_File_Names (Index).all;

               Config_Name : constant File_Name_Type := Name_Find (Str);
               Temp_File   : constant Boolean :=
                               Len > 4
                                 and then
                                   (Str (Len - 3 .. Len) = ".TMP"
                                      or else
                                    Str (Len - 3 .. Len) = ".tmp");
               --  Extension indicating a temporary config file?

            begin
               --  Skip it if it's the default name, already loaded above.
               --  Otherwise, we get confusing warning messages about seeing
               --  the same thing twice.

               if Config_Name /= Gnat_Adc
                 and then Config_Name /= Dot_Gnat_Adc
               then
                  --  Load the file, error if we did not find it

                  Source_Config_File := Load_Config_File (Config_Name);

                  if Source_Config_File <= No_Source_File then
                     Osint.Fail
                       ("cannot find configuration pragmas file "
                        & Config_File_Names (Index).all);

                  --  If we did find the file, and it is not a temporary file,
                  --  then we add a compilation dependency for it so that if it
                  --  changes, we force a recompilation.

                  elsif not Temp_File then
                     Prepcomp.Add_Dependency (Source_Config_File);
                  end if;

                  --  Parse the config pragmas file, and accumulate results

                  Initialize_Scanner (No_Unit, Source_Config_File);
                  Append_List_To
                    (Config_Pragmas, Par (Configuration_Pragmas => True));
               end if;
            end;
         end loop;
      end if;

      --  Now analyze all pragmas except those whose analysis must be
      --  deferred till after the main unit is analyzed.

      if Config_Pragmas /= Error_List
        and then Operating_Mode /= Check_Syntax
      then
         Prag := First (Config_Pragmas);
         while Present (Prag) loop
            if not Delay_Config_Pragma_Analyze (Prag) then
               Analyze_Pragma (Prag);
            end if;

            Next (Prag);
         end loop;
      end if;

      --  Restore style check, but if config file turned on checks, leave on

      Opt.Style_Check := Save_Style_Check or Style_Check;

      --  Capture any modifications to suppress options from config pragmas

      Opt.Suppress_Options := Scope_Suppress;

      --  If a target dependency info file has been read through switch
      --  -gnateT=, add it to the dependencies.

      if Target_Dependent_Info_Read_Name /= null then
         declare
            Index : Source_File_Index;
         begin
            Name_Len := 0;
            Add_Str_To_Name_Buffer (Target_Dependent_Info_Read_Name.all);
            Index := Load_Config_File (Name_Enter);
            Prepcomp.Add_Dependency (Index);
         end;
      end if;

      --  This is where we can capture the value of the compilation unit
      --  specific restrictions that have been set by the config pragma
      --  files (or from Targparm), for later restoration when processing
      --  e.g. subunits.

      Save_Config_Cunit_Boolean_Restrictions;

      --  If there was a -gnatem switch, initialize the mappings of unit names
      --  to file names and of file names to path names from the mapping file.

      if Mapping_File_Name /= null then
         Fmap.Initialize (Mapping_File_Name.all);
      end if;

      --  Adjust Optimize_Alignment mode from debug switches if necessary

      if Debug_Flag_Dot_SS then
         Optimize_Alignment := 'S';
      elsif Debug_Flag_Dot_TT then
         Optimize_Alignment := 'T';
      end if;

      --  We have now processed the command line switches, and the
      --  configuration pragma files, so this is the point at which we want to
      --  capture the values of the configuration switches (see Opt for further
      --  details).

      Register_Config_Switches;

      --  Check for file which contains No_Body pragma

      if Source_File_Is_No_Body (Source_Index (Main_Unit)) then
         Change_Main_Unit_To_Spec;
      end if;

      --  Initialize the scanner. Note that we do this after the call to
      --  Create_Standard, which uses the scanner in its processing of
      --  floating-point bounds.

      Initialize_Scanner (Main_Unit, Source_Index (Main_Unit));

      --  Here we call the parser to parse the compilation unit (or units in
      --  the check syntax mode, but in that case we won't go on to the
      --  semantics in any case).

      Discard_List (Par (Configuration_Pragmas => False));
      Parsing_Main_Extended_Source := False;

      --  The main unit is now loaded, and subunits of it can be loaded,
      --  without reporting spurious loading circularities.

      Set_Loading (Main_Unit, False);

      --  Now that the main unit is installed, we can complete the analysis
      --  of the pragmas in gnat.adc and the configuration file, that require
      --  a context for their semantic processing.

      if Config_Pragmas /= Error_List
        and then Operating_Mode /= Check_Syntax

        --  Do not attempt to process deferred configuration pragmas if the
        --  main unit failed to load, to avoid cascaded inconsistencies that
        --  can lead to a compiler crash.

        and then Fatal_Error (Main_Unit) /= Error_Detected
      then
         --  Pragmas that require some semantic activity, such as
         --  Interrupt_State, cannot be processed until the main unit is
         --  installed, because they require a compilation unit on which to
         --  attach with_clauses, etc. So analyze them now.

         declare
            Prag : Node_Id;

         begin
            Prag := First (Config_Pragmas);
            while Present (Prag) loop

               --  Guard against the case where a configuration pragma may be
               --  split into multiple pragmas and the original rewritten as a
               --  null statement.

               if Nkind (Prag) = N_Pragma
                 and then Delay_Config_Pragma_Analyze (Prag)
               then
                  Analyze_Pragma (Prag);
               end if;

               Next (Prag);
            end loop;
         end;
      end if;

      --  If we have restriction No_Exception_Propagation, and we did not have
      --  an explicit switch turning off Warn_On_Non_Local_Exception, then turn
      --  on this warning by default if we have encountered an exception
      --  handler.

      if Restriction_Check_Required (No_Exception_Propagation)
        and then not No_Warn_On_Non_Local_Exception
        and then Exception_Handler_Encountered
      then
         Warn_On_Non_Local_Exception := True;
      end if;

      --  Disable Initialize_Scalars for runtime files to avoid circular
      --  dependencies.

      if Initialize_Scalars
        and then Fname.Is_Predefined_File_Name (File_Name (Main_Source_File))
      then
         Initialize_Scalars   := False;
         Init_Or_Norm_Scalars := Normalize_Scalars;
      end if;

      --  Now on to the semantics. Skip if in syntax only mode

      if Operating_Mode /= Check_Syntax then

         --  Install the configuration pragmas in the tree

         Set_Config_Pragmas
           (Aux_Decls_Node (Cunit (Main_Unit)), Config_Pragmas);

         --  Following steps are skipped if we had a fatal error during parsing

         if Fatal_Error (Main_Unit) /= Error_Detected then

            --  Reset Operating_Mode to Check_Semantics for subunits. We cannot
            --  actually generate code for subunits, so we suppress expansion.
            --  This also corrects certain problems that occur if we try to
            --  incorporate subunits at a lower level.

            if Operating_Mode = Generate_Code
              and then Nkind (Unit (Cunit (Main_Unit))) = N_Subunit
            then
               Operating_Mode := Check_Semantics;
            end if;

            --  Analyze (and possibly expand) main unit

            Scope_Suppress := Suppress_Options;
            Semantics (Cunit (Main_Unit));

            --  Cleanup processing after completing main analysis

            pragma Assert (Operating_Mode in Check_Semantics | Generate_Code);

            if Operating_Mode = Generate_Code or else GNATprove_Mode then

               --  In GNATprove_Mode we do not perform most expansions but body
               --  instantiation is needed.

               Instantiate_Bodies;

               --  Analyze inlined bodies if required

               if Inline_Processing_Required then
                  Analyze_Inlined_Bodies;
               end if;

               --  Remove entities from program that do not have any execution
               --  time references.

               if Debug_Flag_UU then
                  Collect_Garbage_Entities;
               end if;

               --  Check access-before-elaboration rules

               if Legacy_Elaboration_Checks then
                  Check_Elab_Calls;
               end if;

               --  Examine all top level scenarios collected during analysis
               --  and resolution. Diagnose conditional ABEs, install run-time
               --  checks to catch conditional ABEs, and guarantee the prior
               --  elaboration of external units.

               Check_Elaboration_Scenarios;

            --  Examine all top level scenarios collected during analysis and
            --  resolution in order to diagnose conditional ABEs, even in the
            --  presence of serious errors.

            else
               Check_Elaboration_Scenarios;
            end if;

            --  List library units if requested

            if List_Units then
               Lib.List;
            end if;

            --  Output waiting warning messages

            Sem_Warn.Output_Non_Modified_In_Out_Warnings;
            Sem_Warn.Output_Unreferenced_Messages;
            Sem_Warn.Check_Unused_Withs;
            Sem_Warn.Output_Unused_Warnings_Off_Warnings;

            --  Remove any ignored Ghost code as it must not appear in the
            --  executable. This action must be performed very late because it
            --  heavily alters the tree.

            if Operating_Mode = Generate_Code or else GNATprove_Mode then
               Remove_Ignored_Ghost_Code;
            end if;

            --  At this stage we can unnest subprogram bodies if required

            if Total_Errors_Detected = 0 then
               Exp_Unst.Unnest_Subprograms (Cunit (Main_Unit));
            end if;

         end if;
      end if;
   end;

   --  Qualify all entity names in inner packages, package bodies, etc

   if not GNATprove_Mode then
      Exp_Dbug.Qualify_All_Entity_Names;
   end if;

   --  SCIL backend requirement. Check that SCIL nodes associated with
   --  dispatching calls reference subprogram calls.

   if Generate_SCIL then
      pragma Debug (Sem_SCIL.Check_SCIL_Nodes (Cunit (Main_Unit)));
      null;
   end if;

   --  Verify the validity of the tree

   if Debug_Flag_Underscore_VV then
      VAST.Check_Tree (Cunit (Main_Unit));
   end if;

   --  Validate all the subprogram calls; this work will be done by VAST; in
   --  the meantime it is done to check extra formals and it can be disabled
   --  using -gnatd_X (which also disables all the other assertions on extra
   --  formals). It is invoked using pragma Debug to avoid adding any cost
   --  when the compiler is built with assertions disabled.

   if not Debug_Flag_Underscore_XX then
      pragma Debug (Exp_Ch6.Validate_Subprogram_Calls (Cunit (Main_Unit)));
   end if;

   --  Dump the source now. Note that we do this as soon as the analysis
   --  of the tree is complete, because it is not just a dump in the case
   --  of -gnatD, where it rewrites all source locations in the tree.

   Sprint.Source_Dump;

   --  Check again for configuration pragmas that appear in the context
   --  of the main unit. These pragmas only affect the main unit, and the
   --  corresponding flag is reset after each call to Semantics, but they
   --  may affect the generated ali for the unit, and therefore the flag
   --  must be set properly after compilation. Currently we only check for
   --  Initialize_Scalars, but others should be checked: as well???

   declare
      Item : Node_Id;

   begin
      Item := First (Context_Items (Cunit (Main_Unit)));
      while Present (Item) loop
         if Nkind (Item) = N_Pragma
           and then Pragma_Name (Item) = Name_Initialize_Scalars
         then
            Initialize_Scalars := True;
         end if;

         Next (Item);
      end loop;
   end;

   --  If a mapping file has been specified by a -gnatem switch, update
   --  it if there has been some sources that were not in the mappings.

   if Mapping_File_Name /= null then
      Fmap.Update_Mapping_File (Mapping_File_Name.all);
   end if;

   return;
end Frontend;
