fcl-passrc: useanalzer: use restored proc references

git-svn-id: trunk@38385 -
This commit is contained in:
Mattias Gaertner 2018-02-28 18:32:53 +00:00
parent c93c15429d
commit cb5be65887
2 changed files with 62 additions and 4 deletions

View File

@ -1664,8 +1664,9 @@ function IsValidIdent(const Ident: string; AllowDots: Boolean = False; StrictDot
function NoNil(o: TObject): TObject; function NoNil(o: TObject): TObject;
function dbgs(const Flags: TPasResolverComputeFlags): string; overload; function dbgs(const Flags: TPasResolverComputeFlags): string; overload;
function dbgs(const a: TResolvedRefAccess): string; function dbgs(const a: TResolvedRefAccess): string; overload;
function dbgs(const Flags: TResolvedReferenceFlags): string; overload; function dbgs(const Flags: TResolvedReferenceFlags): string; overload;
function dbgs(const a: TPSRefAccess): string; overload;
implementation implementation
@ -2152,6 +2153,11 @@ begin
Result:='['+Result+']'; Result:='['+Result+']';
end; end;
function dbgs(const a: TPSRefAccess): string;
begin
str(a,Result);
end;
{ TPasProcScopeReference } { TPasProcScopeReference }
procedure TPasProcScopeReference.SetElement(const AValue: TPasElement); procedure TPasProcScopeReference.SetElement(const AValue: TPasElement);

View File

@ -187,6 +187,7 @@ type
function FindOverrideList(El: TPasElement): TPAOverrideList; function FindOverrideList(El: TPasElement): TPAOverrideList;
procedure SetOptions(AValue: TPasAnalyzerOptions); procedure SetOptions(AValue: TPasAnalyzerOptions);
procedure UpdateAccess(IsWrite: Boolean; IsRead: Boolean; Usage: TPAElement); procedure UpdateAccess(IsWrite: Boolean; IsRead: Boolean; Usage: TPAElement);
procedure OnUseProcScopeRef(data, DeclScope: pointer);
protected protected
procedure RaiseInconsistency(const Id: int64; Msg: string); procedure RaiseInconsistency(const Id: int64; Msg: string);
procedure RaiseNotSupported(const Id: int64; El: TPasElement; const Msg: string = ''); procedure RaiseNotSupported(const Id: int64; El: TPasElement; const Msg: string = '');
@ -238,6 +239,7 @@ type
procedure AnalyzeProcRefs(Proc: TPasProcedure); procedure AnalyzeProcRefs(Proc: TPasProcedure);
procedure EmitModuleHints(aModule: TPasModule); virtual; procedure EmitModuleHints(aModule: TPasModule); virtual;
function FindElement(El: TPasElement): TPAElement; function FindElement(El: TPasElement): TPAElement;
function FindUsedElement(El: TPasElement): TPAElement;
// utility // utility
function IsUsed(El: TPasElement): boolean; // valid after calling Analyze* function IsUsed(El: TPasElement): boolean; // valid after calling Analyze*
function IsTypeInfoUsed(El: TPasElement): boolean; // valid after calling Analyze* function IsTypeInfoUsed(El: TPasElement): boolean; // valid after calling Analyze*
@ -248,6 +250,7 @@ type
procedure EmitMessage(const Id: int64; const MsgType: TMessageType; procedure EmitMessage(const Id: int64; const MsgType: TMessageType;
MsgNumber: integer; Fmt: String; const Args: array of const; PosEl: TPasElement); MsgNumber: integer; Fmt: String; const Args: array of const; PosEl: TPasElement);
procedure EmitMessage(Msg: TPAMessage); procedure EmitMessage(Msg: TPAMessage);
function GetUsedElements: TFPList; virtual; // list of TPAElement
property OnMessage: TPAMessageEvent read FOnMessage write FOnMessage; property OnMessage: TPAMessageEvent read FOnMessage write FOnMessage;
property Options: TPasAnalyzerOptions read FOptions write SetOptions; property Options: TPasAnalyzerOptions read FOptions write SetOptions;
property Resolver: TPasResolver read FResolver write FResolver; property Resolver: TPasResolver read FResolver write FResolver;
@ -259,6 +262,7 @@ function CompareElementWithPAElement(El, Id: Pointer): integer;
function ComparePAOverrideLists(List1, List2: Pointer): integer; function ComparePAOverrideLists(List1, List2: Pointer): integer;
function CompareElementWithPAOverrideList(El, List: Pointer): integer; function CompareElementWithPAOverrideList(El, List: Pointer): integer;
function GetElModName(El: TPasElement): string; function GetElModName(El: TPasElement): string;
function dbgs(a: TPAIdentifierAccess): string; overload;
implementation implementation
@ -313,6 +317,11 @@ begin
Result:=aModule.Name+'.'+Result; Result:=aModule.Name+'.'+Result;
end; end;
function dbgs(a: TPAIdentifierAccess): string;
begin
str(a,Result);
end;
{ TPAMessage } { TPAMessage }
constructor TPAMessage.Create; constructor TPAMessage.Create;
@ -509,6 +518,28 @@ begin
end; end;
end; end;
procedure TPasAnalyzer.OnUseProcScopeRef(data, DeclScope: pointer);
var
Ref: TPasProcScopeReference absolute data;
Scope: TPasProcedureScope absolute DeclScope;
begin
if Scope=nil then ;
case Ref.Access of
psraNone: ;
psraRead: UseElement(Ref.Element,rraRead,false);
psraWrite: UseElement(Ref.Element,rraAssign,false);
psraReadWrite: UseElement(Ref.Element,rraReadAndAssign,false);
psraWriteRead:
begin
UseElement(Ref.Element,rraAssign,false);
UseElement(Ref.Element,rraRead,false);
end;
psraTypeInfo: UsePublished(Ref.Element);
else
RaiseNotSupported(20180228191928,Ref.Element,dbgs(Ref.Access));
end;
end;
procedure TPasAnalyzer.RaiseInconsistency(const Id: int64; Msg: string); procedure TPasAnalyzer.RaiseInconsistency(const Id: int64; Msg: string);
begin begin
{$IFDEF VerbosePasAnalyzer} {$IFDEF VerbosePasAnalyzer}
@ -1349,6 +1380,9 @@ begin
writeln('TPasAnalyzer.UseProcedure ',GetElModName(Proc)); writeln('TPasAnalyzer.UseProcedure ',GetElModName(Proc));
{$ENDIF} {$ENDIF}
if ProcScope.References<>nil then
ProcScope.References.ForEachCall(@OnUseProcScopeRef,ProcScope);
UseProcedureType(Proc.ProcType,false); UseProcedureType(Proc.ProcType,false);
ImplProc:=Proc; ImplProc:=Proc;
@ -2159,18 +2193,23 @@ begin
Result:=TPAElement(Node.Data); Result:=TPAElement(Node.Data);
end; end;
function TPasAnalyzer.IsUsed(El: TPasElement): boolean; function TPasAnalyzer.FindUsedElement(El: TPasElement): TPAElement;
var var
ProcScope: TPasProcedureScope; ProcScope: TPasProcedureScope;
begin begin
if not IsIdentifier(El) then exit(true); if not IsIdentifier(El) then exit(nil);
if El is TPasProcedure then if El is TPasProcedure then
begin begin
ProcScope:=El.CustomData as TPasProcedureScope; ProcScope:=El.CustomData as TPasProcedureScope;
if ProcScope.DeclarationProc<>nil then if ProcScope.DeclarationProc<>nil then
El:=ProcScope.DeclarationProc; El:=ProcScope.DeclarationProc;
end; end;
Result:=FindElement(El)<>nil; Result:=FindElement(El);
end;
function TPasAnalyzer.IsUsed(El: TPasElement): boolean;
begin
Result:=FindUsedElement(El)<>nil;
end; end;
function TPasAnalyzer.IsTypeInfoUsed(El: TPasElement): boolean; function TPasAnalyzer.IsTypeInfoUsed(El: TPasElement): boolean;
@ -2294,5 +2333,18 @@ begin
end; end;
end; end;
function TPasAnalyzer.GetUsedElements: TFPList;
var
Node: TAVLTreeNode;
begin
Result:=TFPList.Create;
Node:=FUsedElements.FindLowest;
while Node<>nil do
begin
Result.Add(Node.Data);
Node:=FUsedElements.FindSuccessor(Node);
end;
end;
end. end.