diff --git a/compiler/packages/fcl-passrc/src/pasresolver.pp b/compiler/packages/fcl-passrc/src/pasresolver.pp index b9b5a3e..9d0f26e 100644 --- a/compiler/packages/fcl-passrc/src/pasresolver.pp +++ b/compiler/packages/fcl-passrc/src/pasresolver.pp @@ -18837,7 +18837,10 @@ begin begin // inside procedure: first param is function result ProcScope:=TPasProcedureScope(Scopes[i]); - CtxProc:=TPasProcedure(ProcScope.Element); + if ProcScope.DeclarationProc<>nil then + CtxProc:=ProcScope.DeclarationProc + else + CtxProc:=TPasProcedure(ProcScope.Element); if not (CtxProc.ProcType is TPasFunctionType) then begin if RaiseOnError then diff --git a/compiler/packages/fcl-passrc/src/pasuseanalyzer.pas b/compiler/packages/fcl-passrc/src/pasuseanalyzer.pas index 5faf8d4..f2b731b 100644 --- a/compiler/packages/fcl-passrc/src/pasuseanalyzer.pas +++ b/compiler/packages/fcl-passrc/src/pasuseanalyzer.pas @@ -1281,7 +1281,7 @@ begin if CanSkipGenericType(ProcType) then exit; for i:=0 to ProcType.Args.Count-1 do UseSubEl(TPasArgument(ProcType.Args[i]).ArgType); - if El is TPasFunctionType then + if (El is TPasFunctionType) and (TPasFunctionType(El).ResultEl<>nil) then UseSubEl(TPasFunctionType(El).ResultEl.ResultType); end else if C=TPasSpecializeType then @@ -1543,12 +1543,15 @@ begin UseExpr(ForLoop.StartExpr); UseExpr(ForLoop.EndExpr); ForScope:=ForLoop.CustomData as TPasForLoopScope; - MarkImplScopeRef(ForLoop,ForScope.GetEnumerator,psraRead); - UseProcedure(ForScope.GetEnumerator); - MarkImplScopeRef(ForLoop,ForScope.MoveNext,psraRead); - UseProcedure(ForScope.MoveNext); - MarkImplScopeRef(ForLoop,ForScope.Current,psraRead); - UseVariable(ForScope.Current,rraRead,false); + if ForScope<>nil then + begin + MarkImplScopeRef(ForLoop,ForScope.GetEnumerator,psraRead); + UseProcedure(ForScope.GetEnumerator); + MarkImplScopeRef(ForLoop,ForScope.MoveNext,psraRead); + UseProcedure(ForScope.MoveNext); + MarkImplScopeRef(ForLoop,ForScope.Current,psraRead); + UseVariable(ForScope.Current,rraRead,false); + end; UseImplElement(ForLoop.Body); end else if C=TPasImplIfElse then @@ -1650,12 +1653,14 @@ procedure TPasAnalyzer.UseExpr(El: TPasExpr); UseElement(SubEl,rraAssign,false); end; - procedure UseBuilInFuncTypeInfo; + procedure UseBuiltInFuncTypeInfo; var ParentParams: TPRParentParams; ParamResolved: TPasResolverResult; SubEl: TPasElement; Params: TPasExprArray; + ProcScope: TPasProcedureScope; + Proc: TPasProcedure; begin Resolver.GetParamsOfNameExpr(El,ParentParams); if ParentParams.Params=nil then @@ -1672,7 +1677,11 @@ procedure TPasAnalyzer.UseExpr(El: TPasExpr); if (ParamResolved.IdentEl is TPasProcedure) and (TPasProcedure(ParamResolved.IdentEl).ProcType is TPasFunctionType) then begin - SubEl:=TPasFunctionType(TPasProcedure(ParamResolved.IdentEl).ProcType).ResultEl.ResultType; + Proc:=TPasProcedure(ParamResolved.IdentEl); + ProcScope:=Proc.CustomData as TPasProcedureScope; + if ProcScope.DeclarationProc<>nil then + Proc:=ProcScope.DeclarationProc; + SubEl:=TPasFunctionType(Proc.ProcType).ResultEl.ResultType; MarkImplScopeRef(El,SubEl,psraTypeInfo); UseTypeInfo(SubEl); end @@ -1751,7 +1760,7 @@ begin end; bfTypeInfo: begin - UseBuilInFuncTypeInfo; + UseBuiltInFuncTypeInfo; exit; end; bfAssert: diff --git a/compiler/packages/pastojs/src/pas2jsfiler.pp b/compiler/packages/pastojs/src/pas2jsfiler.pp index 6e73c21..2b044cd 100644 --- a/compiler/packages/pastojs/src/pas2jsfiler.pp +++ b/compiler/packages/pastojs/src/pas2jsfiler.pp @@ -3455,7 +3455,7 @@ begin ParentRef.Obj.Add('Specs',ParentRef.Specs); end; ParentRef.Specs.Add(Ref.Obj); - if Ref.Id=0 then + if (Ref.Id=0) then CreateElReferenceId(Ref); // every specialization needs an ID end else @@ -5651,11 +5651,12 @@ procedure TPCUReader.ResolveSpecializedElements(Complete: boolean); OtherPendSpec: TPCUReaderPendingSpecialized; begin Result:=false; + if PendSpec.RefEl=nil then exit; for i:=0 to PendSpec.Params.Count-1 do begin Param:=TPCUReaderPendingSpecializedParam(PendSpec.Params[i]); Ref:=GetElReference(Param.Id,PendSpec.GenericEl); - if Ref.Element<>nil then continue; + if (Ref=nil) or (Ref.Element<>nil) then continue; OtherPendSpec:=FPendingSpecialize; while OtherPendSpec<>nil do begin @@ -5669,6 +5670,27 @@ procedure TPCUReader.ResolveSpecializedElements(Complete: boolean); end; end; + function FreeTemplateSpecialization(PendSpec: TPCUReaderPendingSpecialized): boolean; + // checks if PendSpec params are only TPasGenericTemplateType + // if yes, frees this PendSpec + var + i: Integer; + Param: TPCUReaderPendingSpecializedParam; + Ref: TPCUFilerElementRef; + begin + Result:=true; + for i:=0 to PendSpec.Params.Count-1 do + begin + Param:=TPCUReaderPendingSpecializedParam(PendSpec.Params[i]); + Ref:=GetElReference(Param.Id,PendSpec.GenericEl); + if Ref=nil then + exit(false); + if not (Ref.Element is TPasGenericTemplateType) then + exit(false); + end; + DeletePendingSpecialize(PendSpec); + end; + var PendSpec, NextPendSpec, UnresolvedSpec: TPCUReaderPendingSpecialized; Changed: Boolean; @@ -5681,6 +5703,7 @@ begin while PendSpec<>nil do begin NextPendSpec:=PendSpec.Next; + if PendSpec.RefEl=nil then begin // no referrer -> use the first element, waiting for this ID @@ -5698,6 +5721,11 @@ begin Changed:=true else UnresolvedSpec:=PendSpec; + end + else if Complete and (PendSpec.RefEl=nil) then + begin + if FreeTemplateSpecialization(PendSpec) then + Changed:=true; end; PendSpec:=NextPendSpec; end;