CVS difference for ais/ai-00251.txt

Differences between 1.34 and version 1.35
Log of other versions for file ais/ai-00251.txt

--- ais/ai-00251.txt	2005/08/21 06:00:19	1.34
+++ ais/ai-00251.txt	2005/10/31 05:18:17	1.35
@@ -1,4 +1,4 @@
-!standard 03.04    (02)                            05-07-27   AI95-00251/22
+!standard 03.04    (02)                            05-09-20   AI95-00251/23
 !standard 02.09    (02)
 !standard 03.02    (04)
 !standard 03.02.01 (02)
@@ -25,6 +25,10 @@
 !standard 12.05.01 (03)
 !standard 12.05.01 (15)
 !standard 12.05.05 (01)
+!standard 13.1 (13)
+!standard 13.13.2(9)
+!standard 13.13.2(27)
+!standard 13.13.2(36/1)
 !standard 13.14 (07)
 !class amendment 00-12-04
 !status Amendment 200Y 04-03-29
@@ -469,7 +473,7 @@
 	  overriding), then any null procedure overrides all abstract
 	  subprograms and all subprograms that require overriding; if more than
 	  one such homograph remains that is not thus overridden, then if they
-	  are all fully conformant with one another, one is chosen arbitarily;
+	  are all fully conformant with one another, one is chosen arbitrarily;
 	  if not, they are all hidden from all visibility.
 
 
@@ -557,7 +561,7 @@
     (This section is entirely new.)
 
         The class determined for a formal interface type is the class of all
-        interface types.
+        tagged types.
 
                                  Syntax
 
@@ -578,6 +582,15 @@
         The actual type shall be limited if and only if the formal type is
         limited.
 
+13.1 Operational and Representation Items
+
+   Add after 13.1(13):
+       A type_declaration is illegal if it has one or more progenitors, and a
+       representation item applies to a progenitor or ancestor, and this
+       representation item conflicts with the representation of some other
+       progenitor or ancestor. The cases that cause conflicts are
+       implementation defined.
+
 13.13.2 Stream-Oriented Attributes
 
    Change the last sentence of paragraph 9 (as modified by AI-195) to:
@@ -588,7 +601,14 @@
       the extension components is not available at the freezing point of T,
       then the attribute of T shall be directly specified.
 
+   Add after paragraph 27:
+
+      If T is an abstract type, then S'Input is an abstract function.
 
+   Add a sentence to the end of paragraph 36 (as modified by AI-195):
+      Furthermore, if a stream-oriented attribute is specified for an interface
+      type by an attribute_definition_clause, the subprogram name given in the
+      clause shall statically denote a null procedure.
 
 13.14 Freezing Rules
 
@@ -1397,7 +1417,7 @@
 previous implicit declaration of an inherited subprogram.>
 @dinss
 @xbullet<If two or more homographs are implicitly declared at the same place:>
-@xinbull<If at least one is a subprogram that is neither a null procedure not
+@xinbull<If at least one is a subprogram that is neither a null procedure nor
 an abstract subprogram, and does not require overriding (see 3.9.3), then
 they override those that are null procedures, abstract subprograms, or
 require overriding. If more than one such homograph remains that is not thus
@@ -1406,7 +1426,7 @@
 overriding), then any null procedure overrides all abstract subprograms and all
 subprograms that require overriding; if more than one such homograph remains
 that is not thus overridden, then if they are all fully conformant with one
-another, one is chosen arbitarily; if not, they are all hidden from all
+another, one is chosen arbitrarily; if not, they are all hidden from all
 visibility.>
 
 !corrigendum 12.5(03)
@@ -1463,7 +1483,7 @@
 
 @dinsc
 The class determined for a formal interface type is the class of all
-interface types.
+tagged types.
 
 @i<@s8<Syntax>>
 
@@ -1477,6 +1497,18 @@
 
 The actual type shall be limited if and only if the formal type is limited.
 
+!corrigendum 13.1(13)
+
+@dinsa
+A representation or operational item that is not supported by the
+implementation is illegal, or raises an exception at run time.
+@dinst
+A @fa<type_declaration> is illegal if it has one or more progenitors, and a
+representation item applies to a progenitor or ancestor, and this
+representation item conflicts with the representation of some other
+progenitor or ancestor. The cases that cause conflicts are
+implementation defined.
+
 !corrigendum 13.13.2(9/1)
 
 @drepl
@@ -1509,6 +1541,39 @@
 components is not available at the freezing point of @i<T>, then the attribute
 of @i<T> shall be directly specified.
 
+
+!corrigendum 13.13.2(27)
+
+@dinsa
+S'Output then calls S'Write to write the value of @i<Item> to the stream. S'Input
+then creates an object (with the bounds or discriminants, if any, taken from
+the stream), initializes it with S'Read, and returns the value of the object.
+@dinst
+If @i<T> is an abstract type, then S'Input is an abstract function.
+
+
+!corrigendum 13.13.2(36/1)
+!comment This is mostly a conflict-creator.
+
+@drepl
+The stream-oriented attributes may be specified for any type via an
+@fa<attribute_definition_clause>. All nonlimited types have default
+implementations for these operations. An @fa<attribute_reference> for one of
+these attributes is illegal if the type is limited, unless the attribute
+has been specified by an @fa<attribute_definition_clause> or (for a type
+extension) the attribute has been specified for an ancestor type. For an
+@fa<attribute_definition_clause> specifying one of these attributes, the
+subtype of the Item parameter shall be the base subtype if scalar, and the
+first subtype otherwise. The same rule applies to the result of the Input
+function.
+@dby
+The stream-oriented attributes may be specified for any type via an
+@fa<attribute_definition_clause>. The subprogram name given in such a
+clause shall not denote an abstract subprogram.
+Furthermore, if a stream-oriented attribute is specified for an interface type
+by an @fa<attribute_definition_clause>, the subprogram name given in the
+clause shall statically denote a null procedure.
+
 !corrigendum 13.14(7)
 
 @dinsa
@@ -5424,6 +5489,386 @@
 
 ****************************************************************
 
+From: Tucker Taft
+Sent: Saturday, January 22, 2005  1:14 PM
+
+I have been reviewing parts of John's forthcoming and
+much-anticipated rationale, chapter by chapter.  It is
+an extremely useful "grounding" since you suddenly see
+proposed rules or syntaxes that are either great, or
+simply awful.
+
+Today's installment focused on generics, and it reminded
+me of a general question I have had -- what are formal
+interfaces good for?  I certainly am not suggesting
+we should drop them, but currently the rules for matching
+formals and actuals seem very strict, and might very
+well interfere with creating "generic" generics.  But
+without some idea of how formal interfaces might be used,
+it is pretty tough to know.  So my question is,
+does anyone have any good examples of use?
+
+-Tuck
+
+P.S. Here are my own thoughts on the subject:
+
+-------
+
+I have been having *some* thoughts on how a formal interface might
+be useful.  First, I think it makes sense to focus on
+why you might write a generic package that mentions an
+interface type at all in its formal part.  It might be:
+
+    package Linked_Lists is
+       -- Define an interface useful for singly-linked lists
+       type Linkable is interface;
+       function Next(L : access constant Linkable)
+         return access Linkable'Class is abstract;
+       procedure Set_Next(L : access Linkable;
+         Next : access Linkable'Class) is abstract;
+
+       generic
+         type Element(<>) is new Linkable with private;
+       package Homogeneous_Lists is
+         -- Create a homogeneous list, given an element
+         -- type that implements Linkable
+         type List is private;
+         procedure Append(L : in out List; E : not null access Element);
+         procedure Prepend(L : in out List; E : not null access Element);
+         function First(L : List) return access Element;
+           -- returns null if L is empty
+         function Remove_First(L : in out List) return access Element;
+         function Last(L : List) return access Element;
+         function Remove_Last(L : in out List) return access Element;
+       end Homogeneous_Lists;
+    end Linked_Lists;
+
+    package Linked_Lists.Heterogeneous_Lists is new
+      Homogeneous_Lists(Linkable'Class);
+        -- Provide a heterogeneous "List" type which allows
+        -- elements of any linkable type.
+        -- (I think this is very cool, though I know it gives
+        --  Randy heartaches ;-)
+
+------
+
+Ok, so that is an example of a generic that uses an interface
+in the specification of a formal type.  But why would the
+interface itself want to be a formal type?  Perhaps one
+of the reasons is that there are already a dozen "Linkable"
+interfaces out there being used for this and that, and the
+last thing we need is yet *another* one.  So instead of
+reinventing a Linkable interface, we change the above
+abstraction as a whole to be generic:
+
+    generic
+
+       type Linkable is interface;
+         -- Import an interface useful for singly-linked lists
+       with function Next(L : access constant Linkable)
+         return access Linkable'Class is abstract;
+       with procedure Set_Next(L : access Linkable;
+         Next : access Linkable'Class) is abstract;
+
+    package Generic_Linked_Lists is
+
+       generic
+         type Element(<>) is new Linkable with private;
+       package Homogeneous_Lists is
+         -- Create a homogeneous list, given an element
+
+       ... etc.
+
+Does the above make sense?  Does it even work?  In particular,
+I wonder whether the Element type ends up with its own
+Next and Set_Next (formal) dispatching operations, thanks to the
+formal abstract subprograms declared in the outer generic.
+Did we ever talk about that?  I suppose we don't really
+need for formal Element type to inherit the dispatching
+operations Next and Set_Next, since we can accomplish
+the same thing by making a dispatching call using the
+one's associated with Linkable, but it makes some sense
+that a formal derived type would inherit the formal dispatching
+operations from an ancestor formal type.  Perhaps it is
+unnecessary complexity, given the ability to reach them
+via a dispatching call, and the fact you can't override
+them anyway.  But it is interesting.
+
+In any case, I have wandered off the track.  The main
+question is this an example of how formal interfaces
+would be used?  I suppose roughly the same thing could
+be accomplished by combining the nested generics into
+a single generic, e.g.:
+
+    generic
+
+       type Linkable is interface;
+         -- Import an interface useful for singly-linked lists
+       with function Next(L : access constant Linkable)
+         return access Linkable'Class is abstract;
+       with procedure Set_Next(L : access Linkable;
+         Next : access Linkable'Class) is abstract;
+       type Element(<>) is new Linkable with private;
+     package Linked_Lists is
+       type List is private;
+       ...
+
+though then, for some reason, it seems a bit harder to
+understand.
+
+I see a somewhat similar situation might arise with a
+generalized scheduling package which wants to take a task
+type:
+
+    package Scheduling is
+       type Root_Task is task interface;
+       type Scheduling_Params is record
+           Cycle : Milliseconds;
+           Etc ...
+       end record;
+
+
+       generic
+           type Some_Task(<>) is new Root_Task with private;
+       package Controller is
+           function Create_And_Start_Task(Params: Scheduling_Params)
+             return access Some_Task;
+           procedure Change_Cycle(New_Cycle : Milliseconds;
+             T : not null access Some_Task);
+           ...
+       end Controller;
+    end Scheduling;
+
+Here, again, there might be many Root_Task interfaces
+(given that the language doesn't define one ;-),
+and it might be better to import one rather than
+have each abstraction with its own root task.
+Hence:
+
+     generic
+         type Root_Task is task interface;
+     package Scheduling is
+         type Scheduling_Params is record ...
+
+----
+
+None of the above are what I would call "compelling"
+examples.  Does anyone have any better ones?
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Monday, January 24, 2005  5:38 AM
+
+Tuck wrote:
+
+>     generic
+>
+>        type Linkable is interface;
+>          -- Import an interface useful for singly-linked lists
+>        with function Next(L : access constant Linkable)
+>          return access Linkable'Class is abstract;
+>        with procedure Set_Next(L : access Linkable;
+>          Next : access Linkable'Class) is abstract;
+>
+>     package Generic_Linked_Lists is
+>
+>        generic
+>          type Element(<>) is new Linkable with private;
+>        package Homogeneous_Lists is
+>          -- Create a homogeneous list, given an element
+>
+>        ... etc.
+>
+> Does the above make sense?  Does it even work?  In particular,
+> I wonder whether the Element type ends up with its own
+> Next and Set_Next (formal) dispatching operations, thanks to the
+> formal abstract subprograms declared in the outer generic.
+> Did we ever talk about that?  I suppose we don't really
+> need for formal Element type to inherit the dispatching
+> operations Next and Set_Next, since we can accomplish
+> the same thing by making a dispatching call using the
+> one's associated with Linkable, but it makes some sense
+> that a formal derived type would inherit the formal dispatching
+> operations from an ancestor formal type.  Perhaps it is
+> unnecessary complexity, given the ability to reach them
+> via a dispatching call, and the fact you can't override
+> them anyway.
+
+The wording for derived operations is currently based on primitive-ness,
+and Next and Set_Next are not primitive operations of Linkable (although
+they are dispatching), so they are not inherited.  As you point out, it's
+OK because you can call them in a dispatching manner.  I wouldn't change
+the rules here, because having to inherit the formal abstract subprograms
+would add more complexity both in the language and in compilers, for
+little benefits.
+
+> The main
+> question is this an example of how formal interfaces
+> would be used?
+
+I suppose that "naked" interfaces would seldom be used, but interfaces
+derived from other interfaces make a lot of sense.
+
+In one of his papers, John had an example where he had geometric objects
+(triangles, circles, etc.), and he was mixing them with an interface
+Printable to be able to print them out.
+He had a generic like:
+
+	generic
+	   type T is abstract tagged private;
+	package Make_Printable is
+	   type Printable_T is abstract new T and Printable with private;
+	   ...
+	end;
+
+But I suspect that in real life you might have "specializations" of the
+interface Printable, say for different output devices.  So instead of
+directly deriving from Printable, you might want to derive from any
+interface that implements Printable:
+
+	generic
+	   type T is abstract tagged private;
+	   type Any_Printable is interface and Printable;
+	package Make_Printable is
+	   type Printable_T is abstract new T and Any_Printable with
+private;
+	   ...
+	end;
+
+
+If you assume that people will have rather fancy hierarchies of interfaces
+(that's what they do in Java and C#) then the second generic is
+substantially more flexible than the first one.
+
+****************************************************************
+
+From: Gary Dismukes
+Sent: Thursday, February 17, 2005  3:09 PM
+
+Javier Miranda noticed that the syntax for interface_type_definition
+is inconsistent between AI-251 and AI-345.  The syntax given in AI-345
+specifies an "AND" preceding the interface list whereas AI-251 doesn't
+have the "AND", and the AARM syntax is what's in AI-345.  Shouldn't
+AI-251 be revised to be consistent with the syntax of AI-345?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, February 17, 2005  6:13 PM
+
+I don't know the right answer here. If we insist on updating all of the AIs
+for the results of later AIs, we'll have a huge (and relatively useless) job
+on our hands. So, we've usually left AIs as linear changes: first 251, which
+is modified by 345, which is modified by 401, etc. Similarly, we don't
+update AIs when they conflict with other AIs; only the AARM and Amendment
+show the net overall change. And, since we have updated the AARM and added
+appropriate notes, references back to the AIs should be necessary only in
+cases of in-depth research.
+
+Of course, if you're volunteering to update the 40 or so AIs, I'll be happy
+to tell you what needs to be done. :-) :-)
+
+****************************************************************
+
+From: Gary Dismukes
+Sent: Thursday, February 17, 2005  7:40 PM
+
+OK, that's fine.  For some reason I was under the impression that you
+were trying to keep the corrigendum sections of the AIs in synch with
+the RM changes, so thought I should ask about this inconsistency.
+
+> Of course, if you're volunteering to update the 40 or so AIs, I'll be happy
+> to tell you what needs to be done. :-) :-)
+
+Nope, not volunteering.  I think I can live with the status quo. ;-)
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, February 17, 2005  8:05 PM
+
+> OK, that's fine.  For some reason I was under the impression that you
+> were trying to keep the corrigendum sections of the AIs in synch with
+> the RM changes, so thought I should ask about this inconsistency.
+
+With *editorial* changes, yes, but not changes that are big enough to have
+required another AI. Smaller editorial changes have to be reflected
+somewhere, and that would either mean presentation AIs or updates-in-place
+(and clearly the latter are easier, and better for everyone). Big changes
+are handled by new AIs, and it wouldn't make much sense to modify the old
+ones in that case.
+
+****************************************************************
+
+From: Adam Beneschan
+Sent: Saturday, February 19, 2005  1:22 PM
+
+!topic Ada 05 allows many interesting new type conversions
+!reference RM05 4.6
+!from Adam Beneschan 05-02-18
+!discussion
+
+It appears that, on reading 4.6 carefully (yes, I know Randy would
+tell me "Don't do that"), you can now convert an integer to a record
+type.
+
+The Ada 95 manual's intent was (loosely) to allow type conversions
+between types that had a common ancestor, and to allow certain other
+explicitly defined type conversions in four cases.  The organization
+was:
+
+- If case 1 then ...
+- If case 2 then ...
+- If case 3 then ...
+- If case 4 then ...
+- If none of the above four cases apply, then there must be a common
+  ancestor, and furthermore blah-blah-blah.
+
+The Ada 05 manual reorganized this, and the organization is now
+something like:
+
+- If there is a common ancestor, then blah-blah-blah.
+- If there is no common ancestor, then:
+--  If the target type is numeric then ...
+--  If the target type is an array type then ...
+--  If the target type is universal_access then ...
+--  If the target type is a general access-to-object type then ...
+--  If the target type is an access-to-subprogram type then ...
+
+BUT it doesn't say what happens if there's no common ancestor and the
+target type doesn't fall into one of these five cases, such as the
+case where the target type is a record type.  Since there's no "If"
+that applies to this case, it would appear that there is no Legality
+Rule that makes this illegal, regardless of what the operand is.
+
+What's missing is something after the last "If" saying:
+
+--  If the target type does not fall into one of the above five cases,
+    then the type conversion is illegal.
+
+I realize this is a nitpick, but I'm sure it was an oversight not to
+include something like this, and I think it probably ought to be
+added.
+
+****************************************************************
+
+From: Christoph Grein
+Sent: Tuesday, February 22, 2005  4:35 AM
+
+Ada 2005 Amendment 1 (Draft 10)
+
+3.9.4 Interface Types
+
+Insert new clause: [AI95-00251-01; AI95-00345-01]
+An interface type is an abstract tagged type that provides a restricted
+form of multiple inheritance. A tagged, task, or protected type
+{can}have one or more interface types as ancestors.
+
+Probably "can" missing.
+
+****************************************************************
+
 From: Adam Beneschan
 Sent: Thursday, April 21, 2005  7:47 PM
 
@@ -5535,6 +5980,183 @@
 
 ****************************************************************
 
+From: Robert I. Eachus
+Sent: Tuesday, May 10, 2005  10:54 PM
+
+>Anyway, go read the availability rules in 13.13.2(39-49/2) in the draft 11
+>AARM. You should be able to figure out any answer about stream attributes
+>there (although they might make *your* head hurt); if you can't, then tell
+>us what you think the hole is.
+
+First:  13.1 (15.1):
+      {/8652/0040
+<http://www.adaic.com/standards/rm-amend/html/defect1.html#8652/0040>/}
+{/AI95-00108-01
+<http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00108.TXT>/} A
+derived type inherits each type-related aspect of representation of its
+parent type that was directly specified before the declaration of the
+derived type, or (in the case where the parent is derived) that was
+inherited by the parent type from the grandparent type. A derived
+subtype inherits each subtype-specific aspect of representation of its
+parent subtype that was directly specified before the declaration of the
+derived type, or (in the case where the parent is derived) that was
+inherited by the parent subtype from the grandparent subtype, but only
+if the parent subtype statically matches the first subtype of the parent
+type. An inherited aspect of representation is overridden by a
+subsequent representation item that specifies the same aspect of the
+type or subtype.
+
+There are two things missing here.  First, I assume that allowing
+representation clauses for interface types is not intended.  But it
+seems to me that, at least in the AARM, a note to this paragraph should
+spell out that  representation attributes are not inherited from
+interface types.
+
+3.9.4(7/2):
+     {/AI95-00251-01
+<http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00251.TXT>/} All
+user-defined primitive subprograms of an interface type shall be
+abstract subprograms or null procedures.
+
+So predefined operators like "="  (as opposed to user defined "=") are
+allowed, as are the attribute subprograms like 'Read and 'Write.  That's
+how I remembered the new RM wording, and I think the user-defined is
+required.
+
+But 13.13.2(2..6) says:
+
+   For every subtype S of a specific type /T/, the following attributes
+are defined.
+
+   S'Write
+
+   S'Read...
+
+Seems pretty clear, and I can't see how interface types are not specific
+types.
+
+13.13.2(10..14): For every subtype S'Class of a class-wide type /T/'Class:
+
+          S'Class'Write
+         ...
+         S'Class'Read
+
+Looks to me like class-wide Read and Write are there too.
+
+So say you have the following declarations:
+
+  package P is
+    type I is interface;
+  end P;
+
+  with P; with Ada.Finalization;
+  package Q is
+    type D is new Ada.Finalization.Controlled and P.I;
+  end Q;
+
+    with P, Q;
+   procedure Fubar is
+   begin
+      ..
+      P.I'Write(...,P.I(D));
+   end Fubar;
+
+Head hurts....
+
+Seriously, P.I'Class'Write(...,D);  seems well defined and even possibly
+useful, but allowing the 'Read and 'Write of abstract types be called
+seems mischievous.
+
+****************************************************************
+
+From: Gary Dismukes
+Sent: Wednesday, May 11, 2005  1:17 AM
+
+> Seriously, P.I'Class'Write(...,D);  seems well defined and even possibly
+> useful, but allowing the 'Read and 'Write of abstract types be called
+> seems mischievous.
+
+But that's nothing new.  It's just that those attribute have to be invoked
+by a dispatching call in the case of an abstract type, and in fact the
+'Class versions are defined to make dispatching calls to 'Read and 'Write.
+The dispatchingness of the non-'Class versions is clarified in AI-335.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, May 11, 2005  3:07 PM
+
+> There are two things missing here.  First, I assume that allowing
+> representation clauses for interface types is not intended.  But it
+> seems to me that, at least in the AARM, a note to this paragraph should
+> spell out that  representation attributes are not inherited from
+> interface types.
+
+Interfaces could have representation clauses if the implementation allows
+it. A clause that specified the location of the tag might be very useful in
+some models. But we don't *require* any.
+
+In any case, there is no problem here, because this says that the
+representation is inherited from the parent type. If the parent type is an
+interface, it will inherit whatever values there are there - no problem. But
+interfaces that are not parents (that is, are in an interface_list) don't
+participate. So representation is inherited from exactly one type, which is
+good.
+
+> 3.9.4(7/2):
+>      {/AI95-00251-01
+> <http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00251.TXT>/} All
+> user-defined primitive subprograms of an interface type shall be
+> abstract subprograms or null procedures.
+>
+> So predefined operators like "="  (as opposed to user defined "=") are
+> allowed, as are the attribute subprograms like 'Read and 'Write.  That's
+> how I remembered the new RM wording, and I think the user-defined is
+> required.
+
+Right, the predefined operations are allowed. But there are no requirements
+on those operations; they're predefined after all!
+
+...
+> So say you have the following declarations:
+>
+>   package P is
+>     type I is interface;
+>   end P;
+>
+>   with P; with Ada.Finalization;
+>   package Q is
+>     type D is new Ada.Finalization.Controlled and P.I;
+>   end Q;
+>
+>     with P, Q;
+>    procedure Fubar is
+>    begin
+>       ..
+>       P.I'Write(...,P.I(D));
+>    end Fubar;
+>
+> Head hurts....
+
+You didn't look at the availability rules. T'Read etc. are *always* defined
+for *all* types; but there are types that it can't be called for.
+
+> Seriously, P.I'Class'Write(...,D);  seems well defined and even possibly
+> useful, but allowing the 'Read and 'Write of abstract types be called
+> seems mischievous.
+
+But if you had, you would have found that P.I'Read is in fact allowed. Of
+course, it does nothing, because there are no components. And it is good
+that it is defined, so that if an interface is the parent type, the
+attributes compose properly.
+
+That is, for
+    type R is new P.I with ...
+we want R'Read to be well-defined by default; but that requires its parent's
+'Read to be well-defined by default.
+
+****************************************************************
+
 From: Bob Duff
 Sent: Monday, June  6, 2005  12:36 PM
 
@@ -5848,4 +6470,1969 @@
 composite.
 
 ****************************************************************
+
+!topic Multiple overriding
+!reference RM06 8.3, 3.9.2, 3.9.3
+!from Adam Beneschan 05-06-17
+!discussion
+
+
+Interfaces now make it possible that two (or more) inherited
+homographs can be declared at the same place.  8.3(26.1/2) makes it
+clear that one of those, P1, will override all the others---P2, P3,
+etc.  (Of course, I don't intend for "P1", "P2", etc., to reflect the
+subprogram name---all those subprograms have the same identifier.)
+
+Suppose that a later homograph P100 is explicitly declared that
+overrides P1.  Does it also override P2, P3, etc.?
+
+The rules seem to imply that it does.  8.3(9/1-10/1) seems to indicate
+that whenever two homographs occur in the same declarative region, and
+one is overridable and one is non-overridable, the non-overridable one
+overrides the overridable one.  Whether the overridable one was
+already overridden previously seems not be taken into account by the
+rules.
+
+The answer to the above question (Does P100 override P2, etc.) affects
+the legality of a couple situations, and I'm not clear that a "yes"
+answer leads to the desired result.
+
+Case I:
+
+    package Pak1 is
+        type I1 is interface;
+        procedure Foo (X : in I1) is abstract;
+    end Pak1;
+
+    package Pak2 is
+        type Rec is tagged null record;
+        procedure Foo (X : in Rec);
+    end Pak2;
+
+    package Pak3 is
+        type Child is abstract new Pak2.Rec and Pak1.I1 with record
+            ...
+        end record;
+        -- (A)
+        -- procedure Foo (X : in Child) is abstract;    --Foo1
+        -- procedure Foo (X : in Child);                --Foo2
+    private
+        procedure Foo (X : in Child) is abstract;       --Foo3
+    end Pak3;
+
+At point (A), two implicit homographs are declared as shown.  The
+rules say that Foo2 overrides Foo1 at that point.  Later, though,
+there is an abstract overriding procedure in the private part.
+
+3.9.3(10) says:
+
+    For an abstract type declared in a visible part, an abstract
+    primitive subprogram shall not be declared in the private part,
+    unless it is overriding an abstract subprogram implicitly declared
+    in the visible part. . . .
+
+If there were no Foo declared for the type I1, Foo3 would be illegal.
+However, since Foo *is* declared for I1, there is now an abstract
+subprogram (Foo1) implicitly declared in the visible part.  If the
+interpretation is that Foo3 overrides both Foo1 and Foo2, then the
+"unless" condition of 3.9.3(10) is satisfied, and the declaration of
+Foo3 is legal.  I suspect this is not what is desired.
+
+
+Case II:
+
+    package Pak1 is
+        type I1 is interface;
+        procedure Foo (X : in out I1) is null;
+    end Pak1;
+
+    package Pak2 is
+        type Rec is tagged null record;
+        procedure Foo (X : in Rec);
+    end Pak2;
+
+    package Pak3 is
+        type Child is new Pak2.Rec and Pak1.I1 with record
+            ...
+        end record;
+        -- (A)
+        -- procedure Foo (X : in out Child) is null;    --Foo1
+        -- procedure Foo (X : in Child);                --Foo2
+
+        procedure Foo (X : in Child);                   --Foo3
+    end Pak3;
+
+At point (A), two implicit homographs are declared as shown.  The
+rules say that Foo2 overrides Foo1 at that point.  Furthermore, since
+the rules about "full conformance" only apply when we select a null
+(resp. abstract) procedure from multiple null procedures to be the
+overriding one, and that isn't the case here (8.3(26.1/2)), the
+derived type declaration is legal.
+
+Later, we declare an overriding procedure.  3.9.2(10/2) says, in part,
+
+    If the dispatching operation overrides an inherited subprogram, it
+    shall be subtype conformant with the inherited subprogram.
+
+Whether the declaration of Foo3 is legal depends on whether Foo3 is
+considered to override both Foo1 and Foo2.  If it does, then Foo3 is
+illegal (it's not mode conformant with Foo1).  If Foo3 overrides only
+Foo2 [because Foo1 was previously overridden], then the declaration of
+Foo3 is legal.  I'm guessing that having Foo3 be illegal would be
+surprising, if nothing else, because the rules about homographs when
+multiple inheritance occurs is that a "real" subprogram is supposed to
+override a null one, and it would seem a bit surprising that the null
+one, which supposedly got superseded by the real subprogram, still has
+an effect on the legality of a later declaration.
+
+****************************************************************
+
+From: Adam Beneschan
+Sent: Friday, June 17, 2005  7:43 PM
+
+Second thoughts re Case II:
+
+After I sent this, it occurred to me that 3.9.2(20/2) has an impact on
+all this: "For the execution of a call on a dispatching operation, the
+body executed ... for an implicitly declared dispatching operation
+that is overridden is the body for the overriding subprogram".
+
+I'm assuming that in the above case, we *do* want Foo3 to override
+Foo1 and Foo2, because then Foo3 becomes the overriding subprogram for
+a dispatching operation for both Pak2.Rec and Pak1.I1.  Thus, if we
+say Foo(X) where X has type Pak1.I1'Class, and the actual object's tag
+is for the type Child, I'm assuming that we'd want Foo3 to be
+executed.  In that case, it makes sense that Foo3 would be illegal,
+since the parameter mode is different than a dispatching operation on
+Pak1.I1'Class would expect.  So I think I goofed when I wrote my
+previous post.
+
+Of course, there's also the minor problem that, according to the
+rules, Foo1 is overridden by *both* Foo2 and Foo3, so that when
+3.9.2(20/2) talks about "*the* overriding subprogram" for Foo1, it's
+sort of lying because there's more than one overriding subprogram.
+But I think we can all assume Foo3 is what is meant.  I don't know
+whether it's worthwhile to try to fix the rules in this case.
+
+However, I think the case I previously mentioned, involving 3.9.3(10),
+is still a problem.  (Perhaps the solution is to add a bit of language
+to 3.9.3(10).)
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, August 23, 2005  5:35 AM
+
+An issue that has been discussed several times by the ARG, but never
+properly resolved, is that of the interaction between tag placement and
+interfaces.
+
+The problem is that it is possible to combine interfaces in ways that
+would result in conflicting placement for the tag.  Consider for instance:
+
+	type I1 is interface; -- Tag at offset 0 by default.
+
+	type T1 is tagged
+	   record
+	      Component : Natural;
+	   end record;
+
+	for T use
+	   record
+	      Component at 0 range 0..31; -- Tag somewhere else,
+                                          -- probably at offset 4.
+	   end record;
+
+	type R is new T and I1 with ...; -- Where is the tag?
+
+Also, some compilers allow the user to specify the location of the tag in
+a tagged record type, and it would seem sensible to be able to specify the
+location of the tag for an interface, in particular if it is used for
+interfacing (pun?) with another language.  We  don't want to *require*
+support for this kind of representation item, but we certainly want  to
+*allow* it.  Say that an implementation wishes to support tag placement
+with the implementation-defined attribute Tag_Offset, and consider:
+
+	type I1 is interface;
+	for I1'Tag_Offset use 0; -- Just an example syntax, could be a
+                                 -- pragma, etc.
+
+	type I2 is interface;
+	for I2'Tag_Offset use 4;
+
+	type R is new I1 and I2 with null record; -- Where is the tag?
+
+What should an implementation do with these examples?  It doesn't make
+sense to reject the representation clauses because that would defeat the
+purpose (remember that the three types could live in three separately
+compiled units).  But obviously there is not consistent layout for type R.
+
+There is currently no rule in the RM that would allow an implementation to
+reject the declaration of type R.  The paragraph that allows an
+implementation to reject a representation item that it doesn't like is
+13.1(13/1) which reads:
+
+"A representation or operational item that is not supported by the
+implementation is illegal, or raises an exception at run time."
+
+This rule assumes that whether a representation item is supported or not
+can be determined in isolation, by looking only at this representation
+item (and possibly at other representation items for the same type).  It's
+not the situation we have here: each representation item is perfectly
+fine, it's their interaction that causes trouble.
+
+In order to deal with this issue, I am proposing to add a post-compilation
+rule to allow an implementation to refuse to produce an executable if it
+encounters representation items that it thinks are somehow inconsistent:
+
+Add after 13.1(13/1)
+
+Post-Compilation Rules
+
+"A set of representation or operational items that, taken together, are
+not supported by the implementation, is rejected prior to running the
+partition."
+
+In practice it's unlikely that implementations would defer the check until
+link-time for the fun of it, so the customary "optimization" of
+post-compilation rule would probably apply, and the declaration of type R
+would be rejected at compilation time.
+
+This solution represents no additional work for implementation that don't
+support nondefault tag placement, and is the more flexible in terms of
+when the actual check is performed for those that do.
+
+Feedback welcome.
+
+*************************************************************
+
+From: Arnaud Charlet
+Sent: Tuesday, August 23, 2005  6:54 AM
+
+> 	type I1 is interface;
+> 	for I1'Tag_Offset use 0; -- Just an example syntax, could be a
+> pragma, etc.
+
+> What should an implementation do with these examples?
+
+Given that the code is using non standard attributes or pragmas, it
+is up to the implementation to define the semantics in this case I would
+say.
+
+> There is currently no rule in the RM that would allow an implementation to
+> reject the declaration of type R.
+
+And that does not seem to be needed within the language as defined in
+the RM.
+
+> In order to deal with this issue, I am proposing to add a post-compilation
+> rule to allow an implementation to refuse to produce an executable if it
+> encounters representation items that it thinks are somehow inconsistent:
+
+That seems fine to add this rule as part of your implementation, but
+I do not see it as needed as part of the Ada 2005 standard.
+Could you explain why would this be needed or what this would bring ?
+
+*************************************************************
+
+From: Erhard Ploedereder
+Sent: Tuesday, August 23, 2005  8:04 AM
+
+note that:
+
+13.1(13/1) which reads:
+"A representation or operational item that is not supported by the
+implementation is illegal, or raises an exception at run time."
+
+and
+
+Add after 13.1(13/1)
+Post-Compilation Rules
+"A set of representation or operational items that, taken together, are
+not supported by the implementation, is rejected prior to running the
+partition."
+
+are in direct contradiction for a set of one. The latter disallows the
+raising of an exception perrmitted by the first one.
+
+Apart from the lawyerly observation...the first one must have, for some
+reason, allowed the raising of an exception because there was no static
+way of deciding. If so, this would likely afflict the second rule as well,
+if written in this generality. (Hence, archeaology required on the 1. rule.)
+
+If not so, the second one could simply replace (for good reason) the first
+one. Lest someone shout: it is NOT an incompatibility to render a program
+illegal that cannot have worked in the first place.
+
+Secondary comment:
+For the problem at hand, a static legality rule would work just fine.
+(I hate "optimized post-compilation rules".)
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, August 23, 2005  8:37 AM
+
+> 13.1(13/1) which reads:
+> "A representation or operational item that is not supported
+> by the implementation is illegal, or raises an exception at run time."
+>
+> and
+>
+> Add after 13.1(13/1)
+> Post-Compilation Rules
+> "A set of representation or operational items that, taken
+> together, are not supported by the implementation, is
+> rejected prior to running the partition."
+>
+> are in direct contradiction for a set of one. The latter
+> disallows the raising of an exception perrmitted by the first one.
+
+Good point.  The second should say "A set of two or more...".
+
+> Apart from the lawyerly observation...the first one must
+> have, for some reason, allowed the raising of an exception
+> because there was no static way of deciding. If so, this
+> would likely afflict the second rule as well, if written in
+> this generality. (Hence, archeaology required on the 1. rule.)
+
+That crossed my mind, and the reason why I didn't include an exception in
+the second rule is that, in the case of a set of two or more
+representation items, it's not at all clear where the exception should be
+raised, and therefore where it could be handled (not that handling these
+exceptions is a great idea, but we want well-defined semantics).  These
+are questions that are best left unanswered.
+
+> Secondary comment:
+> For the problem at hand, a static legality rule would work
+> just fine. (I hate "optimized post-compilation rules".)
+
+It's hard to write a static legality rule that would cover
+implementation-defined attributes/pragmas/whatever.  Furthermore, I was
+concerned that a static legality rule could possibly lead to contract
+model issues.
+
+*************************************************************
+
+From: Bob Duff
+Sent: Tuesday, August 23, 2005  8:38 AM
+
+Erhard said:
+
+> note that:
+>
+> 13.1(13/1) which reads:
+> "A representation or operational item that is not supported by the
+> implementation is illegal, or raises an exception at run time."
+>
+> and
+>
+> Add after 13.1(13/1)
+> Post-Compilation Rules
+> "A set of representation or operational items that, taken together, are
+> not supported by the implementation, is rejected prior to running the
+> partition."
+>
+> are in direct contradiction for a set of one. The latter disallows the
+> raising of an exception perrmitted by the first one.
+
+Good point.
+
+I believe the part about raising an exception is there because some rep
+clauses or pragmas cannot be checked at compile time, because they can
+contain non-static expressions.  Storage_Size comes to mind.
+If you write:
+
+    for T'Storage_Size use Read_From_Keyboard(...);
+
+you can't expect the compiler to detect problems (like request for too
+much memory) before running the program!
+
+Anyway, I think it's important that we understand that this rule has
+nothing to do with implementation-defined pragmas and attributes.
+Implementation-defined pragmas and attributes can violate this rule, or
+in fact *any* language rule.  It just doesn't make any sense to give
+permission to invent pragmas and attributes, without also giving
+permission to invent the rules that apply to them.
+
+*************************************************************
+
+From: Bob Duff
+Sent: Tuesday, August 23, 2005  7:49 AM
+
+> 	type R is new T and I1 with ...; -- Where is the tag?
+
+I agree that an implementation should be allowed to reject this.
+
+I think 13.5.1(21) could reasonably be interpreted to allow such
+rejection:
+
+21    An implementation may reserve a storage place for the tag field of a
+      tagged type, and disallow other components from overlapping that place.
+
+This rule was intended to disallow the rep clause on T.
+(Well, to *allow* that disallowance.  ;-))
+But in Ada 200X, the implementation could allow that clause on T,
+and then say "I reserve offset 0 for the tag of R,"
+and complain because Component overlaps that.
+
+I don't think we need to worry about whether the implementation is
+rejecting T or R, here -- illegal is illegal.  (Even though they might
+be separately compiled.)
+
+We could add an AARM annotation after the above paragraph,
+showing your example.
+
+> Also, some compilers allow the user to specify the location of the tag in
+> a tagged record type, and it would seem sensible to be able to specify the
+> location of the tag for an interface, in particular if it is used for
+> interfacing (pun?) with another language.  We  don't want to *require*
+> support for this kind of representation item, but we certainly want  to
+> *allow* it.  Say that an implementation wishes to support tag placement
+> with the implementation-defined attribute Tag_Offset, and consider:
+...
+
+I think if an implementation invents attributes, it gets to make up the
+rules for those attributes.  So in this case, the implementation can
+*certainly* say R is illegal.  It can choose to say so at compile time
+or link time.  Or even at run time, thought that would be unwise.
+
+We don't need to give special permissions related to implementation
+defined attributes or pragmas.
+
+...
+> This rule assumes that whether a representation item is supported or not
+> can be determined in isolation, by looking only at this representation
+> item (and possibly at other representation items for the same type).  It's
+> not the situation we have here: each representation item is perfectly
+> fine, it's their interaction that causes trouble.
+
+That's true from a compiler-writer's perspective, but I don't think the
+language needs to care whether it's this thing or that thing that's
+illegal, versus the "interaction" between them that's illegal.
+
+> In order to deal with this issue, I am proposing to add a post-compilation
+> rule to allow an implementation to refuse to produce an executable if it
+> encounters representation items that it thinks are somehow inconsistent:
+>
+> Add after 13.1(13/1)
+>
+> Post-Compilation Rules
+>
+> "A set of representation or operational items that, taken together, are
+> not supported by the implementation, is rejected prior to running the
+> partition."
+
+This seems too broad, to me.  If you think we need some permission, I
+think we should make it apply to the very specific case shown by your
+first example (assuming you don't buy my interpretation of 13.5.1(21)).
+The above wording could be taken as permission to disallow all kinds of
+rep clauses, even in the presence of the SP Annex.
+
+I'm quite sure we don't need any wording related to your second example.
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, August 23, 2005  8:30 AM
+
+...
+> This rule was intended to disallow the rep clause on T.
+> (Well, to *allow* that disallowance.  ;-))
+> But in Ada 200X, the implementation could allow that clause
+> on T, and then say "I reserve offset 0 for the tag of R," and
+> complain because Component overlaps that.
+>
+> I don't think we need to worry about whether the
+> implementation is rejecting T or R, here -- illegal is
+> illegal.  (Even though they might be separately compiled.)
+
+You are missing the point.
+
+Say that you have an (Ada 95) implementation that currently supports T.
+Not required, but surely allowed, right?  Now this implementation (and its
+users) want to move to Ada 2005.  Nobody wants to start rejecting T. They
+want to reject R, which is were the logical impossibility arises. I claim
+that there is no rule in the manual that currently allows this.
+
+> I think if an implementation invents attributes, it gets to
+> make up the rules for those attributes.
+
+I disagree. If an implementation claims that an attribute (or a pragma)
+is a representation item, it has to comply with the rules regarding
+representation items, and again there is no rule that says that you can
+reject a declaration because you didn't like some distantly related
+representation item.
+
+Of course, an implementation could say that the attribute is not a
+representation item, but a thingamabob, but that would be
+counter-productive because it would force it to spell out the static and
+dynamic rules for thingamabobs, and it would force the users to learn
+these rules.
+
+*************************************************************
+
+From: Bob Duff
+Sent: Tuesday, August 23, 2005  9:03 AM
+
+> You are missing the point.
+>
+> Say that you have an (Ada 95) implementation that currently supports T.
+> Not required, but surely allowed, right?
+
+Yes.
+
+>...Now this implementation (and its
+> users) want to move to Ada 2005.  Nobody wants to start rejecting T.
+
+An implementation is allowed to start rejecting T.
+But I agree: the implementer probably does not *want* to do so.
+And there is no requirement to do so.
+
+>...They
+> want to reject R, which is were the logical impossibility arises.  I claim
+> that there is no rule in the manual that currently allows this.
+
+What's wrong with my argument that 13.5.1(21) allows the implementation
+to reject programs containing R, but not programs containing T but not R?
+
+The RM shouldn't care whether the error message points to the line of
+code with the rep clause for T, or the line of code declaring R.  In
+fact, a friendly implementation would point to *both* lines.
+
+> > I think if an implementation invents attributes, it gets to
+> > make up the rules for those attributes.
+>
+> I disagree.  If an implementation claims that an attribute (or a pragma)
+> is a representation item, it has to comply with the rules regarding
+> representation items, and again there is no rule that says that you can
+> reject a declaration because you didn't like some distantly related
+> representation item.
+>
+> Of course, an implementation could say that the attribute is not a
+> representation item, but a thingamabob, but that would be
+> counter-productive because it would force it to spell out the static and
+> dynamic rules for thingamabobs, and it would force the users to learn
+> these rules.
+
+An implementation can define an attribute called Tag_Offset,
+and say in its documentation, "This is a representation item,
+except that whenever you use it, you have to obey the following
+rules: (1) every identifier in the program must have at least three
+characters.  (2) No type name can start with the letter 'R'.
+(3) <Some other silly rule.>  (4) You can't inherit from
+an interface that has a different Tag_Offset."
+
+Our job as language designers/maintainers it to promote uniformity for
+the standard features, not to force implementers to design their
+implementation-defined features in a sensible way.
+
+From a practical point of view: How could you write an ACATS test that
+fails implementations that define Tag_Offset in a "wrong" way?
+If you can't test it, then it's not a meaningful rule.
+You can't fail the ACATS because of what's in your implementation's
+documentation!
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, August 23, 2005  10:01 AM
+
+> From a practical point of view: How could you write an ACATS
+> test that fails implementations that define Tag_Offset in a
+> "wrong" way? If you can't test it, then it's not a meaningful
+> rule.
+
+I could certainly write a test based on my first example (the one without
+Tag_Offset).  It would have an OPTIONAL ERROR on the declaration of T (in
+case the implementation doesn't allow the record rep spec) and an OK on
+the declaration of R (because if you allowed T I still don't see on what
+ground you are going to reject R).  And you would have to petition the
+test claiming that you don't know how to support R.  And I would argue
+that there is a perfectly good implementation strategy to deal with this
+(put the tag at offset -4 by default) and that you should change your
+compiler.
+
+> You can't fail the ACATS because of what's in your
+> implementation's documentation!
+
+Ever heard of the Documentation Requirements?
+
+*************************************************************
+
+From: Bob Duff
+Sent: Tuesday, August 23, 2005  10:52 AM
+
+Pascal said:
+
+> > From a practical point of view: How could you write an ACATS
+> > test that fails implementations that define Tag_Offset in a
+> > "wrong" way? If you can't test it, then it's not a meaningful
+> > rule.
+>
+> I could certainly write a test based on my first example (the one without
+> Tag_Offset).
+
+You're mixing up the two examples.  My claim is that you can't test
+alleged rules that apply to *implementation-defined* features: pragmas,
+attributes, non-standard modes.  This has to do with your *second*
+example.
+
+I agree that your *first* example is a testable issue.
+
+>...It would have an OPTIONAL ERROR on the declaration of T (in
+> case the implementation doesn't allow the record rep spec) and an OK on
+> the declaration of R (because if you allowed T I still don't see on what
+> ground you are going to reject R).  And you would have to petition the
+> test claiming that you don't know how to support R.
+
+No, I would base my petition on 13.5.1(21):
+
+21    An implementation may reserve a storage place for the tag field of a
+      tagged type, and disallow other components from overlapping that place.
+
+I would say, "My implementation reserves offset 0 for the tag field of
+R, and your test tries to make a component of R (namely Component)
+overlap that place.  Therefore, your test is wrong."
+
+I would not have to appeal to any difficulty of implementation.
+
+This is the third time I've mentioned 13.5.1(21)!  Please tell
+me specifically what you think of my interpretation of that paragraph!
+I admit, it's a *little* bit of a stretch.  ;-)
+
+(Oh, by the way, my hypothetical implementation would not choose to
+reserve offset 0 for the tag field of T -- just for R.)
+
+>...  And I would argue
+> that there is a perfectly good implementation strategy to deal with this
+> (put the tag at offset -4 by default) and that you should change your
+> compiler.
+
+Hmm, I hadn't thought of *that* implementation.  I was thinking I'd have
+to play the C++ mutiple inheritance game.
+
+> > You can't fail the ACATS because of what's in your
+> > implementation's documentation!
+>
+> Ever heard of the Documentation Requirements?
+
+I've heard of them.  ;-)  They are completely meaningless in any formal
+sense, they are untestable, and they serve to *damage* the quality of
+most implementation's documentation.  To my knowledge, nobody has ever
+failed validation due to what's in their documentation, despite the fact
+that in every implementation I've looked at, the documentation contains
+serious falsehoods, and fails to properly address some of the
+Documentation Requirements.
+
+I claim that if I added this sentence:
+
+    In this implementation, identifiers are limited to 6 characters.
+
+to our documentation, we would not fail validation because of it.
+(So long as the compiler does not limit identifiers to 6 characters,
+of course.)
+
+To summarize my suggestions:
+
+    Your first example may or may not be a real issue.
+    I think an AARM annotation is sufficient, but I wouldn't
+    object to a narrow rule that addresses that specific issue.
+
+    Your second example is not an issue, and we shouldn't waste ink
+    talking about it in the RM.
+
+Note that we agree on the outcome: compilers should be allowed to reject
+both of your examples.  And compilers that choose to reject them can
+also *accept* the examples without the "R".  We're merely arguing about
+whether the RM needs to be changed to make that true, or whether it's
+already true.
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, August 24, 2005  8:01 AM
+
+> I would say, "My implementation reserves offset 0 for the tag
+> field of R, and your test tries to make a component of R
+> (namely Component) overlap that place.  Therefore, your test
+> is wrong."
+
+And if I was running the circus I would say "surely your implementation
+doesn't reserve offset 0 since it didn't reject the record representation
+clause on type T, so you are lying to me; give yourself a slap on the
+hand, and go fix your compiler".
+
+> This is the third time I've mentioned 13.5.1(21)!  Please
+> tell me specifically what you think of my interpretation of
+> that paragraph! I admit, it's a *little* bit of a stretch.  ;-)
+
+13.5.1(21) is an implementation advice regarding the support of record
+representation clauses.  It tells you that you may reject a record
+representation clause because some component overlaps with the storage you
+have reserved for the tag.  In my first example, that mean that you are
+perfectly entitled to reject the representation item for T.
+
+However, I don't see how you could interpret this paragraph as giving you
+a permission to reject a distantly related *type declaration*.  Remember,
+there is no representation item for R, so you have to reject the type
+declaration.  I guess I fail to see how 13.5.1(21) support the logical
+connection between "I put the tag at offset 0" (fine) and "therefore I
+reject R" (huh?).  In terms of logic, this doesn't seem to have more
+justification than, say, "I put the tag at offset 0, therefore I reject
+any tagged record that is not a null record".
+
+I always find it unpleasant when the rules in section 13 cause constructs
+that have nothing to do with representation items to be illegal.  There
+are cases where that has to happen, and this is obviously one of these.
+But I hate the notion that you have to dig an obscure IA to justify
+rejecting a type declaration that looks perfectly good.  Imagine the
+user's puzzlement when they get an error on type R saying "see
+13.5.1(21)".
+
+*************************************************************
+
+From: Bob Duff
+Sent: Wednesday, August 24, 2005  3:17 PM
+
+Pascal said:
+
+> > I would say, "My implementation reserves offset 0 for the tag
+> > field of R, and your test tries to make a component of R
+> > (namely Component) overlap that place.  Therefore, your test
+> > is wrong."
+>
+> And if I was running the circus...
+
+I love that phrase, "if I was running the circus".  I first heard it
+from Steve Baird.  Did he make it up?  ;-)
+
+>... I would say "surely your implementation
+> doesn't reserve offset 0 since it didn't reject the record representation
+> clause on type T, so you are lying to me; give yourself a slap on the
+> hand, and go fix your compiler".
+
+I'm not lying!  My hypothetical implementation reserves offset 0 in R,
+but does not reserve offset 0 in T.  What's wrong with that?
+
+The actual rule my implementation uses is "If a tagged type inherits
+from an interface, offset 0 is reserved for the tag."  13.5.1(21) seems
+to me to allow that -- it doesn't say that I always have to reserve the
+same storage place, or that if I reserve a place for the tag in one type
+I must do so for all types.
+
+I'm astonished that you think this is a lie.  The implementation wants
+to reserve offset 0 for tags of interfaces.  Therefore of course it must
+also reserve offset 0 for anything derived from an interface.  This is
+really the truth -- it's really what's going on in the machine code!
+
+> > This is the third time I've mentioned 13.5.1(21)!  Please
+> > tell me specifically what you think of my interpretation of
+> > that paragraph! I admit, it's a *little* bit of a stretch.  ;-)
+>
+> 13.5.1(21) is an implementation advice regarding the support of record
+> representation clauses.
+
+It's a "recommended level of support", which mutates from impl advice
+into hard rules in the SP annex.  All the rules about which rep clauses
+must be supported, and which need not be supported, are "recommended
+level of support".  If you insist on a new rule forbidding (or allowing
+implementations to forbid) your first example, then I would presume this
+new rule should also be "recommended level of support".
+
+>...  It tells you that you may reject a record
+> representation clause because some component overlaps with the storage you
+> have reserved for the tag.
+
+It doesn't say anything about rejecting rep clauses.  It just says the
+impl can disallow the overlapping.  Your example has overlapping (in R,
+but not in T).
+
+>...  In my first example, that mean that you are
+> perfectly entitled to reject the representation item for T.
+>
+> However, I don't see how you could interpret this paragraph as giving you
+> a permission to reject a distantly related *type declaration*.  Remember,
+> there is no representation item for R, so you have to reject the type
+> declaration.
+
+"Reject" is Ada-83-think.  See 1.1.3(4.a).
+
+There is no requirement that my compiler point to a particular line of
+code, and say that's the one I'm rejecting.
+
+>  I guess I fail to see how 13.5.1(21) support the logical
+> connection between "I put the tag at offset 0" (fine) and "therefore I
+> reject R" (huh?).  In terms of logic, this doesn't seem to have more
+> justification than, say, "I put the tag at offset 0, therefore I reject
+> any tagged record that is not a null record".
+
+21    An implementation may reserve a storage place for the tag field of a
+      tagged type, and disallow other components from overlapping that place.
+
+R is a tagged type.  This rule allows me to reserve offset 0 for the tag
+of R.  You have requested (in your first example) to have a component
+overlapping that place.  (Your request is somewhat indirect -- it's
+inherited from T.)  My hypothetical implementation disallows that
+overlapping -- as we both agree it should.
+
+> I always find it unpleasant when the rules in section 13 cause constructs
+> that have nothing to do with representation items to be illegal.
+
+R is derived from a type whose representation has been specified.
+Why do you think R has "nothing to do with representation items"?
+
+>...There
+> are cases where that has to happen, and this is obviously one of these.
+> But I hate the notion that you have to dig an obscure IA to justify
+> rejecting a type declaration that looks perfectly good.  Imagine the
+> user's puzzlement when they get an error on type R saying "see
+> 13.5.1(21)".
+
+I'm perfectly capable of designing a clear error message for this case,
+and so are you.  But that's got nothing to do with the Ada RM.
+
+
+P.S. I'm trying to think of wording to suggest that will allow
+implementations to disallow your first example.  That's what you want,
+right?  The best I can come up with is:
+
+    If a type is derived from one or more interfaces, then the
+    implementation may reserve a storage place for the tag field.
+    It may disallow other components from overlapping that place,
+    even if the relevant record_representation_clause came from an
+    ancestor type.
+
+But that's just a special case of what 13.5.1(21) already says!
+
+Maybe just adding a NOTE, saying that 13.5.1(21) applies even in cases
+where the rep clause came from an ancestor type?
+
+*************************************************************
+
+From: Stephen W. Baird
+Sent: Wednesday, August 24, 2005  4:22 PM
+
+> I love that phrase, "if I was running the circus".  I first heard it
+> from Steve Baird.  Did he make it up?  ;-)
+
+"If I Ran the Circus" is a book by Dr. Seuss.
+
+See also his discussion of extended character sets, "On Beyond Zebra!".
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Thursday, August 25, 2005  3:33 AM
+
+> It's a "recommended level of support", which mutates from
+> impl advice into hard rules in the SP annex.  All the rules
+> about which rep clauses must be supported, and which need not
+> be supported, are "recommended level of support".
+
+There is no such thing as "hard rules".  The "recommended level of
+support" IA become implementation requirements in annex C.  That's
+reasonably clear from C.2(2).
+
+This is another reason why I don't like 13.5.1(21): what does it mean for
+an IR to say "an implementation may reserve..."?  This doesn't sound like
+a requirement to me.  In fact 13.5.1 has an implementation permissions
+section, and 13.5.1(21) should really go in that section.
+
+> If you
+> insist on a new rule forbidding (or allowing implementations
+> to forbid) your first example, then I would presume this new
+> rule should also be "recommended level of support".
+
+No, it should be an implementation permission.  And it should go in 13.1,
+because it really doesn't have much to do with record representation
+clauses in the first place.
+
+> "Reject" is Ada-83-think.  See 1.1.3(4.a).
+>
+> There is no requirement that my compiler point to a
+> particular line of code, and say that's the one I'm rejecting.
+
+Yeah, give me a break.  1.1.3(4.a) is largely disconnected from reality.
+Try to pass the ACATS with a compiler that prints out '?' when it finds an
+error anywhere in a unit.
+
+>     If a type is derived from one or more interfaces, then the
+>     implementation may reserve a storage place for the tag field.
+>     It may disallow other components from overlapping that place,
+>     even if the relevant record_representation_clause came from an
+>     ancestor type.
+
+I would not want to mention record_representation_clauses explicitly,
+because I believe that other representation items can have the same
+effect.  For instance, say that in my example I remove the
+record_representation_clause and put a pragma Pack (T) instead.  In these
+circumstances, I might choose to allocate only 16 bits for the tag
+(instead of the default 32) because I know that my dispatch tables are all
+gathered together in a small segment of my address space.
+
+This causes the same problem because the interface assumes that the tag
+has the default 32-bit representation, so there is no consistent layout
+for R.
+
+Of course, I am not saying that any of this is required, but we don't want
+the RM to forbid it.
+
+*************************************************************
+
+From: Bob Duff
+Sent: Friday, August 26, 2005  8:26 AM
+
+> > It's a "recommended level of support", which mutates from
+> > impl advice into hard rules in the SP annex.  All the rules
+> > about which rep clauses must be supported, and which need not
+> > be supported, are "recommended level of support".
+>
+> There is no such thing as "hard rules".
+
+By "hard rules", I just mean rules that a conforming implementation has
+to obey, as opposed to mere "impl advice", which is "soft".
+
+>...  The "recommended level of
+> support" IA become implementation requirements in annex C.  That's
+> reasonably clear from C.2(2).
+
+Right.
+
+> This is another reason why I don't like 13.5.1(21): what does it mean for
+> an IR to say "an implementation may reserve..."?  This doesn't sound like
+> a requirement to me.  In fact 13.5.1 has an implementation permissions
+> section, and 13.5.1(21) should really go in that section.
+
+There are many cases like this, and people do seem to find them
+confusing.  It's sort of a double negative or something.
+
+Consider, for example, 13.3(72), which is another example of the same
+thing:
+
+72    An implementation need not support specified Component_Sizes that are
+      less than the Size of the component subtype.
+
+73    An implementation should support specified Component_Sizes that are
+      factors and multiples of the word size. For such Component_Sizes, the
+      array should contain no gaps between components. For other
+      Component_Sizes (if supported), the array should contain no gaps between
+      components when packing is also specified; the implementation should
+      forbid this combination in cases where it cannot support a no-gaps
+      representation.
+
+The reason it's written that way is so that when the SP Annex includes
+these rules by reference, the "need not" part will be included.  If para
+72 were not part of the "recommended levels", then implementations
+conforming to the SP Annex would be required to obey para 73, but would
+have no permission as in para 72, which would be impossible to implement.
+
+I agree this is confusing, but unless we change it everywhere,
+I suggest we stick with this style.
+
+Consider the implementation permission at 13.1(20):
+
+An implementation may place implementation-defined restrictions on
+representation items.
+
+If you conform to the SP annex, you no longer have this permission,
+because it is *not* part of the "recommended levels".
+
+> > If you
+> > insist on a new rule forbidding (or allowing implementations
+> > to forbid) your first example, then I would presume this new
+> > rule should also be "recommended level of support".
+>
+> No, it should be an implementation permission.  And it should go in 13.1,
+> because it really doesn't have much to do with record representation
+> clauses in the first place.
+>
+> > "Reject" is Ada-83-think.  See 1.1.3(4.a).
+> >
+> > There is no requirement that my compiler point to a
+> > particular line of code, and say that's the one I'm rejecting.
+>
+> Yeah, give me a break.
+
+That's not a very language-lawyerly style of debate.  ;-)
+
+>...  1.1.3(4.a) is largely disconnected from reality.
+> Try to pass the ACATS with a compiler that prints out '?' when it finds an
+> error anywhere in a unit.
+
+You'd have to do a lot of splitting of B tests.  People don't do that
+because it's easier to implement good error recovery, and because people
+don't want to make useless compilers.  But I believe such splitting is
+within the validation rules, and certainly conforms to the RM.
+
+> >     If a type is derived from one or more interfaces, then the
+> >     implementation may reserve a storage place for the tag field.
+> >     It may disallow other components from overlapping that place,
+> >     even if the relevant record_representation_clause came from an
+> >     ancestor type.
+>
+> I would not want to mention record_representation_clauses explicitly,
+> because I believe that other representation items can have the same
+> effect.  For instance, say that in my example I remove the
+> record_representation_clause and put a pragma Pack (T) instead.  In these
+> circumstances, I might choose to allocate only 16 bits for the tag
+> (instead of the default 32) because I know that my dispatch tables are all
+> gathered together in a small segment of my address space.
+
+Good point.  You just convinced that the rule should go in 13.1, and
+that it should cover all rep items.  What about pragma Convention?
+I suppose that could cause similar trouble?
+
+But I still think the new rule should be "recommended level", so that it
+gets included by reference in the SP Annex.
+
+Your original suggestion was:
+
+    Add after 13.1(13/1)
+
+    Post-Compilation Rules
+
+    "A set of representation or operational items that, taken together, are
+    not supported by the implementation, is rejected prior to running the
+    partition."
+
+I still don't think that's quite what we want.  Erhard pointed out one
+reason.
+
+Another reason is that the above talks about what *is* supported.  What
+we need to do is *define* what needs to be supported, and what need not
+be supported (if the SP Annex is supported).  Something like this:
+
+    An implementation may disallow a type declaration if it inherits
+    from one or more interfaces, and the representation or operational
+    items that apply to the interfaces, ancestor types, and the type
+    itself, conflict with one another.
+
+    [...AARM example using pragma Pack or pragma Convention...]
+
+I see no reason to make this a post-compilation rule.
+
+> This causes the same problem because the interface assumes that the tag
+> has the default 32-bit representation, so there is no consistent layout
+> for R.
+>
+> Of course, I am not saying that any of this is required, but we don't want
+> the RM to forbid it.
+
+Agreed.
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, August 31, 2005  2:28 AM
+
+> Good point.  You just convinced that the rule should go in
+> 13.1, and that it should cover all rep items.  What about
+> pragma Convention? I suppose that could cause similar trouble?
+
+Yes, I suppose that Convention could have a similar effect.
+
+> Another reason is that the above talks about what *is*
+> supported.  What we need to do is *define* what needs to be
+> supported, and what need not be supported (if the SP Annex is
+> supported).  Something like this:
+>
+>     An implementation may disallow a type declaration if it inherits
+>     from one or more interfaces, and the representation or operational
+>     items that apply to the interfaces, ancestor types, and the type
+>     itself, conflict with one another.
+>
+>     [...AARM example using pragma Pack or pragma Convention...]
+>
+> I see no reason to make this a post-compilation rule.
+
+I think it's only progenitors that can cause trouble.  Furthermore, I
+would not mention the type itself, as I would expect the representation
+items for the type to be rejected, not the type declaration.  So my
+preference would go to something like:
+
+"An implementation may disallow a type_declaration if it has one or more
+progenitors, and the representation or operational items that apply to the
+progenitors and the ancestor types conflict with one another."
+
+Is "may disallow" OK?  Or should it be "need not support"?
+
+Do we have to mention "operational items"?  I don't think so because they
+are not subject to the inheritance rule that apply to representation
+items.
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, August 31, 2005  2:37 PM
+
+...
+> I think it's only progenitors that can cause trouble.  Furthermore, I
+> would not mention the type itself, as I would expect the representation
+> items for the type to be rejected, not the type declaration.  So my
+> preference would go to something like:
+>
+> "An implementation may disallow a type_declaration if it has one or more
+> progenitors, and the representation or operational items that apply to the
+> progenitors and the ancestor types conflict with one another."
+>
+> Is "may disallow" OK?  Or should it be "need not support"?
+>
+> Do we have to mention "operational items"?  I don't think so because they
+> are not subject to the inheritance rule that apply to representation
+> items.
+
+This sounds funny to me.  How could an implementation possibly
+support conflicting aspect items?  Don't we want to *require* that
+such conflicting aspect items be treated as an error, unless the
+conflict can be (and is) resolved by an overriding aspect item?
+To me "conflicting" implies a problem that must be reported.
+I would include operational items for completeness.
+
+I also don't see how this should be something that depends on
+whether the implementation supports the Systems Programming Annex.
+
+It seems this could be described either as a normal legality rule
+(always the best if possible), or as an implementation requirement.
+This rule seems inappropriate for an implementation permission
+or as advice that doesn't become a requirement until you get
+to the SP Annex.
+
+*************************************************************
+
+From: Bob Duff
+Sent: Wednesday, August 31, 2005  5:25 PM
+
+I think you're getting confused by the double-negative nature of
+recommended levels of support that give permission.
+
+I think we need a permission, here, because we don't want to define
+"conflicting".  We want to leave that up to the implementation.  That
+is, we want to allow an implementation to declare certain type_decls
+illegal, based on the *implementation*'s definition of conflicting
+representation items.
+
+We could then add a *requirement* that conflicting rep items cause some
+illegality, but that seems unnecessary.
+
+The point about SP annex is not to make something required, but to allow
+implementations to reject these things.  Implementations that do not
+support the SP annex already have permission to reject anything they
+like.  We just need to make sure the wording does not negate that
+permission for implementations that support the SP annex.
+
+I suppose we could have a legality rule: Conflicting blah blah is
+illegal.  "Conflicting blah blah" is implementation defined.
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, August 31, 2005  11:07 PM
+
+I would prefer something like these latter two sentences.  I believe we
+have gotten ourselves into trouble more than once with the double-negative
+style of implementation permission, and if they confuse us,
+the must be totally impenetrable to the typical user.
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Thursday, September 1, 2005  2:37 AM
+
+> This sounds funny to me.  How could an implementation
+> possibly support conflicting aspect items?  Don't we want to
+> *require* that such conflicting aspect items be treated as an
+> error, unless the conflict can be (and is) resolved by an
+> overriding aspect item? To me "conflicting" implies a problem
+> that must be reported. I would include operational items for
+> completeness.
+
+The only predefined operational items are, as far as I can tell,
+External_Tag and the stream attributes.  Neither of those are inherited:
+External_Tag always gets a default value, and the stream attributes are
+built anew, possibly incorporating the corresponding attribute of the
+parent.  In both cases, there cannot be any conflict.  So if we go for a
+legality rule with a limited scope, we should not permit rejection of
+operational items: we don't want an implementation to argue that there is
+some mysterious conflict that prevents it from supporting some perfectly
+good streaming attributes.
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Thursday, September 1, 2005  2:29 AM
+
+Why don't you try to put some wording together?  It would be nice to have
+something for Randy when he comes back from vacation, after Labor Day.
+
+*************************************************************
+
+From: Bob Duff
+Sent: Monday, September 5, 2005  3:56 PM
+
+How about:
+
+If a type_declaration has one or more progenitors, then any
+representation items that apply to the progenitors and the ancestor
+types shall not conflict with one another.  It is implementation defined
+whether a set of representation items conflict.
+
+*************************************************************
+
+From: Stephen W. Baird
+Sent: Monday, September 5, 2005  4:44 PM
+
+Is it sufficiently clear from this wording that a conflict is possible
+even if no representation items apply to the progenitors?
+
+In this example,
+
+     package Pkg1 is
+       type Ifc is interface;
+
+       type T is tagged record Fld : Integer; end record;
+       for T use record Fld at 0 range 0 .. Integer'Size - 1; end record;
+       -- forces non-default tag location, at least for most implementations
+     end Pkg1;
+
+     with Pkg1;
+     package Pkg2 is
+       type D is new Pkg1.T and Pkg1.Ifc;
+     end Pkg2;
+
+we certainly want an implementation to have the option of rejecting Pkg2,
+even if Pkg1 is accepted.
+
+On the other hand, it would seem very odd to allow the rejection of Pkg2
+if the representation clause in Pkg1 were commented out.
+Do you think that we need to make the distinction between these two cases
+clearer, or that the wording you've suggested already accomplishes this,
+or that the distinction is unimportant?
+
+*************************************************************
+
+From: Bob Duff
+Sent: Monday, September 5, 2005  6:31 PM
+
+> Is it sufficiently clear from this wording that a conflict is possible
+> even if no representation items apply to the progenitors?
+
+No.  :-(
+
+> In this example,
+>
+>      package Pkg1 is
+>        type Ifc is interface;
+>
+>        type T is tagged record Fld : Integer; end record;
+>        for T use record Fld at 0 range 0 .. Integer'Size - 1; end record;
+>        -- forces non-default tag location, at least for most implementations
+>      end Pkg1;
+>
+>      with Pkg1;
+>      package Pkg2 is
+>        type D is new Pkg1.T and Pkg1.Ifc;
+>      end Pkg2;
+>
+> we certainly want an implementation to have the option of rejecting Pkg2,
+> even if Pkg1 is accepted.
+>
+> On the other hand, it would seem very odd to allow the rejection of Pkg2
+> if the representation clause in Pkg1 were commented out.
+
+I agree with all of the above.  Certainly, if there are no rep items in
+sight, the implementation should be required to choose some
+representation that works.  So I guess the point is: a rep item could
+conflict with another rep item, or with a default-chosen rep.  But
+default-chosen reps can't conflict with each other.
+
+With that in mind, let me try again:
+
+A type_declaration is illegal if it has one or more progenitors, and a
+representation item applies to a progenitor or ancestor, and this
+representation item conflicts with the representation of some other
+progenitor or ancestor.  The cases that cause conflicts are
+implementation defined.
+
+AARM examples can make it clear what in the world the above actually
+means in real life.
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, September 6, 2005  2:50 AM
+
+Sounds good to me.
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Monday, September 5, 2005  7:21 PM
+
+> If a type_declaration has one or more progenitors, then any
+> representation items that apply to the progenitors and the ancestor
+> types shall not conflict with one another.  It is implementation defined
+> whether a set of representation items conflict.
+
+can you see a case where the conflicting rep items are all ones that
+are required to be accepted. Pascal's example is crtainly a case
+where the rep clause in question does not have to be accepted.
+
+*************************************************************
+
+From: Bob Duff
+Sent: Monday, September 5, 2005  8:10 PM
+
+Well, I suppose pragma Pack is required to be accepted.
+But it's not required to affect the tag representation.
+As far as I can tell, the only issue is the representation
+of tags -- it has to agree for all progenitors and ancestors
+of a given type.
+
+>... Pascal's example is crtainly a case
+> where the rep clause in question does not have to be accepted.
+
+Right.
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Monday, September 5, 2005  8:31 PM
+
+Right
+
+Can't we just be specific then and say something like
+
+It is implementation defined whether component clauses for
+tagged types are accepted, and if so, what such clauses
+are accepted. In some cases, the acceptance of such a rep
+clause may depend on the presence of other type declarations
+either in the same package or in some different unit.
+An implementation may reject the rep clause, or reject
+some type declaration affected by this rep clause, or
+reject the progran at bind/link time.
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, September 6, 2005  2:57 AM
+
+It's not only component_clauses that cause trouble.  Pragma Pack and
+pragma Convention could conceivably alter the layout of the tag.
+Furthermore, Bob convinced me that there is no point in deferring the
+check to link time when it can always be done at compile time.
+
+I think that Bob's wording is just fine.  It addresses the problem at
+hand, and is specific enough that implementations cannot use it to reject
+any random type_declaration.
+
+We should remember that implementers are not in the business of sabotaging
+their own implementation, so they are unlikely to use this rule to reject
+types that do not cause serious trouble.  At any rate, we should trust the
+hidden hand of the market.
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Tuesday, September 6, 2005  5:39 AM
+
+I think pragma Convention is not a problem (i.e. ok to reject), but to
+me rejecting pragma Pack (or decls depending on it in someway) would
+be non-conforming and should not be allowed.
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Tuesday, September 6, 2005  5:41 AM
+
+> It's not only component_clauses that cause trouble.  Pragma Pack and
+> pragma Convention could conceivably alter the layout of the tag.
+> Furthermore, Bob convinced me that there is no point in deferring the
+> check to link time when it can always be done at compile time.
+
+Actually, I think the permission should extend quite generally to
+any rep clause that is not required to be accepted.
+
+*************************************************************
+
+From: Robert I. Eachus
+Sent: Tuesday, September 6, 2005  9:33 PM
+
+Bob Duff wrote:
+
+>  How about:
+>
+>If a type_declaration has one or more progenitors, then any
+>representation items that apply to the progenitors and the ancestor
+>types shall not conflict with one another.  It is implementation defined
+>whether a set of representation items conflict.
+
+I prefer a wording that starts out closer to the expected problem:
+
+A type declaration is illegal if it inherits one or more conflicting
+representation items from progenitors or ancestor types.  It is
+implementation defined whether a set of representation items conflict.
+
+So far so good. But as I understand the discussion there is another
+sentence needed:
+
+A type-related representation item is not allowed if it conflicts with a
+user-specified representation item inherited from a progenitor or ancestor type.
+
+
+Obviously if this sentence is added to the paragraph, I would put it in
+the middle.  Ancient history now, but anyone else remember that derived
+types were allowed to have different representation specifications to
+support a Steelman requirement?  That requirement is mostly satisfied in
+practice by conversions between unrelated numeric types, and was never
+very useful for enumeration types anyway.
+
+Two further questions:  Are there any operational items that we have to
+worry about here?  The only ones that I can think of that might be an
+issue are 'Read and 'Write, and as I read 13.13.2(8.1/1) those are not
+inherited for tagged types.
+
+Second, do we need to define a recommend level of support here for the
+purposes of Annex C?  If so what should it be?  I think that 13.5.1(22)
+covers the tag location issue.  But do we need to recommend that
+indentical specifications for things like bit-order don't conflict?
+Should we go further and recommend that clauses that place the tag at
+the beginning of a record be considered non-conflicting?  Or just that
+clauses that place the tag in the same place be allowed?  I don't like
+that since it probably takes some work by implementors, when what we
+really want is clauses that place the tag in its normal place for that
+implementation be considered non-conflicting.
+
+*************************************************************
+
+[This thread occurred privately, and then was forwarded later to the ARG list;
+thus it's out of order here. - ED]
+
+From: Javier Miranda
+Sent: Thursday, September 1, 2005  2:47 AM
+
+Pascal,
+
+This is a combined example (based in the examples used in this thread):
+
+>	type I1 is interface;
+>	for I1'Tag_Offset use 0; -- Just an example syntax, could be a pragma, etc.
+>
+>	type I2 is interface;
+>	for I2'Tag_Offset use 4;
+>
+>       type T1 is tagged record
+>          Component : Natural;
+>       end record;
+>       for T1 use record
+>          Component at 0 range 0 .. 31; -- Tag somewhere else, probably at 4
+>       end record;
+>
+>	type R is new T1 and I1 and I2 with null record; -- Where is the tag?
+
+Being interfaces "abstract" types with no data it seems to me wrong to specify
+the position of their tag; they have no data and I only see appropriate the use
+of representation clauses in types containing data.
+
+> ... But obviously there is not consistent layout for type R.
+
+Following this argument there is no conflict; the layout of R should be
+specified after its declaration (which is compatible with existing Ada95 code)
+
+       type R is new I1 and I2 with null record;
+       for  R'Tag_Offset use ...;
+       for I1'Tag_Offset use ...;
+       for I2'Tag_Offset use ...;
+
+> "An implementation may disallow a type_declaration if it has one or more
+> progenitors, and the representation or operational items that apply to
+> the progenitors and the ancestor types conflict with one another."
+
+Following the proposed approach this rule is no longer needed.
+
+*************************************************************
+
+From: Javier Miranda
+Sent: Thursday, September 1, 2005  3:23 AM
+
+I have just detected one bug in my example. Replace:
+
+>        type R is new I1 and I2 with null record;
+>        for  R'Tag_Offset use ...;
+>        for I1'Tag_Offset use ...;
+>        for I2'Tag_Offset use ...;
+
+by
+        type R is new I1 and I2 with null record;
+        for  R'Tag_Offset use ...;
+        for  R.I1'Tag_Offset use ...;
+        for  R.I2'Tag_Offset use ...;
+
+or even better:
+
+        type R is new I1 and I2 with null record;
+        for  R use
+           Tag    at ... range ...;
+           I1'Tag at ... range ...;
+           I2'Tag at ... range ...;
+           ...;
+        end record;
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Wednesday, September 14, 2005  3:04 AM
+
+> Being interfaces "abstract" types with no data it seems to me wrong to specify
+> the position of their tag; they have no data and I only see appropriate the use
+> of representation clauses in types containing data.
+
+These are implementation dependent clauses, so you cannot say "wrong"
+about them!
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Friday, September 2, 2005  3:00 AM
+
+> Being interfaces "abstract" types with no data it seems to me
+> wrong to specify the position of their tag; they have no data
+> and I only see appropriate the use of representation clauses
+> in types containing data.
+
+You are confused by your implementation model, for which presumably the
+Tag_Offset attribute would not make much sense.  In order to ensure C++
+compatibility, you have several tags for each object.  That's fine, but
+this is certainly *not* an implementation model that we want to *require*
+(although of course we want to allow it).  Speaking for IBM Rational, we
+are going to have a single tag for each object (and a number of auxiliary
+data structures for dealing with interfaces).  A single tag is actually
+the model that the ARG had in mind when designing interfaces.  The premise
+was that interfaces should be substantially easier/cheaper to implement
+than full multiple inheritance, and therefore would not need the
+associated runtime baggage.  I am not saying that your implementation is a
+bad idea, but it is rather atypical I think, in the sense that you favored
+compatibility with C++ over other criteria.
+
+So this discussion regarding tag placement is probably only relevant to
+implementations that have a single tag per object.  For such an
+implementation, one reason for wanting the tag at a non-zero offset might
+be to interface with another language/library that has such a requirement.
+Another reason might be for interfacing with a system that doesn't care
+about the location of the tag, but needs it to get "out of the way" (we
+have had that request once).
+
+Note incidentally that, ignoring the tag for a moment, it makes perfect
+sense to specify some representation items for interfaces.  Even though
+there are no values of interface types, there are pieces of code that are
+compiled using only the minimal properties of interfaces.  For instance:
+
+	type Int is interface;
+	for Int'Alignment use 8;
+
+	procedure P (X : Int'Class) is
+	begin
+	   ... -- Take advantage of the alignment of X to generate better
+               -- code here.
+	end;
+
+Evidently, all objects of types descended from Int would have to be 8-byte
+aligned.  Generally speaking interfaces represent a "contract", and that
+contract may include physical properties like the alignment.
+
+> Following this argument there is no conflict; the layout of R
+> should be specified after its declaration (which is
+> compatible with existing Ada95 code). Thus your example would
+> be written as follows:
+>
+>         type R is new I1 and I2 with null record;
+>         for  R'Tag_Offset use ...;
+>         for  R.I1'Tag_Offset use ...;
+>         for  R.I2'Tag_Offset use ...;
+
+This is inventing new syntax (R.I1 is not a valid name in any dialect of
+Ada).  Implementations are not allowed to do that even for
+implementation-defined attributes, and we (the ARG) are not going to do
+that at such a late date, even if this was a good idea, which it isn't.
+
+> or even better:
+>
+>         type R is new I1 and I2 with null record;
+>         for  R use
+>            Tag    at ... range ...;
+>            I1'Tag at ... range ...;
+>            I2'Tag at ... range ...;
+>            ...;
+>         end record;
+
+This is just fine, but again it only makes sense in your implementation
+model.  The rest of us will have a single tag per object.
+
+> Following the proposed approach this rule is no longer needed.
+
+I disagree for the reasons exposed above.  The point is that the RM should
+not disallow specifying the tag location for an implementation that uses a
+single tag per object.  At the moment it does.  This needs fixing.
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Friday, September 2, 2005  5:52 AM
+
+I find this entire discussion confused and muddled by
+implementation models. After all there is no requirement
+that objects have tag fields at all, and there are
+perfectly viable implementation models where there are
+no such fields.
+
+I would completely remove from the RM any attempt to
+talk about details of rep clauses for implementation
+dependent fields. Let an implementation decide what
+it does or does not want to allow here, and don't make
+any attempt to promote portability.
+
+If an implementation accepts a combination of rep clauses
+that results in a blow up, that's a bug!
+
+Javier has started an untracked thread here which seems
+very unfortunate,
+
+Javier, please take care of properly forwarding these
+messages to the arg list.
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Friday, September 2, 2005  6:02 AM
+
+Pascal Leroy wrote:
+>   I am not saying that your implementation is a
+> bad idea, but it is rather atypical I think, in the sense that you favored
+> compatibility with C++ over other criteria.
+
+atypical is a curious word to use for the implementation used
+by far the most Ada programmers, and so far the only available
+implementation of Ada 2005 :-)
+
+And yes indeed, since one of the major purposes of interfaces
+for us is interfacing to other languages, conforming to the C++
+ABI is indeed a requirement for us. We don't think we have users
+for whom better performance than C++ in this respect is a
+requirement, whereas interfacing to C++ is clearly a customer
+requirement.
+
+If our competitors choose to ignore what we think is a very
+important requirement, that's fine with us, but the RM should
+not in any way prefer or suggest one implementation over another.
+Let the marketplace decide, and let implementations do what
+they like here without constraints. Perhaps someone will surprise
+us wit a completely different model that we have not anticipated
+and hich is better than either of the models on the table.
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Saturday, September 3, 2005  2:44 AM
+
+> I find this entire discussion confused and muddled by
+> implementation models. After all there is no requirement that
+> objects have tag fields at all, and there are perfectly
+> viable implementation models where there are no such fields.
+
+This being a chapter 13 issue, implementation models are perfectly
+relevant.  Yes, it is possible to implement tagged types without tag
+fields, but that's not the point.  The point is that an implementation
+should be *allowed* to use an implementation model that has one tag field
+per object.  The RM as written precludes such a model.
+
+> I would completely remove from the RM any attempt to
+> talk about details of rep clauses for implementation
+> dependent fields. Let an implementation decide what
+> it does or does not want to allow here, and don't make
+> any attempt to promote portability.
+>
+> If an implementation accepts a combination of rep clauses
+> that results in a blow up, that's a bug!
+
+I fear that you are missing the point.  The construct that is problematic
+in the case under discussion is not a rep clause, it a type declaration.
+Implementations are allowed to reject rep clauses that they don't like,
+but they don't get to reject type declarations that they don't like.  A
+permission is needed in this particular case.
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Saturday, September 3, 2005  2:52 AM
+
+> atypical is a curious word to use for the implementation used
+> by far the most Ada programmers, and so far the only
+> available implementation of Ada 2005 :-)
+
+The word "atypical" was not intended to imply a value judgment.  However,
+I believe that most the compilers which support interfaces, in whatever
+language, don't use a full-fledged MI model.  In that sense your solution
+is at one extreme of the design space.  That's just a fact, and it's true
+regardless of how many people use your technology, so please don't give me
+the marketing pep talk.
+
+> If our competitors choose to ignore what we think is a very
+> important requirement, that's fine with us, but the RM should
+> not in any way prefer or suggest one implementation over
+> another. Let the marketplace decide, and let implementations
+> do what they like here without constraints.
+
+Agreed.  The point I am arguing is that the RM is currently preventing a
+single-tag-per-object implementation model, and that's just not acceptable
+to me.  If this situation persisted, I would have no qualms about voting
+against the entire Amendment.
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Saturday, September 3, 2005  6:58 AM
+
+Pascal Leroy wrote:
+
+> This being a chapter 13 issue, implementation models are perfectly
+> relevant.  Yes, it is possible to implement tagged types without tag
+> fields, but that's not the point.  The point is that an implementation
+> should be *allowed* to use an implementation model that has one tag field
+> per object.  The RM as written precludes such a model.
+
+I guess I would agree if this can be done without too much
+violence to the current semantic model.
+
+> I fear that you are missing the point.  The construct that is problematic
+> in the case under discussion is not a rep clause, it a type declaration.
+> Implementations are allowed to reject rep clauses that they don't like,
+> but they don't get to reject type declarations that they don't like.  A
+> permission is needed in this particular case.
+
+It's pretty uncomfortsable to have legality in the absence
+of rep clauses be implementation dependent.
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Saturday, September 3, 2005  7:11 AM
+
+...
+> The word "atypical" was not intended to imply a value judgment.  However,
+> I believe that most the compilers which support interfaces, in whatever
+> language, don't use a full-fledged MI model.  In that sense your solution
+> is at one extreme of the design space.  That's just a fact, and it's true
+> regardless of how many people use your technology, so please don't give me
+> the marketing pep talk.
+
+Well, certainly one important Java compiler, gcj, uses
+the c++ abi, precisely for easy interfacing to C++.
+
+> Agreed.  The point I am arguing is that the RM is currently preventing a
+> single-tag-per-object implementation model, and that's just not acceptable
+> to me.  If this situation persisted, I would have no qualms about voting
+> against the entire Amendment.
+
+I am confused, I though that this amendment had
+already been approved by WG 9. Isn't that what the
+line:
+
+!status WG9 Approved 04-06-18
+
+in AI-251 is about?
+
+That being said, I think it reasonable to make an effort to
+accomodate the requirements of one of the few compilers
+attempting to implement the language, but I still do not like
+legality in the absence of rep clauses being impl defined.
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Saturday, September 3, 2005  7:18 AM
+
+> The word "atypical" was not intended to imply a value judgment.  However,
+> I believe that most the compilers which support interfaces, in whatever
+> language, don't use a full-fledged MI model.  In that sense your solution
+> is at one extreme of the design space.  That's just a fact, and it's true
+> regardless of how many people use your technology, so please don't give me
+> the marketing pep talk.
+
+Actually, it seems to me to be a fairly natural choice for
+implementing the interface model as defined in Ada 2005. I
+don't see it as extreme.
+
+(and by the way don't you find it a bit over the top to be
+using terms like atypical and extreme .. I do, these are
+certainly value-laden words better kept out of technical
+discussions :-)
+
+I do see it as reasonable to accomodate the one tag model
+if it can be done without too much difficulty. I must say I
+found the discussion of rep clauses and Tag_Offset confusing,
+since as I think you agree the discussion of impl defined
+attributes and rep clauses cannot by definition be relevant
+to the discussion of what type declarations are legal.
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Monday, September 5, 2005 12:42 AM
+
+> It's pretty uncomfortsable to have legality in the absence
+> of rep clauses be implementation dependent.
+
+Well, there has to be a rep clause somewhere for a problem to arise.  But
+it can be on a distantly-related type.
+
+Anyway I share your discomfort, and that's why I like Bob Duff's notion of
+making the permission very narrow.
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Monday, September 5, 2005 12:46 AM
+
+> I am confused, I though that this amendment had
+> already been approved by WG 9. Isn't that what the
+> line:
+>
+> !status WG9 Approved 04-06-18
+>
+> in AI-251 is about?
+
+Individual AIs have been approved by WG9, but that happened at a time when
+we had not considered the (numerous) interactions between the AIs.  There
+won't be a formal WG9 vote on the totality of the Amendment (including all
+the interactions) before there is a final RM, which is expected to happen
+this fall.  Of course, corrections at this point are of a rather minor
+nature, but they can still have a quite significant impact on
+implementations (that's the case with this representation business).
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Monday, September 5, 2005 12:59 AM
+
+> (and by the way don't you find it a bit over the top to be
+> using terms like atypical and extreme .. I do, these are
+> certainly value-laden words better kept out of technical
+> discussions :-)
+
+You're right.  Apologies for that.
+
+> I do see it as reasonable to accomodate the one tag model
+> if it can be done without too much difficulty. I must say I
+> found the discussion of rep clauses and Tag_Offset confusing,
+> since as I think you agree the discussion of impl defined
+> attributes and rep clauses cannot by definition be relevant
+> to the discussion of what type declarations are legal.
+
+Javier mentioned the Tag_Offset attribute, which is not the interesting
+example, because you can do pretty much what you like with implementation
+defined attributes.  More interesting is the following example, shown in
+my original message.  First, declare an interface without any
+representation item:
+
+	type Int is interface;
+
+The compiler generates code for Int or Int'Class (e.g. dispatching calls)
+assuming that the tag is at offset 0.  Then declare a root tagged type T1
+with a record rep clause that forces a "normal" component to land at
+offset 0:
+
+	type T1 is tagged
+	   record
+	      C : Integer;
+	   end record;
+
+	for T1 use
+	   record
+	      C at 0 range 0..31;
+	   end record;
+
+With this representation clause, presumably the tag is at offset 4.  Of
+course there is no requirement for an implementation to support this rep
+clause, but if it does in Ada 95 (ours does) it would be distinctly
+obnoxious to have to make it illegal in Ada 2005 (that would be an
+unacceptable incompatibility for us).  Now combine Int and T1 as follows:
+
+	type T2 is new T1 and Int with null record;
+
+Int wants the tag at offset 0, but T1 has a user component there, so there
+is no consistent layout for T2.  I claim that an implementation should be
+allowed to reject T2 on the grounds that it pulls together inconsistent
+representation items.  Forcing implementations to either reject the rep
+clause for T1, or to use a full multiple inheritance model, are not
+acceptable options in my view.
+
+*************************************************************
+
+From: Robewrt Dewar
+Sent: Monday, September 5, 2005  3:02 AM
+
+>>It's pretty uncomfortsable to have legality in the absence
+>>of rep clauses be implementation dependent.
+>
+> Well, there has to be a rep clause somewhere for a problem to arise.  But
+> it can be on a distantly-related type.
+
+But isn't this a impl defined rep clause?
+in which case you are allowed to reject the program
+
+it is fine for this rejection to be in the form of rejecting a type
+declaration (the issue of what is rejected is irrelevant from an
+RM point of view, and irrelevant from an ACATS point of view for
+an impl-defined rep clause). If you are saying that you want
+permission to reject a type clause just in case there might be
+such a rep clause, I don't like it. Better just not to allow
+the rep clause, the rejection can be at bind time if necessary.
+
+> Anyway I share your discomfort, and that's why I like Bob Duff's notion of
+> making the permission very narrow.
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Monday, September 5, 2005  3:22 AM
+
+Pascal Leroy wrote:
+
+> Int wants the tag at offset 0, but T1 has a user component there, so there
+> is no consistent layout for T2.  I claim that an implementation should be
+> allowed to reject T2 on the grounds that it pulls together inconsistent
+> representation items.  Forcing implementations to either reject the rep
+> clause for T1, or to use a full multiple inheritance model, are not
+> acceptable options in my view.
+
+There is no requirement that the example program you gave be allowed.
+It can be rejected because of the combined presence of the rep clause
+and the type declaration. To me it is fine if this rejection comes
+in the form of rejecting the type declaration.
+
+Certainly we don't require that implementations accept the rep clause
+you suggest.
+
+I would suggest a rather general permission of the form:
+
+Programs containing rep clauses not required by the RM may be rejected.
+This rejection may be in the form of rejecting the rep clause itself,
+or in the form of rejecting other constructs depending in some way on
+the rep clause in question or in the form of rejection at bind time.
+
+To me this is already implicit in the language definition. I don't
+think we should ever be in the business of saying that you don't need
+to accept some impl defined extension, but if you do then the consequence.
+
+But I have no objection to making some gweneral statement to that
+effect, and in fact making it more general.
+
+For example, I think iot is fine for an implementation to introduce
+a 128-bit integer type that cannot be used for indexing arrays.
+
+Bottom line. A compiler may reject the program you provide.
+How this rejection occurs should not be micromanaged by the RM.
+is that you must accept all programs containing this extension.
+
+*************************************************************
 

Questions? Ask the ACAA Technical Agent