mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-02 15:52:05 +02:00
* fix tw3930 after r37927
o "unique" class (and interface) type aliases should actually not exist at all except for overload resolution. All the rest (VMT, UUID, RTTI, ...) should be taken from the aliased class/interface o there is one Delphi-incompatibily left after this change, but it shouldn't matter: tw8180 does not compile if you change the declaration to "tcl=class(TInterfacedObject,XStr,iinterface)", while Kylix does compile that. It doesn't really matter though, because in Kylix this actually adds iinterface twice as implemented interface, so there is no point in accepting this. git-svn-id: trunk@46773 -
This commit is contained in:
parent
c45e56bc91
commit
cc315e0ac7
@ -133,6 +133,9 @@ implementation
|
|||||||
{ Skip forward defs }
|
{ Skip forward defs }
|
||||||
if (oo_is_forward in tobjectdef(def).objectoptions) then
|
if (oo_is_forward in tobjectdef(def).objectoptions) then
|
||||||
continue;
|
continue;
|
||||||
|
{ skip unique type aliases, they use the RTTI from the parent class }
|
||||||
|
if tobjectdef(def).is_unique_objpasdef then
|
||||||
|
continue;
|
||||||
write_persistent_type_info(tobjectdef(def).symtable,is_global);
|
write_persistent_type_info(tobjectdef(def).symtable,is_global);
|
||||||
end;
|
end;
|
||||||
procdef :
|
procdef :
|
||||||
|
@ -699,11 +699,16 @@ implementation
|
|||||||
|
|
||||||
function CreateWrapperName(_class : tobjectdef;AImplIntf : TImplementedInterface;i : longint;pd : tprocdef) : string;
|
function CreateWrapperName(_class : tobjectdef;AImplIntf : TImplementedInterface;i : longint;pd : tprocdef) : string;
|
||||||
var
|
var
|
||||||
|
realintfdef: tobjectdef;
|
||||||
tmpstr : AnsiString;
|
tmpstr : AnsiString;
|
||||||
hs : string;
|
hs : string;
|
||||||
crc : DWord;
|
crc : DWord;
|
||||||
begin
|
begin
|
||||||
tmpstr:=_class.objname^+'_$_'+AImplIntf.IntfDef.objname^+'_$_'+tostr(i)+'_$_'+pd.mangledname;
|
realintfdef:=AImplIntf.IntfDef;
|
||||||
|
while realintfdef.is_unique_objpasdef do
|
||||||
|
realintfdef:=realintfdef.childof;
|
||||||
|
|
||||||
|
tmpstr:=_class.objname^+'_$_'+realintfdef.objname^+'_$_'+tostr(i)+'_$_'+pd.mangledname;
|
||||||
if length(tmpstr)>100 then
|
if length(tmpstr)>100 then
|
||||||
begin
|
begin
|
||||||
crc:=0;
|
crc:=0;
|
||||||
@ -749,14 +754,18 @@ implementation
|
|||||||
pd: tprocdef;
|
pd: tprocdef;
|
||||||
siid,
|
siid,
|
||||||
siidstr: tsymstr;
|
siidstr: tsymstr;
|
||||||
|
nonuniqueintf: tobjectdef;
|
||||||
begin
|
begin
|
||||||
|
nonuniqueintf:=AImplIntf.IntfDef;
|
||||||
|
while nonuniqueintf.is_unique_objpasdef do
|
||||||
|
nonuniqueintf:=nonuniqueintf.childof;
|
||||||
tcb.maybe_begin_aggregate(interfaceentrydef);
|
tcb.maybe_begin_aggregate(interfaceentrydef);
|
||||||
{ GUID (or nil for Corba interfaces) }
|
{ GUID (or nil for Corba interfaces) }
|
||||||
tcb.next_field:=tabstractrecorddef(interfaceentrydef).symtable.Find('IIDREF') as tfieldvarsym;
|
tcb.next_field:=tabstractrecorddef(interfaceentrydef).symtable.Find('IIDREF') as tfieldvarsym;
|
||||||
siid:='';
|
siid:='';
|
||||||
if AImplIntf.IntfDef.objecttype in [odt_interfacecom] then
|
if nonuniqueintf.objecttype in [odt_interfacecom] then
|
||||||
begin
|
begin
|
||||||
siid:=make_mangledname('IID',AImplIntf.IntfDef.owner,AImplIntf.IntfDef.objname^);
|
siid:=make_mangledname('IID',nonuniqueintf.owner,nonuniqueintf.objname^);
|
||||||
tcb.emit_tai(Tai_const.Create_sym_offset(
|
tcb.emit_tai(Tai_const.Create_sym_offset(
|
||||||
current_asmdata.RefAsmSymbol(siid,AT_DATA,true),0),cpointerdef.getreusable(rec_tguid));
|
current_asmdata.RefAsmSymbol(siid,AT_DATA,true),0),cpointerdef.getreusable(rec_tguid));
|
||||||
end
|
end
|
||||||
@ -766,7 +775,7 @@ implementation
|
|||||||
{ VTable }
|
{ VTable }
|
||||||
tcb.next_field:=tabstractrecorddef(interfaceentrydef).symtable.Find('VTABLE') as tfieldvarsym;
|
tcb.next_field:=tabstractrecorddef(interfaceentrydef).symtable.Find('VTABLE') as tfieldvarsym;
|
||||||
tcb.queue_init(voidpointertype);
|
tcb.queue_init(voidpointertype);
|
||||||
tcb.queue_emit_asmsym(fintfvtablelabels[intfindex],AImplIntf.VtblImplIntf.IntfDef);
|
tcb.queue_emit_asmsym(fintfvtablelabels[intfindex],nonuniqueintf);
|
||||||
{ IOffset field }
|
{ IOffset field }
|
||||||
case AImplIntf.VtblImplIntf.IType of
|
case AImplIntf.VtblImplIntf.IType of
|
||||||
etFieldValue, etFieldValueClass,
|
etFieldValue, etFieldValueClass,
|
||||||
@ -792,20 +801,20 @@ implementation
|
|||||||
|
|
||||||
{ IIDStr }
|
{ IIDStr }
|
||||||
tcb.next_field:=tabstractrecorddef(interfaceentrydef).symtable.Find('IIDSTRREF') as tfieldvarsym;
|
tcb.next_field:=tabstractrecorddef(interfaceentrydef).symtable.Find('IIDSTRREF') as tfieldvarsym;
|
||||||
siidstr:=make_mangledname('IIDSTR',AImplIntf.IntfDef.owner,AImplIntf.IntfDef.objname^);
|
siidstr:=make_mangledname('IIDSTR',nonuniqueintf.owner,nonuniqueintf.objname^);
|
||||||
tcb.queue_init(cpointerdef.getreusable(cshortstringtype));
|
tcb.queue_init(cpointerdef.getreusable(cshortstringtype));
|
||||||
tcb.queue_emit_asmsym(
|
tcb.queue_emit_asmsym(
|
||||||
current_asmdata.RefAsmSymbol(
|
current_asmdata.RefAsmSymbol(
|
||||||
siidstr,
|
siidstr,
|
||||||
AT_DATA,
|
AT_DATA,
|
||||||
true),
|
true),
|
||||||
cpointerdef.getreusable(carraydef.getreusable(cansichartype,length(AImplIntf.IntfDef.iidstr^)+1)));
|
cpointerdef.getreusable(carraydef.getreusable(cansichartype,length(nonuniqueintf.iidstr^)+1)));
|
||||||
{ IType }
|
{ IType }
|
||||||
tcb.next_field:=tabstractrecorddef(interfaceentrydef).symtable.Find('ITYPE') as tfieldvarsym;
|
tcb.next_field:=tabstractrecorddef(interfaceentrydef).symtable.Find('ITYPE') as tfieldvarsym;
|
||||||
tcb.emit_ord_const(aint(AImplIntf.VtblImplIntf.IType),interfaceentrytypedef);
|
tcb.emit_ord_const(aint(AImplIntf.VtblImplIntf.IType),interfaceentrytypedef);
|
||||||
tcb.maybe_end_aggregate(interfaceentrydef);
|
tcb.maybe_end_aggregate(interfaceentrydef);
|
||||||
|
|
||||||
if findunitsymtable(AImplIntf.IntfDef.owner).moduleid<>findunitsymtable(_Class.owner).moduleid then
|
if findunitsymtable(nonuniqueintf.owner).moduleid<>findunitsymtable(_Class.owner).moduleid then
|
||||||
begin
|
begin
|
||||||
if siid<>'' then
|
if siid<>'' then
|
||||||
current_module.add_extern_asmsym(siid,AB_EXTERNAL,AT_DATA);
|
current_module.add_extern_asmsym(siid,AB_EXTERNAL,AT_DATA);
|
||||||
@ -1300,6 +1309,8 @@ implementation
|
|||||||
if ([df_generic,df_genconstraint]*def.defoptions<>[]) or
|
if ([df_generic,df_genconstraint]*def.defoptions<>[]) or
|
||||||
(oo_is_forward in tobjectdef(def).objectoptions) then
|
(oo_is_forward in tobjectdef(def).objectoptions) then
|
||||||
continue;
|
continue;
|
||||||
|
if tobjectdef(def).is_unique_objpasdef then
|
||||||
|
continue;
|
||||||
do_write_vmts(tobjectdef(def).symtable,is_global);
|
do_write_vmts(tobjectdef(def).symtable,is_global);
|
||||||
{ Write also VMT if not done yet }
|
{ Write also VMT if not done yet }
|
||||||
if not(ds_vmt_written in def.defstates) then
|
if not(ds_vmt_written in def.defstates) then
|
||||||
|
@ -674,7 +674,8 @@ implementation
|
|||||||
gentypename,genorgtypename : TIDString;
|
gentypename,genorgtypename : TIDString;
|
||||||
newtype : ttypesym;
|
newtype : ttypesym;
|
||||||
sym : tsym;
|
sym : tsym;
|
||||||
hdef : tdef;
|
hdef,
|
||||||
|
hdef2 : tdef;
|
||||||
defpos,storetokenpos : tfileposinfo;
|
defpos,storetokenpos : tfileposinfo;
|
||||||
old_block_type : tblock_type;
|
old_block_type : tblock_type;
|
||||||
old_checkforwarddefs: TFPObjectList;
|
old_checkforwarddefs: TFPObjectList;
|
||||||
@ -927,9 +928,11 @@ implementation
|
|||||||
if is_object(hdef) or
|
if is_object(hdef) or
|
||||||
is_class_or_interface_or_dispinterface(hdef) then
|
is_class_or_interface_or_dispinterface(hdef) then
|
||||||
begin
|
begin
|
||||||
{ just create a child class type; this is
|
{ just create a copy that is a child of the original class class type; this is
|
||||||
Delphi-compatible }
|
Delphi-compatible }
|
||||||
hdef:=cobjectdef.create(tobjectdef(hdef).objecttype,genorgtypename,tobjectdef(hdef),true);
|
hdef2:=tstoreddef(hdef).getcopy;
|
||||||
|
tobjectdef(hdef2).childof:=tobjectdef(hdef);
|
||||||
|
hdef:=hdef2;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -959,6 +962,7 @@ implementation
|
|||||||
(tabstractpointerdef(hdef).pointeddef.typ=forwarddef) then
|
(tabstractpointerdef(hdef).pointeddef.typ=forwarddef) then
|
||||||
current_module.checkforwarddefs.add(hdef);
|
current_module.checkforwarddefs.add(hdef);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
include(hdef.defoptions,df_unique);
|
include(hdef.defoptions,df_unique);
|
||||||
end;
|
end;
|
||||||
if not assigned(hdef.typesym) then
|
if not assigned(hdef.typesym) then
|
||||||
@ -1114,7 +1118,7 @@ implementation
|
|||||||
finalize_class_external_status(tobjectdef(hdef));
|
finalize_class_external_status(tobjectdef(hdef));
|
||||||
|
|
||||||
{ Build VMT indexes, skip for type renaming and forward classes }
|
{ Build VMT indexes, skip for type renaming and forward classes }
|
||||||
if (hdef.typesym=newtype) and
|
if not istyperenaming and
|
||||||
not(oo_is_forward in tobjectdef(hdef).objectoptions) then
|
not(oo_is_forward in tobjectdef(hdef).objectoptions) then
|
||||||
build_vmt(tobjectdef(hdef));
|
build_vmt(tobjectdef(hdef));
|
||||||
|
|
||||||
|
@ -511,6 +511,7 @@ interface
|
|||||||
function needs_separate_initrtti : boolean;override;
|
function needs_separate_initrtti : boolean;override;
|
||||||
function has_non_trivial_init_child(check_parent:boolean):boolean;override;
|
function has_non_trivial_init_child(check_parent:boolean):boolean;override;
|
||||||
function rtti_mangledname(rt:trttitype):TSymStr;override;
|
function rtti_mangledname(rt:trttitype):TSymStr;override;
|
||||||
|
function is_unique_objpasdef: boolean;
|
||||||
function vmt_mangledname : TSymStr;
|
function vmt_mangledname : TSymStr;
|
||||||
function vmt_def: trecorddef;
|
function vmt_def: trecorddef;
|
||||||
procedure check_forwards; override;
|
procedure check_forwards; override;
|
||||||
@ -3900,6 +3901,8 @@ implementation
|
|||||||
|
|
||||||
constructor tclassrefdef.create(def:tdef);
|
constructor tclassrefdef.create(def:tdef);
|
||||||
begin
|
begin
|
||||||
|
while tobjectdef(def).is_unique_objpasdef do
|
||||||
|
def:=tobjectdef(def).childof;
|
||||||
inherited create(classrefdef,def);
|
inherited create(classrefdef,def);
|
||||||
if df_specialization in tstoreddef(def).defoptions then
|
if df_specialization in tstoreddef(def).defoptions then
|
||||||
genericdef:=cclassrefdef.create(tstoreddef(def).genericdef);
|
genericdef:=cclassrefdef.create(tstoreddef(def).genericdef);
|
||||||
@ -7890,7 +7893,10 @@ implementation
|
|||||||
begin
|
begin
|
||||||
if not(oo_has_vmt in objectoptions) then
|
if not(oo_has_vmt in objectoptions) then
|
||||||
Message1(parser_n_object_has_no_vmt,objrealname^);
|
Message1(parser_n_object_has_no_vmt,objrealname^);
|
||||||
vmt_mangledname:=make_mangledname('VMT',owner,objname^);
|
if not is_unique_objpasdef then
|
||||||
|
vmt_mangledname:=make_mangledname('VMT',owner,objname^)
|
||||||
|
else
|
||||||
|
vmt_mangledname:=childof.vmt_mangledname;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -7899,13 +7905,18 @@ implementation
|
|||||||
where: tsymtable;
|
where: tsymtable;
|
||||||
vmttypesym: tsymentry;
|
vmttypesym: tsymentry;
|
||||||
begin
|
begin
|
||||||
where:=get_top_level_symtable(true);
|
if not is_unique_objpasdef then
|
||||||
vmttypesym:=where.Find('vmtdef$'+mangledparaname);
|
begin
|
||||||
if not assigned(vmttypesym) or
|
where:=get_top_level_symtable(true);
|
||||||
(vmttypesym.typ<>symconst.typesym) or
|
vmttypesym:=where.Find('vmtdef$'+mangledparaname);
|
||||||
(ttypesym(vmttypesym).typedef.typ<>recorddef) then
|
if not assigned(vmttypesym) or
|
||||||
internalerror(2015052501);
|
(vmttypesym.typ<>symconst.typesym) or
|
||||||
result:=trecorddef(ttypesym(vmttypesym).typedef);
|
(ttypesym(vmttypesym).typedef.typ<>recorddef) then
|
||||||
|
internalerror(2015052501);
|
||||||
|
result:=trecorddef(ttypesym(vmttypesym).typedef);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
result:=childof.vmt_def;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -7971,7 +7982,12 @@ implementation
|
|||||||
function tobjectdef.rtti_mangledname(rt: trttitype): TSymStr;
|
function tobjectdef.rtti_mangledname(rt: trttitype): TSymStr;
|
||||||
begin
|
begin
|
||||||
if not(objecttype in [odt_objcclass,odt_objcprotocol]) then
|
if not(objecttype in [odt_objcclass,odt_objcprotocol]) then
|
||||||
result:=inherited rtti_mangledname(rt)
|
begin
|
||||||
|
if not is_unique_objpasdef then
|
||||||
|
result:=inherited rtti_mangledname(rt)
|
||||||
|
else
|
||||||
|
result:=childof.rtti_mangledname(rt)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
{ necessary in case of a dynamic array of nsobject, or
|
{ necessary in case of a dynamic array of nsobject, or
|
||||||
@ -8054,6 +8070,13 @@ implementation
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function tobjectdef.is_unique_objpasdef: boolean;
|
||||||
|
begin
|
||||||
|
result:=
|
||||||
|
(df_unique in defoptions) and
|
||||||
|
is_class_or_interface_or_dispinterface(self)
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function tobjectdef.members_need_inittable : boolean;
|
function tobjectdef.members_need_inittable : boolean;
|
||||||
begin
|
begin
|
||||||
|
@ -3607,6 +3607,10 @@ implementation
|
|||||||
formalnameptr,
|
formalnameptr,
|
||||||
foundnameptr: pshortstring;
|
foundnameptr: pshortstring;
|
||||||
begin
|
begin
|
||||||
|
while pd.is_unique_objpasdef do
|
||||||
|
begin
|
||||||
|
pd:=pd.childof;
|
||||||
|
end;
|
||||||
{ not a formal definition -> return it }
|
{ not a formal definition -> return it }
|
||||||
if not(oo_is_formal in pd.objectoptions) then
|
if not(oo_is_formal in pd.objectoptions) then
|
||||||
begin
|
begin
|
||||||
|
@ -13,18 +13,63 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TFoo.create;
|
constructor TFoo.create;
|
||||||
begin end;
|
begin
|
||||||
|
writeln('TFoo.create');
|
||||||
|
end;
|
||||||
|
|
||||||
constructor TBaz.create;
|
constructor TBaz.create;
|
||||||
begin end;
|
begin
|
||||||
|
inherited;
|
||||||
|
writeln('TBaz.create');
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
test1tbar: boolean;
|
||||||
|
|
||||||
|
procedure test1(o: TFoo; error: longint); overload;
|
||||||
|
begin
|
||||||
|
writeln('test1 tfoo');
|
||||||
|
o.free;
|
||||||
|
if test1tbar then
|
||||||
|
halt(error);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure test1(o: TBar; error: longint); overload;
|
||||||
|
begin
|
||||||
|
writeln('test1 tbar');
|
||||||
|
o.free;
|
||||||
|
if not test1tbar then
|
||||||
|
halt(error);
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
b: tbar;
|
||||||
begin
|
begin
|
||||||
if not tbar.inheritsfrom(tfoo) then
|
if not tbar.inheritsfrom(tfoo) then
|
||||||
halt(1);
|
begin
|
||||||
|
writeln('error 1');
|
||||||
|
halt(1);
|
||||||
|
end;
|
||||||
if not tbaz.inheritsfrom(tbar) then
|
if not tbaz.inheritsfrom(tbar) then
|
||||||
halt(2);
|
begin
|
||||||
if tbar.classname<>'TBar' then
|
writeln('error 2');
|
||||||
halt(3);
|
halt(2);
|
||||||
|
end;
|
||||||
|
if tbar.classname<>'TFoo' then
|
||||||
|
begin
|
||||||
|
writeln('error 3');
|
||||||
|
halt(3);
|
||||||
|
end;
|
||||||
if tfoo.classname<>'TFoo' then
|
if tfoo.classname<>'TFoo' then
|
||||||
halt(4);
|
begin
|
||||||
|
writeln('error 4');
|
||||||
|
halt(4);
|
||||||
|
end;
|
||||||
|
TBaz.create.free;
|
||||||
|
test1tbar:=false;
|
||||||
|
test1(tfoo.create,5);
|
||||||
|
test1(tbar.create,6);
|
||||||
|
b:=tbar.create;
|
||||||
|
test1tbar:=true;
|
||||||
|
test1(b,7);
|
||||||
end.
|
end.
|
||||||
|
@ -10,7 +10,14 @@ type
|
|||||||
|
|
||||||
var
|
var
|
||||||
x : tcl;
|
x : tcl;
|
||||||
|
p: pointer;
|
||||||
|
i: iunknown;
|
||||||
begin
|
begin
|
||||||
x:=tcl.create;
|
x:=tcl.create;
|
||||||
x._Addref;
|
x._Addref;
|
||||||
|
i:=x as iunknown;
|
||||||
|
if (x as iunknown).queryinterface(xstr,p) <> S_OK then
|
||||||
|
halt(1);
|
||||||
|
if (x as iunknown).queryinterface(iinterface,p) <> S_OK then
|
||||||
|
halt(2);
|
||||||
end.
|
end.
|
||||||
|
Loading…
Reference in New Issue
Block a user