mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 14:09:17 +02:00
fcl-passrc: started specialize type reference a<b>.c
git-svn-id: trunk@49256 -
This commit is contained in:
parent
1ab2ad3b06
commit
6d551fad4c
@ -1690,6 +1690,7 @@ type
|
|||||||
procedure FinishMethodImplHeader(ImplProc: TPasProcedure); virtual;
|
procedure FinishMethodImplHeader(ImplProc: TPasProcedure); virtual;
|
||||||
procedure FinishExceptOnExpr; virtual;
|
procedure FinishExceptOnExpr; virtual;
|
||||||
procedure FinishExceptOnStatement; virtual;
|
procedure FinishExceptOnStatement; virtual;
|
||||||
|
procedure FinishParserSpecializeType(El: TPasSpecializeType); virtual;
|
||||||
procedure FinishWithDo(El: TPasImplWithDo); virtual;
|
procedure FinishWithDo(El: TPasImplWithDo); virtual;
|
||||||
procedure FinishForLoopHeader(Loop: TPasImplForLoop); virtual;
|
procedure FinishForLoopHeader(Loop: TPasImplForLoop); virtual;
|
||||||
procedure FinishDeclaration(El: TPasElement); virtual;
|
procedure FinishDeclaration(El: TPasElement); virtual;
|
||||||
@ -2153,6 +2154,7 @@ type
|
|||||||
function PushHelperDotScope(HiType: TPasType): TPasDotBaseScope;
|
function PushHelperDotScope(HiType: TPasType): TPasDotBaseScope;
|
||||||
function PushTemplateDotScope(TemplType: TPasGenericTemplateType; ErrorEl: TPasElement): TPasDotBaseScope;
|
function PushTemplateDotScope(TemplType: TPasGenericTemplateType; ErrorEl: TPasElement): TPasDotBaseScope;
|
||||||
function PushDotScope(HiType: TPasType): TPasDotBaseScope;
|
function PushDotScope(HiType: TPasType): TPasDotBaseScope;
|
||||||
|
function PushParserSpecializeType(SpecType: TPasSpecializeType): TPasDotBaseScope;
|
||||||
function PushWithExprScope(Expr: TPasExpr): TPasWithExprScope;
|
function PushWithExprScope(Expr: TPasExpr): TPasWithExprScope;
|
||||||
function StashScopes(NewScopeCnt: integer): integer; // returns old StashDepth
|
function StashScopes(NewScopeCnt: integer): integer; // returns old StashDepth
|
||||||
function StashSubExprScopes: integer; // returns old StashDepth
|
function StashSubExprScopes: integer; // returns old StashDepth
|
||||||
@ -5238,6 +5240,9 @@ begin
|
|||||||
begin
|
begin
|
||||||
// El is the first element found -> raise error
|
// El is the first element found -> raise error
|
||||||
// ToDo: use the ( as error position
|
// ToDo: use the ( as error position
|
||||||
|
{$IFDEF VerbosePasResolver}
|
||||||
|
writeln('TPasResolver.OnFindCallElements El=',GetObjPath(El));
|
||||||
|
{$ENDIF}
|
||||||
RaiseMsg(20170216151525,nIllegalQualifierAfter,sIllegalQualifierAfter,
|
RaiseMsg(20170216151525,nIllegalQualifierAfter,sIllegalQualifierAfter,
|
||||||
['(',El.ElementTypeName],Data^.Params);
|
['(',El.ElementTypeName],Data^.Params);
|
||||||
end;
|
end;
|
||||||
@ -7606,6 +7611,12 @@ begin
|
|||||||
PopScope;
|
PopScope;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPasResolver.FinishParserSpecializeType(El: TPasSpecializeType);
|
||||||
|
begin
|
||||||
|
if El=nil then ;
|
||||||
|
PopScope;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TPasResolver.FinishWithDo(El: TPasImplWithDo);
|
procedure TPasResolver.FinishWithDo(El: TPasImplWithDo);
|
||||||
begin
|
begin
|
||||||
PopWithScope(El);
|
PopWithScope(El);
|
||||||
@ -18120,6 +18131,13 @@ begin
|
|||||||
SpecializeElList(GenEl,SpecEl,GenEl.Params,SpecEl.Params,true
|
SpecializeElList(GenEl,SpecEl,GenEl.Params,SpecEl.Params,true
|
||||||
{$IFDEF CheckPasTreeRefCount},'TPasSpecializeType.Params'{$ENDIF});
|
{$IFDEF CheckPasTreeRefCount},'TPasSpecializeType.Params'{$ENDIF});
|
||||||
|
|
||||||
|
if GenEl.SubType<>nil then
|
||||||
|
begin
|
||||||
|
PushParserSpecializeType(SpecEl);
|
||||||
|
SpecializeElType(GenEl,SpecEl,GenEl.SubType,SpecEl.SubType);
|
||||||
|
PopScope;
|
||||||
|
end;
|
||||||
|
|
||||||
FinishSpecializeType(SpecEl);
|
FinishSpecializeType(SpecEl);
|
||||||
{$IFDEF VerbosePasResolver}
|
{$IFDEF VerbosePasResolver}
|
||||||
//writeln('TPasResolver.SpecializeSpecializeType ',GetObjName(SpecEl.DestType),' ',GetObjName(SpecEl.CustomData));
|
//writeln('TPasResolver.SpecializeSpecializeType ',GetObjName(SpecEl.DestType),' ',GetObjName(SpecEl.CustomData));
|
||||||
@ -21807,6 +21825,7 @@ end;
|
|||||||
procedure TPasResolver.BeginScope(ScopeType: TPasScopeType; El: TPasElement);
|
procedure TPasResolver.BeginScope(ScopeType: TPasScopeType; El: TPasElement);
|
||||||
begin
|
begin
|
||||||
case ScopeType of
|
case ScopeType of
|
||||||
|
stSpecializeType: PushParserSpecializeType(El as TPasSpecializeType);
|
||||||
stWithExpr: PushWithExprScope(El as TPasExpr);
|
stWithExpr: PushWithExprScope(El as TPasExpr);
|
||||||
else
|
else
|
||||||
RaiseMsg(20181210163324,nNotYetImplemented,sNotYetImplemented+' BeginScope',[IntToStr(ord(ScopeType))],nil);
|
RaiseMsg(20181210163324,nNotYetImplemented,sNotYetImplemented+' BeginScope',[IntToStr(ord(ScopeType))],nil);
|
||||||
@ -21824,9 +21843,10 @@ begin
|
|||||||
stResourceString: FinishResourcestring(El as TPasResString);
|
stResourceString: FinishResourcestring(El as TPasResString);
|
||||||
stProcedure: FinishProcedure(El as TPasProcedure);
|
stProcedure: FinishProcedure(El as TPasProcedure);
|
||||||
stProcedureHeader: FinishProcedureType(El as TPasProcedureType);
|
stProcedureHeader: FinishProcedureType(El as TPasProcedureType);
|
||||||
|
stSpecializeType: FinishParserSpecializeType(El as TPasSpecializeType);
|
||||||
|
stWithExpr: FinishWithDo(El as TPasImplWithDo);
|
||||||
stExceptOnExpr: FinishExceptOnExpr;
|
stExceptOnExpr: FinishExceptOnExpr;
|
||||||
stExceptOnStatement: FinishExceptOnStatement;
|
stExceptOnStatement: FinishExceptOnStatement;
|
||||||
stWithExpr: FinishWithDo(El as TPasImplWithDo);
|
|
||||||
stForLoopHeader: FinishForLoopHeader(El as TPasImplForLoop);
|
stForLoopHeader: FinishForLoopHeader(El as TPasImplForLoop);
|
||||||
stDeclaration: FinishDeclaration(El);
|
stDeclaration: FinishDeclaration(El);
|
||||||
stAncestors: FinishAncestors(El as TPasClassType);
|
stAncestors: FinishAncestors(El as TPasClassType);
|
||||||
@ -22784,6 +22804,12 @@ begin
|
|||||||
Result:=PushHelperDotScope(HiType);
|
Result:=PushHelperDotScope(HiType);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TPasResolver.PushParserSpecializeType(SpecType: TPasSpecializeType
|
||||||
|
): TPasDotBaseScope;
|
||||||
|
begin
|
||||||
|
Result:=PushDotScope(SpecType.DestType);
|
||||||
|
end;
|
||||||
|
|
||||||
function TPasResolver.PushWithExprScope(Expr: TPasExpr): TPasWithExprScope;
|
function TPasResolver.PushWithExprScope(Expr: TPasExpr): TPasWithExprScope;
|
||||||
var
|
var
|
||||||
WithEl: TPasImplWithDo;
|
WithEl: TPasImplWithDo;
|
||||||
@ -27709,7 +27735,9 @@ procedure TPasResolver.ComputeElement(El: TPasElement; out
|
|||||||
var
|
var
|
||||||
TypeEl: TPasType;
|
TypeEl: TPasType;
|
||||||
begin
|
begin
|
||||||
if SpecType.CustomData is TPasSpecializeTypeData then
|
if SpecType.SubType<>nil then
|
||||||
|
ComputeElement(SpecType.SubType,ResolvedEl,Flags,StartEl)
|
||||||
|
else if SpecType.CustomData is TPasSpecializeTypeData then
|
||||||
begin
|
begin
|
||||||
TypeEl:=TPasSpecializeTypeData(SpecType.CustomData).SpecializedType;
|
TypeEl:=TPasSpecializeTypeData(SpecType.CustomData).SpecializedType;
|
||||||
if TypeEl=nil then
|
if TypeEl=nil then
|
||||||
@ -28393,6 +28421,7 @@ function TPasResolver.ResolveAliasType(aType: TPasType; SkipTypeAlias: boolean
|
|||||||
): TPasType;
|
): TPasType;
|
||||||
var
|
var
|
||||||
C: TClass;
|
C: TClass;
|
||||||
|
SpecType: TPasSpecializeType;
|
||||||
begin
|
begin
|
||||||
while aType<>nil do
|
while aType<>nil do
|
||||||
begin
|
begin
|
||||||
@ -28406,9 +28435,16 @@ begin
|
|||||||
aType:=NoNil(TResolvedReference(aType.CustomData).Declaration) as TPasType
|
aType:=NoNil(TResolvedReference(aType.CustomData).Declaration) as TPasType
|
||||||
else if C=TPasSpecializeType then
|
else if C=TPasSpecializeType then
|
||||||
begin
|
begin
|
||||||
if aType.CustomData is TPasSpecializeTypeData then
|
SpecType:=TPasSpecializeType(aType);
|
||||||
exit(TPasSpecializeTypeData(aType.CustomData).SpecializedType);
|
if SpecType.SubType<>nil then
|
||||||
aType:=TPasSpecializeType(aType).DestType;
|
// e.g. a<b>.c
|
||||||
|
aType:=SpecType.SubType
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if SpecType.CustomData is TPasSpecializeTypeData then
|
||||||
|
exit(TPasSpecializeTypeData(SpecType.CustomData).SpecializedType);
|
||||||
|
aType:=SpecType.DestType;
|
||||||
|
end;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
exit(aType);
|
exit(aType);
|
||||||
|
@ -2471,6 +2471,7 @@ begin
|
|||||||
if Param is TPasGenericTemplateType then continue;
|
if Param is TPasGenericTemplateType then continue;
|
||||||
UseElement(Param,rraRead,false);
|
UseElement(Param,rraRead,false);
|
||||||
end;
|
end;
|
||||||
|
UseElType(El,El.SubType,Mode);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPasAnalyzer.UseVariable(El: TPasVariable;
|
procedure TPasAnalyzer.UseVariable(El: TPasVariable;
|
||||||
|
@ -157,6 +157,7 @@ type
|
|||||||
stResourceString, // e.g. TPasResString
|
stResourceString, // e.g. TPasResString
|
||||||
stProcedure, // also method, procedure, constructor, destructor, ...
|
stProcedure, // also method, procedure, constructor, destructor, ...
|
||||||
stProcedureHeader,
|
stProcedureHeader,
|
||||||
|
stSpecializeType, // calls BeginScope to resolve c in a<b>.c
|
||||||
stWithExpr, // calls BeginScope after parsing every WITH-expression
|
stWithExpr, // calls BeginScope after parsing every WITH-expression
|
||||||
stExceptOnExpr,
|
stExceptOnExpr,
|
||||||
stExceptOnStatement,
|
stExceptOnStatement,
|
||||||
@ -1766,6 +1767,8 @@ begin
|
|||||||
ReadSpecializeArguments(ST,ST.Params);
|
ReadSpecializeArguments(ST,ST.Params);
|
||||||
if CurToken<>tkGreaterThan then
|
if CurToken<>tkGreaterThan then
|
||||||
ParseExcTokenError('[20190801113005]');
|
ParseExcTokenError('[20190801113005]');
|
||||||
|
// Important: resolve type reference AFTER args, because arg count is needed
|
||||||
|
ST.DestType:=ResolveTypeReference(GenName,ST,ST.Params.Count);
|
||||||
|
|
||||||
// Check for cascaded specialize A<B>.C or A<B>.C<D>
|
// Check for cascaded specialize A<B>.C or A<B>.C<D>
|
||||||
NextToken;
|
NextToken;
|
||||||
@ -1774,10 +1777,10 @@ begin
|
|||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
NextToken;
|
NextToken;
|
||||||
|
Engine.BeginScope(stSpecializeType,ST);
|
||||||
ST.SubType:=ParseSimpleType(ST,CurSourcePos,GenName,False);
|
ST.SubType:=ParseSimpleType(ST,CurSourcePos,GenName,False);
|
||||||
|
Engine.FinishScope(stSpecializeType,ST);
|
||||||
end;
|
end;
|
||||||
// Important: resolve type reference AFTER args, because arg count is needed
|
|
||||||
ST.DestType:=ResolveTypeReference(GenName,ST,ST.Params.Count);
|
|
||||||
|
|
||||||
Engine.FinishScope(stTypeDef,ST);
|
Engine.FinishScope(stTypeDef,ST);
|
||||||
Result:=ST;
|
Result:=ST;
|
||||||
|
@ -157,7 +157,7 @@ type
|
|||||||
procedure TestGenProc_TypeParamCntOverloadNoParams;
|
procedure TestGenProc_TypeParamCntOverloadNoParams;
|
||||||
procedure TestGenProc_TypeParamWithDefaultParamDelphiFail;
|
procedure TestGenProc_TypeParamWithDefaultParamDelphiFail;
|
||||||
procedure TestGenProc_ParamSpecWithT;
|
procedure TestGenProc_ParamSpecWithT;
|
||||||
procedure TestGenProc_ParamSpecWithTNestedType; // ToDo
|
procedure TestGenProc_ParamSpecWithTNestedType;
|
||||||
// ToDo: NestedResultAssign
|
// ToDo: NestedResultAssign
|
||||||
|
|
||||||
// generic function infer types
|
// generic function infer types
|
||||||
@ -2557,8 +2557,6 @@ end;
|
|||||||
|
|
||||||
procedure TTestResolveGenerics.TestGenProc_ParamSpecWithTNestedType;
|
procedure TTestResolveGenerics.TestGenProc_ParamSpecWithTNestedType;
|
||||||
begin
|
begin
|
||||||
exit;
|
|
||||||
|
|
||||||
StartProgram(false);
|
StartProgram(false);
|
||||||
Add([
|
Add([
|
||||||
'{$mode delphi}',
|
'{$mode delphi}',
|
||||||
@ -2578,7 +2576,7 @@ begin
|
|||||||
'var',
|
'var',
|
||||||
' Bird: TBird<TObject>;',
|
' Bird: TBird<TObject>;',
|
||||||
'begin',
|
'begin',
|
||||||
' Fly<TObject>(Run,Bird);',
|
' Fly<TObject>(@Run,Bird);',
|
||||||
'']);
|
'']);
|
||||||
ParseProgram;
|
ParseProgram;
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user