--| +=========================================================================+ --| | | --| | REGION_SUPPORT - support for declarative region parts | --| | | --| | This package encapsulates the concept of a declarative region part, | --| | and more specifically it encapsulates the definition and identification | --| | of declarative region parts in terms of Asis elements. | --| | | --| | Greg Janee | --| | General Research Corporation | --| | | --| | Modified 12/12/94 by Chuck Hobin: | --| | | --| | * Added the function Defines_A_Declarative_Region. | --| | * Removed An_Exception_Handler from Region_Kinds. | --| | * Changed default value of Expand_Instantiations parameters from | --| | False to True. | --| | * Updated documentation. | --| +=========================================================================+ --| A "declarative region" (LRM 8.1) is a logical portion of program text --| that bounds the scope of declarations. This text may consist of --| several disjoint parts which are distributed across multiple compilation --| units. We define a "region part" to be a physical, contiguous text --| fragment, residing in a single compilation unit, that is a distinct part --| of one declarative region. A declarative region contains one or more --| non-overlapping region parts which, taken together, comprise the entire --| text of the region. --| --| For example, the declarative region of package can contain up to --| four region parts: --| - a package specification visible part --| - a package specification private part --| - a package body stub --| - a package body --| If the package is generic, then a fifth region part is identified --| for the generic formal part. --| --| This package exports two things. First, its specification exports --| a general mechanism with which sets of Asis elements are mapped --| to region parts. Second, its body defines a particular such mapping. --| --| In the general model, each Asis element kind denotes zero --| or more declarative region parts. If an element kind denotes one or --| more region parts, each part has a unique kind and contains a --| non-overlapping subset of the element's children. Some of the --| element's children might not be contained in any of the parts; these --| children are contained in the parent region part. As a special case, --| an Asis.Compilation_Unit always denotes exactly one region part, --| and all its children are in that part. (This region part logically --| belongs to the implicit declarative region, formed by package Standard, --| which encloses all library units - LRM 8.6). --| --| A particular example may clarify the general model. Under this model, --| the element kind A_Declaration/A_Package_Declaration denotes two regions: --| --| 1) A_Package_Specification_Visible_Part --| 2) A_Package_Specification_Private_Part --| --| The declarative items in the visible part of the package are contained --| in the first region, while those in the private part are contained in --| the second. The name of the package is in neither region; it is --| effectively contained in the parent region. --| --| The mapping implemented by the body of this package restricts the --| general model to reflect the semantic rules of LRM 8.1. These --| rules specify the conditions under which certain Ada constructs --| form a declarative region. For example, a renaming declaration --| forms a region only if it contains a formal part. Also, the --| the mapping omits region parts that do not actually exist in --| the source code of a compilation unit. --| --| EXAMPLE: --| --| package P is --| A : Integer; --| end P; --| --| Because this package does not contain the keyword PRIVATE, the --| corresonding A_Package_Declaration element denotes only one region --| part: A_Package_Specification_Visible_Part. --| with Asis; package Region_Support is --| The kinds of region parts generated by the body of this package... type Region_Kinds is (A_Compilation_Unit, A_Record_Type_Declaration, An_Incomplete_Type_Declaration, A_Private_Type_Declaration, A_Package_Specification_Visible_Part, A_Package_Specification_Private_Part, A_Package_Body, A_Procedure_Specification, A_Procedure_Body, A_Function_Specification, A_Function_Body, A_Procedure_Rename_Declaration, A_Function_Rename_Declaration, A_Generic_Package_Formal_Part, A_Generic_Package_Specification_Visible_Part, A_Generic_Package_Specification_Private_Part, A_Generic_Procedure_Formal_Part, A_Generic_Procedure_Specification_Part, A_Generic_Function_Formal_Part, A_Generic_Function_Specification_Part, A_Task_Declaration, A_Task_Body, A_Task_Type_Declaration, An_Entry_Declaration, A_Procedure_Body_Stub, A_Function_Body_Stub, A_Package_Body_Stub, A_Task_Body_Stub, A_Generic_Formal_Private_Type_Declaration, A_Generic_Formal_Procedure_Specification, A_Generic_Formal_Function_Specification, A_For_Loop_Statement, A_While_Loop_Statement, A_Simple_Loop_Statement, A_Block_Statement, An_Accept_Statement, A_Record_Representation_Clause); --| A Region object identifies a region part. It has three attributes: a --| kind; a "head" element or compilation unit (i.e., the element or unit --| that denotes the region part); and zero or more child elements of the --| head element or unit that comprise the region part. type Region (Kind : Region_Kinds := A_Compilation_Unit) is private; type Region_List is array (Integer range <>) of Region; --| Access functions for type Region. In case it's not obvious, Head_Unit --| should be applied to region parts of kind A_Compilation_Unit only, while --| Head_Element should be applied to all other kinds of region parts only. function Kind (The_Region : in Region) return Region_Kinds; function Head_Element (The_Region : in Region) return Asis.Element; function Head_Unit (The_Region : in Region) return Asis.Compilation_Unit; function Subelements (The_Region : in Region; Include_Pragmas : in Boolean := True) return Asis.Element_List; --| Equivalent_Region returns the region part corresponding to a compilation --| unit. function Equivalent_Region (The_Unit : in Asis.Compilation_Unit) return Region; --| If Expand_Instantiations is true when calling the following --| functions, instantiation elements effectively have one or two children: --| the corresponding specification element (if present) and body element --| (if present). function Denotes_One_Or_More_Regions (The_Element : in Asis.Element; Expand_Instantiations : in Boolean := True) return Boolean; --| Denoted_Regions and Non_Region_Subelements should be called on --| elements that denote one or more region parts only. An exception will --| result otherwise. --| --| The parameter Include_Instance_Bodies in Denoted_Regions controls whether --| the body region part (if present) of a generic instantiation is returned. --| This parameter is meaningful only when Expand_Instantiations is True. --| --| Non_Region_Subelements returns the child elements of the --| given element that are not part of any denoted region (i.e., are --| part of the parent region). function Denoted_Regions (The_Element : in Asis.Element; Expand_Instantiations : in Boolean := True; Include_Instance_Bodies : in Boolean := True) return Region_List; function Non_Region_Subelements (The_Element : in Asis.Element; Expand_Instantiations : in Boolean := True; Include_Pragmas : in Boolean := True) return Asis.Element_List; --| The constituent region parts of a declarative region may have more than --| one head element. For example, the logical declarative region of a package --| may have region parts which are denoted by three different elements: --| 1) A_Package_Declaration, 2) A_Package_Body_Stub, and 3) --| A_Package_Body_Declaration. In this case, the A_Package_Declaration --| element is said to "define" the declarative region; the other elements --| do not define a declarative region but simply denote additional region --| parts belonging to an existing region. Given a head element that is NOT a --| defining element, the corresponding defining element can be determined --| as follows: --| --| * For a declaration element, apply the query --| Asis.Expressions.Name_Declaration to the declaration's entity name --| definition. --| --| * For a record representation clause element, apply the query --| Asis.Expressions.Name_Declaration to the type simple name in the --| clause. --| --| * For an accept statement, apply the query Asis.Statements.Accepted_Entry --| to the statement. --| --| Function Defines_A_Declarative_Region returns true for any element that: --| * denotes one or more regions, and --| * is the defining element of a declarative region. --| Note: this operation always expands instantiations when identifying denoted --| regions. function Defines_A_Declarative_Region (The_Element : in Asis.Element) return Boolean; --| When an Asis exception is encountered, an error message is logged --| using the Msg_Log package and Region_Error is raised. Region_Error : exception; private type Region (Kind : Region_Kinds := A_Compilation_Unit) is record case Kind is when A_Compilation_Unit => Unit : Asis.Compilation_Unit; when others => Element : Asis.Element; end case; end record; end Region_Support;