------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             S I N P U T . L                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2021, 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 Alloc;
with Atree;          use Atree;
with Debug;          use Debug;
with Einfo;          use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils;    use Einfo.Utils;
with Errout;         use Errout;
with Fname;          use Fname;
with Lib;            use Lib;
with Opt;            use Opt;
with Osint;          use Osint;
with Output;         use Output;
with Prep;           use Prep;
with Prepcomp;       use Prepcomp;
with Scans;          use Scans;
with Scn;            use Scn;
with Sem_Aux;        use Sem_Aux;
with Sem_Util;       use Sem_Util;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Snames;         use Snames;
with System;         use System;

with System.OS_Lib;  use System.OS_Lib;

package body Sinput.L is

   Prep_Buffer : Text_Buffer_Ptr := null;
   --  A buffer to temporarily stored the result of preprocessing a source.
   --  It is only allocated if there is at least one source to preprocess.

   Prep_Buffer_Last : Text_Ptr := 0;
   --  Index of the last significant character in Prep_Buffer

   Initial_Size_Of_Prep_Buffer : constant := 10_000;
   --  Size of Prep_Buffer when it is first allocated

   --  When a file is to be preprocessed and the options to list symbols
   --  has been selected (switch -s), Prep.List_Symbols is called with a
   --  "foreword", a single line indicating what source the symbols apply to.
   --  The following two constant String are the start and the end of this
   --  foreword.

   Foreword_Start : constant String :=
                      "Preprocessing Symbols for source """;

   Foreword_End : constant String := """";

   -----------------
   -- Subprograms --
   -----------------

   procedure Put_Char_In_Prep_Buffer (C : Character);
   --  Add one character in Prep_Buffer, extending Prep_Buffer if need be.
   --  Used to initialize the preprocessor.

   procedure New_EOL_In_Prep_Buffer;
   --  Add an LF to Prep_Buffer (used to initialize the preprocessor)

   function Load_File
     (N : File_Name_Type;
      T : Osint.File_Type) return Source_File_Index;
   --  Load a source file, a configuration pragmas file or a definition file
   --  Coding also allows preprocessing file, but not a library file ???

   -------------------------------
   -- Adjust_Instantiation_Sloc --
   -------------------------------

   procedure Adjust_Instantiation_Sloc
     (N      : Node_Id;
      Factor : Sloc_Adjustment)
   is
      Loc : constant Source_Ptr := Sloc (N);

   begin
      --  We only do the adjustment if the value is between the appropriate low
      --  and high values. It is not clear that this should ever not be the
      --  case, but in practice there seem to be some nodes that get copied
      --  twice, and this is a defence against that happening.

      if Loc in Factor.Lo .. Factor.Hi then
         Set_Sloc (N, Loc + Factor.Adjust);
      end if;
   end Adjust_Instantiation_Sloc;

   --------------------------------
   -- Complete_Source_File_Entry --
   --------------------------------

   procedure Complete_Source_File_Entry is
      CSF : constant Source_File_Index := Current_Source_File;
   begin
      Trim_Lines_Table (CSF);
      Source_File.Table (CSF).Source_Checksum := Checksum;
   end Complete_Source_File_Entry;

   ---------------------------------
   -- Create_Instantiation_Source --
   ---------------------------------

   procedure Create_Instantiation_Source
     (Inst_Node        : Entity_Id;
      Template_Id      : Entity_Id;
      Factor           : out Sloc_Adjustment;
      Inlined_Body     : Boolean := False;
      Inherited_Pragma : Boolean := False)
   is
      Dnod : constant Node_Id := Declaration_Node (Template_Id);
      Xold : Source_File_Index;
      Xnew : Source_File_Index;

   begin
      Xold      := Get_Source_File_Index (Sloc (Template_Id));
      Factor.Lo := Source_File.Table (Xold).Source_First;
      Factor.Hi := Source_File.Table (Xold).Source_Last;

      Source_File.Append (Source_File.Table (Xold));
      Xnew := Source_File.Last;

      if Debug_Flag_L then
         Write_Eol;
         Write_Str ("*** Create_Instantiation_Source: created source ");
         Write_Int (Int (Xnew));
         Write_Line ("");
      end if;

      declare
         Sold : Source_File_Record renames Source_File.Table (Xold);
         Snew : Source_File_Record renames Source_File.Table (Xnew);

         Inst_Spec : Node_Id;

      begin
         Snew.Index            := Xnew;
         Snew.Inlined_Body     := Inlined_Body;
         Snew.Inherited_Pragma := Inherited_Pragma;
         Snew.Template         := Xold;

         --  For a genuine generic instantiation, assign new instance id. For
         --  inlined bodies or inherited pragmas, we retain that of the
         --  template, but we save the call location.

         if Inlined_Body or Inherited_Pragma then
            Snew.Inlined_Call := Sloc (Inst_Node);

         else
            --  If the spec has been instantiated already, and we are now
            --  creating the instance source for the corresponding body now,
            --  retrieve the instance id that was assigned to the spec, which
            --  corresponds to the same instantiation sloc.

            Inst_Spec := Instance_Spec (Inst_Node);
            if Present (Inst_Spec) then
               declare
                  Inst_Spec_Ent : Entity_Id;
                  --  Instance spec entity

                  Inst_Spec_Sloc : Source_Ptr;
                  --  Virtual sloc of the spec instance source

                  Inst_Spec_Inst_Id : Instance_Id;
                  --  Instance id assigned to the instance spec

               begin
                  Inst_Spec_Ent := Defining_Entity (Inst_Spec);

                  --  For a subprogram instantiation, we want the subprogram
                  --  instance, not the wrapper package.

                  if Present (Related_Instance (Inst_Spec_Ent)) then
                     Inst_Spec_Ent := Related_Instance (Inst_Spec_Ent);
                  end if;

                  --  The specification of the instance entity has a virtual
                  --  sloc within the instance sloc range.

                  --  ??? But the Unit_Declaration_Node has the sloc of the
                  --  instantiation, which is somewhat of an oddity.

                  Inst_Spec_Sloc :=
                    Sloc
                      (Specification (Unit_Declaration_Node (Inst_Spec_Ent)));
                  Inst_Spec_Inst_Id :=
                    Source_File.Table
                      (Get_Source_File_Index (Inst_Spec_Sloc)).Instance;

                  pragma Assert
                    (Sloc (Inst_Node) = Instances.Table (Inst_Spec_Inst_Id));
                  Snew.Instance := Inst_Spec_Inst_Id;
               end;

            else
               Instances.Append (Sloc (Inst_Node));
               Snew.Instance := Instances.Last;
            end if;
         end if;

         --  Now compute the new values of Source_First and Source_Last and
         --  adjust the source file pointer to have the correct bounds for the
         --  new range of values.

         --  Source_First must be greater than the last Source_Last value and
         --  also must be a multiple of Source_Align.

         Snew.Source_First :=
           ((Source_File.Table (Xnew - 1).Source_Last + Source_Align) /
              Source_Align) * Source_Align;
         Factor.Adjust := Snew.Source_First - Factor.Lo;
         Snew.Source_Last := Factor.Hi + Factor.Adjust;

         Set_Source_File_Index_Table (Xnew);

         Snew.Sloc_Adjust := Sold.Sloc_Adjust - Factor.Adjust;

         --  Modify the Dope of the instance Source_Text to use the
         --  above-computed bounds.

         declare
            Dope : constant Dope_Ptr :=
              new Dope_Rec'(Snew.Source_First, Snew.Source_Last);
         begin
            Snew.Source_Text := Sold.Source_Text;
            Set_Dope (Snew.Source_Text'Address, Dope);
            pragma Assert (Snew.Source_Text'First = Snew.Source_First);
            pragma Assert (Snew.Source_Text'Last = Snew.Source_Last);
         end;

         if Debug_Flag_L then
            Write_Str ("  for ");

            if Nkind (Dnod) in N_Proper_Body
              and then Was_Originally_Stub (Dnod)
            then
               Write_Str ("subunit ");

            elsif Ekind (Template_Id) = E_Generic_Package then
               if Nkind (Dnod) = N_Package_Body then
                  Write_Str ("body of package ");
               else
                  Write_Str ("spec of package ");
               end if;

            elsif Ekind (Template_Id) = E_Function then
               Write_Str ("body of function ");

            elsif Ekind (Template_Id) = E_Procedure then
               Write_Str ("body of procedure ");

            elsif Ekind (Template_Id) = E_Generic_Function then
               Write_Str ("spec of function ");

            elsif Ekind (Template_Id) = E_Generic_Procedure then
               Write_Str ("spec of procedure ");

            elsif Ekind (Template_Id) = E_Package_Body then
               Write_Str ("body of package ");

            else pragma Assert (Ekind (Template_Id) = E_Subprogram_Body);
               if Nkind (Dnod) = N_Procedure_Specification then
                  Write_Str ("body of procedure ");
               else
                  Write_Str ("body of function ");
               end if;
            end if;

            Write_Name (Chars (Template_Id));
            Write_Eol;

            Write_Str ("  copying from file name = ");
            Write_Name (File_Name (Xold));
            Write_Eol;

            Write_Str ("  old source index = ");
            Write_Int (Int (Xold));
            Write_Eol;

            Write_Str ("  old lo = ");
            Write_Int (Int (Factor.Lo));
            Write_Eol;

            Write_Str ("  old hi = ");
            Write_Int (Int (Factor.Hi));
            Write_Eol;

            Write_Str ("  new lo = ");
            Write_Int (Int (Snew.Source_First));
            Write_Eol;

            Write_Str ("  new hi = ");
            Write_Int (Int (Snew.Source_Last));
            Write_Eol;

            Write_Str ("  adjustment factor = ");
            Write_Int (Int (Factor.Adjust));
            Write_Eol;

            Write_Str ("  instantiation location: ");
            Write_Location (Sloc (Inst_Node));
            Write_Eol;
         end if;
      end;
   end Create_Instantiation_Source;

   ----------------------
   -- Load_Config_File --
   ----------------------

   function Load_Config_File
     (N : File_Name_Type) return Source_File_Index
   is
   begin
      return Load_File (N, Osint.Config);
   end Load_Config_File;

   --------------------------
   -- Load_Definition_File --
   --------------------------

   function Load_Definition_File
     (N : File_Name_Type) return Source_File_Index
   is
   begin
      return Load_File (N, Osint.Definition);
   end Load_Definition_File;

   ---------------
   -- Load_File --
   ---------------

   function Load_File
     (N : File_Name_Type;
      T : Osint.File_Type) return Source_File_Index
   is
      FD  : File_Descriptor;
      Hi  : Source_Ptr;
      Lo  : Source_Ptr;
      Src : Source_Buffer_Ptr;
      X   : Source_File_Index;

      Preprocessing_Needed : Boolean := False;

   begin
      --  If already there, don't need to reload file. An exception occurs
      --  in multiple unit per file mode. It would be nice in this case to
      --  share the same source file for each unit, but this leads to many
      --  difficulties with assumptions (e.g. in the body of lib), that a
      --  unit can be found by locating its source file index. Since we do
      --  not expect much use of this mode, it's no big deal to waste a bit
      --  of space and time by reading and storing the source multiple times.

      if Multiple_Unit_Index = 0 then
         for J in 1 .. Source_File.Last loop
            if Source_File.Table (J).File_Name = N then
               return J;
            end if;
         end loop;
      end if;

      --  Here we must build a new entry in the file table

      --  But first, we must check if a source needs to be preprocessed,
      --  because we may have to load and parse a definition file, and we want
      --  to do that before we load the source, so that the buffer of the
      --  source will be the last created, and we will be able to replace it
      --  and modify Hi without stepping on another buffer.

      if T = Osint.Source and then not Is_Internal_File_Name (N) then
         Prepare_To_Preprocess
           (Source => N, Preprocessing_Needed => Preprocessing_Needed);
      end if;

      Source_File.Increment_Last;
      X := Source_File.Last;

      if Debug_Flag_L then
         Write_Eol;
         Write_Str ("Sinput.L.Load_File: created source ");
         Write_Int (Int (X));
         Write_Str (" for ");
         Write_Str (Get_Name_String (N));
      end if;

      --  Compute starting index, respecting alignment requirement

      if X = Source_File.First then
         Lo := First_Source_Ptr;
      else
         Lo := ((Source_File.Table (X - 1).Source_Last + Source_Align) /
                  Source_Align) * Source_Align;
      end if;

      Osint.Read_Source_File (N, Lo, Hi, Src, FD, T);

      if Null_Source_Buffer_Ptr (Src) then
         Source_File.Decrement_Last;

         if FD = Null_FD then
            return No_Source_File;
         else
            return No_Access_To_Source_File;
         end if;
      else
         if Debug_Flag_L then
            Write_Eol;
            Write_Str ("*** Build source file table entry, Index = ");
            Write_Int (Int (X));
            Write_Str (", file name = ");
            Write_Name (N);
            Write_Eol;
            Write_Str ("  lo = ");
            Write_Int (Int (Lo));
            Write_Eol;
            Write_Str ("  hi = ");
            Write_Int (Int (Hi));
            Write_Eol;

            Write_Str ("  first 10 chars -->");

            declare
               procedure Wchar (C : Character);
               --  Writes character or ? for control character

               -----------
               -- Wchar --
               -----------

               procedure Wchar (C : Character) is
               begin
                  if C < ' '
                    or else C in ASCII.DEL .. Character'Val (16#9F#)
                  then
                     Write_Char ('?');
                  else
                     Write_Char (C);
                  end if;
               end Wchar;

            begin
               for J in Lo .. Lo + 9 loop
                  Wchar (Src (J));
               end loop;

               Write_Str ("<--");
               Write_Eol;

               Write_Str ("  last 10 chars  -->");

               for J in Hi - 10 .. Hi - 1 loop
                  Wchar (Src (J));
               end loop;

               Write_Str ("<--");
               Write_Eol;

               if Src (Hi) /= EOF then
                  Write_Str ("  error: no EOF at end");
                  Write_Eol;
               end if;
            end;
         end if;

         declare
            S         : Source_File_Record renames Source_File.Table (X);
            File_Type : Type_Of_File;

         begin
            case T is
               when Osint.Source =>
                  File_Type := Sinput.Src;

               when Osint.Library =>
                  raise Program_Error;

               when Osint.Config =>
                  File_Type := Sinput.Config;

               when Osint.Definition =>
                  File_Type := Def;

               when Osint.Preprocessing_Data =>
                  File_Type := Preproc;
            end case;

            S := (Debug_Source_Name   => N,
                  File_Name           => N,
                  File_Type           => File_Type,
                  First_Mapped_Line   => No_Line_Number,
                  Full_Debug_Name     => Osint.Full_Source_Name,
                  Full_File_Name      => Osint.Full_Source_Name,
                  Full_Ref_Name       => Osint.Full_Source_Name,
                  Instance            => No_Instance_Id,
                  Identifier_Casing   => Unknown,
                  Inlined_Call        => No_Location,
                  Inlined_Body        => False,
                  Inherited_Pragma    => False,
                  Keyword_Casing      => Unknown,
                  Last_Source_Line    => 1,
                  License             => Unknown,
                  Lines_Table         => null,
                  Lines_Table_Max     => 1,
                  Logical_Lines_Table => null,
                  Num_SRef_Pragmas    => 0,
                  Reference_Name      => N,
                  Sloc_Adjust         => 0,
                  Source_Checksum     => 0,
                  Source_First        => Lo,
                  Source_Last         => Hi,
                  Source_Text         => Src,
                  Template            => No_Source_File,
                  Unit                => No_Unit,
                  Time_Stamp          => Osint.Current_Source_File_Stamp,
                  Index               => X);

            Alloc_Line_Tables (S, Opt.Table_Factor * Alloc.Lines_Initial);
            S.Lines_Table (1) := Lo;
         end;

         --  Preprocess the source if it needs to be preprocessed

         if Preprocessing_Needed then

            --  Temporarily set the Source_File_Index_Table entries for the
            --  source, to avoid crash when reporting an error.

            Set_Source_File_Index_Table (X);

            if Opt.List_Preprocessing_Symbols then
               declare
                  Foreword : constant String :=
                    Foreword_Start & Get_Name_String (N) & Foreword_End;
               begin
                  Prep.List_Symbols (Foreword);
               end;
            end if;

            declare
               T : constant Nat := Total_Errors_Detected;
               --  Used to check if there were errors during preprocessing

               Save_Style_Check : Boolean;
               --  Saved state of the Style_Check flag (which needs to be
               --  temporarily set to False during preprocessing, see below).

               Modified : Boolean;

            begin
               --  If this is the first time we preprocess a source, allocate
               --  the preprocessing buffer.

               if Prep_Buffer = null then
                  Prep_Buffer :=
                    new Text_Buffer (1 .. Initial_Size_Of_Prep_Buffer);
               end if;

               --  Make sure the preprocessing buffer is empty

               Prep_Buffer_Last := 0;

               --  Initialize the preprocessor hooks

               Prep.Setup_Hooks
                 (Error_Msg         => Errout.Error_Msg'Access,
                  Scan              => Scn.Scanner.Scan'Access,
                  Set_Ignore_Errors => Errout.Set_Ignore_Errors'Access,
                  Put_Char          => Put_Char_In_Prep_Buffer'Access,
                  New_EOL           => New_EOL_In_Prep_Buffer'Access);

               --  Initialize scanner and set its behavior for preprocessing,
               --  then preprocess. Also disable style checks, since some of
               --  them are done in the scanner (specifically, those dealing
               --  with line length and line termination), and cannot be done
               --  during preprocessing (because the source file index table
               --  has not been set yet).

               Scn.Scanner.Initialize_Scanner (X);

               Scn.Scanner.Set_Special_Character ('#');
               Scn.Scanner.Set_Special_Character ('$');
               Scn.Scanner.Set_End_Of_Line_As_Token (True);
               Save_Style_Check := Opt.Style_Check;
               Opt.Style_Check := False;

               --  The actual preprocessing step

               Preprocess (Modified);

               --  Reset the scanner to its standard behavior, and restore the
               --  Style_Checks flag.

               Scn.Scanner.Reset_Special_Characters;
               Scn.Scanner.Set_End_Of_Line_As_Token (False);
               Opt.Style_Check := Save_Style_Check;

               --  If there were errors during preprocessing, record an error
               --  at the start of the file, and do not change the source
               --  buffer.

               if T /= Total_Errors_Detected then
                  Errout.Error_Msg
                    ("file could not be successfully preprocessed", Lo);
                  return No_Source_File;

               else
                  --  Output the result of the preprocessing, if requested and
                  --  the source has been modified by the preprocessing. Only
                  --  do that for the main unit (spec, body and subunits).

                  if Generate_Processed_File
                    and then Modified
                    and then
                     ((Compiler_State = Parsing
                        and then Parsing_Main_Extended_Source)
                       or else
                        (Compiler_State = Analyzing
                          and then Analysing_Subunit_Of_Main))
                  then
                     declare
                        FD     : File_Descriptor;
                        NB     : Integer;
                        Status : Boolean;

                        Prep_Filename : constant String :=
                          Get_Name_String (N) & Prep_Suffix;

                     begin
                        Delete_File (Prep_Filename, Status);

                        FD := Create_New_File (Prep_Filename, Text);

                        Status := FD /= Invalid_FD;

                        if Status then
                           NB :=
                             Write
                               (FD,
                                Prep_Buffer (1)'Address,
                                Integer (Prep_Buffer_Last));
                           Status := NB = Integer (Prep_Buffer_Last);
                        end if;

                        if Status then
                           Close (FD, Status);
                        end if;

                        if not Status then
                           Errout.Error_Msg
                             ("??could not write processed file """ &
                              Name_Buffer (1 .. Name_Len) & '"',
                              Lo);
                        end if;
                     end;
                  end if;

                  --  Set the new value of Hi

                  Hi := Lo + Source_Ptr (Prep_Buffer_Last);

                  --  Create the new source buffer

                  declare
                     Var_Ptr : constant Source_Buffer_Ptr_Var :=
                       new Source_Buffer (Lo .. Hi);
                     --  Allocate source buffer, allowing extra character at
                     --  end for EOF.

                  begin
                     Var_Ptr (Lo .. Hi - 1) :=
                       Prep_Buffer (1 .. Prep_Buffer_Last);
                     Var_Ptr (Hi) := EOF;
                     Src := Var_Ptr.all'Access;
                  end;

                  --  Record in the table the new source buffer and the
                  --  new value of Hi.

                  Source_File.Table (X).Source_Text := Src;
                  Source_File.Table (X).Source_Last := Hi;

                  --  Reset Last_Line to 1, because the lines do not
                  --  have necessarily the same starts and lengths.

                  Source_File.Table (X).Last_Source_Line := 1;
               end if;
            end;
         end if;

         Set_Source_File_Index_Table (X);
         return X;
      end if;
   end Load_File;

   ----------------------------------
   -- Load_Preprocessing_Data_File --
   ----------------------------------

   function Load_Preprocessing_Data_File
     (N : File_Name_Type) return Source_File_Index
   is
   begin
      return Load_File (N, Osint.Preprocessing_Data);
   end Load_Preprocessing_Data_File;

   ----------------------
   -- Load_Source_File --
   ----------------------

   function Load_Source_File
     (N : File_Name_Type) return Source_File_Index
   is
   begin
      return Load_File (N, Osint.Source);
   end Load_Source_File;

   ----------------------------
   -- New_EOL_In_Prep_Buffer --
   ----------------------------

   procedure New_EOL_In_Prep_Buffer is
   begin
      Put_Char_In_Prep_Buffer (ASCII.LF);
   end New_EOL_In_Prep_Buffer;

   -----------------------------
   -- Put_Char_In_Prep_Buffer --
   -----------------------------

   procedure Put_Char_In_Prep_Buffer (C : Character) is
   begin
      --  If preprocessing buffer is not large enough, double it

      if Prep_Buffer_Last = Prep_Buffer'Last then
         declare
            New_Prep_Buffer : constant Text_Buffer_Ptr :=
              new Text_Buffer (1 .. 2 * Prep_Buffer_Last);

         begin
            New_Prep_Buffer (Prep_Buffer'Range) := Prep_Buffer.all;
            Free (Prep_Buffer);
            Prep_Buffer := New_Prep_Buffer;
         end;
      end if;

      Prep_Buffer_Last := Prep_Buffer_Last + 1;
      Prep_Buffer (Prep_Buffer_Last) := C;
   end Put_Char_In_Prep_Buffer;

   -------------------------
   -- Source_File_Is_Body --
   -------------------------

   function Source_File_Is_Body (X : Source_File_Index) return Boolean is
      Pcount : Natural;

   begin
      Initialize_Scanner (No_Unit, X);

      --  Loop to look for subprogram or package body

      loop
         case Token is

            --  PRAGMA, WITH, USE (which can appear before a body)

            when Tok_Pragma
               | Tok_Use
               | Tok_With
            =>
               --  We just want to skip any of these, do it by skipping to a
               --  semicolon, but check for EOF, in case we have bad syntax.

               loop
                  if Token = Tok_Semicolon then
                     Scan;
                     exit;
                  elsif Token = Tok_EOF then
                     return False;
                  else
                     Scan;
                  end if;
               end loop;

            --  PACKAGE

            when Tok_Package =>
               Scan; -- Past PACKAGE

               --  We have a body if and only if BODY follows

               return Token = Tok_Body;

            --  FUNCTION or PROCEDURE

            when Tok_Function
               | Tok_Procedure
            =>
               Pcount := 0;

               --  Loop through tokens following PROCEDURE or FUNCTION

               loop
                  Scan;

                  case Token is

                     --  For parens, count paren level (note that paren level
                     --  can get greater than 1 if we have default parameters).

                     when Tok_Left_Paren =>
                        Pcount := Pcount + 1;

                     when Tok_Right_Paren =>
                        Pcount := Pcount - 1;

                     --  EOF means something weird, probably no body

                     when Tok_EOF =>
                        return False;

                     --  BEGIN or IS or END definitely means body is present

                     when Tok_Begin
                        | Tok_End
                        | Tok_Is
                     =>
                        return True;

                     --  Semicolon means no body present if at outside any
                     --  parens. If within parens, ignore, since it could be
                     --  a parameter separator.

                     when Tok_Semicolon =>
                        if Pcount = 0 then
                           return False;
                        end if;

                     --  Skip anything else

                     when others =>
                        null;
                  end case;
               end loop;

            --  Anything else in main scan means we don't have a body

            when others =>
               return False;
         end case;
      end loop;
   end Source_File_Is_Body;

   ----------------------------
   -- Source_File_Is_No_Body --
   ----------------------------

   function Source_File_Is_No_Body (X : Source_File_Index) return Boolean is
   begin
      Initialize_Scanner (No_Unit, X);

      if Token /= Tok_Pragma then
         return False;
      end if;

      Scan; -- past pragma

      if Token /= Tok_Identifier
        or else Chars (Token_Node) /= Name_No_Body
      then
         return False;
      end if;

      Scan; -- past No_Body

      if Token /= Tok_Semicolon then
         return False;
      end if;

      Scan; -- past semicolon

      return Token = Tok_EOF;
   end Source_File_Is_No_Body;

end Sinput.L;
