-------------------------------------------------------------------------------
-- (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 (Sem)
procedure Wf_Generic_Subprogram_Instantiation
  (Node           : in     STree.SyntaxNode;
   Scope          : in     Dictionary.Scopes;
   Component_Data : in out ComponentManager.ComponentData;
   The_Heap       : in out Heap.HeapRecord)
is

   type Kind_Of_Generic_T is (Generic_Procedure, Generic_Function);

   Generic_Sym, Instantiation_Sym                       : Dictionary.Symbol;
   Errors_Found, Ok                                     : Boolean;
   Next_Node, Instantiation_Ident_Node, Constraint_Node : STree.SyntaxNode;
   Is_Overriding                                        : Boolean := False;
   Kind_Of_Generic                                      : Kind_Of_Generic_T;

   ----------------------------------------------------------
   -- Checks that the identifier after "is new" represents a visible generic unit of the
   -- appropriate kind.  Returns symbol of this generic unit if legal or a null symbol
   -- otherwise.
   procedure Check_Generic
     (Ident_Node  : in     STree.SyntaxNode;
      Scope       : in     Dictionary.Scopes;
      Kind        : in     Kind_Of_Generic_T;
      Generic_Sym :    out Dictionary.Symbol)
   --# global in     CommandLineData.Content;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SPARK_IO.File_Sys;
   --#        in out STree.Table;
   --# derives ErrorHandler.Error_Context,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         Ident_Node,
   --#                                         Kind,
   --#                                         LexTokenManager.State,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table &
   --#         Generic_Sym                from CommandLineData.Content,
   --#                                         Dictionary.Dict,
   --#                                         Ident_Node,
   --#                                         Kind,
   --#                                         LexTokenManager.State,
   --#                                         Scope,
   --#                                         STree.Table &
   --#         STree.Table                from *,
   --#                                         CommandLineData.Content,
   --#                                         Dictionary.Dict,
   --#                                         Ident_Node,
   --#                                         LexTokenManager.State,
   --#                                         Scope;
   --# pre Syntax_Node_Type (Ident_Node, STree.Table) = SP_Symbols.dotted_simple_name;
   --# post STree.Table = STree.Table~;
   is
      Current_Node : STree.SyntaxNode;
   begin
      Current_Node := Last_Child_Of (Start_Node => Ident_Node);
      -- ASSUME Current_Node = identifier
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => Current_Node) = SP_Symbols.identifier,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Current_Node = identifier in Check_Generic");
      Generic_Sym :=
        Dictionary.LookupItem
        (Name              => Node_Lex_String (Node => Current_Node),
         Scope             => Scope,
         Context           => Dictionary.ProgramContext,
         Full_Package_Name => False);
      loop
         --# assert STree.Table = STree.Table~;
         if Dictionary.Is_Null_Symbol (Generic_Sym) then
            ErrorHandler.Semantic_Error
              (Err_Num   => 1,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Current_Node),
               Id_Str    => Node_Lex_String (Node => Current_Node));
            exit;
         end if;
         STree.Set_Node_Lex_String (Sym  => Generic_Sym,
                                    Node => Current_Node);
         Current_Node := Parent_Node (Current_Node => Current_Node);
         -- ASSUME Current_Node = dotted_simple_name
         SystemErrors.RT_Assert
           (C       => Syntax_Node_Type (Node => Current_Node) = SP_Symbols.dotted_simple_name,
            Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Current_Node = dotted_simple_name in Check_Generic");
         exit when Current_Node = Ident_Node;
         if not Dictionary.IsPackage (Generic_Sym) then
            ErrorHandler.Semantic_Error
              (Err_Num   => 18,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Current_Node),
               Id_Str    => Node_Lex_String (Node => Current_Node));
            Generic_Sym := Dictionary.NullSymbol;
            exit;
         end if;
         Current_Node := Next_Sibling (Current_Node => Current_Node);
         -- ASSUME Current_Node = identifier
         SystemErrors.RT_Assert
           (C       => Syntax_Node_Type (Node => Current_Node) = SP_Symbols.identifier,
            Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Current_Node = identifier in Check_Generic");
         Generic_Sym :=
           Dictionary.LookupSelectedItem
           (Prefix   => Generic_Sym,
            Selector => Node_Lex_String (Node => Current_Node),
            Scope    => Scope,
            Context  => Dictionary.ProgramContext);
      end loop;

      -- Validate generic unit symbol
      if not Dictionary.Is_Null_Symbol (Generic_Sym) then

         -- Kludge Alert
         -- If I am honest, I don't really understand why this is needed.  We have looked
         -- up the generic in program context so I would expect to get the Ada function
         -- symbol.  A test case showed otherwise, hence this is in for now.  PNA 13/1/4
         if Dictionary.IsImplicitProofFunction (Generic_Sym) then
            Generic_Sym := Dictionary.GetAdaFunction (Generic_Sym);
         end if;

         if Dictionary.Is_Generic_Subprogram (The_Symbol => Generic_Sym) then
            if Kind = Generic_Procedure and then Dictionary.IsFunction (Generic_Sym) then
               -- wrong sort of subprogram
               ErrorHandler.Semantic_Error
                 (Err_Num   => 631,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Current_Node),
                  Id_Str    => LexTokenManager.Null_String);
               Generic_Sym := Dictionary.NullSymbol;
            elsif Kind = Generic_Function and then Dictionary.IsProcedure (Generic_Sym) then
               -- wrong sort of subprogram
               ErrorHandler.Semantic_Error
                 (Err_Num   => 632,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Current_Node),
                  Id_Str    => LexTokenManager.Null_String);
               Generic_Sym := Dictionary.NullSymbol;
            elsif not Dictionary.SubprogramSignatureIsWellformed (Dictionary.IsAbstract, Generic_Sym) then
               -- right sort of subprogram, but generic declaration had errors
               ErrorHandler.Semantic_Warning
                 (Err_Num  => 390,
                  Position => Node_Position (Node => Current_Node),
                  Id_Str   => LexTokenManager.Null_String);
               Generic_Sym := Dictionary.NullSymbol;
            end if;
         else -- not a generic subprgoram at all
            ErrorHandler.Semantic_Error_Sym
              (Err_Num   => 630,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Current_Node),
               Sym       => Generic_Sym,
               Scope     => Scope);
            Generic_Sym := Dictionary.NullSymbol;
         end if;
      end if;
   end Check_Generic;

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

   procedure Wf_Generic_Actual_Part
     (Actual_Part_Node  : in     STree.SyntaxNode;
      Instantiation_Sym : in     Dictionary.Symbol;
      Scope             : in     Dictionary.Scopes;
      Component_Data    : in out ComponentManager.ComponentData;
      The_Heap          : in out Heap.HeapRecord;
      Error_Found       :    out Boolean)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     ContextManager.Ops.Unit_Stack;
   --#        in out Aggregate_Stack.State;
   --#        in out Dictionary.Dict;
   --#        in out ErrorHandler.Error_Context;
   --#        in out LexTokenManager.State;
   --#        in out SLI.State;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Statistics.TableUsage;
   --#        in out STree.Table;
   --# derives Aggregate_Stack.State,
   --#         Component_Data,
   --#         Dictionary.Dict,
   --#         LexTokenManager.State,
   --#         Statistics.TableUsage,
   --#         STree.Table,
   --#         The_Heap                   from *,
   --#                                         Actual_Part_Node,
   --#                                         CommandLineData.Content,
   --#                                         Component_Data,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         Instantiation_Sym,
   --#                                         LexTokenManager.State,
   --#                                         Scope,
   --#                                         STree.Table,
   --#                                         The_Heap &
   --#         ErrorHandler.Error_Context,
   --#         SLI.State,
   --#         SPARK_IO.File_Sys          from Actual_Part_Node,
   --#                                         CommandLineData.Content,
   --#                                         Component_Data,
   --#                                         ContextManager.Ops.File_Heap,
   --#                                         ContextManager.Ops.Unit_Heap,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         Instantiation_Sym,
   --#                                         LexTokenManager.State,
   --#                                         Scope,
   --#                                         SLI.State,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         The_Heap &
   --#         Error_Found                from Actual_Part_Node,
   --#                                         CommandLineData.Content,
   --#                                         Component_Data,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         Instantiation_Sym,
   --#                                         LexTokenManager.State,
   --#                                         Scope,
   --#                                         STree.Table,
   --#                                         The_Heap;
   --# pre Syntax_Node_Type (Actual_Part_Node, STree.Table) = SP_Symbols.generic_actual_part;
   --# post STree.Table = STree.Table~;
      is separate;

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

   procedure Process_Generic_Procedure_Instantiation
     (Node                     : in out STree.SyntaxNode;
      Scope                    : in     Dictionary.Scopes;
      Instantiation_Ident_Node :    out STree.SyntaxNode;
      Constraint_Node          :    out STree.SyntaxNode;
      Ok                       :    out Boolean)
   --# global in     CommandLineData.Content;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SPARK_IO.File_Sys;
   --# derives Constraint_Node,
   --#         Instantiation_Ident_Node,
   --#         Node                       from Node,
   --#                                         STree.Table &
   --#         ErrorHandler.Error_Context,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table &
   --#         Ok                         from CommandLineData.Content,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.procedure_specification;
   --# post Syntax_Node_Type (Instantiation_Ident_Node, STree.Table) = SP_Symbols.identifier and
   --#   Syntax_Node_Type (Node, STree.Table) = SP_Symbols.procedure_annotation and
   --#   Syntax_Node_Type (Constraint_Node, STree.Table) = SP_Symbols.procedure_constraint;
   is
      Formal_Part_Node, Global_Node, Dependency_Node, Declare_Node : STree.SyntaxNode;
   begin
      Instantiation_Ident_Node := Child_Node (Current_Node => Node);
      -- ASSUME Instantiation_Ident_Node = simple_name
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => Instantiation_Ident_Node) = SP_Symbols.simple_name,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Instantiation_Ident_Node = simple_name in Process_Generic_Procedure_Instantiation");

      Formal_Part_Node := Next_Sibling (Current_Node => Instantiation_Ident_Node);

      Instantiation_Ident_Node := Child_Node (Current_Node => Instantiation_Ident_Node);
      -- ASSUME Instantiation_Ident_Node = identifier
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => Instantiation_Ident_Node) = SP_Symbols.identifier,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Instantiation_Ident_Node = identifier in Process_Generic_Procedure_Instantiation");
      Check_Valid_Ident (Ident_Node    => Instantiation_Ident_Node,
                         Current_Scope => Scope,
                         Ok            => Ok);

      -- ASSUME Formal_Part_Node = formal_part OR NULL
      if Syntax_Node_Type (Node => Formal_Part_Node) = SP_Symbols.formal_part then
         -- ASSUME Formal_Part_Node = formal_part
         Ok := False;
         ErrorHandler.Semantic_Error
           (Err_Num   => 628,
            Reference => ErrorHandler.No_Reference,
            Position  => Node_Position (Node => Formal_Part_Node),
            Id_Str    => Node_Lex_String (Node => Instantiation_Ident_Node));
      elsif Formal_Part_Node /= STree.NullNode then
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Formal_Part_Node = formal_part OR NULL in Process_Generic_Procedure_Instantiation");
      end if;

      Node := Next_Sibling (Current_Node => Node);
      -- ASSUME Node = procedure_annotation
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => Node) = SP_Symbols.procedure_annotation,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Node = procedure_annotation in Process_Generic_Procedure_Instantiation");

      Get_Subprogram_Anno_Key_Nodes
        (Node            => Node,
         Global_Node     => Global_Node,
         Dependency_Node => Dependency_Node,
         Declare_Node    => Declare_Node,
         Constraint_Node => Constraint_Node);

      -- ASSUME Global_Node = moded_global_definition OR NULL
      -- ASSUME Dependency_Node = dependency_relation OR NULL
      -- ASSUME Declare_Node = declare_annotation OR NULL
      if Syntax_Node_Type (Node => Global_Node) = SP_Symbols.moded_global_definition
        or else Syntax_Node_Type (Node => Dependency_Node) = SP_Symbols.dependency_relation
        or else Syntax_Node_Type (Node => Declare_Node) = SP_Symbols.declare_annotation then
         -- ASSUME Global_Node = moded_global_definition
         Ok := False;
         ErrorHandler.Semantic_Error
           (Err_Num   => 626,
            Reference => ErrorHandler.No_Reference,
            Position  => Node_Position (Node => Node),
            Id_Str    => Node_Lex_String (Node => Instantiation_Ident_Node));
      end if;

      -- ASSUME Constraint_Node = procedure_constraint
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => Constraint_Node) = SP_Symbols.procedure_constraint,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Constraint_Node = procedure_constraint in Process_Generic_Procedure_Instantiation");
   end Process_Generic_Procedure_Instantiation;

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

   procedure Process_Generic_Function_Instantiation
     (Node                     : in out STree.SyntaxNode;
      Scope                    : in     Dictionary.Scopes;
      Instantiation_Ident_Node :    out STree.SyntaxNode;
      Ok                       :    out Boolean)
   --# global in     CommandLineData.Content;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SPARK_IO.File_Sys;
   --# derives ErrorHandler.Error_Context,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table &
   --#         Instantiation_Ident_Node,
   --#         Node                       from Node,
   --#                                         STree.Table &
   --#         Ok                         from CommandLineData.Content,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.simple_name;
   --# post Syntax_Node_Type (Instantiation_Ident_Node, STree.Table) = SP_Symbols.identifier and
   --#   Syntax_Node_Type (Node, STree.Table) = SP_Symbols.function_constraint;
   is
   begin
      Instantiation_Ident_Node := Child_Node (Current_Node => Node);
      -- ASSUME Instantiation_Ident_Node = identifier
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => Instantiation_Ident_Node) = SP_Symbols.identifier,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Instantiation_Ident_Node = identifier in Process_Generic_Function_Instantiation");
      Check_Valid_Ident (Ident_Node    => Instantiation_Ident_Node,
                         Current_Scope => Scope,
                         Ok            => Ok);

      Node := Next_Sibling (Current_Node => Node);
      -- ASSUME Node = function_constraint
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => Node) = SP_Symbols.function_constraint,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Node = function_constraint in Process_Generic_Function_Instantiation");
   end Process_Generic_Function_Instantiation;

begin -- Wf_Generic_Subprogram_Instantiation
   Next_Node := Child_Node (Current_Node => Node);
   -- ASSUME Next_Node = overriding_indicator OR procedure_specification OR simple_name
   if Syntax_Node_Type (Node => Next_Node) = SP_Symbols.overriding_indicator then
      -- ASSUME Next_Node = overriding_indicator
      -- ASSUME Child_Node (Current_Node => Next_Node) = RWoverriding OR RWnot
      if Syntax_Node_Type (Node => Child_Node (Current_Node => Next_Node)) = SP_Symbols.RWoverriding then
         -- ASSUME Child_Node (Current_Node => Next_Node) = RWoverriding
         Is_Overriding := True;
      elsif Syntax_Node_Type (Node => Child_Node (Current_Node => Next_Node)) /= SP_Symbols.RWnot then
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Child_Node (Current_Node => Next_Node) = RWoverriding OR RWnot " &
              "in Wf_Generic_Subprogram_Instantiation");
      end if;
      Next_Node := Next_Sibling (Current_Node => Next_Node);
   elsif Syntax_Node_Type (Node => Next_Node) /= SP_Symbols.procedure_specification
     and then Syntax_Node_Type (Node => Next_Node) /= SP_Symbols.simple_name then
      SystemErrors.Fatal_Error
        (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Next_Node = overriding_indicator OR procedure_specification OR simple_name " &
           "in Wf_Generic_Subprogram_Instantiation");
   end if;
   -- ASSUME Next_Node = procedure_specification OR simple_name
   if Syntax_Node_Type (Node => Next_Node) = SP_Symbols.procedure_specification then
      -- ASSUME Next_Node = procedure_specification
      Process_Generic_Procedure_Instantiation
        (Node                     => Next_Node,
         Scope                    => Scope,
         Instantiation_Ident_Node => Instantiation_Ident_Node,
         Constraint_Node          => Constraint_Node,
         Ok                       => Ok);
      Kind_Of_Generic := Generic_Procedure;
   elsif Syntax_Node_Type (Node => Next_Node) = SP_Symbols.simple_name then
      -- ASSUME Next_Node = simple_name
      Process_Generic_Function_Instantiation
        (Node                     => Next_Node,
         Scope                    => Scope,
         Instantiation_Ident_Node => Instantiation_Ident_Node,
         Ok                       => Ok);
      Constraint_Node := Next_Node;
      Kind_Of_Generic := Generic_Function;
   else
      Instantiation_Ident_Node := STree.NullNode;
      Constraint_Node          := STree.NullNode;
      Ok                       := False;
      Kind_Of_Generic          := Generic_Function;
      SystemErrors.Fatal_Error
        (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Next_Node = procedure_specification OR simple_name in Wf_Generic_Subprogram_Instantiation");
   end if;

   Next_Node := Next_Sibling (Current_Node => Next_Node);
   -- ASSUME Next_Node = dotted_simple_name
   SystemErrors.RT_Assert
     (C       => Syntax_Node_Type (Node => Next_Node) = SP_Symbols.dotted_simple_name,
      Sys_Err => SystemErrors.Invalid_Syntax_Tree,
      Msg     => "Expect Next_Node = dotted_simple_name in Wf_Generic_Subprogram_Instantiation");

   if Ok then
      Check_Generic (Ident_Node  => Next_Node,
                     Scope       => Scope,
                     Kind        => Kind_Of_Generic,
                     Generic_Sym => Generic_Sym);
      if not Dictionary.Is_Null_Symbol (Generic_Sym) then
         -- add the instantiation
         Dictionary.AddSubprogramInstantiation
           (Name          => Node_Lex_String (Node => Instantiation_Ident_Node),
            Comp_Unit     => ContextManager.Ops.Current_Unit,
            Declaration   => Dictionary.Location'(Start_Position => Node_Position (Node => Instantiation_Ident_Node),
                                                  End_Position   => Node_Position (Node => Instantiation_Ident_Node)),
            TheGeneric    => Generic_Sym,
            Specification => Dictionary.Location'(Start_Position => Node_Position (Node => Node),
                                                  End_Position   => Node_Position (Node => Node)),
            Scope         => Scope,
            Context       => Dictionary.ProgramContext,
            Subprogram    => Instantiation_Sym);
         STree.Add_Node_Symbol (Node => Instantiation_Ident_Node,
                                Sym  => Instantiation_Sym);
         Next_Node := Next_Sibling (Current_Node => Next_Node);
         -- ASSUME Next_Node = generic_actual_part
         SystemErrors.RT_Assert
           (C       => Syntax_Node_Type (Node => Next_Node) = SP_Symbols.generic_actual_part,
            Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Next_Node = generic_actual_part in Wf_Generic_Subprogram_Instantiation");

         -- check parameters etc.
         Wf_Generic_Actual_Part
           (Actual_Part_Node  => Next_Node,
            Instantiation_Sym => Instantiation_Sym,
            Scope             => Scope,
            Component_Data    => Component_Data,
            The_Heap          => The_Heap,
            Error_Found       => Errors_Found);

         if Errors_Found then
            Dictionary.SetSubprogramSignatureNotWellformed (Dictionary.IsAbstract, Instantiation_Sym);
         else
            -- do formal/actual substitutions
            Dictionary.InstantiateSubprogramParameters
              (ActualSubprogramSym => Instantiation_Sym,
               Comp_Unit           => ContextManager.Ops.Current_Unit,
               Declaration         => Dictionary.Location'(Start_Position => Node_Position (Node => Instantiation_Ident_Node),
                                                           End_Position   => Node_Position (Node => Instantiation_Ident_Node)));

            Check_No_Overloading_From_Tagged_Ops
              (Ident_Node    => Instantiation_Ident_Node,
               Subprog_Sym   => Instantiation_Sym,
               Scope         => Scope,
               Abstraction   => Dictionary.IsRefined,
               Is_Overriding => Is_Overriding);

            Wf_Subprogram_Constraint
              (Node           => Constraint_Node,
               Subprogram_Sym => Instantiation_Sym,
               First_Seen     => True,
               Component_Data => Component_Data,
               The_Heap       => The_Heap);
         end if;
      end if;
   end if;
end Wf_Generic_Subprogram_Instantiation;
