* setup a proper symtable stack before parsing the generic declaration itself, resolves #9419

git-svn-id: trunk@8820 -
This commit is contained in:
florian 2007-10-15 19:43:01 +00:00
parent 3752cfb649
commit 7229dcfdcb
6 changed files with 76 additions and 26 deletions

1
.gitattributes vendored
View File

@ -8478,6 +8478,7 @@ tests/webtbs/tw9347a.pp svneol=native#text/plain
tests/webtbs/tw9347b.pp svneol=native#text/plain
tests/webtbs/tw9384.pp svneol=native#text/plain
tests/webtbs/tw9385.pp svneol=native#text/plain
tests/webtbs/tw9419.pp svneol=native#text/plain
tests/webtbs/tw9461.pp svneol=native#text/plain
tests/webtbs/tw9667.pp svneol=native#text/plain
tests/webtbs/tw9672.pp svneol=native#text/plain

View File

@ -202,6 +202,7 @@ interface
function get_module(moduleindex : longint) : tmodule;
function get_source_file(moduleindex,fileindex : longint) : tinputfile;
procedure addloadedunit(hp:tmodule);
function find_module_from_symtable(st:tsymtable):tmodule;
implementation
@ -221,6 +222,24 @@ implementation
Global Functions
*****************************************************************************}
function find_module_from_symtable(st:tsymtable):tmodule;
var
hp : tmodule;
begin
result:=nil;
hp:=tmodule(loaded_units.first);
while assigned(hp) do
begin
if (hp.globalsymtable=st) or
(hp.localsymtable=st) then
begin
result:=hp;
exit;
end;
hp:=tmodule(hp.next);
end;
end;
procedure set_current_module(p:tmodule);
begin
{ save the state of the scanner }

View File

@ -116,13 +116,6 @@ implementation
end;
{ Unused:
function tokenstring(i : ttoken):string;
begin
tokenstring:=tokeninfo^[i].str;
end;
}
{ consumes token i, write error if token is different }
procedure consume(i : ttoken);
begin

View File

@ -1779,25 +1779,6 @@ implementation
procedure specialize_objectdefs(p:TObject;arg:pointer);
function find_module_from_symtable(st:tsymtable):tmodule;
var
hp : tmodule;
begin
result:=nil;
hp:=tmodule(loaded_units.first);
while assigned(hp) do
begin
if (hp.globalsymtable=st) or
(hp.localsymtable=st) then
begin
result:=hp;
exit;
end;
hp:=tmodule(hp.next);
end;
end;
var
i : longint;
hp : tdef;

View File

@ -67,6 +67,8 @@ implementation
{ symtable }
symconst,symsym,symtable,
defutil,defcmp,
{ modules }
fmodule,
{ pass 1 }
node,ncgrtti,nobj,
nmat,nadd,ncal,nset,ncnv,ninl,ncon,nld,nflw,
@ -86,6 +88,9 @@ implementation
genericdef : tstoreddef;
generictype : ttypesym;
generictypelist : TFPObjectList;
oldsymtablestack : tsymtablestack;
hmodule : tmodule;
pu : tused_unit;
begin
{ retrieve generic def that we are going to replace }
genericdef:=tstoreddef(pt1.resultdef);
@ -148,6 +153,32 @@ implementation
{ force correct error location if too much type parameters are passed }
if token<>_RSHARPBRACKET then
consume(_RSHARPBRACKET);
{ Setup symtablestack a definition time
to get types right, however this is not perfect, we should probably record
the resolved symbols }
oldsymtablestack:=symtablestack;
symtablestack:=tsymtablestack.create;
if not assigned(genericdef) then
internalerror(200705151);
hmodule:=find_module_from_symtable(genericdef.owner);
if hmodule=nil then
internalerror(200705152);
pu:=tused_unit(hmodule.used_units.first);
while assigned(pu) do
begin
if not assigned(pu.u.globalsymtable) then
internalerror(200705153);
symtablestack.push(pu.u.globalsymtable);
pu:=tused_unit(pu.next);
end;
if assigned(hmodule.globalsymtable) then
symtablestack.push(hmodule.globalsymtable);
{ hacky, but necessary to insert the newly generated class properly }
symtablestack.push(oldsymtablestack.top);
{ Reparse the original type definition }
if not err then
begin
@ -158,6 +189,11 @@ implementation
{ Consume the semicolon if it is also recorded }
try_to_consume(_SEMICOLON);
end;
{ Restore symtablestack }
symtablestack.free;
symtablestack:=oldsymtablestack;
generictypelist.free;
consume(_RSHARPBRACKET);
end;

20
tests/webtbs/tw9419.pp Normal file
View File

@ -0,0 +1,20 @@
uses
fgl;
type
TEnum = (ta, tb, tc);
TMyMap = specialize TFPGMap<string, TEnum>;
var
map : TMyMap;
c : TEnum;
i : Longint;
begin
map := TMymap.Create();
map.Add('Hello', ta);
map.Find('Hello', i);
end.