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

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

            pragma Assert
              (Operating_Mode = Generate_Code
                or else Operating_Mode = Check_Semantics);

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

            --  Analyze all inlined bodies, check access-before-elaboration
            --  rules, and remove ignored Ghost code when generating code or
            --  compiling for GNATprove.

            if Operating_Mode = Generate_Code or else GNATprove_Mode then
               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;

               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;
