This is a prototype implementation of a language extension that allows
calls to primitives of untagged types to be written using prefixed
notation.  That is, the first actual parameter of the call is given as a
prefix using selected_component syntax, and the selector is a primitive
operation of the actual's type). The basic implementation approach is to
employ the Direct_Primitive_Operations field for use by untagged types.
While we could choose to include only the primitives for which a
prefixed call could be made, it seems better to include all primitives,
consistent with the meaning of this list and for uniformity with tagged
types.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

        * doc/gnat_rm/implementation_defined_pragmas.rst: Add a
        description of the feature of prefixed-view calls for untagged
        types to the section on pragma Extensions_Allowed.
        * gnat_rm.texi: Regenerate.
        * einfo.ads: Update specification for
        Direct_Primitive_Operations to reflect its use for untagged
        types when Extensions_Allowed is True.
        * gen_il-gen-gen_entities.adb: Allow Direct_Primitive_Operations
        as a field of untagged classes of types by removing the "Pre"
        test of "Is_Tagged_Type (N)", and making that field generally
        available for all types and subtypes by defining it for
        Type_Kind and removing its specification for individual classes
        of types.
        * sem_ch3.adb (Analyze_Full_Type_Declaration): Initialize the
        Direct_Primitive_Operations list when not already set for the
        new (sub)type and its base type (except when Ekind of the type
        is E_Void, which can happen due to errors in cases where
        Derived_Type_Declaration is called and perhaps in other
        situations).
        (Analyze_Subtype_Declaration): Inherit
        Direct_Primitive_Operations list from the base type, for record
        and private cases.
        (Build_Derived_Record_Type): Initialize the
        Direct_Primitive_Operations list for derived record and private
        types.
        (Build_Derived_Type): Initialize the Direct_Primitive_Operations
        list for derived types (and also for their associated base types
        when needed).
        (Process_Full_View): For full types that are untagged record and
        private types, copy the primitive operations of the partial view
        to the primitives list of the full view.
        * sem_ch4.adb (Analyze_Selected_Component): Allow prefixed
        notation for subprogram calls in the case of untagged
        types (when Extensions_Allowed is True). In the case where
        Is_Private_Type (Prefix_Type) is True, call Try_Object_Operation
        when a discriminant selector wasn't found. Also call
        Try_Object_Operation in other type kind cases (when
        Extensions_Allowed is True).
        (Try_Object_Operation.Try_One_Prefixed_Interpretation): Prevent
        early return in the untagged case (when Extensions_Allowed is
        True). Condition main call to Try_Primitive_Operation on the
        type having primitives, and after that, if Prim_Result is False,
        test for case where the prefix type is a named access type with
        primitive operations and in that case call
        Try_Primitive_Operation after temporarily resetting Obj_Type to
        denote the access type (and restore it to the designated type
        after the call)
        (Try_Object_Operation.Valid_First_Argument_Of): Do matching type
        comparison by testing Base_Type (Obj_Type) against
        Base_Type (Typ), rather than against just Typ, to properly
        handle cases where the object prefix has a constrained
        subtype.  (Fixes a bug discovered while working on this
        feature.)
        * sem_ch6.adb
        (New_Overloaded_Entity.Check_For_Primitive_Subprogram): Add a
        primitive of an untagged type to the type's list of primitive
        operations, for both explicit and implicit (derived, so
        Comes_From_Source is False) subprogram declarations. In the case
        where the new primitive overrides an inherited subprogram,
        locate the primitives Elist that references the overridden
        subprogram, and replace that element of the list with the new
        subprogram (done by calling the new procedure
        Add_Or_Replace_Untagged_Primitive on the result type and each
        formal atype).
        (Check_For_Primitive_Subprogram.Add_Or_Replace_Untagged_Primitive):
        New nested procedure to either add or replace an untagged
        primitive subprogram in a given type's list of primitive
        operations (replacement happens in case where the new subprogram
        overrides a primitive of the type).
        * sem_ch7.adb (New_Private_Type): When Extensions_Allowed is
        True, initialize the Direct_Primitive_Operations list of a
        private type to New_Elmt_List in the case of untagged types.
        * sem_ch8.adb (Find_Selected_Component): In the case where the
        prefix is an entity name, relax condition that tests
        Has_Components so that Analyze_Selected_Component will also be
        called when Extensions_Allowed is True and the prefix type is
        any type.

Attachment: patch.diff.gz
Description: application/gzip

Reply via email to