BTW, I don't think you need to create the vtable on the fly in that case. The Pkg.Print function will need a static link, but the vtable doesn't need to encode that. I just checked our Ada compiler. We stopped development on this compiler after Ada 95, but the only change I had to make to your example to make it Ada 95-friendly, was the call to Print: Pkg.Print(Object). (They were avoiding the Object.Function syntax in Ada 95, but I assume they relented and added some syntactic sugar in Ada 2005 or 2012.) Our compiler does indeed generate a static vtable.
Interesting: this indeed works if Main.Pkg.Print calls take a static link, but how can the caller find the static link to pass in the general case? This is obvious in my previous example (the call happens in the same scope that owns the static link), but thanks to type derivation, calls to Main.Pkg.Print can actually appear in other places. For instance: package Base is type T is abstract tagged null record; procedure Print (Self : T) is abstract; procedure Call_Print (Self : T'Class); function Get_Msg return String; end Base; package body Base is procedure Call_Print (Self : T'Class) is begin Print (Self); end Call_Print; function Get_Msg return String is begin return "Hello world"; end Get_Msg; end Base; with Ada.Text_IO; use Ada.Text_IO; with Base; procedure Main is Msg : constant String := Base.Get_Msg; package Pkg is type T is new Base.T with null record; overriding procedure Print (Self : T); end Pkg; package body Pkg is overriding procedure Print (Self : T) is begin Put_Line (Msg); end Print; end Pkg; Object : Pkg.T; begin Base.Call_Print (Object); end Main; Since Main.Pkg.Print overrides a library-level primitive, it can’t take a static link so the only way for it to have access to the Main.Msg local is through Self. I guess a compiler could decide to put the static link in each Main.Pkg.T object rather than in their vtable (and thus have a static vtable), but as far as I can tell, GNAT stores the static link in the vtable instead, so the vtable cannot be static. That looks like the more compelling reason, then. I tried this in our Ada 95 compiler, and it's rejected because of accessibility rules (13.9.1(3)). And it looks like a legit rejection. Those usually are designed to avoid dangling references of access types, but they used the same concept for type extensions (derived tagged types). I don't know if the rationale was to avoid static link issues specifically, or if that was just a happy side effect. But evidently they loosened the rules in a later language revision. BTW, I sure hope objects of Main.Pkg.T cannot escape the invocation of Main! If so, it seems like you're moving into lambda closure territory. Todd
-- Dwarf-discuss mailing list Dwarf-discuss@lists.dwarfstd.org https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss