mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-17 15:19:22 +02:00
FPDebug: find "self", added references to owner.
git-svn-id: trunk@43657 -
This commit is contained in:
parent
4dac3a41c9
commit
51dbc1ee16
@ -363,6 +363,8 @@ type
|
|||||||
function ReadName(out AName: String): Boolean; inline;
|
function ReadName(out AName: String): Boolean; inline;
|
||||||
function ReadName(out AName: PChar): Boolean; inline;
|
function ReadName(out AName: PChar): Boolean; inline;
|
||||||
function ReadStartScope(out AStartScope: TDbgPtr): Boolean; inline;
|
function ReadStartScope(out AStartScope: TDbgPtr): Boolean; inline;
|
||||||
|
function IsAddressInStartScope(AnAddress: TDbgPtr): Boolean; inline;
|
||||||
|
function IsArtificial: Boolean; inline;
|
||||||
public
|
public
|
||||||
// Scope
|
// Scope
|
||||||
procedure GoParent; inline;
|
procedure GoParent; inline;
|
||||||
@ -586,20 +588,33 @@ type
|
|||||||
private
|
private
|
||||||
FCU: TDwarfCompilationUnit;
|
FCU: TDwarfCompilationUnit;
|
||||||
FInformationEntry: TDwarfInformationEntry;
|
FInformationEntry: TDwarfInformationEntry;
|
||||||
FParentTypeInfo: TDbgDwarfIdentifier;
|
FOwnerTypeInfo: TDbgDwarfIdentifier;
|
||||||
FNestedTypeInfo: TDbgDwarfTypeIdentifier;
|
FNestedTypeInfo: TDbgDwarfTypeIdentifier;
|
||||||
FDwarfReadFlags: set of (didtNameRead, didtTypeRead);
|
FParentTypeInfo: TDbgDwarfIdentifier;
|
||||||
|
FRefByParentCount: Integer;
|
||||||
|
FDwarfReadFlags: set of (didtNameRead, didtTypeRead, didtArtificialRead, didtIsArtifical);
|
||||||
function GetNestedTypeInfo: TDbgDwarfTypeIdentifier;
|
function GetNestedTypeInfo: TDbgDwarfTypeIdentifier;
|
||||||
function GetParentTypeInfo: TDbgDwarfIdentifier;
|
|
||||||
procedure SetParentTypeInfo(AValue: TDbgDwarfIdentifier);
|
procedure SetParentTypeInfo(AValue: TDbgDwarfIdentifier);
|
||||||
protected
|
protected
|
||||||
|
(* There will be a circular reference between parenttype and self
|
||||||
|
"self" will only set its reference to parenttype, if self has other references. *)
|
||||||
|
procedure DoReferenceAdded; override;
|
||||||
|
procedure DoReferenceReleased; override;
|
||||||
|
procedure IncRefByParentCount;
|
||||||
|
procedure DecRefByParentCount;
|
||||||
|
|
||||||
function DoGetNestedTypeInfo: TDbgDwarfTypeIdentifier; virtual;
|
function DoGetNestedTypeInfo: TDbgDwarfTypeIdentifier; virtual;
|
||||||
function ReadMemberVisibility(out AMemberVisibility: TDbgSymbolMemberVisibility): Boolean;
|
function ReadMemberVisibility(out AMemberVisibility: TDbgSymbolMemberVisibility): Boolean;
|
||||||
|
function IsArtificial: Boolean; // usud by formal param and subprogram
|
||||||
procedure NameNeeded; override;
|
procedure NameNeeded; override;
|
||||||
procedure TypeInfoNeeded; override;
|
procedure TypeInfoNeeded; override;
|
||||||
property NestedTypeInfo: TDbgDwarfTypeIdentifier read GetNestedTypeInfo;
|
property NestedTypeInfo: TDbgDwarfTypeIdentifier read GetNestedTypeInfo;
|
||||||
property InformationEntry: TDwarfInformationEntry read FInformationEntry;
|
property InformationEntry: TDwarfInformationEntry read FInformationEntry;
|
||||||
property ParentTypeInfo: TDbgDwarfIdentifier read GetParentTypeInfo write SetParentTypeInfo;
|
|
||||||
|
// OwnerTypeInfo: reverse of "NestedTypeInfo" (variable that is of this type)
|
||||||
|
property OwnerTypeInfo: TDbgDwarfIdentifier read FOwnerTypeInfo; // write SetOwnerTypeInfo;
|
||||||
|
// ParentTypeInfo: funtion for local var / class for member
|
||||||
|
property ParentTypeInfo: TDbgDwarfIdentifier read FParentTypeInfo write SetParentTypeInfo;
|
||||||
|
|
||||||
procedure Init; virtual;
|
procedure Init; virtual;
|
||||||
class function GetSubClass(ATag: Cardinal): TDbgDwarfIdentifierClass;
|
class function GetSubClass(ATag: Cardinal): TDbgDwarfIdentifierClass;
|
||||||
@ -620,9 +635,23 @@ type
|
|||||||
procedure MemberVisibilityNeeded; override;
|
procedure MemberVisibilityNeeded; override;
|
||||||
procedure Init; override;
|
procedure Init; override;
|
||||||
public
|
public
|
||||||
|
destructor Destroy; override;
|
||||||
class function CreateValueSubClass(AName: String; AnInformationEntry: TDwarfInformationEntry): TDbgDwarfValueIdentifier;
|
class function CreateValueSubClass(AName: String; AnInformationEntry: TDwarfInformationEntry): TDbgDwarfValueIdentifier;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TDbgDwarfValueLocationIdentifier }
|
||||||
|
|
||||||
|
TDbgDwarfValueLocationIdentifier = class(TDbgDwarfValueIdentifier)
|
||||||
|
private
|
||||||
|
FLocationParser: TDwarfLocationExpression;
|
||||||
|
procedure FrameBaseNeeded(ASender: TObject);
|
||||||
|
protected
|
||||||
|
procedure InitLocationParser(const ALocationParser: TDwarfLocationExpression); virtual;
|
||||||
|
procedure AddressNeeded; override; // DW_AT_location
|
||||||
|
public
|
||||||
|
destructor Destroy; override;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TDbgDwarfTypeIdentifier }
|
{ TDbgDwarfTypeIdentifier }
|
||||||
TDbgDwarfIdentifierStructure = class;
|
TDbgDwarfIdentifierStructure = class;
|
||||||
|
|
||||||
@ -812,8 +841,9 @@ DECL = DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line
|
|||||||
|
|
||||||
{ TDbgDwarfIdentifierMember }
|
{ TDbgDwarfIdentifierMember }
|
||||||
|
|
||||||
TDbgDwarfIdentifierMember = class(TDbgDwarfValueIdentifier)
|
TDbgDwarfIdentifierMember = class(TDbgDwarfValueLocationIdentifier)
|
||||||
protected
|
protected
|
||||||
|
procedure InitLocationParser(const ALocationParser: TDwarfLocationExpression); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TDbgDwarfIdentifierStructure }
|
{ TDbgDwarfIdentifierStructure }
|
||||||
@ -822,7 +852,7 @@ DECL = DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line
|
|||||||
// record or class
|
// record or class
|
||||||
private
|
private
|
||||||
FMembers: TRefCntObjList;
|
FMembers: TRefCntObjList;
|
||||||
FLastChildByName: TDbgSymbol;
|
FLastChildByName: TDbgDwarfIdentifier;
|
||||||
procedure CreateMembers;
|
procedure CreateMembers;
|
||||||
protected
|
protected
|
||||||
procedure KindNeeded; override;
|
procedure KindNeeded; override;
|
||||||
@ -861,6 +891,7 @@ DECL = DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line
|
|||||||
FAddressInfo: PDwarfAddressInfo;
|
FAddressInfo: PDwarfAddressInfo;
|
||||||
FStateMachine: TDwarfLineInfoStateMachine;
|
FStateMachine: TDwarfLineInfoStateMachine;
|
||||||
FFrameBaseParser: TDwarfLocationExpression;
|
FFrameBaseParser: TDwarfLocationExpression;
|
||||||
|
FSelfParameter: TDbgDwarfValueIdentifier;
|
||||||
function StateMachineValid: Boolean;
|
function StateMachineValid: Boolean;
|
||||||
function ReadVirtuality(out AFlags: TDbgSymbolFlags): Boolean;
|
function ReadVirtuality(out AFlags: TDbgSymbolFlags): Boolean;
|
||||||
protected
|
protected
|
||||||
@ -868,29 +899,26 @@ DECL = DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line
|
|||||||
procedure KindNeeded; override;
|
procedure KindNeeded; override;
|
||||||
procedure SizeNeeded; override;
|
procedure SizeNeeded; override;
|
||||||
function GetFlags: TDbgSymbolFlags; override;
|
function GetFlags: TDbgSymbolFlags; override;
|
||||||
|
function GetSelfParameter(AnAddress: TDbgPtr = 0): TDbgDwarfValueIdentifier;
|
||||||
|
|
||||||
function GetChild(AIndex: Integer): TDbgSymbol; override;
|
|
||||||
function GetColumn: Cardinal; override;
|
function GetColumn: Cardinal; override;
|
||||||
function GetCount: Integer; override;
|
|
||||||
function GetFile: String; override;
|
function GetFile: String; override;
|
||||||
// function GetFlags: TDbgSymbolFlags; override;
|
// function GetFlags: TDbgSymbolFlags; override;
|
||||||
function GetLine: Cardinal; override;
|
function GetLine: Cardinal; override;
|
||||||
// function GetReference: TDbgSymbol; override;
|
|
||||||
public
|
public
|
||||||
constructor Create(ACompilationUnit: TDwarfCompilationUnit; AInfo: PDwarfAddressInfo; AAddress: TDbgPtr); overload;
|
constructor Create(ACompilationUnit: TDwarfCompilationUnit; AInfo: PDwarfAddressInfo; AAddress: TDbgPtr); overload;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
// TODO members = locals ?
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TDbgDwarfIdentifierVariable }
|
{ TDbgDwarfIdentifierVariable }
|
||||||
|
|
||||||
TDbgDwarfIdentifierVariable = class(TDbgDwarfValueIdentifier)
|
TDbgDwarfIdentifierVariable = class(TDbgDwarfValueLocationIdentifier)
|
||||||
private
|
public
|
||||||
FLocationParser: TDwarfLocationExpression;
|
end;
|
||||||
procedure FrameBaseNeeded(ASender: TObject);
|
|
||||||
protected
|
TDbgDwarfIdentifierParameter = class(TDbgDwarfValueLocationIdentifier)
|
||||||
procedure AddressNeeded; override;
|
|
||||||
public
|
public
|
||||||
destructor Destroy; override;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TDbgDwarfUnit }
|
{ TDbgDwarfUnit }
|
||||||
@ -1445,19 +1473,43 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TDbgDwarfIdentifierVariable }
|
{ TDbgDwarfIdentifierMember }
|
||||||
|
|
||||||
procedure TDbgDwarfIdentifierVariable.FrameBaseNeeded(ASender: TObject);
|
procedure TDbgDwarfIdentifierMember.InitLocationParser(const ALocationParser: TDwarfLocationExpression);
|
||||||
|
var
|
||||||
|
owner: TDbgDwarfIdentifier;
|
||||||
|
begin
|
||||||
|
inherited InitLocationParser(ALocationParser);
|
||||||
|
owner := OwnerTypeInfo;
|
||||||
|
while (owner <> nil) and not(owner is TDbgDwarfValueIdentifier) do
|
||||||
|
owner := owner.OwnerTypeInfo;
|
||||||
|
if owner <> nil then
|
||||||
|
ALocationParser.FStack.Push(owner.Address, lseValue);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TDbgDwarfValueLocationIdentifier }
|
||||||
|
|
||||||
|
procedure TDbgDwarfValueLocationIdentifier.InitLocationParser(const ALocationParser: TDwarfLocationExpression);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDbgDwarfValueLocationIdentifier.FrameBaseNeeded(ASender: TObject);
|
||||||
var
|
var
|
||||||
p: TDbgDwarfIdentifier;
|
p: TDbgDwarfIdentifier;
|
||||||
begin
|
begin
|
||||||
debugln(['TDbgDwarfIdentifierVariable.FrameBaseNeeded ']);
|
debugln(['TDbgDwarfIdentifierVariable.FrameBaseNeeded ']);
|
||||||
p := ParentTypeInfo;
|
p := ParentTypeInfo;
|
||||||
if (p <> nil) and (p is TDbgDwarfProcSymbol) then
|
if (p <> nil) and (p is TDbgDwarfProcSymbol) then
|
||||||
(ASender as TDwarfLocationExpression).FFrameBase := TDbgDwarfProcSymbol(p).GetFrameBase;
|
(ASender as TDwarfLocationExpression).FFrameBase := TDbgDwarfProcSymbol(p).GetFrameBase
|
||||||
|
;
|
||||||
|
{$warning TODO}
|
||||||
|
//else
|
||||||
|
//if OwnerTypeInfo <> nil then
|
||||||
|
// OwnerTypeInfo.fr;
|
||||||
|
// TODO: check owner
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDbgDwarfIdentifierVariable.AddressNeeded;
|
procedure TDbgDwarfValueLocationIdentifier.AddressNeeded;
|
||||||
var
|
var
|
||||||
Val: TByteDynArray;
|
Val: TByteDynArray;
|
||||||
begin
|
begin
|
||||||
@ -1480,6 +1532,7 @@ DebugLnEnter(['>> TDbgDwarfIdentifierVariable.AddressNeeded ']); try
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
FLocationParser := TDwarfLocationExpression.Create(@Val[0], Length(Val), FCU);
|
FLocationParser := TDwarfLocationExpression.Create(@Val[0], Length(Val), FCU);
|
||||||
|
InitLocationParser(FLocationParser);
|
||||||
FLocationParser.OnFrameBaseNeeded := @FrameBaseNeeded;
|
FLocationParser.OnFrameBaseNeeded := @FrameBaseNeeded;
|
||||||
FLocationParser.Evaluate;
|
FLocationParser.Evaluate;
|
||||||
end;
|
end;
|
||||||
@ -1491,7 +1544,7 @@ DebugLnEnter(['>> TDbgDwarfIdentifierVariable.AddressNeeded ']); try
|
|||||||
finally DebugLnExit(['<< TDbgDwarfIdentifierVariable.AddressNeeded ']); end;
|
finally DebugLnExit(['<< TDbgDwarfIdentifierVariable.AddressNeeded ']); end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TDbgDwarfIdentifierVariable.Destroy;
|
destructor TDbgDwarfValueLocationIdentifier.Destroy;
|
||||||
begin
|
begin
|
||||||
FreeAndNil(FLocationParser);
|
FreeAndNil(FLocationParser);
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
@ -2661,7 +2714,8 @@ DebugLn(['p=',p^, ' , ', FData^, ' Cnt=',FStack.Count, ' top=',FStack.Peek(0).Va
|
|||||||
if not AssertMinCount(2) then exit;
|
if not AssertMinCount(2) then exit;
|
||||||
Entry := FStack.Pop;
|
Entry := FStack.Pop;
|
||||||
Entry2 := FStack.Peek(0);
|
Entry2 := FStack.Peek(0);
|
||||||
FStack.Modify(0, Entry2.Value div (1 shl Entry.Value), lseValue);
|
if Entry.Value > 0 then
|
||||||
|
FStack.Modify(0, Entry2.Value div (1 shl (Entry.Value - 1)), lseValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
DW_OP_skip: begin
|
DW_OP_skip: begin
|
||||||
@ -2742,7 +2796,11 @@ DebugLn(['p=',p^, ' , ', FData^, ' Cnt=',FStack.Count, ' top=',FStack.Peek(0).Va
|
|||||||
DW_OP_bit_piece = $9d; // 2
|
DW_OP_bit_piece = $9d; // 2
|
||||||
*)
|
*)
|
||||||
else
|
else
|
||||||
debugln(['TDwarfLocationExpression.Evaluate UNKNOWN ', p^]);
|
begin
|
||||||
|
debugln(['TDwarfLocationExpression.Evaluate UNKNOWN ', p^]);
|
||||||
|
SetError;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -3312,6 +3370,23 @@ begin
|
|||||||
Result := False;
|
Result := False;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TDwarfInformationEntry.IsAddressInStartScope(AnAddress: TDbgPtr): Boolean;
|
||||||
|
var
|
||||||
|
StartScope: TDbgPtr;
|
||||||
|
begin
|
||||||
|
Result := not ReadStartScope(StartScope);
|
||||||
|
if Result then exit; // no startscope, always in scope
|
||||||
|
Result := AnAddress >= StartScope;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TDwarfInformationEntry.IsArtificial: Boolean;
|
||||||
|
var
|
||||||
|
Val: Integer;
|
||||||
|
begin
|
||||||
|
Result := ReadValue(DW_AT_artificial, Val);
|
||||||
|
if Result then Result := Val <> 0;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TDbgDwarfUnit }
|
{ TDbgDwarfUnit }
|
||||||
|
|
||||||
procedure TDbgDwarfUnit.Init;
|
procedure TDbgDwarfUnit.Init;
|
||||||
@ -3333,6 +3408,7 @@ begin
|
|||||||
Ident.GoNamedChildEx(AIndex);
|
Ident.GoNamedChildEx(AIndex);
|
||||||
if Ident <> nil then
|
if Ident <> nil then
|
||||||
Result := TDbgDwarfIdentifier.CreateSubClass('', Ident);
|
Result := TDbgDwarfIdentifier.CreateSubClass('', Ident);
|
||||||
|
// No need to set ParentTypeInfo
|
||||||
ReleaseRefAndNil(Ident);
|
ReleaseRefAndNil(Ident);
|
||||||
FLastChildByName := Result;
|
FLastChildByName := Result;
|
||||||
end;
|
end;
|
||||||
@ -3585,6 +3661,8 @@ begin
|
|||||||
sym := TDbgDwarfIdentifier.CreateSubClass('', Info2);
|
sym := TDbgDwarfIdentifier.CreateSubClass('', Info2);
|
||||||
FMembers.Add(sym);
|
FMembers.Add(sym);
|
||||||
sym.ReleaseReference;
|
sym.ReleaseReference;
|
||||||
|
sym.IncRefByParentCount;
|
||||||
|
sym.ParentTypeInfo := self;
|
||||||
Info2.ReleaseReference;
|
Info2.ReleaseReference;
|
||||||
end;
|
end;
|
||||||
Info.GoNext;
|
Info.GoNext;
|
||||||
@ -3658,8 +3736,17 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TDbgDwarfIdentifierEnum.Destroy;
|
destructor TDbgDwarfIdentifierEnum.Destroy;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
FreeAndNil(FMembers);
|
if FMembers <> nil then begin
|
||||||
|
for i := 0 to FMembers.Count - 1 do
|
||||||
|
with TDbgDwarfIdentifier(FMembers[i]) do begin
|
||||||
|
ParentTypeInfo := nil;
|
||||||
|
DecRefByParentCount;
|
||||||
|
end;
|
||||||
|
FreeAndNil(FMembers);
|
||||||
|
end;
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -3781,6 +3868,12 @@ begin
|
|||||||
SetSymbolType(stValue);
|
SetSymbolType(stValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
destructor TDbgDwarfValueIdentifier.Destroy;
|
||||||
|
begin
|
||||||
|
ParentTypeInfo := nil;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
class function TDbgDwarfValueIdentifier.CreateValueSubClass(AName: String;
|
class function TDbgDwarfValueIdentifier.CreateValueSubClass(AName: String;
|
||||||
AnInformationEntry: TDwarfInformationEntry): TDbgDwarfValueIdentifier;
|
AnInformationEntry: TDwarfInformationEntry): TDbgDwarfValueIdentifier;
|
||||||
var
|
var
|
||||||
@ -3816,6 +3909,8 @@ begin
|
|||||||
sym := TDbgDwarfIdentifier.CreateSubClass('', Info2);
|
sym := TDbgDwarfIdentifier.CreateSubClass('', Info2);
|
||||||
FMembers.Add(sym);
|
FMembers.Add(sym);
|
||||||
sym.ReleaseReference;
|
sym.ReleaseReference;
|
||||||
|
sym.IncRefByParentCount;
|
||||||
|
sym.ParentTypeInfo := self;
|
||||||
Info2.ReleaseReference;
|
Info2.ReleaseReference;
|
||||||
end;
|
end;
|
||||||
Info.GoNext;
|
Info.GoNext;
|
||||||
@ -3876,8 +3971,17 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TDbgDwarfIdentifierArray.Destroy;
|
destructor TDbgDwarfIdentifierArray.Destroy;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
FreeAndNil(FMembers);
|
if FMembers <> nil then begin
|
||||||
|
for i := 0 to FMembers.Count - 1 do
|
||||||
|
with TDbgDwarfIdentifier(FMembers[i]) do begin
|
||||||
|
ParentTypeInfo := nil;
|
||||||
|
DecRefByParentCount;
|
||||||
|
end;
|
||||||
|
FreeAndNil(FMembers);
|
||||||
|
end;
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -3889,26 +3993,28 @@ var
|
|||||||
ti: TDbgSymbol;
|
ti: TDbgSymbol;
|
||||||
begin
|
begin
|
||||||
// Todo, maybe create all children?
|
// Todo, maybe create all children?
|
||||||
ReleaseRefAndNil(FLastChildByName);
|
if FLastChildByName <> nil then begin
|
||||||
|
FLastChildByName.ParentTypeInfo := nil;
|
||||||
|
FLastChildByName.DecRefByParentCount;
|
||||||
|
ReleaseRefAndNil(FLastChildByName);
|
||||||
|
end;
|
||||||
Result := nil;
|
Result := nil;
|
||||||
|
|
||||||
Ident := FInformationEntry.FindNamedChild(AIndex);
|
Ident := FInformationEntry.FindNamedChild(AIndex);
|
||||||
if Ident <> nil then
|
if Ident <> nil then begin
|
||||||
Result := TDbgDwarfIdentifier.CreateSubClass('', Ident);
|
FLastChildByName := TDbgDwarfIdentifier.CreateSubClass('', Ident);
|
||||||
//assert is member ?
|
FLastChildByName.IncRefByParentCount;
|
||||||
ReleaseRefAndNil(Ident);
|
FLastChildByName.ParentTypeInfo := self;
|
||||||
FLastChildByName := Result;
|
//assert is member ?
|
||||||
if (Result <> nil) then
|
ReleaseRefAndNil(Ident);
|
||||||
exit;
|
Result := FLastChildByName;
|
||||||
|
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
ti := TypeInfo; // Parent
|
ti := TypeInfo; // Parent
|
||||||
if ti <> nil then begin
|
if ti <> nil then
|
||||||
Result := ti.MemberByName[AIndex];
|
Result := ti.MemberByName[AIndex];
|
||||||
FLastChildByName := Result;
|
|
||||||
if FLastChildByName <> nil then
|
|
||||||
FLastChildByName.AddReference;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDbgDwarfIdentifierStructure.GetMemberCount: Integer;
|
function TDbgDwarfIdentifierStructure.GetMemberCount: Integer;
|
||||||
@ -3924,9 +4030,22 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TDbgDwarfIdentifierStructure.Destroy;
|
destructor TDbgDwarfIdentifierStructure.Destroy;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
ReleaseRefAndNil(FLastChildByName);
|
if FMembers <> nil then begin
|
||||||
FreeAndNil(FMembers);
|
for i := 0 to FMembers.Count - 1 do
|
||||||
|
with TDbgDwarfIdentifier(FMembers[i]) do begin
|
||||||
|
ParentTypeInfo := nil;
|
||||||
|
DecRefByParentCount;
|
||||||
|
end;
|
||||||
|
FreeAndNil(FMembers);
|
||||||
|
end;
|
||||||
|
if FLastChildByName <> nil then begin
|
||||||
|
FLastChildByName.ParentTypeInfo := nil;
|
||||||
|
FLastChildByName.DecRefByParentCount;
|
||||||
|
ReleaseRefAndNil(FLastChildByName);
|
||||||
|
end;
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -3948,6 +4067,8 @@ begin
|
|||||||
sym := TDbgDwarfIdentifier.CreateSubClass('', Info2);
|
sym := TDbgDwarfIdentifier.CreateSubClass('', Info2);
|
||||||
FMembers.Add(sym);
|
FMembers.Add(sym);
|
||||||
sym.ReleaseReference;
|
sym.ReleaseReference;
|
||||||
|
sym.IncRefByParentCount;
|
||||||
|
sym.ParentTypeInfo := self;
|
||||||
Info2.ReleaseReference;
|
Info2.ReleaseReference;
|
||||||
end;
|
end;
|
||||||
Info.GoNext;
|
Info.GoNext;
|
||||||
@ -4114,32 +4235,53 @@ begin
|
|||||||
Result := FNestedTypeInfo;
|
Result := FNestedTypeInfo;
|
||||||
if (Result <> nil) or (didtTypeRead in FDwarfReadFlags) then
|
if (Result <> nil) or (didtTypeRead in FDwarfReadFlags) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
include(FDwarfReadFlags, didtTypeRead);
|
include(FDwarfReadFlags, didtTypeRead);
|
||||||
FNestedTypeInfo := DoGetNestedTypeInfo;
|
FNestedTypeInfo := DoGetNestedTypeInfo;
|
||||||
|
if FNestedTypeInfo <> nil then
|
||||||
|
FNestedTypeInfo.FOwnerTypeInfo := Self;
|
||||||
Result := FNestedTypeInfo;
|
Result := FNestedTypeInfo;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDbgDwarfIdentifier.GetParentTypeInfo: TDbgDwarfIdentifier;
|
|
||||||
var
|
|
||||||
ti: TDwarfInformationEntry;
|
|
||||||
begin
|
|
||||||
Result := FParentTypeInfo;
|
|
||||||
if Result <> nil then
|
|
||||||
exit;
|
|
||||||
|
|
||||||
ti := FInformationEntry.Clone;
|
|
||||||
ti.GoParent;
|
|
||||||
if ti.HasValidScope then begin
|
|
||||||
FParentTypeInfo := TDbgDwarfIdentifier.CreateSubClass('', ti);
|
|
||||||
Result := FParentTypeInfo;
|
|
||||||
end;
|
|
||||||
|
|
||||||
ti.ReleaseReference;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TDbgDwarfIdentifier.SetParentTypeInfo(AValue: TDbgDwarfIdentifier);
|
procedure TDbgDwarfIdentifier.SetParentTypeInfo(AValue: TDbgDwarfIdentifier);
|
||||||
begin
|
begin
|
||||||
|
if FParentTypeInfo = AValue then exit;
|
||||||
|
|
||||||
|
if (RefCount > FRefByParentCount) and (FParentTypeInfo <> nil) then
|
||||||
|
FParentTypeInfo.ReleaseReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FParentTypeInfo, 'FParentTypeInfo'){$ENDIF};
|
||||||
|
|
||||||
FParentTypeInfo := AValue;
|
FParentTypeInfo := AValue;
|
||||||
|
|
||||||
|
if (RefCount > FRefByParentCount) and (FParentTypeInfo <> nil) then
|
||||||
|
FParentTypeInfo.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FParentTypeInfo, 'FParentTypeInfo'){$ENDIF};
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDbgDwarfIdentifier.DoReferenceAdded;
|
||||||
|
begin
|
||||||
|
inherited DoReferenceAdded;
|
||||||
|
if (RefCount = FRefByParentCount + 1) and (FParentTypeInfo <> nil) then
|
||||||
|
FParentTypeInfo.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FParentTypeInfo, 'FParentTypeInfo'){$ENDIF};
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDbgDwarfIdentifier.DoReferenceReleased;
|
||||||
|
begin
|
||||||
|
inherited DoReferenceReleased;
|
||||||
|
if (RefCount = FRefByParentCount) and (FParentTypeInfo <> nil) then
|
||||||
|
FParentTypeInfo.ReleaseReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FParentTypeInfo, 'FParentTypeInfo'){$ENDIF};
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDbgDwarfIdentifier.IncRefByParentCount;
|
||||||
|
begin
|
||||||
|
inc(FRefByParentCount);
|
||||||
|
if (RefCount = FRefByParentCount) and (FParentTypeInfo <> nil) then
|
||||||
|
FParentTypeInfo.ReleaseReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FParentTypeInfo, 'FParentTypeInfo'){$ENDIF};
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDbgDwarfIdentifier.DecRefByParentCount;
|
||||||
|
begin
|
||||||
|
dec(FRefByParentCount);
|
||||||
|
if (RefCount = FRefByParentCount + 1) and (FParentTypeInfo <> nil) then
|
||||||
|
FParentTypeInfo.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FParentTypeInfo, 'FParentTypeInfo'){$ENDIF};
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDbgDwarfIdentifier.DoGetNestedTypeInfo: TDbgDwarfTypeIdentifier;
|
function TDbgDwarfIdentifier.DoGetNestedTypeInfo: TDbgDwarfTypeIdentifier;
|
||||||
@ -4179,6 +4321,16 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TDbgDwarfIdentifier.IsArtificial: Boolean;
|
||||||
|
begin
|
||||||
|
if not(didtArtificialRead in FDwarfReadFlags) then begin
|
||||||
|
if FInformationEntry.IsArtificial then
|
||||||
|
Include(FDwarfReadFlags, didtIsArtifical);
|
||||||
|
Include(FDwarfReadFlags, didtArtificialRead);
|
||||||
|
end;
|
||||||
|
Result := didtIsArtifical in FDwarfReadFlags;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TDbgDwarfIdentifier.NameNeeded;
|
procedure TDbgDwarfIdentifier.NameNeeded;
|
||||||
var
|
var
|
||||||
AName: String;
|
AName: String;
|
||||||
@ -4203,7 +4355,6 @@ class function TDbgDwarfIdentifier.GetSubClass(ATag: Cardinal): TDbgDwarfIdentif
|
|||||||
begin
|
begin
|
||||||
case ATag of
|
case ATag of
|
||||||
// TODO:
|
// TODO:
|
||||||
DW_TAG_formal_parameter,
|
|
||||||
DW_TAG_constant:
|
DW_TAG_constant:
|
||||||
Result := TDbgDwarfValueIdentifier;
|
Result := TDbgDwarfValueIdentifier;
|
||||||
DW_TAG_string_type,
|
DW_TAG_string_type,
|
||||||
@ -4230,6 +4381,7 @@ begin
|
|||||||
DW_TAG_array_type: Result := TDbgDwarfIdentifierArray;
|
DW_TAG_array_type: Result := TDbgDwarfIdentifierArray;
|
||||||
// Value types
|
// Value types
|
||||||
DW_TAG_variable: Result := TDbgDwarfIdentifierVariable;
|
DW_TAG_variable: Result := TDbgDwarfIdentifierVariable;
|
||||||
|
DW_TAG_formal_parameter: Result := TDbgDwarfIdentifierParameter;
|
||||||
DW_TAG_member: Result := TDbgDwarfIdentifierMember;
|
DW_TAG_member: Result := TDbgDwarfIdentifierMember;
|
||||||
DW_TAG_subprogram: Result := TDbgDwarfProcSymbol;
|
DW_TAG_subprogram: Result := TDbgDwarfProcSymbol;
|
||||||
//
|
//
|
||||||
@ -4274,6 +4426,10 @@ begin
|
|||||||
ReleaseRefAndNil(FInformationEntry);
|
ReleaseRefAndNil(FInformationEntry);
|
||||||
ReleaseRefAndNil(FNestedTypeInfo);
|
ReleaseRefAndNil(FNestedTypeInfo);
|
||||||
ReleaseRefAndNil(FParentTypeInfo);
|
ReleaseRefAndNil(FParentTypeInfo);
|
||||||
|
if FNestedTypeInfo <> nil then begin
|
||||||
|
assert((FNestedTypeInfo.FOwnerTypeInfo = nil) or (FNestedTypeInfo.FOwnerTypeInfo= self), 'FNestedTypeInfo.FOwnerTypeInfo is nil or self');
|
||||||
|
FNestedTypeInfo.FOwnerTypeInfo := nil;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDbgDwarfIdentifier.StartScope: TDbgPtr;
|
function TDbgDwarfIdentifier.StartScope: TDbgPtr;
|
||||||
@ -4349,14 +4505,14 @@ end;
|
|||||||
destructor TDbgDwarfProcSymbol.Destroy;
|
destructor TDbgDwarfProcSymbol.Destroy;
|
||||||
begin
|
begin
|
||||||
FreeAndNil(FStateMachine);
|
FreeAndNil(FStateMachine);
|
||||||
|
if FSelfParameter <> nil then begin
|
||||||
|
FSelfParameter.ParentTypeInfo := nil;
|
||||||
|
FSelfParameter.DecRefByParentCount;
|
||||||
|
FSelfParameter.ReleaseReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FSelfParameter, 'FSelfParameter'){$ENDIF};
|
||||||
|
end;
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDbgDwarfProcSymbol.GetChild(AIndex: Integer): TDbgSymbol;
|
|
||||||
begin
|
|
||||||
Result:=inherited GetChild(AIndex);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TDbgDwarfProcSymbol.GetColumn: Cardinal;
|
function TDbgDwarfProcSymbol.GetColumn: Cardinal;
|
||||||
begin
|
begin
|
||||||
if StateMachineValid
|
if StateMachineValid
|
||||||
@ -4364,11 +4520,6 @@ begin
|
|||||||
else Result := inherited GetColumn;
|
else Result := inherited GetColumn;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDbgDwarfProcSymbol.GetCount: Integer;
|
|
||||||
begin
|
|
||||||
Result:=inherited GetCount;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TDbgDwarfProcSymbol.GetFile: String;
|
function TDbgDwarfProcSymbol.GetFile: String;
|
||||||
begin
|
begin
|
||||||
if StateMachineValid
|
if StateMachineValid
|
||||||
@ -4490,6 +4641,43 @@ begin
|
|||||||
Result := Result + flg;
|
Result := Result + flg;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TDbgDwarfProcSymbol.GetSelfParameter(AnAddress: TDbgPtr): TDbgDwarfValueIdentifier;
|
||||||
|
const
|
||||||
|
this1: string = 'THIS';
|
||||||
|
this2: string = 'this';
|
||||||
|
var
|
||||||
|
InfoEntry: TDwarfInformationEntry;
|
||||||
|
tg: Cardinal;
|
||||||
|
begin
|
||||||
|
// special: search "self"
|
||||||
|
// Todo nested procs
|
||||||
|
Result := FSelfParameter;
|
||||||
|
if Result <> nil then exit;
|
||||||
|
|
||||||
|
InfoEntry := InformationEntry.Clone;
|
||||||
|
//StartScopeIdx := InfoEntry.ScopeIndex;
|
||||||
|
InfoEntry.GoParent;
|
||||||
|
tg := InfoEntry.AbbrevTag;
|
||||||
|
if (tg = DW_TAG_class_type) or (tg = DW_TAG_structure_type) then begin
|
||||||
|
InfoEntry.ScopeIndex := InformationEntry.ScopeIndex;
|
||||||
|
if InfoEntry.GoNamedChildEx(@this1[1], @this2[1]) then begin
|
||||||
|
if ((AnAddress = 0) or InfoEntry.IsAddressInStartScope(AnAddress)) and
|
||||||
|
InfoEntry.IsArtificial
|
||||||
|
then begin
|
||||||
|
Result := TDbgDwarfValueIdentifier.CreateValueSubClass('self', InfoEntry);
|
||||||
|
FSelfParameter := Result;
|
||||||
|
{$IFDEF WITH_REFCOUNT_DEBUG} // Rename the ref
|
||||||
|
FSelfParameter.AddReference(@FSelfParameter, 'FSelfParameter'); FSelfParameter.ReleaseReference;
|
||||||
|
{$ENDIF}
|
||||||
|
FSelfParameter.IncRefByParentCount;
|
||||||
|
FSelfParameter.ParentTypeInfo := Self;
|
||||||
|
debugln(['TDbgDwarfProcSymbol.GetSelfParameter ', dbgs(InfoEntry.FScope, FCU), DbgSName(Result)]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
InfoEntry.ReleaseReference;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TDbgDwarf }
|
{ TDbgDwarf }
|
||||||
|
|
||||||
constructor TDbgDwarf.Create(ALoader: TDbgImageLoader);
|
constructor TDbgDwarf.Create(ALoader: TDbgImageLoader);
|
||||||
@ -5814,12 +6002,12 @@ begin
|
|||||||
FAddress := AnAddress;
|
FAddress := AnAddress;
|
||||||
FDwarf := ADwarf;
|
FDwarf := ADwarf;
|
||||||
FSymbol := ASymbol;
|
FSymbol := ASymbol;
|
||||||
FSymbol.AddReference;
|
FSymbol.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FSymbol, 'Context to Symbol'){$ENDIF};
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TDbgDwarfInfoAddressContext.Destroy;
|
destructor TDbgDwarfInfoAddressContext.Destroy;
|
||||||
begin
|
begin
|
||||||
FSymbol.ReleaseReference;
|
FSymbol.ReleaseReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FSymbol, 'Context to Symbol'){$ENDIF};
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -5835,7 +6023,7 @@ var
|
|||||||
FwdInfoPtr: Pointer;
|
FwdInfoPtr: Pointer;
|
||||||
tg: Cardinal;
|
tg: Cardinal;
|
||||||
p1, p2: PChar;
|
p1, p2: PChar;
|
||||||
StartScope: TDbgPtr;
|
SelfParam: TDbgDwarfValueIdentifier;
|
||||||
begin
|
begin
|
||||||
Result := nil;
|
Result := nil;
|
||||||
if (FSymbol = nil) or not(FSymbol is TDbgDwarfProcSymbol) or (AName = '') then
|
if (FSymbol = nil) or not(FSymbol is TDbgDwarfProcSymbol) or (AName = '') then
|
||||||
@ -5853,6 +6041,16 @@ begin
|
|||||||
//InfoEntry := TDwarfInformationEntry.Create(CU, nil);
|
//InfoEntry := TDwarfInformationEntry.Create(CU, nil);
|
||||||
//InfoEntry.ScopeIndex := SubRoutine.FAddressInfo^.ScopeIndex;
|
//InfoEntry.ScopeIndex := SubRoutine.FAddressInfo^.ScopeIndex;
|
||||||
|
|
||||||
|
// special: search "self"
|
||||||
|
// Todo nested procs
|
||||||
|
if s2 = 'self' then begin
|
||||||
|
Result := SubRoutine.GetSelfParameter(FAddress);
|
||||||
|
if Result <> nil then begin
|
||||||
|
Result.AddReference;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
while InfoEntry.HasValidScope do begin
|
while InfoEntry.HasValidScope do begin
|
||||||
debugln(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier Searching ', dbgs(InfoEntry.FScope, CU)]);
|
debugln(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier Searching ', dbgs(InfoEntry.FScope, CU)]);
|
||||||
StartScopeIdx := InfoEntry.ScopeIndex;
|
StartScopeIdx := InfoEntry.ScopeIndex;
|
||||||
@ -5860,17 +6058,15 @@ begin
|
|||||||
//if InfoEntry.Abbrev = nil then
|
//if InfoEntry.Abbrev = nil then
|
||||||
// exit;
|
// exit;
|
||||||
|
|
||||||
if InfoEntry.ReadStartScope(StartScope)
|
if not InfoEntry.IsAddressInStartScope(FAddress) // StartScope = first valid address
|
||||||
then begin
|
then begin
|
||||||
if StartScope > FAddress then begin
|
// CONTINUE: Search parent(s)
|
||||||
// CONTINUE: Search parent(s)
|
InfoEntry.ScopeIndex := StartScopeIdx;
|
||||||
InfoEntry.ScopeIndex := StartScopeIdx;
|
InfoEntry.GoParent;
|
||||||
InfoEntry.GoParent;
|
Continue;
|
||||||
Continue;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if InfoEntry.ReadName(InfoName)
|
if InfoEntry.ReadName(InfoName) and not InfoEntry.IsArtificial
|
||||||
then begin
|
then begin
|
||||||
if (CompareUtf8BothCase(p1, p2, InfoName)) then begin
|
if (CompareUtf8BothCase(p1, p2, InfoName)) then begin
|
||||||
Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntry);
|
Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntry);
|
||||||
@ -5882,16 +6078,33 @@ begin
|
|||||||
tg := InfoEntry.AbbrevTag;
|
tg := InfoEntry.AbbrevTag;
|
||||||
|
|
||||||
if InfoEntry.GoNamedChildEx(p1, p2) then begin
|
if InfoEntry.GoNamedChildEx(p1, p2) then begin
|
||||||
if not InfoEntry.ReadStartScope(StartScope) then
|
if InfoEntry.IsAddressInStartScope(FAddress) and not InfoEntry.IsArtificial then begin
|
||||||
StartScope := 0;
|
if (tg = DW_TAG_class_type) or (tg = DW_TAG_structure_type) then begin
|
||||||
if StartScope <= FAddress then begin
|
// access via self
|
||||||
Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntry);
|
SelfParam := SubRoutine.GetSelfParameter(FAddress);
|
||||||
|
if (SelfParam <> nil) then begin
|
||||||
|
// TODO: only valid, as long as context is valid, because if comnext is freed, then self is lost too
|
||||||
|
Result := SelfParam.TypeInfo.MemberByName[AName];
|
||||||
|
Result.AddReference;
|
||||||
|
if Result<> nil then debugln(['TDbgDwarfInfoAddressContext.FindSymbol SELF !!!!!!!!!!!!!'])
|
||||||
|
else debugln(['TDbgDwarfInfoAddressContext.FindSymbol ????????????????']);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if Result = nil then
|
||||||
|
Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntry);
|
||||||
|
|
||||||
|
// TODO: nested
|
||||||
|
if (StartScopeIdx = SubRoutine.InformationEntry.ScopeIndex) then // searching in subroutine
|
||||||
|
TDbgDwarfIdentifier(Result).ParentTypeInfo := SubRoutine;
|
||||||
|
|
||||||
DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier found ', dbgs(InfoEntry.FScope, CU), DbgSName(Result)]);
|
DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier found ', dbgs(InfoEntry.FScope, CU), DbgSName(Result)]);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if (tg = DW_TAG_class_type) or (tg = DW_TAG_structure_type) then begin
|
if (tg = DW_TAG_class_type) or (tg = DW_TAG_structure_type) then begin
|
||||||
|
// TODO: only search most inner class (if classes can be nested.
|
||||||
|
// outer classes static data may be available.
|
||||||
// search parent class
|
// search parent class
|
||||||
InfoEntry.ScopeIndex := StartScopeIdx;
|
InfoEntry.ScopeIndex := StartScopeIdx;
|
||||||
InfoEntryParent := InfoEntry.FindChildByTag(DW_TAG_inheritance);
|
InfoEntryParent := InfoEntry.FindChildByTag(DW_TAG_inheritance);
|
||||||
@ -5900,16 +6113,24 @@ begin
|
|||||||
InfoEntryParent := TDwarfInformationEntry.Create(FwdCompUint, FwdInfoPtr);
|
InfoEntryParent := TDwarfInformationEntry.Create(FwdCompUint, FwdInfoPtr);
|
||||||
DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier PARENT ', dbgs(InfoEntryParent, FwdCompUint) ]);
|
DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier PARENT ', dbgs(InfoEntryParent, FwdCompUint) ]);
|
||||||
|
|
||||||
if InfoEntryParent.ReadStartScope(StartScope) then
|
if not InfoEntry.IsAddressInStartScope(FAddress) then
|
||||||
if StartScope > FAddress then
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
InfoEntryTmp := InfoEntryParent.FindChildByTag(DW_TAG_inheritance);
|
InfoEntryTmp := InfoEntryParent.FindChildByTag(DW_TAG_inheritance);
|
||||||
if InfoEntryParent.GoNamedChildEx(p1, p2) then begin
|
if InfoEntryParent.GoNamedChildEx(p1, p2) then begin
|
||||||
if not InfoEntryParent.ReadStartScope(StartScope) then
|
if InfoEntry.IsAddressInStartScope(FAddress) then begin
|
||||||
StartScope := 0;
|
SelfParam := SubRoutine.GetSelfParameter(FAddress);
|
||||||
if StartScope <= FAddress then begin
|
if (SelfParam <> nil) then begin
|
||||||
Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntryParent);
|
// TODO: only valid, as long as context is valid, because if comnext is freed, then self is lost too
|
||||||
|
Result := SelfParam.TypeInfo.MemberByName[AName];
|
||||||
|
Result.AddReference;
|
||||||
|
if Result<> nil then debugln(['TDbgDwarfInfoAddressContext.FindSymbol SELF !!!!!!!!!!!!!'])
|
||||||
|
else debugln(['TDbgDwarfInfoAddressContext.FindSymbol ????????????????']);
|
||||||
|
end
|
||||||
|
else debugln(['TDbgDwarfInfoAddressContext.FindSymbol XXXXXXXXXXXXX no self']);
|
||||||
|
;
|
||||||
|
if Result = nil then
|
||||||
|
Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntryParent);
|
||||||
InfoEntryParent.ReleaseReference;
|
InfoEntryParent.ReleaseReference;
|
||||||
InfoEntryTmp.ReleaseReference;
|
InfoEntryTmp.ReleaseReference;
|
||||||
DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier found ', dbgs(InfoEntryParent.FScope, CU), DbgSName(Result)]);
|
DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier found ', dbgs(InfoEntryParent.FScope, CU), DbgSName(Result)]);
|
||||||
@ -5952,9 +6173,7 @@ begin
|
|||||||
|
|
||||||
CU2.ScanAllEntries;
|
CU2.ScanAllEntries;
|
||||||
if InfoEntry.GoNamedChildEx(p1, p2) then begin
|
if InfoEntry.GoNamedChildEx(p1, p2) then begin
|
||||||
if not InfoEntry.ReadStartScope(StartScope) then
|
if InfoEntry.IsAddressInStartScope(FAddress) then begin
|
||||||
StartScope := 0;
|
|
||||||
if StartScope <= FAddress then begin
|
|
||||||
// only variables are marked "external", but types not / so we may need all top level
|
// only variables are marked "external", but types not / so we may need all top level
|
||||||
Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntry);
|
Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntry);
|
||||||
DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier found (other unit) ', dbgs(InfoEntry.FScope, CU2), DbgSName(Result)]);
|
DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier found (other unit) ', dbgs(InfoEntry.FScope, CU2), DbgSName(Result)]);
|
||||||
|
@ -106,6 +106,7 @@ type
|
|||||||
FAddress: TDbgPtr;
|
FAddress: TDbgPtr;
|
||||||
FSize: Integer;
|
FSize: Integer;
|
||||||
FTypeInfo: TDbgSymbol;
|
FTypeInfo: TDbgSymbol;
|
||||||
|
FReference: TDbgSymbol;
|
||||||
FMemberVisibility: TDbgSymbolMemberVisibility;
|
FMemberVisibility: TDbgSymbolMemberVisibility;
|
||||||
|
|
||||||
function GetSymbolType: TDbgSymbolType; inline;
|
function GetSymbolType: TDbgSymbolType; inline;
|
||||||
@ -123,8 +124,9 @@ type
|
|||||||
function GetFile: String; virtual;
|
function GetFile: String; virtual;
|
||||||
function GetFlags: TDbgSymbolFlags; virtual;
|
function GetFlags: TDbgSymbolFlags; virtual;
|
||||||
function GetLine: Cardinal; virtual;
|
function GetLine: Cardinal; virtual;
|
||||||
function GetParent: TDbgSymbol; virtual;
|
procedure SetReference(AValue: TDbgSymbol); virtual;
|
||||||
function GetReference: TDbgSymbol; virtual;
|
function GetReference: TDbgSymbol; virtual;
|
||||||
|
function GetParent: TDbgSymbol; virtual;
|
||||||
|
|
||||||
function GetValueObject: TDbgSymbolValue; virtual;
|
function GetValueObject: TDbgSymbolValue; virtual;
|
||||||
function GetHasOrdinalValue: Boolean; virtual;
|
function GetHasOrdinalValue: Boolean; virtual;
|
||||||
@ -185,7 +187,8 @@ type
|
|||||||
//
|
//
|
||||||
property Flags: TDbgSymbolFlags read GetFlags;
|
property Flags: TDbgSymbolFlags read GetFlags;
|
||||||
property Count: Integer read GetCount; deprecated;
|
property Count: Integer read GetCount; deprecated;
|
||||||
property Reference: TDbgSymbol read GetReference; deprecated;
|
// 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 Parent: TDbgSymbol read GetParent; deprecated;
|
||||||
//property Children[AIndex: Integer]: TDbgSymbol read GetChild;
|
//property Children[AIndex: Integer]: TDbgSymbol read GetChild;
|
||||||
// VALUE
|
// VALUE
|
||||||
@ -296,8 +299,8 @@ end;
|
|||||||
|
|
||||||
destructor TDbgSymbol.Destroy;
|
destructor TDbgSymbol.Destroy;
|
||||||
begin
|
begin
|
||||||
|
SetTypeInfo(nil);
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
ReleaseRefAndNil(FTypeInfo);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDbgSymbol.GetAddress: TDbgPtr;
|
function TDbgSymbol.GetAddress: TDbgPtr;
|
||||||
@ -321,6 +324,11 @@ begin
|
|||||||
Result := FMemberVisibility;
|
Result := FMemberVisibility;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TDbgSymbol.SetReference(AValue: TDbgSymbol);
|
||||||
|
begin
|
||||||
|
FReference := AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
function TDbgSymbol.GetValueObject: TDbgSymbolValue;
|
function TDbgSymbol.GetValueObject: TDbgSymbolValue;
|
||||||
begin
|
begin
|
||||||
Result := nil;
|
Result := nil;
|
||||||
@ -354,6 +362,11 @@ begin
|
|||||||
Result := FSymbolType;
|
Result := FSymbolType;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TDbgSymbol.GetReference: TDbgSymbol;
|
||||||
|
begin
|
||||||
|
Result := FReference;
|
||||||
|
end;
|
||||||
|
|
||||||
function TDbgSymbol.GetHasBounds: Boolean;
|
function TDbgSymbol.GetHasBounds: Boolean;
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
@ -420,11 +433,18 @@ end;
|
|||||||
|
|
||||||
procedure TDbgSymbol.SetTypeInfo(AValue: TDbgSymbol);
|
procedure TDbgSymbol.SetTypeInfo(AValue: TDbgSymbol);
|
||||||
begin
|
begin
|
||||||
ReleaseRefAndNil(FTypeInfo);
|
if FTypeInfo <> nil then begin
|
||||||
|
//Assert((FTypeInfo.Reference = self) or (FTypeInfo.Reference = nil), 'FTypeInfo.Reference = self|nil');
|
||||||
|
FTypeInfo.Reference := nil;
|
||||||
|
{$IFDEF WITH_REFCOUNT_DEBUG}FTypeInfo.ReleaseReference(@FTypeInfo, 'SetTypeInfo'); FTypeInfo := nil;{$ENDIF}
|
||||||
|
ReleaseRefAndNil(FTypeInfo);
|
||||||
|
end;
|
||||||
FTypeInfo := AValue;
|
FTypeInfo := AValue;
|
||||||
Include(FEvaluatedFields, sfiTypeInfo);
|
Include(FEvaluatedFields, sfiTypeInfo);
|
||||||
if FTypeInfo <> nil then
|
if FTypeInfo <> nil then begin
|
||||||
FTypeInfo.AddReference;
|
FTypeInfo.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FTypeInfo, 'SetTypeInfo'){$ENDIF};
|
||||||
|
FTypeInfo.Reference := self;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDbgSymbol.SetMemberVisibility(AValue: TDbgSymbolMemberVisibility);
|
procedure TDbgSymbol.SetMemberVisibility(AValue: TDbgSymbolMemberVisibility);
|
||||||
@ -474,11 +494,6 @@ begin
|
|||||||
Result := nil;
|
Result := nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDbgSymbol.GetReference: TDbgSymbol;
|
|
||||||
begin
|
|
||||||
Result := nil;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TDbgSymbol.KindNeeded;
|
procedure TDbgSymbol.KindNeeded;
|
||||||
begin
|
begin
|
||||||
SetKind(skNone);
|
SetKind(skNone);
|
||||||
|
@ -425,6 +425,7 @@ end;
|
|||||||
|
|
||||||
procedure TPasParserSymbolPointer.TypeInfoNeeded;
|
procedure TPasParserSymbolPointer.TypeInfoNeeded;
|
||||||
begin
|
begin
|
||||||
|
// TODO: review, this changes reference in typeinfo, which points to another object already
|
||||||
SetTypeInfo(FPointedTo);
|
SetTypeInfo(FPointedTo);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user