fcl-passrc: half specialized type

git-svn-id: trunk@42715 -
This commit is contained in:
Mattias Gaertner 2019-08-17 13:35:16 +00:00
parent 5bf43bd1d4
commit 4787de8764
3 changed files with 51 additions and 11 deletions

View File

@ -2209,9 +2209,10 @@ type
function IsArrayExpr(Expr: TParamsExpr): TPasArrayType;
function IsArrayOperatorAdd(Expr: TPasExpr): boolean;
function IsTypeCast(Params: TParamsExpr): boolean;
function IsGenericTemplType(const ResolvedEl: TPasResolverResult): boolean;
function GetTypeParameterCount(aType: TPasGenericType): integer;
function GetGenericConstraintKeyword(El: TPasExpr): TToken;
function IsGenericTemplType(const ResolvedEl: TPasResolverResult): boolean;
function IsFullySpecialized(El: TPasGenericType): boolean;
function IsInterfaceType(const ResolvedEl: TPasResolverResult;
IntfType: TPasClassInterfaceType): boolean; overload;
function IsInterfaceType(TypeEl: TPasType; IntfType: TPasClassInterfaceType): boolean; overload;
@ -25472,6 +25473,23 @@ begin
end;
end;
function TPasResolver.IsFullySpecialized(El: TPasGenericType): boolean;
var
GenScope: TPasGenericScope;
Params: TPasTypeArray;
i: Integer;
begin
if (El.GenericTemplateTypes<>nil) and (El.GenericTemplateTypes.Count>0) then
exit(false);
if not (El.CustomData is TPasGenericScope) then exit(true);
GenScope:=TPasGenericScope(El.CustomData);
if GenScope.SpecializedItem=nil then exit(true);
Params:=GenScope.SpecializedItem.Params;
for i:=0 to length(Params)-1 do
if Params[i] is TPasGenericTemplateType then exit(false);
Result:=true;
end;
function TPasResolver.IsInterfaceType(const ResolvedEl: TPasResolverResult;
IntfType: TPasClassInterfaceType): boolean;
begin

View File

@ -831,7 +831,7 @@ var
s: String;
E: EPasAnalyzer;
begin
s:='['+IntToStr(Id)+']: Element='+GetElModName(El);
s:='['+IntToStr(Id)+']: Element='+GetObjPath(El);
if Msg<>'' then S:=S+' '+Msg;
E:=EPasAnalyzer.Create(s);
E.PasElement:=El;
@ -1065,6 +1065,7 @@ var
Prop: TPasProperty;
ProcType: TPasProcedureType;
ClassEl: TPasClassType;
ArrType: TPasArrayType;
begin
{$IFDEF VerbosePasAnalyzer}
writeln('TPasAnalyzer.UsePublished START ',GetObjName(El));
@ -1100,10 +1101,13 @@ begin
else if C=TPasRangeType then
else if C=TPasArrayType then
begin
UseSubEl(TPasArrayType(El).ElType);
for i:=0 to length(TPasArrayType(El).Ranges)-1 do
ArrType:=TPasArrayType(El);
if (ScopeModule=nil) and not Resolver.IsFullySpecialized(ArrType) then
RaiseNotSupported(20190817151437,ArrType);
UseSubEl(ArrType.ElType);
for i:=0 to length(ArrType.Ranges)-1 do
begin
Member:=TPasArrayType(El).Ranges[i];
Member:=ArrType.Ranges[i];
Resolver.ComputeElement(Member,MemberResolved,[rcConstant]);
UseSubEl(MemberResolved.HiTypeEl);
end;
@ -1145,11 +1149,20 @@ begin
else if C.InheritsFrom(TPasProcedureType) then
begin
ProcType:=TPasProcedureType(El);
if (ScopeModule=nil) and not Resolver.IsFullySpecialized(ProcType) then
RaiseNotSupported(20190817151554,ProcType);
for i:=0 to ProcType.Args.Count-1 do
UseSubEl(TPasArgument(ProcType.Args[i]).ArgType);
if El is TPasFunctionType then
UseSubEl(TPasFunctionType(El).ResultEl.ResultType);
end
else if C=TPasSpecializeType then
UseSubEl(TPasSpecializeType(El).DestType)
else if C=TPasGenericTemplateType then
begin
if ScopeModule=nil then
RaiseNotSupported(20190817110226,El);
end
else
begin
{$IFDEF VerbosePasAnalyzer}
@ -1844,6 +1857,8 @@ begin
writeln('TPasAnalyzer.UseProcedureType ',GetElModName(ProcType));
{$ENDIF}
if not MarkElementAsUsed(ProcType) then exit;
if (ScopeModule=nil) and not Resolver.IsFullySpecialized(ProcType) then
RaiseNotSupported(20190817151651,ProcType);
for i:=0 to ProcType.Args.Count-1 do
begin
@ -1861,6 +1876,7 @@ procedure TPasAnalyzer.UseType(El: TPasType; Mode: TPAUseMode);
var
C: TClass;
i: Integer;
ArrType: TPasArrayType;
begin
if El=nil then exit;
@ -1896,10 +1912,13 @@ begin
end
else if C=TPasArrayType then
begin
if not MarkElementAsUsed(El) then exit;
for i:=0 to length(TPasArrayType(El).Ranges)-1 do
UseExpr(TPasArrayType(El).Ranges[i]);
UseElType(El,TPasArrayType(El).ElType,Mode);
ArrType:=TPasArrayType(El);
if (ScopeModule=nil) and not Resolver.IsFullySpecialized(ArrType) then
RaiseNotSupported(20190817151449,ArrType);
if not MarkElementAsUsed(ArrType) then exit;
for i:=0 to length(ArrType.Ranges)-1 do
UseExpr(ArrType.Ranges[i]);
UseElType(El,ArrType.ElType,Mode);
end
else if (C=TPasRecordType) or (C=TPasClassType) then
UseClassOrRecType(TPasMembersType(El),Mode)
@ -1928,6 +1947,7 @@ begin
UseProcedureType(TPasProcedureType(El))
else if C=TPasSpecializeType then
UseSpecializeType(TPasSpecializeType(El),Mode)
else if C=TPasGenericTemplateType then
else
RaiseNotSupported(20170306170315,El);
@ -2001,6 +2021,8 @@ var
aClass: TPasClassType;
begin
FirstTime:=true;
if (ScopeModule=nil) and not Resolver.IsFullySpecialized(El) then
RaiseNotSupported(20190817110919,El);
case Mode of
paumAllExports: exit;
paumAllPasUsable:

View File

@ -5908,8 +5908,8 @@ begin
' if unit1.j1=0 then ;',
' if unitdots.unit1.j1=0 then ;',
'']);
CheckResolverException('Duplicate identifier "unitdots.unit1" at unitdots.main1.pas(2,14)',
nDuplicateIdentifier);
CheckParserException('Duplicate identifier "unit1" at token ";" in file unitdots.main1.pas at line 2 column 27',
nParserDuplicateIdentifier);
end;
procedure TTestResolver.TestUnit_Unit1DotUnit2Fail;