|
@@ -91,6 +91,12 @@ interface
|
|
tllvmshadowsymtable = class;
|
|
tllvmshadowsymtable = class;
|
|
{$endif llvm}
|
|
{$endif llvm}
|
|
|
|
|
|
|
|
+ tmanagementoperator_offset_entry = record
|
|
|
|
+ pd : tprocdef;
|
|
|
|
+ offset : asizeint;
|
|
|
|
+ end;
|
|
|
|
+ pmanagementoperator_offset_entry = ^tmanagementoperator_offset_entry;
|
|
|
|
+
|
|
tabstractrecordsymtable = class(tstoredsymtable)
|
|
tabstractrecordsymtable = class(tstoredsymtable)
|
|
{$ifdef llvm}
|
|
{$ifdef llvm}
|
|
private
|
|
private
|
|
@@ -120,6 +126,10 @@ interface
|
|
function is_packed: boolean;
|
|
function is_packed: boolean;
|
|
function has_single_field(out def:tdef): boolean;
|
|
function has_single_field(out def:tdef): boolean;
|
|
function get_unit_symtable: tsymtable;
|
|
function get_unit_symtable: tsymtable;
|
|
|
|
+ { collects all management operators of the specified type in list (which
|
|
|
|
+ is not cleared); the entries are copies and thus must be freed by the
|
|
|
|
+ caller }
|
|
|
|
+ procedure get_managementoperator_offset_list(mop:tmanagementoperator;list:tfplist);
|
|
protected
|
|
protected
|
|
{ size in bytes including padding }
|
|
{ size in bytes including padding }
|
|
_datasize : asizeint;
|
|
_datasize : asizeint;
|
|
@@ -128,8 +138,12 @@ interface
|
|
databitsize : asizeint;
|
|
databitsize : asizeint;
|
|
{ size in bytes of padding }
|
|
{ size in bytes of padding }
|
|
_paddingsize : word;
|
|
_paddingsize : word;
|
|
|
|
+ { array of tmanagementoperator_offset_entry lists; only assigned if
|
|
|
|
+ they had been queried once by get_management_operator_list }
|
|
|
|
+ mop_list : array[tmanagementoperator] of tfplist;
|
|
procedure setdatasize(val: asizeint);
|
|
procedure setdatasize(val: asizeint);
|
|
function getfieldoffset(sym: tfieldvarsym; base: asizeint; var globalfieldalignment: shortint): asizeint;
|
|
function getfieldoffset(sym: tfieldvarsym; base: asizeint; var globalfieldalignment: shortint): asizeint;
|
|
|
|
+ procedure do_get_managementoperator_offset_list(data:tobject;arg:pointer);
|
|
public
|
|
public
|
|
function iscurrentunit: boolean; override;
|
|
function iscurrentunit: boolean; override;
|
|
property datasize : asizeint read _datasize write setdatasize;
|
|
property datasize : asizeint read _datasize write setdatasize;
|
|
@@ -479,7 +493,6 @@ implementation
|
|
TStoredSymtable
|
|
TStoredSymtable
|
|
*****************************************************************************}
|
|
*****************************************************************************}
|
|
|
|
|
|
-
|
|
|
|
constructor tstoredsymtable.create(const s:string);
|
|
constructor tstoredsymtable.create(const s:string);
|
|
begin
|
|
begin
|
|
inherited create(s);
|
|
inherited create(s);
|
|
@@ -1161,11 +1174,22 @@ implementation
|
|
|
|
|
|
|
|
|
|
destructor tabstractrecordsymtable.destroy;
|
|
destructor tabstractrecordsymtable.destroy;
|
|
|
|
+ var
|
|
|
|
+ mop : tmanagementoperator;
|
|
|
|
+ mopofs : pmanagementoperator_offset_entry;
|
|
|
|
+ i : longint;
|
|
begin
|
|
begin
|
|
{$ifdef llvm}
|
|
{$ifdef llvm}
|
|
if refcount=1 then
|
|
if refcount=1 then
|
|
fllvmst.free;
|
|
fllvmst.free;
|
|
{$endif llvm}
|
|
{$endif llvm}
|
|
|
|
+ for mop in tmanagementoperator do
|
|
|
|
+ begin
|
|
|
|
+ if assigned(mop_list[mop]) then
|
|
|
|
+ for i:=0 to mop_list[mop].count-1 do
|
|
|
|
+ dispose(pmanagementoperator_offset_entry(mop_list[mop][i]));
|
|
|
|
+ mop_list[mop].free;
|
|
|
|
+ end;
|
|
inherited destroy;
|
|
inherited destroy;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -1608,6 +1632,71 @@ implementation
|
|
result:=result.defowner.owner;
|
|
result:=result.defowner.owner;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+
|
|
|
|
+ procedure tabstractrecordsymtable.do_get_managementoperator_offset_list(data:tobject;arg:pointer);
|
|
|
|
+ var
|
|
|
|
+ sym : tsym absolute data;
|
|
|
|
+ fsym : tfieldvarsym absolute data;
|
|
|
|
+ mop : tmanagementoperator absolute arg;
|
|
|
|
+ entry : pmanagementoperator_offset_entry;
|
|
|
|
+ sublist : tfplist;
|
|
|
|
+ i : longint;
|
|
|
|
+ begin
|
|
|
|
+ if sym.typ<>fieldvarsym then
|
|
|
|
+ exit;
|
|
|
|
+ if not is_record(fsym.vardef) and not is_object(fsym.vardef) and not is_cppclass(fsym.vardef) then
|
|
|
|
+ exit;
|
|
|
|
+ if not assigned(mop_list[mop]) then
|
|
|
|
+ internalerror(2018082303);
|
|
|
|
+
|
|
|
|
+ if is_record(fsym.vardef) then
|
|
|
|
+ begin
|
|
|
|
+ if mop in trecordsymtable(trecorddef(fsym.vardef).symtable).managementoperators then
|
|
|
|
+ begin
|
|
|
|
+ new(entry);
|
|
|
|
+ entry^.pd:=search_management_operator(mop,fsym.vardef);
|
|
|
|
+ if not assigned(entry^.pd) then
|
|
|
|
+ internalerror(2018082302);
|
|
|
|
+ entry^.offset:=fsym.fieldoffset;
|
|
|
|
+ mop_list[mop].add(entry);
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ sublist:=tfplist.create;
|
|
|
|
+ tabstractrecordsymtable(tabstractrecorddef(fsym.vardef).symtable).get_managementoperator_offset_list(mop,sublist);
|
|
|
|
+ for i:=0 to sublist.count-1 do
|
|
|
|
+ begin
|
|
|
|
+ entry:=pmanagementoperator_offset_entry(sublist[i]);
|
|
|
|
+ entry^.offset:=entry^.offset+fsym.fieldoffset;
|
|
|
|
+ mop_list[mop].add(entry);
|
|
|
|
+ end;
|
|
|
|
+ { we don't need to remove the entries as they become part of list }
|
|
|
|
+ sublist.free;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ procedure tabstractrecordsymtable.get_managementoperator_offset_list(mop:tmanagementoperator;list:tfplist);
|
|
|
|
+ var
|
|
|
|
+ i : longint;
|
|
|
|
+ entry,entrycopy : pmanagementoperator_offset_entry;
|
|
|
|
+ begin
|
|
|
|
+ if not assigned(list) then
|
|
|
|
+ internalerror(2018082301);
|
|
|
|
+ if mop=mop_none then
|
|
|
|
+ exit;
|
|
|
|
+ if not assigned(mop_list[mop]) then
|
|
|
|
+ begin
|
|
|
|
+ mop_list[mop]:=tfplist.create;
|
|
|
|
+ SymList.ForEachCall(@do_get_managementoperator_offset_list,pointer(ptruint(mop)));
|
|
|
|
+ end;
|
|
|
|
+ for i:=0 to mop_list[mop].count-1 do
|
|
|
|
+ begin
|
|
|
|
+ entry:=pmanagementoperator_offset_entry(mop_list[mop][i]);
|
|
|
|
+ New(entrycopy);
|
|
|
|
+ entrycopy^:=entry^;
|
|
|
|
+ list.add(entrycopy);
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
procedure tabstractrecordsymtable.setdatasize(val: asizeint);
|
|
procedure tabstractrecordsymtable.setdatasize(val: asizeint);
|
|
begin
|
|
begin
|
|
_datasize:=val;
|
|
_datasize:=val;
|