mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 14:49:28 +02:00
Preparations for upcoming work on generics:
+ symconst.pas: add a new flag to symtables to mark them as containing at least one generic (will be used to decide whether an expression like "Foo<Bar" should even remotely be considered a specialization) * utils/ppudump.pp: respect the new flag * pdecl.pas, types_dec: add the flag for every generic we have parsed * pgenutil.pas, generate_specialization: add the flag to the specialize symtable if a nested generic set it for the temporary symtable (does not happen currently, but will in the future when nested generics are supported) + keep references to all generic para symbols in the def; this way the symtable containing the type parameters does not need to be walked every time we need to do something with the parameters git-svn-id: trunk@22379 -
This commit is contained in:
parent
2d0f01e0dd
commit
29c71d39ac
@ -619,6 +619,9 @@ implementation
|
|||||||
{ update the definition of the type }
|
{ update the definition of the type }
|
||||||
if assigned(hdef) then
|
if assigned(hdef) then
|
||||||
begin
|
begin
|
||||||
|
if df_generic in hdef.defoptions then
|
||||||
|
{ flag parent symtables that they now contain a generic }
|
||||||
|
hdef.owner.includeoption(sto_has_generic);
|
||||||
if assigned(hdef.typesym) then
|
if assigned(hdef.typesym) then
|
||||||
begin
|
begin
|
||||||
istyperenaming:=true;
|
istyperenaming:=true;
|
||||||
|
@ -478,6 +478,11 @@ uses
|
|||||||
tdef(item).ChangeOwner(specializest);
|
tdef(item).ChangeOwner(specializest);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ if a generic was declared during the specialization we need to
|
||||||
|
flag the specialize symtable accordingly }
|
||||||
|
if sto_has_generic in tempst.tableoptions then
|
||||||
|
specializest.includeoption(sto_has_generic);
|
||||||
|
|
||||||
tempst.free;
|
tempst.free;
|
||||||
|
|
||||||
specialization_done(state);
|
specialization_done(state);
|
||||||
|
@ -497,7 +497,8 @@ type
|
|||||||
|
|
||||||
{ options for symtables }
|
{ options for symtables }
|
||||||
tsymtableoption = (
|
tsymtableoption = (
|
||||||
sto_has_helper { contains at least one helper symbol }
|
sto_has_helper, { contains at least one helper symbol }
|
||||||
|
sto_has_generic { contains at least one generic symbol }
|
||||||
);
|
);
|
||||||
tsymtableoptions = set of tsymtableoption;
|
tsymtableoptions = set of tsymtableoption;
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ interface
|
|||||||
tstoreddef = class(tdef)
|
tstoreddef = class(tdef)
|
||||||
protected
|
protected
|
||||||
typesymderef : tderef;
|
typesymderef : tderef;
|
||||||
|
procedure fillgenericparas(symtable:tsymtable);
|
||||||
public
|
public
|
||||||
{$ifdef EXTDEBUG}
|
{$ifdef EXTDEBUG}
|
||||||
fileinfo : tfileposinfo;
|
fileinfo : tfileposinfo;
|
||||||
@ -61,6 +62,9 @@ interface
|
|||||||
genericdef : tstoreddef;
|
genericdef : tstoreddef;
|
||||||
genericdefderef : tderef;
|
genericdefderef : tderef;
|
||||||
generictokenbuf : tdynamicarray;
|
generictokenbuf : tdynamicarray;
|
||||||
|
{ this list contains references to the symbols that make up the
|
||||||
|
generic parameters; the symbols are not owned by this list }
|
||||||
|
genericparas : tfphashobjectlist;
|
||||||
constructor create(dt:tdeftyp);
|
constructor create(dt:tdeftyp);
|
||||||
constructor ppuload(dt:tdeftyp;ppufile:tcompilerppufile);
|
constructor ppuload(dt:tdeftyp;ppufile:tcompilerppufile);
|
||||||
destructor destroy;override;
|
destructor destroy;override;
|
||||||
@ -84,6 +88,10 @@ interface
|
|||||||
function is_fpuregable : boolean;
|
function is_fpuregable : boolean;
|
||||||
{ generics }
|
{ generics }
|
||||||
procedure initgeneric;
|
procedure initgeneric;
|
||||||
|
{ this function can be used to determine whether a def is really a
|
||||||
|
generic declaration or just a normal type declared inside another
|
||||||
|
generic }
|
||||||
|
function is_generic:boolean;inline;
|
||||||
private
|
private
|
||||||
savesize : asizeuint;
|
savesize : asizeuint;
|
||||||
end;
|
end;
|
||||||
@ -1330,6 +1338,23 @@ implementation
|
|||||||
TDEF (base class for definitions)
|
TDEF (base class for definitions)
|
||||||
****************************************************************************}
|
****************************************************************************}
|
||||||
|
|
||||||
|
procedure tstoreddef.fillgenericparas(symtable: tsymtable);
|
||||||
|
var
|
||||||
|
sym : tsym;
|
||||||
|
i : longint;
|
||||||
|
begin
|
||||||
|
if not assigned(symtable) then
|
||||||
|
internalerror(2012091201);
|
||||||
|
if [df_generic,df_specialization]*defoptions=[] then
|
||||||
|
exit;
|
||||||
|
for i:=0 to symtable.symlist.count-1 do
|
||||||
|
begin
|
||||||
|
sym:=tsym(symtable.symlist[i]);
|
||||||
|
if sp_generic_para in sym.symoptions then
|
||||||
|
genericparas.Add(sym.name,sym);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
constructor tstoreddef.create(dt:tdeftyp);
|
constructor tstoreddef.create(dt:tdeftyp);
|
||||||
var
|
var
|
||||||
insertstack : psymtablestackitem;
|
insertstack : psymtablestackitem;
|
||||||
@ -1341,6 +1366,7 @@ implementation
|
|||||||
{$endif}
|
{$endif}
|
||||||
generictokenbuf:=nil;
|
generictokenbuf:=nil;
|
||||||
genericdef:=nil;
|
genericdef:=nil;
|
||||||
|
genericparas:=tfphashobjectlist.create(false);
|
||||||
|
|
||||||
{ Don't register forwarddefs, they are disposed at the
|
{ Don't register forwarddefs, they are disposed at the
|
||||||
end of an type block }
|
end of an type block }
|
||||||
@ -1376,6 +1402,7 @@ implementation
|
|||||||
generictokenbuf.free;
|
generictokenbuf.free;
|
||||||
generictokenbuf:=nil;
|
generictokenbuf:=nil;
|
||||||
end;
|
end;
|
||||||
|
genericparas.free;
|
||||||
inherited destroy;
|
inherited destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1386,6 +1413,7 @@ implementation
|
|||||||
buf : array[0..255] of byte;
|
buf : array[0..255] of byte;
|
||||||
begin
|
begin
|
||||||
inherited create(dt);
|
inherited create(dt);
|
||||||
|
genericparas:=tfphashobjectlist.create(false);
|
||||||
DefId:=ppufile.getlongint;
|
DefId:=ppufile.getlongint;
|
||||||
current_module.deflist[DefId]:=self;
|
current_module.deflist[DefId]:=self;
|
||||||
{$ifdef EXTDEBUG}
|
{$ifdef EXTDEBUG}
|
||||||
@ -1626,6 +1654,11 @@ implementation
|
|||||||
generictokenbuf:=tdynamicarray.create(256);
|
generictokenbuf:=tdynamicarray.create(256);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function tstoreddef.is_generic: boolean;
|
||||||
|
begin
|
||||||
|
result:=genericparas.count>0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{****************************************************************************
|
{****************************************************************************
|
||||||
Tstringdef
|
Tstringdef
|
||||||
@ -2946,6 +2979,7 @@ implementation
|
|||||||
tarraysymtable(symtable).deref;
|
tarraysymtable(symtable).deref;
|
||||||
_elementdef:=tdef(_elementdefderef.resolve);
|
_elementdef:=tdef(_elementdefderef.resolve);
|
||||||
rangedef:=tdef(rangedefderef.resolve);
|
rangedef:=tdef(rangedefderef.resolve);
|
||||||
|
fillgenericparas(symtable);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -3489,6 +3523,8 @@ implementation
|
|||||||
else
|
else
|
||||||
tstoredsymtable(symtable).deref;
|
tstoredsymtable(symtable).deref;
|
||||||
|
|
||||||
|
fillgenericparas(symtable);
|
||||||
|
|
||||||
{ assign TGUID? load only from system unit }
|
{ assign TGUID? load only from system unit }
|
||||||
if not(assigned(rec_tguid)) and
|
if not(assigned(rec_tguid)) and
|
||||||
(upper(typename)='TGUID') and
|
(upper(typename)='TGUID') and
|
||||||
@ -3687,6 +3723,7 @@ implementation
|
|||||||
tparasymtable(parast).deref;
|
tparasymtable(parast).deref;
|
||||||
{ recalculated parameters }
|
{ recalculated parameters }
|
||||||
calcparas;
|
calcparas;
|
||||||
|
fillgenericparas(parast);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -5502,6 +5539,7 @@ implementation
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
tstoredsymtable(symtable).deref;
|
tstoredsymtable(symtable).deref;
|
||||||
|
fillgenericparas(symtable);
|
||||||
if objecttype=odt_helper then
|
if objecttype=odt_helper then
|
||||||
extendeddef:=tdef(extendeddefderef.resolve);
|
extendeddef:=tdef(extendeddefderef.resolve);
|
||||||
for i:=0 to vmtentries.count-1 do
|
for i:=0 to vmtentries.count-1 do
|
||||||
|
@ -492,7 +492,8 @@ type
|
|||||||
const
|
const
|
||||||
symtblopts=ord(high(tsymtableoption)) + 1;
|
symtblopts=ord(high(tsymtableoption)) + 1;
|
||||||
symtblopt : array[1..symtblopts] of tsymtblopt=(
|
symtblopt : array[1..symtblopts] of tsymtblopt=(
|
||||||
(mask:sto_has_helper; str:'Has helper')
|
(mask:sto_has_helper; str:'Has helper'),
|
||||||
|
(mask:sto_has_generic; str:'Has generic')
|
||||||
);
|
);
|
||||||
var
|
var
|
||||||
options : tsymtableoptions;
|
options : tsymtableoptions;
|
||||||
|
Loading…
Reference in New Issue
Block a user