-------------------------------------------------------------------------------
-- (C) Altran Praxis Limited
-------------------------------------------------------------------------------
--
-- The SPARK toolset is free software; you can redistribute it and/or modify it
-- under terms of the GNU General Public License as published by the Free
-- Software Foundation; either version 3, or (at your option) any later
-- version. The SPARK toolset is distributed in the hope that it will be
-- useful, but WITHOUT 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 the SPARK toolset; see file
-- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy of
-- the license.
--
--=============================================================================

separate (Dictionary)
procedure LookupScope
  (Name          : in     LexTokenManager.Lex_String;
   Stop_At       : in     LexTokenManager.Lex_String;
   Scope         : in     Scopes;
   Calling_Scope : in     Scopes;
   Context       : in     Contexts;
   Item          :    out Symbol;
   Is_Visible    :    out Boolean)
-- The extra Calling_Scope parameter is only used when LookUpScope is called from
-- LookUpSelectedItem because in this case only the scope we start the search in
-- is not the same as the scope where the search started (former is the visible
-- scope of the prefix package).  The extra parameter only affects the selection of
-- the correct implicit proof function that corresponds to an Ada function
is
   Region : Symbol;

   --------------------------------------------------------------------------------

   function Lookup_Declarations
     (Name    : LexTokenManager.Lex_String;
      Stop_At : LexTokenManager.Lex_String;
      Context : Contexts;
      Head    : RawDict.Declaration_Info_Ref)
     return    Symbol
   --# global in Dict;
   --#        in LexTokenManager.State;
   is
      The_Declaration        : RawDict.Declaration_Info_Ref;
      Item, Declarative_Item : Symbol;
      Declarative_Item_Name  : LexTokenManager.Lex_String;

      --------------------------------------------------------------------------------

      function Lookup_Declaration
        (Name                  : LexTokenManager.Lex_String;
         Declarative_Item      : Symbol;
         Declarative_Item_Name : LexTokenManager.Lex_String;
         Context               : Contexts;
         The_Declaration       : RawDict.Declaration_Info_Ref)
        return                  Symbol
      --# global in Dict;
      --#        in LexTokenManager.State;
      is
         Item : Symbol;

         --------------------------------------------------------------------------------

         function Lookup_Enumeration_Literals
           (Name     : LexTokenManager.Lex_String;
            The_Type : RawDict.Type_Info_Ref)
           return     RawDict.Enumeration_Literal_Info_Ref
         --# global in Dict;
         --#        in LexTokenManager.State;
         is
            The_Enumeration_Literal : RawDict.Enumeration_Literal_Info_Ref;
         begin
            Trace_Lex_Str (Msg => "      In Lookup_Enumeration_Literals, seeking ",
                           L   => Name);
            The_Enumeration_Literal := RawDict.Get_Type_First_Enumeration_Literal (Type_Mark => The_Type);
            while The_Enumeration_Literal /= RawDict.Null_Enumeration_Literal_Info_Ref
              and then LexTokenManager.Lex_String_Case_Insensitive_Compare
              (Lex_Str1 => RawDict.Get_Enumeration_Literal_Name (The_Enumeration_Literal => The_Enumeration_Literal),
               Lex_Str2 => Name) /=
              LexTokenManager.Str_Eq loop
               The_Enumeration_Literal :=
                 RawDict.Get_Next_Enumeration_Literal (The_Enumeration_Literal => The_Enumeration_Literal);
            end loop;
            return The_Enumeration_Literal;
         end Lookup_Enumeration_Literals;

      begin -- Lookup_Declaration
         if Context = ProgramContext
           and then RawDict.Get_Declaration_Context (The_Declaration => The_Declaration) = ProofContext then
            Item := NullSymbol;
         else
            if LexTokenManager.Lex_String_Case_Insensitive_Compare (Lex_Str1 => Declarative_Item_Name,
                                                                    Lex_Str2 => Name) =
              LexTokenManager.Str_Eq then
               Item := Declarative_Item;
            elsif RawDict.GetSymbolDiscriminant (Declarative_Item) = Type_Symbol
              and then Is_Type (Type_Mark => RawDict.Get_Type_Info_Ref (Item => Declarative_Item))
              and then RawDict.Get_Type_Discriminant (Type_Mark => RawDict.Get_Type_Info_Ref (Item => Declarative_Item)) =
              Enumeration_Type_Item then
               Item :=
                 RawDict.Get_Enumeration_Literal_Symbol
                 (Lookup_Enumeration_Literals (Name     => Name,
                                               The_Type => RawDict.Get_Type_Info_Ref (Item => Declarative_Item)));
            else
               Item := NullSymbol;
            end if;
         end if;
         return Item;
      end Lookup_Declaration;

   begin -- Lookup_Declarations
      Trace_Lex_Str (Msg => "In Lookup_Declarations, seeking ",
                     L   => Name);
      Item            := NullSymbol;
      The_Declaration := Head;
      loop
         exit when The_Declaration = RawDict.Null_Declaration_Info_Ref;
         Declarative_Item := RawDict.Get_Declaration_Item (The_Declaration => The_Declaration);
         if RawDict.GetSymbolDiscriminant (Declarative_Item) = Operator_Symbol then
            Declarative_Item_Name := LexTokenManager.Null_String;
         else
            Declarative_Item_Name := GetSimpleName (Declarative_Item);
         end if;
         Trace_Lex_Str (Msg => "Declarative_Item_Name is ",
                        L   => Declarative_Item_Name);
         exit when LexTokenManager.Lex_String_Case_Insensitive_Compare
           (Lex_Str1 => Stop_At,
            Lex_Str2 => LexTokenManager.Null_String) /=
           LexTokenManager.Str_Eq
           and then LexTokenManager.Lex_String_Case_Insensitive_Compare
           (Lex_Str1 => Stop_At,
            Lex_Str2 => Declarative_Item_Name) =
           LexTokenManager.Str_Eq;
         Item :=
           Lookup_Declaration
           (Name                  => Name,
            Declarative_Item      => Declarative_Item,
            Declarative_Item_Name => Declarative_Item_Name,
            Context               => Context,
            The_Declaration       => The_Declaration);
         exit when Item /= NullSymbol;
         The_Declaration := RawDict.Get_Next_Declaration (The_Declaration => The_Declaration);
      end loop;
      return Item;
   end Lookup_Declarations;

   --------------------------------------------------------------------------------

   function Lookup_Known_Discriminants (Name     : in LexTokenManager.Lex_String;
                                        The_Type : in RawDict.Type_Info_Ref) return Symbol
   --# global in Dict;
   --#        in LexTokenManager.State;
   is
      The_Discriminant : Symbol;
   begin
      Trace_Lex_Str (Msg => "In Lookup_Known_Discriminants, seeking ",
                     L   => Name);
      case RawDict.Get_Type_Discriminant (Type_Mark => The_Type) is
         when Protected_Type_Item =>
            The_Discriminant := RawDict.Get_Protected_Type_First_Discriminant (The_Protected_Type => The_Type);
         when Task_Type_Item =>
            The_Discriminant := RawDict.Get_Task_Type_First_Discriminant (The_Task_Type => The_Type);
         when others => -- non-exec code
            The_Discriminant := NullSymbol;
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Invalid_Symbol_Table,
               Msg     => "in Dictionary.Lookup_Known_Discriminants");
      end case;

      while (The_Discriminant /= NullSymbol
               and then LexTokenManager.Lex_String_Case_Insensitive_Compare
               (Lex_Str1 => RawDict.GetDiscriminantName (The_Discriminant),
                Lex_Str2 => Name) /=
               LexTokenManager.Str_Eq) loop
         The_Discriminant := RawDict.GetNextDiscriminant (The_Discriminant);
      end loop;
      return The_Discriminant;
   end Lookup_Known_Discriminants;

   --------------------------------------------------------------------------------

   function Lookup_Package_Visible_Declarations
     (The_Package : RawDict.Package_Info_Ref;
      Name        : LexTokenManager.Lex_String;
      Context     : Contexts)
     return        Symbol
   --# global in Dict;
   --#        in LexTokenManager.State;
   is
      Item : Symbol;

      ------------------------------------------------------------------------------

      function Lookup_Own_Variables
        (Name        : LexTokenManager.Lex_String;
         The_Package : RawDict.Package_Info_Ref)
        return        RawDict.Variable_Info_Ref
      --# global in Dict;
      --#        in LexTokenManager.State;
      is
         The_Own_Variable : RawDict.Own_Variable_Info_Ref;
         The_Variable     : RawDict.Variable_Info_Ref;
      begin
         Trace_Lex_Str (Msg => "   In Lookup_Own_Variables, seeking ",
                        L   => Name);
         The_Own_Variable := RawDict.Get_Package_Own_Variables (The_Package => The_Package);
         loop
            if The_Own_Variable = RawDict.Null_Own_Variable_Info_Ref then
               The_Variable := RawDict.Null_Variable_Info_Ref;
               exit;
            end if;
            The_Variable := RawDict.Get_Own_Variable_Variable (The_Own_Variable => The_Own_Variable);
            exit when LexTokenManager.Lex_String_Case_Insensitive_Compare
              (Lex_Str1 => RawDict.Get_Variable_Name (The_Variable => The_Variable),
               Lex_Str2 => Name) =
              LexTokenManager.Str_Eq;
            The_Own_Variable := RawDict.Get_Next_Own_Variable (The_Own_Variable => The_Own_Variable);
         end loop;
         return The_Variable;
      end Lookup_Own_Variables;

      ------------------------------------------------------------------------------

      function Lookup_Own_Tasks
        (Name        : LexTokenManager.Lex_String;
         The_Package : RawDict.Package_Info_Ref)
        return        RawDict.Variable_Info_Ref
      --# global in Dict;
      --#        in LexTokenManager.State;
      is
         The_Task_Type : Symbol;
         The_Variable  : RawDict.Variable_Info_Ref;
      begin
         Trace_Lex_Str (Msg => "   In Lookup_Own_Tasks, seeking ",
                        L   => Name);
         The_Task_Type := RawDict.Get_Package_Task_List (The_Package => The_Package);
         loop
            if The_Task_Type = NullSymbol then
               The_Variable := RawDict.Null_Variable_Info_Ref;
               exit;
            end if;
            The_Variable := RawDict.GetOwnTaskVariable (The_Task_Type);
            exit when LexTokenManager.Lex_String_Case_Insensitive_Compare
              (Lex_Str1 => RawDict.Get_Variable_Name (The_Variable => The_Variable),
               Lex_Str2 => Name) =
              LexTokenManager.Str_Eq;
            The_Task_Type := RawDict.GetNextOwnTask (The_Task_Type);
         end loop;
         return The_Variable;
      end Lookup_Own_Tasks;

   begin -- Lookup_Package_Visible_Declarations
      Trace_Lex_Str (Msg => "   In Lookup_Package_Visible_Declarations, seeking ",
                     L   => Name);
      if LexTokenManager.Lex_String_Case_Insensitive_Compare
        (Lex_Str1 => RawDict.Get_Package_Name (The_Package => The_Package),
         Lex_Str2 => Name) =
        LexTokenManager.Str_Eq then
         Item := RawDict.Get_Package_Symbol (The_Package);
      else
         Item :=
           Lookup_Declarations
           (Name    => Name,
            Stop_At => LexTokenManager.Null_String,
            Context => Context,
            Head    => RawDict.Get_Package_First_Visible_Declaration (The_Package => The_Package));
         if Item = NullSymbol then
            Item :=
              Lookup_Declarations
              (Name    => Name,
               Stop_At => LexTokenManager.Null_String,
               Context => Context,
               Head    => RawDict.Get_Package_Visible_Renaming_Declarations (The_Package => The_Package));
         end if;
         if Item = NullSymbol
           and then RawDict.Get_Package_Generic_Unit (The_Package => The_Package) /= RawDict.Null_Generic_Unit_Info_Ref then
            Item :=
              Lookup_Declarations
              (Name    => Name,
               Stop_At => LexTokenManager.Null_String,
               Context => Context,
               Head    => RawDict.Get_Generic_Unit_First_Declaration
                 (The_Generic_Unit => RawDict.Get_Package_Generic_Unit (The_Package => The_Package)));
         end if;
         if Item = NullSymbol and then Context = ProofContext then
            Item := RawDict.Get_Variable_Symbol (Lookup_Own_Variables (Name        => Name,
                                                                       The_Package => The_Package));
            if Item = NullSymbol then
               Item := RawDict.Get_Variable_Symbol (Lookup_Own_Tasks (Name        => Name,
                                                                      The_Package => The_Package));
            end if;
         end if;
      end if;
      return Item;
   end Lookup_Package_Visible_Declarations;

   ------------------------------------------------------------------------------

   function Lookup_Protected_Type_Visible_Declarations
     (The_Protected_Type : RawDict.Type_Info_Ref;
      Name               : LexTokenManager.Lex_String;
      Context            : Contexts)
     return               Symbol
   --# global in Dict;
   --#        in LexTokenManager.State;
   --# pre RawDict.Get_Type_Discriminant (The_Protected_Type, Dict) = Protected_Type_Item;
   is
      Item : Symbol;
   begin
      Trace_Lex_Str (Msg => "   In Lookup_Protected_Type_Visible_Declarations, seeking ",
                     L   => Name);
      if LexTokenManager.Lex_String_Case_Insensitive_Compare
        (Lex_Str1 => RawDict.Get_Type_Name (Type_Mark => The_Protected_Type),
         Lex_Str2 => Name) =
        LexTokenManager.Str_Eq then
         -- if we find PT (say) when looking from within PT then what we want to return is the
         -- implicitly declared abstract own variable of PT rather than the type itself
         Item :=
           RawDict.Get_Variable_Symbol
           (RawDict.Get_Own_Variable_Variable
              (The_Own_Variable => RawDict.Get_Protected_Type_Own_Variable (The_Protected_Type => The_Protected_Type)));
      else
         Item :=
           Lookup_Declarations
           (Name    => Name,
            Stop_At => LexTokenManager.Null_String,
            Context => Context,
            Head    => RawDict.Get_Protected_Type_First_Visible_Declaration (The_Protected_Type => The_Protected_Type));
      end if;

      -- If not found then check the known discriminants
      if Item = NullSymbol then
         Item := Lookup_Known_Discriminants (Name     => Name,
                                             The_Type => The_Protected_Type);
      end if;
      return Item;
   end Lookup_Protected_Type_Visible_Declarations;

   ------------------------------------------------------------------------------

   function LookupVisibleDeclarations
     (Name      : LexTokenManager.Lex_String;
      TheRegion : Symbol;
      Context   : Contexts)
     return      Symbol
   --# global in Dict;
   --#        in LexTokenManager.State;
   is
      Item : Symbol;

      ------------------------------------------------------------------------------

      function Lookup_Task_Type_Visible_Declarations
        (The_Task_Type : RawDict.Type_Info_Ref;
         Name          : LexTokenManager.Lex_String)
        return          Symbol
      --# global in Dict;
      --#        in LexTokenManager.State;
      is
         Item : Symbol;
      begin
         Trace_Lex_Str (Msg => "   In Lookup_Task_Type_Visible_Declarations, seeking ",
                        L   => Name);
         -- check the know discriminants
         Item := Lookup_Known_Discriminants (Name     => Name,
                                             The_Type => The_Task_Type);

         return Item;
      end Lookup_Task_Type_Visible_Declarations;

   begin -- LookupVisibleDeclarations
      Trace_Lex_Str (Msg => "In LookupVisibleDeclarations, seeking ",
                     L   => Name);
      case RawDict.GetSymbolDiscriminant (TheRegion) is
         when Package_Symbol =>
            Item :=
              Lookup_Package_Visible_Declarations
              (The_Package => RawDict.Get_Package_Info_Ref (Item => TheRegion),
               Name        => Name,
               Context     => Context);
         when Type_Symbol =>
            if Is_Type (Type_Mark => RawDict.Get_Type_Info_Ref (Item => TheRegion)) then
               case RawDict.Get_Type_Discriminant (Type_Mark => RawDict.Get_Type_Info_Ref (Item => TheRegion)) is
                  when Protected_Type_Item =>
                     Item :=
                       Lookup_Protected_Type_Visible_Declarations
                       (The_Protected_Type => RawDict.Get_Type_Info_Ref (Item => TheRegion),
                        Name               => Name,
                        Context            => Context);
                  when Task_Type_Item =>
                     Item :=
                       Lookup_Task_Type_Visible_Declarations
                       (The_Task_Type => RawDict.Get_Type_Info_Ref (Item => TheRegion),
                        Name          => Name);
                  when others =>
                     Item := NullSymbol; -- can't be reached, there just to avoid DFerr
                     SystemErrors.Fatal_Error
                       (Sys_Err => SystemErrors.Invalid_Symbol_Table,
                        Msg     => "in Dictionary.LookupVisibleDeclarations");
               end case;
            else
               Item := NullSymbol; -- can't be reached, there just to avoid DFerr
               SystemErrors.Fatal_Error
                 (Sys_Err => SystemErrors.Invalid_Symbol_Table,
                  Msg     => "in Dictionary.LookupVisibleDeclarations");
            end if;
         when Generic_Unit_Symbol =>
            Item :=
              Lookup_Declarations
              (Name    => Name,
               Stop_At => LexTokenManager.Null_String,
               Context => Context,
               Head    => RawDict.Get_Generic_Unit_First_Declaration
                 (The_Generic_Unit => RawDict.Get_Generic_Unit_Info_Ref (Item => TheRegion)));
         when others => -- non-exec code
            Item := NullSymbol; -- can't be reached, there just to avoid DFerr
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Invalid_Symbol_Table,
               Msg     => "in Dictionary.LookupVisibleDeclarations");
      end case;
      return Item;
   end LookupVisibleDeclarations;

   ------------------------------------------------------------------------------

   procedure Lookup_Local_Declarations
     (Name          : in     LexTokenManager.Lex_String;
      Stop_At       : in     LexTokenManager.Lex_String;
      Region        : in     Symbol;
      Context       : in     Contexts;
      Scope_Type    : in     Visibility;
      Calling_Scope : in     Scopes;
      Item          :    out Symbol;
      Is_Visible    :    out Boolean)
   --# global in Dict;
   --#        in LexTokenManager.State;
   --# derives Is_Visible,
   --#         Item       from Calling_Scope,
   --#                         Context,
   --#                         Dict,
   --#                         LexTokenManager.State,
   --#                         Name,
   --#                         Region,
   --#                         Scope_Type,
   --#                         Stop_At;
   is
      The_Discriminant : SymbolDiscriminant;

      ------------------------------------------------------------------------------

      function Lookup_Package_Body
        (Name        : LexTokenManager.Lex_String;
         Stop_At     : LexTokenManager.Lex_String;
         The_Package : RawDict.Package_Info_Ref;
         Context     : Contexts;
         Scope_Type  : Visibility)
        return        Symbol
      --# global in Dict;
      --#        in LexTokenManager.State;
      is
         Item : Symbol;

         ------------------------------------------------------------------------------

         function Lookup_Refinement_Constituents
           (Name        : LexTokenManager.Lex_String;
            The_Package : RawDict.Package_Info_Ref)
           return        RawDict.Variable_Info_Ref
         --# global in Dict;
         --#        in LexTokenManager.State;
         is
            AbstractOwnVariables : Iterator;
            Constituent          : RawDict.Variable_Info_Ref;

            ------------------------------------------------------------------------------

            function Lookup_Constituents
              (Name         : LexTokenManager.Lex_String;
               The_Variable : RawDict.Variable_Info_Ref)
              return         RawDict.Variable_Info_Ref
            --# global in Dict;
            --#        in LexTokenManager.State;
            is
               Constituents : Iterator;
               Constituent  : RawDict.Variable_Info_Ref;
            begin
               Trace_Lex_Str (Msg => "         In Lookup_Constituents, seeking ",
                              L   => Name);
               Constituents := First_Constituent (The_Variable => The_Variable);
               loop
                  if IsNullIterator (Constituents) then
                     Constituent := RawDict.Null_Variable_Info_Ref;
                     exit;
                  end if;
                  Constituent := RawDict.Get_Variable_Info_Ref (CurrentSymbol (Constituents));
                  exit when LexTokenManager.Lex_String_Case_Insensitive_Compare
                    (Lex_Str1 => RawDict.Get_Variable_Name (The_Variable => Constituent),
                     Lex_Str2 => Name) =
                    LexTokenManager.Str_Eq
                    and then not Is_Own_Variable (The_Variable => Constituent);
                  Constituents := NextSymbol (Constituents);
               end loop;
               return Constituent;
            end Lookup_Constituents;

         begin -- Lookup_Refinement_Constituents
            Trace_Lex_Str (Msg => "      In Lookup_Refinement_Constituents, seeking ",
                           L   => Name);

            AbstractOwnVariables := First_Abstract_Own_Variable (The_Package => The_Package);
            Constituent          := RawDict.Null_Variable_Info_Ref;

            loop
               exit when IsNullIterator (AbstractOwnVariables);
               Constituent :=
                 Lookup_Constituents
                 (Name         => Name,
                  The_Variable => RawDict.Get_Variable_Info_Ref (CurrentSymbol (AbstractOwnVariables)));
               exit when Constituent /= RawDict.Null_Variable_Info_Ref;
               AbstractOwnVariables := NextSymbol (AbstractOwnVariables);
            end loop;
            return Constituent;
         end Lookup_Refinement_Constituents;

      begin -- Lookup_Package_Body
         Trace_Lex_Str (Msg => "In Lookup_Package_Body, seeking ",
                        L   => Name);
         if Scope_Type = Privat then
            Item :=
              Lookup_Declarations
              (Name    => Name,
               Stop_At => Stop_At,
               Context => Context,
               Head    => RawDict.Get_Package_First_Private_Declaration (The_Package => The_Package));
         else
            Item :=
              Lookup_Declarations
              (Name    => Name,
               Stop_At => Stop_At,
               Context => Context,
               Head    => RawDict.Get_Package_First_Local_Declaration (The_Package => The_Package));

            if Item = NullSymbol then
               Item :=
                 Lookup_Declarations
                 (Name    => Name,
                  Stop_At => Stop_At,
                  Context => Context,
                  Head    => RawDict.Get_Package_Local_Renaming_Declarations (The_Package => The_Package));
            end if;

            if Item = NullSymbol and then Context = ProofContext then
               Item := RawDict.Get_Variable_Symbol (Lookup_Refinement_Constituents (Name        => Name,
                                                                                    The_Package => The_Package));
            end if;

            if Item = NullSymbol then
               Item :=
                 Lookup_Declarations
                 (Name    => Name,
                  Stop_At => Stop_At,
                  Context => Context,
                  Head    => RawDict.Get_Package_First_Private_Declaration (The_Package => The_Package));
            end if;
         end if;

         if Item = NullSymbol then
            Item := Lookup_Package_Visible_Declarations (The_Package => The_Package,
                                                         Name        => Name,
                                                         Context     => Context);
         end if;
         return Item;
      end Lookup_Package_Body;

      ------------------------------------------------------------------------------

      procedure Lookup_Subprogram_Body
        (Name           : in     LexTokenManager.Lex_String;
         Stop_At        : in     LexTokenManager.Lex_String;
         The_Subprogram : in     RawDict.Subprogram_Info_Ref;
         Context        : in     Contexts;
         Item           :    out Symbol;
         Is_Visible     :    out Boolean)
      --# global in Dict;
      --#        in LexTokenManager.State;
      --# derives Is_Visible,
      --#         Item       from Context,
      --#                         Dict,
      --#                         LexTokenManager.State,
      --#                         Name,
      --#                         Stop_At,
      --#                         The_Subprogram;
      is

         procedure LookupSubprogramParameters
           (Name           : in     LexTokenManager.Lex_String;
            The_Subprogram : in     RawDict.Subprogram_Info_Ref;
            Context        : in     Contexts;
            Parameter      :    out Symbol;
            Is_Visible     :    out Boolean)
         --# global in Dict;
         --#        in LexTokenManager.State;
         --# derives Is_Visible from Context,
         --#                         Dict,
         --#                         LexTokenManager.State,
         --#                         Name,
         --#                         The_Subprogram &
         --#         Parameter  from Dict,
         --#                         LexTokenManager.State,
         --#                         Name,
         --#                         The_Subprogram;
         is
            The_Subprogram_Parameter : RawDict.Subprogram_Parameter_Info_Ref;

            ------------------------------------------------------------------------------

            procedure Lookup_Global_Variables
              (Name           : in     LexTokenManager.Lex_String;
               The_Subprogram : in     RawDict.Subprogram_Info_Ref;
               Context        : in     Contexts;
               Variable       :    out Symbol;
               Is_Visible     :    out Boolean)
            --# global in Dict;
            --#        in LexTokenManager.State;
            --# derives Is_Visible from Context,
            --#                         Dict,
            --#                         LexTokenManager.State,
            --#                         Name,
            --#                         The_Subprogram &
            --#         Variable   from Dict,
            --#                         LexTokenManager.State,
            --#                         Name,
            --#                         The_Subprogram;
            is
               The_Global_Variable      : RawDict.Global_Variable_Info_Ref;
               The_Variable             : RawDict.Variable_Info_Ref;
               The_Subprogram_Parameter : RawDict.Subprogram_Parameter_Info_Ref;
               Stop                     : Boolean := False;
            begin
               Variable   := NullSymbol;
               Is_Visible := False;
               Trace_Lex_Str (Msg => "         In Lookup_Global_Variables, seeking ",
                              L   => Name);

               The_Global_Variable :=
                 RawDict.Get_Subprogram_First_Global_Variable
                 (The_Subprogram => The_Subprogram,
                  Abstraction    => Get_Subprogram_Abstraction
                    (The_Subprogram => The_Subprogram,
                     Scope          => Set_Visibility (The_Visibility => Local,
                                                       The_Unit       => RawDict.Get_Subprogram_Symbol (The_Subprogram))));

               while not Stop loop
                  if The_Global_Variable = RawDict.Null_Global_Variable_Info_Ref then
                     Variable   := NullSymbol;
                     Is_Visible := False;
                     exit;
                  end if;
                  case RawDict.Get_Kind_Of_Global_Variable (The_Global_Variable => The_Global_Variable) is
                     when RawDict.Subprogram_Variable_Item =>
                        The_Variable := RawDict.Get_Global_Variable_Variable (The_Global_Variable => The_Global_Variable);
                        if LexTokenManager.Lex_String_Case_Insensitive_Compare
                          (Lex_Str1 => RawDict.Get_Variable_Name (The_Variable => The_Variable),
                           Lex_Str2 => Name) =
                          LexTokenManager.Str_Eq
                          and then not RawDict.Get_Global_Variable_Prefix_Needed (The_Global_Variable => The_Global_Variable) then
                           Variable   := RawDict.Get_Variable_Symbol (The_Variable);
                           Is_Visible := Context = ProofContext or else Variable_Is_Declared (The_Variable => The_Variable);
                           Stop       := True;
                        end if;
                     when RawDict.Subprogram_Parameter_Item =>
                        The_Subprogram_Parameter :=
                          RawDict.Get_Global_Variable_Parameter (The_Global_Variable => The_Global_Variable);
                        if LexTokenManager.Lex_String_Case_Insensitive_Compare
                          (Lex_Str1 => RawDict.Get_Subprogram_Parameter_Name (The_Subprogram_Parameter => The_Subprogram_Parameter),
                           Lex_Str2 => Name) =
                          LexTokenManager.Str_Eq
                          and then not RawDict.Get_Global_Variable_Prefix_Needed (The_Global_Variable => The_Global_Variable) then
                           Variable   := RawDict.Get_Subprogram_Parameter_Symbol (The_Subprogram_Parameter);
                           Is_Visible := True;
                           Stop       := True;
                        end if;
                     when others => -- non-exec code
                        Stop := True;
                        SystemErrors.Fatal_Error
                          (Sys_Err => SystemErrors.Invalid_Symbol_Table,
                           Msg     => "in Dictionary.Lookup_Global_Variables");
                  end case;
                  The_Global_Variable := RawDict.Get_Next_Global_Variable (The_Global_Variable => The_Global_Variable);
               end loop;
            end Lookup_Global_Variables;

         begin -- LookupSubprogramParameters
            Trace_Lex_Str (Msg => "      In LookupSubprogramParameters, seeking ",
                           L   => Name);

            The_Subprogram_Parameter := RawDict.Get_Subprogram_First_Parameter (The_Subprogram => The_Subprogram);
            while The_Subprogram_Parameter /= RawDict.Null_Subprogram_Parameter_Info_Ref
              and then LexTokenManager.Lex_String_Case_Insensitive_Compare
              (Lex_Str1 => RawDict.Get_Subprogram_Parameter_Name (The_Subprogram_Parameter => The_Subprogram_Parameter),
               Lex_Str2 => Name) /=
              LexTokenManager.Str_Eq loop
               The_Subprogram_Parameter :=
                 RawDict.Get_Next_Subprogram_Parameter (The_Subprogram_Parameter => The_Subprogram_Parameter);
            end loop;

            if The_Subprogram_Parameter = RawDict.Null_Subprogram_Parameter_Info_Ref then
               Lookup_Global_Variables (Name, The_Subprogram, Context, Parameter, Is_Visible);
            else
               Parameter  := RawDict.Get_Subprogram_Parameter_Symbol (The_Subprogram_Parameter);
               Is_Visible := True;
            end if;
         end LookupSubprogramParameters;

      begin -- Lookup_Subprogram_Body
         Trace_Lex_Str (Msg => "In Lookup_Subprogram_Body, seeking ",
                        L   => Name);
         Item :=
           Lookup_Declarations
           (Name    => Name,
            Stop_At => Stop_At,
            Context => Context,
            Head    => RawDict.Get_Subprogram_First_Declaration (The_Subprogram => The_Subprogram));
         if Item = NullSymbol then
            Item :=
              Lookup_Declarations
              (Name    => Name,
               Stop_At => Stop_At,
               Context => Context,
               Head    => RawDict.Get_Subprogram_Renaming_Declarations (The_Subprogram => The_Subprogram));
         end if;

         if Item = NullSymbol then
            LookupSubprogramParameters (Name, The_Subprogram, Context, Item, Is_Visible);
         else
            Is_Visible := True;
         end if;
      end Lookup_Subprogram_Body;

      ------------------------------------------------------------------------------

      function LookupLoop (Name    : LexTokenManager.Lex_String;
                           TheLoop : Symbol) return Symbol
      --# global in Dict;
      --#        in LexTokenManager.State;
      is
         Item : Symbol;

         -----------------------------------------------------------------------------

         function LookupLoopParameter (Name    : LexTokenManager.Lex_String;
                                       ForLoop : Symbol) return Symbol
         --# global in Dict;
         --#        in LexTokenManager.State;
         is
            Item : Symbol;
         begin
            Trace_Lex_Str (Msg => "   In LookupLoopParameter, seeking ",
                           L   => Name);

            if LexTokenManager.Lex_String_Case_Insensitive_Compare
              (Lex_Str1 => GetSimpleName (RawDict.GetLoopParameter (ForLoop)),
               Lex_Str2 => Name) =
              LexTokenManager.Str_Eq then
               Item := RawDict.GetLoopParameter (ForLoop);
            else
               Item := NullSymbol;
            end if;

            return Item;

         end LookupLoopParameter;

      begin -- LookupLoop
         Trace_Lex_Str (Msg => "In LookupLoop, seeking ",
                        L   => Name);

         if Is_For_Loop (TheSymbol => TheLoop) then
            Item := LookupLoopParameter (Name, TheLoop);
         else
            Item := NullSymbol;
         end if;

         return Item;

      end LookupLoop;

      --------------------------------------------------------------------------------

      function Lookup_Type
        (Name       : LexTokenManager.Lex_String;
         Context    : Contexts;
         The_Type   : RawDict.Type_Info_Ref;
         Scope_Type : Visibility)
        return       Symbol
      --# global in Dict;
      --#        in LexTokenManager.State;
      is
         Item : Symbol;

         --------------------------------------------------------------------------------

         function Lookup_Record_Components
           (Name     : LexTokenManager.Lex_String;
            The_Type : RawDict.Type_Info_Ref)
           return     RawDict.Record_Component_Info_Ref
         --# global in Dict;
         --#        in LexTokenManager.State;
         is
            The_Record_Component       : RawDict.Record_Component_Info_Ref;
            The_First_Record_Component : RawDict.Record_Component_Info_Ref;
            Current_Record             : RawDict.Type_Info_Ref;
         begin
            Trace_Lex_Str (Msg => "      In Lookup_Record_Components, seeking ",
                           L   => Name);
            Current_Record := The_Type;
            loop
               The_First_Record_Component := RawDict.Get_Type_First_Record_Component (Type_Mark => Current_Record);
               The_Record_Component       := The_First_Record_Component;
               while (The_Record_Component /= RawDict.Null_Record_Component_Info_Ref -- did not find
                        and then LexTokenManager.Lex_String_Case_Insensitive_Compare
                        (Lex_Str1 => RawDict.Get_Record_Component_Name (The_Record_Component => The_Record_Component),
                         Lex_Str2 => Name) /=
                        LexTokenManager.Str_Eq) loop -- found
                  The_Record_Component := RawDict.Get_Next_Record_Component (The_Record_Component => The_Record_Component);
               end loop;

               exit when The_Record_Component /= RawDict.Null_Record_Component_Info_Ref; -- carry success out of outer loop

               -- if we get here we failed to find field in local declarations
               -- so we search in inherited fields if there are any
               -- exit if no inherited fields found
               exit when not RawDict.Get_Record_Component_Inherited_Field (The_Record_Component => The_First_Record_Component);

               -- restart search in inherited fields
               Current_Record := RawDict.Get_Record_Component_Type (The_Record_Component => The_First_Record_Component);
            end loop;
            return The_Record_Component;
         end Lookup_Record_Components;

         --------------------------------------------------------------------------------

         function Lookup_Protected_Local_Scope
           (Name               : LexTokenManager.Lex_String;
            Context            : Contexts;
            The_Protected_Type : RawDict.Type_Info_Ref;
            Scope_Type         : Visibility)
           return               Symbol
         --# global in Dict;
         --#        in LexTokenManager.State;
         --# pre RawDict.Get_Type_Discriminant (The_Protected_Type, Dict) = Protected_Type_Item;
         is
            Item : Symbol;

            --------------------------------------------------------------------------------

            function Lookup_Protected_Elements
              (Name               : LexTokenManager.Lex_String;
               Context            : Contexts;
               The_Protected_Type : RawDict.Type_Info_Ref)
              return               Symbol
            --# global in Dict;
            --#        in LexTokenManager.State;
            --# pre RawDict.Get_Type_Discriminant (The_Protected_Type, Dict) = Protected_Type_Item;
            is
               Item : Symbol;
               It   : Iterator;

               function Lookup_Refinement_Constituents
                 (Name               : LexTokenManager.Lex_String;
                  The_Protected_Type : RawDict.Type_Info_Ref)
                 return               Symbol
               --# global in Dict;
               --#        in LexTokenManager.State;
               is
                  Constituents : Iterator;
                  Constituent  : Symbol;
               begin
                  Constituents :=
                    First_Constituent
                    (The_Variable => Get_Protected_Type_Own_Variable (The_Protected_Type => The_Protected_Type));
                  loop
                     if IsNullIterator (Constituents) then
                        Constituent := NullSymbol;
                        exit;
                     end if;
                     Constituent := CurrentSymbol (Constituents);
                     exit when LexTokenManager.Lex_String_Case_Insensitive_Compare
                       (Lex_Str1 => GetSimpleName (Constituent),
                        Lex_Str2 => Name) =
                       LexTokenManager.Str_Eq;
                     Constituents := NextSymbol (Constituents);
                  end loop;

                  return Constituent;
               end Lookup_Refinement_Constituents;

            begin -- Lookup_Protected_Elements
               Trace_Lex_Str (Msg => "      In Lookup_Protected_Elements, seeking ",
                              L   => Name);
               Item := NullSymbol;
               It   := First_Protected_Element (The_Protected_Type => The_Protected_Type);
               while not IsNullIterator (It) loop
                  if LexTokenManager.Lex_String_Case_Insensitive_Compare
                    (Lex_Str1 => GetSimpleName (CurrentSymbol (It)),
                     Lex_Str2 => Name) =
                    LexTokenManager.Str_Eq then
                     Item := CurrentSymbol (It);
                     exit;
                  end if;
                  It := NextSymbol (It);
               end loop;

               -- As we add each protected element to the Dictionary they first get added as
               -- refinement cosntiuents (in proof context) and then as variables.  The variable
               -- add must match each up with the refinement constituent already added so we
               -- need a special look up here to find them
               if Item = NullSymbol and then Context = ProofContext then
                  Item := Lookup_Refinement_Constituents (Name               => Name,
                                                          The_Protected_Type => The_Protected_Type);
               end if;

               -- if Item is null at this point then we have not found a match in the private part
               -- of the private type but we must also look in the visible part since things here
               -- are also directly visible
               if Item = NullSymbol then
                  Item :=
                    Lookup_Protected_Type_Visible_Declarations
                    (The_Protected_Type => The_Protected_Type,
                     Name               => Name,
                     Context            => Context);
               end if;
               return Item;
            end Lookup_Protected_Elements;

         begin -- Lookup_Protected_Local_Scope
            Trace_Lex_Str (Msg => "      In Lookup_Protected_Local_Scope, seeking ",
                           L   => Name);
            -- Search local declarations if we are in local scope.  If this fails (or if we
            -- are in private scope), then search protected elements etc., by calling
            -- Lookup_Protected_Elements
            Item := NullSymbol;
            if Scope_Type = Local then
               -- search starts in protected body where we seek local declarations
               Item :=
                 Lookup_Declarations
                 (Name    => Name,
                  Stop_At => LexTokenManager.Null_String,
                  Context => Context,
                  Head    => RawDict.Get_Protected_Type_First_Local_Declaration (The_Protected_Type => The_Protected_Type));

               if Item = NullSymbol then
                  -- we need to look at the part of the enclosing package body which is "above" the
                  -- protected type declaration
                  Item :=
                    Lookup_Package_Body
                    (Name        => Name,
                     Stop_At     => RawDict.Get_Type_Name (Type_Mark => The_Protected_Type),
                     The_Package => Get_Enclosing_Package
                       (Scope => Set_Visibility
                          (The_Visibility => Local,
                           The_Unit       => RawDict.Get_Type_Symbol (The_Protected_Type))),
                     Context     => Context,
                     Scope_Type  => Local);
               end if;
            end if;

            if Item = NullSymbol then
               -- we either failed to find the item in the protected body or we skipped
               -- it completely because Scope_Type = Privat on entry; so now we search
               -- the private part of the protected type
               Item := Lookup_Protected_Elements (Name               => Name,
                                                  Context            => Context,
                                                  The_Protected_Type => The_Protected_Type);
            end if;
            return Item;
         end Lookup_Protected_Local_Scope;

         --------------------------------------------------------------------------------

         function Lookup_Task_Local_Scope
           (Name          : LexTokenManager.Lex_String;
            Context       : Contexts;
            The_Task_Type : RawDict.Type_Info_Ref)
           return          Symbol
         --# global in Dict;
         --#        in LexTokenManager.State;
         is
            Item : Symbol;

            function Lookup_Global_Variables
              (Name          : LexTokenManager.Lex_String;
               The_Task_Type : RawDict.Type_Info_Ref;
               Context       : Contexts)
              return          RawDict.Variable_Info_Ref
            --# global in Dict;
            --#        in LexTokenManager.State;
            is
               The_Global_Variable  : RawDict.Global_Variable_Info_Ref;
               The_Variable, Result : RawDict.Variable_Info_Ref;
            begin
               Trace_Lex_Str (Msg => "            In Lookup_Global_Variables, seeking ",
                              L   => Name);
               The_Global_Variable :=
                 RawDict.Get_Task_Type_First_Global_Variable
                 (The_Task_Type => The_Task_Type,
                  Abstraction   => Get_Task_Type_Abstraction
                    (The_Task_Type => The_Task_Type,
                     Scope         => Set_Visibility (The_Visibility => Local,
                                                      The_Unit       => RawDict.Get_Type_Symbol (The_Task_Type))));

               loop
                  if The_Global_Variable = RawDict.Null_Global_Variable_Info_Ref then
                     Result := RawDict.Null_Variable_Info_Ref;
                     exit;
                  end if;
                  The_Variable := RawDict.Get_Global_Variable_Variable (The_Global_Variable => The_Global_Variable);
                  if LexTokenManager.Lex_String_Case_Insensitive_Compare
                    (Lex_Str1 => RawDict.Get_Variable_Name (The_Variable => The_Variable),
                     Lex_Str2 => Name) =
                    LexTokenManager.Str_Eq
                    and then not RawDict.Get_Global_Variable_Prefix_Needed (The_Global_Variable => The_Global_Variable) then
                     if Context = ProgramContext and then not Variable_Is_Declared (The_Variable => The_Variable) then
                        Result := RawDict.Null_Variable_Info_Ref;
                     else
                        Result := The_Variable;
                     end if;
                     exit;
                  end if;
                  The_Global_Variable := RawDict.Get_Next_Global_Variable (The_Global_Variable => The_Global_Variable);
               end loop;
               return Result;
            end Lookup_Global_Variables;

         begin -- Lookup_Task_Local_Scope

            -- search starts in task body where we seek local declarations
            Trace_Lex_Str (Msg => "         In Lookup_Task_Local_Scope, seeking ",
                           L   => Name);
            Item :=
              Lookup_Declarations
              (Name    => Name,
               Stop_At => LexTokenManager.Null_String,
               Context => Context,
               Head    => RawDict.Get_Task_Type_First_Local_Declaration (The_Task_Type => The_Task_Type));

            if Item = NullSymbol then
               -- look up globals
               Item :=
                 RawDict.Get_Variable_Symbol
                 (Lookup_Global_Variables (Name          => Name,
                                           The_Task_Type => The_Task_Type,
                                           Context       => Context));
            end if;

            if Item = NullSymbol then
               Item := Lookup_Known_Discriminants (Name     => Name,
                                                   The_Type => The_Task_Type);
            end if;

            return Item;
         end Lookup_Task_Local_Scope;

      begin -- Lookup_Type
         Trace_Lex_Str (Msg => "      In Lookup_Type, seeking ",
                        L   => Name);
         case RawDict.Get_Type_Discriminant (Type_Mark => The_Type) is
            when Record_Type_Item =>
               Item := RawDict.Get_Record_Component_Symbol (Lookup_Record_Components (Name     => Name,
                                                                                      The_Type => The_Type));
            when Protected_Type_Item =>
               Item :=
                 Lookup_Protected_Local_Scope
                 (Name               => Name,
                  Context            => Context,
                  The_Protected_Type => The_Type,
                  Scope_Type         => Scope_Type);
            when Task_Type_Item =>
               Item := Lookup_Task_Local_Scope (Name          => Name,
                                                Context       => Context,
                                                The_Task_Type => The_Type);
            when others => -- non-exec code
               Item := NullSymbol;
               SystemErrors.Fatal_Error (Sys_Err => SystemErrors.Invalid_Symbol_Table,
                                         Msg     => "in Dictionary.Lookup_Type");
         end case;
         return Item;
      end Lookup_Type;

      ------------------------------------------------------------------------------

      function Lookup_Subcomponents
        (Name             : LexTokenManager.Lex_String;
         The_Subcomponent : RawDict.Subcomponent_Info_Ref;
         Calling_Scope    : Scopes)
        return             RawDict.Subcomponent_Info_Ref
      --# global in Dict;
      --#        in LexTokenManager.State;
      is
         Current            : RawDict.Subcomponent_Info_Ref;
         Current_Record     : RawDict.Subcomponent_Info_Ref;
         First_Subcomponent : RawDict.Subcomponent_Info_Ref;
         Found              : Boolean := False;
         IsPrivateField     : Boolean := False;
      begin
         Trace_Lex_Str (Msg => "      In Lookup_Subcomponents, seeking ",
                        L   => Name);
         Current_Record := The_Subcomponent;
         loop
            First_Subcomponent := Current_Record;
            Current            := First_Subcomponent;
            if not IsPrivateField then
               loop -- search fields at current depth of current record
                  exit when Current = RawDict.Null_Subcomponent_Info_Ref;
                  Found :=
                    LexTokenManager.Lex_String_Case_Insensitive_Compare
                    (Lex_Str1 => Get_Subcomponent_Simple_Name (The_Subcomponent => Current),
                     Lex_Str2 => Name) =
                    LexTokenManager.Str_Eq;
                  exit when Found;
                  Current := RawDict.Get_Next_Subcomponent (The_Subcomponent => Current);
               end loop;
            end if;
            exit when Found; -- carry success out of outer loop

            -- if we get here then we failed to find the desired field at the current depth
            -- so we move to the first inherited field (if there is one and if it not a private
            -- extension) and try again
            exit when not RawDict.Get_Record_Component_Inherited_Field
              (The_Record_Component => RawDict.Get_Subcomponent_Record_Component (The_Subcomponent => First_Subcomponent));
            -- no more inherited fields
            IsPrivateField :=
              Type_Is_Private_Here
              (Type_Mark => Get_Subcomponent_Type (The_Subcomponent => Current_Record),
               Scope     => Calling_Scope);
            Current_Record := RawDict.Get_Subcomponent_Subcomponents (The_Subcomponent => First_Subcomponent);
         end loop;
         if not Found then
            Current := RawDict.Null_Subcomponent_Info_Ref;
         end if;
         return Current;
      end Lookup_Subcomponents;

   begin -- Lookup_Local_Declarations

      --  first part of if traps things like declaring a variable P in
      --  a procedure P and also handles implicit return variables in
      --  function proof annotations.
      Trace_Lex_Str (Msg => "   In Lookup_Local_Declarations, seeking ",
                     L   => Name);
      The_Discriminant := RawDict.GetSymbolDiscriminant (Region);

      if LexTokenManager.Lex_String_Case_Insensitive_Compare (Lex_Str1 => GetSimpleName (Region),
                                                              Lex_Str2 => Name) =
        LexTokenManager.Str_Eq
        and then
        -- Trap finding of A in X.A in nested record case
        -- Note that this case also means that seeking PT from the private part or body of PT
        -- returns the type symbol not the implicit own variable of the protected type
        The_Discriminant /= Subcomponent_Symbol
        and then The_Discriminant /= Variable_Symbol
        and then The_Discriminant /= Subprogram_Parameter_Symbol
        and then
        -- This line added as a result of CFR 1738. It allows the rest of the procedure to be
        -- used in the sole situation where we are performing lookup on a member of a record
        -- that has the same name as its own type.
        (The_Discriminant /= Type_Symbol
           or else RawDict.Get_Type_Discriminant (Type_Mark => RawDict.Get_Type_Info_Ref (Item => Region)) /= Record_Type_Item) then
         Item       := Region;
         Is_Visible := True;
      else
         case The_Discriminant is
            when Package_Symbol =>
               Item       :=
                 Lookup_Package_Body
                 (Name        => Name,
                  Stop_At     => Stop_At,
                  The_Package => RawDict.Get_Package_Info_Ref (Item => Region),
                  Context     => Context,
                  Scope_Type  => Scope_Type);
               Is_Visible := Item /= NullSymbol;
            when Subprogram_Symbol =>
               Lookup_Subprogram_Body
                 (Name           => Name,
                  Stop_At        => Stop_At,
                  The_Subprogram => RawDict.Get_Subprogram_Info_Ref (Item => Region),
                  Context        => Context,
                  Item           => Item,
                  Is_Visible     => Is_Visible);
            when LoopSymbol =>
               Item       := LookupLoop (Name, Region);
               Is_Visible := Item /= NullSymbol;
            when Subcomponent_Symbol =>
               Item       :=
                 RawDict.Get_Subcomponent_Symbol
                 (Lookup_Subcomponents
                    (Name             => Name,
                     The_Subcomponent => RawDict.Get_Subcomponent_Subcomponents
                       (The_Subcomponent => RawDict.Get_Subcomponent_Info_Ref (Item => Region)),
                     Calling_Scope    => Calling_Scope));
               Is_Visible := Item /= NullSymbol;
            when Variable_Symbol =>
               Item       :=
                 RawDict.Get_Subcomponent_Symbol
                 (Lookup_Subcomponents
                    (Name             => Name,
                     The_Subcomponent => RawDict.Get_Variable_Subcomponents (The_Variable => RawDict.Get_Variable_Info_Ref (Item => Region)),
                     Calling_Scope    => Calling_Scope));
               Is_Visible := Item /= NullSymbol;
            when Subprogram_Parameter_Symbol =>
               Item       :=
                 RawDict.Get_Subcomponent_Symbol
                 (Lookup_Subcomponents
                    (Name             => Name,
                     The_Subcomponent => RawDict.Get_Subprogram_Parameter_Subcomponents
                       (The_Subprogram_Parameter => RawDict.Get_Subprogram_Parameter_Info_Ref (Item => Region)),
                     Calling_Scope    => Calling_Scope));
               Is_Visible := Item /= NullSymbol;
            when Type_Symbol =>
               -- must be a type (record, task or protected)
               Item       :=
                 Lookup_Type
                 (Name       => Name,
                  Context    => Context,
                  The_Type   => RawDict.Get_Type_Info_Ref (Item => Region),
                  Scope_Type => Scope_Type);
               Is_Visible := Item /= NullSymbol;
            when Quantified_Variable_Symbol | Implicit_Return_Variable_Symbol =>
               Item       := NullSymbol;
               Is_Visible := False;
            when others => -- non-exec code
               Item       := NullSymbol;
               Is_Visible := False;
               SystemErrors.Fatal_Error
                 (Sys_Err => SystemErrors.Invalid_Symbol_Table,
                  Msg     => "in Dictionary.Lookup_Local_Declarations");
         end case;
      end if;
   end Lookup_Local_Declarations;

begin -- LookupScope
   Region := GetRegion (Scope);

   Trace_Lex_Str (Msg => "In LookupScope, seeking ",
                  L   => Name);
   Trace_Sym (Msg   => "   in ",
              Sym   => Region,
              Scope => Scope);
   Trace_Lex_Str (Msg => "   with Stop_At set to ",
                  L   => Stop_At);

   case Get_Visibility (Scope => Scope) is
      when Visible =>
         Item       := LookupVisibleDeclarations (Name, Region, Context);
         Is_Visible := Item /= NullSymbol;
      when Local | Privat =>
         Lookup_Local_Declarations
           (Name          => Name,
            Stop_At       => Stop_At,
            Region        => Region,
            Context       => Context,
            Scope_Type    => Get_Visibility (Scope => Scope),
            Calling_Scope => Calling_Scope,
            Item          => Item,
            Is_Visible    => Is_Visible);
   end case;

   if Context = ProofContext and then IsAdaFunction (Item) then
      Item :=
        RawDict.Get_Subprogram_Implicit_Proof_Function
        (The_Subprogram => RawDict.Get_Subprogram_Info_Ref (Item),
         Abstraction    => Get_Subprogram_Abstraction (The_Subprogram => RawDict.Get_Subprogram_Info_Ref (Item),
                                                       Scope          => Calling_Scope));
   end if;

   Trace_Sym (Msg   => "Found in LookupScope ",
              Sym   => Item,
              Scope => Scope);
end LookupScope;
