fcl-passrc: resolve multi add without stack

This commit is contained in:
mattias 2021-04-05 10:27:27 +00:00
parent c5a6cca33d
commit 0b2b27559f

View File

@ -10522,6 +10522,9 @@ end;
procedure TPasResolver.ResolveBinaryExpr(El: TBinaryExpr;
Access: TResolvedRefAccess);
var
Left, Next: TPasExpr;
Bin: TBinaryExpr;
begin
{$IFDEF VerbosePasResolver}
//writeln('TPasResolver.ResolveBinaryExpr left=',GetObjName(El.left),' right=',GetObjName(El.right),' opcode=',OpcodeStrings[El.OpCode]);
@ -10548,7 +10551,27 @@ begin
RaiseNotYetImplemented(20160922163456,El);
end;
end;
eopAdd,
eopAdd:
begin
// handle multi add
Left:=El.left;
while (Left.ClassType=TBinaryExpr) do
begin
Bin:=TBinaryExpr(Left);
if Bin.OpCode<>eopAdd then break;
Next:=TBinaryExpr(Left).left;
if Next.Parent<>Left then
RaiseNotYetImplemented(20210321201257,Left);
Left:=Next;
end;
ResolveExpr(Left,rraRead);
repeat
Bin:=TBinaryExpr(Left.Parent);
if Bin.right<>nil then
ResolveExpr(Bin.right,rraRead);
Left:=Bin;
until Left=El;
end;
eopSubtract,
eopMultiply,
eopDivide,
@ -12867,6 +12890,8 @@ procedure TPasResolver.ComputeBinaryExpr(Bin: TBinaryExpr; out
StartEl: TPasElement);
var
LeftResolved, RightResolved: TPasResolverResult;
Left: TPasExpr;
SubBin: TBinaryExpr;
begin
if (Bin.OpCode=eopSubIdent)
or ((Bin.OpCode=eopNone) and (Bin.left is TInheritedExpr)) then
@ -12886,11 +12911,37 @@ begin
exit;
end;
ComputeElement(Bin.left,LeftResolved,Flags-[rcNoImplicitProc],StartEl);
ComputeElement(Bin.right,RightResolved,Flags-[rcNoImplicitProc],StartEl);
// ToDo: check operator overloading
Flags:=Flags-[rcNoImplicitProc,rcNoImplicitProcType];
if Bin.OpCode=eopAdd then
begin
// handle multi-adds without stack
Left:=Bin.left;
while Left.ClassType=TBinaryExpr do
begin
SubBin:=TBinaryExpr(Left);
if SubBin.OpCode<>eopAdd then break;
Left:=SubBin.left;
end;
// Left is now left-most of multi add
ComputeElement(Left,LeftResolved,Flags,StartEl);
repeat
SubBin:=TBinaryExpr(Left.Parent);
ComputeElement(SubBin.right,RightResolved,Flags,StartEl);
ComputeBinaryExprRes(Bin,ResolvedEl,Flags,LeftResolved,RightResolved);
// ToDo: check operator overloading
ComputeBinaryExprRes(SubBin,ResolvedEl,Flags,LeftResolved,RightResolved);
LeftResolved:=ResolvedEl;
Left:=SubBin;
until Left=Bin;
end
else
begin
ComputeElement(Bin.left,LeftResolved,Flags,StartEl);
ComputeElement(Bin.right,RightResolved,Flags,StartEl);
// ToDo: check operator overloading
ComputeBinaryExprRes(Bin,ResolvedEl,Flags,LeftResolved,RightResolved);
end;
end;
procedure TPasResolver.ComputeBinaryExprRes(Bin: TBinaryExpr; out