compiler: push to the stack not only nested hierarchy but also class hierarchy for each nested entry both in method declaration and for method body, also push child hierarchy while parsing object members because in other case parent types are invisible for descendants (fixes mantis #0018124, mantis #0018127 and more) + extended test

git-svn-id: trunk@16491 -
This commit is contained in:
paul 2010-12-02 03:04:23 +00:00
parent 37179a6558
commit 2155dadf5e
5 changed files with 102 additions and 52 deletions

1
.gitattributes vendored
View File

@ -10776,6 +10776,7 @@ tests/webtbs/tw18075.pp svneol=native#text/pascal
tests/webtbs/tw18082.pp svneol=native#text/plain tests/webtbs/tw18082.pp svneol=native#text/plain
tests/webtbs/tw18085.pp svneol=native#text/pascal tests/webtbs/tw18085.pp svneol=native#text/pascal
tests/webtbs/tw18086.pp svneol=native#text/pascal tests/webtbs/tw18086.pp svneol=native#text/pascal
tests/webtbs/tw18127.pp svneol=native#text/pascal
tests/webtbs/tw1820.pp svneol=native#text/plain tests/webtbs/tw1820.pp svneol=native#text/plain
tests/webtbs/tw1825.pp svneol=native#text/plain tests/webtbs/tw1825.pp svneol=native#text/plain
tests/webtbs/tw1850.pp svneol=native#text/plain tests/webtbs/tw1850.pp svneol=native#text/plain

View File

@ -1047,11 +1047,13 @@ implementation
{ parse optional GUID for interfaces } { parse optional GUID for interfaces }
parse_guid; parse_guid;
{ parse and insert object members } //symtablestack.push(current_objectdef.symtable);
symtablestack.push(current_objectdef.symtable); push_child_hierarcy(current_objectdef);
insert_generic_parameter_types(genericdef,genericlist); insert_generic_parameter_types(genericdef,genericlist);
{ parse and insert object members }
parse_object_members; parse_object_members;
symtablestack.pop(current_objectdef.symtable); //symtablestack.pop(current_objectdef.symtable);
pop_child_hierarchy(current_objectdef);
end; end;
{ generate vmt space if needed } { generate vmt space if needed }

View File

@ -62,6 +62,14 @@ interface
function parse_proc_head(aclass:tobjectdef;potype:tproctypeoption;var pd:tprocdef):boolean; function parse_proc_head(aclass:tobjectdef;potype:tproctypeoption;var pd:tprocdef):boolean;
function parse_proc_dec(isclassmethod:boolean; aclass:tobjectdef):tprocdef; function parse_proc_dec(isclassmethod:boolean; aclass:tobjectdef):tprocdef;
{ helper functions - they insert nested objects hierarcy to the symtablestack
with object hierarchy
}
function push_child_hierarcy(obj:tobjectdef):integer;
function pop_child_hierarchy(obj:tobjectdef):integer;
function push_nested_hierarchy(obj:tobjectdef):integer;
function pop_nested_hierarchy(obj:tobjectdef):integer;
implementation implementation
uses uses
@ -89,6 +97,51 @@ implementation
Declaring it as string here results in an error when compiling (PFV) } Declaring it as string here results in an error when compiling (PFV) }
current_procinfo = 'error'; current_procinfo = 'error';
function push_child_hierarcy(obj:tobjectdef):integer;
var
_class,hp : tobjectdef;
begin
result:=0;
{ insert class hierarchy in the reverse order }
hp:=nil;
repeat
_class:=obj;
while _class.childof<>hp do
_class:=_class.childof;
hp:=_class;
symtablestack.push(_class.symtable);
inc(result);
until hp=obj;
end;
function push_nested_hierarchy(obj:tobjectdef):integer;
begin
result:=0;
if obj.owner.symtabletype=ObjectSymtable then
inc(result,push_nested_hierarchy(tobjectdef(obj.owner.defowner)));
inc(result,push_child_hierarcy(obj));
end;
function pop_child_hierarchy(obj:tobjectdef):integer;
var
_class : tobjectdef;
begin
result:=0;
_class:=obj;
while assigned(_class) do
begin
symtablestack.pop(_class.symtable);
_class:=_class.childof;
inc(result);
end;
end;
function pop_nested_hierarchy(obj:tobjectdef):integer;
begin
result:=pop_child_hierarchy(obj);
if obj.owner.symtabletype=ObjectSymtable then
inc(result,pop_nested_hierarchy(tobjectdef(obj.owner.defowner)));
end;
procedure insert_funcret_para(pd:tabstractprocdef); procedure insert_funcret_para(pd:tabstractprocdef);
var var
@ -720,23 +773,6 @@ implementation
function parse_proc_head(aclass:tobjectdef;potype:tproctypeoption;var pd:tprocdef):boolean; function parse_proc_head(aclass:tobjectdef;potype:tproctypeoption;var pd:tprocdef):boolean;
function push_objects(obj:tobjectdef):integer;
begin
result:=1;
if obj.owner.symtabletype=ObjectSymtable then
inc(result,push_objects(tobjectdef(obj.owner.defowner)));
symtablestack.push(obj.symtable);
end;
function pop_objects(obj:tobjectdef):integer;
begin
result:=1;
symtablestack.pop(obj.symtable);
if obj.owner.symtabletype=ObjectSymtable then
inc(result,pop_objects(tobjectdef(obj.owner.defowner)));
end;
var var
hs : string; hs : string;
orgsp,sp : TIDString; orgsp,sp : TIDString;
@ -1020,7 +1056,7 @@ implementation
(pd.parast.symtablelevel=normal_function_level) and (pd.parast.symtablelevel=normal_function_level) and
(symtablestack.top.symtabletype<>ObjectSymtable) then (symtablestack.top.symtabletype<>ObjectSymtable) then
begin begin
popclass:=push_objects(pd._class); popclass:=push_nested_hierarchy(pd._class);
old_current_objectdef:=current_objectdef; old_current_objectdef:=current_objectdef;
old_current_genericdef:=current_genericdef; old_current_genericdef:=current_genericdef;
old_current_specializedef:=current_specializedef; old_current_specializedef:=current_specializedef;
@ -1041,7 +1077,7 @@ implementation
current_objectdef:=old_current_objectdef; current_objectdef:=old_current_objectdef;
current_genericdef:=old_current_genericdef; current_genericdef:=old_current_genericdef;
current_specializedef:=old_current_specializedef; current_specializedef:=old_current_specializedef;
dec(popclass, pop_objects(pd._class)); dec(popclass,pop_nested_hierarchy(pd._class));
if popclass<>0 then if popclass<>0 then
internalerror(201011260); // 11 nov 2010 index 0 internalerror(201011260); // 11 nov 2010 index 0
end; end;
@ -1056,8 +1092,8 @@ implementation
var var
pd : tprocdef; pd : tprocdef;
locationstr: string; locationstr: string;
old_parse_generic, old_parse_generic: boolean;
popclass: boolean; popclass: integer;
old_current_objectdef, old_current_objectdef,
old_current_genericdef, old_current_genericdef,
old_current_specializedef: tobjectdef; old_current_specializedef: tobjectdef;
@ -1078,13 +1114,12 @@ implementation
old_parse_generic:=parse_generic; old_parse_generic:=parse_generic;
inc(testcurobject); inc(testcurobject);
{ Add ObjectSymtable to be able to find generic type definitions } { Add ObjectSymtable to be able to find generic type definitions }
popclass:=false; popclass:=0;
if assigned(pd._class) and if assigned(pd._class) and
(pd.parast.symtablelevel=normal_function_level) and (pd.parast.symtablelevel=normal_function_level) and
(symtablestack.top.symtabletype<>ObjectSymtable) then (symtablestack.top.symtabletype<>ObjectSymtable) then
begin begin
symtablestack.push(pd._class.symtable); popclass:=push_nested_hierarchy(pd._class);
popclass:=true;
parse_generic:=(df_generic in pd._class.defoptions); parse_generic:=(df_generic in pd._class.defoptions);
old_current_objectdef:=current_objectdef; old_current_objectdef:=current_objectdef;
old_current_genericdef:=current_genericdef; old_current_genericdef:=current_genericdef;
@ -1100,12 +1135,14 @@ implementation
if is_dispinterface(pd._class) and not is_automatable(pd.returndef) then if is_dispinterface(pd._class) and not is_automatable(pd.returndef) then
Message1(type_e_not_automatable,pd.returndef.typename); Message1(type_e_not_automatable,pd.returndef.typename);
if popclass then if popclass>0 then
begin begin
current_objectdef:=old_current_objectdef; current_objectdef:=old_current_objectdef;
current_genericdef:=old_current_genericdef; current_genericdef:=old_current_genericdef;
current_specializedef:=old_current_specializedef; current_specializedef:=old_current_specializedef;
symtablestack.pop(pd._class.symtable); dec(popclass,pop_nested_hierarchy(pd._class));
if popclass<>0 then
internalerror(201012020);
end; end;
dec(testcurobject); dec(testcurobject);
parse_generic:=old_parse_generic; parse_generic:=old_parse_generic;

View File

@ -1271,25 +1271,13 @@ implementation
procedure tcgprocinfo.add_to_symtablestack; procedure tcgprocinfo.add_to_symtablestack;
var
_class,hp : tobjectdef;
begin begin
{ insert symtables for the class, but only if it is no nested function } { insert symtables for the class, but only if it is no nested function }
if assigned(procdef._class) and if assigned(procdef._class) and
not(assigned(parent) and not(assigned(parent) and
assigned(parent.procdef) and assigned(parent.procdef) and
assigned(parent.procdef._class)) then assigned(parent.procdef._class)) then
begin push_nested_hierarchy(procdef._class);
{ insert them in the reverse order }
hp:=nil;
repeat
_class:=procdef._class;
while _class.childof<>hp do
_class:=_class.childof;
hp:=_class;
symtablestack.push(_class.symtable);
until hp=procdef._class;
end;
{ insert parasymtable in symtablestack when parsing { insert parasymtable in symtablestack when parsing
a function } a function }
@ -1305,8 +1293,6 @@ implementation
procedure tcgprocinfo.remove_from_symtablestack; procedure tcgprocinfo.remove_from_symtablestack;
var
_class : tobjectdef;
begin begin
{ remove localsymtable } { remove localsymtable }
if procdef.localst.symtablelevel>=normal_function_level then if procdef.localst.symtablelevel>=normal_function_level then
@ -1321,14 +1307,7 @@ implementation
not(assigned(parent) and not(assigned(parent) and
assigned(parent.procdef) and assigned(parent.procdef) and
assigned(parent.procdef._class)) then assigned(parent.procdef._class)) then
begin pop_nested_hierarchy(procdef._class);
_class:=procdef._class;
while assigned(_class) do
begin
symtablestack.pop(_class.symtable);
_class:=_class.childof;
end;
end;
end; end;

31
tests/webtbs/tw18127.pp Normal file
View File

@ -0,0 +1,31 @@
{ %norun% }
program tw18127;
{$mode objfpc}{$H+}
type
TBar = class
public
type
TSomeInt = integer;
end;
TFoo1 = class(TBar)
public
const
one = 1;
type
TFoo2 = TSomeInt; // was error: Identifier not found "TSomeInt"
TFoo3 = class
function Func: TFoo2;
end;
end;
function TFoo1.TFoo3.Func: TFoo2; // was error: Identifier not found "TFoo2"
begin
Result := one; // was error: Identifier not found "one"
end;
begin
end.