mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-07 05:00:43 +02:00
FPDebug: scan in enum / helper to build pascal representation of types
git-svn-id: trunk@43330 -
This commit is contained in:
parent
69885cfba0
commit
0f1ab1f8fe
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -1241,6 +1241,7 @@ components/fpdebug/fpimgreadermacho.pas svneol=native#text/pascal
|
|||||||
components/fpdebug/fpimgreadermachofile.pas svneol=native#text/pascal
|
components/fpdebug/fpimgreadermachofile.pas svneol=native#text/pascal
|
||||||
components/fpdebug/fpimgreaderwinpe.pas svneol=native#text/pascal
|
components/fpdebug/fpimgreaderwinpe.pas svneol=native#text/pascal
|
||||||
components/fpdebug/fpimgreaderwinpetypes.pas svneol=native#text/pascal
|
components/fpdebug/fpimgreaderwinpetypes.pas svneol=native#text/pascal
|
||||||
|
components/fpdebug/fppascalbuilder.pas svneol=native#text/pascal
|
||||||
components/fpdebug/fppascalparser.pas svneol=native#text/pascal
|
components/fpdebug/fppascalparser.pas svneol=native#text/pascal
|
||||||
components/fpdebug/macho.pas svneol=native#text/pascal
|
components/fpdebug/macho.pas svneol=native#text/pascal
|
||||||
components/fpdebug/test/FpTest.lpi svneol=native#text/pascal
|
components/fpdebug/test/FpTest.lpi svneol=native#text/pascal
|
||||||
|
@ -214,7 +214,7 @@ type
|
|||||||
property Member[AIndex: Integer]: TDbgSymbol read GetMember;
|
property Member[AIndex: Integer]: TDbgSymbol read GetMember;
|
||||||
property MemberByName[AIndex: String]: TDbgSymbol read GetMemberByName; // Includes inheritance
|
property MemberByName[AIndex: String]: TDbgSymbol read GetMemberByName; // Includes inheritance
|
||||||
//
|
//
|
||||||
property Flags: TDbgSymbolFlags read GetFlags; deprecated;
|
property Flags: TDbgSymbolFlags read GetFlags;
|
||||||
property Count: Integer read GetCount; deprecated;
|
property Count: Integer read GetCount; deprecated;
|
||||||
property Reference: TDbgSymbol read GetReference; deprecated;
|
property Reference: TDbgSymbol read GetReference; deprecated;
|
||||||
property Parent: TDbgSymbol read GetParent; deprecated;
|
property Parent: TDbgSymbol read GetParent; deprecated;
|
||||||
|
@ -263,6 +263,7 @@ type
|
|||||||
procedure SetScopeIndex(AValue: Integer);
|
procedure SetScopeIndex(AValue: Integer);
|
||||||
protected
|
protected
|
||||||
function GoNamedChild(AName: String): Boolean;
|
function GoNamedChild(AName: String): Boolean;
|
||||||
|
function GoNamedChildEx(AName: String): Boolean; // find in enum too // TODO: control search with a flags param, if needed
|
||||||
public
|
public
|
||||||
constructor Create(ACompUnit: TDwarfCompilationUnit; AnInformationEntry: Pointer);
|
constructor Create(ACompUnit: TDwarfCompilationUnit; AnInformationEntry: Pointer);
|
||||||
constructor Create(ACompUnit: TDwarfCompilationUnit; AScope: TDwarfScopeInfo);
|
constructor Create(ACompUnit: TDwarfCompilationUnit; AScope: TDwarfScopeInfo);
|
||||||
@ -626,6 +627,8 @@ DECL = DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line
|
|||||||
{ TDbgDwarfTypeIdentifierModifier }
|
{ TDbgDwarfTypeIdentifierModifier }
|
||||||
|
|
||||||
TDbgDwarfTypeIdentifierModifier = class(TDbgDwarfTypeIdentifier)
|
TDbgDwarfTypeIdentifierModifier = class(TDbgDwarfTypeIdentifier)
|
||||||
|
private
|
||||||
|
function NestedHasMembers: Boolean; inline;
|
||||||
protected
|
protected
|
||||||
procedure KindNeeded; override;
|
procedure KindNeeded; override;
|
||||||
procedure NameNeeded; override;
|
procedure NameNeeded; override;
|
||||||
@ -1613,6 +1616,11 @@ end;
|
|||||||
|
|
||||||
{ TDbgDwarfTypeIdentifierModifier }
|
{ TDbgDwarfTypeIdentifierModifier }
|
||||||
|
|
||||||
|
function TDbgDwarfTypeIdentifierModifier.NestedHasMembers: Boolean;
|
||||||
|
begin
|
||||||
|
Result := (Kind = skClass) or (Kind = skRecord) or (Kind = skEnum);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TDbgDwarfTypeIdentifierModifier.KindNeeded;
|
procedure TDbgDwarfTypeIdentifierModifier.KindNeeded;
|
||||||
var
|
var
|
||||||
t: TDbgSymbol;
|
t: TDbgSymbol;
|
||||||
@ -1666,12 +1674,14 @@ var
|
|||||||
ti: TDbgSymbol;
|
ti: TDbgSymbol;
|
||||||
begin
|
begin
|
||||||
ti := nil;
|
ti := nil;
|
||||||
if (Kind = skClass) or (Kind = skRecord) then
|
if NestedHasMembers then begin
|
||||||
ti := NestedTypeInfo;
|
ti := NestedTypeInfo;
|
||||||
if ti <> nil then
|
if ti <> nil then begin
|
||||||
Result := ti.Member[AIndex]
|
Result := ti.Member[AIndex];
|
||||||
else
|
exit;
|
||||||
Result := inherited GetMember(AIndex);
|
end;
|
||||||
|
end;
|
||||||
|
Result := inherited GetMember(AIndex);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDbgDwarfTypeIdentifierModifier.GetMemberByName(AIndex: String): TDbgSymbol;
|
function TDbgDwarfTypeIdentifierModifier.GetMemberByName(AIndex: String): TDbgSymbol;
|
||||||
@ -1679,12 +1689,14 @@ var
|
|||||||
ti: TDbgSymbol;
|
ti: TDbgSymbol;
|
||||||
begin
|
begin
|
||||||
ti := nil;
|
ti := nil;
|
||||||
if (Kind = skClass) or (Kind = skRecord) then
|
if NestedHasMembers then begin
|
||||||
ti := NestedTypeInfo;
|
ti := NestedTypeInfo;
|
||||||
if ti <> nil then
|
if ti <> nil then begin
|
||||||
Result := ti.MemberByName[AIndex]
|
Result := ti.MemberByName[AIndex];
|
||||||
else
|
exit;
|
||||||
Result := inherited GetMemberByName(AIndex);
|
end;
|
||||||
|
end;
|
||||||
|
Result := inherited GetMemberByName(AIndex);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDbgDwarfTypeIdentifierModifier.GetMemberCount: Integer;
|
function TDbgDwarfTypeIdentifierModifier.GetMemberCount: Integer;
|
||||||
@ -1692,12 +1704,14 @@ var
|
|||||||
ti: TDbgSymbol;
|
ti: TDbgSymbol;
|
||||||
begin
|
begin
|
||||||
ti := nil;
|
ti := nil;
|
||||||
if (Kind = skClass) or (Kind = skRecord) then
|
if NestedHasMembers then begin
|
||||||
ti := NestedTypeInfo;
|
ti := NestedTypeInfo;
|
||||||
if ti <> nil then
|
if ti <> nil then begin
|
||||||
Result := ti.MemberCount
|
Result := ti.MemberCount;
|
||||||
else
|
exit;
|
||||||
Result := inherited GetMemberCount;
|
end;
|
||||||
|
end;
|
||||||
|
Result := inherited GetMemberCount;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TDbgDwarfBaseTypeIdentifier }
|
{ TDbgDwarfBaseTypeIdentifier }
|
||||||
@ -1870,8 +1884,10 @@ end;
|
|||||||
function TDwarfInformationEntry.GoNamedChild(AName: String): Boolean;
|
function TDwarfInformationEntry.GoNamedChild(AName: String): Boolean;
|
||||||
var
|
var
|
||||||
EntryName: String;
|
EntryName: String;
|
||||||
|
s: String;
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
|
s := UpperCase(AName);
|
||||||
GoChild;
|
GoChild;
|
||||||
while HasValidScope do begin
|
while HasValidScope do begin
|
||||||
if not ReadValue(DW_AT_name, EntryName) then begin
|
if not ReadValue(DW_AT_name, EntryName) then begin
|
||||||
@ -1879,7 +1895,7 @@ begin
|
|||||||
Continue;
|
Continue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if UpperCase(EntryName) = UpperCase(AName) then begin
|
if UpperCase(EntryName) = s then begin
|
||||||
// TODO: check DW_AT_start_scope;
|
// TODO: check DW_AT_start_scope;
|
||||||
DebugLn([FPDBG_DWARF_SEARCH, 'GoNamedChild found ', dbgs(FScope, FCompUnit), DbgSName(Self)]);
|
DebugLn([FPDBG_DWARF_SEARCH, 'GoNamedChild found ', dbgs(FScope, FCompUnit), DbgSName(Self)]);
|
||||||
Result := True;
|
Result := True;
|
||||||
@ -1890,6 +1906,52 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TDwarfInformationEntry.GoNamedChildEx(AName: String): Boolean;
|
||||||
|
var
|
||||||
|
EntryName: String;
|
||||||
|
s: String;
|
||||||
|
InEnum: Boolean;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
InEnum := False;
|
||||||
|
s := UpperCase(AName);
|
||||||
|
GoChild;
|
||||||
|
while true do begin
|
||||||
|
while HasValidScope do begin
|
||||||
|
if not ReadValue(DW_AT_name, EntryName) then begin
|
||||||
|
GoNext;
|
||||||
|
Continue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if UpperCase(EntryName) = s then begin
|
||||||
|
// TODO: check DW_AT_start_scope;
|
||||||
|
DebugLn([FPDBG_DWARF_SEARCH, 'GoNamedChildEx found ', dbgs(FScope, FCompUnit), DbgSName(Self)]);
|
||||||
|
Result := True;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Abbrev was prelaped by ReadName
|
||||||
|
if Abbrev.tag = DW_TAG_enumeration_type then begin
|
||||||
|
assert(not InEnum, 'nested enum');
|
||||||
|
InEnum := True;
|
||||||
|
GoChild;
|
||||||
|
Continue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
GoNext;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if InEnum then begin
|
||||||
|
InEnum := False;
|
||||||
|
GoParent;
|
||||||
|
GoNext;
|
||||||
|
continue;
|
||||||
|
end;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
constructor TDwarfInformationEntry.Create(ACompUnit: TDwarfCompilationUnit;
|
constructor TDwarfInformationEntry.Create(ACompUnit: TDwarfCompilationUnit;
|
||||||
AnInformationEntry: Pointer);
|
AnInformationEntry: Pointer);
|
||||||
begin
|
begin
|
||||||
@ -3273,7 +3335,7 @@ 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;
|
||||||
|
|
||||||
if InfoEntry.GoNamedChild(AName) then begin
|
if InfoEntry.GoNamedChildEx(AName) then begin
|
||||||
Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntry);
|
Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntry);
|
||||||
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)]);
|
||||||
break;
|
break;
|
||||||
|
@ -34,7 +34,7 @@ File(s) with other licenses (see also header in file(s):
|
|||||||
|
|
||||||
(Any modifications/translations of this file are from duby)
|
(Any modifications/translations of this file are from duby)
|
||||||
"/>
|
"/>
|
||||||
<Files Count="17">
|
<Files Count="18">
|
||||||
<Item1>
|
<Item1>
|
||||||
<Filename Value="fpdbgclasses.pp"/>
|
<Filename Value="fpdbgclasses.pp"/>
|
||||||
<UnitName Value="FpDbgClasses"/>
|
<UnitName Value="FpDbgClasses"/>
|
||||||
@ -103,6 +103,10 @@ File(s) with other licenses (see also header in file(s):
|
|||||||
<Filename Value="fpimgreadermacho.pas"/>
|
<Filename Value="fpimgreadermacho.pas"/>
|
||||||
<UnitName Value="FpImgReaderMacho"/>
|
<UnitName Value="FpImgReaderMacho"/>
|
||||||
</Item17>
|
</Item17>
|
||||||
|
<Item18>
|
||||||
|
<Filename Value="fppascalbuilder.pas"/>
|
||||||
|
<UnitName Value="fppascalbuilder"/>
|
||||||
|
</Item18>
|
||||||
</Files>
|
</Files>
|
||||||
<Type Value="RunAndDesignTime"/>
|
<Type Value="RunAndDesignTime"/>
|
||||||
<RequiredPkgs Count="2">
|
<RequiredPkgs Count="2">
|
||||||
|
@ -10,7 +10,7 @@ uses
|
|||||||
FpDbgClasses, FpDbgDisasX86, FpDbgDwarf, FpDbgDwarfConst, FpDbgLoader, FpDbgPETypes,
|
FpDbgClasses, FpDbgDisasX86, FpDbgDwarf, FpDbgDwarfConst, FpDbgLoader, FpDbgPETypes,
|
||||||
FpDbgSymbols, FpDbgUtil, FpDbgWinExtra, FpImgReaderWinPE, FpImgReaderElf,
|
FpDbgSymbols, FpDbgUtil, FpDbgWinExtra, FpImgReaderWinPE, FpImgReaderElf,
|
||||||
FpImgReaderElfTypes, FpImgReaderBase, FpPascalParser, macho, FpImgReaderMachoFile,
|
FpImgReaderElfTypes, FpImgReaderBase, FpPascalParser, macho, FpImgReaderMachoFile,
|
||||||
FpImgReaderMacho, LazarusPackageIntf;
|
FpImgReaderMacho, FpPascalBuilder, LazarusPackageIntf;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
236
components/fpdebug/fppascalbuilder.pas
Normal file
236
components/fpdebug/fppascalbuilder.pas
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
unit FpPascalBuilder;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, FpDbgClasses;
|
||||||
|
|
||||||
|
type
|
||||||
|
TTypeNameFlag = (
|
||||||
|
tnfOnlyDeclared, // do not return a substitute with ^ symbol
|
||||||
|
tnfIncludeOneRef // If it is a pointer, and the pointed-to name is known, return ^TXxx
|
||||||
|
// without tnfOnlyDeclared, may return ^^^TXxx if needed
|
||||||
|
|
||||||
|
);
|
||||||
|
TTypeNameFlags = set of TTypeNameFlag;
|
||||||
|
|
||||||
|
TTypeDeclarationFlag = (
|
||||||
|
tdfIncludeVarName, // like i: Integer
|
||||||
|
tdfSkipClassBody // shorten class
|
||||||
|
);
|
||||||
|
TTypeDeclarationFlags = set of TTypeDeclarationFlag;
|
||||||
|
|
||||||
|
function GetTypeName(out ATypeName: String; ADbgSymbol: TDbgSymbol; AFlags: TTypeNameFlags = []): Boolean;
|
||||||
|
function GetTypeAsDeclaration(out ATypeDeclaration: String; ADbgSymbol: TDbgSymbol;
|
||||||
|
AFlags: TTypeDeclarationFlags = []; AnIndent: Integer = 0): Boolean;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
function GetTypeName(out ATypeName: String; ADbgSymbol: TDbgSymbol;
|
||||||
|
AFlags: TTypeNameFlags): Boolean;
|
||||||
|
var
|
||||||
|
s: String;
|
||||||
|
begin
|
||||||
|
Result := ADbgSymbol <> nil;
|
||||||
|
if not Result then
|
||||||
|
exit;
|
||||||
|
if ADbgSymbol.SymbolType = stValue then begin
|
||||||
|
ADbgSymbol := ADbgSymbol.TypeInfo;
|
||||||
|
Result := ADbgSymbol <> nil;
|
||||||
|
if not Result then
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
ATypeName := ADbgSymbol.Name;
|
||||||
|
Result := ATypeName <> '';
|
||||||
|
|
||||||
|
if (tnfIncludeOneRef in AFlags) or
|
||||||
|
((not Result) and (not (tnfOnlyDeclared in AFlags)))
|
||||||
|
then begin
|
||||||
|
ATypeName := '^';
|
||||||
|
while ADbgSymbol.Kind = skPointer do begin
|
||||||
|
ADbgSymbol := ADbgSymbol.TypeInfo;
|
||||||
|
s := ADbgSymbol.Name;
|
||||||
|
if s <> '' then begin
|
||||||
|
ATypeName := ATypeName + s;
|
||||||
|
Result := True;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (tnfOnlyDeclared in AFlags) then // only one level
|
||||||
|
exit;
|
||||||
|
ATypeName := ATypeName + '^';
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := False;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GetTypeAsDeclaration(out ATypeDeclaration: String; ADbgSymbol: TDbgSymbol;
|
||||||
|
AFlags: TTypeDeclarationFlags; AnIndent: Integer): Boolean;
|
||||||
|
var
|
||||||
|
IndentString: String;
|
||||||
|
|
||||||
|
function GetIndent: String;
|
||||||
|
begin
|
||||||
|
if (IndentString = '') and (AnIndent > 0) then
|
||||||
|
IndentString := StringOfChar(' ', AnIndent);
|
||||||
|
Result := IndentString;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Function MembersAsGdbText(out AText: String; WithVisibilty: Boolean; AFlags: TTypeDeclarationFlags = []): Boolean;
|
||||||
|
var
|
||||||
|
CurVis: TDbgSymbolMemberVisibility;
|
||||||
|
|
||||||
|
procedure AddVisibility(AVis: TDbgSymbolMemberVisibility; AFirst: Boolean);
|
||||||
|
begin
|
||||||
|
if not (WithVisibilty and ((CurVis <> AVis) or AFirst)) then
|
||||||
|
exit;
|
||||||
|
CurVis := AVis;
|
||||||
|
case AVis of
|
||||||
|
svPrivate: AText := AText + GetIndent + ' private' + LineEnding;
|
||||||
|
svProtected: AText := AText + GetIndent + ' protected' + LineEnding;
|
||||||
|
svPublic: AText := AText + GetIndent + ' public' + LineEnding;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
c, i: Integer;
|
||||||
|
m: TDbgSymbol;
|
||||||
|
s: String;
|
||||||
|
begin
|
||||||
|
Result := True;
|
||||||
|
AText := '';
|
||||||
|
c := ADbgSymbol.MemberCount;
|
||||||
|
i := 0;
|
||||||
|
while (i < c) and Result do begin
|
||||||
|
m := ADbgSymbol.Member[i];
|
||||||
|
AddVisibility(m.MemberVisibility, i= 0);
|
||||||
|
Result := GetTypeAsDeclaration(s, m, [tdfIncludeVarName] + AFlags, AnIndent + 4);
|
||||||
|
if Result then
|
||||||
|
AText := AText + GetIndent + s + ';' + LineEnding;
|
||||||
|
inc(i);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GetPointerType(out ADeclaration: String): Boolean;
|
||||||
|
var
|
||||||
|
s: String;
|
||||||
|
begin
|
||||||
|
s := '';
|
||||||
|
while ADbgSymbol.Kind = skPointer do begin
|
||||||
|
ADbgSymbol := ADbgSymbol.TypeInfo;
|
||||||
|
s := s + '^';
|
||||||
|
end;
|
||||||
|
Result := GetTypeName(ADeclaration, ADbgSymbol, []);
|
||||||
|
// TODO brackets
|
||||||
|
ADeclaration := s + ADeclaration;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GetBaseType(out ADeclaration: String): Boolean;
|
||||||
|
begin
|
||||||
|
Result := GetTypeName(ADeclaration, ADbgSymbol, []);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GetFunctionType(out ADeclaration: String): Boolean;
|
||||||
|
var
|
||||||
|
s: String;
|
||||||
|
begin
|
||||||
|
// Todo param
|
||||||
|
GetTypeAsDeclaration(s, ADbgSymbol.TypeInfo);
|
||||||
|
ADeclaration := 'function ' + ADbgSymbol.Name + ' () : ' + s + '';
|
||||||
|
if sfVirtual in ADbgSymbol.Flags then ADeclaration := ADeclaration + '; virtual';
|
||||||
|
Result := true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GetProcedureType(out ADeclaration: String): Boolean;
|
||||||
|
begin
|
||||||
|
// Todo param
|
||||||
|
ADeclaration := 'procedure ' + ADbgSymbol.Name + ' ()';
|
||||||
|
if sfVirtual in ADbgSymbol.Flags then ADeclaration := ADeclaration + '; virtual';
|
||||||
|
Result := true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GetClassType(out ADeclaration: String): Boolean;
|
||||||
|
var
|
||||||
|
s, s2: String;
|
||||||
|
begin
|
||||||
|
Result := tdfSkipClassBody in AFlags;
|
||||||
|
if Result then begin
|
||||||
|
GetTypeName(s, ADbgSymbol);
|
||||||
|
ADeclaration := s + ' {=class}';
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
Result := MembersAsGdbText(s, True, [tdfSkipClassBody]);
|
||||||
|
GetTypeName(s2, ADbgSymbol.TypeInfo);
|
||||||
|
if Result then
|
||||||
|
ADeclaration := Format('class(%s)%s%s%send%s',
|
||||||
|
[s2, LineEnding, s, LineEnding, GetIndent]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GetRecordType(out ADeclaration: String): Boolean;
|
||||||
|
var
|
||||||
|
s: String;
|
||||||
|
begin
|
||||||
|
Result := MembersAsGdbText(s, True);
|
||||||
|
if Result then
|
||||||
|
ADeclaration := Format('record%s%s%send%s', [LineEnding, s, LineEnding, GetIndent]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GetEnumType(out ADeclaration: String): Boolean;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
m: TDbgSymbol;
|
||||||
|
begin
|
||||||
|
// TODO assigned value (a,b:=3,...)
|
||||||
|
Result := True;
|
||||||
|
ADeclaration := '(';
|
||||||
|
for i := 0 to ADbgSymbol.MemberCount - 1 do begin
|
||||||
|
m := ADbgSymbol.Member[i];
|
||||||
|
if i > 0 then ADeclaration := ADeclaration + ', ';
|
||||||
|
ADeclaration := ADeclaration + m.Name;
|
||||||
|
end;
|
||||||
|
ADeclaration := ADeclaration + ')'
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
VarName: String;
|
||||||
|
begin
|
||||||
|
Result := ADbgSymbol <> nil;
|
||||||
|
if not Result then
|
||||||
|
exit;
|
||||||
|
VarName := '';
|
||||||
|
if (ADbgSymbol.SymbolType = stValue) and
|
||||||
|
not((ADbgSymbol.Kind = skProcedure) or (ADbgSymbol.Kind = skFunction))
|
||||||
|
then begin
|
||||||
|
if tdfIncludeVarName in AFlags then
|
||||||
|
VarName := ADbgSymbol.Name;
|
||||||
|
ADbgSymbol := ADbgSymbol.TypeInfo;
|
||||||
|
Result := ADbgSymbol <> nil;
|
||||||
|
if not Result then
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
case ADbgSymbol.Kind of
|
||||||
|
skPointer: Result := GetPointerType(ATypeDeclaration);
|
||||||
|
skInteger, skCardinal, skBoolean, skChar, skFloat:
|
||||||
|
Result := GetBaseType(ATypeDeclaration);
|
||||||
|
skFunction: Result := GetFunctionType(ATypeDeclaration);
|
||||||
|
skProcedure: Result := GetProcedureType(ATypeDeclaration);
|
||||||
|
skClass: Result := GetClassType(ATypeDeclaration);
|
||||||
|
skRecord: Result := GetRecordType(ATypeDeclaration);
|
||||||
|
skEnum: Result := GetEnumType(ATypeDeclaration);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if VarName <> '' then
|
||||||
|
ATypeDeclaration := VarName + ': ' + ATypeDeclaration;
|
||||||
|
if AnIndent <> 0 then
|
||||||
|
ATypeDeclaration := GetIndent + ATypeDeclaration;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user