mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 14:27:59 +02:00
* implement sizeof/typeof completely at the node level, based on
loadvmtaddr and vmt_def o give an error when trying to use sizeof on a class/object when targeting the JVM (can't get/load the data size there) git-svn-id: trunk@32764 -
This commit is contained in:
parent
59eff35c5d
commit
8917633199
@ -305,6 +305,12 @@ implementation
|
||||
begin
|
||||
result:=typecheck_new(handled);
|
||||
end;
|
||||
in_sizeof_x:
|
||||
begin
|
||||
{ can't get the size of the data of a class/object }
|
||||
if left.resultdef.typ in [objectdef,classrefdef] then
|
||||
Message(parser_e_illegal_expression);
|
||||
end;
|
||||
end;
|
||||
if not handled then
|
||||
result:=inherited pass_typecheck;
|
||||
|
@ -208,74 +208,9 @@ implementation
|
||||
|
||||
{ second_handle_ the sizeof and typeof routines }
|
||||
procedure tcginlinenode.second_SizeOfTypeOf;
|
||||
var
|
||||
href,
|
||||
hrefvmt : treference;
|
||||
hregister : tregister;
|
||||
begin
|
||||
location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
|
||||
{ for both cases load vmt }
|
||||
if left.nodetype=typen then
|
||||
begin
|
||||
hregister:=hlcg.getaddressregister(current_asmdata.CurrAsmList,voidpointertype);
|
||||
reference_reset_symbol(href,current_asmdata.RefAsmSymbol(tobjectdef(left.resultdef).vmt_mangledname,AT_DATA),0,voidpointertype.size);
|
||||
hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,voidpointertype,voidpointertype,href,hregister);
|
||||
end
|
||||
else
|
||||
begin
|
||||
secondpass(left);
|
||||
hregister:=hlcg.getaddressregister(current_asmdata.CurrAsmList,voidpointertype);
|
||||
|
||||
{ handle self inside a method of a class }
|
||||
case left.location.loc of
|
||||
LOC_CREGISTER,
|
||||
LOC_REGISTER :
|
||||
begin
|
||||
if (left.resultdef.typ=classrefdef) or
|
||||
(po_staticmethod in current_procinfo.procdef.procoptions) then
|
||||
hlcg.a_load_reg_reg(current_asmdata.CurrAsmList,voidpointertype,voidpointertype,left.location.register,hregister)
|
||||
else
|
||||
begin
|
||||
{ load VMT pointer }
|
||||
hlcg.reference_reset_base(hrefvmt,voidpointertype,left.location.register,tobjectdef(left.resultdef).vmt_offset,voidpointertype.size);
|
||||
hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,voidpointertype,voidpointertype,hrefvmt,hregister);
|
||||
end
|
||||
end;
|
||||
LOC_REFERENCE,
|
||||
LOC_CREFERENCE :
|
||||
begin
|
||||
if is_class(left.resultdef) then
|
||||
begin
|
||||
{ deref class }
|
||||
hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,voidpointertype,voidpointertype,left.location.reference,hregister);
|
||||
hlcg.g_maybe_testself(current_asmdata.CurrAsmList,left.resultdef,hregister);
|
||||
{ load VMT pointer }
|
||||
hlcg.reference_reset_base(hrefvmt,voidpointertype,hregister,tobjectdef(left.resultdef).vmt_offset,voidpointertype.size);
|
||||
hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,voidpointertype,voidpointertype,hrefvmt,hregister);
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ load VMT pointer, but not for classrefdefs }
|
||||
if (left.resultdef.typ=objectdef) then
|
||||
begin
|
||||
inc(left.location.reference.offset,tobjectdef(left.resultdef).vmt_offset);
|
||||
left.location.reference.alignment:=newalignment(left.location.reference.alignment,tobjectdef(left.resultdef).vmt_offset);
|
||||
end;
|
||||
hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,voidpointertype,voidpointertype,left.location.reference,hregister);
|
||||
end;
|
||||
end;
|
||||
else
|
||||
internalerror(200301301);
|
||||
end;
|
||||
end;
|
||||
{ in sizeof load size }
|
||||
if inlinenumber=in_sizeof_x then
|
||||
begin
|
||||
hlcg.reference_reset_base(href,voidpointertype,hregister,0,voidpointertype.size);
|
||||
hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
|
||||
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,href,hregister);
|
||||
end;
|
||||
location.register:=hregister;
|
||||
{ handled in pass 1 }
|
||||
internalerror(2015122701);
|
||||
end;
|
||||
|
||||
|
||||
|
@ -3296,6 +3296,7 @@ implementation
|
||||
var
|
||||
hp: tnode;
|
||||
shiftconst: longint;
|
||||
objdef: tobjectdef;
|
||||
|
||||
begin
|
||||
result:=nil;
|
||||
@ -3341,10 +3342,34 @@ implementation
|
||||
in_typeof_x:
|
||||
begin
|
||||
expectloc:=LOC_REGISTER;
|
||||
if (left.nodetype=typen) and
|
||||
(cs_create_pic in current_settings.moduleswitches) and
|
||||
(tf_pic_uses_got in target_info.flags) then
|
||||
include(current_procinfo.flags,pi_needs_got);
|
||||
case left.resultdef.typ of
|
||||
objectdef,classrefdef:
|
||||
begin
|
||||
if left.resultdef.typ=objectdef then
|
||||
begin
|
||||
result:=cloadvmtaddrnode.create(left);
|
||||
objdef:=tobjectdef(left.resultdef);
|
||||
end
|
||||
else
|
||||
begin
|
||||
result:=left;
|
||||
objdef:=tobjectdef(tclassrefdef(left.resultdef).pointeddef);
|
||||
end;
|
||||
left:=nil;
|
||||
if inlinenumber=in_sizeof_x then
|
||||
begin
|
||||
inserttypeconv_explicit(result,cpointerdef.getreusable(objdef.vmt_def));
|
||||
result:=cderefnode.create(result);
|
||||
result:=genloadfield(result,'VINSTANCESIZE');
|
||||
end
|
||||
else
|
||||
inserttypeconv_explicit(result,voidpointertype);
|
||||
end;
|
||||
undefineddef:
|
||||
;
|
||||
else
|
||||
internalerror(2015122702);
|
||||
end;
|
||||
end;
|
||||
|
||||
in_length_x:
|
||||
|
Loading…
Reference in New Issue
Block a user