diff --git a/compiler/packages/fcl-passrc/src/pasresolver.pp b/compiler/packages/fcl-passrc/src/pasresolver.pp index 3e96372..7727493 100644 --- a/compiler/packages/fcl-passrc/src/pasresolver.pp +++ b/compiler/packages/fcl-passrc/src/pasresolver.pp @@ -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