diff --git a/components/fpdebug/fpdbgdwarf.pas b/components/fpdebug/fpdbgdwarf.pas index a3e7a8ae8e..344bdf820b 100644 --- a/components/fpdebug/fpdbgdwarf.pas +++ b/components/fpdebug/fpdbgdwarf.pas @@ -104,7 +104,7 @@ type property StackFrame: Integer read FStackFrame write FStackFrame; procedure ApplyContext(AVal: TFpValue); inline; - function SymbolToValue(ASym: TFpSymbol): TFpValue; inline; + function SymbolToValue(ASym: TFpSymbolDwarf): TFpValue; inline; function GetSelfParameter: TFpValueDwarf; function FindExportedSymbolInUnits(const AName: String; PNameUpper, PNameLower: PChar; @@ -142,12 +142,16 @@ type TFpValueDwarfTypeDefinition = class(TFpValueDwarfBase) private - FSymbol: TFpSymbol; // stType + FSymbol: TFpSymbolDwarf; // stType protected function GetKind: TDbgSymbolKind; override; function GetDbgSymbol: TFpSymbol; override; + + function GetMemberCount: Integer; override; + function GetMemberByName(AIndex: String): TFpValue; override; + function GetMember(AIndex: Int64): TFpValue; override; public - constructor Create(ASymbol: TFpSymbol); // Only for stType + constructor Create(ASymbol: TFpSymbolDwarf); // Only for stType destructor Destroy; override; function GetTypeCastedValue(ADataVal: TFpValue): TFpValue; override; end; @@ -1206,7 +1210,7 @@ begin TFpValueDwarfBase(AVal).FContext := Self; end; -function TFpDwarfInfoAddressContext.SymbolToValue(ASym: TFpSymbol): TFpValue; +function TFpDwarfInfoAddressContext.SymbolToValue(ASym: TFpSymbolDwarf): TFpValue; begin if ASym = nil then begin Result := nil; @@ -1518,7 +1522,30 @@ begin Result := FSymbol; end; -constructor TFpValueDwarfTypeDefinition.Create(ASymbol: TFpSymbol); +function TFpValueDwarfTypeDefinition.GetMemberCount: Integer; +begin + Result := FSymbol.NestedSymbolCount; +end; + +function TFpValueDwarfTypeDefinition.GetMemberByName(AIndex: String): TFpValue; +begin + Result := FSymbol.GetNestedValueByName(AIndex); + if Result = nil then + exit; +// TFpValueDwarf(Result).SetStructureValue(Self); + TFpValueDwarf(Result).FContext := FContext; +end; + +function TFpValueDwarfTypeDefinition.GetMember(AIndex: Int64): TFpValue; +begin + Result := FSymbol.GetNestedValue(AIndex); + if Result = nil then + exit; +// TFpValueDwarf(Result).SetStructureValue(Self); + TFpValueDwarf(Result).FContext := FContext; +end; + +constructor TFpValueDwarfTypeDefinition.Create(ASymbol: TFpSymbolDwarf); begin inherited Create; FSymbol := ASymbol; @@ -4793,7 +4820,9 @@ end; function TFpSymbolDwarfDataMember.HasAddress: Boolean; begin - Result := (InformationEntry.HasAttrib(DW_AT_data_member_location)); + // DW_AT_data_member_location defaults to zero => i.e. at the start of the containing structure + Result := not (InformationEntry.HasAttrib(DW_AT_const_value)); + //(InformationEntry.HasAttrib(DW_AT_data_member_location)); end; { TFpSymbolDwarfTypeStructure } diff --git a/components/fpdebug/fpdbginfo.pas b/components/fpdebug/fpdbginfo.pas index b04687a76c..30a75df179 100644 --- a/components/fpdebug/fpdbginfo.pas +++ b/components/fpdebug/fpdbginfo.pas @@ -1092,7 +1092,7 @@ end; function TFpValueTypeDefinition.GetKind: TDbgSymbolKind; begin - Result := skNone; + Result := skType; end; function TFpValueTypeDefinition.GetDbgSymbol: TFpSymbol; diff --git a/components/fpdebug/fppascalparser.pas b/components/fpdebug/fppascalparser.pas index eb98f2f348..791a8080a9 100644 --- a/components/fpdebug/fppascalparser.pas +++ b/components/fpdebug/fppascalparser.pas @@ -3387,6 +3387,8 @@ end; function TFpPascalExpressionPartOperatorMemberOf.DoGetResultValue: TFpValue; var tmp: TFpValue; + MemberName: String; + MemberSym: TFpSymbol; {$IFDEF FpDebugAutoDerefMember} tmp2: TFpValue; {$ENDIF} @@ -3397,6 +3399,8 @@ begin tmp := Items[0].ResultValue; if (tmp = nil) then exit; + MemberName := Items[1].GetText; + {$IFDEF FpDebugAutoDerefMember} // Copy from TFpPascalExpressionPartOperatorDeRef.DoGetResultValue tmp2 := nil; @@ -3415,9 +3419,9 @@ begin {$ENDIF} if (tmp.Kind in [skClass, skRecord, skObject]) then begin - Result := tmp.MemberByName[Items[1].GetText]; + Result := tmp.MemberByName[MemberName]; if Result = nil then begin - SetError(fpErrNoMemberWithName, [Items[1].GetText]); + SetError(fpErrNoMemberWithName, [MemberName]); exit; end; {$IFDEF WITH_REFCOUNT_DEBUG}Result.DbgRenameReference(nil, 'DoGetResultValue'){$ENDIF}; @@ -3428,6 +3432,30 @@ begin tmp2.ReleaseReference; {$ENDIF} + if (tmp.Kind in [skType]) and + (tmp.DbgSymbol <> nil) and (tmp.DbgSymbol.Kind in [skClass, skRecord, skObject]) + then begin + Result := tmp.MemberByName[MemberName]; + if Result <> nil then begin + // only class fields/constants can have an address without valid "self" instance + if IsReadableLoc(result.DataAddress) then begin // result.Address? + {$IFDEF WITH_REFCOUNT_DEBUG}Result.DbgRenameReference(nil, 'DoGetResultValue'){$ENDIF}; + exit; + end + else begin + ReleaseRefAndNil(Result); + MemberSym := tmp.DbgSymbol.NestedSymbolByName[MemberName]; + if MemberSym <> nil then begin + Result := TFpValueTypeDefinition.Create(MemberSym); + {$IFDEF WITH_REFCOUNT_DEBUG}Result.DbgRenameReference(nil, 'DoGetResultValue'){$ENDIF}; + exit; + end; + end; + end; + SetError(fpErrNoMemberWithName, [Items[1].GetText]); + exit + end; + // Todo unit SetError(fpErrorNotAStructure, [Items[1].GetText, Items[0].GetText]);