mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-17 04:29:25 +02:00
LazDebuggerFp, FpDebug: Enable watch-eval calling functions with records as param (Win-64/32 / Linux-64)
This commit is contained in:
parent
b014798858
commit
f606986f1b
@ -53,12 +53,14 @@ type
|
||||
FLastError: TFpError;
|
||||
FNextParamRegister: Integer;
|
||||
FOrigStackPtr: TDBGPtr;
|
||||
FPreparedStack: Array of Byte;
|
||||
FNeedStringResInFinalize: Boolean;
|
||||
FStringResultMem: TDBGPtr;
|
||||
|
||||
function AllocStack(ASize: Integer): TDbgPtr;
|
||||
function InternalCreateParamSymbol(ParameterMemLocation: TFpDbgMemLocation; ASymbolType: TFpSymbol; AName: String): TFpValue;
|
||||
function InternalCreateParamSymbol(AParamIndex: Integer; ASymbolType: TFpSymbol; AName: String): TFpValue; inline;
|
||||
function AddRecordParam(var ParamSymbol: TFpValue; AParamSymbolType: TFpSymbol; AValue: TFpValue): Boolean;
|
||||
function InternalAddStringResult: Boolean;
|
||||
public
|
||||
constructor Create(const ABaseContext: TFpDbgLocationContext;
|
||||
@ -67,6 +69,7 @@ type
|
||||
ADbgProcess: TDbgProcess;
|
||||
ADbgThread: TDbgThread);
|
||||
destructor Destroy; override;
|
||||
function WriteStack: Boolean; // called by controller-command
|
||||
|
||||
function CreateParamSymbol(AParamIndex: Integer; ASymbolType: TFpSymbol; AName: String = ''): TFpValue; virtual;
|
||||
|
||||
@ -187,6 +190,148 @@ begin
|
||||
ASymbolType, AName);
|
||||
end;
|
||||
|
||||
function TFpDbgInfoCallContext.AddRecordParam(var ParamSymbol: TFpValue;
|
||||
AParamSymbolType: TFpSymbol; AValue: TFpValue): Boolean;
|
||||
// Only intel/amd
|
||||
function ReadRecFromMem(Addr: TDbgPtr; sz: Integer; out Data: QWord): Boolean;
|
||||
var
|
||||
d: QWord;
|
||||
begin
|
||||
Result := FDbgProcess.ReadData(addr, sz, d);
|
||||
if Result then begin
|
||||
Data := 0;
|
||||
Move(d, Data, sz);
|
||||
end
|
||||
else begin
|
||||
FLastError := CreateError(fpErrAnyError, ['failed to read mem']);
|
||||
end;
|
||||
end;
|
||||
|
||||
function HasUnalignedFields: Boolean;
|
||||
var
|
||||
i: Integer;
|
||||
FldLoc: TFpDbgMemLocation;
|
||||
FldSize: TFpDbgValueSize;
|
||||
RecAddr, FldOffs: TDBGPtr;
|
||||
begin
|
||||
Result := False;
|
||||
RecAddr := AValue.Address.Address;
|
||||
for i := 0 to AValue.MemberCount - 1 do begin
|
||||
FldLoc := AValue.Member[i].Address;
|
||||
Result := FldLoc.BitOffset <> 0;
|
||||
if Result then
|
||||
break;
|
||||
FldOffs := FldLoc.Address - RecAddr;
|
||||
FldSize := AValue.Member[i].DataSize;
|
||||
Result := FldSize.BitSize <> 0;
|
||||
if Result then
|
||||
break;
|
||||
Result := FldOffs mod FldSize.Size <> 0;
|
||||
if Result then
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
RecSize, i: Integer;
|
||||
RecLoc: TFpDbgMemLocation;
|
||||
RecAddr, RecData: TDBGPtr;
|
||||
l: SizeInt;
|
||||
begin
|
||||
HasUnalignedFields;
|
||||
RecSize := SizeToFullBytes(AValue.DataSize);
|
||||
Result := not IsError(AValue.LastError);
|
||||
if Result then begin
|
||||
RecLoc := AValue.Address;
|
||||
Result := IsValidLoc(RecLoc);
|
||||
RecAddr := RecLoc.Address;
|
||||
end;
|
||||
if not Result then begin
|
||||
FLastError := AValue.LastError;
|
||||
exit;
|
||||
end;
|
||||
|
||||
{$IF defined(WINDOWS)}
|
||||
if FDbgProcess.Mode = dm32 then begin
|
||||
if (RecSize <= FDbgProcess.PointerSize) then begin
|
||||
Result := ReadRecFromMem(RecAddr, RecSize, RecData);
|
||||
if not Result then
|
||||
exit;
|
||||
|
||||
l := Length(FPreparedStack);
|
||||
SetLength(FPreparedStack, l + 4);
|
||||
if l > 0 then
|
||||
move(FPreparedStack[0], FPreparedStack[4], SizeOf(FPreparedStack[0]) * l);
|
||||
PDWord(@FPreparedStack[0])^ := RecData;
|
||||
|
||||
dec(FNextParamRegister); // no register used
|
||||
exit;
|
||||
end;
|
||||
|
||||
ParamSymbol.AsCardinal := RecAddr;
|
||||
Result := not IsError(ParamSymbol.LastError);
|
||||
FLastError := ParamSymbol.LastError;
|
||||
end
|
||||
else begin
|
||||
if (RecSize <= FDbgProcess.PointerSize) and (RecSize in [2,4,8]) then begin
|
||||
Result := ReadRecFromMem(RecAddr, RecSize, RecData);
|
||||
RecAddr := RecData;
|
||||
end;
|
||||
|
||||
if Result then begin
|
||||
ParamSymbol.AsCardinal := RecAddr;
|
||||
Result := not IsError(ParamSymbol.LastError);
|
||||
FLastError := ParamSymbol.LastError;
|
||||
end;
|
||||
end;
|
||||
{$ElseIf defined(UNIX)}
|
||||
if FDbgProcess.Mode = dm64 then begin
|
||||
if (RecSize <= 16) and not HasUnalignedFields then begin
|
||||
// Use 1 or 2 registers
|
||||
While RecSize > 0 do begin
|
||||
Result := ReadRecFromMem(RecAddr, Min(8, RecSize), RecData);
|
||||
if not Result then
|
||||
exit;
|
||||
|
||||
ParamSymbol.AsCardinal := RecData;
|
||||
Result := not IsError(ParamSymbol.LastError);
|
||||
if not result then begin
|
||||
FLastError := ParamSymbol.LastError;
|
||||
exit;
|
||||
end;
|
||||
dec(RecSize, 8);
|
||||
inc(RecAddr, 8);
|
||||
if RecSize > 0 then begin
|
||||
inc(FNextParamRegister);
|
||||
ParamSymbol.ReleaseReference;
|
||||
ParamSymbol := InternalCreateParamSymbol(FNextParamRegister, AParamSymbolType, '');
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else begin
|
||||
// on the stack
|
||||
dec(FNextParamRegister); // no register used
|
||||
i := (RecSize+7) and $FFFFFFF8;
|
||||
l := Length(FPreparedStack);
|
||||
SetLength(FPreparedStack, l + i);
|
||||
Result := FDbgProcess.ReadData(RecAddr, RecSize, FPreparedStack[l]);
|
||||
if not Result then begin
|
||||
FLastError := CreateError(fpErrAnyError, ['failed to read mem']);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else begin
|
||||
// 32bit linux
|
||||
Result := False;
|
||||
FLastError := CreateError(fpErrAnyError, ['not supported']);
|
||||
end;
|
||||
{$Else}
|
||||
Result := False;
|
||||
FLastError := CreateError(fpErrAnyError, ['not supported']);
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
function TFpDbgInfoCallContext.InternalAddStringResult: Boolean;
|
||||
var
|
||||
ParamSymbol: TFpValue;
|
||||
@ -227,6 +372,19 @@ begin
|
||||
FDbgThread.SetStackPointerRegisterValue(FOrigStackPtr);
|
||||
end;
|
||||
|
||||
function TFpDbgInfoCallContext.WriteStack: Boolean;
|
||||
var
|
||||
m: TDBGPtr;
|
||||
begin
|
||||
if Length(FPreparedStack) = 0 then
|
||||
exit;
|
||||
|
||||
m := AllocStack(Length(FPreparedStack));
|
||||
Result := FDbgProcess.WriteData(m, Length(FPreparedStack), FPreparedStack[0]);
|
||||
if not Result then
|
||||
FLastError := CreateError(fpErrAnyError, ['failed to read mem']);
|
||||
end;
|
||||
|
||||
function TFpDbgInfoCallContext.CreateParamSymbol(AParamIndex: Integer;
|
||||
ASymbolType: TFpSymbol; AName: String): TFpValue;
|
||||
begin
|
||||
@ -245,7 +403,10 @@ begin
|
||||
if not Result then
|
||||
exit;
|
||||
try
|
||||
ParamSymbol.AsCardinal := AValue.AsCardinal;
|
||||
if AValue.Kind = skRecord then
|
||||
Result := AddRecordParam(ParamSymbol, AParamSymbolType, AValue)
|
||||
else
|
||||
ParamSymbol.AsCardinal := AValue.AsCardinal;
|
||||
Result := not IsError(ParamSymbol.LastError);
|
||||
FLastError := ParamSymbol.LastError;
|
||||
finally
|
||||
|
@ -458,6 +458,8 @@ procedure TDbgControllerCallRoutineCmd.Init;
|
||||
begin
|
||||
inherited Init;
|
||||
|
||||
FCallContext.WriteStack;
|
||||
|
||||
FStep := sSingleStep;
|
||||
StoreInstructionPointer;
|
||||
InsertCallInstructionCode;
|
||||
|
@ -902,7 +902,7 @@ begin
|
||||
end;
|
||||
rk := ExprParamVal.Kind;
|
||||
if not(
|
||||
(rk in [skInteger, {skCurrency,} skPointer, skEnum, skCardinal, skBoolean, skChar, skClass]) or
|
||||
(rk in [skInteger, {skCurrency,} skPointer, skEnum, skCardinal, skBoolean, skChar, skClass, skRecord]) or
|
||||
( (rk in [skString, skAnsiString, skWideString]) and (ExprParamVal.FieldFlags * [svfAddress, svfDataAddress] <> []) )
|
||||
)
|
||||
then begin
|
||||
|
@ -0,0 +1,332 @@
|
||||
program WatchesFuncRecordPrg;
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
uses SysUtils;
|
||||
|
||||
type
|
||||
TNibble = 0..15;
|
||||
|
||||
{$IFDEF RECPAD2}
|
||||
TPad = word;
|
||||
{$ELSE}
|
||||
TPad = byte;
|
||||
{$ENDIF}
|
||||
TRecN2 = {$IFDEF PCKREC} packed {$ENDIF} record {$IFDEF RECPAD1} xxx: TPad; {$ENDIF} a, b: TNibble; end;
|
||||
TRecB2 = {$IFDEF PCKREC} packed {$ENDIF} record {$IFDEF RECPAD1} xxx: TPad; {$ENDIF} a, b: Byte; end;
|
||||
TRecW2 = {$IFDEF PCKREC} packed {$ENDIF} record {$IFDEF RECPAD1} xxx: TPad; {$ENDIF} a, b: Word; end;
|
||||
TRecC2 = {$IFDEF PCKREC} packed {$ENDIF} record {$IFDEF RECPAD1} xxx: TPad; {$ENDIF} a, b: Cardinal; end;
|
||||
TRecQ2 = {$IFDEF PCKREC} packed {$ENDIF} record {$IFDEF RECPAD1} xxx: TPad; {$ENDIF} a, b: QWord; end;
|
||||
TRecB3 = {$IFDEF PCKREC} packed {$ENDIF} record {$IFDEF RECPAD1} xxx: TPad; {$ENDIF} a, b, c: Byte; end;
|
||||
TRecW3 = {$IFDEF PCKREC} packed {$ENDIF} record {$IFDEF RECPAD1} xxx: TPad; {$ENDIF} a, b, c: Word; end;
|
||||
TRecC3 = {$IFDEF PCKREC} packed {$ENDIF} record {$IFDEF RECPAD1} xxx: TPad; {$ENDIF} a, b, c: Cardinal; end;
|
||||
TRecQ3 = {$IFDEF PCKREC} packed {$ENDIF} record {$IFDEF RECPAD1} xxx: TPad; {$ENDIF} a, b, c: QWord; end;
|
||||
TRecQ4 = {$IFDEF PCKREC} packed {$ENDIF} record {$IFDEF RECPAD1} xxx: TPad; {$ENDIF} a, b, c, d: QWord; end;
|
||||
TRecQ5 = {$IFDEF PCKREC} packed {$ENDIF} record {$IFDEF RECPAD1} xxx: TPad; {$ENDIF} a, b, c, d ,e: QWord; end;
|
||||
TRecQ6 = {$IFDEF PCKREC} packed {$ENDIF} record {$IFDEF RECPAD1} xxx: TPad; {$ENDIF} a, b, c, d ,e, f: QWord; end;
|
||||
TRecQ7 = {$IFDEF PCKREC} packed {$ENDIF} record {$IFDEF RECPAD1} xxx: TPad; {$ENDIF} a, b, c, d ,e, f, g: QWord; end;
|
||||
|
||||
var
|
||||
CurMemUsed: ptruint;
|
||||
SomeInt: Integer;
|
||||
|
||||
aRecN2, bRecN2: TRecN2;
|
||||
aRecB2, bRecB2: TRecB2;
|
||||
aRecW2, bRecW2: TRecW2;
|
||||
aRecC2, bRecC2: TRecC2;
|
||||
aRecQ2, bRecQ2: TRecQ2;
|
||||
aRecB3, bRecB3: TRecB3;
|
||||
aRecW3, bRecW3: TRecW3;
|
||||
aRecC3, bRecC3: TRecC3;
|
||||
aRecQ3, bRecQ3: TRecQ3;
|
||||
|
||||
aRecQ4, bRecQ4: TRecQ4;
|
||||
aRecQ5, bRecQ5: TRecQ5;
|
||||
aRecQ6, bRecQ6: TRecQ6;
|
||||
aRecQ7, bRecQ7: TRecQ7;
|
||||
|
||||
|
||||
function TestRecN2_a(AVal: TRecN2): Cardinal; begin Result := AVal.a; AVal.a:=0; end;
|
||||
function TestRecN2_b(AVal: TRecN2): Cardinal; begin Result := AVal.b; AVal.a:=0; end;
|
||||
|
||||
function TestRecB2_a(AVal: TRecB2): Cardinal; begin Result := AVal.a; AVal.a:=0; end;
|
||||
function TestRecB2_b(AVal: TRecB2): Cardinal; begin Result := AVal.b; AVal.a:=0; end;
|
||||
function TestRecB3_a(AVal: TRecB3): Cardinal; begin Result := AVal.a; AVal.a:=0; end;
|
||||
function TestRecB3_b(AVal: TRecB3): Cardinal; begin Result := AVal.b; AVal.a:=0; end;
|
||||
function TestRecB3_c(AVal: TRecB3): Cardinal; begin Result := AVal.c; AVal.a:=0; end;
|
||||
|
||||
function TestRecW2_a(AVal: TRecW2): Cardinal; begin Result := AVal.a; AVal.a:=0; end;
|
||||
function TestRecW2_b(AVal: TRecW2): Cardinal; begin Result := AVal.b; AVal.a:=0; end;
|
||||
function TestRecW3_a(AVal: TRecW3): Cardinal; begin Result := AVal.a; AVal.a:=0; end;
|
||||
function TestRecW3_b(AVal: TRecW3): Cardinal; begin Result := AVal.b; AVal.a:=0; end;
|
||||
function TestRecW3_c(AVal: TRecW3): Cardinal; begin Result := AVal.c; AVal.a:=0; end;
|
||||
|
||||
function TestRecC2_a(AVal: TRecC2): Cardinal; begin Result := AVal.a; AVal.a:=0; end;
|
||||
function TestRecC2_b(AVal: TRecC2): Cardinal; begin Result := AVal.b; AVal.a:=0; end;
|
||||
function TestRecC3_a(AVal: TRecC3): Cardinal; begin Result := AVal.a; AVal.a:=0; end;
|
||||
function TestRecC3_b(AVal: TRecC3): Cardinal; begin Result := AVal.b; AVal.a:=0; end;
|
||||
function TestRecC3_c(AVal: TRecC3): Cardinal; begin Result := AVal.c; AVal.a:=0; end;
|
||||
|
||||
function TestRecQ2_a(AVal: TRecQ2): Cardinal; begin Result := AVal.a; AVal.a:=0; end;
|
||||
function TestRecQ2_b(AVal: TRecQ2): Cardinal; begin Result := AVal.b; AVal.a:=0; end;
|
||||
function TestRecQ3_a(AVal: TRecQ3): Cardinal; begin Result := AVal.a; AVal.a:=0; end;
|
||||
function TestRecQ3_b(AVal: TRecQ3): Cardinal; begin Result := AVal.b; AVal.a:=0; end;
|
||||
function TestRecQ3_c(AVal: TRecQ3): Cardinal; begin Result := AVal.c; AVal.a:=0; end;
|
||||
|
||||
function Test1RecB2(AVal: TRecB2; i: byte): Cardinal; begin if i=0 then Result := AVal.a else Result := AVal.b; AVal.a:=0; end;
|
||||
function Test1RecW2(AVal: TRecW2; i: byte): Cardinal; begin if i=0 then Result := AVal.a else Result := AVal.b; AVal.a:=0; end;
|
||||
function Test1RecC2(AVal: TRecC2; i: byte): Cardinal; begin if i=0 then Result := AVal.a else Result := AVal.b; AVal.a:=0; end;
|
||||
function Test1RecQ2(AVal: TRecQ2; i: byte): Cardinal; begin if i=0 then Result := AVal.a else Result := AVal.b; AVal.a:=0; end;
|
||||
function Test2RecB2(i: word; AVal: TRecB2): Cardinal; begin if i=0 then Result := AVal.a else Result := AVal.b; AVal.a:=0; end;
|
||||
function Test2RecW2(i: word; AVal: TRecW2): Cardinal; begin if i=0 then Result := AVal.a else Result := AVal.b; AVal.a:=0; end;
|
||||
function Test2RecC2(i: word; AVal: TRecC2): Cardinal; begin if i=0 then Result := AVal.a else Result := AVal.b; AVal.a:=0; end;
|
||||
function Test2RecQ2(i: word; AVal: TRecQ2): Cardinal; begin if i=0 then Result := AVal.a else Result := AVal.b; AVal.a:=0; end;
|
||||
|
||||
function TestRecN2N2_1(AVal, BVal: TRecN2): Cardinal; begin Result := AVal.a; AVal.a:=0; end;
|
||||
function TestRecN2N2_2(AVal, BVal: TRecN2): Cardinal; begin Result := BVal.a; AVal.a:=0; end;
|
||||
|
||||
function TestRecB2B2_1(AVal, BVal: TRecB2): Cardinal; begin Result := AVal.a; AVal.a:=0; end;
|
||||
function TestRecB2B2_2(AVal, BVal: TRecB2): Cardinal; begin Result := BVal.a; AVal.a:=0; end;
|
||||
function TestRecW2W2_1(AVal, BVal: TRecW2): Cardinal; begin Result := AVal.a; AVal.a:=0; end;
|
||||
function TestRecW2W2_2(AVal, BVal: TRecW2): Cardinal; begin Result := BVal.a; AVal.a:=0; end;
|
||||
function TestRecC2C2_1(AVal, BVal: TRecC2): Cardinal; begin Result := AVal.a; AVal.a:=0; end;
|
||||
function TestRecC2C2_2(AVal, BVal: TRecC2): Cardinal; begin Result := BVal.a; AVal.a:=0; end;
|
||||
function TestRecQ2Q2_1(AVal, BVal: TRecQ2): Cardinal; begin Result := AVal.a; AVal.a:=0; end;
|
||||
function TestRecQ2Q2_2(AVal, BVal: TRecQ2): Cardinal; begin Result := BVal.a; AVal.a:=0; end;
|
||||
|
||||
function Test1RecB2B2(AVal, BVal: TRecB2; i: byte): Cardinal; begin if i=0 then Result := AVal.a else Result := BVal.a; AVal.a:=0; end;
|
||||
function Test1RecW2W2(AVal, BVal: TRecW2; i: byte): Cardinal; begin if i=0 then Result := AVal.a else Result := BVal.a; AVal.a:=0; end;
|
||||
function Test1RecC2C2(AVal, BVal: TRecC2; i: byte): Cardinal; begin if i=0 then Result := AVal.a else Result := BVal.a; AVal.a:=0; end;
|
||||
function Test1RecQ2Q2(AVal, BVal: TRecQ2; i: byte): Cardinal; begin if i=0 then Result := AVal.a else Result := BVal.a; AVal.a:=0; end;
|
||||
|
||||
function Test2RecB2B2(i: word; AVal, BVal: TRecB2): Cardinal; begin if i=0 then Result := AVal.a else Result := BVal.a; AVal.a:=0; end;
|
||||
function Test2RecW2W2(i: word; AVal, BVal: TRecW2): Cardinal; begin if i=0 then Result := AVal.a else Result := BVal.a; AVal.a:=0; end;
|
||||
function Test2RecC2C2(i: word; AVal, BVal: TRecC2): Cardinal; begin if i=0 then Result := AVal.a else Result := BVal.a; AVal.a:=0; end;
|
||||
function Test2RecQ2Q2(i: word; AVal, BVal: TRecQ2): Cardinal; begin if i=0 then Result := AVal.a else Result := BVal.a; AVal.a:=0; end;
|
||||
|
||||
|
||||
function TestRecB2B3_1(AVal: TRecB2; BVal: TRecB3): Cardinal; begin Result := AVal.a; AVal.a:=0; end;
|
||||
function TestRecB2Q2_1(AVal: TRecB2; BVal: TRecQ2): Cardinal; begin Result := AVal.a; AVal.a:=0; end;
|
||||
function TestRecB3B2_1(AVal: TRecB3; BVal: TRecB2): Cardinal; begin Result := AVal.a; AVal.a:=0; end;
|
||||
function TestRecB3Q2_1(AVal: TRecB3; BVal: TRecQ2): Cardinal; begin Result := AVal.a; AVal.a:=0; end;
|
||||
function TestRecQ2B2_1(AVal: TRecQ2; BVal: TRecB2): Cardinal; begin Result := AVal.a; AVal.a:=0; end;
|
||||
function TestRecQ2B3_1(AVal: TRecQ2; BVal: TRecB3): Cardinal; begin Result := AVal.a; AVal.a:=0; end;
|
||||
|
||||
function TestRecB2B3_2(AVal: TRecB2; BVal: TRecB3): Cardinal; begin Result := BVal.a; AVal.a:=0; end;
|
||||
function TestRecB2Q2_2(AVal: TRecB2; BVal: TRecQ2): Cardinal; begin Result := BVal.a; AVal.a:=0; end;
|
||||
function TestRecB3B2_2(AVal: TRecB3; BVal: TRecB2): Cardinal; begin Result := BVal.a; AVal.a:=0; end;
|
||||
function TestRecB3Q2_2(AVal: TRecB3; BVal: TRecQ2): Cardinal; begin Result := BVal.a; AVal.a:=0; end;
|
||||
function TestRecQ2B2_2(AVal: TRecQ2; BVal: TRecB2): Cardinal; begin Result := BVal.a; AVal.a:=0; end;
|
||||
function TestRecQ2B3_2(AVal: TRecQ2; BVal: TRecB3): Cardinal; begin Result := BVal.a; AVal.a:=0; end;
|
||||
|
||||
function Test1RecB2B3(AVal: TRecB2; BVal: TRecB3; i: byte): Cardinal; begin if i=0 then Result := AVal.a else Result := BVal.a; AVal.a:=0; end;
|
||||
function Test1RecB2Q2(AVal: TRecB2; BVal: TRecQ2; i: byte): Cardinal; begin if i=0 then Result := AVal.a else Result := BVal.a; AVal.a:=0; end;
|
||||
function Test1RecB3B2(AVal: TRecB3; BVal: TRecB2; i: byte): Cardinal; begin if i=0 then Result := AVal.a else Result := BVal.a; AVal.a:=0; end;
|
||||
function Test1RecB3Q2(AVal: TRecB3; BVal: TRecQ2; i: byte): Cardinal; begin if i=0 then Result := AVal.a else Result := BVal.a; AVal.a:=0; end;
|
||||
function Test1RecQ2B2(AVal: TRecQ2; BVal: TRecB2; i: byte): Cardinal; begin if i=0 then Result := AVal.a else Result := BVal.a; AVal.a:=0; end;
|
||||
function Test1RecQ2B3(AVal: TRecQ2; BVal: TRecB3; i: byte): Cardinal; begin if i=0 then Result := AVal.a else Result := BVal.a; AVal.a:=0; end;
|
||||
|
||||
function Test2RecB2B3(i: byte; AVal: TRecB2; BVal: TRecB3): Cardinal; begin if i=0 then Result := AVal.a else Result := BVal.a; AVal.a:=0; end;
|
||||
function Test2RecB2Q2(i: byte; AVal: TRecB2; BVal: TRecQ2): Cardinal; begin if i=0 then Result := AVal.a else Result := BVal.a; AVal.a:=0; end;
|
||||
function Test2RecB3B2(i: byte; AVal: TRecB3; BVal: TRecB2): Cardinal; begin if i=0 then Result := AVal.a else Result := BVal.a; AVal.a:=0; end;
|
||||
function Test2RecB3Q2(i: byte; AVal: TRecB3; BVal: TRecQ2): Cardinal; begin if i=0 then Result := AVal.a else Result := BVal.a; AVal.a:=0; end;
|
||||
function Test2RecQ2B2(i: byte; AVal: TRecQ2; BVal: TRecB2): Cardinal; begin if i=0 then Result := AVal.a else Result := BVal.a; AVal.a:=0; end;
|
||||
function Test2RecQ2B3(i: byte; AVal: TRecQ2; BVal: TRecB3): Cardinal; begin if i=0 then Result := AVal.a else Result := BVal.a; AVal.a:=0; end;
|
||||
|
||||
|
||||
function Test2RecQ3Q3(i: byte; AVal, BVal: TRecQ3): Cardinal;
|
||||
begin
|
||||
case i of
|
||||
0: Result := AVal.a; 1: Result := AVal.c;
|
||||
2: Result := BVal.a; 3: Result := BVal.c;
|
||||
end;
|
||||
AVal.a:=0; BVal.a:=0;
|
||||
end;
|
||||
function Test2RecQ4Q4(i: byte; AVal, BVal: TRecQ4): Cardinal;
|
||||
begin
|
||||
case i of
|
||||
0: Result := AVal.a; 1: Result := AVal.d;
|
||||
2: Result := BVal.a; 3: Result := BVal.d;
|
||||
end;
|
||||
AVal.a:=0; BVal.a:=0;
|
||||
end;
|
||||
function Test2RecQ5Q5(i: byte; AVal, BVal: TRecQ5): Cardinal;
|
||||
begin
|
||||
case i of
|
||||
0: Result := AVal.a; 1: Result := AVal.e;
|
||||
2: Result := BVal.a; 3: Result := BVal.e;
|
||||
end;
|
||||
AVal.a:=0; BVal.a:=0;
|
||||
end;
|
||||
function Test2RecQ6Q6(i: byte; AVal, BVal: TRecQ6): Cardinal;
|
||||
begin
|
||||
case i of
|
||||
0: Result := AVal.a; 1: Result := AVal.f;
|
||||
2: Result := BVal.a; 3: Result := BVal.f;
|
||||
end;
|
||||
AVal.a:=0; BVal.a:=0;
|
||||
end;
|
||||
function Test2RecQ7Q7(i: byte; AVal, BVal: TRecQ7): Cardinal;
|
||||
begin
|
||||
case i of
|
||||
0: Result := AVal.a; 1: Result := AVal.g;
|
||||
2: Result := BVal.a; 3: Result := BVal.g;
|
||||
end;
|
||||
AVal.a:=0; BVal.a:=0;
|
||||
end;
|
||||
|
||||
|
||||
function UsedMem: ptruint;
|
||||
var
|
||||
mm: TMemoryManager;
|
||||
hs: TFPCHeapStatus;
|
||||
begin
|
||||
// ensure global vars are in mem
|
||||
TestRecB2_a(aRecB2); TestRecB2_a(bRecB2);
|
||||
TestRecB3_a(aRecB3); TestRecB3_a(bRecB3);
|
||||
TestRecW2_a(aRecW2); TestRecW2_a(bRecW2);
|
||||
TestRecW3_c(aRecW3); TestRecW3_c(bRecW3);
|
||||
TestRecC2_a(aRecC2); TestRecC2_a(bRecC2);
|
||||
TestRecC3_c(aRecC3); TestRecC3_c(bRecC3);
|
||||
TestRecQ2_a(aRecQ2); TestRecQ2_a(bRecQ2);
|
||||
TestRecQ3_c(aRecQ3); TestRecQ3_c(bRecQ3);
|
||||
|
||||
GetMemoryManager(mm);
|
||||
hs := mm.GetFPCHeapStatus();
|
||||
Result := hs.CurrHeapUsed;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
begin
|
||||
aRecN2.a := 11; aRecN2.b := 12;
|
||||
bRecN2.a := 8; bRecN2.b := 9;
|
||||
|
||||
aRecB2.a := 11; aRecB2.b := 21;
|
||||
aRecW2.a := 12; aRecW2.b := 22;
|
||||
aRecC2.a := 13; aRecC2.b := 23;
|
||||
aRecQ2.a := 14; aRecQ2.b := 24;
|
||||
|
||||
bRecB2.a := 51; bRecB2.b := 61;
|
||||
bRecW2.a := 52; bRecW2.b := 62;
|
||||
bRecC2.a := 53; bRecC2.b := 63;
|
||||
bRecQ2.a := 54; bRecQ2.b := 64;
|
||||
|
||||
aRecB3.a := 15; aRecB3.b := 25; aRecB3.c := 35;
|
||||
aRecW3.a := 16; aRecW3.b := 26; aRecW3.c := 36;
|
||||
aRecC3.a := 17; aRecC3.b := 27; aRecC3.c := 37;
|
||||
aRecQ3.a := 18; aRecQ3.b := 28; aRecQ3.c := 38;
|
||||
|
||||
bRecB3.a := 55; bRecB3.b := 65; bRecB3.c := 75;
|
||||
bRecW3.a := 56; bRecW3.b := 66; bRecW3.c := 76;
|
||||
bRecC3.a := 57; bRecC3.b := 67; bRecC3.c := 77;
|
||||
bRecQ3.a := 58; bRecQ3.b := 68; bRecQ3.c := 78;
|
||||
|
||||
aRecQ4.a := 58; aRecQ4.b := 68; aRecQ4.c := 78; aRecQ4.d := 2;
|
||||
aRecQ5.a := 58; aRecQ5.b := 68; aRecQ5.c := 78; aRecQ5.d := 2; aRecQ5.e := 3;
|
||||
aRecQ6.a := 58; aRecQ6.b := 68; aRecQ6.c := 78; aRecQ6.d := 2; aRecQ6.e := 3; aRecQ6.f := 4;
|
||||
aRecQ7.a := 58; aRecQ7.b := 68; aRecQ7.c := 78; aRecQ7.d := 2; aRecQ7.e := 3; aRecQ7.f := 4; aRecQ7.g := 5;
|
||||
|
||||
bRecQ4.a := 59; bRecQ4.b := 69; bRecQ4.c := 79; bRecQ4.d := 92;
|
||||
bRecQ5.a := 59; bRecQ5.b := 69; bRecQ5.c := 79; bRecQ5.d := 92; bRecQ5.e := 93;
|
||||
bRecQ6.a := 59; bRecQ6.b := 69; bRecQ6.c := 79; bRecQ6.d := 92; bRecQ6.e := 93; bRecQ6.f := 94;
|
||||
bRecQ7.a := 59; bRecQ7.b := 69; bRecQ7.c := 79; bRecQ7.d := 92; bRecQ7.e := 93; bRecQ7.f := 94; bRecQ7.g := 95;
|
||||
|
||||
|
||||
// After each test the debugger can check the memusage
|
||||
CurMemUsed := UsedMem;
|
||||
CurMemUsed := UsedMem; // TEST_BREAKPOINT=main
|
||||
CurMemUsed := UsedMem;
|
||||
CurMemUsed := UsedMem;
|
||||
CurMemUsed := UsedMem;
|
||||
CurMemUsed := UsedMem;
|
||||
CurMemUsed := UsedMem;
|
||||
CurMemUsed := UsedMem;
|
||||
|
||||
|
||||
TestRecN2_a(aRecN2);
|
||||
TestRecN2_b(bRecN2);
|
||||
|
||||
TestRecB2_a(aRecB2);
|
||||
TestRecB2_b(bRecB2);
|
||||
TestRecB3_a(aRecB3);
|
||||
TestRecB3_b(aRecB3);
|
||||
TestRecB3_c(bRecB3);
|
||||
|
||||
TestRecW2_a(aRecW2);
|
||||
TestRecW2_b(bRecW2);
|
||||
TestRecW3_a(aRecW3);
|
||||
TestRecW3_b(aRecW3);
|
||||
TestRecW3_c(bRecW3);
|
||||
|
||||
TestRecC2_a(aRecC2);
|
||||
TestRecC2_b(bRecC2);
|
||||
TestRecC3_a(aRecC3);
|
||||
TestRecC3_b(aRecC3);
|
||||
TestRecC3_c(bRecC3);
|
||||
|
||||
TestRecQ2_a(aRecQ2);
|
||||
TestRecQ2_b(bRecQ2);
|
||||
TestRecQ3_a(aRecQ3);
|
||||
TestRecQ3_b(aRecQ3);
|
||||
TestRecQ3_c(bRecQ3);
|
||||
|
||||
|
||||
Test1RecB2(aRecB2,1);
|
||||
Test1RecW2(bRecW2,1);
|
||||
Test1RecC2(aRecC2,1);
|
||||
Test1RecQ2(aRecQ2,1);
|
||||
|
||||
Test2RecB2(1, aRecB2);
|
||||
Test2RecW2(1, bRecW2);
|
||||
Test2RecC2(1, aRecC2);
|
||||
Test2RecQ2(1, aRecQ2);
|
||||
|
||||
TestRecN2N2_1(aRecN2, bRecN2); TestRecN2N2_2(aRecN2, bRecN2);
|
||||
|
||||
TestRecB2B2_1(aRecB2, bRecB2); TestRecB2B2_2(aRecB2, bRecB2);
|
||||
TestRecW2W2_1(aRecW2, bRecW2); TestRecW2W2_2(aRecW2, bRecW2);
|
||||
TestRecC2C2_1(aRecC2, bRecC2); TestRecC2C2_2(aRecC2, bRecC2);
|
||||
TestRecQ2Q2_1(aRecQ2, bRecQ2); TestRecQ2Q2_2(aRecQ2, bRecQ2);
|
||||
|
||||
Test1RecB2B2(aRecB2, bRecB2,1);
|
||||
Test1RecW2W2(aRecW2, bRecW2,1);
|
||||
Test1RecC2C2(aRecC2, bRecC2,1);
|
||||
Test1RecQ2Q2(aRecQ2, bRecQ2,1);
|
||||
|
||||
Test2RecB2B2(1,aRecB2, bRecB2);
|
||||
Test2RecW2W2(1,aRecW2, bRecW2);
|
||||
Test2RecC2C2(1,aRecC2, bRecC2);
|
||||
Test2RecQ2Q2(1,aRecQ2, bRecQ2);
|
||||
|
||||
|
||||
TestRecB2B3_1(aRecB2, bRecB3); TestRecB2B3_2(aRecB2, bRecB3);
|
||||
TestRecB2Q2_1(aRecB2, bRecQ2); TestRecB2Q2_2(aRecB2, bRecQ2);
|
||||
TestRecB3B2_1(aRecB3, bRecB2); TestRecB3B2_2(aRecB3, bRecB2);
|
||||
TestRecB3Q2_1(aRecB3, bRecQ2); TestRecB3Q2_2(aRecB3, bRecQ2);
|
||||
TestRecQ2B2_1(aRecQ2, bRecB2); TestRecQ2B2_2(aRecQ2, bRecB2);
|
||||
TestRecQ2B3_1(aRecQ2, bRecB3); TestRecQ2B3_2(aRecQ2, bRecB3);
|
||||
|
||||
Test1RecB2B3(aRecB2, bRecB3, 1);
|
||||
Test1RecB2Q2(aRecB2, bRecQ2, 1);
|
||||
Test1RecB3B2(aRecB3, bRecB2, 1);
|
||||
Test1RecB3Q2(aRecB3, bRecQ2, 1);
|
||||
Test1RecQ2B2(aRecQ2, bRecB2, 1);
|
||||
Test1RecQ2B3(aRecQ2, bRecB3, 1);
|
||||
|
||||
Test2RecB2B3(1, aRecB2, bRecB3);
|
||||
Test2RecB2Q2(1, aRecB2, bRecQ2);
|
||||
Test2RecB3B2(1, aRecB3, bRecB2);
|
||||
Test2RecB3Q2(1, aRecB3, bRecQ2);
|
||||
Test2RecQ2B2(1, aRecQ2, bRecB2);
|
||||
Test2RecQ2B3(1, aRecQ2, bRecB3);
|
||||
|
||||
Test2RecQ3Q3(1, aRecQ3, bRecQ3);
|
||||
Test2RecQ4Q4(1, aRecQ4, bRecQ4);
|
||||
Test2RecQ5Q5(1, aRecQ5, bRecQ5);
|
||||
Test2RecQ6Q6(1, aRecQ6, bRecQ6);
|
||||
Test2RecQ7Q7(1, aRecQ7, bRecQ7);
|
||||
|
||||
|
||||
end.
|
@ -26,6 +26,7 @@ type
|
||||
procedure TestWatchesValue;
|
||||
procedure TestWatchesFunctions;
|
||||
procedure TestWatchesFunctionsWithString;
|
||||
procedure TestWatchesFunctionsWithRecord;
|
||||
procedure TestWatchesAddressOf;
|
||||
procedure TestWatchesTypeCast;
|
||||
procedure TestWatchesExpression;
|
||||
@ -37,7 +38,8 @@ implementation
|
||||
|
||||
var
|
||||
ControlTestWatch, ControlTestWatchScope, ControlTestWatchValue, ControlTestWatchFunct,
|
||||
ControlTestWatchFunctStr, ControlTestWatchAddressOf, ControlTestWatchTypeCast, ControlTestModify,
|
||||
ControlTestWatchFunctStr, ControlTestWatchFunctRec,
|
||||
ControlTestWatchAddressOf, ControlTestWatchTypeCast, ControlTestModify,
|
||||
ControlTestExpression, ControlTestErrors: Pointer;
|
||||
|
||||
procedure TTestWatches.RunToPause(var ABrk: TDBGBreakPoint;
|
||||
@ -1693,6 +1695,283 @@ begin
|
||||
|
||||
end;
|
||||
|
||||
procedure TTestWatches.TestWatchesFunctionsWithRecord;
|
||||
var
|
||||
ExeName, tbn: String;
|
||||
t: TWatchExpectationList;
|
||||
Src: TCommonSource;
|
||||
BrkPrg: TDBGBreakPoint;
|
||||
i, p: Integer;
|
||||
begin
|
||||
if SkipTest then exit;
|
||||
if not TestControlCanTest(ControlTestWatchFunctRec) then exit;
|
||||
//if not (Compiler.SymbolType in [stDwarf3, stDwarf4]) then exit;
|
||||
//if Compiler.HasFlag('SkipStringFunc') then exit;
|
||||
tbn := TestBaseName;
|
||||
|
||||
try
|
||||
for p := 0 to 3 do
|
||||
for i := 0 to 2 do begin
|
||||
TestBaseName := tbn;
|
||||
TestBaseName := TestBaseName + ' -O'+IntToStr(i) + ' (def: ' + IntToStr(p) + ')';
|
||||
|
||||
Src := GetCommonSourceFor(AppDir + 'WatchesFuncRecordPrg.pas');
|
||||
case p of
|
||||
0: case i of
|
||||
0: TestCompile(Src, ExeName, '_O0', '-O-');
|
||||
1: TestCompile(Src, ExeName, '_O1', '-O-1');
|
||||
2: TestCompile(Src, ExeName, '_O2', '-O-2');
|
||||
end;
|
||||
1: case i of
|
||||
0: TestCompile(Src, ExeName, '_O0_pack', '-dPCKREC -O-');
|
||||
1: TestCompile(Src, ExeName, '_O1_pack', '-dPCKREC -O-1');
|
||||
2: TestCompile(Src, ExeName, '_O2_pack', '-dPCKREC -O-2');
|
||||
end;
|
||||
2: case i of
|
||||
0: TestCompile(Src, ExeName, '_O0_pack_padbyte', '-dPCKREC -dRECPAD1 -O-');
|
||||
1: TestCompile(Src, ExeName, '_O1_pack_padbyte', '-dPCKREC -dRECPAD1 -O-1');
|
||||
2: TestCompile(Src, ExeName, '_O2_pack_padbyte', '-dPCKREC -dRECPAD1 -O-2');
|
||||
end;
|
||||
3: case i of
|
||||
0: TestCompile(Src, ExeName, '_O0_pack_padword', '-dPCKREC -dRECPAD1 -dRECPAD2 -O-');
|
||||
1: TestCompile(Src, ExeName, '_O1_pack_padword', '-dPCKREC -dRECPAD1 -dRECPAD2 -O-1');
|
||||
2: TestCompile(Src, ExeName, '_O2_pack_padword', '-dPCKREC -dRECPAD1 -dRECPAD2 -O-2');
|
||||
end;
|
||||
end;
|
||||
|
||||
t := nil;
|
||||
|
||||
AssertTrue('Start debugger', Debugger.StartDebugger(AppDir, ExeName));
|
||||
|
||||
try
|
||||
t := TWatchExpectationList.Create(Self);
|
||||
t.AcceptSkSimple := [skInteger, skCardinal, skBoolean, skChar, skFloat,
|
||||
skString, skAnsiString, skCurrency, skVariant, skWideString,
|
||||
skInterface, skEnumValue];
|
||||
t.AddTypeNameAlias('integer', 'integer|longint');
|
||||
|
||||
|
||||
BrkPrg := Debugger.SetBreakPoint(Src, 'main');
|
||||
AssertDebuggerNotInErrorState;
|
||||
|
||||
(* ************ Nested Functions ************* *)
|
||||
|
||||
RunToPause(BrkPrg);
|
||||
|
||||
|
||||
t.Clear;
|
||||
|
||||
t.Add('TestRecN2_a(aRecN2)', weCardinal(11)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecN2_b(aRecN2)', weCardinal(12)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
t.Add('TestRecB2_a(aRecB2)', weCardinal(11)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecB2_b(aRecB2)', weCardinal(21)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecB2_a(bRecB2)', weCardinal(51)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecB2_b(bRecB2)', weCardinal(61)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('aRecB2.a', weCardinal(11, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('bRecB2.a', weCardinal(51, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
|
||||
t.Add('TestRecW2_a(aRecW2)', weCardinal(12)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecW2_b(aRecW2)', weCardinal(22)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecW2_a(bRecW2)', weCardinal(52)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecW2_b(bRecW2)', weCardinal(62)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('aRecW2.a', weCardinal(12, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('bRecW2.a', weCardinal(52, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
|
||||
t.Add('TestRecC2_a(aRecC2)', weCardinal(13)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecC2_b(aRecC2)', weCardinal(23)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecC2_a(bRecC2)', weCardinal(53)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecC2_b(bRecC2)', weCardinal(63)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('aRecC2.a', weCardinal(13, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('bRecC2.a', weCardinal(53, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
|
||||
t.Add('TestRecQ2_a(aRecQ2)', weCardinal(14)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecQ2_b(aRecQ2)', weCardinal(24)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecQ2_a(bRecQ2)', weCardinal(54)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecQ2_b(bRecQ2)', weCardinal(64)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('aRecQ2.a', weCardinal(14, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('bRecQ2.a', weCardinal(54, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
|
||||
|
||||
t.Add('TestRecB3_a(aRecB3)', weCardinal(15)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecB3_c(aRecB3)', weCardinal(35)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('aRecB3.a', weCardinal(15, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
|
||||
t.Add('TestRecW3_a(aRecW3)', weCardinal(16)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecW3_c(aRecW3)', weCardinal(36)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('aRecW3.a', weCardinal(16, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
|
||||
t.Add('TestRecC3_a(aRecC3)', weCardinal(17)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecC3_c(aRecC3)', weCardinal(37)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('aRecC3.a', weCardinal(17, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
|
||||
t.Add('TestRecQ3_a(aRecQ3)', weCardinal(18)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecQ3_c(aRecQ3)', weCardinal(38)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('aRecQ3.a', weCardinal(18, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
|
||||
|
||||
t.Add('Test1RecB2(aRecB2, 0)', weCardinal(11)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecB2(aRecB2, 1)', weCardinal(21)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
t.Add('Test1RecW2(aRecW2, 0)', weCardinal(12)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecW2(aRecW2, 1)', weCardinal(22)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
t.Add('Test1RecC2(aRecC2, 0)', weCardinal(13)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecC2(aRecC2, 1)', weCardinal(23)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
t.Add('Test1RecQ2(aRecQ2, 0)', weCardinal(14)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecQ2(aRecQ2, 1)', weCardinal(24)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
|
||||
t.Add('Test2RecB2(0, aRecB2)', weCardinal(11)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecB2(1, aRecB2)', weCardinal(21)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
t.Add('Test2RecW2(0, aRecW2)', weCardinal(12)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecW2(1, aRecW2)', weCardinal(22)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
t.Add('Test2RecC2(0, aRecC2)', weCardinal(13)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecC2(1, aRecC2)', weCardinal(23)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
t.Add('Test2RecQ2(0, aRecQ2)', weCardinal(14)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ2(1, aRecQ2)', weCardinal(24)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
t.Add('aRecB2.a', weCardinal(11, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('aRecW2.a', weCardinal(12, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('aRecC2.a', weCardinal(13, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('aRecQ2.a', weCardinal(14, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
|
||||
|
||||
t.Add('TestRecN2N2_1(aRecN2, bRecN2)', weCardinal(11)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecN2N2_2(aRecN2, bRecN2)', weCardinal(8)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
t.Add('TestRecB2B2_1(aRecB2, bRecB2)', weCardinal(11)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecB2B2_2(aRecB2, bRecB2)', weCardinal(51)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecW2W2_1(aRecW2, bRecW2)', weCardinal(12)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecW2W2_2(aRecW2, bRecW2)', weCardinal(52)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecC2C2_1(aRecC2, bRecC2)', weCardinal(13)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecC2C2_2(aRecC2, bRecC2)', weCardinal(53)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecQ2Q2_1(aRecQ2, bRecQ2)', weCardinal(14)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecQ2Q2_2(aRecQ2, bRecQ2)', weCardinal(54)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
t.Add('Test1RecB2B2(aRecB2, bRecB2, 0)', weCardinal(11)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecB2B2(aRecB2, bRecB2, 1)', weCardinal(51)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecW2W2(aRecW2, bRecW2, 0)', weCardinal(12)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecW2W2(aRecW2, bRecW2, 1)', weCardinal(52)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecC2C2(aRecC2, bRecC2, 0)', weCardinal(13)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecC2C2(aRecC2, bRecC2, 1)', weCardinal(53)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecQ2Q2(aRecQ2, bRecQ2, 0)', weCardinal(14)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecQ2Q2(aRecQ2, bRecQ2, 1)', weCardinal(54)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
t.Add('Test2RecB2B2(0, aRecB2, bRecB2)', weCardinal(11)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecB2B2(1, aRecB2, bRecB2)', weCardinal(51)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecW2W2(0, aRecW2, bRecW2)', weCardinal(12)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecW2W2(1, aRecW2, bRecW2)', weCardinal(52)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecC2C2(0, aRecC2, bRecC2)', weCardinal(13)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecC2C2(1, aRecC2, bRecC2)', weCardinal(53)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ2Q2(0, aRecQ2, bRecQ2)', weCardinal(14)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ2Q2(1, aRecQ2, bRecQ2)', weCardinal(54)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
t.Add('aRecB2.a', weCardinal(11, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('aRecW2.a', weCardinal(12, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('aRecC2.a', weCardinal(13, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('aRecQ2.a', weCardinal(14, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('bRecB2.a', weCardinal(51, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('bRecW2.a', weCardinal(52, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('bRecC2.a', weCardinal(53, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('bRecQ2.a', weCardinal(54, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
|
||||
|
||||
t.Add('TestRecB2B3_1(aRecB2, bRecB3)', weCardinal(11)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecB2Q2_1(aRecB2, bRecQ2)', weCardinal(11)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecB3B2_1(aRecB3, bRecB2)', weCardinal(15)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecB3Q2_1(aRecB3, bRecQ2)', weCardinal(15)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecQ2B2_1(aRecQ2, bRecB2)', weCardinal(14)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecQ2B3_1(aRecQ2, bRecB3)', weCardinal(14)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecB2B3_2(aRecB2, bRecB3)', weCardinal(55)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecB2Q2_2(aRecB2, bRecQ2)', weCardinal(54)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecB3B2_2(aRecB3, bRecB2)', weCardinal(51)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecB3Q2_2(aRecB3, bRecQ2)', weCardinal(54)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecQ2B2_2(aRecQ2, bRecB2)', weCardinal(51)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('TestRecQ2B3_2(aRecQ2, bRecB3)', weCardinal(55)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
|
||||
t.Add('Test1RecB2B3(aRecB2, bRecB3, 0)', weCardinal(11)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecB2Q2(aRecB2, bRecQ2, 0)', weCardinal(11)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecB3B2(aRecB3, bRecB2, 0)', weCardinal(15)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecB3Q2(aRecB3, bRecQ2, 0)', weCardinal(15)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecQ2B2(aRecQ2, bRecB2, 0)', weCardinal(14)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecQ2B3(aRecQ2, bRecB3, 0)', weCardinal(14)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecB2B3(aRecB2, bRecB3, 1)', weCardinal(55)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecB2Q2(aRecB2, bRecQ2, 1)', weCardinal(54)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecB3B2(aRecB3, bRecB2, 1)', weCardinal(51)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecB3Q2(aRecB3, bRecQ2, 1)', weCardinal(54)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecQ2B2(aRecQ2, bRecB2, 1)', weCardinal(51)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test1RecQ2B3(aRecQ2, bRecB3, 1)', weCardinal(55)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
|
||||
t.Add('Test2RecB2B3(0, aRecB2, bRecB3)', weCardinal(11)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecB2Q2(0, aRecB2, bRecQ2)', weCardinal(11)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecB3B2(0, aRecB3, bRecB2)', weCardinal(15)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecB3Q2(0, aRecB3, bRecQ2)', weCardinal(15)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ2B2(0, aRecQ2, bRecB2)', weCardinal(14)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ2B3(0, aRecQ2, bRecB3)', weCardinal(14)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecB2B3(1, aRecB2, bRecB3)', weCardinal(55)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecB2Q2(1, aRecB2, bRecQ2)', weCardinal(54)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecB3B2(1, aRecB3, bRecB2)', weCardinal(51)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecB3Q2(1, aRecB3, bRecQ2)', weCardinal(54)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ2B2(1, aRecQ2, bRecB2)', weCardinal(51)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ2B3(1, aRecQ2, bRecB3)', weCardinal(55)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
t.Add('Test2RecQ3Q3(0, aRecQ3, bRecQ3)', weCardinal(18)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ3Q3(1, aRecQ3, bRecQ3)', weCardinal(38)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ3Q3(2, aRecQ3, bRecQ3)', weCardinal(58)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ3Q3(3, aRecQ3, bRecQ3)', weCardinal(78)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
t.Add('Test2RecQ4Q4(0, aRecQ4, bRecQ4)', weCardinal(58)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ4Q4(1, aRecQ4, bRecQ4)', weCardinal( 2)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ4Q4(2, aRecQ4, bRecQ4)', weCardinal(59)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ4Q4(3, aRecQ4, bRecQ4)', weCardinal(92)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
t.Add('Test2RecQ5Q5(0, aRecQ5, bRecQ5)', weCardinal(58)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ5Q5(1, aRecQ5, bRecQ5)', weCardinal( 3)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ5Q5(2, aRecQ5, bRecQ5)', weCardinal(59)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ5Q5(3, aRecQ5, bRecQ5)', weCardinal(93)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
t.Add('Test2RecQ6Q6(0, aRecQ6, bRecQ6)', weCardinal(58)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ6Q6(1, aRecQ6, bRecQ6)', weCardinal( 4)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ6Q6(2, aRecQ6, bRecQ6)', weCardinal(59)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ6Q6(3, aRecQ6, bRecQ6)', weCardinal(94)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
t.Add('Test2RecQ7Q7(0, aRecQ7, bRecQ7)', weCardinal(58)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ7Q7(1, aRecQ7, bRecQ7)', weCardinal( 5)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ7Q7(2, aRecQ7, bRecQ7)', weCardinal(59)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
t.Add('Test2RecQ7Q7(3, aRecQ7, bRecQ7)', weCardinal(95)).AddEvalFlag([defAllowFunctionCall]).IgnTypeName.SkipEval;
|
||||
|
||||
t.Add('aRecB2.a', weCardinal(11, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('aRecW2.a', weCardinal(12, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('aRecC2.a', weCardinal(13, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('aRecQ2.a', weCardinal(14, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('bRecB2.a', weCardinal(51, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('bRecW2.a', weCardinal(52, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('bRecC2.a', weCardinal(53, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
t.Add('bRecQ2.a', weCardinal(54, #1, -1)).IgnTypeName.SkipEval.IgnKind;
|
||||
|
||||
t.EvalAndCheck;
|
||||
|
||||
|
||||
finally
|
||||
Debugger.RunToNextPause(dcStop);
|
||||
FreeAndNil(t);
|
||||
Debugger.ClearDebuggerMonitors;
|
||||
Debugger.FreeDebugger;
|
||||
end;
|
||||
|
||||
end;
|
||||
finally
|
||||
AssertTestErrors;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TTestWatches.TestWatchesAddressOf;
|
||||
|
||||
type
|
||||
@ -3242,6 +3521,7 @@ initialization
|
||||
ControlTestWatchValue := TestControlRegisterTest('Value', ControlTestWatch);
|
||||
ControlTestWatchFunct := TestControlRegisterTest('Function', ControlTestWatch);
|
||||
ControlTestWatchFunctStr := TestControlRegisterTest('FunctionString', ControlTestWatch);
|
||||
ControlTestWatchFunctRec := TestControlRegisterTest('FunctionRecord', ControlTestWatch);
|
||||
ControlTestWatchAddressOf := TestControlRegisterTest('AddressOf', ControlTestWatch);
|
||||
ControlTestWatchTypeCast := TestControlRegisterTest('TypeCast', ControlTestWatch);
|
||||
ControlTestModify := TestControlRegisterTest('Modify', ControlTestWatch);
|
||||
|
Loading…
Reference in New Issue
Block a user