fcl-passrc: UseTypeInfo of record and class: skip generic elements

This commit is contained in:
mattias 2022-02-10 22:10:58 +01:00
parent 7b62186b9c
commit 30e24e48c2

View File

@ -257,8 +257,9 @@ type
function ElementVisited(El: TPasElement; Mode: TPAUseMode): boolean; overload; function ElementVisited(El: TPasElement; Mode: TPAUseMode): boolean; overload;
function ElementVisited(El: TPasElement; OtherCheck: TPAOtherCheckedEl): boolean; overload; function ElementVisited(El: TPasElement; OtherCheck: TPAOtherCheckedEl): boolean; overload;
procedure MarkImplScopeRef(El, RefEl: TPasElement; Access: TPSRefAccess); procedure MarkImplScopeRef(El, RefEl: TPasElement; Access: TPSRefAccess);
function CanSkipGenericType(El: TPasGenericType): boolean; function IsGenericElement(El: TPasElement): boolean; virtual;
function CanSkipGenericProc(DeclProc: TPasProcedure): boolean; function CanSkipGenericType(El: TPasGenericType): boolean; virtual;
function CanSkipGenericProc(DeclProc: TPasProcedure): boolean; virtual;
procedure UseElement(El: TPasElement; Access: TResolvedRefAccess; procedure UseElement(El: TPasElement; Access: TResolvedRefAccess;
UseFull: boolean); virtual; UseFull: boolean); virtual;
procedure UseTypeInfo(El: TPasElement); virtual; procedure UseTypeInfo(El: TPasElement); virtual;
@ -1032,6 +1033,19 @@ begin
CheckImplRef; CheckImplRef;
end; end;
function TPasAnalyzer.IsGenericElement(El: TPasElement): boolean;
var
C: TClass;
begin
C:=El.ClassType;
if C.InheritsFrom(TPasProcedure) then
Result:=TPasProcedure(El).NameParts<>nil
else if C.InheritsFrom(TPasGenericType) then
Result:=TPasGenericType(El).GenericTemplateTypes<>nil
else
Result:=false;
end;
function TPasAnalyzer.CanSkipGenericType(El: TPasGenericType): boolean; function TPasAnalyzer.CanSkipGenericType(El: TPasGenericType): boolean;
procedure RaiseHalfSpecialized; procedure RaiseHalfSpecialized;
@ -1260,7 +1274,9 @@ begin
Member:=TPasElement(Members[i]); Member:=TPasElement(Members[i]);
if Member.ClassType=TPasAttributes then if Member.ClassType=TPasAttributes then
continue; continue;
if IsUsed(Member) then if IsGenericElement(Member) then
continue;
if IsUsed(Member) then // only used elements of a class
UseTypeInfo(Member); UseTypeInfo(Member);
end; end;
end; end;
@ -1268,7 +1284,7 @@ begin
else if C=TPasClassOfType then else if C=TPasClassOfType then
else if C=TPasRecordType then else if C=TPasRecordType then
begin begin
// published record: use all members // published record: use all members (except generic)
if CanSkipGenericType(TPasRecordType(El)) then exit; if CanSkipGenericType(TPasRecordType(El)) then exit;
Members:=TPasRecordType(El).Members; Members:=TPasRecordType(El).Members;
for i:=0 to Members.Count-1 do for i:=0 to Members.Count-1 do
@ -1276,6 +1292,9 @@ begin
Member:=TPasElement(Members[i]); Member:=TPasElement(Members[i]);
if Member.ClassType=TPasAttributes then if Member.ClassType=TPasAttributes then
continue; // attributes are never used directly continue; // attributes are never used directly
if IsGenericElement(Member) then
continue;
// all elements, even if not used
UseSubEl(Member); UseSubEl(Member);
end; end;
end end