Browse Source

fcl-passrc: useanalzer: use restored proc references

git-svn-id: trunk@38385 -
Mattias Gaertner 7 years ago
parent
commit
cb5be65887
2 changed files with 62 additions and 4 deletions
  1. 7 1
      packages/fcl-passrc/src/pasresolver.pp
  2. 55 3
      packages/fcl-passrc/src/pasuseanalyzer.pas

+ 7 - 1
packages/fcl-passrc/src/pasresolver.pp

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

+ 55 - 3
packages/fcl-passrc/src/pasuseanalyzer.pas

@@ -187,6 +187,7 @@ type
     function FindOverrideList(El: TPasElement): TPAOverrideList;
     procedure SetOptions(AValue: TPasAnalyzerOptions);
     procedure UpdateAccess(IsWrite: Boolean; IsRead: Boolean; Usage: TPAElement);
+    procedure OnUseProcScopeRef(data, DeclScope: pointer);
   protected
     procedure RaiseInconsistency(const Id: int64; Msg: string);
     procedure RaiseNotSupported(const Id: int64; El: TPasElement; const Msg: string = '');
@@ -238,6 +239,7 @@ type
     procedure AnalyzeProcRefs(Proc: TPasProcedure);
     procedure EmitModuleHints(aModule: TPasModule); virtual;
     function FindElement(El: TPasElement): TPAElement;
+    function FindUsedElement(El: TPasElement): TPAElement;
     // utility
     function IsUsed(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;
       MsgNumber: integer; Fmt: String; const Args: array of const; PosEl: TPasElement);
     procedure EmitMessage(Msg: TPAMessage);
+    function GetUsedElements: TFPList; virtual; // list of TPAElement
     property OnMessage: TPAMessageEvent read FOnMessage write FOnMessage;
     property Options: TPasAnalyzerOptions read FOptions write SetOptions;
     property Resolver: TPasResolver read FResolver write FResolver;
@@ -259,6 +262,7 @@ function CompareElementWithPAElement(El, Id: Pointer): integer;
 function ComparePAOverrideLists(List1, List2: Pointer): integer;
 function CompareElementWithPAOverrideList(El, List: Pointer): integer;
 function GetElModName(El: TPasElement): string;
+function dbgs(a: TPAIdentifierAccess): string; overload;
 
 implementation
 
@@ -313,6 +317,11 @@ begin
     Result:=aModule.Name+'.'+Result;
 end;
 
+function dbgs(a: TPAIdentifierAccess): string;
+begin
+  str(a,Result);
+end;
+
 { TPAMessage }
 
 constructor TPAMessage.Create;
@@ -509,6 +518,28 @@ begin
     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);
 begin
   {$IFDEF VerbosePasAnalyzer}
@@ -1349,6 +1380,9 @@ begin
   writeln('TPasAnalyzer.UseProcedure ',GetElModName(Proc));
   {$ENDIF}
 
+  if ProcScope.References<>nil then
+    ProcScope.References.ForEachCall(@OnUseProcScopeRef,ProcScope);
+
   UseProcedureType(Proc.ProcType,false);
 
   ImplProc:=Proc;
@@ -2159,18 +2193,23 @@ begin
     Result:=TPAElement(Node.Data);
 end;
 
-function TPasAnalyzer.IsUsed(El: TPasElement): boolean;
+function TPasAnalyzer.FindUsedElement(El: TPasElement): TPAElement;
 var
   ProcScope: TPasProcedureScope;
 begin
-  if not IsIdentifier(El) then exit(true);
+  if not IsIdentifier(El) then exit(nil);
   if El is TPasProcedure then
     begin
     ProcScope:=El.CustomData as TPasProcedureScope;
     if ProcScope.DeclarationProc<>nil then
       El:=ProcScope.DeclarationProc;
     end;
-  Result:=FindElement(El)<>nil;
+  Result:=FindElement(El);
+end;
+
+function TPasAnalyzer.IsUsed(El: TPasElement): boolean;
+begin
+  Result:=FindUsedElement(El)<>nil;
 end;
 
 function TPasAnalyzer.IsTypeInfoUsed(El: TPasElement): boolean;
@@ -2294,5 +2333,18 @@ begin
   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.