]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ada: Preliminary implementation of structural generic instantiation
authorEric Botcazou <ebotcazou@adacore.com>
Fri, 4 Apr 2025 23:00:34 +0000 (01:00 +0200)
committerMarc Poulhiès <dkm@gcc.gnu.org>
Fri, 19 Sep 2025 09:26:11 +0000 (11:26 +0200)
It contains the changes to the parser required for the new syntax, as well
as the mechanism to instantiate generics implicitly.  The implementation is
strictly structural, in the sense that if the implicit instantiation cannot
be made structural for semantic dependence reasons, then it is rejected.

gcc/ada/ChangeLog:

* doc/gnat_rm/gnat_language_extensions.rst (Structural Generic
Instantiation): New entry
* einfo.ads (Is_Link_Once): New flag defined in entities.
* sinfo.ads (Is_Structural): New flag defined in instantiations.
* gen_il-fields.ads (Opt_Field_Enum): Add Is_Link_Once and
Is_Structural.
* gen_il-gen-gen_entities.adb (Entity_Kind): Add Is_Link_Once
semantic flag.
* gen_il-gen-gen_nodes.adb (N_Generic_Instantiation): Move up
Parent_Spec field and add Is_Structural semantic flag.
* frontend.adb: Add with clause for Sem_Ch12.
(Frontend): After analysis is complete and bodies are instantiated,
call Sem_Ch12.Mark_Link_Once on the declarations of the main unit.
* par.adb (P_Qualified_Simple_Name): Delete.
(P_Qualified_Simple_Name_Resync): Likewise
(P_Exception_Name): New function declaration.
(P_Label_Name): Likewise.
(P_Loop_Name): Likewise.
(P_Generic_Unit_Name): Likewise.
(P_Library_Unit_Name): Likewise.
(P_Package_Name): Likewise.
(P_Parent_Unit_Name): Likewise.
(P_Subtype_Name): Likewise.
(P_Subtype_Name_Resync): Likewise.
* par-ch3.adb (P_Subtype_Mark_Resync): Replace call to
P_Qualified_Simple_Name_Resync by P_Subtype_Name_Resync.
(P_Identifier_Declarations): Replace call to
P_Qualified_Simple_Name_Resync by P_Exception_Name.
(P_Derived_Type_Def_Or_Private_Ext_Decl): Replace call to
P_Qualified_Simple_Name by P_Subtype_Name.
(P_Interface_Type_Definition): Replace calls to
P_Qualified_Simple_Name by P_Subtype_Name.
* par-ch4.adb (P_Reduction_Attribute_Reference): Move around and
change name of parameter.
(P_Name): Document new grammar rule and make a couple of tweaks.
(P_Exception_Name): New function.
(P_Label_Name): Likewise.
(P_Loop_Name): Likewise.
(P_Generic_Unit_Name): Likewise.
(P_Library_Unit_Name): Likewise.
(P_Package_Name): Likewise.
(P_Parent_Unit_Name): Likewise.
(P_Subtype_Name): Likewise.
(P_Subtype_Name_Resync): Likewise.
(P_Qualified_Simple_Name): Rename into...
(P_Simple_Name): ...this.
(P_Qualified_Simple_Name_Resync): Rename into...
(P_Simple_Name_Resync): ...this.  Accept left parenthesis and
dot as name extensions.
(P_Allocator): Replace call to P_Qualified_Simple_Name_Resync
by P_Subtype_Name_Resync.
* par-ch5.adb (P_Goto_Statement): Replace call to
P_Qualified_Simple_Name by P_Label_Name.
(Parse_Loop_Flow_Statement): Replace call to
P_Qualified_Simple_Name by P_Loop_Name.
* par-ch6.adb (P_Subprogram): Replace call to
P_Qualified_Simple_Name by P_Generic_Unit_Name.
* par-ch7.adb (P_Package): Replace calls to
P_Qualified_Simple_Name by P_Package_Name and P_Generic_Unit_Name.
* par-ch8.adb (P_Use_Package_Clause): Replace calls to
P_Qualified_Simple_Name by P_Package_Name.
* par-ch9.adb (P_Task): Replace call to
P_Qualified_Simple_Name by P_Subtype_Name.
(P_Protected): Likewise.
* par-ch10.adb (P_Context_Clause): Replace call to
P_Qualified_Simple_Name by P_Library_Unit_Name.
(P_Subunit): Replace call to P_Qualified_Simple_Name by
P_Parent_Unit_Name.
* par-ch12.adb (P_Generic): Replace call to
P_Qualified_Simple_Name by P_Generic_Unit_Name.
(P_Formal_Derived_Type_Definition): Replace call to
P_Qualified_Simple_Name by P_Subtype_Name.
(P_Formal_Package_Declaration): Replace call to
P_Qualified_Simple_Name by P_Generic_Unit_Name.
* sem_ch4.adb: Add with and use clauses for Sem_Ch12.
(Analyze_Call): Accept implicit instantiations with -gnatX0.
(Analyze_Indexed_Component_Form): Likewise.
* sem_ch8.adb (Analyze_Use_Package): Add guard before inserting
a with clause automatically when there is a use clause.
(Check_In_Previous_With_Clause): Retrieve original names.
(Check_Library_Unit_Renaming): Deal with structural instances.
(End_Use_Type): Minor tweak.
* sem_ch10.adb (Analyze_With_Clause): Remove useless test and
call Defining_Entity_Of_Instance.
* sem_ch12.ads (Build_Structural_Instantiation): New function.
(Mark_Link_Once): New procedure.
* sem_ch12.adb: Add with and use clauses for Exp_Dbug.
(Analyze_Associations): Add support for structural instantiations.
(Analyze_Package_Instantiation): Likewise.
(Analyze_Subprogram_Instantiation): Likewise.
(Analyze_Structural_Associations): New procedure.
(Need_Subprogram_Instance_Body): Return True for instantiation is
in the auxiliary declarations of the main unit.
(Build_Structural_Instantiation): New function.
(Mark_Link_Once): New procedure.
* sem_util.ads (Add_Local_Declaration): New procedure.
(Defining_Entity_Of_Instance): New function.
* sem_util.adb (Add_Local_Declaration): New procedure.
(Defining_Entity_Of_Instance): New function.
* gnat_rm.texi: Regenerate.
* gnat_ugn.texi: Regenerate.

26 files changed:
gcc/ada/doc/gnat_rm/gnat_language_extensions.rst
gcc/ada/einfo.ads
gcc/ada/frontend.adb
gcc/ada/gen_il-fields.ads
gcc/ada/gen_il-gen-gen_entities.adb
gcc/ada/gen_il-gen-gen_nodes.adb
gcc/ada/gnat_rm.texi
gcc/ada/gnat_ugn.texi
gcc/ada/par-ch10.adb
gcc/ada/par-ch12.adb
gcc/ada/par-ch3.adb
gcc/ada/par-ch4.adb
gcc/ada/par-ch5.adb
gcc/ada/par-ch6.adb
gcc/ada/par-ch7.adb
gcc/ada/par-ch8.adb
gcc/ada/par-ch9.adb
gcc/ada/par.adb
gcc/ada/sem_ch10.adb
gcc/ada/sem_ch12.adb
gcc/ada/sem_ch12.ads
gcc/ada/sem_ch4.adb
gcc/ada/sem_ch8.adb
gcc/ada/sem_util.adb
gcc/ada/sem_util.ads
gcc/ada/sinfo.ads

index b0cd5fbfc09d1e61c521552791b542613810fc0d..ed534d1d93e3ac8d52299ac87ce0fb3c1801aa75 100644 (file)
@@ -1884,3 +1884,157 @@ be private to the enclosing package. This is necessary due to the previously
 mentioned legality rule, to prevent breaking the privacy of the type when
 imposing that rule on outside types that derive from the private view of the
 type.
+
+Structural Generic Instantiation
+--------------------------------
+
+The compiler implements a second kind of generic instantiation, called
+"structural", alongside the traditional instantiation specified by the
+language, which is defined as follows: the structural instantiation of
+a generic unit on given actual parameters is the anonymous instantiation
+of the generic unit on the actual parameters done in the outermost scope
+where it would be legal to do an identical traditional instantiation.
+
+There is at most one structural instantiation of a generic unit on given
+actual parameters done in a partition.
+
+Structural generic instances (the product of structural instantiation)
+are implicitly created whenever a reference to them is made in a place
+where a name is accepted by the language.
+
+Syntax
+^^^^^^
+
+.. code-block:: text
+
+   name ::= { set of productions specified in the RM }
+            | structural_generic_instance_name
+
+   structural_generic_instance_name ::= name generic_actual_part
+
+Legality Rules
+^^^^^^^^^^^^^^
+
+The ``name`` in a ``structural_generic_instance_name`` shall denote a generic
+unit that is preelaborated. Note that, unlike in a traditional instantiation,
+there are no square brackets around the ``generic_actual_part`` in the second
+production, which means that it is mandatory and, therefore, that the generic
+unit shall have at least one generic formal parameter.
+
+The generic unit shall not take a generic formal object of mode ``in out``.
+If the generic unit takes a generic formal object of mode ``in``, then the
+corresponding generic actual parameter shall be a static expression.
+
+A ``structural_generic_instance_name`` shall not be present in a library
+unit if the structural instance is also a library unit and has a semantic
+dependence on the former.
+
+Static Semantics
+^^^^^^^^^^^^^^^^
+
+A ``structural_generic_instance_name`` denotes the instance that is the
+product of the structural instantiation of a generic unit on the specified
+actual parameters. This instance is unique to a partition.
+
+Example:
+
+.. code-block:: ada
+
+   with Ada.Containers.Vectors;
+
+   procedure P is
+      V : Ada.Containers.Vectors(Positive,Integer).Vector;
+
+   begin
+      V.Append (1);
+      V.Append (0);
+      Ada.Containers.Vectors(Positive,Integer).Generic_Sorting("<").Sort (V);
+   end;
+
+This procedure references two structural instantiations of two different generic
+units: ``Ada.Containers.Vectors(Positive,Integer)`` is the structural instance
+of the generic unit ``Ada.Containers.Vectors`` on ``Positive`` and ``Integer``
+and ``Ada.Containers.Vectors(Positive,Integer).Generic_Sorting("<")`` is the
+structural instance of the nested generic unit
+``Ada.Containers.Vectors(Positive,Integer).Generic_Sorting`` on ``"<"``.
+
+Note that the following example is illegal:
+
+.. code-block:: ada
+
+   with Ada.Containers.Vectors;
+
+   package Q is
+      type T is record
+         I : Integer;
+      end record;
+
+      V : Ada.Containers.Vectors(Positive,T).Vector;
+   end Q;
+
+The reason is that ``Ada.Containers.Vectors``, ``Positive`` and ``Q.T`` being
+library-level entities, the structural instance ``Ada.Containers.Vectors(Positive,T)`` is a library unit with a dependence
+on ``Q`` and, therefore, cannot be referenced from within ``Q``. The simple
+way out is to declare a traditional instantiation in this case:
+
+.. code-block:: ada
+
+   with Ada.Containers.Vectors;
+
+   package Q is
+      type T is record
+         I : Integer;
+      end record;
+
+      package Vectors_Of_T is new Ada.Containers.Vectors(Positive,T);
+
+      V : Vectors_Of_T.Vector;
+   end Q;
+
+But the following example is legal:
+
+.. code-block:: ada
+
+   with Ada.Containers.Vectors;
+
+   procedure P is
+      type T is record
+         I : Integer;
+      end record;
+
+      V : Ada.Containers.Vectors(Positive,T).Vector;
+   end;
+
+because the structural instance ``Ada.Containers.Vectors(Positive,T)`` is
+not a library unit.
+
+The first example can be rewritten in a less verbose manner:
+
+.. code-block:: ada
+
+   with Ada.Containers.Vectors; use Ada.Containers.Vectors(Positive,Integer);
+
+   procedure P is
+      V : Vector;
+
+   begin
+      V.Append (1);
+      V.Append (0);
+      Generic_Sorting("<").Sort (V);
+   end;
+
+Another example, which additionally uses the inference of dependent types:
+
+.. code-block:: ada
+
+   with Ada.Unchecked_Deallocation;
+
+   procedure P is
+
+      type Integer_Access is access all Integer;
+
+      A : Integer_Access := new Integer'(1);
+
+   begin
+      Ada.Unchecked_Deallocation(Name => Integer_Access) (A);
+   end;
index 669696d4bbb9e6f583b81b60ca0d97cdaf06cbc2..b5d9c1cde66659193dac66c711ea0eca0d682a02 100644 (file)
@@ -3024,6 +3024,13 @@ package Einfo is
 --       record is declared to be limited. Note that this flag is not set
 --       simply because some components of the record are limited.
 
+--    Is_Link_Once
+--       Defined in all entities. Set to indicate that an entity can be defined
+--       in multiple compilation units without generating a linker error. The
+--       compiler guarantees that the multiple definitions are equivalent and,
+--       therefore, that the linker can freely pick one of them. If this flag
+--       is set on an entity, then the Is_Public flag is also set on it.
+
 --    Is_Local_Anonymous_Access
 --       Defined in access types. Set for an anonymous access type to indicate
 --       that the type is created for a record component with an access
@@ -4990,6 +4997,7 @@ package Einfo is
    --    Is_Known_Valid
    --    Is_Limited_Composite
    --    Is_Limited_Record
+   --    Is_Link_Once
    --    Is_Loop_Parameter
    --    Is_Obsolescent
    --    Is_Package_Body_Entity
index 92bc3c6029ce934d878deea111240885bb20a44f..bb700a9a422ccbbda93b49e16101f0f3eb48aef2 100644 (file)
@@ -56,6 +56,7 @@ with Scn;            use Scn;
 with Sem;            use Sem;
 with Sem_Aux;
 with Sem_Ch8;
+with Sem_Ch12;
 with Sem_SCIL;
 with Sem_Elab;       use Sem_Elab;
 with Sem_Prag;       use Sem_Prag;
@@ -432,6 +433,18 @@ begin
                   Analyze_Inlined_Bodies;
                end if;
 
+               --  Mark the structural instances spawned by the main unit as
+               --  Link Once because other units may spawn them too.
+
+               Sem_Ch12.Mark_Link_Once
+                 (Declarations (Aux_Decls_Node (Cunit (Main_Unit))));
+
+               if Nkind (Unit (Cunit (Main_Unit))) = N_Package_Body then
+                  Sem_Ch12.Mark_Link_Once
+                    (Declarations
+                      (Aux_Decls_Node (Spec_Lib_Unit (Cunit (Main_Unit)))));
+               end if;
+
                --  Remove entities from program that do not have any execution
                --  time references.
 
index 6ff9866e64311e410cd0c4feb4a61f9b386678ce..6cd1355d11926899627db582eba4014030b80e71 100644 (file)
@@ -282,6 +282,7 @@ package Gen_IL.Fields is
       Is_SPARK_Mode_On_Node,
       Is_Static_Coextension,
       Is_Static_Expression,
+      Is_Structural,
       Is_Subprogram_Descriptor,
       Is_Task_Allocation_Block,
       Is_Task_Body_Procedure,
@@ -763,6 +764,7 @@ package Gen_IL.Fields is
       Is_Limited_Composite,
       Is_Limited_Interface,
       Is_Limited_Record,
+      Is_Link_Once,
       Is_Local_Anonymous_Access,
       Is_Loop_Parameter,
       Is_Machine_Code_Subprogram,
index 476e69d22cc040412631df861d1deb6ec5ed2f59..bd091cbe823f54d9cbc5c85cf7e03c735fbc7532 100644 (file)
@@ -175,6 +175,7 @@ begin -- Gen_IL.Gen.Gen_Entities
         Sm (Is_Limited_Composite, Flag),
         Sm (Is_Limited_Interface, Flag),
         Sm (Is_Limited_Record, Flag),
+        Sm (Is_Link_Once, Flag),
         Sm (Is_Loop_Parameter, Flag),
         Sm (Is_Obsolescent, Flag),
         Sm (Is_Package_Body_Entity, Flag),
index 0acc1849ba9338d63afe14de6065970c95bbe53a..9ce2511a5617f743236c88b3bf371a1fa0bfc6ce 100644 (file)
@@ -687,13 +687,14 @@ begin -- Gen_IL.Gen.Gen_Nodes
        (Sy (Defining_Unit_Name, Node_Id),
         Sy (Name, Node_Id, Default_Empty),
         Sy (Generic_Associations, List_Id, Default_No_List),
+        Sm (Parent_Spec, Node_Id),
         Sm (Instance_Spec, Node_Id),
         Sm (Is_Declaration_Level_Node, Flag),
         Sm (Is_Elaboration_Checks_OK_Node, Flag),
         Sm (Is_Elaboration_Warnings_OK_Node, Flag),
         Sm (Is_Known_Guaranteed_ABE, Flag),
         Sm (Is_SPARK_Mode_On_Node, Flag),
-        Sm (Parent_Spec, Node_Id)));
+        Sm (Is_Structural, Flag)));
 
    Ab (N_Subprogram_Instantiation, N_Generic_Instantiation,
        (Sy (Must_Override, Flag),
index 5b831377b5e9f29e882db472a563a73b2aed57ff..28e278c7aed797ba1115b7d4c6cd39ec3a81c9bd 100644 (file)
@@ -19,7 +19,7 @@
 
 @copying
 @quotation
-GNAT Reference Manual , Sep 12, 2025
+GNAT Reference Manual , Sep 19, 2025
 
 AdaCore
 
@@ -940,6 +940,7 @@ Experimental Language Extensions
 * Finally construct:: 
 * Continue statement:: 
 * Destructors:: 
+* Structural Generic Instantiation:: 
 
 Storage Model
 
@@ -959,6 +960,12 @@ Finally construct
 * Legality Rules: Legality Rules<2>. 
 * Dynamic Semantics: Dynamic Semantics<2>. 
 
+Structural Generic Instantiation
+
+* Syntax: Syntax<3>. 
+* Legality Rules: Legality Rules<3>. 
+* Static Semantics:: 
+
 Security Hardening Features
 
 * Register Scrubbing:: 
@@ -31440,6 +31447,7 @@ Features activated via @code{-gnatX0} or
 * Finally construct:: 
 * Continue statement:: 
 * Destructors:: 
+* Structural Generic Instantiation:: 
 
 @end menu
 
@@ -32648,7 +32656,7 @@ statement in the sequence of statements of the specified loop_statement.
 Note that @code{continue} is a keyword but it is not a reserved word. This is a
 configuration that does not exist in standard Ada.
 
-@node Destructors,,Continue statement,Experimental Language Extensions
+@node Destructors,Structural Generic Instantiation,Continue statement,Experimental Language Extensions
 @anchor{gnat_rm/gnat_language_extensions destructors}@anchor{476}
 @subsection Destructors
 
@@ -32718,8 +32726,177 @@ mentioned legality rule, to prevent breaking the privacy of the type when
 imposing that rule on outside types that derive from the private view of the
 type.
 
+@node Structural Generic Instantiation,,Destructors,Experimental Language Extensions
+@anchor{gnat_rm/gnat_language_extensions structural-generic-instantiation}@anchor{477}
+@subsection Structural Generic Instantiation
+
+
+The compiler implements a second kind of generic instantiation, called
+“structural”, alongside the traditional instantiation specified by the
+language, which is defined as follows: the structural instantiation of
+a generic unit on given actual parameters is the anonymous instantiation
+of the generic unit on the actual parameters done in the outermost scope
+where it would be legal to do an identical traditional instantiation.
+
+There is at most one structural instantiation of a generic unit on given
+actual parameters done in a partition.
+
+Structural generic instances (the product of structural instantiation)
+are implicitly created whenever a reference to them is made in a place
+where a name is accepted by the language.
+
+@menu
+* Syntax: Syntax<3>. 
+* Legality Rules: Legality Rules<3>. 
+* Static Semantics:: 
+
+@end menu
+
+@node Syntax<3>,Legality Rules<3>,,Structural Generic Instantiation
+@anchor{gnat_rm/gnat_language_extensions id7}@anchor{478}
+@subsubsection Syntax
+
+
+@example
+name ::= @{ set of productions specified in the RM @}
+         | structural_generic_instance_name
+
+structural_generic_instance_name ::= name generic_actual_part
+@end example
+
+@node Legality Rules<3>,Static Semantics,Syntax<3>,Structural Generic Instantiation
+@anchor{gnat_rm/gnat_language_extensions id8}@anchor{479}
+@subsubsection Legality Rules
+
+
+The @code{name} in a @code{structural_generic_instance_name} shall denote a generic
+unit that is preelaborated. Note that, unlike in a traditional instantiation,
+there are no square brackets around the @code{generic_actual_part} in the second
+production, which means that it is mandatory and, therefore, that the generic
+unit shall have at least one generic formal parameter.
+
+The generic unit shall not take a generic formal object of mode @code{in out}.
+If the generic unit takes a generic formal object of mode @code{in}, then the
+corresponding generic actual parameter shall be a static expression.
+
+A @code{structural_generic_instance_name} shall not be present in a library
+unit if the structural instance is also a library unit and has a semantic
+dependence on the former.
+
+@node Static Semantics,,Legality Rules<3>,Structural Generic Instantiation
+@anchor{gnat_rm/gnat_language_extensions static-semantics}@anchor{47a}
+@subsubsection Static Semantics
+
+
+A @code{structural_generic_instance_name} denotes the instance that is the
+product of the structural instantiation of a generic unit on the specified
+actual parameters. This instance is unique to a partition.
+
+Example:
+
+@example
+with Ada.Containers.Vectors;
+
+procedure P is
+   V : Ada.Containers.Vectors(Positive,Integer).Vector;
+
+begin
+   V.Append (1);
+   V.Append (0);
+   Ada.Containers.Vectors(Positive,Integer).Generic_Sorting("<").Sort (V);
+end;
+@end example
+
+This procedure references two structural instantiations of two different generic
+units: @code{Ada.Containers.Vectors(Positive,Integer)} is the structural instance
+of the generic unit @code{Ada.Containers.Vectors} on @code{Positive} and @code{Integer}
+and @code{Ada.Containers.Vectors(Positive,Integer).Generic_Sorting("<")} is the
+structural instance of the nested generic unit
+@code{Ada.Containers.Vectors(Positive,Integer).Generic_Sorting} on @code{"<"}.
+
+Note that the following example is illegal:
+
+@example
+with Ada.Containers.Vectors;
+
+package Q is
+   type T is record
+      I : Integer;
+   end record;
+
+   V : Ada.Containers.Vectors(Positive,T).Vector;
+end Q;
+@end example
+
+The reason is that @code{Ada.Containers.Vectors}, @code{Positive} and @code{Q.T} being
+library-level entities, the structural instance @code{Ada.Containers.Vectors(Positive,T)} is a library unit with a dependence
+on @code{Q} and, therefore, cannot be referenced from within @code{Q}. The simple
+way out is to declare a traditional instantiation in this case:
+
+@example
+with Ada.Containers.Vectors;
+
+package Q is
+   type T is record
+      I : Integer;
+   end record;
+
+   package Vectors_Of_T is new Ada.Containers.Vectors(Positive,T);
+
+   V : Vectors_Of_T.Vector;
+end Q;
+@end example
+
+But the following example is legal:
+
+@example
+with Ada.Containers.Vectors;
+
+procedure P is
+   type T is record
+      I : Integer;
+   end record;
+
+   V : Ada.Containers.Vectors(Positive,T).Vector;
+end;
+@end example
+
+because the structural instance @code{Ada.Containers.Vectors(Positive,T)} is
+not a library unit.
+
+The first example can be rewritten in a less verbose manner:
+
+@example
+with Ada.Containers.Vectors; use Ada.Containers.Vectors(Positive,Integer);
+
+procedure P is
+   V : Vector;
+
+begin
+   V.Append (1);
+   V.Append (0);
+   Generic_Sorting("<").Sort (V);
+end;
+@end example
+
+Another example, which additionally uses the inference of dependent types:
+
+@example
+with Ada.Unchecked_Deallocation;
+
+procedure P is
+
+   type Integer_Access is access all Integer;
+
+   A : Integer_Access := new Integer'(1);
+
+begin
+   Ada.Unchecked_Deallocation(Name => Integer_Access) (A);
+end;
+@end example
+
 @node Security Hardening Features,Obsolescent Features,GNAT language extensions,Top
-@anchor{gnat_rm/security_hardening_features doc}@anchor{477}@anchor{gnat_rm/security_hardening_features id1}@anchor{478}@anchor{gnat_rm/security_hardening_features security-hardening-features}@anchor{15}
+@anchor{gnat_rm/security_hardening_features doc}@anchor{47b}@anchor{gnat_rm/security_hardening_features id1}@anchor{47c}@anchor{gnat_rm/security_hardening_features security-hardening-features}@anchor{15}
 @chapter Security Hardening Features
 
 
@@ -32743,7 +32920,7 @@ These features are supported only by the GCC back end, not by LLVM.
 @end menu
 
 @node Register Scrubbing,Stack Scrubbing,,Security Hardening Features
-@anchor{gnat_rm/security_hardening_features register-scrubbing}@anchor{479}
+@anchor{gnat_rm/security_hardening_features register-scrubbing}@anchor{47d}
 @section Register Scrubbing
 
 
@@ -32779,7 +32956,7 @@ programming languages, see @cite{Using the GNU Compiler Collection (GCC)}.
 @c Stack Scrubbing:
 
 @node Stack Scrubbing,Hardened Conditionals,Register Scrubbing,Security Hardening Features
-@anchor{gnat_rm/security_hardening_features stack-scrubbing}@anchor{47a}
+@anchor{gnat_rm/security_hardening_features stack-scrubbing}@anchor{47e}
 @section Stack Scrubbing
 
 
@@ -32923,7 +33100,7 @@ Bar_Callable_Ptr.
 @c Hardened Conditionals:
 
 @node Hardened Conditionals,Hardened Booleans,Stack Scrubbing,Security Hardening Features
-@anchor{gnat_rm/security_hardening_features hardened-conditionals}@anchor{47b}
+@anchor{gnat_rm/security_hardening_features hardened-conditionals}@anchor{47f}
 @section Hardened Conditionals
 
 
@@ -33013,7 +33190,7 @@ be used with other programming languages supported by GCC.
 @c Hardened Booleans:
 
 @node Hardened Booleans,Control Flow Redundancy,Hardened Conditionals,Security Hardening Features
-@anchor{gnat_rm/security_hardening_features hardened-booleans}@anchor{47c}
+@anchor{gnat_rm/security_hardening_features hardened-booleans}@anchor{480}
 @section Hardened Booleans
 
 
@@ -33074,7 +33251,7 @@ and more details on that attribute, see @cite{Using the GNU Compiler Collection
 @c Control Flow Redundancy:
 
 @node Control Flow Redundancy,,Hardened Booleans,Security Hardening Features
-@anchor{gnat_rm/security_hardening_features control-flow-redundancy}@anchor{47d}
+@anchor{gnat_rm/security_hardening_features control-flow-redundancy}@anchor{481}
 @section Control Flow Redundancy
 
 
@@ -33242,7 +33419,7 @@ see @cite{Using the GNU Compiler Collection (GCC)}.  These options
 can be used with other programming languages supported by GCC.
 
 @node Obsolescent Features,Compatibility and Porting Guide,Security Hardening Features,Top
-@anchor{gnat_rm/obsolescent_features doc}@anchor{47e}@anchor{gnat_rm/obsolescent_features id1}@anchor{47f}@anchor{gnat_rm/obsolescent_features obsolescent-features}@anchor{16}
+@anchor{gnat_rm/obsolescent_features doc}@anchor{482}@anchor{gnat_rm/obsolescent_features id1}@anchor{483}@anchor{gnat_rm/obsolescent_features obsolescent-features}@anchor{16}
 @chapter Obsolescent Features
 
 
@@ -33261,7 +33438,7 @@ compatibility purposes.
 @end menu
 
 @node pragma No_Run_Time,pragma Ravenscar,,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features id2}@anchor{480}@anchor{gnat_rm/obsolescent_features pragma-no-run-time}@anchor{481}
+@anchor{gnat_rm/obsolescent_features id2}@anchor{484}@anchor{gnat_rm/obsolescent_features pragma-no-run-time}@anchor{485}
 @section pragma No_Run_Time
 
 
@@ -33274,7 +33451,7 @@ preferred usage is to use an appropriately configured run-time that
 includes just those features that are to be made accessible.
 
 @node pragma Ravenscar,pragma Restricted_Run_Time,pragma No_Run_Time,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features id3}@anchor{482}@anchor{gnat_rm/obsolescent_features pragma-ravenscar}@anchor{483}
+@anchor{gnat_rm/obsolescent_features id3}@anchor{486}@anchor{gnat_rm/obsolescent_features pragma-ravenscar}@anchor{487}
 @section pragma Ravenscar
 
 
@@ -33283,7 +33460,7 @@ The pragma @code{Ravenscar} has exactly the same effect as pragma
 is part of the new Ada 2005 standard.
 
 @node pragma Restricted_Run_Time,pragma Task_Info,pragma Ravenscar,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features id4}@anchor{484}@anchor{gnat_rm/obsolescent_features pragma-restricted-run-time}@anchor{485}
+@anchor{gnat_rm/obsolescent_features id4}@anchor{488}@anchor{gnat_rm/obsolescent_features pragma-restricted-run-time}@anchor{489}
 @section pragma Restricted_Run_Time
 
 
@@ -33293,7 +33470,7 @@ preferred since the Ada 2005 pragma @code{Profile} is intended for
 this kind of implementation dependent addition.
 
 @node pragma Task_Info,package System Task_Info s-tasinf ads,pragma Restricted_Run_Time,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features id5}@anchor{486}@anchor{gnat_rm/obsolescent_features pragma-task-info}@anchor{487}
+@anchor{gnat_rm/obsolescent_features id5}@anchor{48a}@anchor{gnat_rm/obsolescent_features pragma-task-info}@anchor{48b}
 @section pragma Task_Info
 
 
@@ -33319,7 +33496,7 @@ in the spec of package System.Task_Info in the runtime
 library.
 
 @node package System Task_Info s-tasinf ads,,pragma Task_Info,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features package-system-task-info}@anchor{488}@anchor{gnat_rm/obsolescent_features package-system-task-info-s-tasinf-ads}@anchor{489}
+@anchor{gnat_rm/obsolescent_features package-system-task-info}@anchor{48c}@anchor{gnat_rm/obsolescent_features package-system-task-info-s-tasinf-ads}@anchor{48d}
 @section package System.Task_Info (@code{s-tasinf.ads})
 
 
@@ -33329,7 +33506,7 @@ to support the @code{Task_Info} pragma. The predefined Ada package
 standard replacement for GNAT’s @code{Task_Info} functionality.
 
 @node Compatibility and Porting Guide,GNU Free Documentation License,Obsolescent Features,Top
-@anchor{gnat_rm/compatibility_and_porting_guide doc}@anchor{48a}@anchor{gnat_rm/compatibility_and_porting_guide compatibility-and-porting-guide}@anchor{17}@anchor{gnat_rm/compatibility_and_porting_guide id1}@anchor{48b}
+@anchor{gnat_rm/compatibility_and_porting_guide doc}@anchor{48e}@anchor{gnat_rm/compatibility_and_porting_guide compatibility-and-porting-guide}@anchor{17}@anchor{gnat_rm/compatibility_and_porting_guide id1}@anchor{48f}
 @chapter Compatibility and Porting Guide
 
 
@@ -33351,7 +33528,7 @@ applications developed in other Ada environments.
 @end menu
 
 @node Writing Portable Fixed-Point Declarations,Compatibility with Ada 83,,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide id2}@anchor{48c}@anchor{gnat_rm/compatibility_and_porting_guide writing-portable-fixed-point-declarations}@anchor{48d}
+@anchor{gnat_rm/compatibility_and_porting_guide id2}@anchor{490}@anchor{gnat_rm/compatibility_and_porting_guide writing-portable-fixed-point-declarations}@anchor{491}
 @section Writing Portable Fixed-Point Declarations
 
 
@@ -33473,7 +33650,7 @@ If you follow this scheme you will be guaranteed that your fixed-point
 types will be portable.
 
 @node Compatibility with Ada 83,Compatibility between Ada 95 and Ada 2005,Writing Portable Fixed-Point Declarations,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-ada-83}@anchor{48e}@anchor{gnat_rm/compatibility_and_porting_guide id3}@anchor{48f}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-ada-83}@anchor{492}@anchor{gnat_rm/compatibility_and_porting_guide id3}@anchor{493}
 @section Compatibility with Ada 83
 
 
@@ -33501,7 +33678,7 @@ following subsections treat the most likely issues to be encountered.
 @end menu
 
 @node Legal Ada 83 programs that are illegal in Ada 95,More deterministic semantics,,Compatibility with Ada 83
-@anchor{gnat_rm/compatibility_and_porting_guide id4}@anchor{490}@anchor{gnat_rm/compatibility_and_porting_guide legal-ada-83-programs-that-are-illegal-in-ada-95}@anchor{491}
+@anchor{gnat_rm/compatibility_and_porting_guide id4}@anchor{494}@anchor{gnat_rm/compatibility_and_porting_guide legal-ada-83-programs-that-are-illegal-in-ada-95}@anchor{495}
 @subsection Legal Ada 83 programs that are illegal in Ada 95
 
 
@@ -33601,7 +33778,7 @@ the fix is usually simply to add the @code{(<>)} to the generic declaration.
 @end itemize
 
 @node More deterministic semantics,Changed semantics,Legal Ada 83 programs that are illegal in Ada 95,Compatibility with Ada 83
-@anchor{gnat_rm/compatibility_and_porting_guide id5}@anchor{492}@anchor{gnat_rm/compatibility_and_porting_guide more-deterministic-semantics}@anchor{493}
+@anchor{gnat_rm/compatibility_and_porting_guide id5}@anchor{496}@anchor{gnat_rm/compatibility_and_porting_guide more-deterministic-semantics}@anchor{497}
 @subsection More deterministic semantics
 
 
@@ -33629,7 +33806,7 @@ which open select branches are executed.
 @end itemize
 
 @node Changed semantics,Other language compatibility issues,More deterministic semantics,Compatibility with Ada 83
-@anchor{gnat_rm/compatibility_and_porting_guide changed-semantics}@anchor{494}@anchor{gnat_rm/compatibility_and_porting_guide id6}@anchor{495}
+@anchor{gnat_rm/compatibility_and_porting_guide changed-semantics}@anchor{498}@anchor{gnat_rm/compatibility_and_porting_guide id6}@anchor{499}
 @subsection Changed semantics
 
 
@@ -33671,7 +33848,7 @@ covers only the restricted range.
 @end itemize
 
 @node Other language compatibility issues,,Changed semantics,Compatibility with Ada 83
-@anchor{gnat_rm/compatibility_and_porting_guide id7}@anchor{496}@anchor{gnat_rm/compatibility_and_porting_guide other-language-compatibility-issues}@anchor{497}
+@anchor{gnat_rm/compatibility_and_porting_guide id7}@anchor{49a}@anchor{gnat_rm/compatibility_and_porting_guide other-language-compatibility-issues}@anchor{49b}
 @subsection Other language compatibility issues
 
 
@@ -33704,7 +33881,7 @@ include @code{pragma Interface} and the floating point type attributes
 @end itemize
 
 @node Compatibility between Ada 95 and Ada 2005,Implementation-dependent characteristics,Compatibility with Ada 83,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide compatibility-between-ada-95-and-ada-2005}@anchor{498}@anchor{gnat_rm/compatibility_and_porting_guide id8}@anchor{499}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-between-ada-95-and-ada-2005}@anchor{49c}@anchor{gnat_rm/compatibility_and_porting_guide id8}@anchor{49d}
 @section Compatibility between Ada 95 and Ada 2005
 
 
@@ -33776,7 +33953,7 @@ can declare a function returning a value from an anonymous access type.
 @end itemize
 
 @node Implementation-dependent characteristics,Compatibility with Other Ada Systems,Compatibility between Ada 95 and Ada 2005,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide id9}@anchor{49a}@anchor{gnat_rm/compatibility_and_porting_guide implementation-dependent-characteristics}@anchor{49b}
+@anchor{gnat_rm/compatibility_and_porting_guide id9}@anchor{49e}@anchor{gnat_rm/compatibility_and_porting_guide implementation-dependent-characteristics}@anchor{49f}
 @section Implementation-dependent characteristics
 
 
@@ -33799,7 +33976,7 @@ transition from certain Ada 83 compilers.
 @end menu
 
 @node Implementation-defined pragmas,Implementation-defined attributes,,Implementation-dependent characteristics
-@anchor{gnat_rm/compatibility_and_porting_guide id10}@anchor{49c}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-pragmas}@anchor{49d}
+@anchor{gnat_rm/compatibility_and_porting_guide id10}@anchor{4a0}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-pragmas}@anchor{4a1}
 @subsection Implementation-defined pragmas
 
 
@@ -33821,7 +33998,7 @@ avoiding compiler rejection of units that contain such pragmas; they are not
 relevant in a GNAT context and hence are not otherwise implemented.
 
 @node Implementation-defined attributes,Libraries,Implementation-defined pragmas,Implementation-dependent characteristics
-@anchor{gnat_rm/compatibility_and_porting_guide id11}@anchor{49e}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-attributes}@anchor{49f}
+@anchor{gnat_rm/compatibility_and_porting_guide id11}@anchor{4a2}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-attributes}@anchor{4a3}
 @subsection Implementation-defined attributes
 
 
@@ -33835,7 +34012,7 @@ Ada 83, GNAT supplies the attributes @code{Bit}, @code{Machine_Size} and
 @code{Type_Class}.
 
 @node Libraries,Elaboration order,Implementation-defined attributes,Implementation-dependent characteristics
-@anchor{gnat_rm/compatibility_and_porting_guide id12}@anchor{4a0}@anchor{gnat_rm/compatibility_and_porting_guide libraries}@anchor{4a1}
+@anchor{gnat_rm/compatibility_and_porting_guide id12}@anchor{4a4}@anchor{gnat_rm/compatibility_and_porting_guide libraries}@anchor{4a5}
 @subsection Libraries
 
 
@@ -33864,7 +34041,7 @@ be preferable to retrofit the application using modular types.
 @end itemize
 
 @node Elaboration order,Target-specific aspects,Libraries,Implementation-dependent characteristics
-@anchor{gnat_rm/compatibility_and_porting_guide elaboration-order}@anchor{4a2}@anchor{gnat_rm/compatibility_and_porting_guide id13}@anchor{4a3}
+@anchor{gnat_rm/compatibility_and_porting_guide elaboration-order}@anchor{4a6}@anchor{gnat_rm/compatibility_and_porting_guide id13}@anchor{4a7}
 @subsection Elaboration order
 
 
@@ -33900,7 +34077,7 @@ pragmas either globally (as an effect of the `-gnatE' switch) or locally
 @end itemize
 
 @node Target-specific aspects,,Elaboration order,Implementation-dependent characteristics
-@anchor{gnat_rm/compatibility_and_porting_guide id14}@anchor{4a4}@anchor{gnat_rm/compatibility_and_porting_guide target-specific-aspects}@anchor{4a5}
+@anchor{gnat_rm/compatibility_and_porting_guide id14}@anchor{4a8}@anchor{gnat_rm/compatibility_and_porting_guide target-specific-aspects}@anchor{4a9}
 @subsection Target-specific aspects
 
 
@@ -33913,10 +34090,10 @@ on the robustness of the original design.  Moreover, Ada 95 (and thus
 Ada 2005, Ada 2012, and Ada 2022) are sometimes
 incompatible with typical Ada 83 compiler practices regarding implicit
 packing, the meaning of the Size attribute, and the size of access values.
-GNAT’s approach to these issues is described in @ref{4a6,,Representation Clauses}.
+GNAT’s approach to these issues is described in @ref{4aa,,Representation Clauses}.
 
 @node Compatibility with Other Ada Systems,Representation Clauses,Implementation-dependent characteristics,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-other-ada-systems}@anchor{4a7}@anchor{gnat_rm/compatibility_and_porting_guide id15}@anchor{4a8}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-other-ada-systems}@anchor{4ab}@anchor{gnat_rm/compatibility_and_porting_guide id15}@anchor{4ac}
 @section Compatibility with Other Ada Systems
 
 
@@ -33959,7 +34136,7 @@ far beyond this minimal set, as described in the next section.
 @end itemize
 
 @node Representation Clauses,Compatibility with HP Ada 83,Compatibility with Other Ada Systems,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide id16}@anchor{4a9}@anchor{gnat_rm/compatibility_and_porting_guide representation-clauses}@anchor{4a6}
+@anchor{gnat_rm/compatibility_and_porting_guide id16}@anchor{4ad}@anchor{gnat_rm/compatibility_and_porting_guide representation-clauses}@anchor{4aa}
 @section Representation Clauses
 
 
@@ -34052,7 +34229,7 @@ with thin pointers.
 @end itemize
 
 @node Compatibility with HP Ada 83,,Representation Clauses,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-hp-ada-83}@anchor{4aa}@anchor{gnat_rm/compatibility_and_porting_guide id17}@anchor{4ab}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-hp-ada-83}@anchor{4ae}@anchor{gnat_rm/compatibility_and_porting_guide id17}@anchor{4af}
 @section Compatibility with HP Ada 83
 
 
@@ -34082,7 +34259,7 @@ extension of package System.
 @end itemize
 
 @node GNU Free Documentation License,Index,Compatibility and Porting Guide,Top
-@anchor{share/gnu_free_documentation_license doc}@anchor{4ac}@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{4ad}
+@anchor{share/gnu_free_documentation_license doc}@anchor{4b0}@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{4b1}
 @chapter GNU Free Documentation License
 
 
index e0c2d2571f611ddb15f7bc3b785953785133ec25..e21652d5cad3aac9b7fc08b3afad7b22140764d7 100644 (file)
@@ -19,7 +19,7 @@
 
 @copying
 @quotation
-GNAT User's Guide for Native Platforms , Sep 12, 2025
+GNAT User's Guide for Native Platforms , Sep 19, 2025
 
 AdaCore
 
@@ -30295,8 +30295,8 @@ to permit their use in free software.
 
 @printindex ge
 
-@anchor{d2}@w{                              }
 @anchor{gnat_ugn/gnat_utility_programs switches-related-to-project-files}@w{                              }
+@anchor{d2}@w{                              }
 
 @c %**end of body
 @bye
index 37121dd5028b630c52e61c59fbfe3bf1fdd9d8dd..540339738130678029ab9f45cd1abc541d0736f7 100644 (file)
@@ -925,7 +925,7 @@ package body Ch10 is
                   --  then the compilation of the child unit itself is the
                   --  place where such an "error" should be caught.
 
-                  Set_Name (With_Node, P_Qualified_Simple_Name);
+                  Set_Name (With_Node, P_Library_Unit_Name);
                   if Name (With_Node) = Error then
                      Remove (With_Node);
                   end if;
@@ -1038,7 +1038,7 @@ package body Ch10 is
       Scan; -- past SEPARATE;
 
       U_Left_Paren;
-      Set_Name (Subunit_Node, P_Qualified_Simple_Name);
+      Set_Name (Subunit_Node, P_Parent_Unit_Name);
       U_Right_Paren;
 
       Ignore (Tok_Semicolon);
index 5fb6f8c987727afa6809c24e967cde3f0ae1a9a9..7bd449d0b72fb08e72ec14281061efd9edb6f654 100644 (file)
@@ -124,6 +124,8 @@ package body Ch12 is
             Check_Misspelling_Of (Tok_Renames);
 
             if Token = Tok_Renames then
+               Scan; -- past RENAMES
+
                if Ren_Token = Tok_Package then
                   Decl_Node := New_Node
                     (N_Generic_Package_Renaming_Declaration, Gen_Sloc);
@@ -137,10 +139,8 @@ package body Ch12 is
                     (N_Generic_Function_Renaming_Declaration, Gen_Sloc);
                end if;
 
-               Scan; -- past RENAMES
                Set_Defining_Unit_Name (Decl_Node, Def_Unit);
-               Set_Name (Decl_Node, P_Name);
-
+               Set_Name (Decl_Node, P_Generic_Unit_Name);
                P_Aspect_Specifications (Decl_Node, Semicolon => False);
                TF_Semicolon;
                return Decl_Node;
@@ -944,7 +944,7 @@ package body Ch12 is
          Set_Interface_List (Def_Node, New_List);
 
          loop
-            Append (P_Qualified_Simple_Name, Interface_List (Def_Node));
+            Append (P_Subtype_Name, Interface_List (Def_Node));
             exit when Token /= Tok_And;
             Scan; -- past AND
          end loop;
@@ -1285,7 +1285,7 @@ package body Ch12 is
       Set_Defining_Identifier (Def_Node, P_Defining_Identifier (C_Is));
       T_Is;
       T_New;
-      Set_Name (Def_Node, P_Qualified_Simple_Name);
+      Set_Name (Def_Node, P_Generic_Unit_Name);
 
       if Token = Tok_Left_Paren then
          Save_Scan_State (Scan_State); -- at the left paren
index a685812de60420cb79c6de43c4d4658fe11db36d..56c1b894c0df9ffc908d7684efb0a64a30118553 100644 (file)
@@ -1092,7 +1092,7 @@ package body Ch3 is
          return Error;
 
       else
-         Type_Node := P_Qualified_Simple_Name_Resync;
+         Type_Node := P_Subtype_Name_Resync;
 
          --  Check for a subtype mark attribute. The only valid possibilities
          --  are 'CLASS and 'BASE. Anything else is a definite error. We may
@@ -1704,7 +1704,7 @@ package body Ch3 is
                No_List;
                Decl_Node :=
                  New_Node (N_Exception_Renaming_Declaration, Ident_Sloc);
-               Set_Name (Decl_Node, P_Qualified_Simple_Name_Resync);
+               Set_Name (Decl_Node, P_Exception_Name);
                No_Constraint;
             else
                Decl_Node := New_Node (N_Exception_Declaration, Prev_Token_Ptr);
@@ -2054,7 +2054,7 @@ package body Ch3 is
          Set_Interface_List (Typedef_Node, New_List);
 
          loop
-            Append (P_Qualified_Simple_Name, Interface_List (Typedef_Node));
+            Append (P_Subtype_Name, Interface_List (Typedef_Node));
             exit when Token /= Tok_And;
             Scan; -- past AND
          end loop;
@@ -4177,7 +4177,7 @@ package body Ch3 is
 
          Set_Abstract_Present   (Typedef_Node);
          Set_Interface_Present  (Typedef_Node);
-         Set_Subtype_Indication (Typedef_Node, P_Qualified_Simple_Name);
+         Set_Subtype_Indication (Typedef_Node, P_Subtype_Name);
 
          Set_Record_Extension_Part (Typedef_Node,
            New_Node (N_Record_Definition, Token_Ptr));
@@ -4188,8 +4188,7 @@ package body Ch3 is
             Scan; -- past AND
 
             loop
-               Append (P_Qualified_Simple_Name,
-                       Interface_List (Typedef_Node));
+               Append (P_Subtype_Name, Interface_List (Typedef_Node));
                exit when Token /= Tok_And;
                Scan; -- past AND
             end loop;
index ebdc587f0e156dfc96d5bc86fccb6d16a0ce1030..351007787f15b0b667a84b04e0f741d1e446354a 100644 (file)
@@ -82,8 +82,6 @@ package body Ch4 is
    function P_Relation                              return Node_Id;
    function P_Term                                  return Node_Id;
    function P_Declare_Expression                    return Node_Id;
-   function P_Reduction_Attribute_Reference (S : Node_Id)
-      return Node_Id;
 
    function P_Binary_Adding_Operator                return Node_Kind;
    function P_Logical_Operator                      return Node_Kind;
@@ -91,6 +89,9 @@ package body Ch4 is
    function P_Relational_Operator                   return Node_Kind;
    function P_Unary_Adding_Operator                 return Node_Kind;
 
+   function P_Simple_Name        (Instance_OK : Boolean) return Node_Id;
+   function P_Simple_Name_Resync (Instance_OK : Boolean) return Node_Id;
+
    procedure Bad_Range_Attribute (Loc : Source_Ptr);
    --  Called to place complaint about bad range attribute at the given
    --  source location. Terminates by raising Error_Resync.
@@ -108,6 +109,10 @@ package body Ch4 is
    --  prefix. The current token is known to be an apostrophe and the
    --  following token is known to be RANGE.
 
+   function P_Reduction_Attribute_Reference (Pref : Node_Id) return Node_Id;
+   --  Scan a reduction attribute reference. The caller has scanned out the
+   --  prefix. The current token is known to be an identifier.
+
    function P_Case_Expression return Node_Id;
    --  Scans out a case expression. Called with Token pointing to the CASE
    --  keyword, and returns pointing to the terminating right parent,
@@ -152,9 +157,10 @@ package body Ch4 is
    --  NAME ::=
    --    DIRECT_NAME        | EXPLICIT_DEREFERENCE
    --  | INDEXED_COMPONENT  | SLICE
-   --  | SELECTED_COMPONENT | ATTRIBUTE
+   --  | SELECTED_COMPONENT | ATTRIBUTE_REFERENCE
    --  | TYPE_CONVERSION    | FUNCTION_CALL
    --  | CHARACTER_LITERAL  | TARGET_NAME
+   --  | STRUCTURAL_GENERIC_INSTANCE_NAME
 
    --  DIRECT_NAME ::= IDENTIFIER | OPERATOR_SYMBOL
 
@@ -192,6 +198,8 @@ package body Ch4 is
 
    --  TARGET_NAME ::= @   (AI12-0125-3: abbreviation for LHS)
 
+   --  STRUCTURAL_GENERIC_INSTANCE_NAME ::= NAME GENERIC_ACTUAL_PART
+
    --  Note: syntactically a procedure call looks just like a function call,
    --  so this routine is in practice used to scan out procedure calls as well.
 
@@ -683,6 +691,7 @@ package body Ch4 is
 
       --      If there is at least one occurrence of identifier => (but
       --      none of the other cases apply), then we have a call.
+      --      This case is handled by LP_State_Call.
 
       --  Test for Id => case
 
@@ -902,8 +911,7 @@ package body Ch4 is
       --  have seen at least one named parameter already.
 
       Error_Msg_SC
-         ("positional parameter association " &
-           "not allowed after named one");
+        ("positional parameter association not allowed after named one");
 
       Error_Loc := Token_Ptr;
 
@@ -929,79 +937,290 @@ package body Ch4 is
 
    end P_Name;
 
+   --  These functions parse a restricted form of Names which are either
+   --  designators or structural generic instance names, and are preceded,
+   --  or not, by a sequence of prefixes that are either direct names or
+   --  structural generic instance names.
+
+   --  Error recovery: can raise Error_Resync
+
+   function P_Exception_Name return Node_Id is
+   begin
+      return P_Simple_Name_Resync (Instance_OK => False);
+   end P_Exception_Name;
+
+   function P_Label_Name return Node_Id is
+   begin
+      return P_Simple_Name_Resync (Instance_OK => False);
+   end P_Label_Name;
+
+   function P_Loop_Name return Node_Id is
+   begin
+      return P_Simple_Name_Resync (Instance_OK => False);
+   end P_Loop_Name;
+
+   function P_Subtype_Name_Resync return Node_Id is
+   begin
+      return P_Simple_Name_Resync (Instance_OK => False);
+   end P_Subtype_Name_Resync;
+
+   --  Error recovery: cannot raise Error_Resync
+
+   function P_Generic_Unit_Name return Node_Id is
+   begin
+      return P_Simple_Name (Instance_OK => False);
+   end P_Generic_Unit_Name;
+
+   function P_Library_Unit_Name return Node_Id is
+   begin
+      return P_Simple_Name (Instance_OK => False);
+   end P_Library_Unit_Name;
+
+   function P_Package_Name return Node_Id is
+   begin
+      return P_Simple_Name (Instance_OK => True);
+   end P_Package_Name;
+
+   function P_Parent_Unit_Name return Node_Id is
+   begin
+      return P_Simple_Name (Instance_OK => False);
+   end P_Parent_Unit_Name;
+
+   function P_Subtype_Name return Node_Id is
+   begin
+      return P_Simple_Name (Instance_OK => False);
+   end P_Subtype_Name;
+
    --  This function parses a restricted form of Names which are either
-   --  designators, or designators preceded by a sequence of prefixes
-   --  that are direct names.
+   --  designators or structural generic instance names, and are preceded,
+   --  or not, by a sequence of prefixes that are either direct names or
+   --  structural generic instance names.
+
+   --  If Instance_OK is False, the simple name cannot be a structural
+   --  generic instance name, preceded or not by prefixes (Instance_OK
+   --  has no effects on the accepted prefixes, if any).
 
    --  Error recovery: cannot raise Error_Resync
 
-   function P_Qualified_Simple_Name return Node_Id is
+   function P_Simple_Name (Instance_OK : Boolean) return Node_Id is
    begin
-      return P_Qualified_Simple_Name_Resync;
+      return P_Simple_Name_Resync (Instance_OK);
    exception
       when Error_Resync =>
          return Error;
-   end P_Qualified_Simple_Name;
+   end P_Simple_Name;
 
-   --  This procedure differs from P_Qualified_Simple_Name only in that it
-   --  raises Error_Resync if any error is encountered. It only returns after
-   --  scanning a valid qualified simple name.
+   --  This procedure differs from P_Simple_Name only in that it raises
+   --  Error_Resync if any error is encountered. It only returns after
+   --  scanning a valid simple name.
 
    --  Error recovery: can raise Error_Resync
 
-   function P_Qualified_Simple_Name_Resync return Node_Id is
-      Designator_Node : Node_Id;
-      Prefix_Node     : Node_Id;
-      Selector_Node   : Node_Id;
-      Dot_Sloc        : Source_Ptr := No_Location;
+   function P_Simple_Name_Resync (Instance_OK : Boolean) return Node_Id is
+      Arg_Node      : Node_Id;
+      Ident_Node    : Node_Id;
+      Name_Node     : Node_Id;
+      Prefix_Node   : Node_Id;
+      Scan_State_Id : Saved_Scan_State;
+      Scan_State_LP : Saved_Scan_State;
+
+      Arg_List  : List_Id := No_List; -- kill junk warning
 
    begin
-      --  Prefix_Node is set to the gathered prefix so far, Empty means that
-      --  no prefix has been scanned. This allows us to build up the result
-      --  in the required right recursive manner.
+      --  Case of not a designator
 
-      Prefix_Node := Empty;
+      if Token not in Token_Class_Desig then
+         Discard_Junk_Node (P_Identifier); -- to issue the error message
+         raise Error_Resync;
+      end if;
 
-      --  Loop through prefixes
+      Name_Node := Token_Node;
 
-      loop
-         Designator_Node := Token_Node;
+      Scan; -- past designator
 
-         if Token not in Token_Class_Desig then
-            Discard_Junk_Node (P_Identifier); -- to issue the error message
-            raise Error_Resync;
+      --  Loop scanning past name extensions. A label is used for control
+      --  transfer for this loop for ease of interfacing with the finite state
+      --  machine in the parenthesis scanning circuit, and also to allow for
+      --  passing in control to the appropriate point from the above code.
 
-         else
-            Scan; -- past designator
-            exit when Token /= Tok_Dot;
-         end if;
+      <<Scan_Name_Extension>>
+
+      case Token is
+         when Tok_Left_Paren =>
+            Save_Scan_State (Scan_State_LP); -- at left paren
+            Scan; -- past left paren
+            Arg_List := New_List;
+            goto Scan_Name_Extension_Left_Paren;
+
+         when Tok_Dot =>
+            Scan; -- past dot
+            goto Scan_Name_Extension_Dot;
+
+         when others =>
+            return Name_Node;
+      end case;
+
+      --  Case of name extended by dot (selection), dot is already skipped
+      --  and the scan state at the point of the dot is saved in Scan_State.
+
+      <<Scan_Name_Extension_Dot>>
+
+      if Token in Token_Class_Desig then
+         Prefix_Node := Name_Node;
+         Name_Node := New_Node (N_Selected_Component, Prev_Token_Ptr);
+         Set_Prefix (Name_Node, Prefix_Node);
+         Set_Selector_Name (Name_Node, Token_Node);
+         Scan; -- past selector
+         goto Scan_Name_Extension;
 
-         --  Here at a dot, with token just before it in Designator_Node
+      --  Here if nothing legal after the dot
+
+      else
+         Discard_Junk_Node (P_Identifier); -- to issue the error message
+         raise Error_Resync;
+      end if;
+
+      --  Here for left parenthesis extending name (left paren skipped)
+
+      <<Scan_Name_Extension_Left_Paren>>
+
+      --  We now have to scan through a list of items, terminated by a
+      --  right parenthesis. The scan is handled by a finite state
+      --  machine. The possibilities are:
+
+      --   (expression, expression, ..)
+
+      --      This is interpreted as an indexed component, i.e. as a
+      --      case of a name which can be extended in the normal manner.
+      --      This case is handled by LP_State_Expr.
+
+      --      Note: if and case expressions (without an extra level of
+      --      parentheses) are permitted in this context).
+
+      --   (..., identifier => expression , ...)
+
+      --      If there is at least one occurrence of identifier => (but
+      --      none of the other cases apply), then we have a call.
+      --      This case is handled by LP_State_Call.
+
+      --  Test for Id => case
+
+      if Token in Tok_Identifier | Tok_Operator_Symbol | Tok_Others then
+         Save_Scan_State (Scan_State_Id); -- at Id
+         Scan; -- past Id
+
+         --  Test for => (allow := as an error substitute)
+
+         if Token in Tok_Arrow | Tok_Colon_Equal then
+            Restore_Scan_State (Scan_State_Id); -- to Id
+            goto LP_State_Call;
 
-         if No (Prefix_Node) then
-            Prefix_Node := Designator_Node;
          else
-            Selector_Node := New_Node (N_Selected_Component, Dot_Sloc);
-            Set_Prefix (Selector_Node, Prefix_Node);
-            Set_Selector_Name (Selector_Node, Designator_Node);
-            Prefix_Node := Selector_Node;
+            Restore_Scan_State (Scan_State_Id); -- to Id
          end if;
+      end if;
 
-         Dot_Sloc := Token_Ptr;
-         Scan; -- past dot
-      end loop;
+      --  Here we have an expression after all
 
-      --  Fall out of the loop having just scanned an identifier
+      <<LP_State_Expr>>
+
+      if Token in Tok_Box | Tok_Right_Paren then
+         goto LP_State_Rewind;
+      end if;
+
+      Append (P_Expression_Or_Range_Attribute_If_OK, Arg_List);
+
+      if Token = Tok_Comma then
+         Scan; -- past comma
+         goto Scan_Name_Extension_Left_Paren;
+
+      elsif Token = Tok_Right_Paren then
+         Scan; -- past right paren
+
+         if not Instance_OK and then Token /= Tok_Dot then
+            goto LP_State_Rewind;
+         end if;
+
+         Prefix_Node := Name_Node;
+         Name_Node := New_Node (N_Indexed_Component, Sloc (Prefix_Node));
+         Set_Prefix (Name_Node, Prefix_Node);
+         Set_Expressions (Name_Node, Arg_List);
+         goto Scan_Name_Extension;
 
-      if No (Prefix_Node) then
-         return Designator_Node;
       else
-         Selector_Node := New_Node (N_Selected_Component, Dot_Sloc);
-         Set_Prefix (Selector_Node, Prefix_Node);
-         Set_Selector_Name (Selector_Node, Designator_Node);
-         return Selector_Node;
+         goto LP_State_Rewind;
       end if;
-   end P_Qualified_Simple_Name_Resync;
+
+      --  LP_State_Call corresponds to the situation in which at least one
+      --  instance of Id => Expression has been encountered, so we know that
+      --  we do not have a name, but rather a call. We enter it with the
+      --  scan pointer pointing to the next argument to scan, and Arg_List
+      --  containing the list of arguments scanned so far.
+
+      <<LP_State_Call>>
+
+      --  Test for case of Id => Expression (named parameter)
+
+      if Token in Tok_Identifier | Tok_Operator_Symbol | Tok_Others then
+         Save_Scan_State (Scan_State_Id); -- at Id
+         Ident_Node := Token_Node;
+         Scan; -- past Id
+
+         --  Deal with => (allow := as incorrect substitute)
+
+         if Token in Tok_Arrow | Tok_Colon_Equal then
+            Arg_Node := New_Node (N_Parameter_Association, Prev_Token_Ptr);
+            T_Arrow;
+            if Token in Tok_Box then
+               goto LP_State_Rewind;
+            end if;
+            Set_Selector_Name (Arg_Node, Ident_Node);
+            Set_Explicit_Actual_Parameter (Arg_Node, P_Expression);
+            Append (Arg_Node, Arg_List);
+
+            --  If a comma follows, go back and scan next entry
+
+            if Comma_Present then
+               goto LP_State_Call;
+
+            --  Otherwise we have the end of a call
+
+            else
+               T_Right_Paren; -- past right paren
+
+               if not Instance_OK and then Token /= Tok_Dot then
+                  goto LP_State_Rewind;
+               end if;
+
+               Prefix_Node := Name_Node;
+               Name_Node := New_Node (N_Function_Call, Sloc (Prefix_Node));
+               Set_Name (Name_Node, Prefix_Node);
+               Set_Parameter_Associations (Name_Node, Arg_List);
+               goto Scan_Name_Extension;
+            end if;
+
+         --  Filter out tokens that may appear in constraints
+
+         elsif Token in Tok_Vertical_Bar then
+            goto LP_State_Rewind;
+
+         --  Not named parameter: Id started an expression after all
+
+         else
+            Restore_Scan_State (Scan_State_Id); -- to Id
+         end if;
+      end if;
+
+      --  Here if entry did not start with Id => which means that it
+      --  is a positional parameter, which is not allowed, since we
+      --  have seen at least one named parameter already.
+
+      goto LP_State_Expr;
+
+      <<LP_State_Rewind>>
+      Restore_Scan_State (Scan_State_LP);
+      return Name_Node;
+   end P_Simple_Name_Resync;
 
    ----------------------
    -- 4.1  Direct_Name --
@@ -1117,7 +1336,7 @@ package body Ch4 is
    -- P_Reduction_Attribute_Reference --
    -------------------------------------
 
-   function P_Reduction_Attribute_Reference (S : Node_Id)
+   function P_Reduction_Attribute_Reference (Pref : Node_Id)
       return Node_Id
    is
       Attr_Node  : Node_Id;
@@ -1132,7 +1351,7 @@ package body Ch4 is
          Error_Msg ("Reduce attribute expected", Prev_Token_Ptr);
       end if;
 
-      Set_Prefix (Attr_Node, S);
+      Set_Prefix (Attr_Node, Pref);
       Set_Expressions (Attr_Node, New_List);
       T_Left_Paren;
       Append (P_Name, Expressions (Attr_Node));
@@ -3399,7 +3618,7 @@ package body Ch4 is
         and then Token = Tok_Identifier
       then
          Save_Scan_State (Scan_State);
-         Type_Node := P_Qualified_Simple_Name_Resync;
+         Type_Node := P_Subtype_Name_Resync;
          if Token = Tok_Apostrophe then
             Scan;
             if Token_Name = Name_Make then
index cc0e6c167fc2ada4c5235428e379af4f39be4f81..76a536b33d11f960634280439a0434cbe79b6c09 100644 (file)
@@ -2042,7 +2042,7 @@ package body Ch5 is
    begin
       Goto_Node := New_Node (N_Goto_Statement, Token_Ptr);
       Scan; -- past GOTO (or TO)
-      Set_Name (Goto_Node, P_Qualified_Simple_Name_Resync);
+      Set_Name (Goto_Node, P_Label_Name);
       Append_Elmt (Goto_Node, Goto_List);
 
       if Token = Tok_When then
@@ -2393,7 +2393,7 @@ package body Ch5 is
       Scan; -- past EXIT or CONTINUE
 
       if Token = Tok_Identifier then
-         Set_Name (N, P_Qualified_Simple_Name);
+         Set_Name (N, P_Loop_Name);
       elsif Style_Check and then Nkind (N) = N_Exit_Statement then
          --  This statement has no name, so check that
          --  the innermost loop is unnamed too.
index 2465108f7abc60b3db3bde101c1793c575dd052d..a6418a5dc9ea6633d94d8be4a8fd8fff59208a2c 100644 (file)
@@ -366,8 +366,8 @@ package body Ch6 is
                Inst_Node := New_Node (N_Procedure_Instantiation, Fproc_Sloc);
             end if;
 
-            Set_Name (Inst_Node, P_Qualified_Simple_Name);
             Set_Defining_Unit_Name (Inst_Node, Name_Node);
+            Set_Name (Inst_Node, P_Generic_Unit_Name);
             Set_Generic_Associations (Inst_Node, P_Generic_Actual_Part_Opt);
             P_Aspect_Specifications (Inst_Node, Semicolon => True);
             Pop_Scope_Stack; -- Don't need scope stack entry in this case
index da663685e4eec6074321f8758259453adc663bdc..ff55c87055f09aa8bf63289cecb360156fc7f9fa 100644 (file)
@@ -187,7 +187,7 @@ package body Ch7 is
             Package_Node :=
               New_Node (N_Package_Renaming_Declaration, Package_Sloc);
             Set_Defining_Unit_Name (Package_Node, Name_Node);
-            Set_Name (Package_Node, P_Qualified_Simple_Name);
+            Set_Name (Package_Node, P_Package_Name);
 
             No_Constraint;
             P_Aspect_Specifications (Package_Node, Semicolon => False);
@@ -224,7 +224,7 @@ package body Ch7 is
                Package_Node :=
                  New_Node (N_Package_Instantiation, Package_Sloc);
                Set_Defining_Unit_Name (Package_Node, Name_Node);
-               Set_Name (Package_Node, P_Qualified_Simple_Name);
+               Set_Name (Package_Node, P_Generic_Unit_Name);
                Set_Generic_Associations
                  (Package_Node, P_Generic_Actual_Part_Opt);
 
index 8be1ceb0e0eda001f40c935bf7a86e308b50cf3f..16f7f954c515ba224f02898d4ef33e44d19fa3a0 100644 (file)
@@ -128,7 +128,7 @@ package body Ch8 is
 
       loop
          Use_Node := New_Node (N_Use_Package_Clause, Use_Sloc);
-         Set_Name (Use_Node, P_Qualified_Simple_Name);
+         Set_Name (Use_Node, P_Package_Name);
 
          --  Locally chain each name's use-package node
 
index 5edce03a728b31aa174b98aeb1993e408b0c70d0..3ba1e708a742555ab87a1997a6268630bedbecd9 100644 (file)
@@ -221,7 +221,7 @@ package body Ch9 is
                Set_Interface_List (Task_Node, New_List);
 
                loop
-                  Append (P_Qualified_Simple_Name, Interface_List (Task_Node));
+                  Append (P_Subtype_Name, Interface_List (Task_Node));
                   exit when Token /= Tok_And;
                   Scan; --  past AND
                end loop;
@@ -557,8 +557,7 @@ package body Ch9 is
             Set_Interface_List (Protected_Node, New_List);
 
             loop
-               Append (P_Qualified_Simple_Name,
-                 Interface_List (Protected_Node));
+               Append (P_Subtype_Name, Interface_List (Protected_Node));
 
                exit when Token /= Tok_And;
                Scan; --  past AND
index 99bbed2cfb2c1e8b2b3e3ed8e317c56654c3a92c..8ced09dc009887b7487a1da7d350cd6d8fb4a07e 100644 (file)
@@ -829,8 +829,15 @@ function Par (Configuration_Pragmas : Boolean) return List_Id is
       function P_Expression                           return Node_Id;
       function P_Expression_Or_Range_Attribute        return Node_Id;
       function P_Name                                 return Node_Id;
-      function P_Qualified_Simple_Name                return Node_Id;
-      function P_Qualified_Simple_Name_Resync         return Node_Id;
+      function P_Exception_Name                       return Node_Id;
+      function P_Label_Name                           return Node_Id;
+      function P_Loop_Name                            return Node_Id;
+      function P_Generic_Unit_Name                    return Node_Id;
+      function P_Library_Unit_Name                    return Node_Id;
+      function P_Package_Name                         return Node_Id;
+      function P_Parent_Unit_Name                     return Node_Id;
+      function P_Subtype_Name                         return Node_Id;
+      function P_Subtype_Name_Resync                  return Node_Id;
       function P_Simple_Expression                    return Node_Id;
       function P_Simple_Expression_Or_Range_Attribute return Node_Id;
 
index 7b126aa0f3f9b9db907d58365cc5247a16e3c3fc..ffd3eaa6bec1391abe07750c114eb1dbdc188bf8 100644 (file)
@@ -3169,13 +3169,12 @@ package body Sem_Ch10 is
 
       elsif Unit_Kind = N_Package_Instantiation
         and then Nkind (U) = N_Package_Instantiation
-        and then Present (Instance_Spec (U))
       then
          --  If the instance has not been rewritten as a package declaration,
          --  then it appeared already in a previous with clause. Retrieve
          --  the entity from the previous instance.
 
-         E_Name := Defining_Entity (Specification (Instance_Spec (U)));
+         E_Name := Defining_Entity_Of_Instance (U);
 
       elsif Unit_Kind in N_Subprogram_Instantiation then
 
@@ -3186,9 +3185,7 @@ package body Sem_Ch10 is
          --  been rewritten as the declaration of the wrapper itself.
 
          if Nkind (U) in N_Subprogram_Instantiation then
-            E_Name :=
-              Related_Instance
-                (Defining_Entity (Specification (Instance_Spec (U))));
+            E_Name := Defining_Entity_Of_Instance (U);
          else
             E_Name := Related_Instance (Defining_Entity (U));
          end if;
index 0f1746f1ac51101672fb910120ed05cdff164571..fbf2bfca1f8954c6ffe8d17aa79753113df04d3f 100644 (file)
@@ -33,6 +33,7 @@ with Einfo.Utils;    use Einfo.Utils;
 with Elists;         use Elists;
 with Errout;         use Errout;
 with Expander;       use Expander;
+with Exp_Dbug;       use Exp_Dbug;
 with Fname;          use Fname;
 with Fname.UF;       use Fname.UF;
 with Freeze;         use Freeze;
@@ -1290,6 +1291,11 @@ package body Sem_Ch12 is
    --  onto Default_Actuals, and actuals that require freezing are
    --  appended onto Actuals_To_Freeze.
 
+   procedure Analyze_Structural_Associations
+     (N     : Node_Id;
+      Match : Associations.Match_Rec);
+   --  Analyze associations for structural instantiation N
+
    procedure Check_Fixed_Point_Warning
      (Match     : Associations.Match_Rec;
       Renamings : List_Id);
@@ -2365,6 +2371,16 @@ package body Sem_Ch12 is
       Match : constant Match_Rec := Match_Assocs (N, Formals, F_Copy);
 
    begin
+      if Nkind (N) in N_Generic_Instantiation and then Is_Structural (N) then
+         Analyze_Structural_Associations (N, Match);
+
+         --  Bail out if the instantiation has been turned into something else
+
+         if Nkind (N) not in N_Generic_Instantiation then
+            return Result_Renamings;
+         end if;
+      end if;
+
       for Index in Match.Assocs'Range loop
          declare
             Assoc : Assoc_Rec renames Match.Assocs (Index);
@@ -4848,6 +4864,13 @@ package body Sem_Ch12 is
 
       function Needs_Body_Instantiated (Gen_Unit : Entity_Id) return Boolean is
       begin
+         --  If the instantiation is in the auxiliary declarations of the main
+         --  unit, then the body is needed, even if the main unit is generic.
+
+         if Parent (N) = Aux_Decls_Node (Cunit (Main_Unit)) then
+            return True;
+         end if;
+
          --  No need to instantiate bodies in generic units
 
          if Is_Generic_Unit (Cunit_Entity (Main_Unit)) then
@@ -5134,6 +5157,17 @@ package body Sem_Ch12 is
               Formals => Generic_Formal_Declarations (Act_Tree),
               F_Copy  => Generic_Formal_Declarations (Gen_Decl));
 
+         --  Bail out if the instantiation has been turned into something else
+
+         if Nkind (N) /= N_Package_Instantiation then
+            if Parent_Installed then
+               Remove_Parent;
+            end if;
+
+            Restore_Env;
+            goto Leave;
+         end if;
+
          Vis_Prims_List := Check_Hidden_Primitives (Renamings);
 
          --  Set minimal decoration on the original entity
@@ -5141,6 +5175,18 @@ package body Sem_Ch12 is
          Mutate_Ekind (Defining_Entity (N), E_Package);
          Set_Scope (Defining_Entity (N), Current_Scope);
 
+         --  From now on only Act_Decl_Id matters. If was copied from the
+         --  original entity earlier but, if the instance is structural,
+         --  the latter has been changed, so adjust it accordingly.
+
+         if Chars (Defining_Entity (N)) /= Chars (Act_Decl_Id) then
+            pragma Assert (Is_Structural (N));
+            Set_Incomplete_Actuals
+              (Defining_Entity (N), Incomplete_Actuals (Act_Decl_Id));
+            Act_Decl_Id := New_Copy (Defining_Entity (N));
+            Set_Is_Not_Self_Hidden (Act_Decl_Id);
+         end if;
+
          Set_Instance_Env (Gen_Unit, Act_Decl_Id);
          Set_Is_Generic_Instance (Act_Decl_Id);
          Generate_Definition (Act_Decl_Id);
@@ -6011,6 +6057,454 @@ package body Sem_Ch12 is
       Analyze_Subprogram_Instantiation (N, E_Procedure);
    end Analyze_Procedure_Instantiation;
 
+   -------------------------------------
+   -- Analyze_Structural_Associations --
+   -------------------------------------
+
+   procedure Analyze_Structural_Associations
+     (N     : Node_Id;
+      Match : Associations.Match_Rec)
+   is
+      use Associations;
+
+      Loc : constant Source_Ptr := Sloc (N);
+      --  The source location of the instantiation
+
+      type Accessibility_Depth is record
+         Global : Uint;
+         Local  : Uint;
+      end record;
+      --  The accessibility depth of an entity is the depth of the outermost
+      --  scope from which the entity can be accessed at run time. It's zero
+      --  for library-level entities since they can be accessed from Standard.
+
+      --  However it can be accessed at run time only after being elaborated;
+      --  for a library-level entity, this means that it can be accessed from
+      --  Standard only after its enclosing library unit is elaborated, which
+      --  means that it can be accessed from all the other library units (that
+      --  have a dependence on this enclosing library unit) as if it was itself
+      --  declared in Standard, but not from this enclosing library unit.
+
+      --  Global contains the accessibility depth as computed from outside the
+      --  library or program unit where the entity is declared.
+
+      --  Local contains the accessibility depth as computed from the current
+      --  scope, which may be different from Global if the scope is within the
+      --  library or program unit where the entity is declared.
+
+      procedure Append_Entity_Name (B : in out Bounded_String; E : Entity_Id);
+      --  Append E's name to B
+
+      procedure Append_Expression (B : in out Bounded_String; N : Node_Id);
+      --  Append an encoding of N, a compile-time known expression, to B
+
+      function Get_Actual_Subtype (N : Node_Id) return Entity_Id;
+      --  Return the actual subtype of the formal object declared by N, which
+      --  is an N_Formal_Object_Declaration. It's the declared subtype of the
+      --  formal object if it is not a generic type, otherwise it's the actual
+      --  corresponding to this generic type in the instantiation.
+
+      function Get_Entity_Depth (E : Entity_Id) return Accessibility_Depth;
+      --  Return the accessibility depth of E
+
+      procedure Structural_Instantiation_Error (N : Node_Id);
+      --  Output an error for the specified structural instantiation
+
+      function Max (L, R : Accessibility_Depth) return Accessibility_Depth is
+        (Global => UI_Max (L.Global, R.Global),
+         Local  => UI_Max (L.Local,  R.Local));
+      --  Return a pair made up of the maximum value of each component
+
+      function OK_For_Structural_Instantiation (E : Entity_Id) return Boolean;
+      --  Return True if the generic unit E is OK for structural instantiation
+      --  and False if it is not, giving an error in the latter case.
+
+      procedure Rewrite_As_Renaming (N : Node_Id; E : Entity_Id);
+      --  Rewrite N as a renaming of E
+
+      ------------------------
+      -- Append_Entity_Name --
+      ------------------------
+
+      procedure Append_Entity_Name (B : in out Bounded_String; E : Entity_Id)
+      is
+      begin
+         if Operating_Mode = Generate_Code then
+            Get_External_Name (E);
+            Append (B, Global_Name_Buffer);
+         else
+            Append (B, 'E');
+            Append (B, Nat (E));
+         end if;
+      end Append_Entity_Name;
+
+      -----------------------
+      -- Append_Expression --
+      -----------------------
+
+      procedure Append_Expression (B : in out Bounded_String; N : Node_Id) is
+         Typ : constant Entity_Id := Etype (N);
+
+      begin
+         if Is_Integer_Type (Typ) then
+            Append (B, 'I');
+            Append (B, UI_Image (Expr_Value (N)));
+
+         elsif Is_Real_Type (Typ) then
+            declare
+               Val : constant Ureal := Expr_Value_R (N);
+            begin
+               Append (B, 'R');
+               Append (B, UI_Image (Norm_Num (Val)));
+               Append (B, '_');
+               Append (B, UI_Image (Norm_Den (Val)));
+            end;
+
+         elsif Is_Enumeration_Type (Typ) then
+            Append (B, 'E');
+            Append_Entity_Name (B, Expr_Value_E (N));
+
+         elsif Is_String_Type (Typ) then
+            Append (B, 'S');
+            Append (B, Strval (Expr_Value_S (N)));
+
+         else
+            raise Program_Error;
+         end if;
+      end Append_Expression;
+
+      ------------------------
+      -- Get_Actual_Subtype --
+      ------------------------
+
+      function Get_Actual_Subtype (N : Node_Id) return Entity_Id is
+         Subt : constant Entity_Id := Entity (Subtype_Mark (N));
+
+      begin
+         if not Is_Generic_Type (Subt) then
+            return Subt;
+         end if;
+
+         for Index in Match.Assocs'Range loop
+            declare
+               Assoc : Assoc_Rec renames Match.Assocs (Index);
+
+            begin
+               if Assoc.Actual.Kind = Name_Exp
+                 and then Nkind (Assoc.An_Formal) = N_Formal_Type_Declaration
+                 and then Defining_Identifier (Assoc.An_Formal) = Subt
+               then
+                  return Entity (Assoc.Actual.Name_Exp);
+               end if;
+            end;
+         end loop;
+
+         return Empty;
+      end Get_Actual_Subtype;
+
+      ----------------------
+      -- Get_Entity_Depth --
+      ----------------------
+
+      function Get_Entity_Depth (E : Entity_Id) return Accessibility_Depth is
+         Global : constant Uint := Scope_Depth (Enclosing_Dynamic_Scope (E));
+         CS     : constant Entity_Id := Current_Scope;
+
+         S : Entity_Id := Scope (E);
+
+      begin
+         --  Generic formal types are treated as local entities
+
+         if Is_Generic_Type (E) then
+            return (Global => Scope_Depth (S), Local => Scope_Depth (S));
+         end if;
+
+         --  Compute the accessibility depth from the current scope
+
+         while Scope_Depth (S) > Global
+           and then (not Scope_Within_Or_Same (CS, S)
+                      or else
+                        (Ekind (S) = E_Package
+                          and then Is_Generic_Instance (S)
+                          and then Alias (Related_Instance (S)) = CS))
+         loop
+            S := Scope (S);
+         end loop;
+
+         return (Global => Global, Local => Scope_Depth (S));
+      end Get_Entity_Depth;
+
+      ------------------------------------
+      -- Structural_Instantiation_Error --
+      ------------------------------------
+
+      procedure Structural_Instantiation_Error (N : Node_Id) is
+      begin
+         Error_Msg_N ("generic unit cannot be instantiated structurally", N);
+      end Structural_Instantiation_Error;
+
+      -------------------------------------
+      -- OK_For_Structural_Instantiation --
+      -------------------------------------
+
+      function OK_For_Structural_Instantiation (E : Entity_Id) return Boolean
+      is
+         Formals : constant List_Id :=
+                     Generic_Formal_Declarations (Unit_Declaration_Node (E));
+         Unit_Entity : constant Entity_Id :=
+                         Cunit_Entity (Get_Source_Unit (E));
+
+         Formal : Node_Id;
+
+      begin
+         --  Check that the generic unit is preelaborated
+
+         if Ekind (Unit_Entity) in E_Package | E_Generic_Package
+           and then not Is_Preelaborated (Unit_Entity)
+           and then not Is_Pure (Unit_Entity)
+         then
+            Structural_Instantiation_Error (N);
+            Error_Msg_NE
+              ("\generic unit& is not preelaborated", N, Unit_Entity);
+            return False;
+         end if;
+
+         --  Check that there is no generic formal object of mode In Out
+
+         Formal := First (Formals);
+         while Present (Formal) loop
+            if Nkind (Formal) = N_Formal_Object_Declaration
+              and then Out_Present (Formal)
+            then
+               Structural_Instantiation_Error (N);
+               Error_Msg_NE
+                 ("\in out formal parameter& not allowed", N,
+                  Defining_Identifier (Formal));
+               return False;
+            end if;
+
+            Next (Formal);
+         end loop;
+
+         return True;
+      end OK_For_Structural_Instantiation;
+
+      -------------------------
+      -- Rewrite_As_Renaming --
+      -------------------------
+
+      procedure Rewrite_As_Renaming (N : Node_Id; E : Entity_Id) is
+      begin
+         case Nkind (N) is
+            when N_Function_Instantiation =>
+               Rewrite (N,
+                 Make_Subprogram_Renaming_Declaration (Loc,
+                   Specification =>
+                     Make_Function_Specification (Loc,
+                       Defining_Unit_Name       => Defining_Unit_Name (N),
+                       Parameter_Specifications =>
+                         New_Copy_List
+                           (Parameter_Specifications
+                             (Subprogram_Specification (E))),
+                       Result_Definition        =>
+                         New_Occurrence_Of (Etype (E), Loc)),
+                   Name          => New_Occurrence_Of (E, Loc)));
+
+            when N_Procedure_Instantiation =>
+               Rewrite (N,
+                 Make_Subprogram_Renaming_Declaration (Loc,
+                   Specification =>
+                     Make_Procedure_Specification (Loc,
+                       Defining_Unit_Name       => Defining_Unit_Name (N),
+                       Parameter_Specifications =>
+                         New_Copy_List
+                           (Parameter_Specifications
+                             (Subprogram_Specification (E)))),
+                   Name          => New_Occurrence_Of (E, Loc)));
+
+            when N_Package_Instantiation =>
+               Rewrite (N,
+                 Make_Package_Renaming_Declaration (Loc,
+                   Defining_Unit_Name => Defining_Unit_Name (N),
+                   Name               => New_Occurrence_Of (E, Loc)));
+
+            when others =>
+               raise Program_Error;
+         end case;
+      end Rewrite_As_Renaming;
+
+      --  Local variables
+
+      Buf   : Bounded_String;
+      Depth : Accessibility_Depth;
+      Ent   : Entity_Id;
+      Nam   : Name_Id;
+      R     : Node_Id;
+      Scop  : Entity_Id;
+
+   --  Start of processing for Analyze_Structural_Associations
+
+   begin
+      if not OK_For_Structural_Instantiation (Match.Gen_Unit) then
+         return;
+      end if;
+
+      --  Compute the name and the scope depth of the structural instance
+
+      Append_Entity_Name (Buf, Match.Gen_Unit);
+      Append (Buf, "SI");
+      Depth := Get_Entity_Depth (Match.Gen_Unit);
+
+      for Index in Match.Assocs'Range loop
+         declare
+            Assoc : Assoc_Rec renames Match.Assocs (Index);
+
+         begin
+            Append (Buf, '_');
+
+            case Assoc.Actual.Kind is
+               when Name_Exp
+                  | Exp_Func_Default
+               =>
+                  if Nkind (Assoc.An_Formal) = N_Formal_Object_Declaration then
+                     --  Resolve the expression to compute whether it is static
+
+                     Resolve
+                       (Assoc.Actual.Name_Exp,
+                        Get_Actual_Subtype (Assoc.An_Formal));
+
+                     if Is_OK_Static_Expression (Assoc.Actual.Name_Exp) then
+                        --  We need the value of the expression to encode it
+
+                        pragma Assert
+                          (Compile_Time_Known_Value (Assoc.Actual.Name_Exp));
+
+                        Append_Expression (Buf, Assoc.Actual.Name_Exp);
+
+                     else
+                        Structural_Instantiation_Error (N);
+                        Error_Msg_N
+                          ("\expression is not static", Assoc.Actual.Name_Exp);
+                     end if;
+
+                  elsif Nkind (Assoc.Actual.Name_Exp) = N_Operator_Symbol then
+                     Append (Buf, Chars (Assoc.Actual.Name_Exp));
+
+                  else pragma Assert (Is_Entity_Name (Assoc.Actual.Name_Exp));
+                     Ent := Entity (Assoc.Actual.Name_Exp);
+
+                     --  If this is a type that is a renaming of another one,
+                     --  as is the case for actuals in instances, retain the
+                     --  latter. Beware of Natural and Positive, see Cstand.
+
+                     if Is_Type (Ent)
+                       and then Nkind (Parent (Ent)) = N_Subtype_Declaration
+                       and then
+                         Is_Entity_Name (Subtype_Indication (Parent (Ent)))
+                       and then not Comes_From_Source (Parent (Ent))
+                       and then Scope (Ent) /= Standard_Standard
+                     then
+                        Ent := Entity (Subtype_Indication (Parent (Ent)));
+                     end if;
+
+                     --  ??? Need to implement handling of explicit renaming
+
+                     Append_Entity_Name (Buf, Ent);
+                     Depth := Max (Depth, Get_Entity_Depth (Ent));
+                  end if;
+
+               when Box_Subp_Default =>
+                  Append (Buf, 'F');
+
+               when Null_Default =>
+                  Append (Buf, 'N');
+
+               when others =>
+                  Structural_Instantiation_Error (N);
+            end case;
+         end;
+      end loop;
+
+      Nam := Name_Find (Buf);
+      Ent := Get_Name_Entity_Id (Nam);
+
+      --  If the structural instance has already been created, then rewrite
+      --  this occurrence as a renaming of it.
+
+      if Present (Ent) then
+         Rewrite_As_Renaming (N, Ent);
+         Analyze (N);
+
+      --  Otherwise, create it in the outermost possible scope
+
+      else
+         --  Depth.Global is the accessibility depth of the structural instance
+         --  which is defined to be the depth of the outermost scope where the
+         --  instantiation is possible. If the depth cannot be reached from the
+         --  current scope, then the structural instance cannot be accessed out
+         --  of it and we would need to create a local instance instead.
+
+         if Depth.Local > Depth.Global then
+            Structural_Instantiation_Error (N);
+            Error_Msg_N ("\local entity used in the instantiation", N);
+            return;
+         end if;
+
+         Scop := Current_Scope;
+
+         --  If the current scope is too nested, analyze the instantiation
+         --  relocated in the outermost possible scope, which will invoke
+         --  us recursively with a matching scope depth this time.
+
+         if Scope_Depth (Scop) > Depth.Global then
+            while Scope_Depth (Scop) > Depth.Global loop
+               Scop := Scope (Scop);
+            end loop;
+
+            R := Relocate_Node (N);
+
+            --  If the scope is Standard, the instantiation is done outside the
+            --  current compilation unit and, therefore, needs a clean context.
+
+            if Scop = Standard_Standard then
+               declare
+                  S_Expander_Active  : constant Boolean := Expander_Active;
+                  S_Full_Analysis    : constant Boolean := Full_Analysis;
+                  S_In_Spec_Expr     : constant Boolean := In_Spec_Expression;
+                  S_Inside_A_Generic : constant Boolean := Inside_A_Generic;
+
+               begin
+                  Expander_Active := (Operating_Mode = Opt.Generate_Code);
+                  Full_Analysis := True;
+                  In_Spec_Expression := False;
+                  Inside_A_Generic := False;
+
+                  Add_Local_Declaration (R, N, Scop => Scop);
+
+                  Expander_Active := S_Expander_Active;
+                  Full_Analysis := S_Full_Analysis;
+                  In_Spec_Expression := S_In_Spec_Expr;
+                  Inside_A_Generic := S_Inside_A_Generic;
+               end;
+
+            else
+               Add_Local_Declaration (R, N, Scop => Scop);
+            end if;
+
+            Ent := Defining_Entity_Of_Instance (R);
+            Rewrite_As_Renaming (N, Ent);
+            Analyze (N);
+
+         --  Otherwise we are in the right scope and only need to set the
+         --  name of the instance.
+
+         else
+            Ent := Make_Defining_Identifier (Loc, Chars => Nam);
+            Set_Defining_Unit_Name (N, Ent);
+         end if;
+      end if;
+   end Analyze_Structural_Associations;
+
    -----------------------------------
    -- Need_Subprogram_Instance_Body --
    -----------------------------------
@@ -6056,9 +6550,12 @@ package body Sem_Ch12 is
 
       if (Is_In_Main_Unit (N) or else Is_Inlined_Or_Child_Of_Inlined (Subp))
 
-        --  No need to instantiate bodies in generic units
+        --  No need to instantiate bodies in generic units, except when the
+        --  instantiation is in the auxiliary declarations of the main unit;
+        --  in this case the body is needed, even if the main unit is generic.
 
-        and then not Is_Generic_Unit (Cunit_Entity (Main_Unit))
+        and then (not Is_Generic_Unit (Cunit_Entity (Main_Unit))
+                   or else Parent (N) = Aux_Decls_Node (Cunit (Main_Unit)))
 
         --  Must be generating code or analyzing code in GNATprove mode
 
@@ -6482,6 +6979,17 @@ package body Sem_Ch12 is
               Formals => Generic_Formal_Declarations (Act_Tree),
               F_Copy  => Generic_Formal_Declarations (Gen_Decl));
 
+         --  Bail out if the instantiation has been turned into something else
+
+         if Nkind (N) not in N_Subprogram_Instantiation then
+            if Parent_Installed then
+               Remove_Parent;
+            end if;
+
+            Restore_Env;
+            goto Leave;
+         end if;
+
          Vis_Prims_List := Check_Hidden_Primitives (Renamings);
 
          --  The subprogram itself cannot contain a nested instance, so the
@@ -6828,6 +7336,69 @@ package body Sem_Ch12 is
       end if;
    end Get_Associated_Node;
 
+   ------------------------------------
+   -- Build_Structural_Instantiation --
+   ------------------------------------
+
+   function Build_Structural_Instantiation
+     (N        : Node_Id;
+      Gen_Unit : Entity_Id;
+      Actuals  : List_Id) return Entity_Id
+   is
+      Loc     : constant Source_Ptr := Sloc (N);
+      Inst_Id : constant Entity_Id  := Make_Temporary (Loc, 'P');
+
+      Inst : Node_Id;
+
+   begin
+      case Ekind (Gen_Unit) is
+         when E_Generic_Function =>
+            Inst :=
+              Make_Function_Instantiation (Loc,
+                Defining_Unit_Name   => Inst_Id,
+                Name                 => New_Occurrence_Of (Gen_Unit, Loc),
+                Generic_Associations => Actuals);
+
+         when E_Generic_Package =>
+            Inst :=
+              Make_Package_Instantiation (Loc,
+                Defining_Unit_Name   => Inst_Id,
+                Name                 => New_Occurrence_Of (Gen_Unit, Loc),
+                Generic_Associations => Actuals);
+
+         when E_Generic_Procedure =>
+            Inst :=
+              Make_Procedure_Instantiation (Loc,
+                Defining_Unit_Name   => Inst_Id,
+                Name                 => New_Occurrence_Of (Gen_Unit, Loc),
+                Generic_Associations => Actuals);
+
+         when others =>
+            raise Program_Error;
+      end case;
+
+      Set_Is_Internal (Inst_Id);
+      Set_Is_Structural (Inst);
+
+      --  The instantiation must be added to a declarative part for technical
+      --  reasons pertaining to freezing (see the Freeze_Package_Instance and
+      --  Freeze_Subprogram_Instance procedures).
+
+      Add_Local_Declaration (Inst, N, Scop => Empty);
+      if Error_Posted (Inst) then
+         return Empty;
+      end if;
+
+      --  If the structural instance had already been created, this occurrence
+      --  has been turned into a renaming of it.
+
+      if Nkind (Inst) in N_Renaming_Declaration then
+         return Defining_Entity (Inst);
+      else
+         return Defining_Entity_Of_Instance (Inst);
+      end if;
+   end Build_Structural_Instantiation;
+
    -----------------------------------
    -- Build_Subprogram_Decl_Wrapper --
    -----------------------------------
@@ -15912,6 +16483,64 @@ package body Sem_Ch12 is
       end loop;
    end Map_Formal_Package_Entities;
 
+   --------------------
+   -- Mark_Link_Once --
+   --------------------
+
+   procedure Mark_Link_Once (Decls : List_Id) is
+      procedure Mark_Link_Once (Ent : Entity_Id);
+
+      --------------------
+      -- Mark_Link_Once --
+      --------------------
+
+      procedure Mark_Link_Once (Ent : Entity_Id) is
+      begin
+         if Is_Public (Ent) then
+            Set_Is_Link_Once (Ent);
+         end if;
+
+         if Ekind (Ent) in E_Package | E_Package_Body
+           and then No (Renamed_Entity (Ent))
+         then
+            declare
+               Pack_Ent : Entity_Id;
+
+            begin
+               Pack_Ent := First_Entity (Ent);
+               while Present (Pack_Ent) loop
+                  Mark_Link_Once (Pack_Ent);
+
+                  Next_Entity (Pack_Ent);
+               end loop;
+            end;
+         end if;
+      end Mark_Link_Once;
+
+      Decl : Node_Id;
+      Spec : Node_Id;
+
+   begin
+      Decl := First (Decls);
+      while Present (Decl) loop
+         if Nkind (Decl) in N_Generic_Instantiation
+           and then Is_Structural (Decl)
+         then
+            Spec := Instance_Spec (Decl);
+
+            Mark_Link_Once (Defining_Entity (Specification (Spec)));
+
+            if Nkind (Decl) = N_Package_Instantiation
+              and then Present (Corresponding_Body (Spec))
+            then
+               Mark_Link_Once (Corresponding_Body (Spec));
+            end if;
+         end if;
+
+         Next (Decl);
+      end loop;
+   end Mark_Link_Once;
+
    -----------------------
    -- Move_Freeze_Nodes --
    -----------------------
index 3e703a5906ca0787b855f5665117b2a4a01f3d48..83c3114667b86a1a94d92259772ce28de24b8694 100644 (file)
@@ -44,6 +44,14 @@ package Sem_Ch12 is
    --  Must be invoked just at the end of the end of the processing of a
    --  generic spec or body.
 
+   function Build_Structural_Instantiation
+     (N        : Node_Id;
+      Gen_Unit : Entity_Id;
+      Actuals  : List_Id) return Entity_Id;
+   --  Build a structural instantiation of Gen_Unit on Actuals at N and return
+   --  its defining entity, after either having inserted it at the appropriate
+   --  place in the tree or turned it into a renaming of a previous instance.
+
    procedure Check_Generic_Child_Unit
      (Gen_Id           : Node_Id;
       Parent_Installed : in out Boolean);
@@ -114,6 +122,9 @@ package Sem_Ch12 is
    --  Return true if E is a package created for an abbreviated instantiation
    --  to check conformance between formal package and corresponding actual.
 
+   procedure Mark_Link_Once (Decls : List_Id);
+   --  Mark all the structural instances present in Decls as Link Once
+
    function Need_Subprogram_Instance_Body
      (N    : Node_Id;
       Subp : Entity_Id) return Boolean;
index 018c8a07932458c5f5553775bdc620f201c44a3b..31debfee85ce53273c2b9932bad82aa29284f6f4 100644 (file)
@@ -54,6 +54,7 @@ with Sem_Cat;        use Sem_Cat;
 with Sem_Ch3;        use Sem_Ch3;
 with Sem_Ch6;        use Sem_Ch6;
 with Sem_Ch8;        use Sem_Ch8;
+with Sem_Ch12;       use Sem_Ch12;
 with Sem_Dim;        use Sem_Dim;
 with Sem_Disp;       use Sem_Disp;
 with Sem_Dist;       use Sem_Dist;
@@ -1263,6 +1264,55 @@ package body Sem_Ch4 is
                      No_Interpretation;
                   end if;
 
+               --  Or this may be a reference to a structural instantiation
+               --  with named associations if GNAT extensions are allowed.
+
+               elsif (Is_Generic_Subprogram (Nam_Ent)
+                       or else Ekind (Nam_Ent) = E_Generic_Package)
+                 and then All_Extensions_Allowed
+                 and then not Is_Empty_List (Parameter_Associations (N))
+               then
+                  declare
+                     Act      : Node_Id;
+                     Act_List : List_Id;
+                     Assoc    : Node_Id;
+                     Inst_Id  : Entity_Id;
+
+                  begin
+                     Act_List := New_List;
+                     Assoc := First (Parameter_Associations (N));
+                     while Present (Assoc) loop
+                        if Nkind (Assoc) = N_Parameter_Association then
+                           Act :=
+                             Make_Generic_Association (Sloc (Assoc),
+                               Selector_Name                     =>
+                                 Relocate_Node (Selector_Name (Assoc)),
+                               Explicit_Generic_Actual_Parameter =>
+                                 Relocate_Node
+                                   (Explicit_Actual_Parameter (Assoc)));
+                        else
+                           Act :=
+                             Make_Generic_Association (Sloc (Assoc),
+                               Explicit_Generic_Actual_Parameter =>
+                                 Relocate_Node (Assoc));
+                        end if;
+
+                        Append_To (Act_List, Act);
+                        Next (Assoc);
+                     end loop;
+
+                     Inst_Id :=
+                       Build_Structural_Instantiation (N, Nam_Ent, Act_List);
+                     if Present (Inst_Id) then
+                        Rewrite (N, New_Occurrence_Of (Inst_Id, Loc));
+                     else
+                        Rewrite (N,
+                          Make_Raise_Program_Error (Loc,
+                            Reason => PE_Explicit_Raise));
+                     end if;
+                     Analyze (N);
+                  end;
+
                else
                   No_Interpretation;
                end if;
@@ -2734,6 +2784,10 @@ package body Sem_Ch4 is
       --  If the prefix of an indexed component is overloaded, the proper
       --  interpretation is selected by the index types and the context.
 
+      procedure Process_Generic_Instantiation;
+      --  The prefix in indexed component form is a generic unit. This
+      --  routine processes it and builds the implicit instantiation.
+
       ---------------------------
       -- Process_Function_Call --
       ---------------------------
@@ -3046,6 +3100,37 @@ package body Sem_Ch4 is
          end if;
       end Process_Overloaded_Indexed_Component;
 
+      -----------------------------------
+      -- Process_Generic_Instantiation --
+      -----------------------------------
+
+      procedure Process_Generic_Instantiation is
+         Act_List : List_Id;
+         Expr     : Node_Id;
+         Inst_Id  : Entity_Id;
+
+      begin
+         Act_List := New_List;
+         Expr := First (Expressions (N));
+         while Present (Expr) loop
+            Append_To (Act_List,
+              Make_Generic_Association (Sloc (Expr),
+                Explicit_Generic_Actual_Parameter =>
+                  Relocate_Node (Expr)));
+            Next (Expr);
+         end loop;
+
+         Inst_Id := Build_Structural_Instantiation (N, U_N, Act_List);
+         if Present (Inst_Id) then
+            Rewrite (N, New_Occurrence_Of (Inst_Id, Sloc (N)));
+         else
+            Rewrite (N,
+              Make_Raise_Program_Error (Sloc (N),
+                Reason => PE_Explicit_Raise));
+         end if;
+         Analyze (N);
+      end Process_Generic_Instantiation;
+
    --  Start of processing for Analyze_Indexed_Component_Form
 
    begin
@@ -3119,9 +3204,21 @@ package body Sem_Ch4 is
 
             --  A common beginner's (or C++ templates fan) error
 
-            Error_Msg_N ("generic subprogram cannot be called", N);
-            Set_Etype (N, Any_Type);
-            return;
+            if All_Extensions_Allowed
+              and then not Is_Empty_List (Expressions (N))
+            then
+               Process_Generic_Instantiation;
+            else
+               Error_Msg_N ("generic subprogram cannot be called", N);
+               Set_Etype (N, Any_Type);
+               return;
+            end if;
+
+         elsif Ekind (U_N) = E_Generic_Package
+           and then All_Extensions_Allowed
+           and then not Is_Empty_List (Expressions (N))
+         then
+            Process_Generic_Instantiation;
 
          else
             Process_Indexed_Component_Or_Slice;
index e6ef65860d630f58bd15b4cfea6f3a7c1c36ce43..4814c0301edbce1ca70cd1dfd19fc324edbd4eba 100644 (file)
@@ -4340,7 +4340,12 @@ package body Sem_Ch8 is
          --  by inserting an extra with clause since redundant clauses don't
          --  really matter.
 
-         if All_Extensions_Allowed and then Is_In_Context_Clause (Clause) then
+         if All_Extensions_Allowed
+           and then Is_In_Context_Clause (Clause)
+           and then Nkind (Pack) in N_Expanded_Name
+                                  | N_Identifier
+                                  | N_Selected_Component
+         then
             declare
                Unum        : Unit_Number_Type;
                With_Clause : constant Node_Id :=
@@ -4531,6 +4536,10 @@ package body Sem_Ch8 is
 
       Id := Subtype_Mark (N);
       Find_Type (Id);
+      if not Is_Entity_Name (Id) then
+         pragma Assert (Serious_Errors_Detected > 0);
+         return;
+      end if;
       E := Base_Type (Entity (Id));
 
       --  There are many cases where a use_type_clause may be reanalyzed due to
@@ -5031,10 +5040,37 @@ package body Sem_Ch8 is
    -----------------------------------
 
    procedure Check_In_Previous_With_Clause (N, Nam : Node_Id) is
-      Pack : constant Entity_Id := Entity (Original_Node (Nam));
+
+      function Get_Name (N : Node_Id) return Node_Id;
+      --  Return the name of a package that may be present in a clause
+
+      --------------
+      -- Get_Name --
+      --------------
+
+      function Get_Name (N : Node_Id) return Node_Id is
+      begin
+         case Nkind (N) is
+            when N_Indexed_Component =>
+               return Prefix (N);
+
+            when N_Function_Call =>
+               return Name (N);
+
+            when others =>
+               return N;
+         end case;
+      end Get_Name;
+
+      --  Local variables
+
+      Pack : constant Entity_Id := Entity (Get_Name (Original_Node (Nam)));
+
       Item : Node_Id;
       Par  : Node_Id;
 
+   --  Start of processing for Check_In_Previous_With_Clause
+
    begin
       Item := First (Context_Items (Parent (N)));
       while Present (Item) and then Item /= N loop
@@ -5045,7 +5081,7 @@ package body Sem_Ch8 is
            and then Nkind (Name (Item)) /= N_Selected_Component
            and then Entity (Name (Item)) = Pack
          then
-            Par := Nam;
+            Par := Get_Name (Original_Node (Nam));
 
             --  Find root library unit in with_clause
 
@@ -5053,7 +5089,7 @@ package body Sem_Ch8 is
                Par := Prefix (Par);
             end loop;
 
-            if Is_Child_Unit (Entity (Original_Node (Par))) then
+            if Is_Child_Unit (Entity (Par)) then
                Error_Msg_NE ("& is not directly visible", Par, Entity (Par));
             else
                return;
@@ -5085,6 +5121,14 @@ package body Sem_Ch8 is
       if Nkind (Parent (N)) /= N_Compilation_Unit then
          return;
 
+      --  Structural instances can always be renamed
+
+      elsif Is_Generic_Instance (Old_E)
+        and then Present (Get_Unit_Instantiation_Node (Old_E))
+        and then Is_Structural (Get_Unit_Instantiation_Node (Old_E))
+      then
+         return;
+
       --  Check for library unit. Note that we used to check for the scope
       --  being Standard here, but that was wrong for Standard itself.
 
@@ -5467,10 +5511,7 @@ package body Sem_Ch8 is
          end if;
       end if;
 
-      if Is_Empty_Elmt_List (Used_Operations (N)) then
-         return;
-
-      else
+      if Present (Used_Operations (N)) then
          Elmt := First_Elmt (Used_Operations (N));
          while Present (Elmt) loop
             Set_Is_Potentially_Use_Visible (Node (Elmt), False);
index 432b036396d71ec6102de7778d0902a92309d486..ff2b2351937566eb0c415617f945c0e6d6282792 100644 (file)
@@ -347,6 +347,133 @@ package body Sem_Util is
       Analyze (Decl);
    end Add_Global_Declaration;
 
+   ---------------------------
+   -- Add_Local_Declaration --
+   ---------------------------
+
+   procedure Add_Local_Declaration
+     (Decl : Node_Id;
+      N    : Node_Id;
+      Scop : Entity_Id)
+   is
+      function Find_Associated_Scope (N : Node_Id) return Scope_Kind_Id;
+      --  Return the scope associated with the declarative part of N
+
+      ---------------------------
+      -- Find_Associated_Scope --
+      ---------------------------
+
+      function Find_Associated_Scope (N : Node_Id) return Scope_Kind_Id is
+      begin
+         case Nkind (N) is
+            when N_Block_Statement =>
+               return Entity (Identifier (N));
+
+            when N_Compilation_Unit
+               | N_Compilation_Unit_Aux
+            =>
+               return Standard_Standard;
+
+            when N_Package_Specification
+               | N_Protected_Definition
+               | N_Task_Definition
+            =>
+               return Defining_Entity (Parent (N));
+
+            when N_Entry_Body
+               | N_Package_Body
+               | N_Protected_Body
+               | N_Task_Body
+            =>
+               return Corresponding_Spec (N);
+
+            when N_Subprogram_Body =>
+               if Acts_As_Spec (N) then
+                  return Defining_Entity (N);
+               else
+                  return Corresponding_Spec (N);
+               end if;
+
+            when others =>
+               raise Program_Error;
+         end case;
+      end Find_Associated_Scope;
+
+      --  Local variables
+
+      Nod : Node_Id;
+      Par : Node_Id;
+
+   --  Start of processing for Add_Local_Declaration
+
+   begin
+      Nod := N;
+      Par := Parent (Nod);
+
+      --  Look for the innermost enclosing construct with a declarative part
+
+      while Nkind (Par) not in N_Block_Statement
+                             | N_Compilation_Unit
+                             | N_Compilation_Unit_Aux
+                             | N_Entry_Body
+                             | N_Package_Body
+                             | N_Package_Specification
+                             | N_Protected_Body
+                             | N_Protected_Definition
+                             | N_Subprogram_Body
+                             | N_Task_Body
+                             | N_Task_Definition
+         or else (Present (Scop) and Find_Associated_Scope (Par) /= Scop)
+      loop
+         Nod := Par;
+         Par := Parent (Nod);
+      end loop;
+
+      --  Compilation units do not directly have a declarative part
+
+      if Nkind (Par) = N_Compilation_Unit then
+         Par := Aux_Decls_Node (Par);
+      end if;
+
+      --  Insert Decl before N or at the end of the declarative part
+
+      case Nkind (Par) is
+         when N_Block_Statement
+            | N_Compilation_Unit_Aux
+            | N_Entry_Body
+            | N_Package_Body
+            | N_Protected_Body
+            | N_Subprogram_Body
+            | N_Task_Body
+         =>
+            if Is_List_Member (Nod)
+              and then List_Containing (Nod) = Declarations (Par)
+            then
+               Insert_Before (Nod, Decl);
+
+            else
+               if No (Declarations (Par)) then
+                  Set_Declarations (Par, New_List);
+               end if;
+
+               Append_To (Declarations (Par), Decl);
+            end if;
+
+         when N_Package_Specification
+            | N_Protected_Definition
+            | N_Task_Definition
+         =>
+            Insert_Before (Nod, Decl);
+
+         when others =>
+            raise Program_Error;
+      end case;
+
+      Push_Scope (Find_Associated_Scope (Par));
+      Analyze (Decl);
+      Pop_Scope;
+   end Add_Local_Declaration;
+
    --------------------------------
    -- Address_Integer_Convert_OK --
    --------------------------------
@@ -6743,6 +6870,28 @@ package body Sem_Util is
       end if;
    end Defining_Entity;
 
+   ---------------------------------
+   -- Defining_Entity_Of_Instance --
+   ---------------------------------
+
+   function Defining_Entity_Of_Instance (N : Node_Id) return Entity_Id is
+      pragma Assert (Nkind (N) in N_Generic_Instantiation);
+      Spec : constant Node_Id := Instance_Spec (N);
+
+   begin
+      --  Fall back to Defining_Entity in case of previous errors
+
+      if No (Spec) then
+         return Defining_Entity (N);
+      end if;
+
+      if Nkind (N) = N_Package_Instantiation then
+         return Defining_Entity (Specification (Spec));
+      else
+         return Related_Instance (Defining_Entity (Specification (Spec)));
+      end if;
+   end Defining_Entity_Of_Instance;
+
    ------------------------------
    -- Defining_Entity_Or_Empty --
    ------------------------------
index 8d6cf54fa6c6f13ea0a05c2500aab61ce33959d9..ee9ecd2abb4949bec04b2441b8d51a1f95017f5f 100644 (file)
@@ -62,6 +62,15 @@ package Sem_Util is
    --  for the current unit. The declared entity is added to current scope,
    --  so the caller should push a new scope as required before the call.
 
+   procedure Add_Local_Declaration
+     (Decl : Node_Id;
+      N    : Node_Id;
+      Scop : Entity_Id);
+   --  This procedure adds a declaration Decl to the innermost declarative
+   --  part that covers N, whose associated scope is Scop if Scop is present,
+   --  and before N if N is in this declarative part. The declared entity is
+   --  added to the scope associated with the declarative part.
+
    function Add_Suffix (E : Entity_Id; Suffix : Character) return Name_Id;
    --  Returns the name of E adding Suffix
 
@@ -687,6 +696,11 @@ package Sem_Util is
    --  This is equivalent to Defining_Entity but it returns Empty for nodes
    --  without an entity instead of raising Program_Error.
 
+   function Defining_Entity_Of_Instance (N : Node_Id) return Entity_Id;
+   --  Given an N_Generic_Instantiation node, returns the defining entity of
+   --  the instance, that is to say the entity that is declared at N (which
+   --  is not the same as Defining_Entity (N), see Sem_Ch12).
+
    function Denotes_Discriminant
      (N                : Node_Id;
       Check_Concurrent : Boolean := False) return Boolean;
index bde67a05b6e6eb878efeb4abdcf9b2fbc1c3f559..2c15b80d12ef55a8762f4e8207c9c83105fd3d58 100644 (file)
@@ -1878,6 +1878,12 @@ package Sinfo is
    --    Indicates that an expression is a static expression according to the
    --    rules in RM-4.9. See Sem_Eval for details.
 
+   --  Is_Structural
+   --    Present in N_Generic_Instantiation nodes. Set if the instantiation is
+   --    structural, that is to say, is the unique anonymous instantiation of
+   --    the generic unit on the actual parameters done in the outermost scope
+   --    where it would be legal to declare an identical named instantiation.
+
    --  Is_Subprogram_Descriptor
    --    Present in N_Object_Declaration, and set only for the object
    --    declaration generated for a subprogram descriptor in fast exception
@@ -7119,6 +7125,7 @@ package Sinfo is
       --  Is_Elaboration_Warnings_OK_Node
       --  Is_Declaration_Level_Node
       --  Is_Known_Guaranteed_ABE
+      --  Is_Structural
 
       --  N_Procedure_Instantiation
       --  Sloc points to PROCEDURE
@@ -7135,6 +7142,7 @@ package Sinfo is
       --  Must_Override set if overriding indicator present
       --  Must_Not_Override set if not_overriding indicator present
       --  Is_Known_Guaranteed_ABE
+      --  Is_Structural
 
       --  N_Function_Instantiation
       --  Sloc points to FUNCTION
@@ -7151,6 +7159,7 @@ package Sinfo is
       --  Must_Override set if overriding indicator present
       --  Must_Not_Override set if not_overriding indicator present
       --  Is_Known_Guaranteed_ABE
+      --  Is_Structural
 
       --  Note: overriding indicator is an Ada 2005 feature