!standard 3.9 08-06-13 SI99-0024-1/09 !class amendment 06-11-12 !status work item 06-11-12 !status received 06-11-12 !priority High !difficulty Hard !subject Provide a semantic model 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. 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 propose to include in our ASIS semantic model: - Program_Unit_View - Package_View - Subprogram_View - Task_Unit - Protected_Unit - Generic_View - Single_Entry - Entry_Family - Subtype_View - Object_View - Callable_View - Exception In addition, we propose to define certain other abstractions that allow us to characterize or manipulate the above entities or views: - Direct_Visibility_View - Declarative_Region_View - Region_Part - Profile We use the term view only when there 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). On the other hand, 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. 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." Because we are proposing a relatively large set of interfaces, we are not currently proposing wording, but rather are working to specify the queries to be provided using a more economical syntax than full Ada package specifications. Once we agree on the set of interfaces to be provided, we will then create actual Ada packages with corresponding detailed descriptions for each operation. DETAILED SEMANTIC MODEL In this section, we define the operations that can be performed on the various kinds of entities and views. The operations available are listed underneath each kind of entity/view. The operations are defined in a notation such as: Subtype_View: ... Is_Derived -> Boolean Parent_Subtype -> Subtype_View Is_Descendant(Subtype_View) -> Boolean The above means that the operation Is_Derived is defined on Subtype_Views and (implicitly) takes one parameter being a Subtype_View, and returns a Boolean result. The indented Parent_Subtype operation is defined only if the Is_Derived operations returns True, and it returns a Subtype_View as a result. Finally, the "Is_Descendant" operation is defined on Subtype_Views, and in addition to the (implicit) first parameter being Subtype_View, this takes an additional parameter (also a Subtype_View in this case), and returns a Boolean result. Hopefully this notation will be sufficiently clear to allow the set of operations to be understood and relatively easily updated, without worrying about continually revising a lot of Ada subprogram specifications. As indicated above, once we settle on the desired interfaces, we can write out the package specifications in full detail. Semantic Attributes: Entity_Or_View Kind_Of_Entity -> enum Expr_Denoting_Entity -> Asis.Expression Has_Declaration -> Boolean Entity_Declaration -> Asis.Declaration Entity_Identifier -> Asis.Identifier Is_Overloadable -> Boolean Enclosing_Scope -> Declarative_Region Logical_Position_In_Region -> Natural Enclosing_Compilation_Unit -> Asis.Compilation_Unit Is_Renaming -> Boolean Renamed_Entity -> Entity Is_Program_Unit -> Boolean Has_Body -> Boolean Entity_Body -> Asis.Declaration Has_Stub -> Boolean Entity_Stub -> Asis.Declaration Is_Compilation_Unit -> Boolean Is_Library_Unit -> Boolean Parent_Library_Unit -> Entity Representation_Items -> List of Representation_Items Contains_Declarative_Region -> Boolean Contained_Region -> Declarative_Region Region_Part Kind_Of_Region_Part -> enum (Generic_Formal_Part, 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) Enclosing_Region -> Declarative_Region Declarations -> List of Entitities Lookup(Identifier) -> List of Entity_Or_View Declarative_Region -> Enclosing_Entity -> Entity Has_Generic_Formal_Part -> Boolean Generic_Formal_Part -> Region_Part Visible_Parts -> List of Region_Parts Private_Part -> Region_Part (may be empty) Body_Part -> Region_Part (may be empty) Declarative_Region_View -> Region -> Declarative_Region Visible_Position_In_Region -> Natural Introduced_Position_In_Region -> Natural Visible_Children -> Set of Declarative_Region_Views Lookup(Identifier) -> Entity_Or_View Direct_Visibility_View -> Visibility_Stack -> List of Declarative_Region_Views Use_Visibility -> Set of Package_Views + Set of Subtype_Views Subprogram_View Subprogram_Profile -> Profile Is_Instance -> Boolean Instantiated_Generic -> Generic_Subprogram Actual_Part -> List of Associations Is_Abstract -> Boolean Is_Overriding -> Boolean Overrides -> Set of Subprograms Is_Null -> Boolean Is_Primitive -> Boolean Primitive_On_Types -> Set of Subtypes Is_Dispatching_Operation -> Boolean Associated_Tagged_Type -> Subtype_View Package_View Is_Limited_View -> Boolean Full_View -> Package View Is_Instance -> Boolean Instantiated_Generic -> Generic_Package Actual_Part -> List of Associations Is_Formal_Package -> Boolean Is_Pure -> Boolean Is_Preelaborated -> Boolean Is_Remote_Call_Interface -> Boolean Is_Remote_Types_Package -> Boolean Generic Entity Formal_Part -> Region_Part Current_Instance -> Entity Subtype_View Category -> {boolean, character, ordinary_enum, signed int, modular int, ordinary fixed, decimal fixed, float, access-to-obj, access-to-subp, record, record extension, array, task, protected, interface, private, private extension} Are_Of_Same_Type(Subtype_View) -> Boolean Is_First_Subtype -> Boolean Is_Secondary_Subtype -> Boolean Preconstraint_Subtype -> Subtype_View Constraint -> Asis.Constraint First_Subtype -> Subtype_View Primitive_Subprograms -> List of Subprograms Is_Formal_Type -> Boolean Is_Aspect_Specified(Aspect) -> Boolean Is_Aspect_Directly_Specified(Aspect) -> Boolean Is_Constrained -> Boolean Constraint -> Asis.Constraint Is_Definite -> Boolean Is_Derived -> Boolean Parent_Subtype -> Subtype_View Ultimate_Ancestor -> Subtype_View Is_Descendant(Subtype_View) -> Boolean Is_Ancestor(Subtype_View) -> Boolean Is_Incomplete_View -> Boolean Complete_View -> Subtype_View Is_Partial_View -> Boolean Full_View -> Subtype_View Is_Elementary -> Boolean Is_Universal -> Boolean Is_Scalar -> Boolean Base_Subtype -> Subtype_View Low_Bound,High_Bound -> Expression/Value/? Is_Discrete -> Boolean Is_Access -> Boolean Is_Anonymous_Access -> Boolean Is_Access_Parameter_Subtype -> Boolean Is_Access_Result_Subtype -> Boolean Static_Accessibility -> Natural Excludes_Null -> Boolean Is_Access_To_Object -> Boolean Designated_Subtype -> Subtype_View Is_Access_To_Constant -> Boolean Is_Pool_Specific -> Boolean Is_Access_To_Subprogram -> Boolean Designated_Profile -> Profile Is_Composite -> Boolean Is_Record -> Boolean Is_Array -> Boolean Is_Protected -> Boolean Is_Task -> Boolean Is_Tagged -> Boolean Is_Classwide -> Boolean Root_Subtype -> Subtype_View Is_Specific_Tagged -> Boolean Classwide_Subtype -> Subtype_View Is_Synchronized_Tagged -> Boolean Is_Interface -> Boolean Is_Abstract -> Boolean Progenitors -> List of Subtype_Views Has_Known_Discriminants -> Boolean Discriminants -> Region_Part Has_Unknown_Discriminants -> Boolean Has_Nondiscriminant_Components -> Boolean Nondiscriminant_Components -> Region_Part Is_Limited -> Boolean Has_Preelaborable_Initialization -> Boolean Needs_Finalization -> Boolean Contains_Task -> Boolean Object_View Nominal_Subtype -> Subtype_View Is_Component -> Boolean Enclosing_Object -> Object_View Is_Constant_View -> Boolean Is_Aliased_View -> Boolean Static_Accessibility -> Natural Callable_View Callable_Profile -> Profile Denoted_Callable_Unit -> Callable_Unit Is_Prefixed_View -> Boolean Prefix_Object -> Object_View Unprefixed_Callable_View -> Callable_View Profile Parameters -> Region_Part Has_Result_Subtype -> Boolean Result_Subtype -> Subtype_View Has_Family_Index -> Boolean Family_Index_Definition -> Subtype_View Convention -> enum (Intrinsic_Convention, Ada_Convention, Protected_Convention, Entry_Convention, Other_Convention, Unspecified_Convention) Convention_Identifier -> Asis.Identifier ----------------------- Additional thoughts 11/15/06: Additional operations: Are_Views_Of_Same_Entity(Other_View) -> Boolean Syntax -> Semantic linkages Need some way to get direct-visibility-view from a point in the AST Every declaration/name/expression needs linkage to entity/view Unlike the AST, the objects representing views might not exist until requested. They are more like handles into the symbol table. Prefixed views are a problem, since they are always implicit. Build this incrementally based on needs, e.g. for dispatching calls, for prefixed views, for inherited operations. Is_Implicit_Dereference, Is_Implicit_Tick_Access Corresponding_Representation_Clauses (Aspects, Representation_Items) should be associated with individaul entities, since two entities with the same syntactic declaration can have different representation. Drop the region view lookup stuff Keep the region part stuff Keep the ordering No child part Slice? (enclosing) Is_Value(object-view) Is_Object(object-view) Links from existing ASIS expression -> object view name -> entity_or_view require ASIS expressions under certain circumstances such as for defaults, parameter specifications, formal parameters make it clear what is not provided for implicit expressions, etc. ------------------------------------------- PACKAGE SPECIFICATION In deciding how to represent the above 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. !wording XX.X ASIS Semantic Subsystem XX.X.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. ----------------------------------------------------- XX.X.1 Package Asis.Views The library package Asis.Views shall exist. The package shall provide interfaces equivalent to those described in the following subclauses. ----------------------------------------------------- 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 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 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 Asis.Identifier is abstract; package Declarative_Regions is type Declarative_Region is private; type View_Declaration is abstract tagged null record; type View_Declaration_Vector is tagged; 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 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_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 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; 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); function Representation_Items(D : View_Declaration) return Asis.Representation_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 String is abstract; function Wide_Expanded_Name(D : View_Declaration) return Wide_String is abstract; function Wide_Wide_Expanded_Name(D : View_Declaration) return Wide_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; function Equal(Left, Right : View_Declaration'Class) return Boolean; package View_Declaration_Vectors is new Ada.Containers.Indefinite_Vectors( Positive, View_Declaration'Class, Equal); 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; package View_Holders is new Ada.Containers.Holders(View'Class); type View_Holder is new View_Holders.Holder with null record; function Equal(Left, Right : View'Class) return Boolean; package View_Vectors is new Ada.Containers.Indefinite_Vectors(Positive, View'Class, Equal); type View_Vector is new View_Vectors.Vector with null record; end Asis.Views; XX.X.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 abstract tagged null record; 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; 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. The View_Kind of an object 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 a given object belongs. [QUESTION: Now that we are using a tagged type hierarchy, these boolean queries are redundant with membership tests such as "V in Callable_View'Class" -- should we eliminate these query functions?] XX.X.1.2 Function Expr_Denoting_View function Expr_Denoting_View(V : View) return Asis.Expression is abstract; Returns an Asis.Expression or Asis.Name that denotes the given View. This is one of the primary mechanisms for navigating from the Semantic Subsystem to the other parts of ASIS. XX.X.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 Asis.Identifier is abstract; Each program entity can have an associated convention. The convention of the entity identified by a view 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 identifier given in the pragma Convention, Import, or Export used to specify the convention of the entity. XX.X.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. XX.X.1.5 Type Declarative_Region and type View_Declaration type Declarative_Region is private; type View_Declaration is abstract tagged null record; function Defined_View(D : View_Declaration) return View'Class; 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; 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; A View_Declaration represents the declaration, if any, that defines a given view. A Declarative_Region represents a declarative region in which declarations may occur. Function Defined_View returns the View defined by a given declaration. If a given 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 given declaration. Function View_Identifier returns the Asis.Identifier introduced by the given declaration. Function Is_Imported returns True if and only if the declaration is completed with a pragma Import. Function Enclosing_Region returns the Declarative_Region enclosing the given declaration. Function Are_Declarared_In_Same_Region(A, B) returns True if and only if Enclosing_Region(A) and Enclosing_Region(B) represent the same region. Function Is_Declared_Earlier_In_Same_Region(A, B) if and only if Are_Declared_In_Same_Region(A, B) is True and A occurs before B in the logical sequence of the program, where a package specification is presumed to occur before the corresponding package body in this sequence. XX.X.1.6 Type Region_Part and type Region_Part_Kinds 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 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_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 Enclosing_Region_Part(D : View_Declaration) return Region_Part is abstract; 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 returns the kind of the given Region_Part. Function Is_Empty returns True if and only if the given region part has no declarative items within it. Function Declarative_Items returns the list of Asis.Declarative_Item's that occur within the given region part. Procedure Declarations returns in the parameter Declarations a vector comprising the declarations that occur within the given region part. Function Region returns the Declarative_Region of which the given Region_Part is a part. Function All_Region_Parts returns an array of the region parts comprising the given declarative region. Function Visible_Region_Parts returns an array of the visible parts of the given declarative region. Function Private_Part returns the private part of the given declarative region. Private_Part returns an empty Region_Part if there is no private part, or if the private part is empty. Function Body_Part returns the body part of the given declarative region. Body_Part returns an empty Region_Part if there is no body part, or if the body part 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 returns the Region_Part in which the given declaration occurs. XX.X.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; function Enclosing_Compilation_Unit(D : View_Declaration) return Asis.Compilation_Unit is abstract; function Expanded_Name(D : View_Declaration) return String is abstract; function Wide_Expanded_Name(D : View_Declaration) return Wide_String is abstract; function Wide_Wide_Expanded_Name(D : View_Declaration) return Wide_Wide_String is abstract; Declarative regions are generally associated with language constructs, and may be nested. Function Defining_Construct returns the Asis.Element with which the given declarative region is associated. Function Has_Defining_Declaration returns True if and only if the given Declarative_Region is associated with an enclosing declaration. Function Defining_Declaration returns the declaration that defines the given region. Defining_Declaration raises XXX_Error if Has_Defining_Declaration(R) returns False. Function Has_Enclosing_Region returns True if and only the given region has an enclosing region. Function Enclosing_Region returns that region, or raises XXX_Error if Has_Enclosing_Region(R) returns False. Function Enclosing_Compilation_Unit returns the Asis.Compilation_Unit representing the compilation unit in which the given declaration occurs. Function Wide_Wide_Expanded_Name returns the Wide_Wide_String representing the full expanded name denoting the given declaration. Functions Expanded_Name and Wide_Expanded_Name return the corresponding String or Wide_String, with any characters of the expanded name that are not representable replaced by an implementation-defined sequence of characters. XX.X.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); 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; Declarations may overload, override, or rename other declarations. Function Is_Overloadable returns True if and only if the declaration is one that may be overloaded. Function Is_Overriding returns True if and only if the declaration overrides one or more other declarations. Procedure Overridden_Declarations returns (in the Overridden parameter) a vector of those declarations overridden by the given declaration. Overridden will be an empty vector if the given declaration does not override any other declaration. Function Is_Renaming returns True if and only if the given declaration is a renaming of another view. Function Renamed_View returns that view, or raises XXX_Error if Is_Renaming returns False. Function Is_Renaming_As_Body returns True if and only if the given declaration is a renaming-as-body. XX.X.1.8 Representation Items function Representation_Items(D : View_Declaration) return Asis.Representation_Clause_List is abstract; Function Representation_Items returns a list of representation clauses that apply to the given declaration. XX.X.1.9 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; Function Has_Declaration returns True if and only if the given view was defined by a declaration. Function Declaration returns that view, or raises XXX_Error if Has_Declaration returns False. Function Defines_Declarative_Region returns True if and only if the given view is of an entity that has its own declarative region. Function Defined_Region returns that region, or raises XXX_Error if Defines_Declarative_Region returns False. --------------------------------------------------------------- XX.X.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. 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 abstract new View_Declaration with null record; type Program_Unit_Vector is tagged; 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 Is_Compilation_Unit(P : Program_Unit) return Boolean is abstract; procedure Depends_Semantically_On( P : Program_Unit; Depends_On : out Program_Unit_Vector'Class); 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_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; function Equal(Left, Right : Program_Unit'Class) return Boolean; package Program_Unit_Vectors is new Ada.Containers.Indefinite_Vectors(Positive, Program_Unit'Class, Equal); type Program_Unit_Vector is new Program_Unit_Vectors.Vector with null record; end Asis.Program_Units; XX.2.1 Type Program_Unit type Program_Unit is abstract new View_Declaration with null record; 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; 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 returns True if and only if the given program unit requires a completion. Function Has_Body returns True if the given program unit has a completion that is a body. Function Body_Of_Program_Unit returns the body, or raises XXX_Error if Has_Body returns False. Function Is_Instance returns True if and only if the given program unit is an instance of a generic unit. Function Instantiated_Generic returns the generic unit given the instance, or raises XXX_Error if Is_Instance returns False. Function Actual_Part returns the list of actual parameters passed to the instantiation, or raises XXX_Error if Is_Instance returns False. XX.X.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); 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; Function Is_Compilation_Unit returns True if and only if the given program unit 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 this compilation unit depends semantically, or raises XXX_Error if Is_Compilation_Unit returns False for the given program unit. Function Is_Subunit returns True if and only if the given program unit is separately compiled as a subunit. Function Stub_Of_Program_Unit returns the Asis.Declaration that represents the stub of the subunit, or raises XXX_Error if Is_Subunit returns False. Function Is_Library_Item returns True if and only if the given program unit is separately compiled as a library item. XX.X.2.3 Type Library_Item 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_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; 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 returns True if and only if the given library item is a child of a unit other than package Standard. Function Parent_Library_Unit returns the parent library item, or raises XXX_Error if Has_Parent_Library_Unit returns False for the given library item. Function Is_Pure_Unit returns True if and only if the given library item is declared pure. Function Is_Preelaborated_Unit returns True if and only if the given library item is preelaborated. Function Is_Remote_Call_Interface_Unit returns True if and only if the pragma Remote_Call_Interface applies to the library item. Function Is_Remote_Types_Unit returns True if and only if the pragma Remote_Types applies to the library item. --------------------------------------------------------------- XX.X.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. 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 abstract new View with null record; type Subtype_Vector is tagged; 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_Base_Subtype(S : Subtype_View) return Boolean is abstract; function Base_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; procedure Progenitors(S : Subtype_View; Progenitors : out Subtype_Vector'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 Is_Aspect_Specified(S : Subtype_View; Aspect : Asis.Identifier) return Boolean is abstract; function Is_Aspect_Directly_Specified(S : Subtype_View; Aspect : Asis.Identifier) return Boolean 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 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, Equal); type Subtype_Vector is new Subtype_Vectors.Vector with null record; end Asis.Subtype_Views; XX.X.3.1 Type Subtype_View 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_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 type Subtype_View represents a view of a subtype. The category and other characteristics of the subtype can be determined with the above functions. XX.X.3.2 Types, Subtypes, and Constraints 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_Base_Subtype(S : Subtype_View) return Boolean is abstract; function Base_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 Are_Of_Same_Type returns True if and only if Left and Right represent subtypes of the same type. Function Is_First_Subtype returns True if and only if the given subtype is the first subtype of its type. Function Is_Secondary_Subtype(S) is equivalent to not Is_First_Subtype(S). Function Has_Constraint returns True if and only if the given subtype has a constraint. Function Constraint returns the Asis element representing the constraint of the given subtype, or raises XXX_Error if Has_Constraint returns False. XX.X.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; 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_Static_Subtype returns True if and only if the given subtype is static. Function Is_Statically_Constrained returns True if and only if the given subtype is constrained and its constraint is static. Function Are_Statically_Matching returns True if and only if the given subtypes are of the same type and are statically matching. Function Is_Statically_Compatible returns True if and only if the constraint of the first subtype is statically compatible with the second subtype. XX.X.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; 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 Primitive_Subprograms returns in the parameter Primitives a vector of declarations for the primitive subprograms of the type of the given subtype. Function Is_Derived returns True if and only if the type of the given subtype 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 such a type, or raises XXX_Error if Is_Derived returns False for the given subtype. Function Is_Descendant returns True if and only if the type of the first subtype is a descendant of the type of the second subtype. Function Ultimate_Ancestor returns an ancestor of the given subtype that is not itself a descendant of any other type; it will be the type itself if Is_Derived returns False for the type and Progenitors 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. XX.X.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; Function Is_Incomplete_View returns True if and only if the type of the given subtype is an incomplete view of a type. Function Complete_View returns the complete view of a subtype. If the given subtype is already of a complete view, Complete_View returns the given subtype. Function Is_Partial_View returns True if and only if the type of the given subtype is a partial view of a type. Function Full_View returns the full view of a subtype. If the given subtype is already a full view, Full_View returns the given subtype. XX.X.3.6 Representational and Operational Aspects function Is_Aspect_Specified(S : Subtype_View; Aspect : Asis.Identifier) return Boolean is abstract; function Is_Aspect_Directly_Specified(S : Subtype_View; Aspect : Asis.Identifier) return Boolean is abstract; Function Is_Aspect_Specified returns True if and only if the representational or operational aspect specified by the identifier is specified for the given subtype. Function Is_Aspect_Directly_Specified returns True if and only if the representational or operational aspect specified by the identifier is directly specified for the given subtype. These functions returns False if the identifier does not correspond to a representational or operational aspect of the language or of the implementation. The following are the identifiers associated with language-defined representational and operational aspects: Alignment, Bit_Order, Coding, Component_Size, Controlled, Convention, Exported, External_Tag, Imported, Input, Layout, Output, Packing, Read, Size, Small, Storage_Pool, Storage_Size, Stream_Size, Write --------------------------------------------------------------- XX.X.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. 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 abstract new View with null record; function Is_Constant(O : Object_View) return Boolean is abstract; 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'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 new Natural; 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; function Is_Access_Attribute_Reference(O : Object_View) return Boolean is abstract; function Designated_Object(O : Object_View) return Object_View'Class is abstract; function Is_Implicit_Access_Attribute_Reference(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 Static_Integer_Image(O : Object_View) return 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 String 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; function Object_Size(O : Object_View) return Natural is abstract; function Object_Alignment(O : Object_View) return 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; XX.X.4.1 Type Object_View type Object_View is abstract new View with null record; function Is_Constant(O : Object_View) return Boolean is abstract; function Nominal_Subtype(O : Object_View) return Subtype_View'Class is abstract; The type Object_View represents views of objects and values, as denoted by names or expressions. Function Is_Constant returns True if and only if the view 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.X.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; Function Is_Component returns True if and only if the given view is of a component of an enclosing composite object. Function Enclosing_Object returns a view of that enclosing object, or raises XXX_Error if Is_Component returns False. Function Is_Indexed_Component returns True if and only if the given view is of an indexed component. Function Index_Value returns a view of the value of the index of the indexed component, or raises XXX_Error if Is_Indexed_Component returns False. Function Is_Selected_Component returns True if and only if the given view if of a selected component. Function Selector_Declaration returns the declaration of the given component, or raises XXX_Error if Is_Selected_Component 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, or raise XXX_Error if Is_Selected_Component returns False. XX.X.4.3 Aliased Views and Dereferences function Is_Aliased(O : Object_View) return Boolean is abstract; type Static_Accessibility_Level is new Natural; 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; function Is_Access_Attribute_Reference(O : Object_View) return Boolean is abstract; function Designated_Object(O : Object_View) return Object_View'Class is abstract; function Is_Implicit_Access_Attribute_Reference(O : Object_View) return Boolean is abstract; Function Is_Aliased returns True if and only if the view is aliased. Function Static_Accessibility returns the static accessibility level of the view, or raises XXX_Error if Is_Aliased returns False. The static accessibility level value 0 is returned if the view if of a library level object. Incomparable_Accessibility_Level is returned for a dereference of an access-to-object parameter. Deepest_Accessibility_Level corresponds to the level of the dereference of an access-to-subprogram parameter. Function Is_Dereference returns True if and only if the object is a dereference of an access-to-object value. Function Dereferenced_Value returns a view of the access value that was dereferenced, or raises XXX_Error if Is_Dereference returns False. Function Is_Implicit_Dereference returns True if and only if the object is an implicit dereference of an access-to-object value. Function Is_Access_Attribute_Reference returns True if and only if the view is of an (explicit or implicit) Access attribute reference of an aliased object. Function Designated_Object returns the object designated by the access value, or raises XXX_Error if Is_Access_Attribute_Reference returns False. Function Is_Implicit_Access_Attribute_Reference returns True if and only if the view 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. XX.X.4.4 Static Values function Is_Static_Integer(O : Object_View) return Boolean is abstract; function Static_Integer_Value(O : Object_View) return Longest_Integer is abstract; function Static_Integer_Image(O : Object_View) return 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 String 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 Is_Static_Integer returns True if and only if the given view is of the value of a static expression of an integer type. Function Static_Integer_Value returns the value of the expression, or raises XXX_Error if Is_Static_Integer returns False. If the value is outside the range of Longest_Integer, it raises Constraint_Error. Function Static_Integer_Image returns the image of the value of the expression, with the syntax used by the Image attribute of its type (with a leading minus if negative, and a leading space otherwise), or raises XXX_Error if Is_Static_Integer returns False. A correct image is returned even if the value is outside the base range of the type. Function Is_Static_Real returns True if and only if the given view is of the value of a static expression of a real type. Function Static_Real_Value returns the value of the expression converted to the Longest_Float type, or raises XXX_Error if Is_Static_Real 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. The denominator is one when the numerator is zero. Function Is_Static_String returns True if and only if the given view is of the value of a static expression of a string type. Function Static_Wide_Wide_String_Value returns a Wide_Wide_String whose characters match the corresponding characters of the static value. Function Static_Wide_String_Value and Static_String_Value return a Wide_String and a String, respectively, with corresponding characters if defined in Wide_Character and Character, respectively, or with implementation-defined replacements. XX.X.4.5 Representational Object Attributes function Object_Size(O : Object_View) return Natural is abstract; function Object_Alignment(O : Object_View) return Natural is abstract; Function Object_Size returns the same value as the Size attribute of the given object, 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 Natural'Last. Function Object_Alignment returns the same value as the Alignment attribute of the given object. 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.X.5 Package Asis.Profiles The library package Asis.Profiles shall exist. The package shall provide interfaces equivalent to those described in the following subclauses. 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 ... -- Not specified by the language end Asis.Profiles; XX.X.5.* Details TBD --------------------------------------------------------------- XX.X.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. 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; function Is_Universal(E : Elementary_Subtype) return Boolean is abstract; 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; function Is_Root_Numeric(S : Scalar_Subtype) return Boolean 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; 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 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; XX.X.6.* Details TBD --------------------------------------------------------------- XX.X.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. 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 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 : out Tagged_Subtype_Vector'Class); 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 Ada.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; XX.X.7.* Details TBD --------------------------------------------------------------- XX.X.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. 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 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 : out Subtype_Vector); 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; 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; XX.X.8.* Details TBD --------------------------------------------------------------- XX.X.9 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. 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 abstract new View 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 Ada.Containers.Holders(Package_View'Class); type Package_Holder is new Package_Holders.Holder with null record; end Asis.Package_Views; XX.X.9.* Details TBD --------------------------------------------------------------- XX.X.10 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. 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 abstract new View 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 Ada.Containers.Holders(Generic_View'Class); type Generic_Holder is new Generic_Holders.Holder with null record; end Asis.Generic_Views; XX.X.10.* Details TBD --------------------------------------------------------------- XX.X.11 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. 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 abstract new View with null record; function Names_Are_Discarded(E : Exception_View) return Boolean is abstract; 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; XX.X.11.* Details TBD --------------------------------------------------------------- XX.X.12 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. 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 abstract new View with null record; function Corresponding_Statement(S : Statement_View) return ASIS.Statement is abstract; package Statement_View_Holders is new Ada.Containers.Holders(Statement_View'Class); type Statement_View_Holder is new Statement_View_Holders.Holder with null record; end Asis.Exception_Views; XX.X.12.* Details TBD --------------------------------------------------------------- Add at end of Asis.Declarations: function Corresponding_View_Declaration( Declaration: in Asis.Declaration) return Asis.Declarative_Regions.View_Declaration; 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; !discussion --!corrigendum A.18.2(239/2) !ACATS test !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 '{' { 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; -- Represents 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 represents 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 represents 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.) ****************************************************************