mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-16 04:59:25 +02:00
* setup a proper symtable stack before parsing the generic declaration itself, resolves #9419
git-svn-id: trunk@8820 -
This commit is contained in:
parent
3752cfb649
commit
7229dcfdcb
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -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
|
||||
|
@ -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 }
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
20
tests/webtbs/tw9419.pp
Normal 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.
|
Loading…
Reference in New Issue
Block a user