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:
svenbarth 2012-09-13 11:35:35 +00:00
parent 2d0f01e0dd
commit 29c71d39ac
5 changed files with 50 additions and 2 deletions

View File

@ -619,6 +619,9 @@ implementation
{ update the definition of the type }
if assigned(hdef) then
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
begin
istyperenaming:=true;

View File

@ -478,6 +478,11 @@ uses
tdef(item).ChangeOwner(specializest);
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;
specialization_done(state);

View File

@ -497,7 +497,8 @@ type
{ options for symtables }
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;

View File

@ -53,6 +53,7 @@ interface
tstoreddef = class(tdef)
protected
typesymderef : tderef;
procedure fillgenericparas(symtable:tsymtable);
public
{$ifdef EXTDEBUG}
fileinfo : tfileposinfo;
@ -61,6 +62,9 @@ interface
genericdef : tstoreddef;
genericdefderef : tderef;
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 ppuload(dt:tdeftyp;ppufile:tcompilerppufile);
destructor destroy;override;
@ -84,6 +88,10 @@ interface
function is_fpuregable : boolean;
{ generics }
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
savesize : asizeuint;
end;
@ -1330,6 +1338,23 @@ implementation
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);
var
insertstack : psymtablestackitem;
@ -1341,6 +1366,7 @@ implementation
{$endif}
generictokenbuf:=nil;
genericdef:=nil;
genericparas:=tfphashobjectlist.create(false);
{ Don't register forwarddefs, they are disposed at the
end of an type block }
@ -1376,6 +1402,7 @@ implementation
generictokenbuf.free;
generictokenbuf:=nil;
end;
genericparas.free;
inherited destroy;
end;
@ -1386,6 +1413,7 @@ implementation
buf : array[0..255] of byte;
begin
inherited create(dt);
genericparas:=tfphashobjectlist.create(false);
DefId:=ppufile.getlongint;
current_module.deflist[DefId]:=self;
{$ifdef EXTDEBUG}
@ -1626,6 +1654,11 @@ implementation
generictokenbuf:=tdynamicarray.create(256);
end;
function tstoreddef.is_generic: boolean;
begin
result:=genericparas.count>0;
end;
{****************************************************************************
Tstringdef
@ -2946,6 +2979,7 @@ implementation
tarraysymtable(symtable).deref;
_elementdef:=tdef(_elementdefderef.resolve);
rangedef:=tdef(rangedefderef.resolve);
fillgenericparas(symtable);
end;
@ -3489,6 +3523,8 @@ implementation
else
tstoredsymtable(symtable).deref;
fillgenericparas(symtable);
{ assign TGUID? load only from system unit }
if not(assigned(rec_tguid)) and
(upper(typename)='TGUID') and
@ -3687,6 +3723,7 @@ implementation
tparasymtable(parast).deref;
{ recalculated parameters }
calcparas;
fillgenericparas(parast);
end;
@ -5502,6 +5539,7 @@ implementation
end
else
tstoredsymtable(symtable).deref;
fillgenericparas(symtable);
if objecttype=odt_helper then
extendeddef:=tdef(extendeddefderef.resolve);
for i:=0 to vmtentries.count-1 do

View File

@ -492,7 +492,8 @@ type
const
symtblopts=ord(high(tsymtableoption)) + 1;
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
options : tsymtableoptions;