Version 1.18 of si99s/si99-0024-1.txt

Unformatted version of si99s/si99-0024-1.txt version 1.18
Other versions for file si99s/si99-0024-1.txt

!standard 3.9          09-02-28 SI99-0024-1/14
!class amendment 06-11-12
!status ARG Approved 10-0-0 09-02-20
!status work item 06-11-12
!status received 06-11-12
!priority High
!difficulty Hard
!subject Provide a semantic subsystem in addition to existing syntactic model
!summary
ASIS currently provides a model that is closely based on the syntax. This SI proposes to add a set of packages that provide a canonicalized semantic model, which captures more of the work already done by (the front end of) the compiler.
!problem
The current ASIS model is very tied to the syntactic structure of the program library. However, there are times when it is more efficient to use a more abstract, semantic model. This SI proposes such a model. In one sense, it may be thought of as defining a "symbol table" for the program library.
!proposal
SEMANTIC VS. STRUCTURAL MODEL
This SI proposes that an additional set of packages be provided as part of ASIS that represent a semantic model of the program library. As currently defined, ASIS provides a structural model of the library, with a relatively limited set of semantic queries that allow references to be traversed to their definitions, and allow traversal between declarations and bodies, or partial and full declarations. The existing approach provides all the information inherent in the original source program, and as such, ensures that other tools can do all the same work that the compiler could do. However, the existing approach doesn't capture much of that work in a useful form, and instead essentially requires that it be performed by every tool.
In this SI we propose to capture more of the work already performed by the compiler, and along the way attempt to canonicalize the information so that the many special cases inherent in the syntactic structure of the program library are reduced to a smaller number of semantic concepts that nevertheless still cover the entire realm of possibilities.
One way to think about what we are doing is providing a "symbol table" for the program library.
Details of the proposal can be found below.
!wording
In Section 5, add after ASIS_Inappropriate_Line_Number in Asis.Exceptions:
ASIS_Inappropriate_View : exception;
Raised when ASIS is given an inappropriate view or profile.
ASIS_Not_In_Context : exception;
Raised for any operation defined in Asis.Views, Asis.Program_Units, Asis.Subtype_Views, Asis.Object_Views, Asis.Profiles, Asis.Callable_Views, Asis.Package_Views, Asis.Generic_Views, Asis.Exception_Views, Asis.Statement_Views, and their subpackages and children, if the result is an entity that is not part of the current context.
Note: This can happen, for instance, if the View is of an incomplete view, and the full view is not part of the context. It also can happen if only a portion of the semantic dependencies of the queried unit is included in the context.
-----------------------------------------------------
XX ASIS Semantic Subsystem
XX.0 Introduction
The ASIS Semantic Subsystem comprises a set of packages that provide a semantic-level interface to the program library. Other parts of ASIS are based on Elements that represent syntactic constructs. The Semantic Subsystem defines a set of types that represent views of entities defined by syntactic constructs. The type View is the most general, representing a view of essentially any kind of program entity. There are seven first-level extensions of View defined: Subtype_View, Object_View, Callable_View, Package_View, Generic_View, Statement_View, and Exception_View. Elementary_Subtype and Composite_Subtype are extensions of Subtype_View, and there are further extensions for particular subcategories of types.
Object_View is used to represent a view that might denote either an object or a pure value. Callable_View is used to represent subprograms, entries, accept statements, etc. A Package_View is used to represent either the full view or the limited view of a package. Generic_View, Statement_View, and Exception_View are used to represent generic units, statements, and exceptions, respectively.
In addition to View and its various extensions, the Semantic Subsystem includes a type View_Declaration used to represent the declaration of a View. These are grouped into Region_Parts, which in turn are grouped into Declarative_Regions.
There are various operations for navigating back and forth between the Semantic Subsystem and other parts of ASIS. When starting from the Semantic Subsystem, given a View_Declaration, there is an operation that identifies the corresponding Asis.Declaration and one that identifies the associated Asis.Identifier. Given a View, there is an operation that identifies the Asis.Expression that denotes it, if any. Given a Declarative_Region, there is an operation that identifies the Asis.Element that defines it, if any.
When starting from an Asis.Element, there is an operation that given an Asis.Declaration can identify the corresponding View_Declaration, one that given an Asis.Type_Definition can identify the corresponding Subtype_View, and one that given an Asis.Expression can identify the corresponding Object_View (or more generally "View" in the case where the Expression is a Name).
The generic packages Containers.Vectors and Containers.Holders are instantiated as needed for various of the types used in the ASIS Semantic Subsystem. These instantiations permit more convenient manipulation of objects of a class-wide type, allowing for extensible lists and more easily updatable variables, despite the fact that class-wide types are indefinite, and normally require initialization at the point of declaration.
Note: The semantic subsystem does not include a value that represents no view. Such a value would be difficult to define for an interface type (which allows no objects), and it is not needed for the intended use of the views. A holder container in the empty state can mean "no view" if the program requires that functionality.
Note: Exception ASIS_Not_In_Context is raised for any operation defined in the packages of the semantic subsystem, if the result is an entity that is not part of the current context (see Section 5). An entity could not be present in the current context because, for instance, if the View is of an incomplete view, and the full view is not included in the context. It also can happen if only a portion of the semantic dependencies of the queried unit is included in the context, and the query returns an entity defined in one of the semantic dependencies that is not included in the context.
AASIS Implementation Note:
The ASIS semantic subsystem is intended to be implemented on top of the internal representation used by the semantic analysis part of the Ada implementation. This typically consists of an annotated abstract syntax tree, with a symbol table that either exists along side the annotated tree, or is interwoven through it. The internal representation may be built up "on the fly" while the ASIS-based tool is executing, or may be a persistent, disk-based representation (such as the typical implementation of the DIANA intermediate representation).
One of the challenges of the ASIS interface is that an ASIS-based tool may store the result from a call on an ASIS operation indefinitely, while the underlying implementation may be paging in and out parts of the internal representation. Thus it is presumed that the Ada types used to represent an ASIS element in the syntactic subsystem, or an ASIS view in the semantic subsystem, consist of an identifier that remains meaningful indefinitely, potentially coupled with a shorter-lived "memory pointer" (access value) that gives more direct access to the associated part of the internal representation.
In the syntactic subsystem, there are relatively few types, with the most important being the Element, and this can map quite directly to an Ada record object, presumably giving the element kind, and the conceptual "pointer" to the associated internal representation "node."
In the Semantic Subsystem, there is a hierarchy of interface types at the user level. Underneath, there is still probably a record object that similarly would have an entity/view kind and a conceptual pointer to the corresponding symbol table or annotated tree "node." In some cases, the semantic subsystem may make distinctions or combine information in a view in a way different from that of the compiler's internal representation. In these cases, this record object might need to carry additional information, since there is no single node in the compiler's internal representation that matches the Semantic Subsystem notion.
To support the hierarchy of interface types used in the Semantic Subsystem, this "record object" would be of a (concrete) tagged type in a parallel hierarchy of non-interface types. This parallel hierarchy would allow sharing of data structures and operations across the Semantic Subsystem. Each point in the non-interface type hierarchy would implement the corresponding type in the interface hierarchy. This allows the "concrete" types to share as little or as much as desired with each other, while preserving the "purity" of an interface hierarchy at the user level.
End AASIS Implementation Note
-----------------------------------------------------
XX.1 Package Asis.Views
The library package Asis.Views shall exist. The package shall provide interfaces equivalent to those described in the following subclauses.
XX.1.1 Type View_Kinds and type View
type View_Kinds is (...);
subtype Exception_View_Kinds is View_Kinds range An_Exception .. An_Exception_Renaming;
subtype Generic_View_Kinds is View_Kinds range A_Generic_Package .. A_Generic_Subprogram_Renaming;
subtype Callable_View_Kinds is View_Kinds range A_Noninstance_Subprogram .. A_Task_Entry;
subtype Object_View_Kinds is View_Kinds range A_Standalone_Object .. An_Expr_Value;
subtype Subtype_View_Kinds is View_Kinds range A_Boolean_Subtype .. An_Incomplete_Subtype;
subtype Package_View_Kinds is View_Kinds range A_Noninstance_Package..A_Limited_Package_View;
subtype Statement_View_Kinds is View_Kinds range A_Label_Statement_View .. A_Loop_Statement_View;
type View is interface;
The tagged type View is the root of a hierarchy of types used to represent views on program entities. The distinct kinds of entities are enumerated by the type View_Kind. Subranges of this enumeration type are defined to correspond to the extensions of the View type.
function Kind (V : View) return View_Kinds is abstract;
function Is_Object_Or_Value (V : View) return Boolean is abstract;
function Is_Callable (V : View) return Boolean is abstract;
function Is_Subtype (V : View) return Boolean is abstract;
function Is_Package (V : View) return Boolean is abstract;
function Is_Generic (V : View) return Boolean is abstract;
function Is_Exception (V : View) return Boolean is abstract;
function Is_Statement (V : View) return Boolean is abstract;
V specifies the view to query for each of these functions.
The View_Kind of an object V whose type is covered by View'Class may be determined by the Kind dispatching operation. In addition, Boolean queries Is_Object_Or_View, Is_Callable, Is_Subtype, Is_Package, Is_Generic, Is_Exception, and Is_Statement, are provided to determine to which extension of View the specified view V belongs.
XX.1.2 Function Element_Denoting_View
function Element_Denoting_View (V : View) return Asis.Element is abstract;
V specifies the view to query.
Returns an Asis.Element that denotes the View V. This is one of the primary mechanisms for navigating from the Semantic Subsystem to the other parts of ASIS.
Note: This is the element that includes the syntactic construct that caused the particular usage represented by the view. This is not the declaration of the view unless the view of a declaration.
Example: for instance, in the following program fragment:
declare Var : Boolean := Func; -- (1) begin loop exit when Var; -- (2) ...
If V is a view representing the use of Var in the exit statement at (2), the element returned by Element_Denoting_View is the one in the exit statement, and not the one in the declaration. In particular, if E is the element representing the exit statement, then Exit_Condition (E) = Element_Denoting_View (V).
XX.1.3 Type Conventions
type Conventions is ( Intrinsic_Convention, Ada_Convention, Protected_Convention, Entry_Convention, Other_Convention, Unspecified_Convention);
function Convention (V : View) return Conventions is abstract;
function Convention_Identifier (V : View) return Wide_String is abstract;
V specifies the view to query for both of these functions.
Each program entity can have an associated convention. The convention of the entity identified by the view V is given by the functions Convention and Convention_Identifier. Function Convention_Identifier returns "Intrinsic", "Ada", "Protected", or "Entry" when function Convention returns the corresponding value of type Conventions. When Convention returns Other_Convention, Convention_Identifier returns the convention identifier given in the pragma Convention, Import, or Export used to specify the convention of the entity.
XX.1.4 Subpackage Declarative_Regions
The subpackage Declarative_Regions within package Views provides semantic information about the declaration, if any, associated with a given view of an entity. This includes the identifier introduced by the declaration to denote the view, as well as indicating the particular part of the declarative region in which the declaration occurred. The subpackage has the contents given in the following subclauses.
XX.1.5 Type Declarative_Region and type View_Declaration
type Declarative_Region is private;
type View_Declaration is interface;
A View_Declaration specifies the declaration, if any, that defines a given view. A Declarative_Region represents a declarative region in which declarations may occur.
function Defined_View (D : View_Declaration) return View'Class is abstract;
function Declaration (D : View_Declaration) return Asis.Declaration is abstract;
function View_Identifier (D : View_Declaration) return Asis.Identifier is abstract;
function Is_Imported (D : View_Declaration) return Boolean is abstract;
function Enclosing_Region (D : View_Declaration) return Declarative_Region is abstract;
D specifies the view declaration to query for each of these functions.
Function Defined_View returns the View defined by declaration D. If a declaration defines multiple views because the list of Identifiers has more that one element, then a separate View_Declaration is associated with each view, just as though they were defined by separate declarations. Function Declaration returns the Asis.Declaration corresponding to the declaration D. Function View_Identifier returns the Asis.Identifier introduced by the declaration D. Function Is_Imported returns True if and only if the declaration D is completed with a pragma Import.
Function Enclosing_Region returns the Declarative_Region enclosing the declaration D.
function Are_Declared_In_Same_Region (Decl1, Decl2 : View_Declaration) return Boolean is abstract;
Decl1 and Decl2 specify the view declarations to compare.
Returns True if Enclosing_Region (Decl1) and Enclosing_Region (Decl2) represent the same region, and returns False otherwise.
function Is_Declared_Earlier_In_Same_Region (Earlier, Later : View_Declaration) return Boolean is abstract;
Earlier and Later specify the view declarations to compare.
Returns True if Are_Declared_In_Same_Region (Earlier, Later) is True and Eariler occurs before Later in the logical sequence of the program, where a package specification is presumed to occur before the corresponding package body in this sequence. Otherwise returns False.
XX.1.6 Type Region_Part and type Region_Part_Kinds
type Region_Part is private;
type Region_Part_List is array (Positive range <>) of Region_Part;
type Region_Part_Kinds is (Generic_Formal_Part, Callable_Formal_Part, Discriminant_Part, Entry_Family_Index_Part, Record_Part, Extension_Part, Package_Visible_Part, Package_Private_Part, Task_Visible_Part, Task_Private_Part, Protected_Visible_Part, Protected_Private_Part, Body_Part, Block_Declarative_Part, Loop_Declarative_Part, Child_Part);
Certain declarative regions are broken up into distinct parts, represented by the type Region_Part. The type Region_Part_Kinds enumerates the distinct kinds of region parts.
function Kind (P : Region_Part) return Region_Part_Kinds;
function Is_Empty (P : Region_Part) return Boolean;
function Declarative_Items (P : Region_Part) return Asis.Declarative_Item_List;
procedure Declarations (P : Region_Part; Declarations : out View_Declaration_Vector'Class);
function Region (P : Region_Part) return Declarative_Region;
P specifies the region part to query for each of these subprograms.
Function Kind returns the kind of the region part P. Function Is_Empty returns True if and only if the region part P has no declarative items within it. Function Declarative_Items returns the list of Asis.Declarative_Items that occur within the region part P. Procedure Declarations returns in the parameter Declarations a vector comprising the declarations that occur within the region part P. Function Region returns the Declarative_Region of which the region part P is a part.
function All_Region_Parts (R : Declarative_Region) return Region_Part_List;
function Visible_Region_Parts (R : Declarative_Region) return Region_Part_List;
function Private_Part (R : Declarative_Region) return Region_Part;
function Body_Part (R : Declarative_Region) return Region_Part;
R specifies the declarative region to query for each of these functions.
Function All_Region_Parts returns an array of the region parts comprising the declarative region R. Function Visible_Region_Parts returns an array of the visible parts of the declarative region R.
Function Private_Part returns the private part of the declarative region R. Private_Part returns an empty Region_Part if R has no private part, or if the private part of R is empty. Function Body_Part returns the body part of the declarative region R. Body_Part returns an empty Region_Part if R has no body part, or if the body part of R is empty. The declarative region of a loop statement or of a block statement has only a body part. Other kinds of regions may have multiple region parts.
function Enclosing_Region_Part (D : View_Declaration) return Region_Part is abstract;
D specifies the view declaration to query.
Returns the Region_Part in which the declaration D occurs.
XX.1.7 Nested Declarative Regions
function Defining_Construct (R : Declarative_Region) return Asis.Element;
function Has_Defining_Declaration (R : Declarative_Region) return Boolean;
function Defining_Declaration (R : Declarative_Region) return View_Declaration'Class;
function Has_Enclosing_Region (R : Declarative_Region) return Boolean;
function Enclosing_Region (R : Declarative_Region) return Declarative_Region;
R specifies the declarative region to query for each of these functions.
Declarative regions are generally associated with language constructs, and may be nested. Function Defining_Construct returns the Asis.Element with which the declarative region R is associated.
Function Has_Defining_Declaration returns True if and only if the declarative region R is associated with an enclosing declaration. Function Defining_Declaration returns the declaration that defines the region R. Defining_Declaration raises ASIS_Inappropriate_View if Has_Defining_Declaration (R) returns False.
Function Has_Enclosing_Region returns True if and only the region R has an enclosing region. Function Enclosing_Region returns the enclosing region of region R, or raises ASIS_Inappropriate_View if Has_Enclosing_Region (R) returns False.
function Enclosing_Compilation_Unit (D : View_Declaration) return Asis.Compilation_Unit is abstract;
function Expanded_Name (D : View_Declaration) return Wide_String is abstract;
D specifies the view declaration to query for each of these functions.
Function Enclosing_Compilation_Unit returns the Asis.Compilation_Unit representing the compilation unit in which the declaration D occurs. Function Expanded_Name returns the Wide_String representing the full expanded name denoting the declaration D (encoded in UTF-16, as described in Section 3).
XX.1.8 Overloading, Overriding, and Renaming
function Is_Overloadable (D : View_Declaration) return Boolean is abstract;
function Is_Overriding (D : View_Declaration) return Boolean is abstract;
procedure Overridden_Declarations (D : View_Declaration; Overridden : out View_Declaration_Vector'Class) is abstract;
function Is_Renaming (D : View_Declaration) return Boolean is abstract;
function Renamed_View (D : View_Declaration) return View'Class is abstract;
function Is_Renaming_As_Body (D : View_Declaration) return Boolean is abstract;
D specifies the view declaration to query for each of these subprograms.
Declarations may overload, override, or rename other declarations. Function Is_Overloadable returns True if and only if the declaration D is a declaration that may be overloaded. Function Is_Overriding returns True if and only if the declaration D overrides one or more other declarations. Procedure Overridden_Declarations returns (in the Overridden parameter) a vector of those declarations overridden by the declaration D. Overridden will be an empty vector if D does not override any other declaration. Function Is_Renaming returns True if and only if the declaration D is a renaming of another view. Function Renamed_View returns the view that the declaration D is a renaming of, or raises ASIS_Inappropriate_View if Is_Renaming (D) returns False. Function Is_Renaming_As_Body returns True if and only if the declaration D is a renaming-as-body.
XX.1.9 Aspect Items
function Aspect_Items (D : View_Declaration) return Asis.Aspect_Clause_List is abstract;
D specifies the view declaration to query.
Function Aspect_Items returns a list of aspect clauses that are visible for the view of the declaration D.
XX.1.10 View Declaration Vectors
package View_Declaration_Vectors is new Ada.Containers.Indefinite_Vectors (Positive, View_Declaration'Class); type View_Declaration_Vector is new View_Declaration_Vectors.Vector with null record;
Type View_Declaration_Vector allows the declaration of a list of View_Declarations.
These are the last interfaces defined in subpackage Declarative_Regions; following subclauses contain interfaces directly defined in package Asis.Views.
XX.1.11 Views and Declarations
function Has_Declaration (V : View) return Boolean is abstract;
function Declaration (V : View) return View_Declaration'Class is abstract;
function Defines_Declarative_Region (V : View) return Boolean is abstract;
function Defined_Region (V : View) return Declarative_Region is abstract;
V specifies the view to query for all of these functions.
Function Has_Declaration returns True if and only if view V was defined by a declaration. Function Declaration returns the declaration that defines view V, or raises ASIS_Inappropriate_View if Has_Declaration (V) returns False. Function Defines_Declarative_Region returns True if and only if view V is of an entity that has its own declarative region. Function Defined_Region returns the declarative region of the entity represented by view V, or raises ASIS_Inappropriate_View if Defines_Declarative_Region (V) returns False.
XX.1.12 Representational and Operational Aspects
type Language_Defined_Aspect_Kinds is (Address, Alignment, Asynchronous, Atomic, Atomic_Components, Bit_Order, Coding, Component_Size, Controlled, Convention, Discarded_Names, Exported, External_Tag, Imported, Independent, Independent_Components, Input, Layout, No_Return, Output, Packing, Read, Size, Small, Storage_Pool, Storage_Size, Stream_Size, Volatile, Volatile_Components, Write);
function Is_Aspect_Specified (V : View; Aspect : Language_Defined_Aspect_Kinds) return Boolean is abstract;
function Is_Aspect_Directly_Specified (V : View; Aspect : Language_Defined_Aspect_Kinds) return Boolean is abstract;
V specifies the view to query and Aspect specifies the language-defined aspect to query for both of these functions.
Function Is_Aspect_Specified returns True if the representational or operational aspect Aspect is specified for the declaration of the view V, and returns False otherwise. Function Is_Aspect_Directly_Specified returns True if the representational or operational aspect Aspect is directly specified for the declaration of the view V, and returns False otherwise.
These functions return False if the Aspect named cannot be specified for the kind of entity represented by V, or if the view V does not have a declaration.
type Implementation_Defined_Aspect_Kinds is (<implementation-defined>);
function Is_Aspect_Specified (V : View; Aspect : Implementation_Defined_Aspect_Kinds) return Boolean is abstract;
function Is_Aspect_Directly_Specified (V : View; Aspect : Implementation_Defined_Aspect_Kinds) return Boolean is abstract;
type Implementation_Defined_Aspect_Kinds is an implementation-defined enumeration of aspect names; it should include the names of all implementation-defined aspects defined by the implementation.
V specifies the view to query and Aspect specifies the implementation-defined aspect to query for both of these functions.
Function Is_Aspect_Specified returns True if the representational or operational aspect Aspect is specified for the declaration of the view V, and returns False otherwise. Function Is_Aspect_Directly_Specified returns True if the representational or operational aspect Aspect is directly specified for the view V, and returns False otherwise.
These functions return False if the named aspect cannot be specified for the kind of entity represented by V, or if the view V does not have a declaration.
Note: To find out all of the aspect clauses for an entity, use function Aspect_Items on the declaration of the entity.
XX.1.13 View Holders
package View_Holders is new Ada.Containers.Holders (View'Class); type View_Holder is new View_Holders.Holder with null record;
Type View_Holder allows the declaration of an uninitialized variable (including a component) that can hold a View.
XX.1.14 View Vectors
package View_Vectors is new Ada.Containers.Indefinite_Vectors (Positive, View'Class); type View_Vector is new View_Vectors.Vector with null record;
Type View_Vector allows the declaration of a list of Views.
---------------------------------------------------------------
XX.2 Package Asis.Program_Units
The library package Asis.Program_Units shall exist. The package shall provide interfaces equivalent to those described in the following subclauses.
XX.2.1 Type Program_Unit
type Program_Unit is interface and View_Declaration;
The type Program_Unit is an extension of View_Declaration, and is used to represent the declaration of a program unit (package, subprogram, task unit, protected unit, protected entry, or generic unit).
function Requires_Completion (P : Program_Unit) return Boolean is abstract;
function Has_Body (P : Program_Unit) return Boolean is abstract;
function Body_Of_Program_Unit (P : Program_Unit) return Asis.Declaration is abstract;
function Is_Instance (P : Program_Unit) return Boolean is abstract;
function Instantiated_Generic (P : Program_Unit) return Program_Unit'Class is abstract;
function Actual_Part (P : Program_Unit) return Asis.Association_List is abstract;
function Expanded_Body (P : Program_Unit) return Asis.Declaration is abstract;
P specifies the program unit view declaration to query for each of these functions.
Function Requires_Completion returns True if and only if the program unit P requires a completion. Function Has_Body returns True if the program unit P has a completion that is a body. Function Body_Of_Program_Unit returns the body that completes the program unit P, or raises ASIS_Inappropriate_View if Has_Body (P) returns False.
Function Is_Instance returns True if and only if the program unit P is an instance of a generic unit. Function Instantiated_Generic returns the generic unit given the instance P, or raises ASIS_Inappropriate_View if Is_Instance (P) returns False. Function Actual_Part returns the list of actual parameters passed to the instantiation P, or raises ASIS_Inappropriate_View if Is_Instance (P) returns False. Function Expanded_Body returns the expanded body of the instantiation P, or raises ASIS_Inappropriate_View if Is_Instance returns False.
XX.2.2 Compilation Units
function Is_Compilation_Unit (P : Program_Unit) return Boolean is abstract;
procedure Depends_Semantically_On ( P : Program_Unit; Depends_On : out Program_Unit_Vector'Class) is abstract;
function Is_Subunit (P : Program_Unit) return Boolean is abstract;
function Stub_Of_Program_Unit (P : Program_Unit) return Asis.Declaration is abstract;
function Is_Library_Item (P : Program_Unit) return Boolean is abstract;
P specifies the program unit view declaration to query for each of these functions.
Function Is_Compilation_Unit returns True if and only if the program unit P is separately compiled as a compilation unit. Procedure Depends_Semantically_On returns in the Depends_On parameter the vector of other compilation units on which compilation unit P depends semantically, or raises ASIS_Inappropriate_View if Is_Compilation_Unit (P) returns False.
Function Is_Subunit returns True if and only if the program unit P is separately compiled as a subunit. Function Stub_Of_Program_Unit returns the Asis.Declaration that specifies the stub of the subunit P, or raises ASIS_Inappropriate_View if Is_Subunit (P) returns False. Function Is_Library_Item returns True if and only if the program unit P is separately compiled as a library item.
XX.2.3 Type Library_Item
type Library_Item is interface and Program_Unit;
The type Library_Item is used to represent program units that are separately compiled as library items -- those for which Is_Library_Item returns True.
function Has_Parent_Library_Unit (L : Library_Item) return Boolean is abstract;
function Parent_Library_Unit (L : Library_Item) return Library_Item'Class is abstract;
function Is_Pure_Unit (L : Library_Item) return Boolean is abstract;
function Is_Preelaborated_Unit (L : Library_Item) return Boolean is abstract;
function Is_Remote_Call_Interface_Unit (L : Library_Item) return Boolean is abstract;
function Is_Remote_Types_Unit (L : Library_Item) return Boolean is abstract;
L specifies the library unit view declaration to query for each of these functions.
Function Has_Parent_Library_Unit returns True if and only if the library item L is a child of a unit other than package Standard. Function Parent_Library_Unit returns the parent library item of a child unit L, or raises ASIS_Inappropriate_View if Has_Parent_Library_Unit (L) returns False.
Function Is_Pure_Unit returns True if and only if the library item L is declared pure. Function Is_Preelaborated_Unit returns True if and only if the library item L is preelaborated. Function Is_Remote_Call_Interface_Unit returns True if and only if the pragma Remote_Call_Interface applies to the library item L. Function Is_Remote_Types_Unit returns True if and only if the pragma Remote_Types applies to the library item L.
XX.2.4 Program Unit Vectors
package Program_Unit_Vectors is new Ada.Containers.Indefinite_Vectors (Positive, Program_Unit'Class); type Program_Unit_Vector is new Program_Unit_Vectors.Vector with null record;
Type Program_Unit_Vector allows the declaration of a list of Program_Units.
---------------------------------------------------------------
XX.3 Package Subtype_Views
The library package Asis.Subtype_Views shall exist. The package shall provide interfaces equivalent to those described in the following subclauses.
XX.3.1 Type Subtype_View
type Subtype_View is interface and View;
The type Subtype_View represents a view of a subtype.
function Is_Elementary (S : Subtype_View) return Boolean is abstract; function Is_Composite (S : Subtype_View) return Boolean is abstract;
function Is_Scalar (S : Subtype_View) return Boolean is abstract; function Is_Enumeration (S : Subtype_View) return Boolean is abstract; function Is_Boolean (S : Subtype_View) return Boolean is abstract; function Is_Character (S : Subtype_View) return Boolean is abstract; function Is_Numeric (S : Subtype_View) return Boolean is abstract; function Is_Discrete (S : Subtype_View) return Boolean is abstract; function Is_Integer (S : Subtype_View) return Boolean is abstract; function Is_Signed_Integer (S : Subtype_View) return Boolean is abstract; function Is_Modular_Integer (S : Subtype_View) return Boolean is abstract; function Is_Real (S : Subtype_View) return Boolean is abstract; function Is_Fixed_Point (S : Subtype_View) return Boolean is abstract; function Is_Ordinary_Fixed_Point (S : Subtype_View) return Boolean is abstract; function Is_Decimal_Fixed_Point (S : Subtype_View) return Boolean is abstract; function Is_Floating_Point (S : Subtype_View) return Boolean is abstract; function Is_Access (S : Subtype_View) return Boolean is abstract; function Is_Access_To_Object (S : Subtype_View) return Boolean is abstract; function Is_Access_To_Subprogram (S : Subtype_View) return Boolean is abstract;
function Is_Record (S : Subtype_View) return Boolean is abstract; function Is_Record_Extension (S : Subtype_View) return Boolean is abstract; function Is_Array (S : Subtype_View) return Boolean is abstract; function Is_String (S : Subtype_View) return Boolean is abstract; function Is_Protected (S : Subtype_View) return Boolean is abstract; function Is_Task (S : Subtype_View) return Boolean is abstract; function Is_Tagged (S : Subtype_View) return Boolean is abstract;
function Is_Formal_Subtype (S : Subtype_View) return Boolean is abstract; function Is_Descended_From_Formal_Subtype (S : Subtype_View) return Boolean is abstract;
function Is_Constrained (S : Subtype_View) return Boolean is abstract; function Is_Definite (S : Subtype_View) return Boolean is abstract;
The category and other characteristics of the subtype can be determined with the above functions. S specifies the view of a subtype to query for each of these functions.
XX.3.2 Types, Subtypes, and Constraints
function Are_Of_Same_Type (Left, Right : Subtype_View) return Boolean is abstract;
Left and Right specify the views of subtypes to test.
Returns True if and only if Left and Right represent subtypes of the same type.
function Is_Unadorned_Subtype (S : Subtype_View) return Boolean is abstract;
function Unadorned_Subtype (S : Subtype_View) return Subtype_View'Class is abstract;
function Is_First_Subtype (S : Subtype_View) return Boolean is abstract;
function Is_Secondary_Subtype (S : Subtype_View) return Boolean is abstract;
function First_Subtype (S : Subtype_View) return Subtype_View'Class is abstract;
function Has_Constraint (S : Subtype_View) return Boolean is abstract;
function Constraint (S : Subtype_View) return Asis.Constraint is abstract;
S specifies the view of a subtype to query for each of these functions.
Function Is_Unadorned_Subtype returns True if the subtype S is scalar and the base subtype of its type, or the subtype S is tagged and the first subtype of its type, or the subtype S is neither tagged nor scalar, and the subtype has no constraint or null exclusion. Otherwise, Is_Unadorned_Subtype returns False.
Function Unadorned_Subtype returns the a view of a subtype without any constraints or null exclusions. Specifically, if the subtype S is a scalar subtype, Unadorned_Subtype returns a view of the base subtype of S. If the subtype S is a tagged subtype, Unadorned_Subtype returns the first subtype of the type of S. If the subtype S is neither tagged nor scalar, Unadorned_Subtype returns a view of a subtype of the type of S that has no constraints or null exclusions.
Note: The definition of Unadorned_Subtype corresponds to the meaning of the italicized T in the Ada Standard. The Ada Standard does not name this concept.
Function Is_First_Subtype returns True if and only if the subtype S is the first subtype of its type. Function Is_Secondary_Subtype (S) is equivalent to not Is_First_Subtype (S). Function First_Subtype returns the a view of the first subtype for the type of the subtype S. If Is_First_Subtype (S) is True, First_Subtype returns S.
Function Has_Constraint returns True if and only if the subtype S has a constraint. Function Constraint returns the Asis element representing the constraint of the subtype S, or raises ASIS_Inappropriate_View if Has_Constraint (S) returns False.
XX.3.3 Static Subtypes and Constraints
function Is_Static_Subtype (S : Subtype_View) return Boolean is abstract;
function Is_Statically_Constrained (S : Subtype_View) return Boolean is abstract;
S specifies the view of a subtype to query for each of these functions.
Function Is_Static_Subtype returns True if and only if the subtype S is static, and returns False otherwise.
Function Is_Statically_Constrained returns True if and only if the subtype S is constrained and its constraint is static, and returns False otherwise.
function Are_Statically_Matching (S1, S2 : Subtype_View) return Boolean is abstract;
S1 and S2 specify views of subtypes to query.
Function Are_Statically_Matching returns True if and only if the subtypes S1 and S2 are of the same type and are statically matching, and returns False otherwise.
function Is_Statically_Compatible (S : Subtype_View; With_Subtype : Subtype_View) return Boolean is abstract;
S and With_Subtype specify views of subtypes to query.
Function Is_Statically_Compatible returns True if and only if the constraint of the subtype S is statically compatible with the subtype With_Subtype, and returns False otherwise.
XX.3.4 Derived Types and Primitive Subprograms
procedure Primitive_Subprograms (S : Subtype_View; Primitives : out Declarative_Regions.View_Declaration_Vector) is abstract;
function Is_Derived (S : Subtype_View) return Boolean is abstract;
function Parent_Subtype (S : Subtype_View) return Subtype_View'Class is abstract;
S specifies the view of a subtype to query for each of these subprograms.
Function Primitive_Subprograms returns in the parameter Primitives a vector of declarations for the primitive subprograms of the type of the subtype S. Function Is_Derived returns True if and only if the type of the subtype S is defined by a derived_type_definition, a private_extension_declaration, or a formal_derived_type_definition. Function Parent_Subtype returns the parent or ancestor subtype for the derived type S, or raises ASIS_Inappropriate_View if Is_Derived (S) returns False.
function Is_Descendant (S : Subtype_View; Of_Subtype : Subtype_View) return Boolean is abstract;
S and Of_Subtype specify the views of subtypes to compare.
Function Is_Descendant returns True if and only if the type of the subtype S is a descendant of the type of the subtype Of_Subtype.
function Ultimate_Ancestor (S : Subtype_View) return Subtype_View'Class is abstract;
S specifies the view of a subtype to query.
Function Ultimate_Ancestor returns an ancestor of the subtype S that is not itself a descendant of any other type; it will be the type itself if Is_Derived (S) returns False and Progenitors (S) (see XX.7.3) returns an empty vector. If there are multiple such ancestors, Ultimate_Ancestor returns the one that is not an interface type, if there is one. If all of the ultimate ancestors are interfaces, Ultimate_Ancestor returns an unspecified one.
Note: Function Ultimate_Ancestor may stop on an incomplete or partial view. If the ultimate full view is needed, call Full_View on the result of Ultimate_Ancestor.
XX.3.5 Incomplete and Partial Views
function Is_Incomplete_View (S : Subtype_View) return Boolean is abstract;
function Complete_View (S : Subtype_View) return Subtype_View'Class is abstract;
function Is_Partial_View (S : Subtype_View) return Boolean is abstract;
function Full_View (S : Subtype_View) return Subtype_View'Class is abstract;
S specifies the view of a subtype to query for all of these functions.
Function Is_Incomplete_View returns True if and only if the type of S is an incomplete view of a type.
If S is an incomplete view, Complete_View returns the completion of S. Otherwise, Complete_View returns S.
Function Is_Partial_View returns True if and only if the type of S is a partial view of a type.
Function Full_View returns the full view of S. If S is already a full view, Full_View returns S.
Note: The Full_View of an incomplete type gives the full view of the completion. This is even true for an incomplete view declared by a limited view of a private type. However, the Complete_View of such an incomplete view is the private type.
XX.3.6 Subtype Aspects
function Subtype_Size (S : Subtype_View) return ASIS_Natural is abstract;
function Subtype_Alignment (S : Subtype_View) return ASIS_Natural is abstract;
S specifies the view of a subtype to query for both of these functions.
Function Subtype_Size returns the same value as the Size attribute of the subtype S, if the object is elementary or if its size is specified. The result is implementation-defined in other cases, and may be ASIS_Natural'Last. Function Subtype_Alignment returns the same value as the Alignment attribute of the subtype S.
XX.3.7 Subtype Holders
package Subtype_Holders is new Ada.Containers.Holders (Subtype_View'Class); type Subtype_Holder is new Subtype_Holders.Holder with null record;
Type Subtype_Holder allows the declaration of an uninitialized variable (including a component) that can hold a Subtype_View.
XX.3.8 Subtype Vectors
package Subtype_Vectors is new Ada.Containers.Indefinite_Vectors (Positive, Subtype_View'Class); type Subtype_Vector is new Subtype_Vectors.Vector with null record;
Type Subtype_Vector allows the declaration of a list of Subtype_Views.
---------------------------------------------------------------
XX.4 Package Asis.Object_Views
The library package Asis.Object_Views shall exist. The package shall provide interfaces equivalent to those described in the following subclauses.
XX.4.1 Type Object_View
type Object_View is interface and View;
The type Object_View represents views of objects and values, as denoted by names or expressions.
function Is_Constant_View (O : Object_View) return Boolean is abstract;
function Nominal_Subtype (O : Object_View) return Subtype_View'Class is abstract;
O specifies the view of an object to query for both of these functions.
Function Is_Constant_View returns True if and only if the object O is a constant view of an object, or is a view of a value. Function Nominal_Subtype returns the nominal subtype of the view.
XX.4.2 Components of Objects
function Is_Component (O : Object_View) return Boolean is abstract;
function Enclosing_Object (O : Object_View) return Object_View'Class is abstract;
function Is_Indexed_Component (O : Object_View) return Boolean is abstract;
function Index_Value (O : Object_View; Dimension : Positive := 1) return Object_View'Class is abstract;
function Is_Selected_Component (O : Object_View) return Boolean is abstract;
function Selector_Declaration (O : Object_View) return View_Declaration'Class is abstract;
function Position (O : Object_View) return Object_View'Class is abstract;
function First_Bit (O : Object_View) return Object_View'Class is abstract;
function Last_Bit (O : Object_View) return Object_View'Class is abstract;
O specifies the view of an object to query for each of these functions.
Function Is_Component returns True if and only if the view O is of a component of an enclosing composite object. Function Enclosing_Object returns a view of the enclosing object of the component O, or raises ASIS_Inappropriate_View if Is_Component (O) returns False.
Function Is_Indexed_Component returns True if and only if the view O is of an indexed component. Function Index_Value returns a view of the value of the index of the indexed component O, or raises ASIS_Inappropriate_View if Is_Indexed_Component (O) returns False.
Function Is_Selected_Component returns True if and only if the view O is of a selected component. Function Selector_Declaration returns the declaration of the selected component O, or raises ASIS_Inappropriate_View if Is_Selected_Component (O) returns False. Functions Position, First_Bit, and Last_Bit, return a view of the value of a reference to the corresponding attribute of the given component O, or raise ASIS_Inappropriate_View if Is_Selected_Component (O) returns False.
XX.4.3 Aliased Views and Dereferences
function Is_Aliased (O : Object_View) return Boolean is abstract;
type Static_Accessibility_Level is range 0 .. <implementation-defined>;
Library_Level : constant Static_Accessibility_Level := 0; Deepest_Accessibility_Level : constant Static_Accessibility_Level; Incomparable_Accessibility_Level : constant Static_Accessibility_Level;
function Static_Accessibility (O : Object_View) return Static_Accessibility_Level is abstract;
function Is_Dereference (O : Object_View) return Boolean is abstract;
function Dereferenced_Value (O : Object_View) return Object_View'Class is abstract;
function Is_Implicit_Dereference (O : Object_View) return Boolean is abstract;
O specifies the view of an object to query for each of these functions.
Function Is_Aliased returns True if and only if the view O is aliased. Function Static_Accessibility returns the static accessibility level of the view O, or raises ASIS_Inappropriate_View if Is_Aliased (O) returns False. The static accessibility level value 0 is returned if the view O is of a library level object. Incomparable_Accessibility_Level is returned if the view O is a dereference of an access-to-object parameter. Deepest_Accessibility_Level is returned if the view O is a dereference of an access-to-subprogram parameter.
Function Is_Dereference returns True if and only if the object O is a dereference of an access-to-object value. Function Dereferenced_Value returns a view of the access value that was dereferenced in the dereference O, or raises ASIS_Inappropriate_View if Is_Dereference (O) returns False. Function Is_Implicit_Dereference returns True if and only if the object O is an implicit dereference of an access-to-object value.
XX.4.4 Static Values
type Longest_Discrete is range <implementation-defined>;
function Is_Static_Discrete (O : Object_View) return Boolean is abstract;
function Static_Discrete_Value (O : Object_View) return Longest_Discrete is abstract;
function Static_Discrete_Image (O : Object_View) return Wide_String is abstract;
function Is_Static_Real (O : Object_View) return Boolean is abstract;
function Static_Real_Value (O : Object_View) return Longest_Float is abstract;
function Static_Real_Image (O : Object_View) return Wide_String is abstract;
function Is_Static_String (O : Object_View) return Boolean is abstract;
function Static_String_Value (O : Object_View) return Wide_String is abstract;
O specifies the view of an object to query for each of these functions.
Function Is_Static_Discrete returns True if and only if the view O is a view of the value of a static expression of a discrete type. Function Static_Discrete_Value returns the value of the static discrete expression O, or raises ASIS_Inappropriate_View if Is_Static_Discrete (O) returns False. If the value is outside the range of Longest_Discrete, it raises Constraint_Error. Function Static_Discrete_Image returns the image of the value of the static discrete expression O, with the syntax used by the Image attribute of its type (with a leading minus if negative, and a leading space otherwise), or raises ASIS_Inappropriate_View if Is_Static_Discrete (O) returns False. A correct image is returned even if the value is outside the base range of the type.
Note: Static_Discrete_Value can be used on integer, character, and enumeration values.
Function Is_Static_Real returns True if and only if the view O is of the value of a static expression of a real type. Function Static_Real_Value returns the value of the static real expression O converted to the Longest_Float type, or raises ASIS_Inappropriate_View if Is_Static_Real (O) returns False. If the value is outside the range of Longest_Real, it raises Constraint_Error. Function Static_Real_Image returns a string containing an optional minus sign, followed by a pair of non-negative integers separated by the character '/' corresponding to a numerator and a denominator for the reduced rational representation of the exact absolute value of the static real expression O. The denominator is one when the numerator is zero. Static_Real_Image raises ASIS_Inappropriate_View if Is_Static_Real (O) returns False.
Function Is_Static_String returns True if and only if the view O is of the value of a static expression of a string type. Function Static_String_Value returns a Wide_String whose characters match the corresponding characters of the static value of the string expression O (encoded in UTF-16, as described in Section 3). The function raises ASIS_Inappropriate_View if Is_Static_String (O) returns False.
XX.4.5 Representational Object Attributes
function Object_Size (O : Object_View) return ASIS_Natural is abstract;
function Object_Alignment (O : Object_View) return ASIS_Natural is abstract;
O specifies the view of an object to query for both of these functions.
Function Object_Size returns the same value as the Size attribute of the object O, if the object is elementary or if its size or its subtype's size is specified. The result is implementation-defined in other cases, and may be ASIS_Natural'Last. Function Object_Alignment returns the same value as the Alignment attribute of the object O. If the view is of a value rather than an object, the result of Object_Size and Object_Alignment is implementation-defined, but is within the range of values possible for objects of the same type.
XX.4.6 Object Holders
package Object_Holders is new Ada.Containers.Holders (Object_View'Class); type Object_Holder is new Object_Holders.Holder with null record;
Type Object_Holder allows the declaration of an uninitialized variable (including a component) that can hold a Object_View.
---------------------------------------------------------------
XX.5 Package Asis.Profiles
The library package Asis.Profiles shall exist. The package shall provide interfaces equivalent to those described in the following subclauses.
XX.5.1 Type Profile
type Profile is private;
The type Profile specifies the profile of a callable entity.
XX.5.2 Function Parameters
function Parameters (P : Profile) return Declarative_Regions.Region_Part;
P specifies the Profile to query.
Returns the Region_Part containing the parameters of the profile.
If there are no parameters in the profile, returns a Region_Part for which Is_Empty returns true.
XX.5.3 Function queries
function Is_Function (P : Profile) return Boolean; function Result_Subtype (P : Profile) return Subtype_View'Class;
P specifies the Profile to query for both of these functions.
Is_Function returns True if the profile represents a function, and returns False otherwise.
Result_Subtype returns the Subtype_View of the return part of the profile, if Is_Function (P) is True. Otherwise, Result_Subtype raises ASIS_Inappropriate_View.
XX.5.4 Family index queries
function Has_Family_Index (P : Profile) return Boolean; function Family_Index_Subtype (P : Profile) return Subtype_View'Class;
P specifies the Profile to query for both of these functions.
Has_Family_Index returns True if the Profile applies to an entry family, and returns False otherwise.
Family_Index_Subtype returns the entry index subtype of the profile P if Has_Family_Index (P) is True. Otherwise, Family_Index_Subtype raises ASIS_Inappropriate_View.
XX.5.5 Profile conventions
function Convention (P : Profile) return Conventions; function Convention_Identifier (P : Profile) return Wide_String;
P specifies the Profile to query for both of these functions.
Function Convention returns the Convention of Profile P. Function Convention_Identifier returns "Intrinsic", "Ada", "Protected", or "Entry" when function Convention returns the corresponding value of type Conventions. When Convention returns Other_Convention, Convention_Identifier returns the identifier given in the pragma Convention, Import, or Export used to specify the convention of the entity.
---------------------------------------------------------------
XX.6 Package Asis.Subtype_Views.Elementary
The library package Asis.Subtype_Views.Elementary shall exist. The package shall provide interfaces equivalent to those described in the following subclauses.
XX.6.1 Elementary subtypes
type Elementary_Subtype is interface and Subtype_View;
The type Elementary_Subtype represents a view of an elementary subtype.
function Is_Universal (E : Elementary_Subtype) return Boolean is abstract;
E specifies the Elementary_Subtype to query.
Returns True if and only if the type of the given subtype is universal_integer, universal_real, universal_fixed, or universal_access. Returns False otherwise.
XX.6.2 Scalar subtypes
type Scalar_Subtype is interface and Elementary_Subtype;
The type Scalar_Subtype represents a view of a scalar subtype.
function Base_Subtype (S : Scalar_Subtype) return Scalar_Subtype'Class is abstract;
function Low_Bound (S : Scalar_Subtype) return Object_View'Class is abstract; function High_Bound (S : Scalar_Subtype) return Object_View'Class is abstract;
function Is_Root_Numeric (S : Scalar_Subtype) return Boolean is abstract;
S specifies the view of a scalar subtype to query for each of these functions.
Function Base_Subtype returns a view of the base subtype of the type of the subtype S. Functions Low_Bound and High_Bound return a view of the corresponding bound of the scalar subtype S. If the scalar subtype S is unconstrained, Low_Bound and High_Bound return a view of the corresponding bound of the base range of the type of the subtype.
Function Is_Root_Numeric returns True if the type of S is root_integer or root_real, and returns False otherwise.
XX.6.3 Discrete subtypes
type Discrete_Subtype is interface and Scalar_Subtype;
The type Discrete_Subtype represents a view of a discrete subtype.
xx.6.4 Access subtypes
type Access_Subtype is interface and Elementary_Subtype;
The type Access_Subtype represents a view of an access subtype.
function Is_Anonymous_Access (A : Access_Subtype) return Boolean is abstract;
function Is_Access_Parameter (A : Access_Subtype) return Boolean is abstract;
function Is_Access_Result (A : Access_Subtype) return Boolean is abstract;
function Is_Access_Discriminant (A : Access_Subtype) return Boolean is abstract;
function Static_Accessibility (A : Access_Subtype) return Object_Views.Static_Accessibility_Level is abstract;
function Excludes_Null (A : Access_Subtype) return Boolean is abstract;
A specifies the view of an access subtype to query for each of these functions.
Function Is_Anonymous_Access returns True if and only if the type of the subtype A is defined by an access_definition rather than an access_type_definition. Function Is_Access_Parameter returns True if and only if the type of the subtype A is that of an access parameter. Function Is_Access_Result returns True if and only if the type of the subtype A is the result type of a function with an access result. Function Is_Access_Discriminant returns True if and only if the type of the subtype A is that of an access discriminant.
Function Static_Accessibility returns the static accessibility level of the type of the subtype A. The static accessibility level value 0 is returned if the type is a library level type. Incomparable_Accessibility_Level is returned for the type of an access-to-object parameter. Deepest_Accessibility_Level is returned for the type of an access-to-subprogram parameter. Function Excludes_Null returns True if and only if the subtype A excludes null.
XX.6.5 Access-to-object subtypes
type Access_To_Object_Subtype is interface and Access_Subtype;
The type Access_To_Object_Subtype represents a view of an access-to-object subtype.
function Designated_Subtype (A : Access_To_Object_Subtype) return Subtype_View'Class is abstract;
function Is_Access_To_Constant (A : Access_To_Object_Subtype) return Boolean is abstract;
function Is_Pool_Specific (A : Access_To_Object_Subtype) return Boolean is abstract;
function Storage_Pool (A : Access_To_Object_Subtype) return Object_View'Class is abstract;
function Storage_Size (A : Access_To_Object_Subtype) return Object_View'Class is abstract;
A specifies the Access_To_Object_Subtype to query for each of these functions.
Function Designated_Subtype returns a view of the designated subtype of the access-to-object subtype A. Function Is_Access_To_Constant returns True if and only if the type of the subtype A is an access-to-constant type. Function Is_Pool_Specific returns True if and only if the type of the subtype A is pool specific.
Function Storage_Pool returns a view of the object denoted by the Storage_Pool attribute of the type of the subtype A, if Storage_Pool is specified. The result is implementation-defined in other cases.
Function Storage_Size returns a view of a value equal to the Storage_Size of the type of the subtype A, if the type is defined to have zero Storage_Size, or if its Storage_Size is specified. The result is implementation-defined in other cases.
XX.6.6 Access-to-subprogram subtypes
type Access_To_Subprogram_Subtype is interface and Access_Subtype;
The type Access_To_Subprogram_Subtype represents a view of an access-to-subprogram subtype.
function Designated_Profile (A : Access_To_Subprogram_Subtype) return Profile is abstract;
A specifies the view of an access-to-subprogram subtype to query.
Returns a view of the designated profile of the type of the subtype A.
---------------------------------------------------------------
XX.7 Package Asis.Subtype_Views.Composite
The library package Asis.Subtype_Views.Composite shall exist. The package shall provide interfaces equivalent to those described in the following subclauses.
XX.7.1 Composite Subtypes
type Composite_Subtype is interface and Subtype_View;
The type Composite_Subtype represents a view of a composite subtype.
function Is_Limited (C : Composite_Subtype) return Boolean is abstract;
function Contains_Task (C : Composite_Subtype) return Boolean is abstract;
function Needs_Finalization (C : Composite_Subtype) return Boolean is abstract;
function Has_Preelaborable_Initialization (C : Composite_Subtype) return Boolean is abstract;
function Has_Unknown_Discriminants (C : Composite_Subtype) return Boolean is abstract;
function Has_Known_Discriminants (C : Composite_Subtype) return Boolean is abstract;
function Discriminants (C : Composite_Subtype) return Declarative_Regions.Region_Part is abstract;
function Discriminants_Have_Defaults (C : Composite_Subtype) return Boolean is abstract;
function Has_Nondiscriminant_Region_Parts (C : Composite_Subtype) return Boolean is abstract;
function Nondiscriminant_Region_Parts (C : Composite_Subtype) return Declarative_Regions.Region_Part_List is abstract;
C specifies the view of a composite subtype to query for each of these functions.
Function Is_Limited returns True if and only if the subtype C is limited. Function Contains_Task returns True if and only if the type of the subtype C has a part that is a task type. Function Needs_Finalization returns True if and only if the type of the subtype C needs finalization. Function Has_Preelaborable_Initialization returns True if and only if the subtype C has preelaborable initialization.
Function Has_Unknown_Discriminants returns True if and only if the subtype C has unknown discriminants. Function Has_Known_Discriminants returns True if and only if the subtype C has known discriminants. Function Discriminants returns a Region_Part for the discriminant part of the subtype C, or raises ASIS_Inappropriate_View if the subtype view does not have known discriminants. Function Discriminants_Have_Defaults returns True if and only if the subtype C has known discriminants with default_expressions.
Function Has_Nondiscriminant_Region_Parts returns True if and only if the subtype C is a descendant of a record type, a record extension, a task type, or a protected type. Function Nondiscriminant_Region_Parts returns a list of Region_Parts, one for each separate visible region part, each comprising components, entries, and protected subprograms from a single list of components or items of subtype C. The returned list is empty if Has_Nondiscriminant_Region_Parts (C) is False.
XX.7.2 Array Subtypes
type Array_Subtype is interface and Composite_Subtype;
The type Array_Subtype represents a view of an array subtype.
function Component_Subtype (A : Array_Subtype) return Subtype_View'Class is abstract;
function Num_Dimensions (A : Array_Subtype) return Positive is abstract;
function Index_Subtype (A : Array_Subtype; Dimension : Positive := 1) return Elementary.Discrete_Subtype'Class is abstract;
function Is_String_Subtype (A : Array_Subtype) return Boolean is abstract;
A specifies the view of an array subtype to query for each of these functions.
Function Component_Subtype returns a view of the component subtype of the type of the array subtype A. Function Num_Dimensions returns a count of the number of dimensions of the type of the array subtype A. Function Index_Subtype returns a view of the index subtype of the type of the array subtype A. Function Is_String_Subtype returns True if and only if the type of the subtype A is a string type.
XX.7.3 Tagged Subtypes
type Tagged_Subtype is interface and Composite_Subtype;
The type Tagged_Subtype represents a view of a tagged subtype.
function Is_Interface (T : Tagged_Subtype) return Boolean is abstract; function Is_Abstract (T : Tagged_Subtype) return Boolean is abstract;
function Is_Synchronized_Tagged (T : Tagged_Subtype) return Boolean is abstract;
function Is_Classwide (T : Tagged_Subtype) return Boolean is abstract;
function Root_Subtype (T : Tagged_Subtype) return Tagged_Subtype'Class is abstract;
function Is_Specific (T : Tagged_Subtype) return Boolean is abstract;
function Classwide_Subtype (T : Tagged_Subtype) return Tagged_Subtype'Class is abstract;
procedure Progenitors ( T : Tagged_Subtype; Progenitors : out Tagged_Subtype_Vector'Class) is abstract;
function External_Tag (T : Tagged_Subtype) return String is abstract;
T specifies the view of a tagged subtype to query for each of these subprograms.
Function Is_Interface returns True if and only if the type of the subtype T is an interface. Function Is_Abstract returns True if and only if the type of the subtype T is abstract. Function Is_Synchronized_Tagged returns True if and only if the type of the subtype T is a synchronized tagged type. Function Is_Classwide returns True if and only if the type of the subtype T is classwide.
Function Root_Subtype returns a view of the subtype of the classwide subtype T, or raises ASIS_Inappropriate_View if the type of the subtype T is not classwide. Function Is_Specific returns True if and only if the type of the subtype T is a specific tagged type. Function Classwide_Subtype returns a view of the classwide subtype rooted at the subtype T, equivalent to the Class attribute of the subtype T, or raises ASIS_Inappropriate_View if the subtype T is not a specific tagged subtype. Function Progenitors returns a vector of the progenitors, if any, of the type of the subtype T. The result is an empty vector if the type has no progenitors. Function External_Tag returns a view of the string value equal to the External_Tag of the type of the subtype T, if External_Tag is specified. Otherwise, the result is implementation-defined.
XX.7.4 Tagged Subtype Vectors
package Tagged_Subtype_Vectors is new Ada.Containers.Indefinite_Vectors (Positive, Tagged_Subtype'Class); type Tagged_Subtype_Vector is new Tagged_Subtype_Vectors.Vector with null record;
Type Tagged_Subtype_Vector allows the declaration of a list of Tagged_Subtypes.
---------------------------------------------------------------
XX.8 Package Asis.Callable_Views
The library package Asis.Callable_Views shall exist. The package shall provide interfaces equivalent to those described in the following subclauses.
XX.8.1 Type Callable_View
type Callable_View is interface and View;
The type Callable_View represents views of callable entities, as denoted by names or expressions.
XX.8.2 function Callable_Profile
function Callable_Profile (C : Callable_View) return Profile is abstract;
C specifies the callable view to query.
Returns the Profile of the callable view C.
XX.8.3 Callable view categorization
function Is_Subprogram (C : Callable_View) return Boolean is abstract; function Is_Enumeration_Literal (C : Callable_View) return Boolean is abstract; function Is_Procedure (C : Callable_View) return Boolean is abstract; function Is_Entry (C : Callable_View) return Boolean is abstract; function Is_Function (C : Callable_View) return Boolean is abstract; function Is_Abstract (C : Callable_View) return Boolean is abstract; function Is_Null (C : Callable_View) return Boolean is abstract;
C specifies the callable view to query for each of these functions.
Is_Subprogram returns True if the callable view C is of a subprogram (that is, C has Callable_View_kinds of A_Noninstance_Subprogram, A_Subprogram_Instance, A_Subprogram_Renaming, A_Protected_Subprogram, An_Imported_Subprogram, An_Attribute_Subprogram, An_Intrinsic_Subprogram, or A_Designated_Subprogram), and returns False otherwise.
Is_Enumeration_Literal returns True if the callable view C is of an enumeration literal, and returns False otherwise.
Is_Procedure returns True if the callable view C represents a procedure, and returns False otherwise.
Is_Entry returns True if the callable view C represents an entry (that is, C has Callable_View_kinds of A_Protected_Entry or A_Task_Entry), otherwise it returns False.
Is_Function returns True if the callable view C represents a function, and returns False otherwise.
Is_Abstract returns True if the callable view C represents a subprogram declared by an abstract_subprogram_declaration or an abstract inherited subprogram, and returns False otherwise.
Is_Null returns true if the Callable_View represents a Null Procedure, and returns False otherwise.
XX.8.4 Primitive operations
function Is_Primitive (C : Callable_View) return Boolean is abstract;
C specifies the callable view to query.
Returns True if the callable view C is of a primitive subprogram. Returns False otherwise.
procedure Primitive_On_Subtypes ( C : Callable_View; Subtypes : out Subtype_Vector) is abstract;
C specifies the callable view to query.
Subtype_Vector is a vector of the subtypes returned by the query.
Returns a vector of the subtypes on which the subprogram C is primitive. For a callable view C that is not primitive, returns Subtype_Vector(Subtype_Vectors.Empty_Vector).
function Is_Dispatching_Operation (C : Callable_View) return Boolean is abstract;
C specifies the callable view to query.
Returns True if C represents a dispatching operation. Returns False otherwise.
function Associated_Tagged_Type (C : Callable_View) return Composite.Tagged_Subtype'Class is abstract;
C specifies the callable view to query.
Returns the controlling tagged type of a dispatching operation C. If C is not a dispatching operation, ASIS_Inappropriate_View is raised.
XX.8.5 Prefixed views
function Is_Prefixed_View (C : Callable_View) return Boolean is abstract;
C specifies the callable view to query.
Returns True if C is a prefixed view of a subprogram. Returns False otherwise.
function Prefix_Object (C : Callable_View) return Object_View'Class is abstract;
C specifies the callable view to query.
if Is_Prefixed_View (C) is True, returns the Object_View of the of the prefix of C. Otherwise, raises ASIS_Inappropriate_View.
function Unprefixed_Callable_View (C : Callable_View) return Callable_View'Class is abstract;
C specifies the callable view to query.
if Is_Prefixed_View (C), returns the standard (unprefixed) form callable_view of C. Returns C otherwise.
XX.8.6 Access-to-subprogram views
function Is_Designated_Subprogram (C : Callable_View) return Boolean is abstract;
C specifies the callable view to query.
Returns True if the callable view C represents an access to subprogram call; otherwise, returnd False.
function Access_To_Subprogram_Value (C : Callable_View) return Object_View is abstract;
C specifies the callable view to query.
If Is_Designated_Subprogram (C) is True, returns the Object_View of the access_to_subprogram object associated with the callable view C.
Otherwise, raises ASIS_Inappropriate_View.
function Is_Implicit_Dereference (C : Callable_View) return Boolean is abstract;
C specifies the callable view to query.
Is_Implicit_Dereference returns True if and only if the callable view C is an implicit dereference of an access-to-subprogram value.
XX.8.7 Callable view holders
package Callable_Holders is new Ada.Containers.Holders (Callable_View'Class); type Callable_Holder is new Callable_Holders.Holder with null record;
Type Callable_Holder allows the declaration of an uninitialized variable (including a component) that can hold a Callable_View.
---------------------------------------------------------------
XX.9 Package Asis.Object_Views.Access_Views
The library package Asis.Object_Views.Access_Views shall exist. The package shall provide interfaces equivalent to those described in the following subclauses.
XX.9.1 Type Access_Object_View
type Access_Object_View is interface and Object_View;
The type Access_Object_View represents views of access objects and values, as denoted by names or expressions.
xx.9.2 Designated object operations
function Is_Object_Access_Attribute_Reference (O : Access_Object_View) return Boolean is abstract;
function Designated_Object (O : Access_Object_View) return Object_View'Class is abstract;
function Is_Implicit_Access_Attribute_Reference (O : Access_Object_View) return Boolean is abstract;
function Is_Subprogram_Access_Attribute_Reference (O : Access_Object_View) return Boolean is abstract;
function Designated_Subprogram (O : Access_Object_View) return Callable_View'Class is abstract;
O specifies the view of an access object to query for each of these functions.
Function Is_Object_Access_Attribute_Reference returns True if and only if the view O is of an (explicit or implicit) Access or Unchecked_Access attribute reference of an aliased object. Function Designated_Object returns the object designated by the access value in the attribute O, or raises ASIS_Inappropriate_View if Is_Object_Access_Attribute_Reference (O) returns False.
Function Is_Implicit_Access_Attribute_Reference returns True if and only if the view O is of a value produced by an implicit Access attribute reference as part of a call on a prefixed view of a subprogram, where the first parameter of the unprefixed subprogram is an access parameter.
Function Is_Subprogram_Access_Attribute_Reference returns True if and only if the view O is of an (explicit or implicit) Access attribute reference of a subprogram. Function Designated_Subprogram returns a view of the subprogram designated by the access value in the attribute O, or raises ASIS_Inappropriate_View if Is_Subprogram_Access_Attribute_Reference (O) returns False.
---------------------------------------------------------------
XX.10 Package Asis.Package_Views
The library package Asis.Package_Views shall exist. The package shall provide interfaces equivalent to those described in the following subclauses.
XX.10.1 Type Package View
type Package_View is interface and View;
The type Package_View represents a view of a package. Every package has a non-limited view. A package may also have a limited view.
AASIS Note: All library packages and packages nested in library packages have a limited view. Other packages (nested in bodies, subprograms, tasks, or blocks) do not.
XX.10.2 Function Has_Limited_View
function Has_Limited_View (P : Package_View) return Boolean is abstract;
P specifies the package view to query.
Returns True if a limited view of P exists (including if P is a limited view). Returns False otherwise.
XX.10.3 Function Is_Limited_View
function Is_Limited_View (P : Package_View) return Boolean is abstract;
P specifies the package view to query.
Returns True if P denotes the limited view of a package. Returns False otherwise.
XX.10.4 Function Full_View
function Full_View (P : Package_View) return Package_View'Class is abstract;
P specifies the package view to query.
If Is_Limited_View (P) then returns the corresponding full view of P. In this case, Limited_View (Full_View (P)) = P.
Returns P otherwise.
In all cases, Is_Limited_View (Full_View (P)) = False.
XX.10.5 Function Is_Full_View
function Is_Full_View (P : Package_View) return Boolean is abstract;
P specifies the package view to query.
Returns True if P denotes the full view of a package. Returns False otherwise.
In all cases, Is_Full_View (P) /= Is_Limited_View (P).
XX.10.6 Function Limited_View
function Limited_View (P : Package_View) return Package_View'Class is abstract;
P specifies the package view to query.
If Is_Limited_View (P) is True, then returns P. Otherwise, if Has_Limited_View (P) is True, then returns the corresponding limited view of P. If Has_Limited_View (P) is False, then raises ASIS_Inappropriate_View.
AASIS Note: If Has_Limited_View (P) then
Is_Limited_View (Limited_View (P)) = True
and
Full_View (Limited_View (P)) = P.
XX.10.7 Package predicates
function Is_Formal_Package (P : Package_View) return Boolean is abstract;
P specifies the package view to query.
Returns True if P denotes a formal package. Returns False otherwise.
XX.10.8 Part selectors
function Visible_Part (P : Package_View) return Declarative_Regions.Region_Part is abstract;
function Private_Part (P : Package_View) return Declarative_Regions.Region_Part is abstract;
P specifies the package view to query.
Visible_Part yields the appropriate (either limited or full) view of the visible part of the package. Private_Part yields the appropriate
(either limited or full) view of the private part of the package.
Note: To find the body of a package view P, use Body_Part (Defined_Region (P)). This technique can also be used to access the stubs of a package.
XX.10.9 Package Holders
package Package_Holders is new Ada.Containers.Holders (Package_View'Class); type Package_Holder is new Package_Holders.Holder with null record;
Type Package_Holder allows the declaration of an uninitialized variable (including a component) that can hold a Package_View.
---------------------------------------------------------------
XX.11 Package Asis.Generic_Views
The library package Asis.Generic_Views shall exist. The package shall provide interfaces equivalent to those described in the following subclauses.
XX.11.1 Type Generic_View
type Generic_View is interface and View;
The type Generic_View represents a view of a generic unit.
XX.11.2 Function Generic_Formal_Part
function Generic_Formal_Part (G : Generic_View) return Declarative_Regions.Region_Part is abstract;
G specifies the view of a generic to query.
Yields a Region_Part that specifies the formal part of the generic G.
XX.11.3 Function Is_Generic_Package
function Is_Generic_Package (G : Generic_View) return Boolean is abstract;
G specifies the view of a generic to query.
Returns True if G denotes a generic package. Returns False otherwise.
XX.11.4 Function Current_Package_Instance
function Current_Package_Instance (G : Generic_View) return Package_Views.Package_View'Class is abstract;
G specifies the view of a generic to query.
If Is_Generic_Package (G) is False, then raises ASIS_Inappropriate_View.
As seen from within itself, a generic unit is an instance (that is, the current instance of the given generic); it is not a generic unit. This function yields a view of that instance for generic G.
XX.11.5 Function Is_Generic_Subprogram
function Is_Generic_Subprogram (G : Generic_View) return Boolean is abstract;
G specifies the view of a generic to query.
Returns True if G denotes a generic subprogram. Returns False otherwise.
Note: In all cases, Is_Generic_Subprogram (G) /= Is_Generic_Package (G).
XX.11.6 Function Current_Subprogram_Instance
function Current_Subprogram_Instance (G : Generic_View) return Callable_Views.Callable_View'Class is abstract;
G specifies the view of a generic to query.
If Is_Generic_Subprogram (G) is False, then raises ASIS_Inappropriate_View.
As seen from within itself, a generic unit is an instance (that is, the current instance of the given generic); it is not a generic unit. This function yields a view of that instance for generic G.
XX.11.7 Generic Holders
package Generic_Holders is new Ada.Containers.Holders (Generic_View'Class); type Generic_Holder is new Generic_Holders.Holder with null record;
Type Generic_Holder allows the declaration of an uninitialized variable (including a component) that can hold a Generic_View.
---------------------------------------------------------------
XX.12 Package Asis.Exception_Views
The library package Asis.Exception_Views shall exist. The package shall provide interfaces equivalent to those described in the following subclauses.
XX.12.1 Type Exception_View
type Exception_View is interface and View;
The type Exception_View represents a view of an exception.
Note: To determine whether a Discard_Names pragma applies to an exception view E, use Is_Aspect_Specified (E, Discarded_Names).
XX.12.2 Exception Holders
package Exception_Holders is new Ada.Containers.Holders (Exception_View'Class); type Exception_Holder is new Exception_Holders.Holder with null record;
Type Exception_Holder allows the declaration of an uninitialized variable (including a component) that can hold a Exception_View.
---------------------------------------------------------------
XX.13 Package Asis.Statement_Views
The library package Asis.Statement_Views shall exist. The package shall provide interfaces equivalent to those described in the following subclauses.
XX.13.1 Type Statement_View
type Statement_View is interface and View;
The type Statement_View represents a view of a statement.
XX.13.2 function Corresponding_Statement
function Corresponding_Statement (S : Statement_View) return ASIS.Statement is abstract;
S specifies the statement view to query.
Yields the ASIS.Statement value corresponding to the statement S.
XX.13.3 Statement Holders
package Statement_Holders is new Ada.Containers.Holders (Statement_View'Class); type Statement_Holder is new Statement_Holders.Holder with null record;
Type Statement_Holder allows the declaration of an uninitialized variable (including a component) that can hold a Statement_View.
---------------------------------------------------------------
XX.14 Package Asis.Declarations.Views
The library package Asis.Declarations.Views shall exist. The package shall provide interfaces equivalent to those described in the following subclauses.
XX.14.1 Function Corresponding_View_Declaration
function Corresponding_View_Declaration ( Declaration: in Asis.Declaration) return Asis.Views.Declarative_Regions.View_Declaration'Class;
Declaration specifies the declaration to query.
Returns a view that specifies the entity denoted by Declaration.
Declaration expects an element that has one of the following Element_Kinds:
A_Declaration
Raises ASIS_Inappropriate_Element with a Status of Value_Error for any element that does not have one of these expected kinds.
---------------------------------------------------------------
XX.15 Package Asis.Definitions.Views
The library package Asis.Definitions.Views shall exist. The package shall provide interfaces equivalent to those described in the following subclauses.
XX.15.1 Function Corresponding_Subtype_View
function Corresponding_Subtype_View ( Type_Definition : in Asis.Type_Definition) return Asis.Subtype_Views.Subtype_View'Class;
Type_Definition specifies the type to query.
Returns a view that specifies the subtype denoted by Type_Definition.
Type_Definition expects an element that has one of the following Definition_Kinds:
A_Type_Definition A_Private_Type_Definition A_Tagged_Private_Type_Definition A_Private_Extension_Definition A_Task_Definition A_Protected_Definition A_Formal_Type_Definition
Raises ASIS_Inappropriate_Element with a Status of Value_Error for any element that does not have one of these expected kinds.
---------------------------------------------------------------
XX.16 Package Asis.Expressions.Views
The library package Asis.Expressions.Views shall exist. The package shall provide interfaces equivalent to those described in the following subclauses.
XX.16.1 Function Corresponding_View
function Corresponding_View ( Expression : in Asis.Expression) return Asis.Views.View'Class;
Expression specifies the expression to query.
Returns the view that describes the semantic meaning of the Expression.
Expression expects an element that has one of the following Element_Kinds:
An_Expression
Raises ASIS_Inappropriate_Element with a Status of Value_Error for any element that does not have one of these expected kinds.
Note: The returned view denotes the expression, and not the declaration of the expression. In addition, the view represents the information available to the expression. This latter point means that the information in the view may depend on the visibility at the point of the reference that the view denotes. For instance, if the Expression denotes a private type whose full type is not visible at the point of Expression in the program and Corresponding_View (Expression) returns V, Is_Record (V) will be False even if the full type of the private type is a record type.
---------------------------------------------------------------
!discussion
GUIDES TO CREATING SEMANTIC MODEL
To guide our efforts, we need to decide on what level of information we want to capture. In particular, there is the information that is implementation independent, and simply captures the language-defined static semantic properties of the program. This we might call the "language-level" semantic information. At the next level down, there is information that reflects some of the decisions made by the implementation which might be useful to a tool, such as the layout of a record, or the linkname of a global object. This we might call the "representation-level" information. Finally, as we get to the "object-code level," there is the information about the range of code addresses associated with each line of source, and the layout of the stack frame for particular subprograms.
For this initial effort, we propose to focus on the "language-level" implementation-independent semantic properties. We envisage that additional packages might be defined as some later point, or by particular ASIS implementations, that provide the lower level "representation" or "object-code" information.
The second guide to our efforts is a list of the typical kinds of applications we imagine being built using this high-level semantic model. One kind of application would be an interpreter, both an interpreter of existing code, and an interpreter of simple expressions or statements typed into the program interactively after establishing a particular context. For example, one might invoke a tool that would essentially elaborate some part of the program library, and then allow the user to type in small test scripts in an Ada-like language which would be interpreted in the context of the given part of the library, as a kind of interactive unit testing capability.
Another type of application would be one that attempted to determine the range of values that each variable within the program could have at run-time, based on an "abstract interpretation" or a data and control flow analysis of its logic. This is similar to an interpreter, except that it does not construct an entire run-time context, but rather an abstraction of it that allows run-time properties to be approximated, generally through an iterative algorithm that stabilizes on a fixed-point approximation.
BASIC SEMANTIC MODEL
The existing ASIS packages define "Elements" which correspond roughly to syntactic "constructs." We propose to define "entities" and "views" thereof that represent the semantic entities defined by the syntactic constructs. In some cases, there is almost a one-to-one correspondence between the entity and the construct, for example, with an exception. For others, such as a "object view" there may be many different kinds of constructs that create object views which nevertheless have relatively similar properties.
Here are the kinds of entities and views we include in our ASIS semantic model:
- Program_Unit_View
- Package_View
- Subtype_View - Object_View - Callable_View - Exception_View - Generic_View - Statement_View
In addition, we propose to define certain other abstractions that allow us to characterize or manipulate the above entities or views:
- Declarative_Region - Region_Part - Profile
We use the term view because for there usually are multiple views possible for the same underlying entity. For a given subprogram, it is possible to have different formal parameter names and defaults, depending on the view. For a package, there is a limited view (associated with a "limited with"), a partial view (e.g. from the outside), a private view (e.g. from a child), and a full view (e.g. from inside the body). However, there is only one view of an exception. For a generic, the only thing that can vary by the view is the name of the generic, so it may not be worth considering these different views. We still consider these latter cases views for consistency in the terminology.
Many entities and views of entities have declarative regions associated with them. We propose to represent a particular view of a declarative region as a set of "region parts," one for each distinct part of a declarative region. Here are the different kinds of region parts:
- generic formal part - discriminant part - formal part - visible part - private part - public child part - private child part - body part
In addition to being able to iterate through the declarations of a region part, we propose to support the lookup of an identifier within a region part, within a declarative region view, or within a direct visibility view. If the lookup is successful, the result would be a single non-overloadable declaration, or a list of overloadable declarations. A direct visibility view supports lookups in a particular context, looking into enclosing scopes and taking use visibility into account. Looking up in a region part or a declarative region view does not worry about enclosing scopes or use visibility, and corresponds more closely to what would be called "selective visibility."
-----------------------
RANDOM THOUGHTS
Unlike the Abstract Syntax Tree (the basis of the structural subsystem of ASIS), the objects representing views might not exist until requested. They are more like handles into the symbol table.
--
A renaming of an object is an Object_View, and so on. The properties returned are that of the renaming, not of the original entity. A user can use Is_Renaming and Renamed_View to access the original entity.
We considered having renames factored out, but that would be wrong for static analysis. For instance, in Obj : renames A.all; Obj is not a dereference. If you were looking for all places that might raise Constraint_Error, a use of Obj is not such a place, while the actual renaming declaration is.
--
Consider Is_Array in the following:
package P is
type Priv is private;
package Nested is type Der is new Priv; end Nested;
private type Priv is array (1..10) of Character; end P;
In the body of Nested, Is_Array(Der) = True, while is it False everywhere else. This implies that Der would need more than one view in this case. Each particular reference has a location, and that should represent what is true at that point. And you might get a different subtype_view, even though the name of the type is the same. That implies that all views depend on the location of the original reference (not just the declaration denoted).
-------------------------------------------
package SPECIFICATION
In deciding how to represent the semantic attribute queries as an Ada package, there were a number of significant issues to be decided. Most basically was how to refer to entities or views. ASIS uses the single type Element for essentially every syntactic construct, and then defines "trivial" subtypes which can be used to aid in readability.
This existing ASIS approach sacrifices all compile-time checking in the use of the ASIS structural queries, which seems a shame. We would prefer to have some kind of type checking to help find misuses of the newly defined semantic queries at compile time. Given the desire to use multiple types to distinguish different kinds of entities, we then face the issue of limited vs. non-limited, tagged vs. non-tagged, interfaces vs. non-interfaces, explicitly derived vs. conversion functions, explicit pointers vs. opaque references, etc.
We had various criteria which led to our current proposal of using a non-tagged hierarchy of discriminated types. One goal was to permit declaring variables whose underlying entity kind might not be known at the point of declaration. Similarly, we wanted to be able to manipulate heterogeneous lists of semantic entities. Both of these create issues when using tagged types, since only class-wide types allow heterogeneity, and those require explicit initialization. An alternative would be to use explicit pointers everywhere, but this could introduce a significant storage management and/or dangling reference burden on the user of the semantic queries. If we decide to use non-tagged, non-pointer types, we clearly want to use non-limited types to allow assignment after initialization. If we decide to use tagged, non-pointer types, then we need to define some kind of "holder" object that can be used to hold one object of a class-wide type, but need not be initialized on declaration, and can appear as a component of a record or array.
With untagged types, choosing between explicitly derived types and types that have explicit conversion functions was based on reducing the number of explicit conversions required and/or reducing the number of redundant declarations for queries that are shared across the type hierarchy. The final decision was whether to incorporate any kind of run-time check at the point of conversion to a descendant type (a so-called "narrowing" conversion), or leave the run-time checking to each query. Clearly it seemed preferable to incorporate a check at the point of conversion where feasible. For untagged types, this can be accomplished by defining a "kind" enumeration, using it as a discriminant of the root type, and then using subtypes of the enumeration as the discriminant for descendant types. This works well for a strict hierarchy, but does not work as well when there are non-hierarchical classifications, such as distinguishing between declared vs. constructed views. In the latter case, we fall back to relying on checks on each query.
For tagged types, we naturally want to rely on the usual rules for conversion, where "narrowing" conversions are checked, and "widening" conversions are free (and implicit when the target is class-wide). With judicious use of interface types, we might also handle non-hierarchical classifications, largely eliminating checks on each query.
Another set of issues revolved around nomenclature. We have chosen to uniformly use the term "subtype" rather than "type or subtype," and use the term "view" rather than "entity or view" as in both cases, the former simpler term includes both of the latter terms. We also had to decide how to classify the views, and we have chosen six basic groups: object views, callable views, subtype views, package views, exception views, and generic views. We considered "typed views" rather than "object views," recognizing that there are still some cases where expressions or names denote "values" rather than "objects," but the term "typed view" seemed too close to "subtype view". An alternative for "callable view" might be "subprogram view," treating entries and corresponding accept statements as special cases of subprograms, but we chose the more generic term since calling a task entry a "subprogram" seems likely to cause confusion.
A final issue had to do with packaging. We have chosen to name the packages by the major view groupings. An alternative would be to combine them all into a single package. Because of interdependences, we ended up combining object views, subtype views, and profiles in the untagged version. In the tagged version, we broke the packages up a bit more, and managed to avoid the problems with the interdependence. Also, we changed the return type of some of the operations to avoid the interdependence.
IMPLEMENTATION USING ADA 95
An Ada 95 version of this would be somewhat harder. Clearly all of the interface types would become "regular" abstract tagged types. However, there is a subtle issue with Declared_Views, since a given type descended from Object_View might or might not want to be a descendant of Declared_View, and that kind of thing implies multiple inheritance. The same goes for Subtype_View and Callable_View. To avoid this problem, we could have a separate type that captures the information associated with a Declared_View, perhaps call it "View_Declaration," and allow any View to have one. That way we wouldn't be depending on multiple inheritance. View_Declaration might be a plain old private type, which would be consistent with the types Region_Part and Declarative_Region used already.
--------------------------------------------
Following are the package specifications for the semantic subsystem (recall that they do not appear in the ASIS Standard):
-----------------------------------------------------
with Ada.Containers.Holders; pragma Elaborate_All (Ada.Containers.Holders);
with Ada.Containers.Indefinite_Vectors; pragma Elaborate_All (Ada.Containers.Indefinite_Vectors);
package Asis.Views is
type View_Kinds is ( An_Exception, An_Exception_Renaming,
A_Generic_Package, A_Generic_Package_Renaming, A_Generic_Subprogram, A_Generic_Subprogram_Renaming,
A_Noninstance_Package, A_Package_Instance, A_Package_Renaming, A_Limited_Package_View,
A_Noninstance_Subprogram, A_Subprogram_Instance, A_Subprogram_Renaming, A_Protected_Subprogram, An_Imported_Subprogram, An_Attribute_Subprogram, An_Intrinsic_Subprogram, A_Designated_Subprogram, A_Generic_Formal_Subprogram, A_Protected_Entry, A_Task_Entry,
A_Standalone_Object, A_Generic_Formal_Object, A_Formal_Parameter_Object, An_Object_Renaming, A_Designated_Object, A_Component_Object, An_Attribute_Object, An_Aggregate_Object, A_Function_Result_Object, A_Named_Number, An_Attribute_Value, An_Expr_Value,
A_Boolean_Subtype, A_Character_Subtype, An_Ordinary_Enumeration_Subtype, A_Signed_Integer_Subtype, A_Modular_Integer_Subtype, An_Ordinary_Fixed_Subtype, A_Decimal_Fixed_Subtype, A_Float_Subtype, An_Access_To_Object_Subtype, An_Access_To_Subprogram_Subtype,
An_Array_Subtype, A_Record_Subtype, A_Record_Extension, A_Task_Subtype, A_Protected_Subtype, An_Interface,
A_Private_Subtype, A_Private_Extension,
An_Incomplete_Subtype,
A_Label_Statement_View, A_Block_Statement_View, A_Loop_Statement_View );
subtype Exception_View_Kinds is View_Kinds range An_Exception .. An_Exception_Renaming;
subtype Generic_View_Kinds is View_Kinds range A_Generic_Package .. A_Generic_Subprogram_Renaming;
subtype Callable_View_Kinds is View_Kinds range A_Noninstance_Subprogram .. A_Task_Entry;
subtype Object_View_Kinds is View_Kinds range A_Standalone_Object .. An_Expr_Value;
subtype Subtype_View_Kinds is View_Kinds range A_Boolean_Subtype .. An_Incomplete_Subtype;
subtype Package_View_Kinds is View_Kinds range A_Noninstance_Package..A_Limited_Package_View;
subtype Statement_View_Kinds is View_Kinds range A_Label_Statement_View .. A_Loop_Statement_View;
type View is interface;
function Kind (V : View) return View_Kinds is abstract;
function Element_Denoting_View (V : View) return Asis.Element is abstract;
function Is_Object_Or_Value (V : View) return Boolean is abstract;
function Is_Callable (V : View) return Boolean is abstract;
function Is_Subtype (V : View) return Boolean is abstract;
function Is_Package (V : View) return Boolean is abstract;
function Is_Generic (V : View) return Boolean is abstract;
function Is_Exception (V : View) return Boolean is abstract;
function Is_Statement (V : View) return Boolean is abstract;
type Conventions is ( Intrinsic_Convention, Ada_Convention, Protected_Convention, Entry_Convention, Other_Convention, Unspecified_Convention);
function Convention (V : View) return Conventions is abstract;
function Convention_Identifier (V : View) return Wide_String is abstract;
package Declarative_Regions is
type Declarative_Region is private;
type View_Declaration is interface;
type View_Declaration_Vector is tagged; -- Incomplete type.
type Region_Part is private;
type Region_Part_List is array (Positive range <>) of Region_Part;
type Region_Part_Kinds is (Generic_Formal_Part, Callable_Formal_Part, Discriminant_Part, Entry_Family_Index_Part, Record_Part, Extension_Part, Package_Visible_Part, Package_Private_Part, Task_Visible_Part, Task_Private_Part, Protected_Visible_Part, Protected_Private_Part, Body_Part, Block_Declarative_Part, Loop_Declarative_Part, Child_Part);
function Kind (P : Region_Part) return Region_Part_Kinds;
function Is_Empty (P : Region_Part) return Boolean;
function Declarative_Items (P : Region_Part) return Asis.Declarative_Item_List;
procedure Declarations (P : Region_Part; Declarations : out View_Declaration_Vector'Class);
function Region (P : Region_Part) return Declarative_Region;
function All_Region_Parts (R : Declarative_Region) return Region_Part_List;
function Visible_Region_Parts (R : Declarative_Region) return Region_Part_List;
function Private_Part (R : Declarative_Region) return Region_Part;
function Body_Part (R : Declarative_Region) return Region_Part;
function Defining_Construct (R : Declarative_Region) return Asis.Element;
function Has_Defining_Declaration (R : Declarative_Region) return Boolean;
function Defining_Declaration (R : Declarative_Region) return View_Declaration'Class;
function Has_Enclosing_Region (R : Declarative_Region) return Boolean;
function Enclosing_Region (R : Declarative_Region) return Declarative_Region;
function Defined_View (D : View_Declaration) return View'Class is abstract;
function Declaration (D : View_Declaration) return Asis.Declaration is abstract;
function View_Identifier (D : View_Declaration) return Asis.Identifier is abstract;
function Is_Imported (D : View_Declaration) return Boolean is abstract;
function Is_Overloadable (D : View_Declaration) return Boolean is abstract;
function Is_Overriding (D : View_Declaration) return Boolean is abstract;
procedure Overridden_Declarations (D : View_Declaration; Overridden : out View_Declaration_Vector'Class) is abstract;
function Aspect_Items (D : View_Declaration) return Asis.Aspect_Clause_List is abstract;
function Enclosing_Region (D : View_Declaration) return Declarative_Region is abstract;
function Enclosing_Region_Part (D : View_Declaration) return Region_Part is abstract;
function Expanded_Name (D : View_Declaration) return Wide_String is abstract;
function Are_Declared_In_Same_Region (Decl1, Decl2 : View_Declaration) return Boolean is abstract;
function Is_Declared_Earlier_In_Same_Region (Earlier, Later : View_Declaration) return Boolean is abstract;
function Enclosing_Compilation_Unit (D : View_Declaration) return Asis.Compilation_Unit is abstract;
function Is_Renaming (D : View_Declaration) return Boolean is abstract;
function Renamed_View (D : View_Declaration)
return View'Class is abstract;
package View_Declaration_Vectors is new Ada.Containers.Indefinite_Vectors ( Positive, View_Declaration'Class); type View_Declaration_Vector is new View_Declaration_Vectors.Vector with null record;
private
... -- Not specified by the language
end Declarative_Regions;
use Declarative_Regions;
function Defines_Declarative_Region (V : View) return Boolean is abstract;
function Defined_Region (V : View) return Declarative_Region is abstract;
function Has_Declaration (V : View) return Boolean is abstract;
function Declaration (V : View) return View_Declaration'Class is abstract;
type Language_Defined_Aspect_Kinds is (Address, Alignment, Asynchronous, Atomic, Atomic_Components, Bit_Order, Coding, Component_Size, Controlled, Convention, Discarded_Names, Exported, External_Tag, Imported, Independent, Independent_Components, Input, Layout, No_Return, Output, Packing, Read, Size, Small, Storage_Pool, Storage_Size, Stream_Size, Volatile, Volatile_Components, Write);
function Is_Aspect_Specified (V : View; Aspect : Language_Defined_Aspect_Kinds) return Boolean is abstract;
function Is_Aspect_Directly_Specified (V : View; Aspect : Language_Defined_Aspect_Kinds) return Boolean is abstract;
type Implementation_Defined_Aspect_Kinds is (<implementation-defined>);
function Is_Aspect_Specified (V : View; Aspect : Implementation_Defined_Aspect_Kinds) return Boolean is abstract;
function Is_Aspect_Directly_Specified (V : View; Aspect : Implementation_Defined_Aspect_Kinds) return Boolean is abstract;
package View_Holders is new Ada.Containers.Holders (View'Class); type View_Holder is new View_Holders.Holder with null record;
package View_Vectors is new Ada.Containers.Indefinite_Vectors (Positive, View'Class); type View_Vector is new View_Vectors.Vector with null record;
end Asis.Views;
with Asis.Views; use Asis.Views; with Ada.Containers.Indefinite_Vectors; pragma Elaborate_All (Ada.Containers.Indefinite_Vectors); package Asis.Program_Units is
use Views.Declarative_Regions;
type Program_Unit is interface and View_Declaration;
type Program_Unit_Vector is tagged; -- Incomplete type.
function Requires_Body (P : Program_Unit) return Boolean is abstract;
function Has_Body (P : Program_Unit) return Boolean is abstract;
function Body_Of_Program_Unit (P : Program_Unit) return Asis.Declaration is abstract;
function Is_Subunit (P : Program_Unit) return Boolean is abstract;
function Stub_Of_Program_Unit (P : Program_Unit) return Asis.Declaration is abstract;
function Is_Instance (P : Program_Unit) return Boolean is abstract;
function Instantiated_Generic (P : Program_Unit) return Program_Unit'Class is abstract;
function Actual_Part (P : Program_Unit) return Asis.Association_List is abstract;
function Expanded_Body (P : Program_Unit) return Asis.Declaration is abstract;
function Is_Compilation_Unit (P : Program_Unit) return Boolean is abstract;
procedure Depends_Semantically_On ( P : Program_Unit; Depends_On : out Program_Unit_Vector'Class) is abstract;
function Is_Library_Item (P : Program_Unit) return Boolean is abstract;
type Library_Item is interface and Program_Unit;
function Has_Parent_Library_Unit (L : Library_Item) return Boolean is abstract;
function Parent_Library_Unit (L : Library_Item) return Library_Item'Class is abstract;
function Is_Pure_Unit (L : Library_Item) return Boolean is abstract;
function Is_Preelaborated_Unit (L : Library_Item) return Boolean is abstract;
function Is_Remote_Call_Interface_Unit (L : Library_Item) return Boolean is abstract;
function Is_Remote_Types_Unit (L : Library_Item) return Boolean is abstract;
package Program_Unit_Vectors is new Ada.Containers.Indefinite_Vectors (Positive, Program_Unit'Class); type Program_Unit_Vector is new Program_Unit_Vectors.Vector with null record;
end Asis.Program_Units;
with Asis.Views; use Asis.Views; with Ada.Containers.Holders; pragma Elaborate_All (Ada.Containers.Holders); with Ada.Containers.Indefinite_Vectors; pragma Elaborate_All (Ada.Containers.Indefinite_Vectors); package Asis.Subtype_Views is
type Subtype_View is interface and View;
type Subtype_Vector is tagged; -- Incomplete type.
function Is_Elementary (S : Subtype_View) return Boolean is abstract; function Is_Composite (S : Subtype_View) return Boolean is abstract;
function Is_Scalar (S : Subtype_View) return Boolean is abstract; function Is_Enumeration (S : Subtype_View) return Boolean is abstract; function Is_Boolean (S : Subtype_View) return Boolean is abstract; function Is_Character (S : Subtype_View) return Boolean is abstract; function Is_Numeric (S : Subtype_View) return Boolean is abstract; function Is_Discrete (S : Subtype_View) return Boolean is abstract; function Is_Integer (S : Subtype_View) return Boolean is abstract; function Is_Signed_Integer (S : Subtype_View) return Boolean is abstract; function Is_Modular_Integer (S : Subtype_View) return Boolean is abstract; function Is_Real (S : Subtype_View) return Boolean is abstract; function Is_Fixed_Point (S : Subtype_View) return Boolean is abstract; function Is_Ordinary_Fixed_Point (S : Subtype_View) return Boolean is abstract; function Is_Decimal_Fixed_Point (S : Subtype_View) return Boolean is abstract; function Is_Floating_Point (S : Subtype_View) return Boolean is abstract; function Is_Access (S : Subtype_View) return Boolean is abstract; function Is_Access_To_Object (S : Subtype_View) return Boolean is abstract; function Is_Access_To_Subprogram (S : Subtype_View) return Boolean is abstract;
function Is_Specific (S : Subtype_View) return Boolean is abstract; function Is_Root_Numeric (S : Subtype_View) return Boolean is abstract; function Is_Universal (S : Subtype_View) return Boolean is abstract; function Is_Classwide (S : Subtype_View) return Boolean is abstract;
function Is_Record (S : Subtype_View) return Boolean is abstract; function Is_Record_Extension (S : Subtype_View) return Boolean is abstract; function Is_Array (S : Subtype_View) return Boolean is abstract; function Is_String (S : Subtype_View) return Boolean is abstract; function Is_Protected (S : Subtype_View) return Boolean is abstract; function Is_Task (S : Subtype_View) return Boolean is abstract; function Is_Tagged (S : Subtype_View) return Boolean is abstract;
function Is_Abstract (S : Subtype_View) return Boolean is abstract; function Is_Interface (S : Subtype_View) return Boolean is abstract;
function Is_Formal_Subtype (S : Subtype_View) return Boolean is abstract; function Is_Descended_From_Formal_Subtype (S : Subtype_View) return Boolean is abstract;
function Is_Constrained (S : Subtype_View) return Boolean is abstract; function Is_Definite (S : Subtype_View) return Boolean is abstract;
function Are_Of_Same_Type (Left, Right : Subtype_View) return Boolean is abstract;
function Is_First_Subtype (S : Subtype_View) return Boolean is abstract;
function Is_Secondary_Subtype (S : Subtype_View) return Boolean is abstract;
function First_Subtype (S : Subtype_View) return Subtype_View'Class is abstract;
function Is_Unadorned_Subtype (S : Subtype_View) return Boolean is abstract;
function Unadorned_Subtype (S : Subtype_View) return Subtype_View'Class is abstract;
function Has_Constraint (S : Subtype_View) return Boolean is abstract;
function Constraint (S : Subtype_View) return Asis.Constraint is abstract;
function Is_Static_Subtype (S : Subtype_View) return Boolean is abstract;
function Is_Statically_Constrained (S : Subtype_View) return Boolean is abstract;
function Are_Statically_Matching (S1, S2 : Subtype_View) return Boolean is abstract;
function Is_Statically_Compatible (S : Subtype_View; With_Subtype : Subtype_View) return Boolean is abstract;
procedure Primitive_Subprograms (S : Subtype_View; Primitives : out Declarative_Regions.View_Declaration_Vector) is abstract;
function Is_Derived_Subtype (S : Subtype_View) return Boolean is abstract;
function Parent_Subtype (S : Subtype_View) return Subtype_View'Class is abstract;
function Is_Descendant (S : Subtype_View; Of_Subtype : Subtype_View) return Boolean is abstract;
function Ultimate_Ancestor (S : Subtype_View) return Subtype_View'Class is abstract;
function Is_Incomplete_View (S : Subtype_View) return Boolean is abstract;
function Complete_View (S : Subtype_View) return Subtype_View'Class is abstract;
function Is_Partial_View (S : Subtype_View) return Boolean is abstract;
function Full_View (S : Subtype_View) return Subtype_View'Class is abstract;
function Subtype_Size (S : Subtype_View) return ASIS_Natural is abstract; -- Returns equivalent to 'Size when subtype is elementary or -- size is specified. Result is implementation-defined in -- other cases, and may be Natural'Last.
function Subtype_Alignment (S : Subtype_View) return ASIS_Natural is abstract;
package Subtype_Holders is new Ada.Containers.Holders (Subtype_View'Class); type Subtype_Holder is new Subtype_Holders.Holder with null record;
package Subtype_Vectors is new Ada.Containers.Indefinite_Vectors (Positive, Subtype_View'Class); type Subtype_Vector is new Subtype_Vectors.Vector with null record;
end Asis.Subtype_Views;
with Asis.Views; use Asis.Views; with Asis.Subtype_Views; use Asis.Subtype_Views; with Ada.Containers.Holders; pragma Elaborate_All (Ada.Containers.Holders); package Asis.Object_Views is
----------------------------------- -- Object Views (Includes "pure" values) -----------------------------------
type Object_View is interface and View;
function Is_Constant_View (O : Object_View) return Boolean is abstract;
function Nominal_Subtype (O : Object_View) return Subtype_View'Class is abstract;
function Is_Renamed_View (O : Object_View) return Boolean is abstract;
function Renamed_View (O : Object_View) return Object_View'Class is abstract;
function Is_Component (O : Object_View) return Boolean is abstract;
function Enclosing_Object (O : Object_View) return Object_View'Class is abstract;
function Is_Indexed_Component (O : Object_View) return Boolean is abstract;
function Index_Value (O : Object_View; Dimension : Positive := 1) return Object_View'Class is abstract;
function Is_Selected_Component (O : Object_View) return Boolean is abstract;
function Selector_Declaration (O : Object_View) return View_Declaration'Class is abstract;
function Position (O : Object_View) return Object_View'Class is abstract;
function First_Bit (O : Object_View) return Object_View'Class is abstract;
function Last_Bit (O : Object_View) return Object_View'Class is abstract;
function Is_Aliased (O : Object_View) return Boolean is abstract;
type Static_Accessibility_Level is range 0 .. <implementation-defined>;
Library_Level : constant Static_Accessibility_Level := 0; Deepest_Accessibility_Level : constant Static_Accessibility_Level; Incomparable_Accessibility_Level : constant Static_Accessibility_Level;
function Static_Accessibility (O : Object_View) return Static_Accessibility_Level is abstract;
function Is_Dereference (O : Object_View) return Boolean is abstract;
function Dereferenced_Value (O : Object_View) return Object_View'Class is abstract;
function Is_Implicit_Dereference (O : Object_View) return Boolean is abstract;
type Longest_Discrete is range <implementation-defined>;
function Is_Static_Discrete (O : Object_View) return Boolean is abstract;
function Static_Discrete_Value (O : Object_View) return Longest_Discrete is abstract;
function Static_Discrete_Image (O : Object_View) return Wide_String is abstract;
function Is_Static_Real (O : Object_View) return Boolean is abstract;
function Static_Real_Value (O : Object_View) return Longest_Float is abstract;
function Static_Real_Image (O : Object_View) return Wide_String is abstract;
function Is_Static_String (O : Object_View) return Boolean is abstract;
function Static_String_Value (O : Object_View) return Wide_String is abstract;
function Object_Size (O : Object_View) return ASIS_Natural is abstract;
function Object_Alignment (O : Object_View) return ASIS_Natural is abstract;
package Object_Holders is new Ada.Containers.Holders (Object_View'Class); type Object_Holder is new Object_Holders.Holder with null record;
private
... -- Not specified by the language
end Asis.Object_Views;
with Asis.Views; use Asis.Views; with Asis.Subtype_Views; use Asis.Subtype_Views; package Asis.Profiles is
-------------------------------- -- Parameter and Result Profiles --------------------------------
type Profile is private;
function Parameters (P : Profile) return Declarative_Regions.Region_Part;
function Is_Function (P : Profile) return Boolean;
function Result_Subtype (P : Profile) return Subtype_View'Class;
function Has_Family_Index (P : Profile) return Boolean;
function Family_Index_Subtype (P : Profile) return Subtype_View'Class;
function Convention (P : Profile) return Conventions;
function Convention_Identifier (P : Profile) return Wide_String;
private
... -- Not specified by the language
end Asis.Profiles;
with Asis.Object_Views; use Asis.Object_Views; with Asis.Profiles; use Asis.Profiles; package Asis.Subtype_Views.Elementary is
------------------------------ -- Elementary Subtype Views -- ------------------------------
type Elementary_Subtype is interface and Subtype_View;
function Is_Universal (E : Elementary_Subtype) return Boolean is abstract;
type Scalar_Subtype is interface and Elementary_Subtype;
function Base_Subtype (S : Scalar_Subtype) return Scalar_Subtype'Class is abstract;
function Low_Bound (S : Scalar_Subtype) return Object_View'Class is abstract; function High_Bound (S : Scalar_Subtype) return Object_View'Class is abstract;
function Is_Root_Numeric (S : Scalar_Subtype) return Boolean is abstract;
type Discrete_Subtype is interface and Scalar_Subtype; --?? Operations on Discrete_Subtypes
--?? Enumeration, Integer, Fixed, Floating -- are separate types needed?
type Access_Subtype is interface and Elementary_Subtype;
function Is_Anonymous_Access (A : Access_Subtype) return Boolean is abstract;
function Is_Access_Parameter (A : Access_Subtype) return Boolean is abstract;
function Is_Access_Result (A : Access_Subtype) return Boolean is abstract;
function Is_Access_Discriminant (A : Access_Subtype) return Boolean is abstract;
function Static_Accessibility (A : Access_Subtype) return Object_Views.Static_Accessibility_Level is abstract;
function Excludes_Null (A : Access_Subtype) return Boolean is abstract;
type Access_To_Object_Subtype is interface and Access_Subtype;
function Designated_Subtype (A : Access_To_Object_Subtype) return Subtype_View'Class is abstract;
function Is_Access_To_Constant (A : Access_To_Object_Subtype) return Boolean is abstract;
function Is_Pool_Specific (A : Access_To_Object_Subtype) return Boolean is abstract;
function Storage_Pool (A : Access_To_Object_Subtype) return Object_View'Class is abstract;
function Storage_Size (A : Access_To_Object_Subtype) return Object_View'Class is abstract;
type Access_To_Subprogram_Subtype is interface and Access_Subtype;
function Designated_Profile (A : Access_To_Subprogram_Subtype) return Profile is abstract;
end Asis.Subtype_Views.Elementary;
with Asis.Subtype_Views.Elementary; package Asis.Subtype_Views.Composite is
----------------------------- -- Composite Subtype Views -- -----------------------------
type Composite_Subtype is interface and Subtype_View;
function Is_Limited (C : Composite_Subtype) return Boolean is abstract;
function Contains_Task (C : Composite_Subtype) return Boolean is abstract;
function Needs_Finalization (C : Composite_Subtype) return Boolean is abstract;
function Has_Preelaborable_Initialization (C : Composite_Subtype) return Boolean is abstract;
function Has_Unknown_Discriminants (C : Composite_Subtype) return Boolean is abstract;
function Has_Known_Discriminants (C : Composite_Subtype) return Boolean is abstract;
function Discriminants (C : Composite_Subtype) return Declarative_Regions.Region_Part is abstract;
function Discriminants_Have_Defaults (C : Composite_Subtype) return Boolean is abstract;
function Has_Nondiscriminant_Region_Parts (C : Composite_Subtype) return Boolean is abstract;
function Nondiscriminant_Region_Parts (C : Composite_Subtype) return Declarative_Regions.Region_Part_List is abstract; -- NOTE: Return an array of region parts to handle -- case of multiple extension parts, or -- visible and private parts of task/protected types
type Array_Subtype is interface and Composite_Subtype;
function Component_Subtype (A : Array_Subtype) return Subtype_View'Class is abstract;
function Num_Dimensions (A : Array_Subtype) return Positive is abstract;
function Index_Subtype (A : Array_Subtype; Dimension : Positive := 1) return Elementary.Discrete_Subtype'Class is abstract;
function Is_String_Subtype (A : Array_Subtype) return Boolean is abstract;
type Tagged_Subtype is interface and Composite_Subtype;
type Tagged_Subtype_Vector is tagged; -- Incomplete type.
function Is_Interface (T : Tagged_Subtype) return Boolean is abstract; function Is_Abstract (T : Tagged_Subtype) return Boolean is abstract;
function Is_Synchronized_Tagged (T : Tagged_Subtype) return Boolean is abstract;
function Is_Classwide (T : Tagged_Subtype) return Boolean is abstract;
function Root_Subtype (T : Tagged_Subtype) return Tagged_Subtype'Class is abstract;
function Is_Specific (T : Tagged_Subtype) return Boolean is abstract;
function Classwide_Subtype (T : Tagged_Subtype) return Tagged_Subtype'Class is abstract;
procedure Progenitors ( T : Tagged_Subtype; Progenitors : out Tagged_Subtype_Vector'Class) is abstract;
function External_Tag (T : Tagged_Subtype) return String is abstract;
package Tagged_Subtype_Vectors is new Ada.Containers.Indefinite_Vectors (Positive, Tagged_Subtype'Class); type Tagged_Subtype_Vector is new Tagged_Subtype_Vectors.Vector with null record;
end Asis.Subtype_Views.Composite;
with Asis.Views; use Asis.Views; with Asis.Subtype_Views; use Asis.Subtype_Views; with Asis.Subtype_Views.Composite; with Asis.Profiles; use Asis.Profiles; with Asis.Object_Views; use Asis.Object_Views; with Ada.Containers.Holders; pragma Elaborate_All (Ada.Containers.Holders); package Asis.Callable_Views is
type Callable_View is interface and View;
function Callable_Profile (C : Callable_View) return Profile is abstract;
function Is_Subprogram (C : Callable_View) return Boolean is abstract;
function Is_Enumeration_Literal (C : Callable_View) return Boolean is abstract;
function Is_Procedure (C : Callable_View) return Boolean is abstract;
function Is_Entry (C : Callable_View) return Boolean is abstract;
function Is_Function (C : Callable_View) return Boolean is abstract;
function Is_Abstract (C : Callable_View) return Boolean is abstract;
function Is_Null (C : Callable_View) return Boolean is abstract;
function Is_Primitive (C : Callable_View) return Boolean is abstract;
procedure Primitive_On_Subtypes ( C : Callable_View; Subtypes : out Subtype_Vector) is abstract;
function Is_Dispatching_Operation (C : Callable_View) return Boolean is abstract;
function Associated_Tagged_Type (C : Callable_View) return Composite.Tagged_Subtype'Class is abstract;
function Is_Prefixed_View (C : Callable_View) return Boolean is abstract;
function Prefix_Object (C : Callable_View) return Object_View'Class is abstract; -- Does this work for task/protected operations?
function Unprefixed_Callable_View (C : Callable_View) return Callable_View'Class is abstract; -- What does this return for a task/protected operation?
function Is_Designated_Subprogram (C : Callable_View) return Boolean is abstract;
function Access_To_Subprogram_Value (C : Callable_View) return Object_View is abstract;
function Is_Implicit_Dereference (C : Callable_View) return Boolean is abstract;
package Callable_Holders is new Ada.Containers.Holders (Callable_View'Class); type Callable_Holder is new Callable_Holders.Holder with null record;
end Asis.Callable_Views;
with Asis.Callable_Views; use Asis.Callable_Views; package Asis.Object_Views.Access_Views is
type Access_Object_View is interface and Object_View;
function Is_Object_Access_Attribute_Reference (O : Access_Object_View) return Boolean is abstract;
function Designated_Object (O : Access_Object_View) return Object_View'Class is abstract;
function Is_Implicit_Access_Attribute_Reference (O : Access_Object_View) return Boolean is abstract;
function Is_Subprogram_Access_Attribute_Reference (O : Access_Object_View) return Boolean is abstract;
function Designated_Subprogram (O : Access_Object_View) return Callable_View'Class is abstract;
end Asis.Object_Views.Access_Views;
with Asis.Views; use Asis.Views; with Ada.Containers.Holders; pragma Elaborate_All (Ada.Containers.Holders); package Asis.Package_Views is
type Package_View is interface and View;
function Has_Limited_View (P : Package_View) return Boolean is abstract;
function Is_Limited_View (P : Package_View) return Boolean is abstract;
function Full_View (P : Package_View) return Package_View'Class is abstract;
function Is_Full_View (P : Package_View) return Boolean is abstract;
function Limited_View (P : Package_View) return Package_View'Class is abstract;
function Is_Formal_Package (P : Package_View) return Boolean is abstract;
function Visible_Part (P : Package_View) return Declarative_Regions.Region_Part is abstract;
function Private_Part (P : Package_View) return Declarative_Regions.Region_Part is abstract;
package Package_Holders is new Ada.Containers.Holders (Package_View'Class); type Package_Holder is new Package_Holders.Holder with null record;
end Asis.Package_Views;
with Asis.Views; use Asis.Views; with Asis.Callable_Views; with Asis.Package_Views; with Ada.Containers.Holders; pragma Elaborate_All (Ada.Containers.Holders); package Asis.Generic_Views is
type Generic_View is interface and View;
function Generic_Formal_Part (G : Generic_View) return Declarative_Regions.Region_Part is abstract;
function Is_Generic_Package (G : Generic_View) return Boolean is abstract;
function Current_Package_Instance (G : Generic_View) return Package_Views.Package_View'Class is abstract;
function Is_Generic_Subprogram (G : Generic_View) return Boolean is abstract;
function Current_Subprogram_Instance (G : Generic_View) return Callable_Views.Callable_View'Class is abstract;
package Generic_Holders is new Ada.Containers.Holders (Generic_View'Class); type Generic_Holder is new Generic_Holders.Holder with null record;
end Asis.Generic_Views;
with Asis.Views; use Asis.Views; with Ada.Containers.Holders; pragma Elaborate_All (Ada.Containers.Holders); package Asis.Exception_Views is
type Exception_View is interface and View;
package Exception_Holders is new Ada.Containers.Holders (Exception_View'Class); type Exception_Holder is new Exception_Holders.Holder with null record;
end Asis.Exception_Views;
with Asis.Views; use Asis.Views; with Ada.Containers.Holders; pragma Elaborate_All (Ada.Containers.Holders); package Asis.Statement_Views is
type Statement_View is interface and View;
function Corresponding_Statement (S : Statement_View) return ASIS.Statement is abstract;
package Statement_Holders is new Ada.Containers.Holders (Statement_View'Class); type Statement_Holder is new Statement_Holders.Holder with null record;
end Asis.Statement_Views;
with Asis.Views.Declarative_Regions; package Asis.Declarations.Views is
function Corresponding_View_Declaration ( Declaration: in Asis.Declaration) return Asis.Views.Declarative_Regions.View_Declaration'Class;
end Asis.Declarations.Views;
with Asis.Subtype_View; package Asis.Definitions.Views is
function Corresponding_Subtype_View ( Type_Definition : in Asis.Type_Definition) return Asis.Subtype_Views.Subtype_View'Class;
end Asis.Definitions.Views;
with Asis.Views; package Asis.Expressions.Views is
function Corresponding_View ( Expression : in Asis.Expression) return Asis.Views.View'Class;
end Asis.Expressions.Views;
-----------------------------------------------------------------
end of full package specifications.
!appendix

From: Robert A. Duff
Date: Monday, November 13, 2006  9:00 AM

> Here is a first draft of my SI on an ASIS semantic model.

Thanks.

Sergey Rybin (rybin@adacore.com) should be in on the discussion.

****************************************************************

From: Jean-Pierre Rosen
Date: Friday, June 9, 2006  1:47 AM

Specifications of my thick_queries package:


----------------------------------------------------------------------
--  Thick_Queries - Package specification                           --
--  Copyright (C) 2002 Adalog                                       --
--  Author: J-P. Rosen                                              --
--                                                                  --
--  ADALOG   is   providing   training,   consultancy,   expertise, --
--  assistance and custom developments  in Ada and related software --
--  engineering techniques.  For more info about our services:      --
--  ADALOG                   Tel: +33 1 41 24 31 40                 --
--  19-21 rue du 8 mai 1945  Fax: +33 1 41 24 07 36                 --
--  94110 ARCUEIL            E-m: info@adalog.fr                    --
--  FRANCE                   URL: http://www.adalog.fr              --
--                                                                  --
--  This  unit is  free software;  you can  redistribute  it and/or --
--  modify  it under  terms of  the GNU  General Public  License as --
--  published by the Free Software Foundation; either version 2, or --
--  (at your  option) any later version.  This  unit is distributed --
--  in the hope  that it will be useful,  but WITHOUT ANY WARRANTY; --
--  without even the implied warranty of MERCHANTABILITY or FITNESS --
--  FOR A  PARTICULAR PURPOSE.  See the GNU  General Public License --
--  for more details.   You should have received a  copy of the GNU --
--  General Public License distributed  with this program; see file --
--  COPYING.   If not, write  to the  Free Software  Foundation, 59 --
--  Temple Place - Suite 330, Boston, MA 02111-1307, USA.           --
--                                                                  --
--  As  a special  exception, if  other files  instantiate generics --
--  from  this unit,  or you  link this  unit with  other  files to --
--  produce an executable,  this unit does not by  itself cause the --
--  resulting executable  to be covered  by the GNU  General Public --
--  License.  This exception does  not however invalidate any other --
--  reasons why  the executable  file might be  covered by  the GNU --
--  Public License.                                                 --
----------------------------------------------------------------------

with Asis;
with System;
package Thick_Queries is

   -------------------------------------------------------------------------------------------------
   --                                                                                             --
   -- Error report                                                                                --
   --                                                                                             --
   -------------------------------------------------------------------------------------------------

   type Error_Procedure is access procedure (Message : Wide_String; Elem : Asis.Element);
   procedure Set_Error_Procedure (To : Error_Procedure);
   -- Defines a user defined procedure called in case of an internal error
   -- ("impossible" cases, or calls with inappropriate elements)
   -- The user procedure may raise an exception. If it doesn't (or no user procedure is defined),
   -- Program_Error will be raised.


   -------------------------------------------------------------------------------------------------
   --                                                                                             --
   -- Queries about program structure                                                             --
   --                                                                                             --
   -------------------------------------------------------------------------------------------------

   function Enclosing_Program_Unit (Element          : Asis.Element;
                                    Including_Accept : Boolean      := False)
                                   return Asis.Defining_Name;
   --  Return the Defining_Name of the innermost enclosing program unit of any Element
   --  If Including_Accept is true and the element is within an accept statement, return
   --  the corresponding entry name from the entry declaration (not really a program unit,
   --  but useful f.e. if the Element is a Return_Statement, and you want to know what you
   --  are returning from).
   --
   --  Appropriate Element_Kinds:
   --     Any element
   --
   --  Returns
   --     A_Defining_Name
   --     Nil_Element if Element is a Compilation_Unit
   --

   function Ultimate_Enclosing_Instantiation (The_Element : Asis.Element) return Asis.Declaration;
   -- For an entity which Is_Part_Of_Instance:
   -- Return the "true" instantiation, i.e. the one written by the user, going up instantiations
   -- that appear in generics.


   function Is_Part_Of_Generic (Declaration : in Asis.Declaration) return Boolean;
   -- Checks whether the Declaration is included (directly or indirectly) in a generic
   -- Expected Element:
   --    A_Declaration


   -------------------------------------------------------------------------------------------------
   --                                                                                             --
   -- Images                                                                                      --
   --                                                                                             --
   -------------------------------------------------------------------------------------------------

   function Attribute_Name_Image (Attribute : Asis.Expression) return Wide_String;
   --  Like Pragma_Name_Image, but for an Attribute_Reference
   --
   --  Appropriate Element_Kinds:
   --    An_Expression
   --  Appropriate Expression_Kinds:
   --    An_Attribute_Reference


   function Extended_Name_Image (Name_Elem : Asis.Element) return Wide_String;
   -- Image of a name, given either as a simple name or as a Selected_Name


   function Full_Name_Image (The_Name     : in Asis.Element;
                             With_Profile : in Boolean := False) return Wide_String;
   -- Full name of a name
   -- Works like Asis.Declarations.Defining_Name_Image (or Name_Image),
   -- but returns the full (unique) name of The_Name, starting from the
   -- enclosing compilation unit (Standard for predefined elements).
   -- If With_Profile is true, "mangles" the name with a profile to provide a name
   -- that is unique even if overloaded.
   --
   -- Appropriate Element_Kinds:
   --    A_Defining_Name
   --    An_Expression
   -- Appropriate Expression_Kinds:
   --    An_Identifier
   --    A_Selected_Component (returns the image of the selector)


   function Profile_Image (The_Name     : Asis.Element;
                           With_Profile : Boolean := True) return Wide_String;
   -- Image of the profile of a callable construct
   -- If name is not a callable construct, returns ""
   -- Otherwise:
   --    for a procedure, entry...:
   --       returns '{' {<Full_Name_Image (types of parameter) '}'}
   --    for a function:
   --       returns '{' {<Full_Name_Image (types of parameter) } ':' Full_Name_Image (result type) '}'
   -- With_Profile determines if the Full_Name_Image generated for parameters and result includes
   -- itself a profile.
   --
   -- Appropriate Element_Kinds:
   --    A_Defining_Name
   --    An_Expression
   -- Appropriate Expression_Kinds:
   --    An_Identifier
   --    A_Selected_Component (returns the image of the selector)


   -------------------------------------------------------------------------------------------------
   --                                                                                             --
   -- Queries about types                                                                         --
   --                                                                                             --
   -------------------------------------------------------------------------------------------------

   function Subtype_Simple_Name (Definition : Asis.Definition) return Asis.Expression;
   -- Like Subtype_Mark, but returns the selector if the subtype mark is a selected component
   -- Moreover, it avoids the ambiguity between Asis.Subtype_Mark and Asis.Definitions.Subtype_Mark

   function Is_Class_Wide_Subtype (The_Subtype : Asis.Declaration) return Boolean;
   -- Unwinds subtype declarations and returns true if the given subtype declaration
   -- ultimately designates a class-wide type.
   --
   -- Appropriate Declaration_Kinds:
   --    A_Subtype_Declaration

   function Is_Limited (The_Subtype : Asis.Declaration) return Boolean;
   -- Returns True if The_Subtype is a declaration of an (explicit or implicit) limited type
   -- Returns False in all other cases

   function Is_Type_Declaration_Kind (The_Subtype : Asis.Declaration; Kind : Asis.Declaration_Kinds) return Boolean;
   -- Unwinds subtype declarations and derivations and returns true if the given subtype
   -- declaration ultimately designates a type of the given kind.
   --
   -- Appropriate Declaration_Kinds:
   --       An_Ordinary_Type_Declaration
   --       A_Task_Type_Declaration
   --       A_Protected_Type_Declaration
   --       A_Private_Type_Declaration
   --       A_Private_Extension_Declaration
   --       A_Subtype_Declaration
   --       A_Formal_Type_Declaration


   function Contains_Type_Declaration_Kind (The_Subtype : Asis.Declaration;
                                            Kind        : Asis.Declaration_Kinds) return Boolean;
   -- Like Is_Type_Declaration_Kind, but for composite types, returns True if any subcomponent is
   -- of the given kind.
   --
   -- Appropriate Declaration_Kinds:
   --       An_Ordinary_Type_Declaration
   --       A_Task_Type_Declaration
   --       A_Protected_Type_Declaration
   --       A_Private_Type_Declaration
   --       A_Private_Extension_Declaration
   --       A_Subtype_Declaration
   --       A_Formal_Type_Declaration


   -------------------------------------------------------------------------------------------------
   --                                                                                             --
   -- Queries about names and expressions                                                         --
   --                                                                                             --
   -------------------------------------------------------------------------------------------------

   function Ultimate_Name (The_Name : Asis.Element) return Asis.Element;
   -- For a name defined by a renaming declaration: returns the name of the entity, which is not
   --   itself defined by a renaming.
   --   - In the case of a renaming whose target is part of a composite type, returns the name
   --     of the field for A_Selected_Name and the name of the array for An_Indexed_Component
   --        (i.e. X : T renames V.Field (2) => Field).
   --   - In the case of a renaming whose target is An_Explicit_Dereference, returns Nil_Element
   --     (the target is statically unknown)
   --   - In the case of a renaming whose target is A_Function_Call, returns Nil_Element
   --     (the target is statically unknown, it designates the result of the function call)
   --   - In the case of the renaming of an attribute, returns the attribute
   -- Otherwise: returns its argument
   --
   -- In any case, if The_Name is A_Defining_Name, then A_Defining_Name is returned
   -- if The_Name is An_Identifier, then An_Identifier (or An_Attribute_Reference) is returned
   --
   -- Appropriate Element_Kinds:
   --    A_Defining_Name
   --    An_Expression
   -- Appropriate Expression_Kinds:
   --    An_Identifier
   --    A_Selected_Component (operates on selector)
   --    An_Attribute_Reference


   function Ultimate_Expression_Type (The_Element : Asis.Expression) return Asis.Definition;
   -- return the type definition of the ultimate ancestor type of The_Element
   -- (going up all subtype and derived type declaration).


   function Expression_Type_Kind (The_Element : Asis.Expression) return Asis.Type_Kinds;
   -- Real kind of an expression
   -- return the Type_Kind of the ultimate ancestor of The_Element
   -- (going up all subtype and derived type declaration).


   type Expression_Usage_Kinds is (Untouched, Read, Write, Read_Write);
   function Expression_Usage_Kind (Expr : Asis.Expression) return Expression_Usage_Kinds;
   -- Returns Untouched if Expr is part of a renaming declaration
   -- Returns Write if Expr designates a variable which is the
   --  target of an assignment statement, or an actual corresponding
   --  to an out parameter in a procedure or entry call.
   -- Returns Read_Write if Expr designates a variable which is
   --  an actual corresponding to an in out parameter in a procedure
   --  or entry call.
   -- Returns Read in all other cases (including when Expr is not a variable)
   --
   -- Note that this function handles access types properly, i.e. in:
   --    Integer_Pointer.all := 1;
   -- if passed Integer_Pointer.all, it will return Write;
   -- if passed Integer_Pointer, it will return Read.

   function Includes_Renaming (Path : Asis.Expression) return Boolean;
   -- Checks whether any element in the Path is a renaming
   --
   -- Appropriate expression kinds:
   --   An_Identifier
   --   A_Selected_Component
   --   A_Function_Call
   --   An_Indexed_Component
   --   A_Slice

   type Pragma_Set is array (Asis.Pragma_Kinds) of Boolean;
   function Corresponding_Pragma_Set (Element : in Asis.Element) return Pragma_Set;
   -- Returns the set of pragmas that apply to the corresponding name or defining name
   -- Note that unlike Corresponding_Pragmas, this query makes sure that the pragma applies
   -- really to the given element in the case of a multiple declaration.
   --
   -- Appropriate element kinds:
   --   An_Expression
   --   A_Defining_Name
   -- Appropriate expression kinds
   --   An_Identifier
   --   A_Selected_Component (function applied to the selector)

   -------------------------------------------------------------------------------------------------
   --                                                                                             --
   -- Queries about callable constructs                                                           --
   --                                                                                             --
   -------------------------------------------------------------------------------------------------

   function Is_Callable_Construct (Element : Asis.Element) return Boolean;
   -- Checks whether the Element is a callable construct
   -- Expected elements:
   --    A_Declaration
   --    A_Definition
   --    A_Defining_Name
   --    An_Expression
   -- Appropriate Expression_Kinds:
   --    An_Identifier
   --    A_Selected_Component (applies to the selector)


   function Called_Simple_Name (Call : Asis.Element) return Asis.Expression;
   -- Given a procedure, entry or function call, returns the simple name of the called
   -- entity (from the call).
   -- It handles all cases in the same function (i.e. whether it is a procedure or a function,
   -- whether the call is from an access to subprogram, etc.)
   -- Returns the simple name of the called entity (i.e. not a Selected_Name).
   -- For calls to an entry family, returns the name of the family
   -- Returns a Nil_Element if the call is through an access to subprogram
   -- Works with dispatching calls!
   --
   -- Appropriate Element_Kinds:
   --    A_Statement
   --    An_Expression
   -- Appropriate Statement_Kinds:
   --    A_Procedure_Call_Statement
   --    An_Entry_Call_Statement
   -- Appropriate Expression_Kinds:
   --    A_Function_Call


   function Called_Profile (Call : Asis.Element) return Asis.Parameter_Specification_List;
   -- Given a procedure, entry or function call, returns the parameter profile of the called
   -- entity.
   -- For simple cases, it is like Parameter_Profile (Corresponding_Called_Entity (Call)),
   -- but it handles all cases in the same function (i.e. whether it is a procedure or a function,
   -- whether the call is from an access to subprogram, etc.)
   --
   -- Appropriate Element_Kinds:
   --    A_Statement
   --    An_Expression
   -- Appropriate Statement_Kinds:
   --    A_Procedure_Call_Statement
   --    An_Entry_Call_Statement
   -- Appropriate Expression_Kinds:
   --    A_Function_Call


   function Formal_Name (Call : Asis.Element; Actual : Asis.List_Index) return Asis.Defining_Name;
   -- Given a procedure, entry or function call, or a generic instantiation, returns the defining name
   -- of the formal corresponding to the actual at the given position in the call.
   -- Note: if the full Parameter_Specification is desired, it is the Enclosing_Element of the Formal_Name
   --
   -- Returns a nil element if:
   --   Actual is greater than the number of actuals in the call
   --   The call is to a dispatching operation


   function Formal_Name (Assoc : Asis.Association) return Asis.Defining_Name;
   -- Same as above, but retrieves the call (or instantiation) and the position given an association


   function Actual_Expression (Call : Asis.Element; Formal : Asis.Defining_Name) return Asis.Expression;
   -- Given a procedure, entry or function call, or a generic instantiation, returns the value
   -- of the actual corresponding to the formal whose defining_identifier is passed.
   -- If there is no such actual (the call used the default value), the default expression is returned.
   --
   -- Returns a nil element if:
   --   The call is to a dispatching operation
   --   The formal is not from the called entity


   function Actual_Parameters (Element : Asis.Element; Normalized : Boolean := False) return Asis.Association_List;
   -- Returns the actual parameters of a procedure, entry, or function call, or of
   -- a generic instantiation


   type Type_Attribute is (None, Base, Class);
   type Profile_Entry is
      record
         Is_Access : Boolean;
         Attribute : Type_Attribute;
         Name      : Asis.Defining_Name;
      end record;
   type Profile_Table is array (Asis.List_Index range <>) of Profile_Entry;
   type Profile_Descriptor (Formals_Length : Asis.ASIS_Natural) is
      record
         Result_Type : Profile_Entry;
         Formals     : Profile_Table (1..Formals_Length);
      end record;
   function Types_Profile (Declaration : in Asis.Declaration) return Profile_Descriptor;
   -- Given a callable entity declaration, returns a list of Defining_Name
   -- First element is the result type for a function, Nil_Element for other callable entities
   -- Other elements are (in order of declaration) the *types* of the parameters.
   -- Multiple declarations are separated, i.e. "A,B : Integer" yields two entries in the table.


   function External_Call_Target (Call : Asis.Element) return Asis.Expression;
   -- Returns the prefix of the call that designates the target object
   -- of an external call (LRM 9.5 (2..7)).
   -- Returns Nil_Element if Element does not designate an external call.
   --
   -- Appropriate Element_Kinds:
   --   An_Expression
   --   A_Statement
   --
   -- Appropriate Expression_Kinds:
   --   A_Function_Call
   --
   -- Appropriate Statement_Kinds:
   --   A_Procedure_Call_Statement
   --   An_Entry_Call_Statement
   --   A_Reqeue_Statement
   --   A_Requeue_Statement_With_Abort

   -------------------------------------------------------------------------------------------------
   --                                                                                             --
   -- Static evaluator and static properties of ranges and constraints                            --
   --                                                                                             --
   -------------------------------------------------------------------------------------------------

   type Biggest_Int is range System.Min_Int .. System.Max_Int; -- The best we can do
   Non_Static : constant Biggest_Int := -1;

   subtype Biggest_Natural          is Biggest_Int range 0          .. Biggest_Int'Last;
   subtype Extended_Biggest_Natural is Biggest_Int range Non_Static .. Biggest_Int'Last;

   type Extended_Biggest_Natural_List is array (Positive range <>) of Extended_Biggest_Natural;


   function Static_Expression_Value_Image (Expression : Asis.Expression) return Wide_String;
   --  Computes the value of Expression if it is a static expression
   --  and represents it as a (wide) string. For enumeration expressions, the
   --  image of the Pos value of the defining enumeration or character literal
   --  corresponding to the  value of the expression is returned.
   --
   --  For non-static expressions, or expressions that we cannot (yet) evaluate,
   --  an empty string is returned.
   --
   --  Currently implemented:
   --  All types:
   --     Constant
   --     Parenthesized expression
   --     'Pred, 'Succ, 'Pos, 'Val, 'First, 'Last
   --     Conversions and qualified expressions
   --  Integer: (provided values are within System.Min_Int .. System.Max_Int)
   --     Literal
   --     Named number
   --     + - * / **
   --  Real:
   --     Literal
   --     Named number
   --  Enumerated:
   --     Literal
   --  String: (no way to distinguish true "" from non-static expression)
   --     Literal
   --     &
   --
   --  Appropriate Element_Kinds:
   --     An_Expression
   --
   --  The specification of this function is derived (and compatible with) the one
   --  declared in the GNAT extension Asis.Extensions
   --  (except that we do not have the same set of implemented/non-implemented features)


   function Discrete_Constraining_Bounds (Elem : Asis.Element) return Asis.Element_List;
   -- Elem must designate a type, a variable, a constant, a formal parameter,
   -- or a generic formal object.
   --
   -- Returns the expressions that constrain the values of a discrete type.
   -- Returned list has two elements
   -- Signed integer type : returns (First_Expression, Last_Expression)
   -- Subtype of modular  : returns (First_Expression, Last_Expression)
   -- Modular type        : returns (Nil_Element, Mod_Expression)
   -- Enumerated type     : returns (First_Defining_Name, Last_Defining_Name)
   --
   -- Returns the bounds that constrain the indexes of an array type.
   -- Returned list has an even number of elements (First(1), Last (1), First (2), Last (2), ...)
   -- Each pair of elements is the same as above
   --
   -- Returns Nil_Element_List if the type that applies to Elem is not discrete or array, or is formal
   --
   -- Appropriate Element_Kinds:
   --   An_Expression
   --   A_Declaration
   --   A_Definition
   --
   -- Appropriate Expression_Kind:
   --   An_Identifier
   --   A_Selected_Component (operates on the selector)
   --   A_Function_Call (operates on the returned object)
   --
   -- Appropriate Declaration_Kinds
   --   An_Ordinary_Type_Declaration
   --   A_Subtype_Declaration
   --   A_Task_Type_Declaration
   --   A_Protected_Type_Declaration
   --   A_Private_Extension_Declaration
   --   An_Incomplete_Type_Declaration
   --   A_Private_Type_Declaration
   --   A_Variable_Declaration
   --   A_Constant_Declaration
   --   A_Component_Declaration
   --   A_Parameter_Specification
   --   A_Formal_Object_Declaration
   --
   -- Appropriate Definition_Kinds
   --   A_Discrete_Range
   --   A_Constraint
   --
   -- Returns Element_Kind:
   --   Not_An_Element
   --   An_Expression
   --   A_Defining_Name


   function Discrete_Constraining_Lengths (Elem : Asis.Element) return Extended_Biggest_Natural_List;
   -- Like Discrete_Constraining_Bounds, but returns the number of values in the range instead of
   -- the bounds if statically determinable
   -- Returns Non_Static (-1) if not statically determinable


   type Result_Confidence is (Unlikely, Possible, Certain);
   type Variable_Overlap  is (Complete, Partial, None);
   type Proximity is
      record
         Confidence : Result_Confidence;
         Overlap    : Variable_Overlap;
      end record;
   Same_Variable : constant Proximity := (Certain, Complete);

   function Variables_Proximity (Left, Right : Asis.Element) return Proximity;
   -- Determines if Left and Right can possibly refer to (par of) the same variables.
   -- If Left or Right is not a variable, always returns (Certain, None)
   -- Overlap => None is only returned with Confidence => Certain
   --
   -- Some especially useful results:
   -- (Certain, Complete): Statically known to be the same variable
   -- (Certain, None)    : Statically known to be different variables
   --
   -- Appropriate Element_Kinds:
   --   An_Expression
   --   A_Defining_Name

   function Same_Value (Left, Right : Asis.Expression) return Boolean;
   -- Determines if Left and Right statically have the same value.
   -- Returns True if:
   --   Left and Right statically denote the same constant or in parameter
   --   or Left and Right are discrete and evaluate statically to the same value.

end Thick_Queries;

****************************************************************

From: Tucker Taft
Sent: Sunday, May 13, 2007  3:16 PM

Here is an updated SI on a semantic model for Asis. [This is version /02 of
the SI - ED] I have included a package specification and some
rationale.  I think it is largely complete, but
there are many issues to be discussed and interfaces
to be reviewed.  Enjoy!

****************************************************************

From: Tucker Taft
Sent: Friday, May 18, 2007  2:53 PM

I realize I never specified the interfaces needed
to go from an ASIS Element to the "View" type
declared in Asis.Views.  Hence, please add the
following to the "wording" section for SI99-0024: [This was done in version
/03 of the SI - ED]

Add at end of Asis.Declarations:

     function Corresponding_Declared_View(
       Declaration: in Asis.Declaration)
       return Asis.Declared_Views.Declared_View;

Add at end of Asis.Definitions:

     function Corresponding_Subtype_View(
       Type_Definition : in Asis.Type_Definition)
       return Asis.Subtype_Views.Subtype_View;

Add at end of Asis.Expressions:

     function Corresponding_View(
       Expression : in Asis.Expression)
       return Asis.Views.View;

****************************************************************

From: Pascal Leroy
Sent: Thursday, May 24, 2007  4:48 AM

> Here is an updated SI on a semantic model for Asis.
> I have included a package specification and some
> rationale.  I think it is largely complete, but
> there are many issues to be discussed and interfaces
> to be reviewed.  Enjoy!

Is there any reason why you didn't use limited_with_clauses for
Typed_Views, rather than lumping 80% of the API in a single package?  This
seems to be the perfect example where you would want to use them to break
circular dependencies.

****************************************************************

From: Tucker Taft
Sent: Thursday, May 24, 2007  9:21 AM

I thought about that, but then realized I would
need to use a lot of access parameters, or switch
over to using tagged types, and the implications
of using access types and/or tagged types seemed
pretty bad (see the discussion section of the
AI about that).

****************************************************************

From: Randy Brukardt
Sent: Thursday, May 24, 2007  9:40 PM

Tucker writes:

> I thought about that, but then realized I would
> need to use a lot of access parameters, or switch
> over to using tagged types, and the implications
> of using access types and/or tagged types seemed
> pretty bad (see the discussion section of the
> AI about that).

Humm, something seems wrong here. I'm on record as believing that
(virtually) all new ADTs should be implemented as tagged, controlled
types. I hardly ever use anything else these days. I can understand
not wanting to require the use of tagged types (although that didn't
seem to be a problem for the containers library, and this is similar),
but creating an interface which is not *allowed* to be implemented that
way is a non-starter for me.

Your reason for this decision is described as:

> We had various criteria which led to our current proposal of using
> a non-tagged hierarchy of discriminated types.  One goal was to permit
> declaring variables whose underlying entity kind might not be known
> at the point of declaration.  Similarly, we wanted to be able to manipulate
> heterogeneous lists of semantic entities.  Both of these precluded
> using tagged types, since only class-wide types allow heterogeneity,
> and those require explicit initialization.

But I don't get it. Surely there is no issue with lists of classwide entities
(it's pretty much the only way to build a usefully hetrogeneous list in Ada);
if you need a different element, you simply swap one in. And it's easier still
if you use an Ada.Containers list.

The object is more of an issue, but as I see it the problem is the visible
discriminant (a programming style that went out with Ada 83 ;-), not the
fact that type is tagged. That is, I think the design should be a bit more
like the existing ASIS:

   type View is tagged private;

   function View_Kind (V : View) return View_Kinds;


If you want compile-time checking, you can always make View an abstract root
type, and derive appropriate subtypes:

   type Subtype_View is new View with private;

   type Type_View is new View with private;

The point is that switching easily between kinds is incompatible with
compile-time checking: you can have one or the other, but not both. But
perhaps there is a middle ground as I described here: it doesn't seem make
a lot of sense to declare objects that can be *any* view; you're more likely
to want any kind of subtype, or the like. And you still can declare any view
as View'Class; it's just going to require a bit more work on the part of the
client (unless they are using an Ada.Container to store these, in which case
the container will do all of the work anyway).

There is a danger of getting too fancy, of course, but the alternative is an
Ada 83 design that has to be implemented with variant records and will be very
difficult to implement appropriate memory management (given the difficultly of
using controlled types).

I'm as guilty as anybody of using these antique designs (I've been using them
forever), but seriously: modern programs are built by stitching components
together, especially the ones defined in our standards. And extending these
types seems like it might be a useful thing to do (so the application can add
information to entities, for instance). Surely prefix calls would be useful.
So, let's try to use the modern tools along with the old ones. (And a useful
side-effect is that we can break up this monolith.)

****************************************************************

From: Tucker Taft
Sent: Thursday, May 24, 2007  10:28 PM

I promise I really tried to use tagged types, and
the result was a proliferation of access types.
Access types seemed like a real problem because
many implementations of ASIS, I believe, will use
some kind of software paging scheme, so you can't
let the user worry about dangling references.
It has to be hidden behind the abstraction.

You can certainly use controlled components in the
*implementation*, because the basic "View"
type is private.  However, making it publicly
tagged is a real problem, since you couldn't declare
a View'class object uninitialized, nor could you
declare one as a component of some other type.
I think that would be a real hardship.

My expectation is that the primary component of
the View type will be a controlled object representing
an abstract "reference" to a semantic entity.  It might
have one component that is an access-to-tagged type
which would be used as a "cache" of a recently
retrieved object, but which could be null,
and another that is some kind of unique ID that
can work even if the relevant compilation unit
is paged out, or not yet loaded in.  Of course
for an all-in-memory-at-the-same-time implementation,
you could just have an access-to-tagged type
component and be done with it, but I think that
could have scalability issues for large systems.
In any case, I don't see the need for a variant
record, though it might make sense in some
implementations.

I suppose another way to think about it is that
we have an untagged, discriminated wrapper around
an access-to-tagged-type, to offload the storage
management issues from the user.  Making the
discriminants visible provides for run-time
checks on conversion, which seems preferable
to delaying the checks until the use of some interface.

I welcome attempts by others to propose something
that works that uses visibly tagged types, but I was
not able to come up with anything workable
that didn't expose all kinds of storage management
issues to the user.  If this were my own private
interface to my compiler's symbol table, I could
probably safely expose a tagged type hierarchy,
but since this is supposed to be an interface that
acts as a kind of "wrapper" around any implementation's
symbol table, I think that is not practical.

This is definitely a situation where the devil is
in the details, and you really need to work out some
examples before you can claim to have a visibly-
tagged-type approach that works reasonably.  All
power to you if you succeed.

****************************************************************

From: Tucker Taft
Sent: Thursday, May 24, 2007  11:28 PM

I seem to be missing a definition of Package_View_Kinds,
which should unsurprisingly be:

    subtype Package_View_Kinds is View_Kinds range
      A_Noninstance_Package..A_Limited_Package_View;

[Added this to version /04 of the SI.]

****************************************************************

From: Randy Brukardt
Sent: Friday, May 25, 2007  12:05 AM

> I promise I really tried to use tagged types, and
> the result was a proliferation of access types.
> Access types seemed like a real problem because
> many implementations of ASIS, I believe, will use
> some kind of software paging scheme, so you can't
> let the user worry about dangling references.
> It has to be hidden behind the abstraction.

I surely agree that lots of access types are a problem, but I don't see why
there would be *any* visible access types. The only reason we ended up with
any in Claw was because copying the objects was too expensive in a few cases
(mainly for parent access); you've previously argued that was because the
entities in question should have been limited. That argument was reasonable
to me. So either these should be limited or there is no problem with access.
(How's that for reasoning from no information? ;-)

> You can certainly use controlled components in the
> *implementation*, because the basic "View"
> type is private.  However, making it publicly
> tagged is a real problem, since you couldn't declare
> a View'class object uninitialized, nor could you
> declare one as a component of some other type.
> I think that would be a real hardship.

I can't imagine why; a View by itself (as opposed to one of the subsets of
it) seems so broad as to be useless. I guess I'd like to see some sample use
cases for this library, because otherwise we're potentially arguing with
very different ideas of how this might be used. And that will make a big
difference as to the design.

Lists of 'class are handled completely by Ada.Containers. So the only
possibly problematic case is a singleton View'Class object or component: the
question is if that is a realistic use case.

> My expectation is that the primary component of
> the View type will be a controlled object representing
> an abstract "reference" to a semantic entity. ...

OK, but there is no reason to hide the taggedness then, and cause issues
with lifetime and access to your containing object. (Requiring the use of
the Rosen trick is not a good thing, IMHO.)

...
> In any case, I don't see the need for a variant
> record, though it might make sense in some
> implementations.

If there is a discriminant, then there ought to be a discriminant-dependent
component. Otherwise, you're just violating information hiding for no real
reason. (Indeed, I'm unconvinced that there is any use for a visible
discriminant...)

> I suppose another way to think about it is that
> we have an untagged, discriminated wrapper around
> an access-to-tagged-type, to offload the storage
> management issues from the user.  Making the
> discriminants visible provides for run-time
> checks on conversion, which seems preferable
> to delaying the checks until the use of some interface.

Huh? In the AI you're talking about *compile-time* checks. That seems like a
worthy goal. But now you're talking about *where* run=time checks occur, and
that just doesn't seem that important: finding runtime failures requires
extensive testing or a fancy tool (kinda like yours...:-), and exactly where
those occur doesn't have much effect on whether they are detected.

> I welcome attempts by others to propose something
> that works that uses visibly tagged types, but I was
> not able to come up with anything workable
> that didn't expose all kinds of storage management
> issues to the user.  If this were my own private
> interface to my compiler's symbol table, I could
> probably safely expose a tagged type hierarchy,
> but since this is supposed to be an interface that
> acts as a kind of "wrapper" around any implementation's
> symbol table, I think that is not practical.

I really would like use-cases where storage management issues would be
exposed to the user. I can't think of any off-hand, but that's because I
don't believe in your Root_Item'Class objects. (Note that I was proposing to
keep the common sets as single tagged types, so it wouldn't be necessary to
use a 'Class object to declare an object of any Subtype_View, for instance.)
But that was all about getting compile-time checking. If you are getting
only run-time checks, there is no problem at all: just replace all of your
current types with root, concrete tagged types and a query function for the
kind. And then you can have all of the objects you want.

In all honesty, if it works for your symboltable, it probably will work for
most of them (they don't seem that different based on what I've heard at ARG
meetings, and yours seems to be among the most complex since it includes its
own virtual memory system). I certainly wouldn't want to worry about the
implementation details: let the ASIS implementers and potential implementers
scream about that if there is a problem.

> This is definitely a situation where the devil is
> in the details, and you really need to work out some
> examples before you can claim to have a visibly-
> tagged-type approach that works reasonably.  All
> power to you if you succeed.

I'd like to know what is being lost with my proposal above (if you really
have no compile-time checking, and looking at it briefly I didn't see much).
Anyway, I'd like to know the use-cases that you have in mind that don't work
with that model.

Finally, lest I seem too negative here, I realize that this spec required a
lot of hard work, and someone had to make an initial proposal. It's lot
easier to take potshots at it after the fact, and I'm certainly doing that.
I certainly appreciate your work (and am really glad I didn't have to do
it!) I realize you might be right that this cannot be a proper O-O design,
but I'm trying to figure out why. This problem doesn't seem that different
from many other O-O problems; if it can't be done well, then that implies
that Ada is inadequate for good O-O design. And it would be valuable to
investigate that if true.

****************************************************************

From: Pascal Leroy
Sent: Friday, May 25, 2007  1:32 AM

> I seem to be missing a definition of Package_View_Kinds,
> which should unsurprisingly be:
>
>     subtype Package_View_Kinds is View_Kinds range
>       A_Noninstance_Package..A_Limited_Package_View;

Along the same lines, Typed_Views.Are_Of_Same_Type should probably take
two parameters.

[Added this to version /04 of the SI.]

****************************************************************

From: Tucker Taft
Sent: Friday, May 25, 2007  12:39 AM

Oops.  One more (serious) bug.  Type View is supposed
to have a default for its discriminant.  That's
pretty critical for all of this to work:

     type View(Kind : View_Kinds :=
       View_Kinds'First) is private;

[Added this to version /04 of the SI.]

****************************************************************

From: Pascal Leroy
Sent: Friday, May 25, 2007  1:45 AM

> You can certainly use controlled components in the
> *implementation*, because the basic "View" type is private.

Incidentally, why is the discriminant of View not defaulted?  Is this an
error, or am I missing something?

Note that for those types that have a defaulted discriminant, it is not
possible for the full type declaration to be a tagged type.  This is a bit
annoying, as tagged types have many nice properties that untagged types
don't have (e.g., equality composes properly).

****************************************************************

From: Pascal Leroy
Sent: Friday, May 25, 2007  4:33 AM

Randy wrote, replying to Tuck:

> > Access types seemed like a real problem because
> > many implementations of ASIS, I believe, will use
> > some kind of software paging scheme, so you can't
> > let the user worry about dangling references.
> > It has to be hidden behind the abstraction.
>
> I surely agree that lots of access types are a problem

I apologize if I am being thick, but I don't understand why we would have
dangling references.

Tuck seems to assume that a View is going to map directly to a symbol
table entry/tree node.  I'm not sure that things would actually work that
way.  I realize that there are numerous differences between
implementations, but in our case a View would certainly *not* be a Diana
node.  One reason is that the physical layout of a Diana node is very
complicated and we wouldn't want to expose that complexity even to the
implementation of Asis.  But more importantly, it's very unlikely that the
a View would match one-to-one with a Diana node.  In all likelihood, a
View would contain a pointer to a Diana node with some extra information
(possibly other pointers) that would make it possible to retrieve all the
properties of the View.  We would certainly page the Diana trees in and
out (in which case we would record in the View enough information to be
able to retrieve the Diana nodes from permanent storage) but we would
*not* page the Views themselves.

The bottom line is there would be an extra level of indirection at the
implementation level, and pointers to Views would remain valid even when
Diana trees are paged out.  Tuck's dangling reference problem seems like a
red herring to me.

> I can't imagine why; a View by itself (as opposed to one of
> the subsets of
> it) seems so broad as to be useless.

Maybe, but that's bogus because you surely have the same problem with,
say, Subtype_View.

> Lists of 'class are handled completely by Ada.Containers.

If you believe that access types are a problem, then you have to believe
that Ada.Containers would be a problem, too: View'Class could only be used
with the indefinite containers, and they are almost certainly implemented
with access types.  The fact that they are hidden from you doesn't fix any
dangling reference problem that might arise.

****************************************************************

From: Randy Brukardt
Sent: Friday, May 25, 2007  1:43 PM

...
> I apologize if I am being thick, but I don't understand why we would have
> dangling references.

I don't give a flying... sorry need to be polite. I don't care about
dangling references; that's not a real problem. My objection to access types
in ADT specifications is simply that they force the user to be aware of and
usually handle storage management issues. Even when the actual objects are
aliased rather than allocated objects. My view is that access types of all
sorts should be minimized in all library specifications, preferably to none
at all.

...
> > I can't imagine why; a View by itself (as opposed to one of
> > the subsets of
> > it) seems so broad as to be useless.
>
> Maybe, but that's bogus because you surely have the same problem with,
> say, Subtype_View.

No, you obviously did not carefully read my proposal. My idea was that
Subtype_View would be a tagged concrete type. There would be a query
function for the Kind; there would not be any types derived from
Subtype_View. So all Subtype_View objects could hold any kind of subtype
view, and there would be no need to use 'Class for that.

The point of that was to get *real* compile-time checking, such that
operations that only make sense for Subtype_Views don't even exist for other
types. Tucker's scheme only moves the run-time check to the call site from
inside the routine: it is just a very weak precondition. Buys very little
IMHO.

> > Lists of 'class are handled completely by Ada.Containers.
>
> If you believe that access types are a problem, then you have to believe
> that Ada.Containers would be a problem, too: View'Class could only be used
> with the indefinite containers, and they are almost certainly implemented
> with access types.  The fact that they are hidden from you doesn't fix any
> dangling reference problem that might arise.

Ada.Containers does the storage management, the user doesn't have to with
access types. If the library isn't able to properly manage itself and gets
dangling references, it is broken. As I said before, my only concern is
about the storage management.

If I had time, I'd make a counter-proposal (seems only fair), but I
unfortunately won't have time before the meeting.

****************************************************************

From: Sergey I. Rybin
Sent: Friday, August 10, 2007  11:32 AM

I've tried to start my own project aimed at designing
the (high level) ASIS semantic model.

Things that I do not like in Tucker Taft's proposal are:

1. Tucker's interface is already far too big, and ASIS already has
    a problem of too big number of queries and other entities
    that are defined in the ASIS Standard. That's why I've tried
    to start from a small and observable step.

2. Ada package specifications in the Tucker's proposal do not contain
    any documentation at all. There are two reasons why I definitely
    do not like this.
    - devil is in the details, when you are writing the documentation,
      you *have* to think about details, so undocumented specs contain
      too much of devil;

    - I do remember how much time it took to finalize all the documentation
      for ASIS 95, so, if we start from such a huge, but completely
      undocumented spec, we have all the chances that it will never be
      completed (as a part of any further ASIS standard)

    That's why I've tried to start with fully documented specifications

3. Tucker's specs are not compilable. I'm going to keep my specs fully
    compilable from the very beginning of the project.

4. There is no usage example in the Tucker's proposal. I've tried to
    provide at least a couple of simple examples.

5. Tucker's proposal looks very hard from the implementer's viewpoint,
    and it is not easy to select a relatively closed and useful subset
    to start from. I've tried to provide a practically mplementable
    start (I think I would need no more then a week to implement what
    I'm suggesting here), and to use an easily extendable set of
    packages.

 From the other side, Tucker's proposal is far more complete and covers
all the language and most of the semantic needs we could imagine at the
application side, and my project in its current state provides only a
very basic scheme and a couple of really useful queries.

The main open issues in my project are:

1. Basic abstractions. I have some strong feeling that we need both
    Views (on Entities) and Entities. Ticker's proposal is based on
    Views only. At the moment I cannot provide any proof or justification
    for the need of both Entities and Views.

2. Classification. At the moment I cannot say in what extent enumeration
    types should be used to classify views and entities. In the current
    spec all the base types are not tagged, but most probably I will
    move to the object oriented classification of the Ada entities without
    using enumeration types.

I'm very far from suggesting that my specs should replace Tucker's proposal
as a means to bridge the gap between low level ASIS queries and high level
semantic needs at the application side. This is just a part of the discussion...

-----

package Asis.Entities is

   --  This package defines the main abstractions for the new ASIS semantic
   --  interface.

   type Entity is private;
--   type Entity is tagged private; ???
   --  Represents an entity. The meaning of the notion "Entity" is defined by
   --  the Ada Standard

   Nil_Entity : constant Entity;
   --  Represents nothing

   Standard_Entity : constant Entity;
   --  specifies the predefined package Standard

   ASIS_Inappropriate_Entity : exception;
   --  Is raised if a given Entity value cannot be used as an argument for a
   --  given query

   type Entity_List is array (Natural range <>) of Entity;
   --  The most trivial solution! Most probably, we have to switch to
   --  containers here (ordered sets?)

   function Is_Equal (Left : Entity; Right : Entity) return Boolean;
   --  Returns True if Left and Right specifies the same Entity, and False
   --  otherwise

   --  ??? Do we need Is_Identical, and do we have to bother about queries for
   --  ??? processing more then one Context at a time?

   function ">" (Left : Entity; Right : Entity) return Boolean;
   --  This function can be used to define ordered containers for Entity
   --  values. This ">" does not have any reasonable "physical" meaning

   function Is_Nil (Left : Entity) return Boolean;
   --  Check if the argument represents nothing

   function Is_Scope (E : Entity) return Boolean;
   --  Some entities are scopes (that is, they may contain other entities as
   --  subcomponents, e.g. a package entity or a protected type entity). The
   --  meaning of the notion "scope" should be as close to Ada Standard as
   --  possible

   type View is
   --  Various kinds of views a context or a client may have on an entity
     (Not_A_View,

      Full_View,
      --  All the entity properties are available. All the non-nil Entities
      --  have full view.

      --  For packages:
      Client_View,
      Child_To_Parent_View,

      --  For library packages
      Limited_Library_View,
      Private_Library_View,
      Limited_Private_Library_View,

      --  For types
      Incomplete_View,
      Private_View,

      --  For renamable entities
      Renamed_View

      --  anything else???
      );

   type View_On_Entity is private;
--   type View_On_Entity is tagged private; ???
--   type View_On_Entity is new Entity with private; ???
   --  Represents a specific view on a specific entity

   Nil_View_On_Entity : constant View_On_Entity;

   ASIS_Inappropriate_View : exception;
   --  Is raised when a given view cannot be applied to a given entity (for
   --  example, we cannot view a package with Incomplete_View

   type View_On_Entity_List is array (Natural range <>) of View_On_Entity;
   --  The most trivial solution! Most probably, we have to switch to
   --  containers here (ordered sets?)

   function Is_Nil (Left : View_On_Entity) return Boolean;
   --  Check if the argument represents nothing

   function Is_Equal
     (Left  : View_On_Entity;
      Right : View_On_Entity)
      return  Boolean;
   --  Returns True if Left and Right specifies the same view on the same
   --  Entity, and False otherwise

   function ">"
     (Left  : View_On_Entity;
      Right : View_On_Entity)
      return  Boolean;
   --  This function can be used to define ordered containers for
   --  View_On_Entity values. This ">" does not have any reasonable "physical"
   --  meaning

   function Represented_Entity (Viewed_Entity : View_On_Entity) return Entity;
   function Represented_View   (Viewed_Entity : View_On_Entity) return View;

   function Get_View
     (On_Entity : Entity;
      View_As   : View)
      return      View_On_Entity;
   --  Returns the desired view at the argument entity. Raises
   --  ASIS_Inappropriate_View if the given view cannot be applied to the
   --  argument entity

   procedure Change_View
     (Viewed_Entity : in out View_On_Entity;
      To_View       : View);
   --  Changes the view to the argument entity.  Raises ASIS_Inappropriate_View
   --  if the given view cannot be applied to the argument entity

private
   --  Just a placeholder for the moment

   type Entity is new Element;

   Nil_Entity : constant Entity := Entity (Nil_Element);

   type View_On_Entity is new Entity;

   Nil_View_On_Entity : constant View_On_Entity := View_On_Entity (Nil_Entity);

end Asis.Entities;

-----

package Asis.Entities.Structure is

   --  This package defines bridges between core Asis abstractions and
   --  Entities.

   --  This package also defines the structural queries for the high-level
   --  semantic abstractions. A program is viwed as a hierarchy of scopes. Each
   --  scope may contain other scopes and entities that are not scopes. This
   --  gives the possibility to decompose and to traverse the semantic
   --  structure of the program

   --------------------------------------
   -- Asis.Compilation_Unit <-> Entity --
   --------------------------------------

   function CU_Entity (CU : Asis.Compilation_Unit) return Entity;
   --  Returns the entity defined by the argumentg compilation unit.
   --
   --  Appropriate Unit_Kinds:
   --     A_Procedure
   --     A_Function
   --     A_Package
   --     A_Generic_Procedure
   --     A_Generic_Function
   --     A_Generic_Package
   --     A_Procedure_Instance
   --     A_Function_Instance
   --     A_Package_Instance
   --     A_Procedure_Renaming
   --     A_Function_Renaming
   --     A_Package_Renaming
   --     A_Generic_Procedure_Renaming
   --     A_Generic_Function_Renaming
   --     A_Generic_Package_Renaming
   --     A_Procedure_Body
   --     A_Function_Body
   --     A_Package_Body
   --     A_Procedure_Body_Subunit
   --     A_Function_Body_Subunit
   --     A_Package_Body_Subunit
   --     A_Task_Body_Subunit
   --     A_Protected_Body_Subunit

   function Enclosing_Unit (E : Entity) return Asis.Compilation_Unit;
   --  Returns ASIS Comnpilation Unit where the given entity is declared.
   --  Raises ASIS_Inappropriate_Entity if Is_Nil (E).

   -------------------------------
   -- Asis.Element <-> Entity --
   -------------------------------

   function Represented_Entity (E : Asis.Element) return Entity;
   --  If the argument Element represents some entity (or some view on this
   --  entity), returns the corresponding entity, Otherwise returns Nil_Entity.
   --
   --  More then one Element can represent the same Entity. For example,
   --  if a given procedure has a separate declaration completed by a body
   --  stub, then the corresponding A_Procedure_Declaration,
   --  A_Procedure_Body_Stub and A_Procedure_Body_Declaration Elements all
   --  represent the same procedure entity.

   function Represented_View (E : Asis.Element) return View_On_Entity;
   --  If the argument Element represents a particular view on some Entity,
   --  returns this view (e.g, A_Private_Type_Declaration Element represents
   --  Private_View on a type Entity. If a represented Entity does not have
   --  any other views except Full_View, returns the full view. If the argument
   --  Element does not represent any Entity, returns Nil_View_On_Entity.

   function Representing_Element (E : Entity) return Asis.Element;
   --  Returns the elemengt that declares (or defines, in case of anonymous
   --  entity) the argument entity.
   --
   --  If an argument Entity is a named entity (that is, it corresponds to some
   --  declaration according to the Ada Standard, then this query returns the
   --  corresponding A_Defining_Name Element. If an argument Entity is
   --  anonymous, then the query returns A_Definition Element that defines the
   --  entity (e,g, A_Subtype_Definition is returned for an anonymous subtype).
   --
   --  Nil_Element is returned for Nil_Entity
   --
   --  ??? Precise descrription of all possible cases is needed.
   --
   --  ??? Do we need similar query for View_On_Entity???

   function Is_Anonymous (E : Entity) return Boolean;
   --  Checks if the Entity is an anonymois entity, that is, has no defining
   --  name associated with it. Returns True for Nil_Entity.

   ------------------------------
   -- Basic structural queries --
   ------------------------------

   --  If an Entity is a scope (that is, Asis.Entities.Is_Scope returns True
   --  for it), it contains other entities, These entities can be obtained
   --  from it. Some of these entities also are Is_Scope, and, therefore,
   --  can be further decomposed.

   type Filter_Access is access function (E : Entity) return Boolean;
   --  Pointer to Entity filters. An Entity filter is a boolean function that
   --  has an entity as its only parameter. Filters can be used when obtaining
   --  entities from scopes to get only those entities that are of interest
   --  for further analysis.

   function No_Filter (E : Entity) return Boolean;
   --  Always returns True

   function Enclosed_Entities
     (Scope_Entity     : Entity;
      Viewed_As        : View          := Full_View;
      Include_Implicit : Boolean       := False;
      Use_Filter       : Filter_Access := No_Filter'Access)
      return Entity_List;
   --  Requires Is_Scope (Scope_Entity), and raises ASIS_Inappropriate_Entity
   --  otherwise. Returns the list of the entities declared in Scope_Entity.
   --  All the other parameters define various ways to filter out entities to
   --  be includes in the result list. Include_Implicit indicates if implicitly
   --  declared entities should be included in the result. Only those entities
   --  for that Use_Filter returns true are included in the result (this gives
   --  the possibility to return, for example, all the subprograms defined in a
   --  given package).

   function Enclosed_Views
     (Scope_Entity     : Entity;
      Viewed_As        : View          := Full_View;
      Include_Implicit : Boolean       := False;
      Use_Filter       : Filter_Access := No_Filter'Access)
      return View_On_Entity_List;
   --  Similar to Enclosed_Entities, but returns views on entities.

   function Enclosing_Scope (E : Entity) return Entity;
   --  Returns the scope Entity where the argument Entity is derfined. Returns
   --  Standard_Entity in case if the argument is a library-level entity.
   --  Returns Nil_ENtity in case if the argument is Standard_Entity. Rasies
   --  ASIS_Inappropriate_Entity if the argument is Nil_Entity

   --  Do we need the following queries:
   --   function Enclosing_Scope (E : View_On_Entity) return Entity;
   --   function Enclosing_Scope (E : Entity) return View_On_Entity;
   --   function Enclosing_Scope (E : View_On_Entity) return View_On_Entity;
   --  ???

end Asis.Entities.Structure;

----

package Asis.Entities.Structure.Traversing is

   --  This package defines the generic traversal procedure Traverse_Scope that
   --  allows an ASIS application to traverse recursively a piece of an Ada
   --  code viewed as a hierarchy of scope entities, Traverse_Scope is in
   --  some way similar to the syntactical traversing procedure
   --  Asis.Iterator.Traverse_Element, but it traverses not the  syntax
   --  structure, but the hierarchy of logically nested entities.

   generic

      type State_Information is limited private;

      with procedure Pre_Operation
                       (E       :        Entity;
                        Control : in out Traverse_Control;
                        State   : in out State_Information) is <>;

      with procedure Post_Operation
                       (E       :        Entity;
                        Control : in out Traverse_Control;
                        State   : in out State_Information) is <>;

   procedure Traverse_Entity
     (E       :        Entity;
      Control : in out Traverse_Control;
      State   : in out State_Information);

   --  E                   - Specifies the initial Entity in the traversal
   --  Control             - Specifies what next to do with the traversal
   --  State_Information   - Specifies other information for the traversal
   --
   --  Traverses the entity and all the entities defined in it if the entity is
   --  a sope entity.
   --
   --  If a scope entity contains one or more entities defined in it, each of
   --  these entities is called a child entity. An entity's parent (scope)
   --  entity is its Enclosing_Scope.  Children with the same parent are
   --  sibling entitues. The type Traverse_Control uses the terms children and
   --  siblings to control the traverse.
   --
   --  For each entity, the formal procedure Pre_Operation is called when first
   --  visiting the entity.  Each of that entity's children are then visited
   --  and finally the formal procedure Post_Operation is called for the
   --  entity.
   --
   --  The order of entity traversal is in terms of the logical ordering of
   --  the entities in the enclosing scope entity. Entities are traversed in
   --  left-to-right and top-to-bottom order.
   --
   --  Traversal of Implicit entities: ???
   --
   --  Traversal can be controlled with the Control parameter.
   --
   --  A call to an instance of Traverse_Entity will not result in calls to
   --  Pre_Operation or Post_Operation unless Control is set to Continue.
   --
   --  The subprograms matching Pre_Operation and Post_Operation can set
   --  their Control parameter to affect the traverse:
   --
   --     Continue                -- Continues the normal depth-first
   --                             -- traversal.
   --
   --     Abandon_Children        -- Prevents traversal of the current entity's
   --                             -- children.
   --                             -- If set in a Pre_Operation, traversal picks
   --                             -- up with the next sibling entity of the
   --                             -- current scope entity.
   --                             -- If set in a Post_Operation, this is the
   --                             -- same as Continue, all children will
   --                             -- already have been traversed. Traversal
   --                             -- picks up with the Post_Operation of the
   --                             -- parent.
   --
   --     Abandon_Siblings        -- Prevents traversal of the current entity's
   --                             -- children and remaining siblings.
   --                             -- If set in a Pre_Operation, this abandons
   --                             -- the associated Post_Operation for the
   --                             -- current entity. Traversal picks up with
   --                             -- the Post_Operation of the parent.
   --                             -- If set in a Post_Operation, traversal
   --                             -- picks up with the Post_Operation of the
   --                             -- parent.
   --
   --     Terminate_Immediately   -- Does exactly that.
   --
   --  Raises ASIS_Inappropriate_Entity if the entity is a Nil_Entity
   --
   --  ??? More possibilities to control traversal?
   --  ???   - filters
   --  ???   - specify views on scopes being traversed?

end Asis.Entities.Structure.Traversing;

----

--  Core ASIS:
with Asis; use Asis;

--  ASIS Semantic Interface:
with Asis.Entities;

package Asis_Semantic_Level_Usage_Examples is

   --  This package contains usage examples for the proposed high-level ASIS
   --  sematic interface.
   --
   --  Because in its current stage the ASIS semantic interface provides only
   --  very basic possibilities, all the example routines in this package
   --  operates on ASIS Elements. The usege of the new queries is demonstrated
   --  in the implementations of these queries.

   function Get_All_Subprograms
     (Scope_Element : Asis.Element)
      return          Asis.Element_List;
   --  If the argument Element corresponds to a scope entity, returns a list
   --  of subprograms declared in this scope. Otherwise returns Nil_Element.
   --  For each subprogram being returned, the first Element defining this
   --  subproram is included in the result list (that is, if a subprogram
   --  has a separate spec, A_Procedure_Declaration or A_Function_Declaration
   --  Element is returned, if there is no separate spec - either a subprogram
   --  body stub or a subprogram body declaration element is returned.

   procedure Print_All_Declared_Entities (Scope_Element : Asis.Element);
   --  If the argument Element corresponds to a scope entity, prints out
   --  defining names of all the entities explicitly declared in this scope.

end Asis_Semantic_Level_Usage_Examples;

-----

with Ada.Wide_Text_IO;

--  Core ASIS:
with Asis.Declarations;
with Asis.Elements;

--  ASIS Semantic Interface:
with Asis.Entities.Structure;
with Asis.Entities.Structure.Traversing;

package body Asis_Semantic_Level_Usage_Examples is

   -----------------------
   -- Local subprograms --
   -----------------------

   function Only_Subprograms (E : Asis.Entities.Entity) return Boolean;
   --  Returns True only for subprogram entities.

   -------------------------
   -- Get_All_Subprograms --
   -------------------------

   function Get_All_Subprograms
     (Scope_Element : Asis.Element)
      return          Asis.Element_List
   is
      Arg_Scope : constant Asis.Entities.Entity :=
        Asis.Entities.Structure.Represented_Entity (Scope_Element);

   begin

      if Asis.Entities.Is_Scope (Arg_Scope) then

         declare
            Result_Entities : constant Asis.Entities.Entity_List :=
               Asis.Entities.Structure.Enclosed_Entities
                 (Scope_Entity => Arg_Scope,
                  Use_Filter   => Only_Subprograms'Access);

            Result_Elements : Asis.Element_List (Result_Entities'Range);
         begin

            for J in Result_Elements'Range loop
               Result_Elements (J) :=
                  Asis.Entities.Structure.Representing_Element
                    (Result_Entities (J));
            end loop;

            return Result_Elements;

         end;

      else
         return Asis.Nil_Element_List;
      end if;

   end Get_All_Subprograms;

   ----------------------
   -- Only_Subprograms --
   ----------------------

   function Only_Subprograms (E : Asis.Entities.Entity) return Boolean is
      Tmp_El : constant Asis.Element :=
        Asis.Entities.Structure.Representing_Element (E);

      Result : Boolean := False;

   begin

      case Asis.Elements.Declaration_Kind (Tmp_El) is
         when A_Procedure_Declaration      |
              A_Function_Declaration       |
              A_Procedure_Body_Declaration |
              A_Function_Body_Declaration  |
              A_Procedure_Body_Stub        |
              A_Function_Body_Stub         |
              A_Procedure_Instantiation    |
              A_Function_Instantiation     =>
            Result := True;
         when others =>
            null;
      end case;

      return Result;
   end Only_Subprograms;

   ---------------------------------
   -- Print_All_Declared_Entities --
   ---------------------------------

   procedure Print_All_Declared_Entities (Scope_Element : Asis.Element) is
      Arg_Scope : constant Asis.Entities.Entity :=
        Asis.Entities.Structure.Represented_Entity (Scope_Element);

      type My_State is (Not_Used);

      procedure Pre_Operation
        (E       :        Asis.Entities.Entity;
         Control : in out Traverse_Control;
         State   : in out My_State);
      --  If an E does have a defining name, prints out it String image. Does
      --  nothing if Is_Anonymous (E);

      procedure Post_Operation
        (E       :        Asis.Entities.Entity;
         Control : in out Traverse_Control;
         State   : in out My_State);
      --  Does nothing

      procedure Print_Defining_Names is new
        Asis.Entities.Structure.Traversing.Traverse_Entity (My_State);

      My_Traversal_State   : My_State              := Not_Used;
      My_Traversal_Control : Asis.Traverse_Control := Asis.Continue;

      procedure Pre_Operation
        (E       :        Asis.Entities.Entity;
         Control : in out Traverse_Control;
         State   : in out My_State)
      is
         Tmp_El : Asis.Element;
      begin

         if not Asis.Entities.Structure.Is_Anonymous (E) then
            Tmp_El := Asis.Entities.Structure.Representing_Element (E);

            Ada.Wide_Text_IO.Put_Line
              (Asis.Declarations.Defining_Name_Image (Tmp_El));
         end if;

      end Pre_Operation;

      procedure Post_Operation
        (E       :        Asis.Entities.Entity;
         Control : in out Traverse_Control;
         State   : in out My_State)
      is
      begin
         null;
      end Post_Operation;

   begin --  Print_All_Declared_Entities

      if not Asis.Entities.Is_Nil (Arg_Scope) then
         Print_Defining_Names
           (Arg_Scope, My_Traversal_Control, My_Traversal_State);
      end if;

   end Print_All_Declared_Entities;

end Asis_Semantic_Level_Usage_Examples;

****************************************************************

From: Tucker Taft
Sent: Wednesday, October 3, 2007  2:01 PM

I have attached an update to SI-24 [This is version /06 - ED.],
providing an ASIS semantic model.  The major change is that I
created a tagged-type version.  It uses interfaces
heavily, but I didn't have to use "limited with."
It presumes the existence of a singleton "holder"
container type, which I illustrated in an earlier
note.  I have attached a slightly updated version
of that as well.

I haven't had the time to create any examples
of use, which could be very telling.  Be that
as it may, hopefully this will provide some
indication of the possibilities.  The tagged
type version does look cleaner.  The package
structure is:
    Asis.Views
    Asis.Declared_Views
    Asis.Subtype_Views
    Asis.Object_Views
    Asis.Profiles
    Asis.Subtype_Views.Elementary
    Asis.Subtype_Views.Composite
    Asis.Callable_Views
    Asis.Package_Views
    Asis.Generic_Views
    Asis.Exception_Views

Here is one issue with the tagged-type version,
as mentioned in the !discussion section:

----

IMPLEMENTATION IN ADA 95

An Ada 95 version of this would be somewhat harder. Clearly all of the
interface types would become "regular" abstract tagged types.
However, there is a subtle issue with Declared_Views, since a given
type descended from Object_View might or might not want to be a
descendant of Declared_View, and that kind of thing implies multiple
inheritance.  The same goes for Subtype_View and Callable_View.  To
avoid this problem, we could have a separate type that captures the
information associated with a Declared_View, perhaps call it
"View_Declaration," and allow any View to have one. That way we
wouldn't be depending on multiple inheritance. View_Declaration might
be a plain old private type, which would be consistent with the types
Region_Part and Declarative_Region used already.

--------

Any comments on the above would be appreciated.  I am
tempted to make the above change, so that most of this
can be prototyped in "pure" Ada 95.  Declared_Views
are a bit confusing the way they are currently connected
into the hierarchy.

****************************************************************

From: Sergey I. Rubin
Sent: Friday, October 5, 2007  1:47 AM

> I have attached an update to SI-24, providing an
> ASIS semantic model.  The major change is that I
> created a tagged-type version.  It uses interfaces
> heavily, but I didn't have to use "limited with."
> It presumes the existence of a singleton "holder"
> container type, which I illustrated in an earlier
> note.  I have attached a slightly updated version
> of that as well.

I think at the current stage we have to move to the
fully compilable version of the proposed interface. I've tried
to compile Tucker's code, and I've got the following problems:

1. Typo in 'function' keyword:

    functino Preconstraint_Subtype(S : Subtype_View)
      return Subtype_View'Class is abstract;

2. Illegal enumeration type definition:

    type Aspect_Kinds is (
      A_Size_Aspect, An_Alignment_Aspect, An_Address_Aspect,
      A_Position_Aspect, ...);

(easy to fix as

    type Aspect_Kinds is (
      A_Size_Aspect, An_Alignment_Aspect, An_Address_Aspect,
      A_Position_Aspect
      --, ...
     );

3. New container facility is defined as:

       package Ada_Containers_Holders is

    but in the package Asis.Views we have:

      with Ada.Containers.Holders;
         pragma Elaborate_All(Ada.Containers.Holders);

    So, what is the right version: Ada_Containers_Holders or
    Ada.Containers.Holders? (If the latter is the intent, this means that
    we have to extend the Ada standard library, right?)

These things are easy to fix, but after fixing them I've got the following
as the result to compile Asis.Views:

C:\ASIS\Tucker_Taft_Proposal\new\code>gnat compile -Pasis_semantic_model.gpr asis-views.ads
gcc -c -gnat05 -I- -gnatA C:\ASIS\Tucker_Taft_Proposal\new\code\asis-views.ads
asis-views.ads:65:04: warning: no primitive operations for "View" after this line
asis-views.ads:73:13: this primitive operation is declared too late
asis-views.ads:75:13: this primitive operation is declared too late
asis-views.ads:77:13: this primitive operation is declared too late
asis-views.ads:79:13: this primitive operation is declared too late
asis-views.ads:81:13: this primitive operation is declared too late
asis-views.ads:83:13: this primitive operation is declared too late
asis-views.ads:85:13: this primitive operation is declared too late
asis-views.ads:87:13: this primitive operation is declared too late
asis-views.ads:89:13: this primitive operation is declared too late
asis-views.ads:96:13: this primitive operation is declared too late
asis-views.ads:98:13: this primitive operation is declared too late
asis-views.ads:102:13: missing full declaration for private type "Declarative_Region"
asis-views.ads:104:13: missing full declaration for private type "Region_Part"
asis-views.ads:145:13: this primitive operation is declared too late
gnatmake: "c:\asis\tucker_taft_proposal\new\code\asis-views.ads" compilation error


****************************************************************

From: Sergey I. Rubin
Sent: Friday, October 5, 2007  2:58 AM

I have a general question about the tagged-type version of the
interface. Sorry if I'm missing something that is explicitly stated
somewhere, but I've not found the explanation myself.

All the views are declared as interfaces. That is, all operations
on views are declared as abstract subprograms.

The question is - where the "real" entity types are supposed to be
declared, and where the implementation of all these operations
are supposed to be?

****************************************************************

From: Tucker Taft
Sent: Friday, October 5, 2007  6:53 AM

The concrete types that implement one or more of
these abstract interface types would be declared privately
by the implementation, and returned as a result of
some call that returns an object of type X'class,
such as Corresponding_View.

****************************************************************

From: Tucker Taft
Sent: Friday, October 5, 2007  7:04 AM

Thanks for pointing out some of these typos.  I was
a bit reluctant to invest the time in getting this
to compile if the direction I was going didn't look
promising to others.

****************************************************************

From: Sergey I. Rubin
Sent: Friday, October 5, 2007  7:59 AM

I'm afraid, making the interface compilable is necessary even
at this stage - this would allow to detect some design problems.

It is easy to fix the problems I listed in previous message,
but for Asis.Declared_Views I've encountered a real
problem - there is no legal way to declare the Depends_Semantically_On
function: it is a primitive operation of Program_Unit type,
but it also needs Program_Unit_Vector type that in its turn
needs the declaration of Program_Unit_Vectors package.

But after the declaration of Program_Unit_Vectors package it
is not allowed to declare other primitive operations of
Program_Unit type!

****************************************************************


From: Tucker Taft
Sent: Friday, October 5, 2007  8:18 AM

The trick is probably to change the functions that
return vectors to be procedures with OUT parameters.
It would be more efficient, and avoid the problem you
describe.  I have attached a version that is almost
fully compilable in Ada 95.   Interfaces have been
replaced with abstract null records, but can easily
be restored.

---

with Ada05.Containers.Holders;
  pragma Elaborate_All(Ada05.Containers.Holders);

with Ada05.Containers.Indefinite_Vectors;
  pragma Elaborate_All(Ada05.Containers.Indefinite_Vectors);

package Asis.Views is

   type View_Kinds is (
     An_Exception, An_Exception_Renaming,

     A_Generic_Package, A_Generic_Package_Renaming,
     A_Generic_Subprogram, A_Generic_Subprogram_Renaming,

     A_Noninstance_Package, A_Package_Instance, A_Package_Renaming,
     A_Limited_Package_View,

     A_Noninstance_Subprogram, A_Subprogram_Instance, A_Subprogram_Renaming,
     A_Protected_Subprogram, An_Imported_Subprogram, An_Attribute_Subprogram,
     An_Intrinsic_Subprogram, A_Designated_Subprogram,
     A_Generic_Formal_Subprogram,
     A_Protected_Entry, A_Task_Entry,

     A_Standalone_Object, A_Generic_Formal_Object,
     A_Formal_Parameter_Object, An_Object_Renaming,
     A_Designated_Object, A_Component_Object,
     An_Attribute_Object, An_Aggregate_Object, A_Function_Result_Object,
     A_Named_Number, An_Attribute_Value, An_Expr_Value,

     A_Boolean_Subtype, A_Character_Subtype, An_Ordinary_Enumeration_Subtype,
     A_Signed_Integer_Subtype, A_Modular_Integer_Subtype,
     An_Ordinary_Fixed_Subtype, A_Decimal_Fixed_Subtype,
     A_Float_Subtype,
     An_Access_To_Object_Subtype, An_Access_To_Subprogram_Subtype,

     An_Array_Subtype, A_Record_Subtype, A_Record_Extension,
     A_Task_Subtype, A_Protected_Subtype, An_Interface,

     A_Private_Subtype, A_Private_Extension,

     An_Incomplete_Subtype
   );

   subtype Exception_View_Kinds is View_Kinds
     range An_Exception .. An_Exception_Renaming;

   subtype Generic_View_Kinds is View_Kinds
     range A_Generic_Package .. A_Generic_Subprogram_Renaming;

   subtype Callable_View_Kinds is View_Kinds
     range A_Noninstance_Subprogram .. A_Task_Entry;

   subtype Object_View_Kinds is View_Kinds
     range A_Standalone_Object .. An_Expr_Value;

   subtype Subtype_View_Kinds is View_Kinds
     range A_Boolean_Subtype .. An_Incomplete_Subtype;

   subtype Package_View_Kinds is View_Kinds range
      A_Noninstance_Package..A_Limited_Package_View;


   type View is abstract tagged null record;


   function Kind(V : View) return View_Kinds is abstract;

   function Expr_Denoting_View(V : View) return Asis.Expression is abstract;

   function Has_Declaration(V : View) return Boolean is abstract;

   function Is_Exception(V : View) return Boolean is abstract;

   function Is_Generic(V : View) return Boolean is abstract;

   function Is_Callable(V : View) return Boolean is abstract;

   function Is_Object_Or_Value(V : View) return Boolean is abstract;

   function Is_Subtype(V : View) return Boolean is abstract;

   function Is_Package(V : View) return Boolean is abstract;

   type Conventions is (
     Intrinsic_Convention, Ada_Convention,
     Protected_Convention, Entry_Convention,
     Other_Convention, Unspecified_Convention);

   function Convention(V : View) return Conventions is abstract;

   function Convention_Identifier(V : View) return Asis.Identifier is abstract;

   package Declarative_Regions is

       type Declarative_Region is private;

       type Region_Part is private;

       type Region_Part_Array is array(Positive range <>) of Region_Part;

       type Region_Part_Kinds is (Generic_Formal_Part, Callable_Formal_Part,
           Discriminant_Part, Entry_Family_Index_Part,
           Record_Part, Extension_Part,
           Package_Visible_Part, Package_Private_Part,
           Task_Visible_Part, Task_Private_Part,
           Protected_Visible_Part,
           Protected_Private_Part,
           Body_Part, Block_Declarative_Part,
           Loop_Declarative_Part, Child_Part);

       function Kind(P : Region_Part) return Region_Part_Kinds;

       function Declarations(P : Region_Part) return Asis.Declarative_Item_List;
         --?? Should this be a vector of (declared) views?

       function All_Region_Parts(R : Declarative_Region)
         return Region_Part_Array;

       function Visible_Region_Parts(R : Declarative_Region)
         return Region_Part_Array;

       function Private_Part(R : Declarative_Region)
         return Region_Part;

       function Body_Part(R : Declarative_Region)
         return Region_Part;

       function Is_Empty(P : Region_Part) return Boolean;

       function Defining_Entity(R : Declarative_Region)
         return View'Class;

       function Enclosing_Region(P : Region_Part) return Declarative_Region;

   private
       type Declarative_Region is null record;   -- TBD

       type Region_Part is null record;  -- TBD

   end Declarative_Regions;


   function Defines_Declarative_Region(V : View) return Boolean is abstract;

   function Defined_Region(V : View)
     return Declarative_Regions.Declarative_Region is abstract;

   function Equal(Left, Right : View'Class) return Boolean;

   package View_Holders is new Ada05.Containers.Holders(View'Class);
   type View_Holder is new View_Holders.Holder with null record;

   package View_Vectors is new
     Ada05.Containers.Indefinite_Vectors(Positive, View'Class, Equal);
   type View_Vector is new View_Vectors.Vector with null record;

end Asis.Views;


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

with Asis.Views;  use Asis.Views;
with Ada05.Containers.Indefinite_Vectors;
  pragma Elaborate_All(Ada05.Containers.Indefinite_Vectors);
package Asis.Declared_Views is

   type Declared_View is abstract new View with null record;

   function View_Declaration(V : Declared_View)
     return Asis.Declaration is abstract;

   function View_Identifier(V : Declared_View)
     return Asis.Identifier is abstract;

   function Is_Overloadable(V : Declared_View)
     return Boolean is abstract;

   function Is_Overriding(V : Declared_View)
     return Boolean is abstract;

       function Overridden_Entity(V : Declared_View)
         return Declared_View'Class is abstract;

   function Representation_Items(V : Declared_View)
     return Asis.Representation_Clause_List is abstract;

   use Views.Declarative_Regions;

   function Enclosing_Region(V : Declared_View)
     return Declarative_Region is abstract;

   function Enclosing_Region_Part(V : Declared_View)
     return Region_Part is abstract;

   function Expanded_Name(V : Declared_View) return String is abstract;
   function Wide_Expanded_Name(V : Declared_View)
     return Wide_String is abstract;
   -- function Wide_Wide_Expanded_Name(V : Declared_View)
     -- return Wide_Wide_String is abstract;

   type Logical_Position is new Natural;

   function Logical_Position_In_Region(V : Declared_View)
     return Logical_Position is abstract;

   function Enclosing_Compilation_Unit(V : Declared_View)
     return Asis.Compilation_Unit is abstract;

   function Is_Renaming(V : Declared_View) return Boolean is abstract;

       function Renamed_View(V : Declared_View) return View'Class is abstract;



   function Is_Program_Unit(V : Declared_View) return Boolean is abstract;

   type Program_Unit is abstract new Declared_View with null record;

   type Program_Unit_Vector; -- Ada05: is tagged;

   function Needs_Body(P : Program_Unit) return Boolean is abstract;

   function Has_Body(P : Program_Unit) return Boolean is abstract;

       function Body_Of_Program_Unit(P : Program_Unit)
         return Asis.Declaration is abstract;

   function Has_Stub(P : Program_Unit) return Boolean is abstract;

       function Stub_Of_Program_Unit(P : Program_Unit)
         return Asis.Declaration is abstract;

   function Is_Instance(P : Program_Unit) return Boolean is abstract;

       function Instantiated_Generic(P : Program_Unit)
         return Program_Unit'Class is abstract;

       function Actual_Part(P : Program_Unit)
         return Asis.Association_List is abstract;

   function Is_Compilation_Unit(P : Program_Unit)
     return Boolean is abstract;

   procedure Depends_Semantically_On(
     P : Program_Unit; Depends_On : access Program_Unit_Vector'Class);
       -- Ada05: use "out" mode


   function Is_Library_Item(P : Program_Unit) return Boolean is abstract;

   type Library_Item is abstract new Program_Unit with null record;

   function Has_Parent_Library_Unit(L : Library_Item)
     return Boolean is abstract;

   function Parent_Library_Unit(L : Library_Item)
     return Library_Item'Class is abstract;

   function Is_Pure(L : Library_Item) return Boolean is abstract;

   function Is_Preelaborated(L : Library_Item) return Boolean is abstract;

   function Is_Remote_Call_Interface(L : Library_Item)
     return Boolean is abstract;

   function Is_Remote_Types_Package(L : Library_Item)
     return Boolean is abstract;

   function Equal(Left, Right : Program_Unit'Class) return Boolean;

   package Program_Unit_Vectors is new
     Ada05.Containers.Indefinite_Vectors(Positive, Program_Unit'Class, Equal);
   type Program_Unit_Vector is new Program_Unit_Vectors.Vector with null record;


end Asis.Declared_Views;

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

with Asis.Views; use Asis.Views;
with Asis.Declared_Views; use Asis.Declared_Views;
with Ada05.Containers.Holders;
  pragma Elaborate_All(Ada05.Containers.Holders);
with Ada05.Containers.Indefinite_Vectors;
  pragma Elaborate_All(Ada05.Containers.Indefinite_Vectors);
package Asis.Subtype_Views is

   type Subtype_View is abstract new View with null record;

   function Is_Elementary(S : Subtype_View) return Boolean is abstract;
   function Is_Composite(S : Subtype_View) return Boolean is abstract;
   function Is_Scalar(S : Subtype_View) return Boolean is abstract;
   function Is_Enumeration(S : Subtype_View) return Boolean is abstract;
   function Is_Numeric(S : Subtype_View) return Boolean is abstract;
   function Is_Discrete(S : Subtype_View) return Boolean is abstract;
   function Is_Integer(S : Subtype_View) return Boolean is abstract;
   function Is_Real(S : Subtype_View) return Boolean is abstract;
   function Is_Fixed_Point(S : Subtype_View) return Boolean is abstract;
   function Is_Floating_Point(S : Subtype_View) return Boolean is abstract;
   function Is_Access(S : Subtype_View) return Boolean is abstract;
   function Is_Access_To_Object(A : Subtype_View) return Boolean is abstract;
   function Is_Access_To_Subprogram(A : Subtype_View)
     return Boolean is abstract;


   function Is_Record(C : Subtype_View) return Boolean is abstract;
   function Is_Record_Extension(C : Subtype_View) return Boolean is abstract;
   function Is_Array(C : Subtype_View) return Boolean is abstract;
   function Is_Protected(C : Subtype_View) return Boolean is abstract;
   function Is_Task(C : Subtype_View) return Boolean is abstract;
   function Is_Tagged(C : Subtype_View) return Boolean is abstract;

   function Are_Of_Same_Type(Left, Right : Subtype_View)
     return Boolean is abstract;

   function Is_First_Subtype(S : Subtype_View) return Boolean is abstract;

   function Is_Secondary_Subtype(S : Subtype_View) return Boolean is abstract;

   function Preconstraint_Subtype(S : Subtype_View)
     return Subtype_View'Class is abstract;

   function Constraint(S : Subtype_View)
     return Asis.Constraint is abstract;

   function First_Subtype(S : Subtype_View)
     return Subtype_View'Class is abstract;

   function Primitive_Subprograms(S : Subtype_View)
     return Asis.Declarative_Item_List is abstract;
       --?? should this be a vector of Declared_Views or Callable_Views

   function Is_Formal_Subtype(S : Subtype_View) return Boolean is abstract;

   function Is_Descended_From_Formal_Subtype(S : Subtype_View)
     return Boolean is abstract;

   type Aspect_Kinds is (
     A_Size_Aspect, An_Alignment_Aspect, An_Address_Aspect,
     A_Position_Aspect); -- ...

   function Is_Aspect_Specified(Aspect : Aspect_Kinds)
     return Boolean is abstract;

   function Is_Aspect_Directly_Specified(Aspect : Aspect_Kinds)
     return Boolean is abstract;

   function Is_Static_Subtype(S : Subtype_View) return Boolean is abstract;

   function Is_Constrained(S : Subtype_View) return Boolean is abstract;

   function Is_Statically_Constrained(S : Subtype_View)
     return Boolean is abstract;

   function Are_Statically_Matching(S1, S2 : Subtype_View)
     return Boolean is abstract;

   function Is_Statically_Compatible(S : Subtype_View;
     With_Subtype : Subtype_View) return Boolean is abstract;

   function Is_Definite(S : Subtype_View) return Boolean is abstract;

   function Is_Derived_Subtype(S : Subtype_View) return Boolean is abstract;

   function Parent_Subtype(S : Subtype_View)
     return Subtype_View'Class is abstract;

   function Ultimate_Ancestor(S : Subtype_View)
     return Subtype_View'Class is abstract;

   function Is_Descendant(S : Subtype_View; Of_Subtype : Subtype_View)
     return Boolean is abstract;

   function Is_Incomplete_View(S : Subtype_View) return Boolean is abstract;

   function Complete_View(S : Subtype_View)
     return Subtype_View'Class is abstract;

   function Is_Partial_View(S : Subtype_View) return Boolean is abstract;

   function Full_View(S : Subtype_View) return Subtype_View'Class is abstract;

   function Subtype_Size(S : Subtype_View) return Natural is abstract;
     -- Returns equivalent to 'Size when subtype is elementary or
     -- size is specified.  Result is implementation-defined in
     -- other cases, and may be Natural'Last.

   function Subtype_Alignment(S : Subtype_View) return Natural is abstract;

   function Equal(Left, Right : Subtype_View'Class) return Boolean;

   package Subtype_Holders is new Ada05.Containers.Holders(Subtype_View'Class);
   type Subtype_Holder is new Subtype_Holders.Holder with null record;

   package Subtype_Vectors is new
     Ada05.Containers.Indefinite_Vectors(Positive, Subtype_View'Class, Equal);
   type Subtype_Vector is new Subtype_Vectors.Vector with null record;


end Asis.Subtype_Views;

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

with Asis.Views; use Asis.Views;
with Asis.Subtype_Views; use Asis.Subtype_Views;
with Ada05.Containers.Holders;
  pragma Elaborate_All(Ada05.Containers.Holders);
package Asis.Object_Views is

   -----------------------------------
   -- Object Views (Includes "pure" values)
   -----------------------------------

   type Object_View is abstract new View with null record;

   function Nominal_Subtype(O : Object_View)
     return Subtype_View'Class is abstract;

   function Is_Component(O : Object_View) return Boolean is abstract;

       function Enclosing_Object(O : Object_View)
         return Object_View is abstract;

       function Position(O : Object_View) return Natural is abstract;
         -- This returns the same as 'Position if specified.
         -- The result is implementation-defined in other cases,
         -- and may be Natural'Last.

   function Is_Constant(O : Object_View) return Boolean is abstract;

   function Is_Aliased(O : Object_View) return Boolean is abstract;

       type Static_Accessibility_Level is new Natural;

       function Static_Accessibility(O : Object_View)
         return Static_Accessibility_Level is abstract;

   function Is_Designated_Object(O : Object_View) return Boolean is abstract;

   function Is_Implicit_Dereference(O : Object_View) return Boolean is abstract;

   function Is_Implicit_Tick_Access(O : Object_View) return Boolean is abstract;

   function Is_Static_Integer(O : Object_View) return Boolean is abstract;

       function Static_Integer_Value(O : Object_View)
         return Longest_Integer is abstract;

   function Is_Static_Real(O : Object_View) return Boolean is abstract;

       function Static_Real_Value(O : Object_View)
         return Longest_Float is abstract;

   function Is_Static_String(O : Object_View) return Boolean is abstract;

       function Static_String_Value(O : Object_View) return String is abstract;

       function Static_Wide_String_Value(O : Object_View)
         return Wide_String is abstract;

       -- function Static_Wide_Wide_String_Value(O : Object_View)
         -- return Wide_Wide_String is abstract;

   function Object_Size(O : Object_View) return Natural is abstract;
     -- This returns the same as 'Size if object is elementary
     -- or its size or its subtype's size is specified.
     -- The result is implementation-defined in other cases,
     -- and may be Natural'Last.

   function Object_Alignment(O : Object_View) return Natural is abstract;

   package Object_Holders is new Ada05.Containers.Holders(Object_View'Class);
   type Object_Holder is new Object_Holders.Holder with null record;

end Asis.Object_Views;

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

with Asis.Views; use Asis.Views;
with Asis.Subtype_Views; use Asis.Subtype_Views;
package Asis.Profiles is

   --------------------------------
   -- Parameter and Result Profiles
   --------------------------------

   type Profile is private;

   function Parameters(P : Profile) return Declarative_Regions.Region_Part;

   function Is_Function(P : Profile) return Boolean;

       function Result_Subtype(P : Profile) return Subtype_View'Class;

   function Has_Family_Index(P : Profile) return Boolean;

       function Family_Index_Subtype(P : Profile) return Subtype_View'Class;

   function Convention(P : Profile) return Conventions;

   function Convention_Identifier(P : Profile) return Asis.Identifier;

private

   type Profile is null record;

end Asis.Profiles;

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

with Asis.Object_Views; use Asis.Object_Views;
with Asis.Profiles; use Asis.Profiles;
package Asis.Subtype_Views.Elementary is

   ------------------------------
   -- Elementary Subtype Views --
   ------------------------------


   type Elementary_Subtype is abstract new Subtype_View with null record;


   type Scalar_Subtype is abstract new Subtype_View with null record;

   function Base_Subtype(S : Scalar_Subtype)
     return Scalar_Subtype'Class is abstract;

   function Low_Bound(S : Scalar_Subtype) return Object_View'Class is abstract;
   function High_Bound(S : Scalar_Subtype) return Object_View'Class is abstract;

   type Discrete_Subtype is abstract new Scalar_Subtype with null record;
   --?? Operations on Discrete_Subtypes

   --?? Enumeration, Integer, Fixed, Floating -- are separate types needed?


   type Access_Subtype is abstract new Elementary_Subtype with null record;

   function Is_Anonymous_Access(A : Access_Subtype) return Boolean is abstract;

   function Is_Access_Parameter(A : Access_Subtype) return Boolean is abstract;

   function Is_Access_Result(A : Access_Subtype) return Boolean is abstract;

   function Is_Access_Discriminant(A : Access_Subtype)
     return Boolean is abstract;

   type Static_Accessibility_Level is new Natural;

   function Static_Accessibility(A : Access_Subtype)
     return Static_Accessibility_Level is abstract;

   function Excludes_Null(A : Access_Subtype) return Boolean is abstract;


   type Access_To_Object_Subtype is abstract new Access_Subtype with null record;

   function Designated_Subtype(A : Access_To_Object_Subtype)
     return Subtype_View'Class is abstract;

   function Is_Access_To_Constant(A : Access_To_Object_Subtype)
     return Boolean is abstract;

   function Is_Pool_Specific(A : Access_To_Object_Subtype)
     return Boolean is abstract;

   function Storage_Pool(A : Access_To_Object_Subtype)
     return Object_View'Class is abstract;

   function Storage_Size(A : Access_To_Object_Subtype)
     return Object_View'Class is abstract;


   type Access_To_Subprogram_Subtype is abstract new Access_Subtype with null record;

   function Designated_Profile(A : Access_To_Subprogram_Subtype)
     return Profile is abstract;

end Asis.Subtype_Views.Elementary;

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

with Asis.Subtype_Views.Elementary;
package Asis.Subtype_Views.Composite is

   -----------------------------
   -- Composite Subtype Views --
   -----------------------------


   type Composite_Subtype is abstract new Subtype_View with null record;

   function Is_Limited(C : Composite_Subtype) return Boolean is abstract;


   function Contains_Task(C : Composite_Subtype) return Boolean is abstract;

   function Needs_Finalization(C : Composite_Subtype)
     return Boolean is abstract;

   function Has_Preelaborable_Initialization(C : Composite_Subtype)
     return Boolean is abstract;

   function Has_Unknown_Discriminants(C : Composite_Subtype)
     return Boolean is abstract;

   function Has_Known_Discriminants(C : Composite_Subtype)
     return Boolean is abstract;

       function Discriminants(C : Composite_Subtype)
         return Declarative_Regions.Region_Part is abstract;

       function Discriminants_Have_Defaults(C : Composite_Subtype)
         return Boolean is abstract;

   function Has_Nondiscriminant_Components(C : Composite_Subtype)
     return Boolean is abstract;

       function Nondiscriminant_Components(C : Composite_Subtype)
         return Declarative_Regions.Region_Part_Array is abstract;
           -- NOTE: Return an array of region parts to handle
           --       case of multiple extension parts, or
           --       visible and private parts of task/protected types


   type Array_Subtype is abstract new Composite_Subtype with null record;

   function Component_Subtype(A : Array_Subtype)
     return Subtype_View'Class is abstract;

   function Num_Dimensions(A : Array_Subtype) return Positive is abstract;

   function Index_Subtype(A : Array_Subtype; Dimension : Positive := 1)
     return Elementary.Discrete_Subtype'Class is abstract;

   function Is_String_Subtype(A : Array_Subtype) return Boolean is abstract;


   type Tagged_Subtype is abstract new Composite_Subtype with null record;

   type Tagged_Subtype_Vector; -- Ada05: is tagged;

   function Is_Interface(T : Tagged_Subtype) return Boolean is abstract;
   function Is_Abstract(T : Tagged_Subtype) return Boolean is abstract;
   function Is_Synchronized_Tagged(T : Tagged_Subtype)
     return Boolean is abstract;

   function Is_Classwide(T : Tagged_Subtype) return Boolean is abstract;

       function Root_Subtype(T : Tagged_Subtype)
         return Tagged_Subtype'Class is abstract;

   function Is_Specific(T : Tagged_Subtype) return Boolean is abstract;

       function Classwide_Subtype(T : Tagged_Subtype)
         return Tagged_Subtype'Class is abstract;

   procedure Progenitors(
     T : Tagged_Subtype; Progenitors : access Tagged_Subtype_Vector'Class);
        -- Ada05: use OUT mode

   function External_Tag(T : Tagged_Subtype) return String is abstract;

   function Equal(Left, Right : Tagged_Subtype'Class) return Boolean;

   package Tagged_Subtype_Vectors is new
     Ada05.Containers.Indefinite_Vectors(Positive, Tagged_Subtype'Class, Equal);

   type Tagged_Subtype_Vector is new
     Tagged_Subtype_Vectors.Vector with null record;


end Asis.Subtype_Views.Composite;

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

with Asis.Views; use Asis.Views;
with Asis.Subtype_Views; use Asis.Subtype_Views;
with Asis.Subtype_Views.Composite;
with Asis.Profiles; use Asis.Profiles;
with Asis.Object_Views; use Asis.Object_Views;
with Ada05.Containers.Holders;
  pragma Elaborate_All(Ada05.Containers.Holders);
package Asis.Callable_Views is

   type Callable_View is abstract new View with null record;

   function Callable_Profile(C : Callable_View) return Profile is abstract;

   function Is_Subprogram(C : Callable_View) return Boolean is abstract;

   function Is_Enumeration_Literal(C : Callable_View)
     return Boolean is abstract;

   function Is_Entry(C : Callable_View) return Boolean is abstract;

   function Is_Function(C : Callable_View) return Boolean is abstract;

   function Is_Abstract(C : Callable_View) return Boolean is abstract;

   function Is_Null(C : Callable_View) return Boolean is abstract;

   function Is_Primitive(C : Callable_View) return Boolean is abstract;

       procedure Primitive_On_Subtypes(
         C : Callable_View; Subtypes : access Subtype_Vector);
           -- Ada05: use "out" mode

       function Is_Dispatching_Operation(C : Callable_View)
         return Boolean is abstract;

           function Associated_Tagged_Type(C : Callable_View)
             return Composite.Tagged_Subtype'Class is abstract;

   function Is_Prefixed_View(C : Callable_View) return Boolean is abstract;

       function Prefix_Object(C : Callable_View)
         return Object_View'Class is abstract;
       function Unprefixed_Callable_View(C : Callable_View)
         return Callable_View'Class is abstract;

   function Is_Designated_Subprogram(C : Callable_View)
     return Boolean is abstract;

   package Callable_Holders is new Ada05.Containers.Holders(Callable_View'Class);
   type Callable_Holder is new Callable_Holders.Holder with null record;

end Asis.Callable_Views;

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

with Asis.Views; use Asis.Views;
with Asis.Declared_Views; use Asis.Declared_Views;
with Ada05.Containers.Holders;
  pragma Elaborate_All(Ada05.Containers.Holders);
package Asis.Package_Views is

   type Package_View is abstract new Program_Unit with null record;

   function Is_Limited_View(P : Package_View) return Boolean is abstract;

       function Full_View(P : Package_View)
         return Package_View'Class is abstract;

   function Is_Full_View(P : Package_View) return Boolean is abstract;

       function Limited_View(P : Package_View)
         return Package_View'Class is abstract;

   function Is_Formal_Package(P : Package_View) return Boolean is abstract;

   function Visible_Part(P : Package_View)
     return Declarative_Regions.Region_Part is abstract;

   package Package_Holders is new Ada05.Containers.Holders(Package_View'Class);
   type Package_Holder is new Package_Holders.Holder with null record;

end Asis.Package_Views;

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

with Asis.Views; use Asis.Views;
with Asis.Declared_Views; use Asis.Declared_Views;
with Asis.Callable_Views;
with Asis.Package_Views;
with Ada05.Containers.Holders;
  pragma Elaborate_All(Ada05.Containers.Holders);
package Asis.Generic_Views is

   type Generic_View is abstract new Program_Unit with null record;

   function Generic_Formal_Part(G : Generic_View)
     return Declarative_Regions.Region_Part is abstract;

   function Is_Generic_Package(G : Generic_View) return Boolean is abstract;

       function Current_Package_Instance(G : Generic_View)
         return Package_Views.Package_View'Class is abstract;

   function Is_Generic_Subprogram(G : Generic_View) return Boolean is abstract;

       function Current_Subprogram_Instance(G : Generic_View)
         return Callable_Views.Callable_View'Class is abstract;

   package Generic_Holders is new Ada05.Containers.Holders(Generic_View'Class);
   type Generic_Holder is new Generic_Holders.Holder with null record;

end Asis.Generic_Views;

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

with Asis.Views; use Asis.Views;
with Asis.Declared_Views; use Asis.Declared_Views;
with Ada05.Containers.Holders;
  pragma Elaborate_All(Ada05.Containers.Holders);
package Asis.Exception_Views is

   type Exception_View is abstract new Declared_View with null record;

   function Names_Are_Discarded(E : Exception_View) return Boolean is abstract;

   package Exception_Holders is new
     Ada05.Containers.Holders(Exception_View'Class);
   type Exception_Holder is new Exception_Holders.Holder with null record;

end Asis.Exception_Views;

****************************************************************

From: Sergey I. Rubin
Sent: Friday, October 5, 2007  8:06 AM

> The concrete types that implement one or more of
> these abstract interface types would be declared privately
> by the implementation, and returned as a result of
> some call that returns an object of type X'class,
> such as Corresponding_View.

Suppose in the application we do:

Var : View'Class := Corresponding_Declared_View (Some_Declaration);
Var_Kind : View_Kinds;

and suppose we would like to query the view Kind:

Var_Kind := Kind (Var);

That means that we need the non-abstract Kind function
declared somewhere in Asis.Views hierarchy. But we do not
have it...

****************************************************************

From: Tucker Taft
Sent: Friday, October 5, 2007  9:33 AM

Even if the function Kind on View is abstract,
you can make a dispatching call on it,
with a View'Class parameter.  Give it a try.
GNAT shouldn't complain.

****************************************************************

From: Sergey I. Rubin
Sent: Friday, October 5, 2007  9:55 AM

Yes, I've missed this possibility (have not got enough
experience in Ada object-oriented programming :( :)

But this means that an application will have
in all the situations define only class-wide
variables and use dispatching calls.

I'm afraid to think about application debugging...

****************************************************************

From: Tucker Taft
Sent: Friday, October 5, 2007  12:33 PM

We'll be in good company.  In Java almost
every call is the equivalent of a "dispatching"
call, and in C++ a high proportion are as well.
I'm sure "gdb" is up to the task (or will be ;-).

****************************************************************

From: Tucker Taft
Sent: Friday, October 5, 2007  12:40 PM

I have attached an Ada95-compilable version
of the ASIS semantic model.  [This is version /07 of the SI - ED.]
I have also restructured it a bit, where now I have
something called a "View_Declaration" which
replaces "Declared_View."  Certain views
have view declarations.  View_Declaration is
the root of a separate hierarchy of types, including
Program_Unit and Library_Item.

This eliminates the need for multiple inheritance,
and I believe will make it somewhat easier to
understand.  A "view" is the more "abstract" thing,
while a "view declaration" is the more concrete
construct that defines the view.  Certain kinds
of views always have (implicit or explicit)
declarations -- package, generic, and exception views --
whereas others don't necessarily have declarations --
object, callable, and subtype views.

Another way of putting it is that some views always
have an associated identifier, while others don't
(i.e. are anonymous).

Feedback is encouraged.

****************************************************************

From: Jean-Pierre Rosen
Sent: Monday, October 15, 2007  9:24 AM

Small stuff...

In type View_Kinds, A_Limited_Package_View is the only literal that
includes "_View". Should be all or none...

Similarly, in Asis.Program_Units, we have "is_pure",
"is_remote_call_interface", etc, but "is_remote_types_PACKAGE".

****************************************************************

From: Tucker Taft
Sent: Monday, October 15, 2007  1:28 PM

Those "inconsistencies" were actually intentional.
I used "_View" in "A_Limited_Package_View" because
we never refer to simply a "limited package" in the
reference manual.  For the second one, it sounds strange
grammatically to have "Is_Remote_Types."  Also, pragma
Pure can usefully be applied to a subprogram, whereas
pragma Remote_Types really only makes sense applied to a
(generic) package.

****************************************************************

From: Tucker Taft
Sent: Monday, October 15, 2007  2:02 PM

Perhaps they should all be changed to a form like
"Is_Pure_Unit," "Is_Remote_Call_Interface_Unit,"
"Is_Remote_Types_Unit," etc.  That would address
both the grammatical and consistency concerns.

****************************************************************

From: Tucker Taft
Sent: Monday, February 4, 2008  3:22 PM

Here is a small update to SI-24.  I didn't have time
to write a significant amount of new wording.  I
wrote an Intro and that is about it.  I also made
the other fixes identified in the minutes. [This is version /05 of the SI - ED]

****************************************************************

From: Randy Brukardt
Sent: Monday, February 4, 2008  11:59 PM

The ASIS standard (see the last sentence of 1.3) says that the package Asis is
always spelled in upper and lower case. (Because some programming environments
can't handle identifiers in a special case??) I've made that change to this SI.

****************************************************************

From: Randy Brukardt
Sent: Tuesday, February 19, 2008  6:33 PM

While working on the minutes of the recent meeting, I noticed what might be
a small problem. Tucker has said that "Corresponding_View" for an expression
would be a callable view (the function) for an operator expression. For
instance, in
    V + 4
the callable view returned would be "+".

But there seems to be expressions for which this doesn't work. The (not yet
existing) definition of Corresponding_View needs to be careful to explain
what happens for such expressions.

One obvious such expression is a numeric literal:
    4
What is the callable view for "4"? Doesn't seem to make sense. I suppose
there could be a literal view to hande this.

But we also have expressions that are operations, not operators:
    B and then C
    Obj in T'Class
Again, the top-level thing is an expression, but there is no callable view
for "and then" or "in". Not sure what these ought to be.

****************************************************************

From: Tucker Taft
Sent: Tuesday, February 19, 2008  7:47 PM

I think you misunderstood me during the meeting.
I never meant to say imply that the "Corresponding_View"
for "V+4" would be a "Callable_View."  It would
be an Object_View.  The properties of this
Object_View would be that it is a constant anonymous
object that is the result of invoking "+"(V, 4).
It would have the appropriate type, not be
aliased, etc.

A literal would be similar.  It would represent
an anonymous object with a static value and an
appropriate type (as determined by overload
resolution, though one could argue whether it's
type should be universal_integer or the specific
type to which it is being implicitly converted).

The view associated with any expression, including
short-circuit operations, can be thought of as
an anonymous object with an appropriate type, etc.

****************************************************************

From: Sergey I. Rybin
Sent: Wednesday, February 20, 2008  4:18 AM

I've got exactly this understanding from the discussion
we've had at the meeting. Of course, it may (and for
sure it will) be some problems with the detailed design,
but the general design idea looks well-defined now.

****************************************************************

From: Randy Brukardt
Sent: Wednesday, February 20, 2008  2:26 PM

> I think you misunderstood me during the meeting.
> I never meant to say imply that the "Corresponding_View"
> for "V+4" would be a "Callable_View."  It would
> be an Object_View.  The properties of this
> Object_View would be that it is a constant anonymous
> object that is the result of invoking "+"(V, 4).
> It would have the appropriate type, not be
> aliased, etc.

Possibly, but that is what I wrote down, and I'm certain that you never said
anything about an "object_view" the whole time. (This is the first time I
even recall hearing the term.) Obviously, the minutes are not going to
reflect this new (to me at least) model.

In any case, having this model in your head (and not on paper!) makes it
completely impossible to reason about it (or progress it!). Can I appeal to
you to do some work on writing this up so that we can seriously think about
it??

****************************************************************

From: Tucker Taft
Sent: Wednesday, February 20, 2008  2:33 PM

I hear you.

****************************************************************

From: Greg Gicca
Sent: Wednesday, February 20, 2008  2:45 PM

This is one of those cases that requires a more open mind.  Here Tucker
needed a more open mind to better read it by the group.  :)

****************************************************************

From: Randy Brukardt
Sent: Sunday, June 15, 2008  1:54 AM

> Here is an update to SI-24, the ASIS Semantic Subsystem.  I did a lot
> of the hard parts (in my view), and would really like some help
> finishing it at this point, as well as some review of what has been
> done so far. [This is version /09 of the SI - ED.]

Here's a few things I noticed when scanning over this version.

(1) I really like XXX_Error. I think that's what happens when children try to get
into a peep show. ;-) I suspect that a better name and a declaration are needed.

(2) In XX.X.3.2, functions First_Subtype, Is_Base_Subtype, and Base_Subtype are
not described. Just when I was wondering precisely what Base_Subtype meant...

(3) In xx.x.3.4, "Progenitors" is mentioned in the description of Ultimate_Ancestor,
but it is not included or described in this subsubclause (or any other for that matter).
It's after Parent_Subtype in the full spec, so I suspect it is supposed to be here.

(4) In xx.x.3.5, is there an easy way to create the needed Asis.Identifier(s) to
query aspects? They may not be readily available in the program text. If not, a
set should be declared somewhere for this use.

I fixed a number of minor typos that I saw, so the version to be posted isn't quite
identical to what you sent. (But I didn't do anything with any of the above.)

****************************************************************

From: Bill Thomas
Sent: Monday, February 17, 2009  10:53 AM

I'm trying to develop examples illustrating use of the semantic subsystem and
saw a few issues with the spec when I compile:

- A circular dependency between Asis.Callable_Views and Asis.Object_Views

- Corresponding_View_Declaration should return
  Asis.Views.Declarative_Regions.View_Declaration'Class

- Interface subprograms must be abstract: (function Defined_View, and
  procedures Overridden_Declarations, Primitive_On_Subtypes,
  Depends_Semantically_On, and Progenitors)

- type Scalar_Subtype should be interface and Elementary_Subtype; (not
  Elementary_View)

****************************************************************

From: Randy Brukardt
Sent: Monday, February 17, 2009  7:43 PM

> I'm trying to develop examples illustrating use of the semantic 
> subsystem and saw a few issues with the spec when I compile:

Thanks Bill. I've fixed the obvious ones in the SI draft; it will get
posted later tonight with everything else.

> - A circular dependency between Asis.Callable_Views and 
> Asis.Object_Views

Humm.

Asis.Callable_Views includes function Prefix_Object (C : Callable_View)
return Object_View'Class; (this is for prefixed views)

and

Asis.Object_Views includes function Designated_Subprogram (O : Object_View)
return Callable_View'Class; (this is for access-to-subprogram objects)

As Bill notes, this doesn't work. I don't see an obvious solution to this
problem. We need to introduce a limited view or another package somewhere,
and this is not easy (we don't allow returning objects of incomplete views
for various reasons, so we can't just drop in a limited with).

Probably the best idea I have would to be add a new child package and type:

package Asis.Object_Views.Access_Views is -- I'd use "access" here, as with
                                          -- the subtypes, but that's reserved.

type Access_Object_Views is new Object_Views and interface;

and then move all of the dereference stuff in xx.4.3 (everything below
Is_Dereference) here. Then the with of Callable_Views can be moved here, and
voila! No more circularity.

But I'll leave this for the meeting; perhaps someone else has a better idea.

> - Corresponding_View_Declaration should return 
> Asis.Views.Declarative_Regions.View_Declaration'Class

OK.

> - Interface subprograms must be abstract: (function Defined_View, and 
> procedures Overridden_Declarations, Primitive_On_Subtypes, 
> Depends_Semantically_On, and Progenitors)

OK. Note that there was an extra declaration of Progenitors in the package
specs provided under "discussion" (for Subtype_View). If you started with
those specs, you ought to delete that.

> - type Scalar_Subtype should be interface and Elementary_Subtype; (not 
> Elementary_View)

Right. I'm a little surprised that the suffix "_View" isn't used on these
(I obviously assumed that so strongly that I never even looked 5 lines
about this declaration to check...) [This declaration was changed by me when
I noticed that it should be derived from Elementary_Subtype rather than
Subtype_View, see the SI for an explanation. Or not, as we'll likely look
at every such correction I inserted in detail at the meeting.]

****************************************************************

From: Tucker Taft
Sent: Monday, February 17, 2009  8:07 PM

An alternative way to break circularity
is to simply return View'Class or some other ancestor'Class, and then
indicate in a comment that the result will in fact be in Callable_View'Class.

****************************************************************

From: Randy Brukardt
Sent: Monday, February 17, 2009  8:18 PM

True enough, but of course that breaks some of the type safety that we were
trying to get with this hierarchy (rather than calling everything "Element"!).

I was noticing that at least half of the object operations are solely about
dereferencing of access objects. [I had to move some of these operations here,
or create them, because they were missing or in the wrong place. That's probably
how the circularity came about.] Since dereferencing of Integers and Strings
don't make sense, it could make sense to split that part into a separate package
that only applies to access values. Then we could get rid of the circularity
without having to sacrifice type safety.

Worth discussing, anyway.

****************************************************************

Questions? Ask the ACAA Technical Agent