------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             R E S T R I C T                              --
--                                                                          --
--                                 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 Atree;          use Atree;
with Casing;         use Casing;
with Einfo;          use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils;    use Einfo.Utils;
with Errout;         use Errout;
with Debug;          use Debug;
with Fname;          use Fname;
with Fname.UF;       use Fname.UF;
with Lib;            use Lib;
with Opt;            use Opt;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Sinput;         use Sinput;
with Stand;          use Stand;
with Targparm;       use Targparm;
with Uname;          use Uname;

package body Restrict is

   Global_Restriction_No_Tasking : Boolean := False;
   --  Set to True when No_Tasking is set in the run-time package System
   --  or in a configuration pragmas file (for example, gnat.adc).

   --------------------------------
   -- Package Local Declarations --
   --------------------------------

   Config_Cunit_Boolean_Restrictions : Save_Cunit_Boolean_Restrictions;
   --  Save compilation unit restrictions set by config pragma files

   Restricted_Profile_Result : Boolean := False;
   --  This switch memoizes the result of Restricted_Profile function calls for
   --  improved efficiency. Valid only if Restricted_Profile_Cached is True.
   --  Note: if this switch is ever set True, it is never turned off again.

   Restricted_Profile_Cached : Boolean := False;
   --  This flag is set to True if the Restricted_Profile_Result contains the
   --  correct cached result of Restricted_Profile calls.

   No_Specification_Of_Aspects : array (Aspect_Id) of Source_Ptr :=
                                   (others => No_Location);
   --  Entries in this array are set to point to a previously occurring pragma
   --  that activates a No_Specification_Of_Aspect check.

   No_Specification_Of_Aspect_Warning : array (Aspect_Id) of Boolean :=
                                          (others => True);
   --  An entry in this array is set False in reponse to a previous call to
   --  Set_No_Speficiation_Of_Aspect for pragmas in the main unit that
   --  specify Warning as False. Once set False, an entry is never reset.

   No_Specification_Of_Aspect_Set : Boolean := False;
   --  Set True if any entry of No_Specifcation_Of_Aspects has been set True.
   --  Once set True, this is never turned off again.

   No_Use_Of_Attribute : array (Attribute_Id) of Source_Ptr :=
                           (others => No_Location);

   No_Use_Of_Attribute_Warning : array (Attribute_Id) of Boolean :=
                                   (others => False);

   No_Use_Of_Attribute_Set : Boolean := False;
   --  Indicates that No_Use_Of_Attribute was set at least once

   No_Use_Of_Pragma : array (Pragma_Id) of Source_Ptr :=
                        (others => No_Location);
   --  Source location of pragma No_Use_Of_Pragma for given pragma, a value
   --  of System_Location indicates occurrence in system.ads.

   No_Use_Of_Pragma_Warning : array (Pragma_Id) of Boolean :=
                                (others => False);

   No_Use_Of_Pragma_Set : Boolean := False;
   --  Indicates that No_Use_Of_Pragma was set at least once

   -----------------------
   -- Local Subprograms --
   -----------------------

   procedure Restriction_Msg (R : Restriction_Id; N : Node_Id);
   --  Called if a violation of restriction R at node N is found. This routine
   --  outputs the appropriate message or messages taking care of warning vs
   --  real violation, serious vs non-serious, implicit vs explicit, the second
   --  message giving the profile name if needed, and the location information.

   function Same_Entity (E1, E2 : Node_Id) return Boolean;
   --  Returns True iff E1 and E2 represent the same entity. Used for handling
   --  of No_Use_Of_Entity => fully_qualified_ENTITY restriction case.

   function Same_Unit (U1, U2 : Node_Id) return Boolean;
   --  Returns True iff U1 and U2 represent the same library unit. Used for
   --  handling of No_Dependence => Unit restriction case.

   function Suppress_Restriction_Message (N : Node_Id) return Boolean;
   --  N is the node for a possible restriction violation message, but the
   --  message is to be suppressed if this is an internal file and this file is
   --  not the main unit. Returns True if message is to be suppressed.

   -------------------
   -- Abort_Allowed --
   -------------------

   function Abort_Allowed return Boolean is
   begin
      if Restrictions.Set (No_Abort_Statements)
        and then Restrictions.Set (Max_Asynchronous_Select_Nesting)
        and then Restrictions.Value (Max_Asynchronous_Select_Nesting) = 0
      then
         return False;
      else
         return True;
      end if;
   end Abort_Allowed;

   ----------------------------------------
   -- Add_To_Config_Boolean_Restrictions --
   ----------------------------------------

   procedure Add_To_Config_Boolean_Restrictions (R : Restriction_Id) is
   begin
      Config_Cunit_Boolean_Restrictions (R) := True;
   end Add_To_Config_Boolean_Restrictions;
   --  Add specified restriction to stored configuration boolean restrictions.
   --  This is used for handling the special case of No_Elaboration_Code.

   -------------------------
   -- Check_Compiler_Unit --
   -------------------------

   procedure Check_Compiler_Unit (Feature : String; N : Node_Id) is
   begin
      if Compiler_Unit then
         Error_Msg_N (Feature & " not allowed in compiler unit!!??", N);
      end if;
   end Check_Compiler_Unit;

   procedure Check_Compiler_Unit (Feature : String; Loc : Source_Ptr) is
   begin
      if Compiler_Unit then
         Error_Msg (Feature & " not allowed in compiler unit!!??", Loc);
      end if;
   end Check_Compiler_Unit;

   ------------------------------------
   -- Check_Elaboration_Code_Allowed --
   ------------------------------------

   procedure Check_Elaboration_Code_Allowed (N : Node_Id) is
   begin
      Check_Restriction (No_Elaboration_Code, N);
   end Check_Elaboration_Code_Allowed;

   -----------------------------------------
   -- Check_Implicit_Dynamic_Code_Allowed --
   -----------------------------------------

   procedure Check_Implicit_Dynamic_Code_Allowed (N : Node_Id) is
   begin
      Check_Restriction (No_Implicit_Dynamic_Code, N);
   end Check_Implicit_Dynamic_Code_Allowed;

   --------------------------------
   -- Check_No_Implicit_Aliasing --
   --------------------------------

   procedure Check_No_Implicit_Aliasing (Obj : Node_Id) is
      E : Entity_Id;

   begin
      --  If restriction not active, nothing to check

      if not Restriction_Active (No_Implicit_Aliasing) then
         return;
      end if;

      --  If we have an entity name, check entity

      if Is_Entity_Name (Obj) then
         E := Entity (Obj);

         --  Restriction applies to entities that are objects

         if Is_Object (E) then
            if Is_Aliased (E) then
               return;

            elsif Present (Renamed_Object (E)) then
               Check_No_Implicit_Aliasing (Renamed_Object (E));
               return;
            end if;

         --  If we don't have an object, then it's OK

         else
            return;
         end if;

      --  For selected component, check selector

      elsif Nkind (Obj) = N_Selected_Component then
         Check_No_Implicit_Aliasing (Selector_Name (Obj));
         return;

      --  Indexed component is OK if aliased components

      elsif Nkind (Obj) = N_Indexed_Component then
         if Has_Aliased_Components (Etype (Prefix (Obj)))
           or else
             (Is_Access_Type (Etype (Prefix (Obj)))
               and then Has_Aliased_Components
                          (Designated_Type (Etype (Prefix (Obj)))))
         then
            return;
         end if;

      --  For type conversion, check converted expression

      elsif Nkind (Obj) in N_Unchecked_Type_Conversion | N_Type_Conversion then
         Check_No_Implicit_Aliasing (Expression (Obj));
         return;

      --  Explicit dereference is always OK

      elsif Nkind (Obj) = N_Explicit_Dereference then
         return;
      end if;

      --  If we fall through, then we have an aliased view that does not meet
      --  the rules for being explicitly aliased, so issue restriction msg.

      Check_Restriction (No_Implicit_Aliasing, Obj);
   end Check_No_Implicit_Aliasing;

   ----------------------------------
   -- Check_No_Implicit_Heap_Alloc --
   ----------------------------------

   procedure Check_No_Implicit_Heap_Alloc (N : Node_Id) is
   begin
      Check_Restriction (No_Implicit_Heap_Allocations, N);
   end Check_No_Implicit_Heap_Alloc;

   ----------------------------------
   -- Check_No_Implicit_Task_Alloc --
   ----------------------------------

   procedure Check_No_Implicit_Task_Alloc (N : Node_Id) is
   begin
      Check_Restriction (No_Implicit_Task_Allocations, N);
   end Check_No_Implicit_Task_Alloc;

   ---------------------------------------
   -- Check_No_Implicit_Protected_Alloc --
   ---------------------------------------

   procedure Check_No_Implicit_Protected_Alloc (N : Node_Id) is
   begin
      Check_Restriction (No_Implicit_Protected_Object_Allocations, N);
   end Check_No_Implicit_Protected_Alloc;

   -----------------------------------
   -- Check_Obsolescent_2005_Entity --
   -----------------------------------

   procedure Check_Obsolescent_2005_Entity (E : Entity_Id; N : Node_Id) is
      function Chars_Is (E : Entity_Id; S : String) return Boolean;
      --  Return True iff Chars (E) matches S (given in lower case)

      --------------
      -- Chars_Is --
      --------------

      function Chars_Is (E : Entity_Id; S : String) return Boolean is
         Nam : constant Name_Id := Chars (E);
      begin
         if Length_Of_Name (Nam) /= S'Length then
            return False;
         else
            return Get_Name_String (Nam) = S;
         end if;
      end Chars_Is;

   --  Start of processing for Check_Obsolescent_2005_Entity

   begin
      if Restriction_Check_Required (No_Obsolescent_Features)
        and then Ada_Version >= Ada_2005
        and then Chars_Is (Scope (E),                 "handling")
        and then Chars_Is (Scope (Scope (E)),         "characters")
        and then Chars_Is (Scope (Scope (Scope (E))), "ada")
        and then Scope (Scope (Scope (Scope (E)))) = Standard_Standard
      then
         if Chars_Is (E, "is_character")      or else
            Chars_Is (E, "is_string")         or else
            Chars_Is (E, "to_character")      or else
            Chars_Is (E, "to_string")         or else
            Chars_Is (E, "to_wide_character") or else
            Chars_Is (E, "to_wide_string")
         then
            Check_Restriction (No_Obsolescent_Features, N);
         end if;
      end if;
   end Check_Obsolescent_2005_Entity;

   ---------------------------
   -- Check_Restricted_Unit --
   ---------------------------

   procedure Check_Restricted_Unit (U : Unit_Name_Type; N : Node_Id) is
   begin
      if Suppress_Restriction_Message (N) then
         return;

      elsif Is_Spec_Name (U) then
         declare
            Fnam : constant File_Name_Type :=
                     Get_File_Name (U, Subunit => False);

         begin
            --  Get file name

            Get_Name_String (Fnam);

            --  Nothing to do if name not at least 5 characters long ending
            --  in .ads or .adb extension, which we strip.

            if Name_Len < 5
              or else (Name_Buffer (Name_Len - 3 .. Name_Len) /= ".ads"
                         and then
                       Name_Buffer (Name_Len - 3 .. Name_Len) /= ".adb")
            then
               return;
            end if;

            --  Strip extension and pad to eight characters

            Name_Len := Name_Len - 4;
            Add_Str_To_Name_Buffer ((Name_Len + 1 .. 8 => ' '));

            --  If predefined unit, check the list of restricted units

            if Is_Predefined_File_Name (Fnam) then
               for J in Unit_Array'Range loop
                  if Name_Len = 8
                    and then Name_Buffer (1 .. 8) = Unit_Array (J).Filenm
                  then
                     Check_Restriction (Unit_Array (J).Res_Id, N);
                  end if;
               end loop;

               --  If not predefined unit, then one special check still
               --  remains. GNAT.Current_Exception is not allowed if we have
               --  restriction No_Exception_Propagation active.

            else
               if Name_Buffer (1 .. 8) = "g-curexc" then
                  Check_Restriction (No_Exception_Propagation, N);
               end if;
            end if;
         end;
      end if;
   end Check_Restricted_Unit;

   -----------------------
   -- Check_Restriction --
   -----------------------

   procedure Check_Restriction
     (R : Restriction_Id;
      N : Node_Id;
      V : Uint := Uint_Minus_1)
   is
      Ignore_Msg_Issued : Boolean;
   begin
      Check_Restriction (Ignore_Msg_Issued, R, N, V);
   end Check_Restriction;

   procedure Check_Restriction
     (Msg_Issued : out Boolean;
      R          : Restriction_Id;
      N          : Node_Id;
      V          : Uint := Uint_Minus_1)
   is
      VV : Integer;
      --  V converted to integer form. If V is greater than Integer'Last,
      --  it is reset to minus 1 (unknown value).

      procedure Update_Restrictions (Info : in out Restrictions_Info);
      --  Update violation information in Info.Violated and Info.Count

      -------------------------
      -- Update_Restrictions --
      -------------------------

      procedure Update_Restrictions (Info : in out Restrictions_Info) is
      begin
         --  If not violated, set as violated now

         if not Info.Violated (R) then
            Info.Violated (R) := True;

            if R in All_Parameter_Restrictions then
               if VV < 0 then
                  Info.Unknown (R) := True;
                  Info.Count (R) := 1;

               else
                  Info.Count (R) := VV;
               end if;
            end if;

         --  Otherwise if violated already and a parameter restriction,
         --  update count by maximizing or summing depending on restriction.

         elsif R in All_Parameter_Restrictions then

            --  If new value is unknown, result is unknown

            if VV < 0 then
               Info.Unknown (R) := True;

            --  If checked by maximization, nothing to do because the
            --  check is per-object.

            elsif R in Checked_Max_Parameter_Restrictions then
               null;

            --  If checked by adding, do add, checking for overflow

            elsif R in Checked_Add_Parameter_Restrictions then
               declare
                  pragma Unsuppress (Overflow_Check);
               begin
                  Info.Count (R) := Info.Count (R) + VV;
               exception
                  when Constraint_Error =>
                     Info.Count (R) := Integer'Last;
                     Info.Unknown (R) := True;
               end;

            --  Should not be able to come here, known counts should only
            --  occur for restrictions that are Checked_max or Checked_Sum.

            else
               raise Program_Error;
            end if;
         end if;
      end Update_Restrictions;

   --  Start of processing for Check_Restriction

   begin
      Msg_Issued := False;

      --  In CodePeer mode, we do not want to check for any restriction, or set
      --  additional restrictions other than those already set in gnat1drv.adb
      --  so that we have consistency between each compilation.

      --  In GNATprove mode restrictions are checked, except for
      --  No_Initialize_Scalars, which is implicitly set in gnat1drv.adb.

      if CodePeer_Mode
        or else (GNATprove_Mode and then R = No_Initialize_Scalars)
      then
         return;
      end if;

      if UI_Is_In_Int_Range (V) then
         VV := Integer (UI_To_Int (V));
      else
         VV := -1;
      end if;

      --  Count can only be specified in the checked val parameter case

      pragma Assert (VV < 0 or else R in Checked_Val_Parameter_Restrictions);

      --  Nothing to do if value of zero specified for parameter restriction

      if VV = 0 then
         return;
      end if;

      --  Update current restrictions

      Update_Restrictions (Restrictions);

      --  If in main extended unit, update main restrictions as well. Note
      --  that as usual we check for Main_Unit explicitly to deal with the
      --  case of configuration pragma files.

      if Current_Sem_Unit = Main_Unit
        or else In_Extended_Main_Source_Unit (N)
      then
         Update_Restrictions (Main_Restrictions);
      end if;

      --  Nothing to do if restriction message suppressed

      if Suppress_Restriction_Message (N) then
         null;

      --  If restriction not set, nothing to do

      elsif not Restrictions.Set (R) then
         null;

      --  Don't complain about No_Obsolescent_Features in an instance, since we
      --  will complain on the template, which is much better. Are there other
      --  cases like this ??? Do we need a more general mechanism ???

      elsif R = No_Obsolescent_Features
        and then Instantiation_Location (Sloc (N)) /= No_Location
      then
         null;

      --  Here if restriction set, check for violation (this is a Boolean
      --  restriction, or a parameter restriction with a value of zero and an
      --  unknown count, or a parameter restriction with a known value that
      --  exceeds the restriction count).

      elsif R in All_Boolean_Restrictions
        or else (Restrictions.Unknown (R)
                   and then Restrictions.Value (R) = 0)
        or else Restrictions.Count (R) > Restrictions.Value (R)
      then
         Msg_Issued := True;
         Restriction_Msg (R, N);
      end if;

      --  For Max_Entries and the like, do not carry forward the violation
      --  count because it does not affect later declarations.

      if R in Checked_Max_Parameter_Restrictions then
         Restrictions.Count (R) := 0;
         Restrictions.Violated (R) := False;
      end if;
   end Check_Restriction;

   -------------------------------------
   -- Check_Restriction_No_Dependence --
   -------------------------------------

   procedure Check_Restriction_No_Dependence (U : Node_Id; Err : Node_Id) is
      DU : Node_Id;

   begin
      --  Ignore call if node U is not in the main source unit. This avoids
      --  cascaded errors, e.g. when Ada.Containers units with other units.
      --  However, allow Standard_Location here, since this catches some cases
      --  of constructs that get converted to run-time calls.

      if not In_Extended_Main_Source_Unit (U)
        and then Sloc (U) /= Standard_Location
      then
         return;
      end if;

      --  Loop through entries in No_Dependence table to check each one in turn

      for J in No_Dependences.First .. No_Dependences.Last loop
         DU := No_Dependences.Table (J).Unit;

         if Same_Unit (U, DU) then
            Error_Msg_Sloc := Sloc (DU);
            Error_Msg_Node_1 := DU;

            if No_Dependences.Table (J).Warn then
               Error_Msg
                 ("?*?violation of restriction `No_Dependence '='> &`#",
                  Sloc (Err));
            else
               Error_Msg
                 ("|violation of restriction `No_Dependence '='> &`#",
                  Sloc (Err));
            end if;

            return;
         end if;
      end loop;
   end Check_Restriction_No_Dependence;

   --------------------------------------------------
   -- Check_Restriction_No_Specification_Of_Aspect --
   --------------------------------------------------

   procedure Check_Restriction_No_Specification_Of_Aspect (N : Node_Id) is
      A_Id : Aspect_Id;
      Id   : Node_Id;

   begin
      --  Ignore call if no instances of this restriction set

      if not No_Specification_Of_Aspect_Set then
         return;
      end if;

      --  Ignore call if node N is not in the main source unit, since we only
      --  give messages for the main unit. This avoids giving messages for
      --  aspects that are specified in withed units.

      if not In_Extended_Main_Source_Unit (N) then
         return;
      end if;

      if Nkind (N) = N_Pragma then
         Id := Pragma_Identifier (N);
      elsif Nkind (N) = N_Attribute_Definition_Clause then
         Id := N;
      else
         Id := Identifier (N);
      end if;

      A_Id := Get_Aspect_Id (Chars (Id));
      pragma Assert (A_Id /= No_Aspect);

      Error_Msg_Sloc := No_Specification_Of_Aspects (A_Id);

      if Error_Msg_Sloc /= No_Location then
         Error_Msg_Node_1 := Id;
         Error_Msg_Warn := No_Specification_Of_Aspect_Warning (A_Id);
         Error_Msg_N
           ("<*<violation of restriction `No_Specification_Of_Aspect '='> &`#",
            Id);
      end if;
   end Check_Restriction_No_Specification_Of_Aspect;

   -------------------------------------------
   -- Check_Restriction_No_Use_Of_Attribute --
   --------------------------------------------

   procedure Check_Restriction_No_Use_Of_Attribute (N : Node_Id) is
      Attr_Id  : Attribute_Id;
      Attr_Nam : Name_Id;

   begin
      --  Nothing to do if the attribute is not in the main source unit, since
      --  we only give messages for the main unit. This avoids giving messages
      --  for attributes that are specified in withed units.

      if not In_Extended_Main_Source_Unit (N) then
         return;

      --  Nothing to do if not checking No_Use_Of_Attribute

      elsif not No_Use_Of_Attribute_Set then
         return;

      --  Do not consider internally generated attributes because this leads to
      --  bizarre errors.

      elsif not Comes_From_Source (N) then
         return;
      end if;

      if Nkind (N) = N_Attribute_Definition_Clause then
         Attr_Nam := Chars (N);
      else
         pragma Assert (Nkind (N) = N_Attribute_Reference);
         Attr_Nam := Attribute_Name (N);
      end if;

      Attr_Id        := Get_Attribute_Id (Attr_Nam);
      Error_Msg_Sloc := No_Use_Of_Attribute (Attr_Id);

      if Error_Msg_Sloc /= No_Location then
         Error_Msg_Name_1 := Attr_Nam;
         Error_Msg_Warn   := No_Use_Of_Attribute_Warning (Attr_Id);
         Error_Msg_N
           ("<*<violation of restriction `No_Use_Of_Attribute '='> %` #", N);
      end if;
   end Check_Restriction_No_Use_Of_Attribute;

   ----------------------------------------
   -- Check_Restriction_No_Use_Of_Entity --
   ----------------------------------------

   procedure Check_Restriction_No_Use_Of_Entity (N : Node_Id) is
   begin
      --  Error defence (not clearly necessary, but better safe)

      if No (Entity (N)) then
         return;
      end if;

      --  If simple name of entity not flagged with Boolean2 flag, then there
      --  cannot be a matching entry in the table, so skip the search.

      if Get_Name_Table_Boolean2 (Chars (Entity (N))) = False then
         return;
      end if;

      --  Restriction is only recognized within a configuration pragma file,
      --  or within a unit of the main extended program. Note: the test for
      --  Main_Unit is needed to properly include the case of configuration
      --  pragma files.

      if Current_Sem_Unit /= Main_Unit
        and then not In_Extended_Main_Source_Unit (N)
      then
         return;
      end if;

      --  Here we must search the table

      for J in No_Use_Of_Entity.First .. No_Use_Of_Entity.Last loop
         declare
            NE_Ent : NE_Entry renames No_Use_Of_Entity.Table (J);
            Ent    : Entity_Id;
            Expr   : Node_Id;

         begin
            Ent  := Entity (N);
            Expr := NE_Ent.Entity;
            loop
               --  Here if at outer level of entity name in reference (handle
               --  also the direct use of Text_IO in the pragma). For example:
               --  pragma Restrictions (No_Use_Of_Entity => Text_IO.Put);

               if Scope (Ent) = Standard_Standard
                 or else (Nkind (Expr) = N_Identifier
                           and then Chars (Ent) = Name_Text_IO
                           and then Chars (Scope (Ent)) = Name_Ada
                           and then Scope (Scope (Ent)) = Standard_Standard)
               then
                  if Nkind (Expr) in N_Identifier | N_Operator_Symbol
                    and then Chars (Ent) = Chars (Expr)
                  then
                     Error_Msg_Node_1 := N;
                     Error_Msg_Warn := NE_Ent.Warn;
                     Error_Msg_Sloc := Sloc (NE_Ent.Entity);
                     Error_Msg_N
                       ("<*<reference to & violates restriction "
                        & "No_Use_Of_Entity #", N);
                     return;

                  else
                     exit;
                  end if;

               --  Here if at outer level of entity name in table

               elsif Nkind (Expr) in N_Identifier | N_Operator_Symbol then
                  exit;

               --  Here if neither at the outer level

               else
                  pragma Assert (Nkind (Expr) = N_Selected_Component);
                  exit when Chars (Selector_Name (Expr)) /= Chars (Ent);
               end if;

               --  Move up a level

               loop
                  Ent := Scope (Ent);
                  exit when not Is_Internal_Name (Chars (Ent));
               end loop;

               Expr := Prefix (Expr);
            end loop;
         end;
      end loop;
   end Check_Restriction_No_Use_Of_Entity;

   ----------------------------------------
   -- Check_Restriction_No_Use_Of_Pragma --
   ----------------------------------------

   procedure Check_Restriction_No_Use_Of_Pragma (N : Node_Id) is
      Id   : constant Node_Id   := Pragma_Identifier (N);
      P_Id : constant Pragma_Id := Get_Pragma_Id (Chars (Id));

   begin
      --  Nothing to do if the pragma is not in the main source unit, since we
      --  only give messages for the main unit. This avoids giving messages for
      --  pragmas that are specified in withed units.

      if not In_Extended_Main_Source_Unit (N) then
         return;

      --  Nothing to do if not checking No_Use_Of_Pragma

      elsif not No_Use_Of_Pragma_Set then
         return;

      --  Do not consider internally generated pragmas because this leads to
      --  bizarre errors.

      elsif not Comes_From_Source (N) then
         return;
      end if;

      Error_Msg_Sloc := No_Use_Of_Pragma (P_Id);

      if Error_Msg_Sloc /= No_Location then
         Error_Msg_Warn := No_Use_Of_Pragma_Warning (P_Id);
         Error_Msg_N
           ("<*<violation of restriction `No_Use_Of_Pragma '='> &` #", Id);
      end if;
   end Check_Restriction_No_Use_Of_Pragma;

   --------------------------------------
   -- Check_Wide_Character_Restriction --
   --------------------------------------

   procedure Check_Wide_Character_Restriction (E : Entity_Id; N : Node_Id) is
   begin
      if Restriction_Check_Required (No_Wide_Characters)
        and then Comes_From_Source (N)
      then
         declare
            T : constant Entity_Id := Root_Type (E);
         begin
            if T = Standard_Wide_Character      or else
               T = Standard_Wide_String         or else
               T = Standard_Wide_Wide_Character or else
               T = Standard_Wide_Wide_String
            then
               Check_Restriction (No_Wide_Characters, N);
            end if;
         end;
      end if;
   end Check_Wide_Character_Restriction;

   ----------------------------------------
   -- Cunit_Boolean_Restrictions_Restore --
   ----------------------------------------

   procedure Cunit_Boolean_Restrictions_Restore
     (R : Save_Cunit_Boolean_Restrictions)
   is
   begin
      for J in Cunit_Boolean_Restrictions loop
         Restrictions.Set (J) := R (J);
      end loop;

      --  If No_Elaboration_Code set in configuration restrictions, and we
      --  in the main extended source, then set it here now. This is part of
      --  the special processing for No_Elaboration_Code.

      if In_Extended_Main_Source_Unit (Cunit_Entity (Current_Sem_Unit))
        and then Config_Cunit_Boolean_Restrictions (No_Elaboration_Code)
      then
         Restrictions.Set (No_Elaboration_Code) := True;
      end if;
   end Cunit_Boolean_Restrictions_Restore;

   -------------------------------------
   -- Cunit_Boolean_Restrictions_Save --
   -------------------------------------

   function Cunit_Boolean_Restrictions_Save
     return Save_Cunit_Boolean_Restrictions
   is
      R : Save_Cunit_Boolean_Restrictions;

   begin
      for J in Cunit_Boolean_Restrictions loop
         R (J) := Restrictions.Set (J);
      end loop;

      return R;
   end Cunit_Boolean_Restrictions_Save;

   ------------------------
   -- Get_Restriction_Id --
   ------------------------

   function Get_Restriction_Id
     (N : Name_Id) return Restriction_Id
   is
   begin
      Get_Name_String (N);
      Set_Casing (All_Upper_Case);

      for J in All_Restrictions loop
         declare
            S : constant String := Restriction_Id'Image (J);
         begin
            if S = Name_Buffer (1 .. Name_Len) then
               return J;
            end if;
         end;
      end loop;

      return Not_A_Restriction_Id;
   end Get_Restriction_Id;

   -----------------------
   -- Global_No_Tasking --
   -----------------------

   function Global_No_Tasking return Boolean is
   begin
      return Global_Restriction_No_Tasking
        or else Targparm.Restrictions_On_Target.Set (No_Tasking);
   end Global_No_Tasking;

   ---------------------------------------------
   -- No_Dynamic_Accessibility_Checks_Enabled --
   ---------------------------------------------

   function No_Dynamic_Accessibility_Checks_Enabled
     (N : Node_Id) return Boolean
   is
      pragma Unreferenced (N);
      --  N is currently unreferenced but present for debugging purposes and
      --  potential future use.

   begin
      return Restrictions.Set (No_Dynamic_Accessibility_Checks);
   end No_Dynamic_Accessibility_Checks_Enabled;

   -------------------------------
   -- No_Exception_Handlers_Set --
   -------------------------------

   function No_Exception_Handlers_Set return Boolean is
   begin
      return (No_Run_Time_Mode or else Configurable_Run_Time_Mode)
        and then (Restrictions.Set (No_Exception_Handlers)
                    or else
                  Restrictions.Set (No_Exception_Propagation));
   end No_Exception_Handlers_Set;

   -------------------------------------
   -- No_Exception_Propagation_Active --
   -------------------------------------

   function No_Exception_Propagation_Active return Boolean is
   begin
      return (No_Run_Time_Mode
               or else Configurable_Run_Time_Mode
               or else Debug_Flag_Dot_G)
        and then Restriction_Active (No_Exception_Propagation);
   end No_Exception_Propagation_Active;

   --------------------------------
   -- OK_No_Dependence_Unit_Name --
   --------------------------------

   function OK_No_Dependence_Unit_Name (N : Node_Id) return Boolean is
   begin
      if Nkind (N) = N_Selected_Component then
         return
           OK_No_Dependence_Unit_Name (Prefix (N))
             and then
           OK_No_Dependence_Unit_Name (Selector_Name (N));

      elsif Nkind (N) = N_Identifier then
         return True;

      else
         Error_Msg_N ("wrong form for unit name for No_Dependence", N);
         return False;
      end if;
   end OK_No_Dependence_Unit_Name;

   ------------------------------
   -- OK_No_Use_Of_Entity_Name --
   ------------------------------

   function OK_No_Use_Of_Entity_Name (N : Node_Id) return Boolean is
   begin
      if Nkind (N) = N_Selected_Component then
         return
           OK_No_Use_Of_Entity_Name (Prefix (N))
             and then
           OK_No_Use_Of_Entity_Name (Selector_Name (N));

      elsif Nkind (N) in N_Identifier | N_Operator_Symbol then
         return True;

      else
         Error_Msg_N ("wrong form for entity name for No_Use_Of_Entity", N);
         return False;
      end if;
   end OK_No_Use_Of_Entity_Name;

   ----------------------------------
   -- Process_Restriction_Synonyms --
   ----------------------------------

   --  Note: body of this function must be coordinated with list of renaming
   --  declarations in System.Rident.

   function Process_Restriction_Synonyms (N : Node_Id) return Name_Id is
      Old_Name : constant Name_Id := Chars (N);
      New_Name : Name_Id;

   begin
      case Old_Name is
         when Name_Boolean_Entry_Barriers =>
            New_Name := Name_Simple_Barriers;

         when Name_Max_Entry_Queue_Depth =>
            New_Name := Name_Max_Entry_Queue_Length;

         when Name_No_Dynamic_Interrupts =>
            New_Name := Name_No_Dynamic_Attachment;

         when Name_No_Requeue =>
            New_Name := Name_No_Requeue_Statements;

         when Name_No_Task_Attributes =>
            New_Name := Name_No_Task_Attributes_Package;

         when others =>
            return Old_Name;
      end case;

      --  Output warning if we are warning on obsolescent features.

      if Warn_On_Obsolescent_Feature then
         Error_Msg_Name_1 := Old_Name;
         Error_Msg_N ("restriction identifier % is obsolescent?j?", N);
         Error_Msg_Name_1 := New_Name;
         Error_Msg_N ("|use restriction identifier % instead?j?", N);
      end if;

      return New_Name;
   end Process_Restriction_Synonyms;

   --------------------------------------
   -- Reset_Cunit_Boolean_Restrictions --
   --------------------------------------

   procedure Reset_Cunit_Boolean_Restrictions is
   begin
      for J in Cunit_Boolean_Restrictions loop
         Restrictions.Set (J) := False;
      end loop;
   end Reset_Cunit_Boolean_Restrictions;

   -----------------------------------------------
   -- Restore_Config_Cunit_Boolean_Restrictions --
   -----------------------------------------------

   procedure Restore_Config_Cunit_Boolean_Restrictions is
   begin
      Cunit_Boolean_Restrictions_Restore (Config_Cunit_Boolean_Restrictions);
   end Restore_Config_Cunit_Boolean_Restrictions;

   ------------------------
   -- Restricted_Profile --
   ------------------------

   function Restricted_Profile return Boolean is
   begin
      if Restricted_Profile_Cached then
         return Restricted_Profile_Result;

      else
         Restricted_Profile_Result := True;
         Restricted_Profile_Cached := True;

         declare
            R : Restriction_Flags  renames
                  Profile_Info (Restricted_Tasking).Set;
            V : Restriction_Values renames
                  Profile_Info (Restricted_Tasking).Value;
         begin
            for J in R'Range loop
               if R (J)
                 and then (Restrictions.Set (J) = False
                            or else Restriction_Warnings (J)
                            or else
                              (J in All_Parameter_Restrictions
                                and then Restrictions.Value (J) > V (J)))
               then
                  Restricted_Profile_Result := False;
                  exit;
               end if;
            end loop;

            return Restricted_Profile_Result;
         end;
      end if;
   end Restricted_Profile;

   ------------------------
   -- Restriction_Active --
   ------------------------

   function Restriction_Active (R : All_Restrictions) return Boolean is
   begin
      return Restrictions.Set (R) and then not Restriction_Warnings (R);
   end Restriction_Active;

   --------------------------------
   -- Restriction_Check_Required --
   --------------------------------

   function Restriction_Check_Required (R : All_Restrictions) return Boolean is
   begin
      return Restrictions.Set (R);
   end Restriction_Check_Required;

   ---------------------
   -- Restriction_Msg --
   ---------------------

   procedure Restriction_Msg (R : Restriction_Id; N : Node_Id) is
      Msg : String (1 .. 100);
      Len : Natural := 0;

      procedure Add_Char (C : Character);
      --  Append given character to Msg, bumping Len

      procedure Add_Str (S : String);
      --  Append given string to Msg, bumping Len appropriately

      procedure Id_Case (S : String; Quotes : Boolean := True);
      --  Given a string S, case it according to current identifier casing, and
      --  store in Error_Msg_String. Then append `~` to the message buffer
      --  to output the string unchanged surrounded in quotes. The quotes
      --  are suppressed if Quotes = False.

      --------------
      -- Add_Char --
      --------------

      procedure Add_Char (C : Character) is
      begin
         Len := Len + 1;
         Msg (Len) := C;
      end Add_Char;

      -------------
      -- Add_Str --
      -------------

      procedure Add_Str (S : String) is
      begin
         Msg (Len + 1 .. Len + S'Length) := S;
         Len := Len + S'Length;
      end Add_Str;

      -------------
      -- Id_Case --
      -------------

      procedure Id_Case (S : String; Quotes : Boolean := True) is
      begin
         Name_Buffer (1 .. S'Last) := S;
         Name_Len := S'Length;
         Set_Casing (Identifier_Casing (Get_Source_File_Index (Sloc (N))));
         Error_Msg_Strlen := Name_Len;
         Error_Msg_String (1 .. Name_Len) := Name_Buffer (1 .. Name_Len);

         if Quotes then
            Add_Str ("`~`");
         else
            Add_Char ('~');
         end if;
      end Id_Case;

   --  Start of processing for Restriction_Msg

   begin
      --  Set warning message if warning

      if Restriction_Warnings (R) then
         Add_Str ("?*?");

      --  If real violation (not warning), then mark it as non-serious unless
      --  it is a violation of No_Finalization in which case we leave it as a
      --  serious message, since otherwise we get crashes during attempts to
      --  expand stuff that is not properly formed due to assumptions made
      --  about no finalization being present.

      elsif R /= No_Finalization then
         Add_Char ('|');
      end if;

      Error_Msg_Sloc := Restrictions_Loc (R);

      --  Set main message, adding implicit if no source location

      if Error_Msg_Sloc > No_Location
        or else Error_Msg_Sloc = System_Location
      then
         Add_Str ("violation of restriction ");
      else
         Add_Str ("violation of implicit restriction ");
         Error_Msg_Sloc := No_Location;
      end if;

      --  Case of parameterized restriction

      if R in All_Parameter_Restrictions then
         Add_Char ('`');
         Id_Case (Restriction_Id'Image (R), Quotes => False);
         Add_Str (" = ^`");
         Error_Msg_Uint_1 := UI_From_Int (Int (Restrictions.Value (R)));

      --  Case of boolean restriction

      else
         Id_Case (Restriction_Id'Image (R));
      end if;

      --  Case of no secondary profile continuation message

      if Restriction_Profile_Name (R) = No_Profile then
         if Error_Msg_Sloc /= No_Location then
            Add_Char ('#');
         end if;

         Add_Char ('!');
         Error_Msg_N (Msg (1 .. Len), N);

      --  Case of secondary profile continuation message present

      else
         Add_Char ('!');
         Error_Msg_N (Msg (1 .. Len), N);

         Len := 0;
         Add_Char ('\');

         --  Set as warning if warning case

         if Restriction_Warnings (R) then
            Add_Str ("??");
         end if;

         --  Set main message

         Add_Str ("from profile ");
         Id_Case (Profile_Name'Image (Restriction_Profile_Name (R)));

         --  Add location if we have one

         if Error_Msg_Sloc /= No_Location then
            Add_Char ('#');
         end if;

         --  Output unconditional message and we are done

         Add_Char ('!');
         Error_Msg_N (Msg (1 .. Len), N);
      end if;
   end Restriction_Msg;

   -----------------
   -- Same_Entity --
   -----------------

   function Same_Entity (E1, E2 : Node_Id) return Boolean is
   begin
      if Nkind (E1) in N_Identifier | N_Operator_Symbol
           and then
         Nkind (E2) in N_Identifier | N_Operator_Symbol
      then
         return Chars (E1) = Chars (E2);

      elsif Nkind (E1) in N_Selected_Component | N_Expanded_Name
              and then
            Nkind (E2) in N_Selected_Component | N_Expanded_Name
      then
         return Same_Unit (Prefix (E1), Prefix (E2))
                  and then
                Same_Unit (Selector_Name (E1), Selector_Name (E2));
      else
         return False;
      end if;
   end Same_Entity;

   ---------------
   -- Same_Unit --
   ---------------

   function Same_Unit (U1, U2 : Node_Id) return Boolean is
   begin
      if Nkind (U1) = N_Identifier and then Nkind (U2) = N_Identifier then
         return Chars (U1) = Chars (U2);

      elsif Nkind (U1) in N_Selected_Component | N_Expanded_Name
              and then
            Nkind (U2) in N_Selected_Component | N_Expanded_Name
      then
         return Same_Unit (Prefix (U1), Prefix (U2))
                  and then
                Same_Unit (Selector_Name (U1), Selector_Name (U2));
      else
         return False;
      end if;
   end Same_Unit;

   --------------------------------------------
   -- Save_Config_Cunit_Boolean_Restrictions --
   --------------------------------------------

   procedure Save_Config_Cunit_Boolean_Restrictions is
   begin
      Config_Cunit_Boolean_Restrictions := Cunit_Boolean_Restrictions_Save;
   end Save_Config_Cunit_Boolean_Restrictions;

   ------------------------------
   -- Set_Profile_Restrictions --
   ------------------------------

   procedure Set_Profile_Restrictions
     (P    : Profile_Name;
      N    : Node_Id;
      Warn : Boolean)
   is
      R : Restriction_Flags  renames Profile_Info (P).Set;
      V : Restriction_Values renames Profile_Info (P).Value;

   begin
      for J in R'Range loop
         if R (J) then
            declare
               Already_Restricted : constant Boolean := Restriction_Active (J);

            begin
               --  Set the restriction

               if J in All_Boolean_Restrictions then
                  Set_Restriction (J, N);
               else
                  Set_Restriction (J, N, V (J));
               end if;

               --  Record that this came from a Profile[_Warnings] restriction

               Restriction_Profile_Name (J) := P;

               --  Set warning flag, except that we do not set the warning
               --  flag if the restriction was already active and this is
               --  the warning case. That avoids a warning overriding a real
               --  restriction, which should never happen.

               if not (Warn and Already_Restricted) then
                  Restriction_Warnings (J) := Warn;
               end if;
            end;
         end if;
      end loop;
   end Set_Profile_Restrictions;

   ---------------------
   -- Set_Restriction --
   ---------------------

   procedure Set_Restriction
     (R : All_Boolean_Restrictions;
      N : Node_Id)
   is
   begin
      Restrictions.Set (R) := True;

      if Restricted_Profile_Cached and Restricted_Profile_Result then
         null;
      else
         Restricted_Profile_Cached := False;
      end if;

      --  Set location, but preserve location of system restriction for nice
      --  error msg with run time name.

      if Restrictions_Loc (R) /= System_Location then
         Restrictions_Loc (R) := Sloc (N);
      end if;

      --  Note restriction came from restriction pragma, not profile

      Restriction_Profile_Name (R) := No_Profile;

      --  Record the restriction if we are in the main unit, or in the extended
      --  main unit. The reason that we test separately for Main_Unit is that
      --  gnat.adc is processed with Current_Sem_Unit = Main_Unit, but nodes in
      --  gnat.adc do not appear to be in the extended main source unit (they
      --  probably should do ???)

      if Current_Sem_Unit = Main_Unit
        or else In_Extended_Main_Source_Unit (N)
      then
         if not Restriction_Warnings (R) then
            Main_Restrictions.Set (R) := True;
         end if;
      end if;
   end Set_Restriction;

   procedure Set_Restriction
     (R : All_Parameter_Restrictions;
      N : Node_Id;
      V : Integer)
   is
   begin
      if Restricted_Profile_Cached and Restricted_Profile_Result then
         null;
      else
         Restricted_Profile_Cached := False;
      end if;

      if Restrictions.Set (R) then
         if V < Restrictions.Value (R) then
            Restrictions.Value (R) := V;
            Restrictions_Loc (R) := Sloc (N);
         end if;

      else
         Restrictions.Set (R) := True;
         Restrictions.Value (R) := V;
         Restrictions_Loc (R) := Sloc (N);
      end if;

      --  Record the restriction if we are in the main unit, or in the extended
      --  main unit. The reason that we test separately for Main_Unit is that
      --  gnat.adc is processed with Current_Sem_Unit = Main_Unit, but nodes in
      --  gnat.adc do not appear to be the extended main source unit (they
      --  probably should do ???)

      if Current_Sem_Unit = Main_Unit
        or else In_Extended_Main_Source_Unit (N)
      then
         if Main_Restrictions.Set (R) then
            if V < Main_Restrictions.Value (R) then
               Main_Restrictions.Value (R) := V;
            end if;

         elsif not Restriction_Warnings (R) then
            Main_Restrictions.Set (R) := True;
            Main_Restrictions.Value (R) := V;
         end if;
      end if;

      --  Note restriction came from restriction pragma, not profile

      Restriction_Profile_Name (R) := No_Profile;
   end Set_Restriction;

   procedure Set_Restriction
     (R    : All_Restrictions;
      N    : Node_Id;
      Warn : Boolean;
      V    : Integer := Integer'First)
   is
      Set : Boolean := True;
   begin
      if Warn and then Restriction_Active (R) then
         Set := False;
      end if;

      if Set then
         if R in All_Boolean_Restrictions then
            Set_Restriction (R, N);
         else
            Set_Restriction (R, N, V);
         end if;

         Restriction_Warnings (R) := Warn;
      end if;
   end Set_Restriction;

   -----------------------------------
   -- Set_Restriction_No_Dependence --
   -----------------------------------

   procedure Set_Restriction_No_Dependence
     (Unit    : Node_Id;
      Warn    : Boolean;
      Profile : Profile_Name := No_Profile)
   is
   begin
      --  Loop to check for duplicate entry

      for J in No_Dependences.First .. No_Dependences.Last loop

         --  Case of entry already in table

         if Same_Unit (Unit, No_Dependences.Table (J).Unit) then

            --  Error has precedence over warning

            if not Warn then
               No_Dependences.Table (J).Warn := False;
            end if;

            return;
         end if;
      end loop;

      --  Entry is not currently in table

      No_Dependences.Append ((Unit, Warn, Profile));
   end Set_Restriction_No_Dependence;

   --------------------------------------
   -- Set_Restriction_No_Use_Of_Entity --
   --------------------------------------

   procedure Set_Restriction_No_Use_Of_Entity
     (Entity  : Node_Id;
      Warn    : Boolean;
      Profile : Profile_Name := No_Profile)
   is
      Nam : Node_Id;

   begin
      --  Loop to check for duplicate entry

      for J in No_Use_Of_Entity.First .. No_Use_Of_Entity.Last loop

         --  Case of entry already in table

         if Same_Entity (Entity, No_Use_Of_Entity.Table (J).Entity) then

            --  Error has precedence over warning

            if not Warn then
               No_Use_Of_Entity.Table (J).Warn := False;
            end if;

            return;
         end if;
      end loop;

      --  Entry is not currently in table

      No_Use_Of_Entity.Append ((Entity, Warn, Profile));

      --  Now we need to find the direct name and set Boolean2 flag

      if Nkind (Entity) in N_Identifier | N_Operator_Symbol then
         Nam := Entity;

      else
         pragma Assert (Nkind (Entity) = N_Selected_Component);
         Nam := Selector_Name (Entity);
         pragma Assert (Nkind (Nam) in N_Identifier | N_Operator_Symbol);
      end if;

      Set_Name_Table_Boolean2 (Chars (Nam), True);
   end Set_Restriction_No_Use_Of_Entity;

   ------------------------------------------------
   -- Set_Restriction_No_Specification_Of_Aspect --
   ------------------------------------------------

   procedure Set_Restriction_No_Specification_Of_Aspect
     (N    : Node_Id;
      Warn : Boolean)
   is
      A_Id : constant Aspect_Id_Exclude_No_Aspect := Get_Aspect_Id (Chars (N));

   begin
      No_Specification_Of_Aspect_Set := True;
      No_Specification_Of_Aspects (A_Id) := Sloc (N);
      No_Specification_Of_Aspect_Warning (A_Id) := Warn;
   end Set_Restriction_No_Specification_Of_Aspect;

   procedure Set_Restriction_No_Specification_Of_Aspect (A_Id : Aspect_Id) is
   begin
      No_Specification_Of_Aspect_Set := True;
      No_Specification_Of_Aspects (A_Id) := System_Location;
      No_Specification_Of_Aspect_Warning (A_Id) := False;
   end Set_Restriction_No_Specification_Of_Aspect;

   -----------------------------------------
   -- Set_Restriction_No_Use_Of_Attribute --
   -----------------------------------------

   procedure Set_Restriction_No_Use_Of_Attribute
     (N    : Node_Id;
      Warn : Boolean)
   is
      A_Id : constant Attribute_Id := Get_Attribute_Id (Chars (N));

   begin
      No_Use_Of_Attribute_Set := True;
      No_Use_Of_Attribute (A_Id) := Sloc (N);
      No_Use_Of_Attribute_Warning (A_Id) := Warn;
   end Set_Restriction_No_Use_Of_Attribute;

   procedure Set_Restriction_No_Use_Of_Attribute (A_Id : Attribute_Id) is
   begin
      No_Use_Of_Attribute_Set := True;
      No_Use_Of_Attribute (A_Id) := System_Location;
      No_Use_Of_Attribute_Warning (A_Id) := False;
   end Set_Restriction_No_Use_Of_Attribute;

   --------------------------------------
   -- Set_Restriction_No_Use_Of_Pragma --
   --------------------------------------

   procedure Set_Restriction_No_Use_Of_Pragma
     (N    : Node_Id;
      Warn : Boolean)
   is
      A_Id : constant Pragma_Id := Get_Pragma_Id (Chars (N));

   begin
      No_Use_Of_Pragma_Set := True;
      No_Use_Of_Pragma (A_Id) := Sloc (N);
      No_Use_Of_Pragma_Warning (A_Id) := Warn;
   end Set_Restriction_No_Use_Of_Pragma;

   procedure Set_Restriction_No_Use_Of_Pragma (A_Id : Pragma_Id) is
   begin
      No_Use_Of_Pragma_Set := True;
      No_Use_Of_Pragma (A_Id) := System_Location;
      No_Use_Of_Pragma_Warning (A_Id) := False;
   end Set_Restriction_No_Use_Of_Pragma;

   ---------------------------
   -- Set_Global_No_Tasking --
   ---------------------------

   procedure Set_Global_No_Tasking is
   begin
      Global_Restriction_No_Tasking := True;
   end Set_Global_No_Tasking;

   ----------------------------------
   -- Suppress_Restriction_Message --
   ----------------------------------

   function Suppress_Restriction_Message (N : Node_Id) return Boolean is
   begin
      --  We only output messages for the extended main source unit

      if In_Extended_Main_Source_Unit (N) then
         return False;

      --  If loaded by rtsfind, then suppress message

      elsif Sloc (N) <= No_Location then
         return True;

      --  Otherwise suppress message if internal file

      else
         return In_Internal_Unit (N);
      end if;
   end Suppress_Restriction_Message;

   ---------------------
   -- Tasking_Allowed --
   ---------------------

   function Tasking_Allowed return Boolean is
   begin
      return not Restrictions.Set (No_Tasking)
        and then (not Restrictions.Set (Max_Tasks)
                   or else Restrictions.Value (Max_Tasks) > 0)
        and then not No_Run_Time_Mode;
   end Tasking_Allowed;

end Restrict;
