mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 09:46:12 +02:00
fcl-passrc: resolve specialized class
git-svn-id: trunk@42544 -
This commit is contained in:
parent
d77a8fb5f4
commit
583ec13074
@ -939,6 +939,13 @@ type
|
|||||||
TPasRecordScope = Class(TPasClassOrRecordScope)
|
TPasRecordScope = Class(TPasClassOrRecordScope)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TPasClassHeaderScope - scope for resolving templates during parsing ancestor+interfaces }
|
||||||
|
|
||||||
|
TPasClassHeaderScope = class(TPasIdentifierScope)
|
||||||
|
public
|
||||||
|
GenericType: TPasGenericType;
|
||||||
|
end;
|
||||||
|
|
||||||
TPasClassScopeFlag = (
|
TPasClassScopeFlag = (
|
||||||
pcsfAncestorResolved,
|
pcsfAncestorResolved,
|
||||||
pcsfSealed,
|
pcsfSealed,
|
||||||
@ -1669,6 +1676,10 @@ type
|
|||||||
function EvalBaseTypeCast(Params: TParamsExpr; bt: TResolverBaseType): TResEvalvalue;
|
function EvalBaseTypeCast(Params: TParamsExpr; bt: TResolverBaseType): TResEvalvalue;
|
||||||
protected
|
protected
|
||||||
// generic/specialize
|
// generic/specialize
|
||||||
|
procedure AddGenericTemplateIdentifiers(GenericTemplateTypes: TFPList;
|
||||||
|
Scope: TPasIdentifierScope);
|
||||||
|
procedure AddSpecializedTemplateIdentifiers(GenericTemplateTypes: TFPList;
|
||||||
|
SpecializedTypes: TPasTypeArray; Scope: TPasIdentifierScope);
|
||||||
function GetSpecializedType(El: TPasSpecializeType): TPasGenericType;
|
function GetSpecializedType(El: TPasSpecializeType): TPasGenericType;
|
||||||
function CheckSpecializeConstraints(El : TPasSpecializeType): boolean; virtual; // false = not fully specialized
|
function CheckSpecializeConstraints(El : TPasSpecializeType): boolean; virtual; // false = not fully specialized
|
||||||
function CreateSpecializedType(El: TPasSpecializeType;
|
function CreateSpecializedType(El: TPasSpecializeType;
|
||||||
@ -5805,6 +5816,11 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
if TopScope.Element=El then
|
if TopScope.Element=El then
|
||||||
|
PopScope // pop TPasClassScope
|
||||||
|
else
|
||||||
|
; // e.g. class forward
|
||||||
|
|
||||||
|
if TopScope is TPasClassHeaderScope then
|
||||||
PopScope;
|
PopScope;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -5901,25 +5917,29 @@ var
|
|||||||
C: TClass;
|
C: TClass;
|
||||||
Scope: TPasIdentifierScope;
|
Scope: TPasIdentifierScope;
|
||||||
GenTemplates: TFPList;
|
GenTemplates: TFPList;
|
||||||
i: Integer;
|
|
||||||
TemplType: TPasGenericTemplateType;
|
TemplType: TPasGenericTemplateType;
|
||||||
begin
|
begin
|
||||||
|
GenTemplates:=aType.GenericTemplateTypes;
|
||||||
|
if (GenTemplates=nil) or (GenTemplates.Count=0) then
|
||||||
|
RaiseNotYetImplemented(20190726184902,aType,'emty generic template list');
|
||||||
|
|
||||||
// add template names to scope
|
// add template names to scope
|
||||||
C:=aType.ClassType;
|
C:=aType.ClassType;
|
||||||
if C.InheritsFrom(TPasMembersType) then
|
if C=TPasRecordType then
|
||||||
Scope:=aType.CustomData as TPasClassOrRecordScope
|
Scope:=NoNil(aType.CustomData) as TPasRecordScope
|
||||||
|
else if C=TPasClassType then
|
||||||
|
begin
|
||||||
|
// create class header scope
|
||||||
|
TemplType:=TPasGenericTemplateType(GenTemplates[0]);
|
||||||
|
Scope:=TPasClassHeaderScope(PushScope(TemplType,TPasClassHeaderScope));
|
||||||
|
TPasClassHeaderScope(Scope).GenericType:=aType;
|
||||||
|
end
|
||||||
// ToDo: TPasArrayType
|
// ToDo: TPasArrayType
|
||||||
// ToDo: TPasProcedureType
|
// ToDo: TPasProcedureType
|
||||||
else
|
else
|
||||||
RaiseNotYetImplemented(20190726150359,aType,GetObjName(aType));
|
RaiseNotYetImplemented(20190726150359,aType,GetObjName(aType));
|
||||||
GenTemplates:=aType.GenericTemplateTypes;
|
|
||||||
if (GenTemplates=nil) or (GenTemplates.Count=0) then
|
AddGenericTemplateIdentifiers(GenTemplates,Scope);
|
||||||
RaiseNotYetImplemented(20190726184902,aType,'emty generic template list');
|
|
||||||
for i:=0 to GenTemplates.Count-1 do
|
|
||||||
begin
|
|
||||||
TemplType:=TPasGenericTemplateType(GenTemplates[i]);
|
|
||||||
AddIdentifier(Scope,TemplType.Name,TemplType,pikSimple);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPasResolver.FinishGenericTemplateType(El: TPasGenericTemplateType);
|
procedure TPasResolver.FinishGenericTemplateType(El: TPasGenericTemplateType);
|
||||||
@ -7708,7 +7728,7 @@ var
|
|||||||
AncestorType, El: TPasType;
|
AncestorType, El: TPasType;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
aModifier, DefAncestorName: String;
|
aModifier, DefAncestorName: String;
|
||||||
IsSealed: Boolean;
|
IsSealed, IsDelphi: Boolean;
|
||||||
CanonicalSelf: TPasClassOfType;
|
CanonicalSelf: TPasClassOfType;
|
||||||
Decl: TPasElement;
|
Decl: TPasElement;
|
||||||
j: integer;
|
j: integer;
|
||||||
@ -7717,8 +7737,13 @@ var
|
|||||||
GroupScope: TPasGroupScope;
|
GroupScope: TPasGroupScope;
|
||||||
C: TClass;
|
C: TClass;
|
||||||
begin
|
begin
|
||||||
|
IsDelphi:=msDelphi in CurrentParser.CurrentModeswitches;
|
||||||
|
|
||||||
if aClass.IsForward then
|
if aClass.IsForward then
|
||||||
begin
|
begin
|
||||||
|
if TopScope is TPasClassHeaderScope then
|
||||||
|
PopScope;
|
||||||
|
|
||||||
// check for duplicate forwards
|
// check for duplicate forwards
|
||||||
C:=aClass.Parent.ClassType;
|
C:=aClass.Parent.ClassType;
|
||||||
if C.InheritsFrom(TPasDeclarations) then
|
if C.InheritsFrom(TPasDeclarations) then
|
||||||
@ -7747,9 +7772,10 @@ begin
|
|||||||
AncestorType:=ResolveAliasType(aClass.AncestorType);
|
AncestorType:=ResolveAliasType(aClass.AncestorType);
|
||||||
if (AncestorType is TPasClassType)
|
if (AncestorType is TPasClassType)
|
||||||
and (TPasClassType(AncestorType).ObjKind=okInterface)
|
and (TPasClassType(AncestorType).ObjKind=okInterface)
|
||||||
and not (msDelphi in CurrentParser.CurrentModeswitches) then
|
and not isDelphi then
|
||||||
begin
|
begin
|
||||||
// e.g. type c = class(intf)
|
// e.g. type c = class(intf)
|
||||||
|
// ObjFPC allows to omit TObject as default ancestor, Delphi does not
|
||||||
aClass.Interfaces.Insert(0,aClass.AncestorType);
|
aClass.Interfaces.Insert(0,aClass.AncestorType);
|
||||||
aClass.AncestorType:=nil;
|
aClass.AncestorType:=nil;
|
||||||
end;
|
end;
|
||||||
@ -7782,7 +7808,7 @@ begin
|
|||||||
sTypeXIsNotYetCompletelyDefined,[HelperForType.Name],aClass);
|
sTypeXIsNotYetCompletelyDefined,[HelperForType.Name],aClass);
|
||||||
end;
|
end;
|
||||||
okRecordHelper:
|
okRecordHelper:
|
||||||
if msDelphi in CurrentParser.CurrentModeswitches then
|
if isDelphi then
|
||||||
begin
|
begin
|
||||||
if (HelperForType.ClassType=TPasRecordType)
|
if (HelperForType.ClassType=TPasRecordType)
|
||||||
or (HelperForType.ClassType=TPasArrayType)
|
or (HelperForType.ClassType=TPasArrayType)
|
||||||
@ -7876,7 +7902,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
if aClass.InterfaceType=citCom then
|
if aClass.InterfaceType=citCom then
|
||||||
begin
|
begin
|
||||||
if msDelphi in CurrentParser.CurrentModeswitches then
|
if isDelphi then
|
||||||
DefAncestorName:='IInterface'
|
DefAncestorName:='IInterface'
|
||||||
else
|
else
|
||||||
DefAncestorName:='IUnknown';
|
DefAncestorName:='IUnknown';
|
||||||
@ -7956,7 +7982,10 @@ begin
|
|||||||
until El=nil;
|
until El=nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// start scope for elements
|
if TopScope is TPasClassHeaderScope then
|
||||||
|
PopScope;
|
||||||
|
|
||||||
|
// start scope for members
|
||||||
{$IFDEF VerbosePasResolver}
|
{$IFDEF VerbosePasResolver}
|
||||||
//writeln('TPasResolver.FinishAncestors ',GetObjName(aClass.CustomData));
|
//writeln('TPasResolver.FinishAncestors ',GetObjName(aClass.CustomData));
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
@ -7964,6 +7993,7 @@ begin
|
|||||||
Include(ClassScope.Flags,pcsfAncestorResolved);
|
Include(ClassScope.Flags,pcsfAncestorResolved);
|
||||||
if IsSealed then
|
if IsSealed then
|
||||||
Include(ClassScope.Flags,pcsfSealed);
|
Include(ClassScope.Flags,pcsfSealed);
|
||||||
|
AddGenericTemplateIdentifiers(aClass.GenericTemplateTypes,ClassScope);
|
||||||
ClassScope.DirectAncestor:=DirectAncestor;
|
ClassScope.DirectAncestor:=DirectAncestor;
|
||||||
if AncestorClassEl<>nil then
|
if AncestorClassEl<>nil then
|
||||||
begin
|
begin
|
||||||
@ -10732,6 +10762,7 @@ var
|
|||||||
ForwardDecl: TPasClassType;
|
ForwardDecl: TPasClassType;
|
||||||
CurScope, LocalScope: TPasIdentifierScope;
|
CurScope, LocalScope: TPasIdentifierScope;
|
||||||
begin
|
begin
|
||||||
|
// Beware: El.ObjKind is not yet set!
|
||||||
{$IFDEF VerbosePasResolver}
|
{$IFDEF VerbosePasResolver}
|
||||||
//writeln('TPasResolver.AddClassType ',GetObjName(El),' Parent=',GetObjName(El.Parent),' ',GetElementSourcePosStr(El));
|
//writeln('TPasResolver.AddClassType ',GetObjName(El),' Parent=',GetObjName(El.Parent),' ',GetElementSourcePosStr(El));
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
@ -13925,6 +13956,34 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPasResolver.AddGenericTemplateIdentifiers(
|
||||||
|
GenericTemplateTypes: TFPList; Scope: TPasIdentifierScope);
|
||||||
|
var
|
||||||
|
TemplType: TPasGenericTemplateType;
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
if GenericTemplateTypes=nil then exit;
|
||||||
|
for i:=0 to GenericTemplateTypes.Count-1 do
|
||||||
|
begin
|
||||||
|
TemplType:=TPasGenericTemplateType(GenericTemplateTypes[i]);
|
||||||
|
Scope.AddIdentifier(TemplType.Name,TemplType,pikSimple);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TPasResolver.AddSpecializedTemplateIdentifiers(
|
||||||
|
GenericTemplateTypes: TFPList; SpecializedTypes: TPasTypeArray;
|
||||||
|
Scope: TPasIdentifierScope);
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
TemplType: TPasGenericTemplateType;
|
||||||
|
begin
|
||||||
|
for i:=0 to length(SpecializedTypes)-1 do
|
||||||
|
begin
|
||||||
|
TemplType:=TPasGenericTemplateType(GenericTemplateTypes[i]);
|
||||||
|
AddIdentifier(Scope,TemplType.Name,SpecializedTypes[i],pikSimple);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TPasResolver.GetSpecializedType(El: TPasSpecializeType
|
function TPasResolver.GetSpecializedType(El: TPasSpecializeType
|
||||||
): TPasGenericType;
|
): TPasGenericType;
|
||||||
var
|
var
|
||||||
@ -14112,10 +14171,15 @@ var
|
|||||||
SrcModule: TPasModule;
|
SrcModule: TPasModule;
|
||||||
SrcModuleScope: TPasModuleScope;
|
SrcModuleScope: TPasModuleScope;
|
||||||
SrcResolver: TPasResolver;
|
SrcResolver: TPasResolver;
|
||||||
OldStashCount, i: Integer;
|
OldStashCount: Integer;
|
||||||
Scope: TPasGenericScope;
|
|
||||||
TemplType: TPasGenericTemplateType;
|
TemplType: TPasGenericTemplateType;
|
||||||
NewParent: TPasElement;
|
NewParent: TPasElement;
|
||||||
|
NewClassType, GenClassType: TPasClassType;
|
||||||
|
GenericTemplateTypes: TFPList;
|
||||||
|
HeaderScope: TPasClassHeaderScope;
|
||||||
|
{$IFDEF VerbosePasResolver}
|
||||||
|
i: integer;
|
||||||
|
{$ENDIF}
|
||||||
begin
|
begin
|
||||||
Result:=nil;
|
Result:=nil;
|
||||||
GenericType:=El.DestType as TPasGenericType;
|
GenericType:=El.DestType as TPasGenericType;
|
||||||
@ -14126,83 +14190,103 @@ begin
|
|||||||
RaiseInternalError(20190728121705);
|
RaiseInternalError(20190728121705);
|
||||||
|
|
||||||
GenScope:=TPasGenericScope(GenericType.CustomData);
|
GenScope:=TPasGenericScope(GenericType.CustomData);
|
||||||
|
GenericTemplateTypes:=GenericType.GenericTemplateTypes;
|
||||||
SpecializedTypes:=GenScope.SpecializedTypes;
|
SpecializedTypes:=GenScope.SpecializedTypes;
|
||||||
|
|
||||||
// change scope
|
// change scope
|
||||||
//writeln('TPasResolver.CreateSpecializedType ',ScopeCount,' FStashScopeCount=',FStashScopeCount);
|
//writeln('TPasResolver.CreateSpecializedType ',ScopeCount,' FStashScopeCount=',FStashScopeCount);
|
||||||
OldStashCount:=InitSpecializeScopes(GenericType);
|
OldStashCount:=InitSpecializeScopes(GenericType);
|
||||||
//writeln('TPasResolver.CreateSpecializedType ',ScopeCount,' FStashScopeCount=',FStashScopeCount);
|
{$IFDEF VerbosePasResolver}
|
||||||
|
writeln('TPasResolver.CreateSpecializedType InitSpecializeScopes: ',ScopeCount,' FStashScopeCount=',FStashScopeCount);
|
||||||
for i:=0 to FScopeCount-1 do
|
for i:=0 to FScopeCount-1 do
|
||||||
writeln(' ',i,'/',FScopeCount,' ',GetObjName(FScopes[i]));
|
writeln(' ',i,'/',FScopeCount,' ',GetObjName(FScopes[i]));
|
||||||
try
|
{$ENDIF}
|
||||||
Result:=TPSSpecializedItem.Create;
|
|
||||||
Result.Params:=ParamsResolved;
|
|
||||||
SpecializedTypes.Add(Result);
|
|
||||||
NewName:=GenericType.Name+'$G'+IntToStr(SpecializedTypes.Count);
|
|
||||||
NewClass:=TPTreeElement(GenericType.ClassType);
|
|
||||||
NewParent:=GenericType.Parent;
|
|
||||||
NewEl:=TPasGenericType(NewClass.Create(NewName,NewParent));
|
|
||||||
Result.SpecializedType:=NewEl; // this calls AddRef
|
|
||||||
|
|
||||||
if NewParent is TPasDeclarations then
|
Result:=TPSSpecializedItem.Create;
|
||||||
begin
|
Result.Params:=ParamsResolved;
|
||||||
TPasDeclarations(NewParent).Declarations.Add(NewEl);
|
SpecializedTypes.Add(Result);
|
||||||
{$IFDEF CheckPasTreeRefCount}NewEl.RefIds.Add('TPasDeclarations.Children');{$ENDIF}
|
NewName:=GenericType.Name+'$G'+IntToStr(SpecializedTypes.Count);
|
||||||
end
|
NewClass:=TPTreeElement(GenericType.ClassType);
|
||||||
else if NewParent is TPasMembersType then
|
NewParent:=GenericType.Parent;
|
||||||
begin
|
NewEl:=TPasGenericType(NewClass.Create(NewName,NewParent));
|
||||||
TPasMembersType(NewParent).Members.Add(NewEl);
|
Result.SpecializedType:=NewEl; // this calls AddRef
|
||||||
{$IFDEF CheckPasTreeRefCount}NewEl.RefIds.Add('TPasMembersType.Members');{$ENDIF}
|
|
||||||
end
|
|
||||||
else
|
|
||||||
NewEl.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF}; // fix refcount
|
|
||||||
|
|
||||||
SpecializePasElementProperties(GenericType,NewEl);
|
if NewParent is TPasDeclarations then
|
||||||
|
begin
|
||||||
|
TPasDeclarations(NewParent).Declarations.Add(NewEl);
|
||||||
|
{$IFDEF CheckPasTreeRefCount}NewEl.RefIds.Add('TPasDeclarations.Children');{$ENDIF}
|
||||||
|
end
|
||||||
|
else if NewParent is TPasMembersType then
|
||||||
|
begin
|
||||||
|
TPasMembersType(NewParent).Members.Add(NewEl);
|
||||||
|
{$IFDEF CheckPasTreeRefCount}NewEl.RefIds.Add('TPasMembersType.Members');{$ENDIF}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
NewEl.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF}; // fix refcount
|
||||||
|
|
||||||
// create scope of specialized type
|
SpecializePasElementProperties(GenericType,NewEl);
|
||||||
Scope:=nil;
|
|
||||||
if NewEl is TPasRecordType then
|
|
||||||
begin
|
|
||||||
TPasRecordType(NewEl).PackMode:=TPasRecordType(GenericType).PackMode;
|
|
||||||
Scope:=TPasGenericScope(PushScope(NewEl,TPasRecordScope));
|
|
||||||
Scope.VisibilityContext:=NewEl;
|
|
||||||
end
|
|
||||||
else if NewEl is TPasClassType then
|
|
||||||
begin
|
|
||||||
//AddClassType();
|
|
||||||
//FinishAncestors();
|
|
||||||
RaiseNotYetImplemented(20190728134934,El);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
RaiseNotYetImplemented(20190728134933,El);
|
|
||||||
Scope.SpecializedFrom:=GenericType;
|
|
||||||
|
|
||||||
// add template identifiers
|
// create GenScope of specialized type
|
||||||
for i:=0 to length(ParamsResolved)-1 do
|
GenScope:=nil;
|
||||||
begin
|
if NewEl is TPasRecordType then
|
||||||
TemplType:=TPasGenericTemplateType(GenericType.GenericTemplateTypes[i]);
|
begin
|
||||||
AddIdentifier(Scope,TemplType.Name,ParamsResolved[i],pikSimple);
|
TPasRecordType(NewEl).PackMode:=TPasRecordType(GenericType).PackMode;
|
||||||
end;
|
GenScope:=TPasGenericScope(PushScope(NewEl,TPasRecordScope));
|
||||||
|
GenScope.VisibilityContext:=NewEl;
|
||||||
|
end
|
||||||
|
else if NewEl is TPasClassType then
|
||||||
|
begin
|
||||||
|
NewClassType:=TPasClassType(NewEl);
|
||||||
|
GenClassType:=TPasClassType(GenericType);
|
||||||
|
NewClassType.ObjKind:=GenClassType.ObjKind;
|
||||||
|
NewClassType.PackMode:=GenClassType.PackMode;
|
||||||
|
// todo AncestorType
|
||||||
|
if GenClassType.HelperForType<>nil then
|
||||||
|
RaiseNotYetImplemented(20190730182758,GenClassType,'');
|
||||||
|
// ToDo: IsForward
|
||||||
|
if GenClassType.IsForward then
|
||||||
|
RaiseNotYetImplemented(20190730182858,GenClassType);
|
||||||
|
NewClassType.IsExternal:=GenClassType.IsExternal;
|
||||||
|
NewClassType.IsShortDefinition:=GenClassType.IsShortDefinition;
|
||||||
|
// ToDo GUIDExpr
|
||||||
|
NewClassType.Modifiers.Assign(GenClassType.Modifiers);
|
||||||
|
// ToDo NewClassType.Interfaces
|
||||||
|
NewClassType.ExternalNameSpace:=GenClassType.ExternalNameSpace;
|
||||||
|
NewClassType.ExternalName:=GenClassType.ExternalName;
|
||||||
|
NewClassType.InterfaceType:=GenClassType.InterfaceType;
|
||||||
|
|
||||||
// specialize recursively
|
// ancestor+interfaces
|
||||||
if NewEl is TPasMembersType then
|
TemplType:=TPasGenericTemplateType(GenericTemplateTypes[0]);
|
||||||
SpecializeMembers(TPasMembersType(GenericType),TPasMembersType(NewEl));
|
HeaderScope:=NoNil(TemplType.CustomData) as TPasClassHeaderScope;
|
||||||
|
PushScope(HeaderScope);
|
||||||
|
FinishAncestors(NewClassType);
|
||||||
|
|
||||||
FinishTypeDef(NewEl);
|
// Note: class scope is created by FinishAncestors
|
||||||
Scope:=nil;
|
GenScope:=NoNil(NewClassType.CustomData) as TPasClassScope;
|
||||||
finally
|
end
|
||||||
// restore scope
|
else
|
||||||
if Scope<>nil then
|
RaiseNotYetImplemented(20190728134933,El);
|
||||||
begin
|
GenScope.SpecializedFrom:=GenericType;
|
||||||
if TopScope<>Scope then
|
|
||||||
RaiseInternalError(20190728144827,GetObjName(TopScope));
|
AddSpecializedTemplateIdentifiers(GenericTemplateTypes,ParamsResolved,GenScope);
|
||||||
PopScope;
|
|
||||||
end;
|
// specialize recursively
|
||||||
RestoreStashedScopes(OldStashCount);
|
if NewEl is TPasMembersType then
|
||||||
//writeln('TPasResolver.CreateSpecializedType ',ScopeCount,' FStashScopeCount=',FStashScopeCount);
|
SpecializeMembers(TPasMembersType(GenericType),TPasMembersType(NewEl));
|
||||||
for i:=0 to FScopeCount-1 do
|
|
||||||
writeln(' ',i,'/',FScopeCount,' ',GetObjName(FScopes[i]));
|
FinishTypeDef(NewEl);
|
||||||
end;
|
{$IFDEF VerbosePasResolver}
|
||||||
|
writeln('TPasResolver.CreateSpecializedType FinishTypeDef:');
|
||||||
|
for i:=0 to FScopeCount-1 do
|
||||||
|
writeln(' ',i,'/',FScopeCount,' ',GetObjName(FScopes[i]));
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
RestoreStashedScopes(OldStashCount);
|
||||||
|
{$IFDEF VerbosePasResolver}
|
||||||
|
writeln('TPasResolver.CreateSpecializedType RestoreStashedScopes:');
|
||||||
|
for i:=0 to FScopeCount-1 do
|
||||||
|
writeln(' ',i,'/',FScopeCount,' ',GetObjName(FScopes[i]));
|
||||||
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TPasResolver.InitSpecializeScopes(El: TPasElement): integer;
|
function TPasResolver.InitSpecializeScopes(El: TPasElement): integer;
|
||||||
|
@ -4333,6 +4333,10 @@ begin
|
|||||||
begin
|
begin
|
||||||
ClassEl := TPasClassType(CreateElement(TPasClassType,
|
ClassEl := TPasClassType(CreateElement(TPasClassType,
|
||||||
TypeName, Parent, NamePos));
|
TypeName, Parent, NamePos));
|
||||||
|
if CurToken=tkobject then
|
||||||
|
ClassEl.ObjKind:=okObject
|
||||||
|
else
|
||||||
|
ClassEl.ObjKind:=okClass;
|
||||||
if AddToParent and (Parent is TPasDeclarations) then
|
if AddToParent and (Parent is TPasDeclarations) then
|
||||||
TPasDeclarations(Parent).Classes.Add(ClassEl);
|
TPasDeclarations(Parent).Classes.Add(ClassEl);
|
||||||
InitGenericType(ClassEl,List);
|
InitGenericType(ClassEl,List);
|
||||||
@ -7106,11 +7110,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPasParser.DoParseClassType(AType: TPasClassType);
|
procedure TPasParser.DoParseClassType(AType: TPasClassType);
|
||||||
|
|
||||||
var
|
var
|
||||||
s: String;
|
s: String;
|
||||||
Expr: TPasExpr;
|
Expr: TPasExpr;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if (CurToken=tkIdentifier) and (AType.ObjKind=okClass) then
|
if (CurToken=tkIdentifier) and (AType.ObjKind=okClass) then
|
||||||
begin
|
begin
|
||||||
|
@ -206,11 +206,11 @@ end;
|
|||||||
|
|
||||||
procedure TTestResolveGenerics.TestGen_Class;
|
procedure TTestResolveGenerics.TestGen_Class;
|
||||||
begin
|
begin
|
||||||
exit;
|
|
||||||
StartProgram(false);
|
StartProgram(false);
|
||||||
Add([
|
Add([
|
||||||
'{$mode objfpc}',
|
'{$mode objfpc}',
|
||||||
'type',
|
'type',
|
||||||
|
' TObject = class end;',
|
||||||
' {#Typ}T = word;',
|
' {#Typ}T = word;',
|
||||||
' generic TBird<{#Templ}T> = class',
|
' generic TBird<{#Templ}T> = class',
|
||||||
' {=Templ}v: T;',
|
' {=Templ}v: T;',
|
||||||
|
Loading…
Reference in New Issue
Block a user