llvm: support for adding/subtracting constants to pointers in typed constants

Fixes webtbs/tw34027 for llvm
This commit is contained in:
Jonas Maebe 2022-05-28 21:59:12 +02:00
parent 573f2c20d7
commit 70908b1449
3 changed files with 34 additions and 10 deletions

View File

@ -428,10 +428,10 @@ type
function queue_subscriptn_multiple_by_name(def: tabstractrecorddef; const fields: array of TIDString): tdef;
{ queue a type conversion operation }
procedure queue_typeconvn(fromdef, todef: tdef); virtual;
{ queue a add operation }
procedure queue_addn(def: tdef; const index: tconstexprint); virtual;
{ queue a sub operation }
procedure queue_subn(def: tdef; const index: tconstexprint); virtual;
{ queue a pointer add operation }
procedure queue_pointeraddn(def: tpointerdef; const index: tconstexprint); virtual;
{ queue a pointer sub operation }
procedure queue_pointersubn(def: tpointerdef; const index: tconstexprint); virtual;
{ finalise the queue (so a new one can be created) and flush the
previously queued operations, applying them in reverse order on a...}
{ ... procdef }
@ -2107,15 +2107,15 @@ implementation
end;
procedure ttai_typedconstbuilder.queue_addn(def: tdef; const index: tconstexprint);
procedure ttai_typedconstbuilder.queue_pointeraddn(def: tpointerdef; const index: tconstexprint);
begin
inc(fqueue_offset,def.size*int64(index));
inc(fqueue_offset,def.pointeddef.size*int64(index));
end;
procedure ttai_typedconstbuilder.queue_subn(def: tdef; const index: tconstexprint);
procedure ttai_typedconstbuilder.queue_pointersubn(def: tpointerdef; const index: tconstexprint);
begin
dec(fqueue_offset,def.size*int64(index));
dec(fqueue_offset,def.pointeddef.size*int64(index));
end;

View File

@ -106,6 +106,8 @@ interface
procedure emit_dynarray_offset(const ll: tasmlabofs; const arrlength: asizeint; const arrdef: tarraydef; const arrconstdatadef: trecorddef); override;
procedure queue_init(todef: tdef); override;
procedure queue_vecn(def: tdef; const index: tconstexprint); override;
procedure queue_pointeraddn(def: tpointerdef; const index: tconstexprint); override;
procedure queue_pointersubn(def: tpointerdef; const index: tconstexprint); override;
procedure queue_subscriptn(def: tabstractrecorddef; vs: tfieldvarsym); override;
procedure queue_typeconvn(fromdef, todef: tdef); override;
procedure queue_emit_staticvar(vs: tstaticvarsym); override;
@ -671,6 +673,28 @@ implementation
end;
procedure tllvmtai_typedconstbuilder.queue_pointeraddn(def: tpointerdef; const index: tconstexprint);
begin
queue_pointersubn(def, -index);
end;
procedure tllvmtai_typedconstbuilder.queue_pointersubn(def: tpointerdef; const index: tconstexprint);
var
ai: taillvm;
aityped: tai;
begin
{ update range checking info }
inherited;
if index.svalue<>low(int64) then
ai:=taillvm.getelementptr_reg_tai_size_const(NR_NO,nil,ptrsinttype,-index.svalue,false)
else
ai:=taillvm.getelementptr_reg_tai_size_const(NR_NO,nil,ptrsinttype,index.svalue,false);
aityped:=wrap_with_type(ai,def);
update_queued_tai(def,aityped,ai,1);
end;
procedure tllvmtai_typedconstbuilder.queue_subscriptn(def: tabstractrecorddef; vs: tfieldvarsym);
var
getllvmfieldaddr,

View File

@ -952,7 +952,7 @@ function get_next_varsym(def: tabstractrecorddef; const SymList:TFPHashObjectLis
is_constcharnode(taddnode(hp).right) or
is_constboolnode(taddnode(hp).right)) and
is_pointer(taddnode(hp).left.resultdef) then
ftcb.queue_addn(tpointerdef(taddnode(hp).left.resultdef).pointeddef,get_ordinal_value(taddnode(hp).right))
ftcb.queue_pointeraddn(tpointerdef(taddnode(hp).left.resultdef),get_ordinal_value(taddnode(hp).right))
else
Message(parser_e_illegal_expression);
end;
@ -963,7 +963,7 @@ function get_next_varsym(def: tabstractrecorddef; const SymList:TFPHashObjectLis
is_constcharnode(taddnode(hp).right) or
is_constboolnode(taddnode(hp).right)) and
is_pointer(taddnode(hp).left.resultdef) then
ftcb.queue_subn(tpointerdef(taddnode(hp).left.resultdef).pointeddef,get_ordinal_value(taddnode(hp).right))
ftcb.queue_pointersubn(tpointerdef(taddnode(hp).left.resultdef),get_ordinal_value(taddnode(hp).right))
else
Message(parser_e_illegal_expression);
end;