-- -- Copyright (C) 2014-2022, AdaCore -- SPDX-License-Identifier: Apache-2.0 -- -- .. note:: At this stage, this package is considered as internal. -- -- This package provides a generic API so that programs can work with the -- $.Introspection packages of all Langkit-generated libraries. -- To facilitate use from a -gnatX project, since we don't use the [] syntax pragma Warnings (Off, "obsolescent"); private with Ada.Containers.Hashed_Maps; with Ada.Exceptions; use Ada.Exceptions; private with Ada.Finalization; private with Ada.Unchecked_Deallocation; with GNATCOLL.GMP.Integers; use GNATCOLL.GMP.Integers; with Langkit_Support.Generic_API.Analysis; use Langkit_Support.Generic_API.Analysis; limited private with Langkit_Support.Internal.Introspection; with Langkit_Support.Slocs; use Langkit_Support.Slocs; with Langkit_Support.Symbols; use Langkit_Support.Symbols; package Langkit_Support.Generic_API.Introspection is ------------------------ -- Polymorphic values -- ------------------------ type Type_Ref is private; -- Reference to the type of a polymorphic value: boolean, integer, -- character, ... No_Type_Ref : constant Type_Ref; -- Special value to express no type reference type Type_Ref_Array is array (Positive range <>) of Type_Ref; function Language (T : Type_Ref) return Language_Id; -- Return the language ID corresponding to the given type. Raise a -- ``Precondition_Failure`` exception if ``T`` is ``No_Type_Ref``. function Debug_Name (T : Type_Ref) return String; -- Return the free-form name of this type for debug purposes, or -- "" if ``T`` is ``No_Type_Ref``. function All_Types (Id : Language_Id) return Type_Ref_Array; -- Return the list of all types that the given language defines type Any_Type_Index is new Natural; -- Language-specific index to designate a type. -- -- A given language defines types for the ``1 .. Last_Type (Language)`` -- range: see the ``Last_Type`` function below. No_Type_Index : constant Any_Type_Index := 0; -- Special ``Any_Type_Index`` to mean: no reference to a type subtype Type_Index is Any_Type_Index range 1 .. Any_Type_Index'Last; function To_Index (T : Type_Ref) return Type_Index; -- Return the index of the given type. Raise a ``Precondition_Failure`` -- exception if ``T`` is ``No_Type_Ref``. function From_Index (Id : Language_Id; T : Type_Index) return Type_Ref; -- Return the type for the given language corresponding to the ``T`` index. -- Raise a ``Precondition_Failure`` exception if ``T`` is not a valid type -- index for the given language. function Last_Type (Id : Language_Id) return Type_Index; -- Return the last type index that is valid for the given language type Type_Category is (Analysis_Unit_Category, Big_Int_Category, Bool_Category, Char_Category, Int_Category, Source_Location_Category, Source_Location_Range_Category, String_Category, Token_Category, Symbol_Category, Enum_Category, Array_Category, Iterator_Category, Struct_Category); -- Each type has a category, which determines the kind of operation that -- can be performed on that type: for instance one can get the length of -- ``Array_Category``-typed values. function Category (T : Type_Ref) return Type_Category; -- Return the category of the given type type Value_Ref is private; -- Reference to a polymorphic value: boolean, integer, character, ... No_Value_Ref : constant Value_Ref; -- Special constant to express no value reference type Value_Ref_Array is array (Positive range <>) of Value_Ref; function "=" (Left, Right : Value_Ref) return Boolean; -- Return whether ``Left`` and ``Right`` are structurally equivalent function Language (Value : Value_Ref) return Language_Id; -- Return the language ID corresponding to the given value. Raise a -- ``Precondition_Failure`` exception if ``Value`` is ``No_Value_Ref``. function Type_Of (Value : Value_Ref) return Type_Ref; -- Return the type of the ``Value`` polymorphic value. Raise a -- ``Precondition_Error`` if ``Value`` is ``No_Value_Ref``. function Type_Matches (Value : Value_Ref; T : Type_Ref) return Boolean; -- Return whether ``Value`` is a valid value to be passed as a ``T`` -- argument. -- -- Raise a ``Precondition_Error`` if: -- -- * ``Value`` is ``No_Value_Ref``; -- * ``T`` is ``No_Type_Ref``; -- * ``Value`` and ``T`` do not belong to the same language. function Image (Value : Value_Ref) return String; -- Return a string that represents ``Value``, for logging/debugging -- purposes. Note that the goal here is to return a short human-readable -- string, not a string that contains all the information in ``Value``. -- -- Unlike other ``Value_Ref`` primitives, it is valid to call ``Image`` on -- ``No_Value_Ref``. -- Constructors/getters for built in types function From_Unit (Id : Language_Id; Value : Lk_Unit) return Value_Ref; function As_Unit (Value : Value_Ref) return Lk_Unit; function From_Big_Int (Id : Language_Id; Value : Big_Integer) return Value_Ref; function As_Big_Int (Value : Value_Ref) return Big_Integer; function From_Bool (Id : Language_Id; Value : Boolean) return Value_Ref; function As_Bool (Value : Value_Ref) return Boolean; function From_Char (Id : Language_Id; Value : Character_Type) return Value_Ref; function As_Char (Value : Value_Ref) return Character_Type; function From_Int (Id : Language_Id; Value : Integer) return Value_Ref; function As_Int (Value : Value_Ref) return Integer; function From_Source_Location (Id : Language_Id; Value : Source_Location) return Value_Ref; function As_Source_Location (Value : Value_Ref) return Source_Location; function From_Source_Location_Range (Id : Language_Id; Value : Source_Location_Range) return Value_Ref; function As_Source_Location_Range (Value : Value_Ref) return Source_Location_Range; function From_String (Id : Language_Id; Value : Text_Type) return Value_Ref; function As_String (Value : Value_Ref) return Text_Type; function From_Token (Id : Language_Id; Value : Lk_Token) return Value_Ref; function As_Token (Value : Value_Ref) return Lk_Token; function From_Symbol (Id : Language_Id; Value : Text_Type) return Value_Ref; function As_Symbol (Value : Value_Ref) return Text_Type; function From_Node (Id : Language_Id; Value : Lk_Node) return Value_Ref; function As_Node (Value : Value_Ref) return Lk_Node; function Type_Of (Node : Lk_Node) return Type_Ref; -- Return the type of ``Node``. Raise a ``Precondition_Failure`` if -- ``Node`` is ``No_Lk_Node``. function Type_Matches (Node : Lk_Node; T : Type_Ref) return Boolean; -- Overload of the ``Type_Matches`` function taking a ``Value_Ref`` -- argument, for convenience. ---------------- -- Enum types -- ---------------- function Is_Enum_Type (T : Type_Ref) return Boolean; -- Return whether ``T`` references an enum type. -- -- All functions below will raise a ``Precondition_Failure`` if passed a -- type which does not satisfy this predicate as ``Enum`` formals. function Enum_Type_Name (Enum : Type_Ref) return Name_Type; -- Return the name of the given enum type function All_Enum_Types (Id : Language_Id) return Type_Ref_Array; -- Return the list of all enum types that the given language defines type Enum_Value_Ref is private; -- Reference to an enum type value No_Enum_Value_Ref : constant Enum_Value_Ref; -- Special value to express no enum value reference type Enum_Value_Ref_Array is array (Positive range <>) of Enum_Value_Ref; function Enum_For (Value : Enum_Value_Ref) return Type_Ref; -- Return the enum type that owns the given value function Enum_Default_Value (Enum : Type_Ref) return Enum_Value_Ref; -- Return the index of the default enum value for the given ``Enum`` enum -- type, or ``No_Enum_Value_Ref`` if this type does not have a default -- value. function Enum_Value_Name (Value : Enum_Value_Ref) return Name_Type; -- Return the name corresponding to the ``Index``th value for the ``Enum`` -- enum type. This raises a ``Out_Of_Bounds_Error`` if ``Index`` is too big -- for this enum type. function Debug_Name (Value : Enum_Value_Ref) return String; -- Return "X.Y" where X is the enum type and Y is the name of this value, -- or "" if ``Value`` is null. function All_Enum_Values (Enum : Type_Ref) return Enum_Value_Ref_Array; -- Return the list of all enum values for the given enum type type Any_Enum_Value_Index is new Natural; subtype Enum_Value_Index is Any_Enum_Value_Index range 1 .. Any_Enum_Value_Index'Last; -- Index of an enum value for a given enum type No_Enum_Value_Index : constant Any_Enum_Value_Index := 0; -- Special ``Any_Enum_Value_Index`` to mean: no reference to a type function To_Index (Value : Enum_Value_Ref) return Enum_Value_Index; -- Return the index of the given type. Raise a ``Precondition_Failure`` -- exception if ``Value`` is ``No_Enum_Value_Ref``. function From_Index (Enum : Type_Ref; Value : Enum_Value_Index) return Enum_Value_Ref; -- Return the value for the given enum type corresponding to the ``Value`` -- index. Raise a ``Precondition_Failure`` exception if ``Value`` is not a -- valid value index for that enum type. function Enum_Last_Value (Enum : Type_Ref) return Enum_Value_Index; -- Return the index of the last enum value for the given ``Enum`` enum type function Create_Enum (Value : Enum_Value_Ref) return Value_Ref; -- Convert an ``Enum_Value_Ref`` into the corresponding ``Value_Ref`` function As_Enum (Value : Value_Ref) return Enum_Value_Ref; -- Assuming ``Value`` is an enum value, return the corresponding -- ``Enum_Value_Ref``. Raise a ``Precondition_Failure`` exception if -- ``Value`` is not an enum value. ----------------- -- Array types -- ----------------- function Is_Array_Type (T : Type_Ref) return Boolean; -- Return whether ``T`` references an array type. -- -- All functions below will raise a ``Precondition_Failure`` if passed a -- type which does not satisfy this predicate as ``T`` formals. function Array_Element_Type (T : Type_Ref) return Type_Ref; -- Return the type of elements in ``T`` arrays function All_Array_Types (Id : Language_Id) return Type_Ref_Array; -- Return the list of all array types that the given language defines function Create_Array (T : Type_Ref; Values : Value_Ref_Array) return Value_Ref; -- Create an array of the given ``T`` type, with the given ``Values``. -- Raise a ``Precondition_Failure`` if any of the following is true: -- -- * ``T`` is null; -- * ``Values`` contains a null value reference; -- * ``Values`` contains a value that does not match ``T``'s element type; -- * one ``Values`` item does not belong to the same language as ``T``. function As_Array (Value : Value_Ref) return Value_Ref_Array; -- Return values for all items in the ``Value`` array. Raise a -- ``Precondition_Failure`` if ``Value`` is null or if it does not -- reference an array. function Array_Length (Value : Value_Ref) return Natural; -- Return the length of the given ``Value`` array. Raise a -- ``Precondition_Failure`` if ``Value`` is null or if it does not -- reference an array. function Array_Item (Value : Value_Ref; Index : Positive) return Value_Ref; -- Return the item at the given ``Index`` in the ``Value`` array. Raise a -- ``Precondition_Failure`` if any of the following is true: -- -- * ``Value`` is null; -- * it does not reference an array; -- * ``Index`` is out of bounds for this array value. -------------------- -- Iterator types -- -------------------- function Is_Iterator_Type (T : Type_Ref) return Boolean; -- Return whether ``T`` references an iterator type. -- -- All functions below will raise a ``Precondition_Failure`` if passed a -- type which does not satisfy this predicate as ``T`` formals. function Iterator_Element_Type (T : Type_Ref) return Type_Ref; -- Return the type of elements in ``T`` iterators function All_Iterator_Types (Id : Language_Id) return Type_Ref_Array; -- Return the list of all iterator types that the given language defines function Iterator_Next (Value : Value_Ref) return Value_Ref; -- Return the next item in the ``Value`` iterator, or ``No_Value_Ref`` if -- there is no item left in the iterator. Raise a ``Precondition_Failure`` -- if ``Value`` is null or not a reference to an iterator. ----------------------- -- Struct/node types -- ----------------------- function Is_Base_Struct_Type (T : Type_Ref) return Boolean; -- Return whether ``T`` references a struct or node type. -- -- All functions below will raise a ``Precondition_Failure`` if passed a -- type which does not satisfy this predicate as ``T`` formals. function Base_Struct_Type_Name (T : Type_Ref) return Name_Type; -- Return the name for the given struct/node type function All_Base_Struct_Types (Id : Language_Id) return Type_Ref_Array; -- Return the list of all base struct types that the given language defines ------------------ -- Struct types -- ------------------ function Is_Struct_Type (T : Type_Ref) return Boolean; -- Return whether ``T`` references a struct type. -- -- All functions below will raise a ``Precondition_Failure`` if passed a -- type which does not satisfy this predicate as ``Struct`` formals. function Struct_Type_Name (Struct : Type_Ref) return Name_Type; -- Return the name for the given struct type function All_Struct_Types (Id : Language_Id) return Type_Ref_Array; -- Return the list of all struct types that the given language defines function Create_Struct (T : Type_Ref; Values : Value_Ref_Array) return Value_Ref; -- Create a struct of the given ``T`` type, with the given ``Values``. -- Raise a ``Precondition_Failure`` if any of the following is true: -- -- * ``T`` is null; -- * ``Values`` contains a null value reference; -- * ``Values`` does not match ``T``'s fields, both in number or in types; -- * one ``Values`` item does not belong to the same language as ``T``. ---------------- -- Node types -- ---------------- function Is_Node_Type (T : Type_Ref) return Boolean; -- Return whether ``T`` references a node type. -- -- All functions below will raise a ``Precondition_Failure`` if passed -- a type which does not satisfy this predicate as ``Node``/``Parent`` -- formals. function Root_Node_Type (Id : Language_Id) return Type_Ref; -- Return the type for the root node in the given language function Node_Type_Name (Node : Type_Ref) return Name_Type; -- Return the name for the given node type function Node_Type_Repr_Name (Node : Type_Ref) return Text_Type; -- Return the "representation" name (i.e. name used in text dumps) for the -- given node type. function Is_Abstract (Node : Type_Ref) return Boolean; -- Return whether ``Node`` designates an abstract node function Is_Token_Node (Node : Type_Ref) return Boolean; -- Return whether ``Node`` designates a token node function Token_Node_Kind (Node : Type_Ref) return Token_Kind_Ref; -- Assuming that ``Node`` designates a token node and that the owning -- language has unparsers enabled, return the associated token kind. function Is_List_Node (Node : Type_Ref) return Boolean; -- Return whether ``Node`` designates a list node function List_Element_Type (Node : Type_Ref) return Type_Ref; -- Assuming that ``Node`` designates a list node, return the type for its -- elements. Raise a ``Precondition_Failure`` if ``Node`` does not -- designates a list node. function Is_Concrete (Node : Type_Ref) return Boolean is (not Is_Abstract (Node)); function Base_Type (Node : Type_Ref) return Type_Ref; -- If ``Node`` is the root node type, raise a ``Bad_Type_Error`` exception. -- Otherwise, return ``Node``'s base type. function Derived_Types (Node : Type_Ref) return Type_Ref_Array; -- Return type references for all direct derivations for ``Node`` function Last_Derived_Type (Node : Type_Ref) return Type_Index; -- Return the index of the ``Result`` type so that the ``Node .. Result`` -- range contains exactly all node types that derive (directly or -- indirectly) from ``Node``. function Is_Derived_From (Node, Parent : Type_Ref) return Boolean; -- Return whether the ``Node`` node type derives (directly or indirectly) -- from ``Parent``. function All_Node_Types (Id : Language_Id) return Type_Ref_Array; -- Return the list of all node types that the given language defines function Grammar_Rule_Type (Rule : Grammar_Rule_Ref) return Type_Ref; -- Return the type for nodes that the given parsing ``Rule`` can create ------------------------- -- Struct/node members -- ------------------------- type Struct_Member_Ref is private; -- Reference to a struct member (field or property) No_Struct_Member_Ref : constant Struct_Member_Ref; -- Special value to express no struct member reference type Struct_Member_Ref_Array is array (Positive range <>) of Struct_Member_Ref; function Debug_Name (Member : Struct_Member_Ref) return String; -- Return "X.Y" where X is the type that owns this member and Y is the name -- of this member, or "" if ``Member`` is null. function Owner (Member : Struct_Member_Ref) return Type_Ref; -- Return the type that owns this member. Raise a ``Precondition_Failure`` -- exception if ``Member`` is ``No_Struct_Member_Ref``. function Is_Property (Member : Struct_Member_Ref) return Boolean; -- Whether ``Member`` is a property function Is_Field (Member : Struct_Member_Ref) return Boolean is (not Is_Property (Member)); -- Whether ``Member`` is a field (simple field for structs, syntax field -- for nodes). function Is_Null_For (Member : Struct_Member_Ref; Node : Type_Ref) return Boolean; -- Return whether ``Member`` is a syntax field that is always null for -- ``Node``. function Syntax_Field_Index (Member : Struct_Member_Ref; Node : Type_Ref) return Positive; -- Return the 1-based index corresponding to the given ``Member`` in the -- given ``Node`` type. -- -- Raise a ``Precondition_Failure`` exception if: -- -- * ``Node`` is not a valid node type; -- * ``Node`` is not a concrete node type; -- * ``Member`` is not a syntax field for ``Node``; -- * ``Member`` is a null syntax field for ``Node``. function All_Members (Id : Language_Id) return Struct_Member_Ref_Array; -- Return all struct members that the given language defines function Members (Struct : Type_Ref) return Struct_Member_Ref_Array; -- Return the list of members that ``Struct`` has function Member_Name (Member : Struct_Member_Ref) return Name_Type; -- Return the name of ``Member`` function Member_Type (Member : Struct_Member_Ref) return Type_Ref; -- Return the type of ``Member`` type Any_Struct_Member_Index is new Natural; subtype Struct_Member_Index is Any_Struct_Member_Index range 1 .. Any_Struct_Member_Index'Last; -- Language-specific index to designate a struct member. -- -- A given language defines members for the ``1 .. Last_Struct_Member -- (Language)`` range: see the ``Last_Struct_Member`` function below. No_Struct_Member : constant Any_Struct_Member_Index := 0; -- Special ``Any_Struct_Member_Index`` to mean: no reference to an argument function To_Index (Member : Struct_Member_Ref) return Struct_Member_Index; -- Return the index of the given struct member. Raise a -- ``Precondition_Failure`` exception if ``Member`` is -- ``No_Struct_Member``. function From_Index (Id : Language_Id; Member : Struct_Member_Index) return Struct_Member_Ref; -- Return the struct member for the given language corresponding to the -- ``Member`` index. Raise a ``Precondition_Failure`` exception if -- ``Member`` is not a valid member index for the given language. function Last_Struct_Member (Id : Language_Id) return Struct_Member_Index; -- Return the last struct member index that is valid for the given language subtype Any_Argument_Index is Natural; subtype Argument_Index is Any_Argument_Index range 1 .. Any_Argument_Index'Last; -- Index of a property argument No_Argument_Index : constant Any_Argument_Index := 0; function Member_Argument_Type (Member : Struct_Member_Ref; Argument : Argument_Index) return Type_Ref; -- Return the type of the given property argument function Member_Argument_Name (Member : Struct_Member_Ref; Argument : Argument_Index) return Name_Type; -- Return the name of the given property argument function Member_Argument_Default_Value (Member : Struct_Member_Ref; Argument : Argument_Index) return Value_Ref; -- Return the default value for the given property argument, or -- ``No_Value_Ref`` if it has no default value. function Member_Last_Argument (Member : Struct_Member_Ref) return Any_Argument_Index; -- Return the index of ``Member``'s last argument according to the given -- language. If it has no argument, return ``No_Argument_Index``. type Value_Or_Error (Is_Error : Boolean) is limited record case Is_Error is when False => Value : Value_Ref; when True => Error : Exception_Occurrence; end case; end record; function Eval_Member (Value : Value_Ref; Member : Struct_Member_Ref; Arguments : Value_Ref_Array := (1 .. 0 => No_Value_Ref)) return Value_Ref; -- Evaluate the given ``Member`` of ``Value`` with the given ``Arguments`` -- and return the result value. Raise a ``Precondition_Failure`` if any of -- the following is true: -- -- * ``Value`` is null, or not a struct; -- * ``Member`` is null, does not belong to the same language as ``Value``, -- or not a valid member for ``Value``; -- * ``Arguments`` does not match the arguments that ``Member`` expects. function Eval_Member (Value : Value_Ref; Member : Struct_Member_Ref; Arguments : Value_Ref_Array := (1 .. 0 => No_Value_Ref)) return Value_Or_Error; -- Likewise, but also return an exception occurrence if the evaluation -- triggers a managed error. -- -- Note that this function may still propagate an exception itself, but in -- that case, it is because ``Eval_Member`` is incorrectly used: an error -- is *returned* only if it is the evaluated member that raises an -- exception. function Eval_Node_Member (Value : Lk_Node; Member : Struct_Member_Ref; Arguments : Value_Ref_Array := (1 .. 0 => No_Value_Ref)) return Value_Ref; -- Shortcut for ``Eval_Member``, working directly on a node function Eval_Node_Member (Value : Lk_Node; Member : Struct_Member_Ref; Arguments : Value_Ref_Array := (1 .. 0 => No_Value_Ref)) return Value_Or_Error; -- Shortcut for ``Eval_Member``, working directly on a node and returning -- exception occurences. function Eval_Syntax_Field (Value : Lk_Node; Member : Struct_Member_Ref) return Lk_Node; -- Shortcut for ``Eval_Member``, valid for syntax fields only --------------- -- Name maps -- --------------- type Name_Map is tagged private; -- Map from names to enum types, enum values, struct types and struct -- members for a given casing convention and a given language. function Create_Name_Map (Id : Language_Id; Symbols : Symbol_Table; Enum_Types : Casing_Convention; Enum_Values : Casing_Convention; Struct_Types : Casing_Convention; Struct_Members : Casing_Convention) return Name_Map; -- Return a map from names to types, values and members for the given -- language. Names are encoded according to the given casing convention for -- each kind of entity, and internalized using the ``Symbols`` symbol -- table. function Lookup_Type (Self : Name_Map; Name : Symbol_Type) return Type_Ref; -- Look for an enum/struct type indexed in ``Self`` called ``Name``. Return -- it if there is one, or ``No_Type_Ref`` is no type matches that name. -- The casing convention used for ``Name`` must match with the one used to -- create ``Self``. function Lookup_Enum_Value (Self : Name_Map; Enum : Type_Ref; Name : Symbol_Type) return Enum_Value_Ref; -- Look in ``Self`` for the enum value called ``Name`` for the given -- ``Enum`` type. Return it if there is one, or ``No_Enum_Value_Ref`` is no -- value matches that name. The casing convention used for ``Name`` must -- match with the one used to create ``Self``. function Lookup_Struct_Member (Self : Name_Map; Struct : Type_Ref; Name : Symbol_Type) return Struct_Member_Ref; -- Look for the ``Struct`` member called ``Name``. Return it if there is -- one, or ``No_Struct_Member_Ref`` if this struct type has no such member. -- The casing convention used for ``Name`` must match with the one used to -- create ``Self``. private type Type_Ref is record Id : Any_Language_Id; Index : Any_Type_Index; -- Either this is ``No_Type_Ref``, and in that case both members should -- be null/zero, either ``Index`` designates a valid type for the -- language ``Id`` represents. end record; type Internal_Value_Access is access all Langkit_Support.Internal.Introspection.Internal_Value'Class; type Value_Ref is new Ada.Finalization.Controlled with record Value : Internal_Value_Access; end record; overriding procedure Adjust (Self : in out Value_Ref); overriding procedure Finalize (Self : in out Value_Ref); type Enum_Value_Ref is record Enum : Type_Ref; Index : Any_Enum_Value_Index; -- Either this is ``No_Enum_Value_Ref``, and in that case both members -- should be null/zero, either ``Index`` designates a valid value for -- the enum type ``Enum`` represents. end record; type Struct_Member_Ref is record Id : Any_Language_Id; Index : Any_Struct_Member_Index; -- Either this is ``No_Struct_Member_Ref``, and in that case both -- members should be null/zero, either ``Index`` designates a valid -- member for the language ``Id`` represents. end record; No_Type_Ref : constant Type_Ref := (null, 0); No_Value_Ref : constant Value_Ref := (Ada.Finalization.Controlled with Value => null); No_Enum_Value_Ref : constant Enum_Value_Ref := (No_Type_Ref, 0); No_Struct_Member_Ref : constant Struct_Member_Ref := (null, 0); package Named_Type_Maps is new Ada.Containers.Hashed_Maps (Key_Type => Symbol_Type, Element_Type => Type_Ref, Hash => Hash, Equivalent_Keys => "="); package Enum_Value_Maps is new Ada.Containers.Hashed_Maps (Key_Type => Symbol_Type, Element_Type => Enum_Value_Ref, Hash => Hash, Equivalent_Keys => "="); type Enum_Value_Map_Array is array (Type_Index range <>) of Enum_Value_Maps.Map; type Enum_Value_Maps_Access is access Enum_Value_Map_Array; procedure Free is new Ada.Unchecked_Deallocation (Enum_Value_Map_Array, Enum_Value_Maps_Access); type Struct_Member_Name_Array is array (Struct_Member_Index range <>) of Symbol_Type; type Struct_Member_Names_Access is access Struct_Member_Name_Array; procedure Free is new Ada.Unchecked_Deallocation (Struct_Member_Name_Array, Struct_Member_Names_Access); type Name_Map is new Ada.Finalization.Controlled with record Id : Language_Id; -- Language for which this map was created. -- -- Since this member is automatically initialized to null and creating a -- name map always assigns it a non-null value, we can compare this -- member to null to check if the name map has been created. Type_Map : Named_Type_Maps.Map; -- Map enum/struct type names to type references Enum_Value_Maps : Enum_Value_Maps_Access; -- For each enum type, map from enum value names to enum value -- references. Struct_Member_Names : Struct_Member_Names_Access; -- Names for all struct members end record; overriding procedure Adjust (Self : in out Name_Map); overriding procedure Finalize (Self : in out Name_Map); procedure Check_Name_Map (Self : Name_Map); -- Raise a ``Precondition_Failure`` exception if ``Self`` is not -- initialized. end Langkit_Support.Generic_API.Introspection;