mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 21:29:42 +02:00
fcl-passrc: specialize generic forward proc
git-svn-id: trunk@43052 -
This commit is contained in:
parent
009a3435c1
commit
422afb8ebc
@ -6554,7 +6554,7 @@ var
|
|||||||
i: Integer;
|
i: Integer;
|
||||||
Body: TProcedureBody;
|
Body: TProcedureBody;
|
||||||
SubEl: TPasElement;
|
SubEl: TPasElement;
|
||||||
SubProcScope, ProcScope: TPasProcedureScope;
|
SubProcScope, ProcScope, DeclProcScope: TPasProcedureScope;
|
||||||
SpecializedItem: TPRSpecializedItem;
|
SpecializedItem: TPRSpecializedItem;
|
||||||
begin
|
begin
|
||||||
{$IFDEF VerbosePasResolver}
|
{$IFDEF VerbosePasResolver}
|
||||||
@ -6600,6 +6600,11 @@ begin
|
|||||||
ProcScope.GroupScope:=nil;
|
ProcScope.GroupScope:=nil;
|
||||||
end;
|
end;
|
||||||
ProcScope.GenericStep:=psgsImplementationParsed;
|
ProcScope.GenericStep:=psgsImplementationParsed;
|
||||||
|
if ProcScope.DeclarationProc<>nil then
|
||||||
|
begin
|
||||||
|
DeclProcScope:=ProcScope.DeclarationProc.CustomData as TPasProcedureScope;
|
||||||
|
DeclProcScope.GenericStep:=psgsImplementationParsed;
|
||||||
|
end;
|
||||||
end
|
end
|
||||||
else if ProcScope.GroupScope<>nil then
|
else if ProcScope.GroupScope<>nil then
|
||||||
RaiseInternalError(20190122142142,GetObjName(Proc));
|
RaiseInternalError(20190122142142,GetObjName(Proc));
|
||||||
@ -6924,7 +6929,7 @@ begin
|
|||||||
DeclProcScope.ImplProc:=Proc;
|
DeclProcScope.ImplProc:=Proc;
|
||||||
ProcScope.DeclarationProc:=DeclProc;
|
ProcScope.DeclarationProc:=DeclProc;
|
||||||
// remove ImplProc from scope
|
// remove ImplProc from scope
|
||||||
(ParentScope as TPasIdentifierScope).RemoveLocalIdentifier(Proc);
|
ParentScope.RemoveLocalIdentifier(Proc);
|
||||||
// replace arguments with declaration arguments
|
// replace arguments with declaration arguments
|
||||||
ReplaceProcScopeImplArgsWithDeclArgs(ProcScope);
|
ReplaceProcScopeImplArgsWithDeclArgs(ProcScope);
|
||||||
exit;
|
exit;
|
||||||
@ -8969,6 +8974,7 @@ begin
|
|||||||
DeclTemplates:=GetProcTemplateTypes(DeclProc);
|
DeclTemplates:=GetProcTemplateTypes(DeclProc);
|
||||||
if ImplTemplates<>nil then
|
if ImplTemplates<>nil then
|
||||||
begin
|
begin
|
||||||
|
writeln('AAA1 TPasResolver.ReplaceProcScopeImplArgsWithDeclArgs DeclProc=',DeclProc.Name,' ImplProc=',ImplProc.Name,' ',ImplTemplates.Count);
|
||||||
if (DeclTemplates=nil) or (ImplTemplates.Count<>DeclTemplates.Count) then
|
if (DeclTemplates=nil) or (ImplTemplates.Count<>DeclTemplates.Count) then
|
||||||
RaiseNotYetImplemented(20190912153602,ImplProc); // inconsistency
|
RaiseNotYetImplemented(20190912153602,ImplProc); // inconsistency
|
||||||
for i:=0 to ImplTemplates.Count-1 do
|
for i:=0 to ImplTemplates.Count-1 do
|
||||||
@ -12061,6 +12067,7 @@ begin
|
|||||||
IsClassConDestructor:=(El.ClassType=TPasClassConstructor)
|
IsClassConDestructor:=(El.ClassType=TPasClassConstructor)
|
||||||
or (El.ClassType=TPasClassDestructor);
|
or (El.ClassType=TPasClassDestructor);
|
||||||
|
|
||||||
|
ClassOrRecType:=nil;
|
||||||
if El.CustomData is TPasProcedureScope then
|
if El.CustomData is TPasProcedureScope then
|
||||||
begin
|
begin
|
||||||
// adding a specialized implementation proc
|
// adding a specialized implementation proc
|
||||||
@ -12068,19 +12075,20 @@ begin
|
|||||||
if ProcScope.DeclarationProc<>nil then
|
if ProcScope.DeclarationProc<>nil then
|
||||||
TypeParams:=ProcScope.DeclarationProc.NameParts;
|
TypeParams:=ProcScope.DeclarationProc.NameParts;
|
||||||
ClassOrRecScope:=ProcScope.ClassRecScope;
|
ClassOrRecScope:=ProcScope.ClassRecScope;
|
||||||
if ClassOrRecScope=nil then
|
if ClassOrRecScope<>nil then
|
||||||
RaiseNotYetImplemented(20190804175307,El);
|
|
||||||
ClassOrRecType:=TPasMembersType(ClassOrRecScope.Element);
|
|
||||||
if GetTypeParameterCount(ClassOrRecType)>0 then
|
|
||||||
RaiseNotYetImplemented(20190804175518,El);
|
|
||||||
if ProcScope.GroupScope<>nil then
|
|
||||||
RaiseNotYetImplemented(20190804175451,El);
|
|
||||||
if (not HasDot) and IsClassConDestructor then
|
|
||||||
begin
|
begin
|
||||||
if El.ClassType=TPasClassConstructor then
|
ClassOrRecType:=TPasMembersType(ClassOrRecScope.Element);
|
||||||
AddClassConDestructor(ClassOrRecScope,TPasProcedure(ClassOrRecScope.ClassConstructor))
|
if GetTypeParameterCount(ClassOrRecType)>0 then
|
||||||
else
|
RaiseNotYetImplemented(20190804175518,El);
|
||||||
AddClassConDestructor(ClassOrRecScope,TPasProcedure(ClassOrRecScope.ClassDestructor));
|
if ProcScope.GroupScope<>nil then
|
||||||
|
RaiseNotYetImplemented(20190804175451,El);
|
||||||
|
if (not HasDot) and IsClassConDestructor then
|
||||||
|
begin
|
||||||
|
if El.ClassType=TPasClassConstructor then
|
||||||
|
AddClassConDestructor(ClassOrRecScope,TPasProcedure(ClassOrRecScope.ClassConstructor))
|
||||||
|
else
|
||||||
|
AddClassConDestructor(ClassOrRecScope,TPasProcedure(ClassOrRecScope.ClassDestructor));
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
PushScope(ProcScope);
|
PushScope(ProcScope);
|
||||||
@ -16268,7 +16276,21 @@ var
|
|||||||
SpecClassOrRecScope: TPasClassOrRecordScope;
|
SpecClassOrRecScope: TPasClassOrRecordScope;
|
||||||
NewImplProcName, OldClassname: String;
|
NewImplProcName, OldClassname: String;
|
||||||
p, LastDotP: Integer;
|
p, LastDotP: Integer;
|
||||||
|
SpecializedProcItem: TPRSpecializedProcItem;
|
||||||
|
SpecializedTypeItem: TPRSpecializedTypeItem;
|
||||||
|
Templates: TFPList;
|
||||||
begin
|
begin
|
||||||
|
SpecializedProcItem:=nil;
|
||||||
|
SpecializedTypeItem:=nil;
|
||||||
|
if SpecializedItem is TPRSpecializedProcItem then
|
||||||
|
// impl proc of a specialized forward proc
|
||||||
|
SpecializedProcItem:=TPRSpecializedProcItem(SpecializedItem)
|
||||||
|
else if SpecializedItem is TPRSpecializedTypeItem then
|
||||||
|
// method of a specialized class/record
|
||||||
|
SpecializedTypeItem:=TPRSpecializedTypeItem(SpecializedItem)
|
||||||
|
else
|
||||||
|
RaiseNotYetImplemented(20190922145050,SpecDeclProc);
|
||||||
|
|
||||||
GenDeclProcScope:=TPasProcedureScope(GenDeclProc.CustomData);
|
GenDeclProcScope:=TPasProcedureScope(GenDeclProc.CustomData);
|
||||||
GenImplProc:=GenDeclProcScope.ImplProc;
|
GenImplProc:=GenDeclProcScope.ImplProc;
|
||||||
if GenImplProc=nil then
|
if GenImplProc=nil then
|
||||||
@ -16293,18 +16315,17 @@ begin
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
// create impl proc name
|
// create impl proc name
|
||||||
NewImplProcName:=GenImplProc.Name;
|
if SpecializedTypeItem<>nil then
|
||||||
|
|
||||||
if SpecializedItem=nil then
|
|
||||||
begin
|
begin
|
||||||
// method of a specialized class/record
|
// method of a specialized class/record
|
||||||
if SpecClassOrRecScope=nil then
|
if SpecClassOrRecScope=nil then
|
||||||
RaiseNotYetImplemented(20190921221839,SpecDeclProc);
|
RaiseNotYetImplemented(20190921221839,SpecDeclProc);
|
||||||
|
NewImplProcName:=GenImplProc.Name;
|
||||||
p:=length(NewImplProcName);
|
p:=length(NewImplProcName);
|
||||||
while (p>0) and (NewImplProcName[p]<>'.') do dec(p);
|
while (p>0) and (NewImplProcName[p]<>'.') do dec(p);
|
||||||
if p=0 then
|
if p=0 then
|
||||||
RaiseNotYetImplemented(20190921221730,GenImplProc);
|
RaiseNotYetImplemented(20190921221730,GenImplProc);
|
||||||
// has classname -> replace generic clasname with specialized classname
|
// has classname -> replace generic classname with specialized classname
|
||||||
LastDotP:=p;
|
LastDotP:=p;
|
||||||
while (p>1) and (NewImplProcName[p-1]<>'.') do dec(p);
|
while (p>1) and (NewImplProcName[p-1]<>'.') do dec(p);
|
||||||
OldClassname:=copy(NewImplProcName,p,LastDotP-p);
|
OldClassname:=copy(NewImplProcName,p,LastDotP-p);
|
||||||
@ -16312,16 +16333,27 @@ begin
|
|||||||
if not SameText(OldClassname,GenClassOrRec.Name) then
|
if not SameText(OldClassname,GenClassOrRec.Name) then
|
||||||
RaiseNotYetImplemented(20190814141833,GenImplProc);
|
RaiseNotYetImplemented(20190814141833,GenImplProc);
|
||||||
NewImplProcName:=LeftStr(NewImplProcName,p-1)+SpecClassOrRec.Name+copy(NewImplProcName,LastDotP,length(NewImplProcName));
|
NewImplProcName:=LeftStr(NewImplProcName,p-1)+SpecClassOrRec.Name+copy(NewImplProcName,LastDotP,length(NewImplProcName));
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
// use classname of GenImplProc and name of SpecDeclProc
|
||||||
|
OldClassname:=GenImplProc.Name;
|
||||||
|
p:=length(OldClassname);
|
||||||
|
while (p>0) and (OldClassname[p]<>'.') do dec(p);
|
||||||
|
if p>0 then
|
||||||
|
NewImplProcName:=LeftStr(OldClassname,p)+SpecDeclProc.Name
|
||||||
|
else
|
||||||
|
NewImplProcName:=SpecDeclProc.Name;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// create impl proc
|
// create impl proc
|
||||||
NewClass:=TPTreeElement(GenImplProc.ClassType);
|
NewClass:=TPTreeElement(GenImplProc.ClassType);
|
||||||
SpecImplProc:=TPasProcedure(NewClass.Create(NewImplProcName,GenImplProc.Parent));
|
SpecImplProc:=TPasProcedure(NewClass.Create(NewImplProcName,GenImplProc.Parent));
|
||||||
SpecDeclProcScope.ImplProc:=SpecImplProc;
|
SpecDeclProcScope.ImplProc:=SpecImplProc;
|
||||||
if SpecializedItem is TPRSpecializedProcItem then
|
if SpecializedProcItem<>nil then
|
||||||
TPRSpecializedProcItem(SpecializedItem).ImplProc:=SpecImplProc
|
SpecializedProcItem.ImplProc:=SpecImplProc
|
||||||
else
|
else
|
||||||
TPRSpecializedTypeItem(SpecializedItem).ImplProcs.Add(SpecImplProc);
|
SpecializedTypeItem.ImplProcs.Add(SpecImplProc);
|
||||||
|
|
||||||
// create impl proc scope
|
// create impl proc scope
|
||||||
SpecImplProcScope:=TPasProcedureScope(CreateScope(SpecImplProc,FScopeClass_Proc));
|
SpecImplProcScope:=TPasProcedureScope(CreateScope(SpecImplProc,FScopeClass_Proc));
|
||||||
@ -16331,9 +16363,20 @@ begin
|
|||||||
SpecImplProcScope.BoolSwitches:=GenImplProcScope.BoolSwitches;
|
SpecImplProcScope.BoolSwitches:=GenImplProcScope.BoolSwitches;
|
||||||
SpecImplProcScope.VisibilityContext:=SpecClassOrRec;
|
SpecImplProcScope.VisibilityContext:=SpecClassOrRec;
|
||||||
SpecImplProcScope.ClassRecScope:=SpecClassOrRecScope;
|
SpecImplProcScope.ClassRecScope:=SpecClassOrRecScope;
|
||||||
|
if GenDeclProcScope.SelfArg<>nil then
|
||||||
|
RaiseNotYetImplemented(20190922154603,GenImplProc);
|
||||||
|
|
||||||
|
if SpecializedProcItem<>nil then
|
||||||
|
begin
|
||||||
|
Templates:=GetProcTemplateTypes(GenDeclProc);
|
||||||
|
AddSpecializedTemplateIdentifiers(Templates,SpecializedItem,SpecImplProcScope,
|
||||||
|
false);
|
||||||
|
end;
|
||||||
|
|
||||||
// specialize props
|
// specialize props
|
||||||
SpecializeElement(GenImplProc,SpecImplProc);
|
SpecializePasElementProperties(GenImplProc,SpecImplProc);
|
||||||
|
AddProcedure(SpecImplProc,nil);
|
||||||
|
SpecializeProcedure(GenImplProc,SpecImplProc,SpecializedItem);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPasResolver.SpecializeElement(GenEl, SpecEl: TPasElement);
|
procedure TPasResolver.SpecializeElement(GenEl, SpecEl: TPasElement);
|
||||||
@ -16744,7 +16787,13 @@ var
|
|||||||
GenBody: TProcedureBody;
|
GenBody: TProcedureBody;
|
||||||
begin
|
begin
|
||||||
GenProcScope:=GenEl.CustomData as TPasProcedureScope;
|
GenProcScope:=GenEl.CustomData as TPasProcedureScope;
|
||||||
if SpecializedItem<>nil then
|
SpecProcScope:=SpecEl.CustomData as TPasProcedureScope;
|
||||||
|
if SpecProcScope<>nil then
|
||||||
|
begin
|
||||||
|
if TopScope<>SpecProcScope then
|
||||||
|
RaiseNotYetImplemented(20190920194151,SpecEl);
|
||||||
|
end
|
||||||
|
else if SpecializedItem<>nil then
|
||||||
begin
|
begin
|
||||||
// specialized generic/parametrized procedure
|
// specialized generic/parametrized procedure
|
||||||
SpecProcScope:=TPasProcedureScope(PushScope(SpecEl,ScopeClass_Procedure));
|
SpecProcScope:=TPasProcedureScope(PushScope(SpecEl,ScopeClass_Procedure));
|
||||||
@ -16766,12 +16815,7 @@ begin
|
|||||||
AddSpecializedTemplateIdentifiers(Templates,SpecializedItem,SpecProcScope,true);
|
AddSpecializedTemplateIdentifiers(Templates,SpecializedItem,SpecProcScope,true);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
RaiseNotYetImplemented(20190922153918,SpecEl);
|
||||||
// specialized procedure of a specialized parent
|
|
||||||
SpecProcScope:=SpecEl.CustomData as TPasProcedureScope;
|
|
||||||
if TopScope<>SpecProcScope then
|
|
||||||
RaiseNotYetImplemented(20190920194151,SpecEl);
|
|
||||||
end;
|
|
||||||
Include(SpecProcScope.Flags,ppsfIsSpecialized);
|
Include(SpecProcScope.Flags,ppsfIsSpecialized);
|
||||||
|
|
||||||
if GenEl.PublicName<>nil then
|
if GenEl.PublicName<>nil then
|
||||||
|
@ -122,7 +122,7 @@ type
|
|||||||
procedure TestGenProc_Function;
|
procedure TestGenProc_Function;
|
||||||
procedure TestGenProc_FunctionDelphi;
|
procedure TestGenProc_FunctionDelphi;
|
||||||
procedure TestGenProc_OverloadDuplicate;
|
procedure TestGenProc_OverloadDuplicate;
|
||||||
procedure TestGenProc_Forward; // ToDo
|
procedure TestGenProc_Forward;
|
||||||
//procedure TestGenProc_External;
|
//procedure TestGenProc_External;
|
||||||
//procedure TestGenProc_UnitIntf;
|
//procedure TestGenProc_UnitIntf;
|
||||||
procedure TestGenProc_BackRef1Fail;
|
procedure TestGenProc_BackRef1Fail;
|
||||||
@ -1751,14 +1751,13 @@ end;
|
|||||||
|
|
||||||
procedure TTestResolveGenerics.TestGenProc_Forward;
|
procedure TTestResolveGenerics.TestGenProc_Forward;
|
||||||
begin
|
begin
|
||||||
exit;
|
|
||||||
StartProgram(false);
|
StartProgram(false);
|
||||||
Add([
|
Add([
|
||||||
'generic procedure Fly<T>(a: T); forward;',
|
'generic procedure Fly<T>(a: T); forward;',
|
||||||
//'generic procedure Run;',
|
'generic procedure Run;',
|
||||||
//'begin',
|
'begin',
|
||||||
//' specialize Fly<word>(3);',
|
' specialize Fly<word>(3);',
|
||||||
//'end;',
|
'end;',
|
||||||
'generic procedure Fly<T>(a: T);',
|
'generic procedure Fly<T>(a: T);',
|
||||||
'var i: T;',
|
'var i: T;',
|
||||||
'begin',
|
'begin',
|
||||||
|
Loading…
Reference in New Issue
Block a user