FPDebug: more Value handling

git-svn-id: trunk@43832 -
This commit is contained in:
martin 2014-01-29 00:01:58 +00:00
parent 2979e368b8
commit e8f2625b6d
3 changed files with 450 additions and 92 deletions

View File

@ -589,35 +589,62 @@ type
TDbgDwarfSymbolValue = class(TDbgSymbolValue)
private
FOwner: TDbgDwarfValueIdentifier; // nor refcounted
protected
function GetKind: TDbgSymbolKind; override;
function GetMemberCount: Integer; override;
function GetMemberByName(AIndex: String): TDbgSymbolValue; override;
function GetMember(AIndex: Integer): TDbgSymbolValue; override;
function GetDbgSymbol: TDbgSymbol; override;
public
constructor Create;
procedure SetOwner(AOwner: TDbgDwarfValueIdentifier);
// SourceValue: TDbgSymbolValue
end;
{ TDbgDwarfIntegerSymbolValue }
TDbgDwarfIntegerSymbolValue = class(TDbgDwarfSymbolValue)
private
FValue: Int64;
FValue: QWord;
FIntValue: Int64;
FSize: Integer;
FEvaluated: Boolean;
FEvaluated: set of (doneUInt, doneInt);
protected
function GetAsCardinal: QWord; override;
function GetAsInteger: Int64; override;
public
constructor Create(ASize: Integer);
end;
{ TDbgDwarfCardinalSymbolValue }
{ TDbgDwarfFloatSymbolValue }
TDbgDwarfCardinalSymbolValue = class(TDbgDwarfSymbolValue)
private
FValue: QWord;
FSize: Integer;
FEvaluated: Boolean;
TDbgDwarfFloatSymbolValue = class(TDbgDwarfIntegerSymbolValue) // TDbgDwarfSymbolValue
protected
function GetAsCardinal: QWord; override;
public
constructor Create(ASize: Integer);
//
end;
{ TDbgDwarfBooleanSymbolValue }
TDbgDwarfBooleanSymbolValue = class(TDbgDwarfIntegerSymbolValue)
protected
function GetAsBool: Boolean; override;
end;
{ TDbgDwarfCharSymbolValue }
TDbgDwarfCharSymbolValue = class(TDbgDwarfIntegerSymbolValue)
protected
// returns single char(byte) / widechar
function GetAsString: AnsiString; override;
function GetAsWideString: WideString; override;
end;
{ TDbgDwarfPointerSymbolValue }
TDbgDwarfPointerSymbolValue = class(TDbgDwarfIntegerSymbolValue)
end;
TDbgDwarfStructSymbolValue = class(TDbgDwarfSymbolValue)
end;
{ TDbgDwarfIdentifier }
@ -679,6 +706,10 @@ type
procedure KindNeeded; override;
procedure MemberVisibilityNeeded; override;
function GetMember(AIndex: Integer): TDbgSymbol; override;
function GetMemberByName(AIndex: String): TDbgSymbol; override;
function GetMemberCount: Integer; override;
procedure Init; override;
public
destructor Destroy; override;
@ -843,6 +874,7 @@ DECL = DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line
procedure KindNeeded; override;
procedure ForwardToSymbolNeeded; override;
function GetStructureBaseAddress(out AnAddress: TDbgPtr; AMember: TDbgDwarfIdentifier; InheritedLoc: Boolean): Boolean; override;
function GetTypedValueObject: TDbgDwarfSymbolValue; override;
public
property IsInternalPointer: Boolean read GetIsInternalPointer write FIsInternalPointer; // Class (also DynArray, but DynArray is handled without this)
end;
@ -907,6 +939,7 @@ DECL = DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line
protected
procedure KindNeeded; override;
procedure TypeInfoNeeded; override; // nil or inherited
function GetTypedValueObject: TDbgDwarfSymbolValue; override;
function GetMember(AIndex: Integer): TDbgSymbol; override;
function GetMemberByName(AIndex: String): TDbgSymbol; override;
@ -1533,28 +1566,57 @@ begin
end;
end;
{ TDbgDwarfBooleanSymbolValue }
function TDbgDwarfBooleanSymbolValue.GetAsBool: Boolean;
begin
Result := QWord(GetAsInteger) <> 0;
end;
{ TDbgDwarfCharSymbolValue }
function TDbgDwarfCharSymbolValue.GetAsString: AnsiString;
begin
if FSize <> 1 then
Result := inherited GetAsString
else
Result := char(byte(GetAsCardinal));
end;
function TDbgDwarfCharSymbolValue.GetAsWideString: WideString;
begin
if FSize > 2 then
Result := inherited GetAsString
else
Result := WideChar(Word(GetAsCardinal));
end;
{ TDbgDwarfCardinalSymbolValue }
function TDbgDwarfCardinalSymbolValue.GetAsCardinal: QWord;
function TDbgDwarfIntegerSymbolValue.GetAsCardinal: QWord;
var
m: TFpDbgMemReaderBase;
addr: TDbgPtr;
begin
if FEvaluated then begin
// TODO: memory representation of values is not dwar, but platform - move
if doneUInt in FEvaluated then begin
Result := FValue;
exit;
end;
Include(FEvaluated, doneUInt);
if (FOwner = nil) or (FOwner.FCU = nil) or
(FOwner.FCU.FOwner = nil) or (FOwner.FCU.FOwner.MemReader = nil) or
((FSize <= 0) or (FSize > SizeOf(Result)))
then begin
Result := inherited GetAsInteger;
FValue := Result;
exit;
end;
addr := FOwner.Address;
if (addr = 0) then begin
Result := inherited GetAsInteger;
FValue := Result;
exit;
end;
@ -1563,59 +1625,79 @@ begin
Result := 0;
m.ReadMemory(addr, FSize, @Result);
FValue := Result;
end;
constructor TDbgDwarfCardinalSymbolValue.Create(ASize: Integer);
begin
inherited Create;
FSize := ASize;
FEvaluated := False;
end;
{ TDbgDwarfIntegerSymbolValue }
function TDbgDwarfIntegerSymbolValue.GetAsInteger: Int64;
var
m: TFpDbgMemReaderBase;
addr: TDbgPtr;
begin
if FEvaluated then begin
Result := FValue;
exit;
end;
if (FOwner = nil) or (FOwner.FCU = nil) or
(FOwner.FCU.FOwner = nil) or (FOwner.FCU.FOwner.MemReader = nil) or
((FSize <= 0) or (FSize > SizeOf(Result)))
then begin
Result := inherited GetAsInteger;
if doneInt in FEvaluated then begin
Result := FIntValue;
exit;
end;
Include(FEvaluated, doneInt);
addr := FOwner.Address;
if (addr = 0) then begin
Result := inherited GetAsInteger;
exit;
end;
m := FOwner.FCU.FOwner.MemReader;
// TODO endian
Result := 0;
m.ReadMemory(addr, FSize, @Result);
Result := GetAsCardinal;
// sign extend
if Result and (int64(1) shl (FSize * 8 - 1)) <> 0 then
Result := Result or (int64(-1) shl (FSize * 8));
FIntValue := Result;
end;
constructor TDbgDwarfIntegerSymbolValue.Create(ASize: Integer);
begin
inherited Create;
FSize := ASize;
FEvaluated := False;
FEvaluated := [];
end;
{ TDbgDwarfSymbolValue }
function TDbgDwarfSymbolValue.GetKind: TDbgSymbolKind;
begin
if FOwner <> nil then
Result := FOwner.Kind
else
Result := inherited GetKind;
end;
function TDbgDwarfSymbolValue.GetMemberCount: Integer;
begin
if FOwner <> nil then
Result := FOwner.MemberCount
else
Result := inherited GetMemberCount;
end;
function TDbgDwarfSymbolValue.GetMemberByName(AIndex: String): TDbgSymbolValue;
var
m: TDbgSymbol;
begin
Result := nil;
if FOwner <> nil then begin
m := FOwner.MemberByName[AIndex];
if m <> nil then
Result := m.Value;
end;
end;
function TDbgDwarfSymbolValue.GetMember(AIndex: Integer): TDbgSymbolValue;
var
m: TDbgSymbol;
begin
Result := nil;
if FOwner <> nil then begin
m := FOwner.Member[AIndex];
if m <> nil then
Result := m.Value;
end;
end;
function TDbgDwarfSymbolValue.GetDbgSymbol: TDbgSymbol;
begin
Result := FOwner;
end;
constructor TDbgDwarfSymbolValue.Create;
begin
inherited Create;
@ -4037,6 +4119,15 @@ begin
end;
end;
function TDbgDwarfTypeIdentifierPointer.GetTypedValueObject: TDbgDwarfSymbolValue;
begin
if IsInternalPointer then
Result := NestedTypeInfo.GetTypedValueObject
else
// TODO:
Result := TDbgDwarfPointerSymbolValue.Create(FCU.FAddressSize);
end;
{ TDbgDwarfTypeIdentifierDeclaration }
function TDbgDwarfTypeIdentifierDeclaration.DoGetNestedTypeInfo: TDbgDwarfTypeIdentifier;
@ -4105,6 +4196,39 @@ begin
inherited MemberVisibilityNeeded;
end;
function TDbgDwarfValueIdentifier.GetMember(AIndex: Integer): TDbgSymbol;
var
ti: TDbgSymbol;
begin
ti := TypeInfo;
if ti <> nil then
Result := ti.Member[AIndex]
else
Result := inherited GetMember(AIndex);
end;
function TDbgDwarfValueIdentifier.GetMemberByName(AIndex: String): TDbgSymbol;
var
ti: TDbgSymbol;
begin
ti := TypeInfo;
if ti <> nil then
Result := ti.MemberByName[AIndex]
else
Result := inherited GetMemberByName(AIndex);
end;
function TDbgDwarfValueIdentifier.GetMemberCount: Integer;
var
ti: TDbgSymbol;
begin
ti := TypeInfo;
if ti <> nil then
Result := ti.MemberCount
else
Result := inherited GetMemberCount;
end;
procedure TDbgDwarfValueIdentifier.Init;
begin
inherited Init;
@ -4396,6 +4520,11 @@ begin
NewInfo.ReleaseReference;
end;
function TDbgDwarfIdentifierStructure.GetTypedValueObject: TDbgDwarfSymbolValue;
begin
Result := TDbgDwarfStructSymbolValue.Create;
end;
{ TDbgDwarfTypeIdentifierModifier }
procedure TDbgDwarfTypeIdentifierModifier.TypeInfoNeeded;
@ -4464,12 +4593,12 @@ end;
function TDbgDwarfBaseIdentifierBase.GetTypedValueObject: TDbgDwarfSymbolValue;
begin
case Kind of
skPointer: ;
skPointer: Result := TDbgDwarfPointerSymbolValue.Create(Size);
skInteger: Result := TDbgDwarfIntegerSymbolValue.Create(Size);
skCardinal: Result := TDbgDwarfCardinalSymbolValue.Create(Size);
skBoolean: ;
skChar: ;
skFloat: ;
skCardinal: Result := TDbgDwarfIntegerSymbolValue.Create(Size);
skBoolean: Result := TDbgDwarfBooleanSymbolValue.Create(Size);
skChar: Result := TDbgDwarfCharSymbolValue.Create(Size);
skFloat: Result := TDbgDwarfFloatSymbolValue.Create(Size);
end;
end;

View File

@ -86,6 +86,8 @@ type
);
TDbgSymbolFields = set of TDbgSymbolField;
TDbgSymbol = class;
{ TDbgSymbolValue }
TDbgSymbolValue = class(TRefCountedObject)
@ -93,12 +95,38 @@ type
function GetAsBool: Boolean; virtual;
function GetAsCardinal: QWord; virtual;
function GetAsInteger: Int64; virtual;
function GetAsString: AnsiString; virtual;
function GetAsWideString: WideString; virtual;
function GetKind: TDbgSymbolKind; virtual;
function GetMember(AIndex: Integer): TDbgSymbolValue; virtual;
function GetMemberByName(AIndex: String): TDbgSymbolValue; virtual;
function GetMemberCount: Integer; virtual;
function GetDbgSymbol: TDbgSymbol; virtual;
public
// Kind: determines which types of value are available
property Kind: TDbgSymbolKind read GetKind;
property AsInteger: Int64 read GetAsInteger;
property AsCardinal: QWord read GetAsCardinal;
property AsBool: Boolean read GetAsBool;
// memdump
//function AsPrintable: String; virtual;
property AsString: AnsiString read GetAsString;
property AsWideString: WideString read GetAsWideString;
// complex
// double
// memdump / Address / Size / Memory
public
(* Member:
For TypeInfo (skType) it excludes BaseClass
For Value (skValue): ???
*)
// base class? Or Member inncludes member from base
property MemberCount: Integer read GetMemberCount;
property Member[AIndex: Integer]: TDbgSymbolValue read GetMember;
property MemberByName[AIndex: String]: TDbgSymbolValue read GetMemberByName; // Includes inheritance
(* DbgSymbol: The TDbgSymbol from which this value came, maybe nil.
Maybe a stType, then there is no Value *)
property DbgSymbol: TDbgSymbol read GetDbgSymbol;
end;
{ TDbgSymbol }
@ -115,7 +143,7 @@ type
FSize: Integer;
FTypeInfo: TDbgSymbol;
FReference: TDbgSymbol;
FMemberVisibility: TDbgSymbolMemberVisibility;
FMemberVisibility: TDbgSymbolMemberVisibility; // Todo: not cached
function GetSymbolType: TDbgSymbolType; inline;
function GetKind: TDbgSymbolKind; inline;
@ -182,14 +210,18 @@ type
// stValue (Variable): Type
// stType: Pointer: type pointed to / Array: Element Type / Func: Result / Class: itheritance
property TypeInfo: TDbgSymbol read GetTypeInfo;
property MemberVisibility: TDbgSymbolMemberVisibility read GetMemberVisibility;
// Location
property FileName: String read GetFile;
property Line: Cardinal read GetLine;
property Column: Cardinal read GetColumn;
// Methods for structures (record / class / enum)
// array: each member represents an index (enum or subrange) and has low/high bounds
property MemberVisibility: TDbgSymbolMemberVisibility read GetMemberVisibility;
property MemberCount: Integer read GetMemberCount;
(* Member:
For TypeInfo (skType) it excludes BaseClass
For Value (skValue): ???
*)
property Member[AIndex: Integer]: TDbgSymbol read GetMember;
property MemberByName[AIndex: String]: TDbgSymbol read GetMemberByName; // Includes inheritance
//
@ -198,15 +230,16 @@ type
// Reference: opposite of TypeInfo / The variable to which a type belongs
property Reference: TDbgSymbol read GetReference write SetReference;
property Parent: TDbgSymbol read GetParent; deprecated;
//property Children[AIndex: Integer]: TDbgSymbol read GetChild;
// VALUE
property Value: TDbgSymbolValue read GetValueObject;
property HasOrdinalValue: Boolean read GetHasOrdinalValue;
property OrdinalValue: Int64 read GetOrdinalValue; // need typecast for QuadWord
// for Subranges
property HasBounds: Boolean read GetHasBounds;
property OrdLowBound: Int64 read GetOrdLowBound; // need typecast for QuadWord
property OrdHighBound: Int64 read GetOrdHighBound; // need typecast for QuadWord
// VALUE
property Value: TDbgSymbolValue read GetValueObject;
property HasOrdinalValue: Boolean read GetHasOrdinalValue;
property OrdinalValue: Int64 read GetOrdinalValue; // need typecast for QuadWord
//TypeCastValue(AValue: TDbgSymbolValue): TDbgSymbolValue;
end;
{ TDbgSymbolForwarder }
@ -279,6 +312,41 @@ end;
{ TDbgSymbolValue }
function TDbgSymbolValue.GetAsString: AnsiString;
begin
Result := '';
end;
function TDbgSymbolValue.GetAsWideString: WideString;
begin
Result := '';
end;
function TDbgSymbolValue.GetDbgSymbol: TDbgSymbol;
begin
Result := nil;
end;
function TDbgSymbolValue.GetKind: TDbgSymbolKind;
begin
Result := skNone;
end;
function TDbgSymbolValue.GetMember(AIndex: Integer): TDbgSymbolValue;
begin
Result := nil;
end;
function TDbgSymbolValue.GetMemberByName(AIndex: String): TDbgSymbolValue;
begin
Result := nil;
end;
function TDbgSymbolValue.GetMemberCount: Integer;
begin
Result := 0;
end;
function TDbgSymbolValue.GetAsBool: Boolean;
begin
Result := False;

View File

@ -51,11 +51,12 @@ type
FExpressionPart: TFpPascalExpressionPart;
FValid: Boolean;
function GetResultType: TDbgSymbol;
function GetResultValue: TDbgSymbolValue;
procedure Parse;
procedure SetError(AMsg: String);
function PosFromPChar(APChar: PChar): Integer;
protected
function GetDbgTyeForIdentifier({%H-}AnIdent: String): TDbgSymbol; virtual;
function GetDbgSymbolForIdentifier({%H-}AnIdent: String): TDbgSymbol; virtual;
property ExpressionPart: TFpPascalExpressionPart read FExpressionPart;
public
constructor Create(ATextExpression: String);
@ -63,7 +64,8 @@ type
function DebugDump: String;
property Error: String read FError;
property Valid: Boolean read FValid;
property ResultType: TDbgSymbol read GetResultType;
//property ResultType: TDbgSymbol read GetResultType; deprecated;
property ResultValue: TDbgSymbolValue read GetResultValue; // May be a type, if expression is a type
end;
@ -77,8 +79,11 @@ type
FExpression: TFpPascalExpression;
FResultType: TDbgSymbol;
FResultTypeFlag: (rtUnknown, rtType, rtTypeCast);
FResultValue: TDbgSymbolValue;
FResultValDone: Boolean;
function GetResultType: TDbgSymbol;
function GetResultTypeCast: TDbgSymbol;
function GetResultValue: TDbgSymbolValue;
function GetSurroundingOpenBracket: TFpPascalExpressionPartBracket;
function GetTopParent: TFpPascalExpressionPart;
procedure SetEndChar(AValue: PChar);
@ -93,6 +98,7 @@ type
procedure Init; virtual;
function DoGetResultType: TDbgSymbol; virtual;
function DoGetIsTypeCast: Boolean; virtual;
function DoGetResultValue: TDbgSymbolValue; virtual;
Procedure ReplaceInParent(AReplacement: TFpPascalExpressionPart);
procedure DoHandleEndOfExpression; virtual;
@ -118,8 +124,9 @@ type
property Parent: TFpPascalExpressionPartContainer read FParent write SetParent;
property TopParent: TFpPascalExpressionPart read GetTopParent; // or self
property SurroundingBracket: TFpPascalExpressionPartBracket read GetSurroundingOpenBracket; // incl self
property ResultType: TDbgSymbol read GetResultType;
property ResultTypeCast: TDbgSymbol read GetResultTypeCast;
property ResultType: TDbgSymbol read GetResultType; deprecated;
property ResultTypeCast: TDbgSymbol read GetResultTypeCast; deprecated;
property ResultValue: TDbgSymbolValue read GetResultValue;
end;
{ TFpPascalExpressionPartContainer }
@ -149,11 +156,11 @@ type
TFpPascalExpressionPartIdentifer = class(TFpPascalExpressionPartContainer)
private
FDbgType: TDbgSymbol; // may be a variable or function or a type ...
FDbgTypeDone: Boolean;
FDbgSymbol: TDbgSymbol;
protected
function DoGetResultType: TDbgSymbol; override;
function DoGetIsTypeCast: Boolean; override;
function DoGetResultValue: TDbgSymbolValue; override;
public
destructor Destroy; override;
end;
@ -161,7 +168,11 @@ type
TFpPascalExpressionPartConstant = class(TFpPascalExpressionPartContainer)
end;
{ TFpPascalExpressionPartConstantNumber }
TFpPascalExpressionPartConstantNumber = class(TFpPascalExpressionPartConstant)
protected
function DoGetResultValue: TDbgSymbolValue; override;
end;
TFpPascalExpressionPartConstantText = class(TFpPascalExpressionPartConstant)
@ -209,6 +220,7 @@ type
protected
function HandleNextPartInBracket(APart: TFpPascalExpressionPart): TFpPascalExpressionPart; override;
function DoGetResultType: TDbgSymbol; override;
function DoGetResultValue: TDbgSymbolValue; override;
end;
{ TFpPascalExpressionPartBracketArgumentList }
@ -349,6 +361,7 @@ type
procedure Init; override;
function IsValidNextPart(APart: TFpPascalExpressionPart): Boolean; override;
function DoGetResultType: TDbgSymbol; override;
function DoGetResultValue: TDbgSymbolValue; override;
end;
implementation
@ -367,6 +380,32 @@ const
type
{ TPasParserWrapperSymbolValue }
TPasParserWrapperSymbolValue = class(TDbgSymbolValue)
private
FSymbol: TDbgSymbol;
protected
function GetKind: TDbgSymbolKind; override;
function GetDbgSymbol: TDbgSymbol; override;
public
constructor Create(ATypeInfo: TDbgSymbol);
end;
{ TPasParserConstNumberSymbolValue }
TPasParserConstNumberSymbolValue = class(TDbgSymbolValue)
private
FValue: QWord;
FSigned: Boolean;
protected
function GetKind: TDbgSymbolKind; override;
function GetAsCardinal: QWord; override;
function GetAsInteger: Int64; override;
public
constructor Create(AValue: QWord; ASigned: Boolean = False);
end;
{ TPasParserSymbolPointer }
TPasParserSymbolPointer = class(TDbgSymbol)
@ -394,6 +433,51 @@ type
destructor Destroy; override;
end;
{ TPasParserConstNumberSymbolValue }
function TPasParserConstNumberSymbolValue.GetKind: TDbgSymbolKind;
begin
if FSigned then
Result := skInteger
else
Result := skCardinal;
end;
function TPasParserConstNumberSymbolValue.GetAsCardinal: QWord;
begin
Result := FValue;
end;
function TPasParserConstNumberSymbolValue.GetAsInteger: Int64;
begin
Result := Int64(FValue);
end;
constructor TPasParserConstNumberSymbolValue.Create(AValue: QWord; ASigned: Boolean);
begin
inherited Create;
FValue := AValue;
FSigned := ASigned;
end;
{ TPasParserTypeCastSymbolValue }
function TPasParserWrapperSymbolValue.GetKind: TDbgSymbolKind;
begin
Result := skNone;
end;
function TPasParserWrapperSymbolValue.GetDbgSymbol: TDbgSymbol;
begin
Result := FSymbol;
end;
constructor TPasParserWrapperSymbolValue.Create(ATypeInfo: TDbgSymbol);
begin
inherited Create;
FSymbol := ATypeInfo;
end;
{ TPasParserSymbolArrayDeIndex }
function TPasParserSymbolArrayDeIndex.GetMemberCount: Integer;
@ -467,7 +551,7 @@ begin
if tmp.MemberCount < 1 then exit; // TODO error
if tmp.MemberCount = 1 then begin
Result := tmp.TypeInfo;
Result.AddReference;
Result.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(nil, 'DoGetResultType'){$ENDIF};
exit;
end;
@ -476,7 +560,7 @@ begin
else
if (tmp.Kind = skPointer) then begin
Result := tmp.TypeInfo;
Result.AddReference;
Result.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(nil, 'DoGetResultType'){$ENDIF};
exit;
end
else
@ -582,7 +666,7 @@ begin
if Result <> nil then begin
// This is a typecast
// TODO: verify cast compatibilty
Result.AddReference;
Result.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(nil, 'DoGetResultType'){$ENDIF};
exit;
end;
end;
@ -673,42 +757,73 @@ begin
else
Result := Items[0].ResultType;
if Result <> nil then
Result.AddReference;
Result.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(nil, 'DoGetResultType'){$ENDIF};
end;
function TFpPascalExpressionPartBracketSubExpression.DoGetResultValue: TDbgSymbolValue;
begin
if Count <> 1 then
Result := nil
else
Result := Items[0].ResultValue;
if Result <> nil then
Result.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(nil, 'DoGetResultValue'){$ENDIF};
end;
{ TFpPascalExpressionPartIdentifer }
function TFpPascalExpressionPartIdentifer.DoGetResultType: TDbgSymbol;
begin
Result := nil;
if (FDbgType = nil) and not FDbgTypeDone then
FDbgType := FExpression.GetDbgTyeForIdentifier(GetText);
FDbgTypeDone := True;
if FDbgType = nil then
Result := ResultValue.DbgSymbol;
if Result = nil then
exit;
case FDbgType.SymbolType of
stValue: Result := FDbgType.TypeInfo;
stType: Result := FDbgType;
case Result.SymbolType of
stValue: Result := Result.TypeInfo;
stType: Result := Result;
else Result := nil;
end;
if Result <> nil then
Result.AddReference;
Result.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(nil, 'DoGetResultType'){$ENDIF};
end;
function TFpPascalExpressionPartIdentifer.DoGetIsTypeCast: Boolean;
begin
if (FDbgType = nil) and not FDbgTypeDone then
FDbgType := FExpression.GetDbgTyeForIdentifier(GetText);
FDbgTypeDone := True;
Result := (FDbgType <> nil) and (FDbgType.SymbolType = stType);
Result := (ResultValue <> nil) and (ResultValue.DbgSymbol <> nil) and (ResultValue.DbgSymbol.SymbolType = stType);
end;
function TFpPascalExpressionPartIdentifer.DoGetResultValue: TDbgSymbolValue;
begin
Result := nil;
// Need to keep a ref, because ValueObject might not reference its owner
assert(FDbgSymbol = nil, 'TFpPascalExpressionPartIdentifer.DoGetResultValue: not yet done');
FDbgSymbol := FExpression.GetDbgSymbolForIdentifier(GetText);
{$IFDEF WITH_REFCOUNT_DEBUG}if FDbgSymbol <> nil then FDbgSymbol.DbgRenameReference(FDbgSymbol, 'DoGetResultValue'){$ENDIF};
if FDbgSymbol = nil then
exit;
Result := FDbgSymbol.Value;
if Result = nil then begin
Result := TPasParserWrapperSymbolValue.Create(FDbgSymbol);
if Result <> nil then Result.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(nil, 'DoGetResultValue'){$ENDIF};
end
else
Result.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(nil, 'DoGetResultValue'){$ENDIF};
end;
destructor TFpPascalExpressionPartIdentifer.Destroy;
begin
inherited Destroy;
ReleaseRefAndNil(FDbgType);
FDbgSymbol.ReleaseReference{$IFDEF WITH_REFCOUNT_DEBUG}(FDbgSymbol, 'DoGetResultValue'){$ENDIF};
end;
{ TFpPascalExpressionPartConstantNumber }
function TFpPascalExpressionPartConstantNumber.DoGetResultValue: TDbgSymbolValue;
begin
Result := TPasParserConstNumberSymbolValue.Create(StrToQWordDef(GetText, 0));
Result.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(nil, 'DoGetResultValue'){$ENDIF};
end;
{ TFpPascalExpressionPartOperatorUnaryPlusMinus }
@ -803,14 +918,14 @@ var
'&': while TokenEndPtr^ in ['0'..'7'] do inc(TokenEndPtr);
'%': while TokenEndPtr^ in ['0'..'1'] do inc(TokenEndPtr);
'0'..'9':
if (TokenEndPtr^ = '0') and ((TokenEndPtr + 1)^ = 'x') and
((TokenEndPtr + 2)^ in ['a'..'z', 'A'..'Z', '0'..'9'])
if (CurPtr^ = '0') and ((CurPtr + 1)^ in ['x', 'X']) and
((CurPtr + 2)^ in ['a'..'z', 'A'..'Z', '0'..'9'])
then begin
inc(TokenEndPtr, 3);
inc(TokenEndPtr, 2);
while TokenEndPtr^ in ['a'..'z', 'A'..'Z', '0'..'9'] do inc(TokenEndPtr);
end
else
while TokenEndPtr^ in ['0'..'0'] do inc(TokenEndPtr);
while TokenEndPtr^ in ['0'..'9'] do inc(TokenEndPtr);
end;
AddPart(TFpPascalExpressionPartConstantNumber);
end;
@ -890,6 +1005,14 @@ begin
Result := FExpressionPart.ResultType;
end;
function TFpPascalExpression.GetResultValue: TDbgSymbolValue;
begin
if (FExpressionPart = nil) or (not Valid) then
Result := nil
else
Result := FExpressionPart.ResultValue;
end;
procedure TFpPascalExpression.SetError(AMsg: String);
begin
FValid := False;
@ -902,7 +1025,7 @@ begin
Result := APChar - @FTextExpression[1] + 1;
end;
function TFpPascalExpression.GetDbgTyeForIdentifier(AnIdent: String): TDbgSymbol;
function TFpPascalExpression.GetDbgSymbolForIdentifier(AnIdent: String): TDbgSymbol;
begin
Result := nil;
end;
@ -986,6 +1109,16 @@ begin
Result := nil;
end;
function TFpPascalExpressionPart.GetResultValue: TDbgSymbolValue;
begin
Result := FResultValue;
if FResultValDone then
exit;
FResultValue := DoGetResultValue;
FResultValDone := True;
Result := FResultValue;
end;
procedure TFpPascalExpressionPart.SetParent(AValue: TFpPascalExpressionPartContainer);
begin
if FParent = AValue then Exit;
@ -1039,6 +1172,11 @@ begin
Result := False;
end;
function TFpPascalExpressionPart.DoGetResultValue: TDbgSymbolValue;
begin
Result := nil;
end;
procedure TFpPascalExpressionPart.ReplaceInParent(AReplacement: TFpPascalExpressionPart);
var
i: Integer;
@ -1105,13 +1243,15 @@ begin
FStartChar := AStartChar;
FEndChar := AnEndChar;
FResultTypeFlag := rtUnknown;
FResultValDone := False;
Init;
end;
destructor TFpPascalExpressionPart.Destroy;
begin
inherited Destroy;
ReleaseRefAndNil(FResultType);
FResultType.ReleaseReference{$IFDEF WITH_REFCOUNT_DEBUG}(nil, 'DoGetResultType'){$ENDIF};
FResultValue.ReleaseReference{$IFDEF WITH_REFCOUNT_DEBUG}(nil, 'DoGetResultValue'){$ENDIF};
end;
function TFpPascalExpressionPart.HandleNextPart(APart: TFpPascalExpressionPart): TFpPascalExpressionPart;
@ -1418,6 +1558,7 @@ begin
if Result = nil then
exit;
Result := TPasParserSymbolPointer.Create(Result);
{$IFDEF WITH_REFCOUNT_DEBUG}Result.DbgRenameReference(nil, 'DoGetResultType');{$ENDIF}
end;
{ TFpPascalExpressionPartOperatorMakeRef }
@ -1448,6 +1589,7 @@ begin
if Result = nil then
exit;
Result := TPasParserSymbolPointer.Create(Result);
{$IFDEF WITH_REFCOUNT_DEBUG}Result.DbgRenameReference(nil, 'DoGetResultType');{$ENDIF}
end;
function TFpPascalExpressionPartOperatorMakeRef.DoGetIsTypeCast: Boolean;
@ -1556,10 +1698,29 @@ begin
tmp := tmp.MemberByName[Items[1].GetText];
if (tmp <> nil) and (tmp.SymbolType = stValue) then begin
Result := tmp.TypeInfo;
Result.AddReference;
Result.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(nil, 'DoGetResultType'){$ENDIF};
end;
end;
end;
function TFpPascalExpressionPartOperatorMemberOf.DoGetResultValue: TDbgSymbolValue;
var
tmp: TDbgSymbolValue;
begin
Result := nil;
if Count <> 2 then exit;
tmp := Items[0].ResultValue;
if (tmp = nil) then exit;
// Todo unit
// TODO MAy need AddReference for the symbol
if (tmp.Kind = skClass) or (tmp.Kind = skRecord) then begin
Result := tmp.MemberByName[Items[1].GetText];
if Result <> nil then
Result.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(nil, 'DoGetResultValue'){$ENDIF};
Assert((Result=nil) or (Result.DbgSymbol=nil)or(Result.DbgSymbol.SymbolType=stValue), 'member is value');
end;
end;
end.