diff --git a/components/fpdebug/fpdbgdwarf.pas b/components/fpdebug/fpdbgdwarf.pas index 52b9eda2fe..3ed87b3fc6 100644 --- a/components/fpdebug/fpdbgdwarf.pas +++ b/components/fpdebug/fpdbgdwarf.pas @@ -121,7 +121,7 @@ type function FindExportedSymbolInUnit(CU: TDwarfCompilationUnit; const ANameInfo: TNameSearchInfo; out AnInfoEntry: TDwarfInformationEntry; out AnIsExternal: Boolean): Boolean; inline; function FindExportedSymbolInUnits(const AName: String; const ANameInfo: TNameSearchInfo; - SkipCompUnit: TDwarfCompilationUnit; out ADbgValue: TFpValue): Boolean; + SkipCompUnit: TDwarfCompilationUnit; out ADbgValue: TFpValue; const OnlyUnitNameLower: String = ''): Boolean; function FindSymbolInStructure(const AName: String; const ANameInfo: TNameSearchInfo; InfoEntry: TDwarfInformationEntry; out ADbgValue: TFpValue): Boolean; inline; // FindLocalSymbol: for the subroutine itself @@ -130,7 +130,7 @@ type public constructor Create(ALocationContext: TFpDbgLocationContext; ASymbol: TFpSymbol; ADwarf: TFpDwarfInfo); destructor Destroy; override; - function FindSymbol(const AName: String): TFpValue; override; + function FindSymbol(const AName: String; const OnlyUnitName: String = ''): TFpValue; override; end; TFpSymbolDwarfType = class; @@ -1357,7 +1357,7 @@ end; function TFpDwarfInfoSymbolScope.FindExportedSymbolInUnits(const AName: String; const ANameInfo: TNameSearchInfo; SkipCompUnit: TDwarfCompilationUnit; out - ADbgValue: TFpValue): Boolean; + ADbgValue: TFpValue; const OnlyUnitNameLower: String): Boolean; const PER_WORKER_CNT = 20; var @@ -1383,6 +1383,8 @@ begin dec(i); CU := FDwarf.CompilationUnits[i]; + if (OnlyUnitNameLower <> '') and (OnlyUnitNameLower <> LowerCase(CU.UnitName)) then + continue; if (CU = SkipCompUnit) or (not CU.KnownNameHashes^[ANameInfo.NameHash and KnownNameHashesBitMask]) then @@ -1559,7 +1561,8 @@ begin inherited Destroy; end; -function TFpDwarfInfoSymbolScope.FindSymbol(const AName: String): TFpValue; +function TFpDwarfInfoSymbolScope.FindSymbol(const AName: String; + const OnlyUnitName: String): TFpValue; var SubRoutine: TFpSymbolDwarfDataProc; // TDbgSymbol; CU: TDwarfCompilationUnit; @@ -1575,11 +1578,18 @@ begin if (AName = '') then exit; + NameInfo := NameInfoForSearch(AName); + + if OnlyUnitName <> '' then begin + // TODO: dwarf info for libraries + FindExportedSymbolInUnits(AName, NameInfo, nil, Result, LowerCase(OnlyUnitName)); + exit; + end; + if FSymbol is TFpSymbolDwarfDataProc then SubRoutine := TFpSymbolDwarfDataProc(FSymbol) else SubRoutine := nil; - NameInfo := NameInfoForSearch(AName); if Symbol = nil then begin FindExportedSymbolInUnits(AName, NameInfo, nil, Result); diff --git a/components/fpdebug/fpdbginfo.pas b/components/fpdebug/fpdbginfo.pas index ea5a832327..ffa6b3434c 100644 --- a/components/fpdebug/fpdbginfo.pas +++ b/components/fpdebug/fpdbginfo.pas @@ -499,7 +499,7 @@ type property SymbolAtAddress: TFpSymbol read GetSymbolAtAddress; property ProcedureAtAddress: TFpValue read GetProcedureAtAddress; // search this, and all parent context - function FindSymbol(const {%H-}AName: String): TFpValue; virtual; + function FindSymbol(const {%H-}AName: String; const OnlyUnitName: String = ''): TFpValue; virtual; property MemManager: TFpDbgMemManager read GetMemManager; property SizeOfAddress: Integer read GetSizeOfAddress; property LocationContext: TFpDbgLocationContext read FLocationContext; @@ -1201,7 +1201,8 @@ begin Result := nil; end; -function TFpDbgSymbolScope.FindSymbol(const AName: String): TFpValue; +function TFpDbgSymbolScope.FindSymbol(const AName: String; + const OnlyUnitName: String): TFpValue; begin Result := nil; end; diff --git a/components/fpdebug/fpdbgsymtablecontext.pas b/components/fpdebug/fpdbgsymtablecontext.pas index 6a83a52b72..3041d67db0 100644 --- a/components/fpdebug/fpdbgsymtablecontext.pas +++ b/components/fpdebug/fpdbgsymtablecontext.pas @@ -36,7 +36,7 @@ type function GetSizeOfAddress: Integer; override; public constructor Create(ALocationContext: TFpDbgLocationContext; AFpSymbolInfo: TFpSymbolInfo); - function FindSymbol(const AName: String): TFpValue; override; + function FindSymbol(const AName: String; const OnlyUnitName: String = ''): TFpValue; override; end; { TFpSymbolInfo } @@ -80,7 +80,8 @@ begin FFpSymbolInfo:=AFpSymbolInfo; end; -function TFpSymbolContext.FindSymbol(const AName: String): TFpValue; +function TFpSymbolContext.FindSymbol(const AName: String; + const OnlyUnitName: String): TFpValue; var i: integer; val: TFpDbgMemLocation; diff --git a/components/fpdebug/fppascalparser.pas b/components/fpdebug/fppascalparser.pas index c29b97eedb..4b2526685e 100644 --- a/components/fpdebug/fppascalparser.pas +++ b/components/fpdebug/fppascalparser.pas @@ -3550,7 +3550,8 @@ begin if Count <> 2 then exit; tmp := Items[0].ResultValue; - if (tmp = nil) then exit; + if (tmp = nil) then + exit; MemberName := Items[1].GetText; @@ -3605,14 +3606,26 @@ begin end; end; end; - SetError(fpErrNoMemberWithName, [Items[1].GetText]); + SetError(fpErrNoMemberWithName, [MemberName]); exit end; - // Todo unit + if (tmp.Kind = skUnit) or + ( (tmp.DbgSymbol <> nil) and (tmp.DbgSymbol.Kind = skUnit) ) + then begin + (* If a class/record/object matches the typename, but did not have the member, + then this could still be a unit. + If the class/record/object is in the same unit as the current contexct (selected function) + then it would hide the unitname, but otherwise a unit in the uses clause would + hide the structure. + *) + Result := Expression.FContext.FindSymbol(MemberName, Items[0].GetText); + if Result <> nil then + exit; + end; - SetError(fpErrorNotAStructure, [Items[1].GetText, Items[0].GetText]); + SetError(fpErrorNotAStructure, [MemberName, Items[0].GetText]); end; end.