mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-10 20:49:23 +02:00
fcl-passrc: useanalyzer: mark needed typeinfo
git-svn-id: trunk@35793 -
This commit is contained in:
parent
5a8578cfaa
commit
a0482df6df
@ -147,15 +147,15 @@ type
|
||||
end;
|
||||
|
||||
TPasAnalyzerOption = (
|
||||
paoKeepPublished, // when a class is used, all its published members are used as well
|
||||
paoOnlyExports // default: use all class members accessible from outside (protected, but not private)
|
||||
);
|
||||
TPasAnalyzerOptions = set of TPasAnalyzerOption;
|
||||
|
||||
TPAUseMode = (
|
||||
paumElement, // mark element
|
||||
paumAllPublic, // mark element and descend into children and mark public identifiers
|
||||
paumAllExports // do not mark element and descend into children and mark exports
|
||||
paumElement, // Mark element. Do not descend into children.
|
||||
paumAllPublic, // Mark element and descend into children and mark public identifiers
|
||||
paumAllExports, // Do not mark element. Descend into children and mark exports.
|
||||
paumPublished // Mark element and its type and descend into children and mark published identifiers
|
||||
);
|
||||
TPAUseModes = set of TPAUseMode;
|
||||
|
||||
@ -188,6 +188,7 @@ type
|
||||
function ElementVisited(El: TPasElement; Mode: TPAUseMode): boolean;
|
||||
procedure UseElement(El: TPasElement; Access: TResolvedRefAccess;
|
||||
UseFull: boolean); virtual;
|
||||
procedure UsePublished(El: TPasElement); virtual;
|
||||
procedure UseModule(aModule: TPasModule; Mode: TPAUseMode); virtual;
|
||||
procedure UseSection(Section: TPasSection; Mode: TPAUseMode); virtual;
|
||||
procedure UseImplBlock(Block: TPasImplBlock; Mark: boolean); virtual;
|
||||
@ -221,6 +222,7 @@ type
|
||||
function FindElement(El: TPasElement): TPAElement;
|
||||
// utility
|
||||
function IsUsed(El: TPasElement): boolean; // valid after calling Analyze*
|
||||
function IsTypeInfoUsed(El: TPasElement): boolean; // valid after calling Analyze*
|
||||
function IsModuleInternal(El: TPasElement): boolean;
|
||||
function IsExport(El: TPasElement): boolean;
|
||||
function IsIdentifier(El: TPasElement): boolean;
|
||||
@ -615,6 +617,80 @@ begin
|
||||
RaiseNotSupported(20170307090947,El);
|
||||
end;
|
||||
|
||||
procedure TPasAnalyzer.UsePublished(El: TPasElement);
|
||||
// mark typeinfo, do not
|
||||
var
|
||||
C: TClass;
|
||||
Members: TFPList;
|
||||
i: Integer;
|
||||
Member: TPasElement;
|
||||
MemberResolved: TPasResolverResult;
|
||||
Prop: TPasProperty;
|
||||
ProcType: TPasProcedureType;
|
||||
begin
|
||||
{$IFDEF VerbosePasAnalyzer}
|
||||
writeln('TPasAnalyzer.UsePublished START ',GetObjName(El));
|
||||
{$ENDIF}
|
||||
if ElementVisited(El,paumPublished) then exit;
|
||||
C:=El.ClassType;
|
||||
if C=TPasUnresolvedSymbolRef then
|
||||
else if (C=TPasVariable) or (C=TPasConst) then
|
||||
UsePublished(TPasVariable(El).VarType)
|
||||
else if C=TPasProperty then
|
||||
begin
|
||||
// published property
|
||||
Prop:=TPasProperty(El);
|
||||
for i:=0 to Prop.Args.Count-1 do
|
||||
UsePublished(TPasArgument(Prop.Args[i]).ArgType);
|
||||
UsePublished(Prop.VarType);
|
||||
// Note: read, write and index don't need extra typeinfo
|
||||
|
||||
// stored and defaultvalue are only used when published -> mark as used
|
||||
UseElement(Prop.StoredAccessor,rraRead,false);
|
||||
UseElement(Prop.DefaultExpr,rraRead,false);
|
||||
end
|
||||
else if (C=TPasAliasType) or (C=TPasTypeAliasType) then
|
||||
UsePublished(TPasAliasType(El).DestType)
|
||||
else if C=TPasSetType then
|
||||
UsePublished(TPasSetType(El).EnumType)
|
||||
else if C=TPasArrayType then
|
||||
begin
|
||||
UsePublished(TPasArrayType(El).ElType);
|
||||
for i:=0 to length(TPasArrayType(El).Ranges)-1 do
|
||||
begin
|
||||
Member:=TPasArrayType(El).Ranges[i];
|
||||
Resolver.ComputeElement(Member,MemberResolved,[rcConstant]);
|
||||
UsePublished(MemberResolved.TypeEl);
|
||||
end;
|
||||
end
|
||||
else if C=TPasPointerType then
|
||||
UsePublished(TPasPointerType(El).DestType)
|
||||
else if C=TPasClassType then
|
||||
else if C=TPasClassOfType then
|
||||
else if C=TPasRecordType then
|
||||
begin
|
||||
// published record: use all members
|
||||
Members:=TPasRecordType(El).Members;
|
||||
for i:=0 to Members.Count-1 do
|
||||
begin
|
||||
UsePublished(TPasElement(Members[i]));
|
||||
UseElement(Member,rraNone,true);
|
||||
end;
|
||||
end
|
||||
else if C.InheritsFrom(TPasProcedure) then
|
||||
UsePublished(TPasProcedure(El).ProcType)
|
||||
else if C.InheritsFrom(TPasProcedureType) then
|
||||
begin
|
||||
ProcType:=TPasProcedureType(El);
|
||||
for i:=0 to ProcType.Args.Count-1 do
|
||||
UsePublished(TPasArgument(ProcType.Args[i]).ArgType);
|
||||
if El is TPasFunctionType then
|
||||
UsePublished(TPasFunctionType(El).ResultEl.ResultType);
|
||||
end
|
||||
else
|
||||
RaiseNotSupported(20170414153904,El);
|
||||
end;
|
||||
|
||||
procedure TPasAnalyzer.UseModule(aModule: TPasModule; Mode: TPAUseMode);
|
||||
|
||||
procedure UseInitFinal(aSection: TPasImplBlock);
|
||||
@ -1158,7 +1234,7 @@ procedure TPasAnalyzer.UseClassType(El: TPasClassType; Mode: TPAUseMode);
|
||||
var
|
||||
i: Integer;
|
||||
Member: TPasElement;
|
||||
UsePublished, FirstTime: Boolean;
|
||||
AllPublished, FirstTime: Boolean;
|
||||
ProcScope: TPasProcedureScope;
|
||||
ClassScope: TPasClassScope;
|
||||
Ref: TResolvedReference;
|
||||
@ -1178,6 +1254,8 @@ begin
|
||||
end;
|
||||
paumElement:
|
||||
if not MarkElementAsUsed(El) then exit;
|
||||
else
|
||||
RaiseInconsistency(20170414152143,IntToStr(ord(Mode)));
|
||||
end;
|
||||
{$IFDEF VerbosePasAnalyzer}
|
||||
writeln('TPasAnalyzer.UseClassType ',GetElModName(El),' ',Mode,' First=',FirstTime);
|
||||
@ -1199,7 +1277,7 @@ begin
|
||||
UseType(TPasType(El.Interfaces[i]),paumElement);
|
||||
end;
|
||||
// members
|
||||
UsePublished:=(Mode<>paumAllExports) and (paoKeepPublished in Options);
|
||||
AllPublished:=(Mode<>paumAllExports);
|
||||
for i:=0 to El.Members.Count-1 do
|
||||
begin
|
||||
Member:=TPasElement(El.Members[i]);
|
||||
@ -1209,10 +1287,11 @@ begin
|
||||
if ProcScope.OverriddenProc<>nil then
|
||||
AddOverride(ProcScope.OverriddenProc,Member);
|
||||
end;
|
||||
if UsePublished and (Member.Visibility=visPublished) then
|
||||
if AllPublished and (Member.Visibility=visPublished) then
|
||||
begin
|
||||
// include published
|
||||
if not FirstTime then continue;
|
||||
UsePublished(Member);
|
||||
end
|
||||
else if Mode=paumElement then
|
||||
continue
|
||||
@ -1763,6 +1842,11 @@ begin
|
||||
Result:=FindElement(El)<>nil;
|
||||
end;
|
||||
|
||||
function TPasAnalyzer.IsTypeInfoUsed(El: TPasElement): boolean;
|
||||
begin
|
||||
Result:=FChecked[paumPublished].Find(El)<>nil;
|
||||
end;
|
||||
|
||||
function TPasAnalyzer.IsModuleInternal(El: TPasElement): boolean;
|
||||
begin
|
||||
if El=nil then
|
||||
@ -1772,7 +1856,7 @@ begin
|
||||
if IsExport(El) then exit(false);
|
||||
case El.Visibility of
|
||||
visPrivate,visStrictPrivate: exit(true);
|
||||
visPublished: if paoKeepPublished in Options then exit(false);
|
||||
visPublished: exit(false);
|
||||
end;
|
||||
Result:=IsModuleInternal(El.Parent);
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user