mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 09:29:26 +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/tw9347b.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw9384.pp svneol=native#text/plain
|
tests/webtbs/tw9384.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw9385.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/tw9461.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw9667.pp svneol=native#text/plain
|
tests/webtbs/tw9667.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw9672.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_module(moduleindex : longint) : tmodule;
|
||||||
function get_source_file(moduleindex,fileindex : longint) : tinputfile;
|
function get_source_file(moduleindex,fileindex : longint) : tinputfile;
|
||||||
procedure addloadedunit(hp:tmodule);
|
procedure addloadedunit(hp:tmodule);
|
||||||
|
function find_module_from_symtable(st:tsymtable):tmodule;
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -221,6 +222,24 @@ implementation
|
|||||||
Global Functions
|
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);
|
procedure set_current_module(p:tmodule);
|
||||||
begin
|
begin
|
||||||
{ save the state of the scanner }
|
{ save the state of the scanner }
|
||||||
|
@ -116,13 +116,6 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ Unused:
|
|
||||||
function tokenstring(i : ttoken):string;
|
|
||||||
begin
|
|
||||||
tokenstring:=tokeninfo^[i].str;
|
|
||||||
end;
|
|
||||||
}
|
|
||||||
|
|
||||||
{ consumes token i, write error if token is different }
|
{ consumes token i, write error if token is different }
|
||||||
procedure consume(i : ttoken);
|
procedure consume(i : ttoken);
|
||||||
begin
|
begin
|
||||||
|
@ -1779,25 +1779,6 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
procedure specialize_objectdefs(p:TObject;arg:pointer);
|
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
|
var
|
||||||
i : longint;
|
i : longint;
|
||||||
hp : tdef;
|
hp : tdef;
|
||||||
|
@ -67,6 +67,8 @@ implementation
|
|||||||
{ symtable }
|
{ symtable }
|
||||||
symconst,symsym,symtable,
|
symconst,symsym,symtable,
|
||||||
defutil,defcmp,
|
defutil,defcmp,
|
||||||
|
{ modules }
|
||||||
|
fmodule,
|
||||||
{ pass 1 }
|
{ pass 1 }
|
||||||
node,ncgrtti,nobj,
|
node,ncgrtti,nobj,
|
||||||
nmat,nadd,ncal,nset,ncnv,ninl,ncon,nld,nflw,
|
nmat,nadd,ncal,nset,ncnv,ninl,ncon,nld,nflw,
|
||||||
@ -86,6 +88,9 @@ implementation
|
|||||||
genericdef : tstoreddef;
|
genericdef : tstoreddef;
|
||||||
generictype : ttypesym;
|
generictype : ttypesym;
|
||||||
generictypelist : TFPObjectList;
|
generictypelist : TFPObjectList;
|
||||||
|
oldsymtablestack : tsymtablestack;
|
||||||
|
hmodule : tmodule;
|
||||||
|
pu : tused_unit;
|
||||||
begin
|
begin
|
||||||
{ retrieve generic def that we are going to replace }
|
{ retrieve generic def that we are going to replace }
|
||||||
genericdef:=tstoreddef(pt1.resultdef);
|
genericdef:=tstoreddef(pt1.resultdef);
|
||||||
@ -148,6 +153,32 @@ implementation
|
|||||||
{ force correct error location if too much type parameters are passed }
|
{ force correct error location if too much type parameters are passed }
|
||||||
if token<>_RSHARPBRACKET then
|
if token<>_RSHARPBRACKET then
|
||||||
consume(_RSHARPBRACKET);
|
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 }
|
{ Reparse the original type definition }
|
||||||
if not err then
|
if not err then
|
||||||
begin
|
begin
|
||||||
@ -158,6 +189,11 @@ implementation
|
|||||||
{ Consume the semicolon if it is also recorded }
|
{ Consume the semicolon if it is also recorded }
|
||||||
try_to_consume(_SEMICOLON);
|
try_to_consume(_SEMICOLON);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ Restore symtablestack }
|
||||||
|
symtablestack.free;
|
||||||
|
symtablestack:=oldsymtablestack;
|
||||||
|
|
||||||
generictypelist.free;
|
generictypelist.free;
|
||||||
consume(_RSHARPBRACKET);
|
consume(_RSHARPBRACKET);
|
||||||
end;
|
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