* current_objectdef is now always valid when parsing is within the

context of a class. This can be either the class declaration or
    a method implementation
  * replaced all current_procinfo.procdef._class with current_objectdef

git-svn-id: trunk@12059 -
This commit is contained in:
peter 2008-11-12 18:54:39 +00:00
parent b580cbc778
commit 8419161964
9 changed files with 86 additions and 89 deletions

View File

@ -217,7 +217,7 @@ implementation
SysUtils,globals,
verbose,systems,
scanner,ppu,dbgbase,
procinfo;
procinfo,symdef;
{$ifdef MEMDEBUG}
var
@ -550,7 +550,10 @@ implementation
if assigned(procinfo) then
begin
if current_procinfo=tprocinfo(procinfo) then
current_procinfo:=nil;
begin
current_procinfo:=nil;
current_objectdef:=nil;
end;
{ release procinfo tree }
while assigned(procinfo) do
begin
@ -629,7 +632,10 @@ implementation
if assigned(procinfo) then
begin
if current_procinfo=tprocinfo(procinfo) then
current_procinfo:=nil;
begin
current_procinfo:=nil;
current_objectdef:=nil;
end;
{ release procinfo tree }
while assigned(procinfo) do
begin

View File

@ -1637,12 +1637,7 @@ implementation
st.defowner.owner.iscurrentunit then
topclassh:=tobjectdef(st.defowner)
else
begin
if assigned(current_procinfo) then
topclassh:=current_procinfo.procdef._class
else
topclassh:=nil;
end;
topclassh:=current_objectdef;
{ link all procedures which have the same # of parameters }
for j:=0 to sym.ProcdefList.Count-1 do

View File

@ -474,9 +474,9 @@ implementation
result:=internalstatements(newstatement);
{ call fail helper and exit normal }
if is_class(current_procinfo.procdef._class) then
if is_class(current_objectdef) then
begin
srsym:=search_class_member(current_procinfo.procdef._class,'FREEINSTANCE');
srsym:=search_class_member(current_objectdef,'FREEINSTANCE');
if assigned(srsym) and
(srsym.typ=procsym) then
begin
@ -496,13 +496,13 @@ implementation
internalerror(200305108);
end
else
if is_object(current_procinfo.procdef._class) then
if is_object(current_objectdef) then
begin
{ parameter 3 : vmt_offset }
{ parameter 2 : pointer to vmt }
{ parameter 1 : self pointer }
para:=ccallparanode.create(
cordconstnode.create(current_procinfo.procdef._class.vmt_offset,s32inttype,false),
cordconstnode.create(current_objectdef.vmt_offset,s32inttype,false),
ccallparanode.create(
ctypeconvnode.create_internal(
load_vmt_pointer_node,

View File

@ -42,7 +42,7 @@ implementation
{$ENDIF}
cutils,cclasses,
globtype,version,tokens,systems,globals,verbose,switches,
symbase,symtable,symsym,
symbase,symtable,symdef,symsym,
finput,fmodule,fppu,
aasmbase,aasmtai,aasmdata,
cgbase,
@ -64,6 +64,7 @@ implementation
current_module:=nil;
current_asmdata:=nil;
current_procinfo:=nil;
current_objectdef:=nil;
loaded_units:=TLinkedList.Create;
@ -133,6 +134,7 @@ implementation
current_module:=nil;
current_procinfo:=nil;
current_asmdata:=nil;
current_objectdef:=nil;
{ unload units }
if assigned(loaded_units) then
@ -284,6 +286,11 @@ implementation
olddata : polddata;
hp,hp2 : tmodule;
begin
{ parsing a procedure or declaration should be finished }
if assigned(current_procinfo) then
internalerror(200811121);
if assigned(current_objectdef) then
internalerror(200811122);
inc(compile_level);
parser_current_file:=filename;
{ Uses heap memory instead of placing everything on the

View File

@ -1410,15 +1410,14 @@ implementation
is_object(hdef) then
begin
consume(_POINT);
if assigned(current_procinfo) and
assigned(current_procinfo.procdef._class) and
if assigned(current_objectdef) and
not(getaddr) then
begin
if current_procinfo.procdef._class.is_related(tobjectdef(hdef)) then
if current_objectdef.is_related(tobjectdef(hdef)) then
begin
p1:=ctypenode.create(hdef);
{ search also in inherited methods }
searchsym_in_class(tobjectdef(hdef),current_procinfo.procdef._class,pattern,srsym,srsymtable);
searchsym_in_class(tobjectdef(hdef),current_objectdef,pattern,srsym,srsymtable);
if assigned(srsym) then
check_hints(srsym,srsym.symoptions);
consume(_ID);
@ -2160,8 +2159,7 @@ implementation
{ Handle references to self }
if (idtoken=_SELF) and
not(block_type in [bt_const,bt_type,bt_const_type,bt_var_type]) and
assigned(current_procinfo) and
assigned(current_procinfo.procdef._class) then
assigned(current_objectdef) then
begin
p1:=load_self_node;
consume(_ID);
@ -2198,9 +2196,9 @@ implementation
again:=true;
consume(_INHERITED);
if assigned(current_procinfo) and
assigned(current_procinfo.procdef._class) then
assigned(current_objectdef) then
begin
hclassdef:=current_procinfo.procdef._class.childof;
hclassdef:=current_objectdef.childof;
{ if inherited; only then we need the method with
the same name }
if token in endtokens then
@ -2218,7 +2216,7 @@ implementation
if (po_msgstr in pd.procoptions) then
searchsym_in_class_by_msgstr(hclassdef,pd.messageinf.str^,srsym,srsymtable)
else
searchsym_in_class(hclassdef,current_procinfo.procdef._class,hs,srsym,srsymtable);
searchsym_in_class(hclassdef,current_objectdef,hs,srsym,srsymtable);
end
else
begin
@ -2226,7 +2224,7 @@ implementation
hsorg:=orgpattern;
consume(_ID);
anon_inherited:=false;
searchsym_in_class(hclassdef,current_procinfo.procdef._class,hs,srsym,srsymtable);
searchsym_in_class(hclassdef,current_objectdef,hs,srsym,srsymtable);
end;
if assigned(srsym) then
begin

View File

@ -266,19 +266,18 @@ implementation
srsym : tsym;
para : tcallparanode;
newstatement : tstatementnode;
hdef : tdef;
begin
result:=internalstatements(newstatement);
if assigned(current_procinfo.procdef._class) then
if assigned(current_objectdef) then
begin
{ a constructor needs a help procedure }
if (current_procinfo.procdef.proctypeoption=potype_constructor) then
begin
if is_class(current_procinfo.procdef._class) then
if is_class(current_objectdef) then
begin
include(current_procinfo.flags,pi_needs_implicit_finally);
srsym:=search_class_member(current_procinfo.procdef._class,'NEWINSTANCE');
srsym:=search_class_member(current_objectdef,'NEWINSTANCE');
if assigned(srsym) and
(srsym.typ=procsym) then
begin
@ -300,17 +299,15 @@ implementation
internalerror(200305108);
end
else
if is_object(current_procinfo.procdef._class) then
if is_object(current_objectdef) then
begin
hdef:=current_procinfo.procdef._class;
hdef:=tpointerdef.create(hdef);
{ parameter 3 : vmt_offset }
{ parameter 2 : address of pointer to vmt,
this is required to allow setting the vmt to -1 to indicate
that memory was allocated }
{ parameter 1 : self pointer }
para:=ccallparanode.create(
cordconstnode.create(current_procinfo.procdef._class.vmt_offset,s32inttype,false),
cordconstnode.create(current_objectdef.vmt_offset,s32inttype,false),
ccallparanode.create(
ctypeconvnode.create_internal(
load_vmt_pointer_node,
@ -341,9 +338,9 @@ implementation
{ maybe call BeforeDestruction for classes }
if (current_procinfo.procdef.proctypeoption=potype_destructor) and
is_class(current_procinfo.procdef._class) then
is_class(current_objectdef) then
begin
srsym:=search_class_member(current_procinfo.procdef._class,'BEFOREDESTRUCTION');
srsym:=search_class_member(current_objectdef,'BEFOREDESTRUCTION');
if assigned(srsym) and
(srsym.typ=procsym) then
begin
@ -373,7 +370,7 @@ implementation
begin
result:=internalstatements(newstatement);
if assigned(current_procinfo.procdef._class) then
if assigned(current_objectdef) then
begin
{ Don't test self and the vmt here. The reason is that }
{ a constructor already checks whether these are valid }
@ -384,9 +381,9 @@ implementation
current_settings.localswitches:=oldlocalswitches-[cs_check_object,cs_check_range];
{ maybe call AfterConstruction for classes }
if (current_procinfo.procdef.proctypeoption=potype_constructor) and
is_class(current_procinfo.procdef._class) then
is_class(current_objectdef) then
begin
srsym:=search_class_member(current_procinfo.procdef._class,'AFTERCONSTRUCTION');
srsym:=search_class_member(current_objectdef,'AFTERCONSTRUCTION');
if assigned(srsym) and
(srsym.typ=procsym) then
begin
@ -410,9 +407,9 @@ implementation
{ a destructor needs a help procedure }
if (current_procinfo.procdef.proctypeoption=potype_destructor) then
begin
if is_class(current_procinfo.procdef._class) then
if is_class(current_objectdef) then
begin
srsym:=search_class_member(current_procinfo.procdef._class,'FREEINSTANCE');
srsym:=search_class_member(current_objectdef,'FREEINSTANCE');
if assigned(srsym) and
(srsym.typ=procsym) then
begin
@ -434,16 +431,16 @@ implementation
internalerror(200305108);
end
else
if is_object(current_procinfo.procdef._class) then
if is_object(current_objectdef) then
begin
{ finalize object data }
if current_procinfo.procdef._class.needs_inittable then
if current_objectdef.needs_inittable then
addstatement(newstatement,finalize_data_node(load_self_node));
{ parameter 3 : vmt_offset }
{ parameter 2 : pointer to vmt }
{ parameter 1 : self pointer }
para:=ccallparanode.create(
cordconstnode.create(current_procinfo.procdef._class.vmt_offset,s32inttype,false),
cordconstnode.create(current_objectdef.vmt_offset,s32inttype,false),
ccallparanode.create(
ctypeconvnode.create_internal(
load_vmt_pointer_node,
@ -474,14 +471,14 @@ implementation
{ a constructor needs call destructor (if available) when it
is not inherited }
if assigned(current_procinfo.procdef._class) and
if assigned(current_objectdef) and
(current_procinfo.procdef.proctypeoption=potype_constructor) then
begin
{ Don't test self and the vmt here. See generate_bodyexit_block }
{ why (JM) }
oldlocalswitches:=current_settings.localswitches;
current_settings.localswitches:=oldlocalswitches-[cs_check_object,cs_check_range];
pd:=current_procinfo.procdef._class.Finddestructor;
pd:=current_objectdef.Finddestructor;
if assigned(pd) then
begin
{ if vmt<>0 then call destructor }
@ -691,9 +688,10 @@ implementation
procedure tcgprocinfo.generate_code;
var
oldprocinfo : tprocinfo;
old_current_procinfo : tprocinfo;
oldmaxfpuregisters : longint;
oldfilepos : tfileposinfo;
old_current_objectdef : tobjectdef;
templist : TAsmList;
headertai : tai;
i : integer;
@ -717,12 +715,14 @@ implementation
if assigned(tg) then
internalerror(200309201);
oldprocinfo:=current_procinfo;
old_current_procinfo:=current_procinfo;
oldfilepos:=current_filepos;
old_current_objectdef:=current_objectdef;
oldmaxfpuregisters:=current_settings.maxfpuregisters;
current_procinfo:=self;
current_filepos:=entrypos;
current_objectdef:=procdef._class;
templist:=TAsmList.create;
@ -1139,7 +1139,8 @@ implementation
templist.free;
current_settings.maxfpuregisters:=oldmaxfpuregisters;
current_filepos:=oldfilepos;
current_procinfo:=oldprocinfo;
current_objectdef:=old_current_objectdef;
current_procinfo:=old_current_procinfo;
end;
@ -1266,21 +1267,22 @@ implementation
procedure tcgprocinfo.parse_body;
var
oldprocinfo : tprocinfo;
oldblock_type : tblock_type;
old_current_procinfo : tprocinfo;
old_block_type : tblock_type;
st : TSymtable;
old_current_objectdef : tobjectdef;
begin
oldprocinfo:=current_procinfo;
oldblock_type:=block_type;
{ reset break and continue labels }
block_type:=bt_body;
old_current_procinfo:=current_procinfo;
old_block_type:=block_type;
old_current_objectdef:=current_objectdef;
current_procinfo:=self;
current_objectdef:=procdef._class;
{ calculate the lexical level }
if procdef.parast.symtablelevel>maxnesting then
Message(parser_e_too_much_lexlevel);
block_type:=bt_body;
{$ifdef state_tracking}
{ aktstate:=Tstate_storage.create;}
@ -1383,10 +1385,11 @@ implementation
{ aktstate.destroy;}
{$endif state_tracking}
current_procinfo:=oldprocinfo;
current_objectdef:=old_current_objectdef;
current_procinfo:=old_current_procinfo;
{ Restore old state }
block_type:=oldblock_type;
block_type:=old_block_type;
end;
@ -1526,23 +1529,22 @@ implementation
var
old_current_procinfo : tprocinfo;
old_current_objectdef : tobjectdef;
pdflags : tpdflags;
pd,firstpd : tprocdef;
s : string;
begin
{ save old state }
old_current_procinfo:=current_procinfo;
old_current_objectdef:=current_objectdef;
{ reset current_procinfo.procdef to nil to be sure that nothing is writing
to an other procdef }
current_procinfo:=nil;
current_objectdef:=nil;
{ parse procedure declaration }
if assigned(old_current_procinfo) and
assigned(old_current_procinfo.procdef) then
pd:=parse_proc_dec(old_current_procinfo.procdef._class)
else
pd:=parse_proc_dec(nil);
pd:=parse_proc_dec(old_current_objectdef);
{ set the default function options }
if parse_only then
@ -1586,7 +1588,7 @@ implementation
begin
{ A method must be forward defined (in the object declaration) }
if assigned(pd._class) and
(not assigned(old_current_procinfo.procdef._class)) then
(not assigned(old_current_objectdef)) then
begin
MessagePos1(pd.fileinfo,parser_e_header_dont_match_any_member,pd.fullprocname(false));
tprocsym(pd.procsym).write_parameter_lists(pd);
@ -1667,6 +1669,7 @@ implementation
current_asmdata.DefineAsmSymbol(pd.mangledname,AB_LOCAL,AT_FUNCTION);
end;
current_objectdef:=old_current_objectdef;
current_procinfo:=old_current_procinfo;
end;

View File

@ -118,7 +118,7 @@ type
constructor create(optype : tcoperand);virtual;
destructor destroy;override;
{ converts the instruction to an instruction how it's used by the assembler writer
and concats it to the passed list. The newly created item is returned if the
and concats it to the passed list. The newly created item is returned if the
instruction was valid, otherwise nil is returned }
function ConcatInstruction(p:TAsmList) : tai;virtual;
Procedure Swapoperands;
@ -693,7 +693,7 @@ end;
Function TOperand.SetupSelf:boolean;
Begin
SetupSelf:=false;
if assigned(current_procinfo.procdef._class) then
if assigned(current_objectdef) then
SetupSelf:=setupvar('self',false)
else
Message(asmr_e_cannot_use_SELF_outside_a_method);
@ -1294,7 +1294,7 @@ Begin
base:=Copy(s,1,i-1);
delete(s,1,i);
if base='SELF' then
st:=current_procinfo.procdef._class.symtable
st:=current_objectdef.symtable
else
begin
asmsearchsym(base,sym,srsymtable);

View File

@ -3863,14 +3863,14 @@ implementation
function tobjectdef.GetTypeName:string;
begin
if (self <> current_objectdef) then
GetTypeName:=typename
{ in this case we will go in endless recursion, because then }
{ there is no tsym associated yet with the def. It can occur }
{ (tests/webtbf/tw4757.pp), so for now give a generic name }
{ instead of the actual type name }
if not assigned(typesym) then
result:='<Currently Parsed Class>'
else
{ in this case we will go in endless recursion, because then }
{ there is no tsym associated yet with the def. It can occur }
{ (tests/webtbf/tw4757.pp), so for now give a generic name }
{ instead of the actual type name }
GetTypeName:='<Currently Parsed Class>';
result:=typename;
end;

View File

@ -1579,14 +1579,8 @@ implementation
(srsymtable.defowner.owner.iscurrentunit) then
topclass:=tobjectdef(srsymtable.defowner)
else
begin
if assigned(current_procinfo) then
topclass:=current_procinfo.procdef._class;
end;
if assigned(current_procinfo) then
context:=current_procinfo.procdef._class
else
context:=nil;
topclass:=current_objectdef;
context:=current_objectdef;
if tsym(srsym).is_visible_for_object(topclass,context) then
begin
{ we need to know if a procedure references symbols
@ -1636,8 +1630,8 @@ implementation
srsym:=tsym(srsymtable.FindWithHash(hashedid));
if assigned(srsym) and
not(srsym.typ in [fieldvarsym,paravarsym]) and
(not assigned(current_procinfo) or
tsym(srsym).is_visible_for_object(current_procinfo.procdef._class,current_procinfo.procdef._class)) then
(not assigned(current_objectdef) or
tsym(srsym).is_visible_for_object(current_objectdef,current_objectdef)) then
begin
{ we need to know if a procedure references symbols
in the static symtable, because then it can't be
@ -1697,20 +1691,15 @@ implementation
function searchsym_in_class(classh,contextclassh:tobjectdef;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
var
hashedid : THashedIDString;
currentclassh : tobjectdef;
begin
result:=false;
hashedid.id:=s;
if assigned(current_procinfo) and assigned(current_procinfo.procdef) then
currentclassh:=current_procinfo.procdef._class
else
currentclassh:=nil;
while assigned(classh) do
begin
srsymtable:=classh.symtable;
srsym:=tsym(srsymtable.FindWithHash(hashedid));
if assigned(srsym) and
tsym(srsym).is_visible_for_object(contextclassh,currentclassh) then
tsym(srsym).is_visible_for_object(contextclassh,current_objectdef) then
begin
addsymref(srsym);
result:=true;
@ -2155,7 +2144,6 @@ implementation
class_tobject:=nil;
interface_iunknown:=nil;
rec_tguid:=nil;
current_objectdef:=nil;
dupnr:=0;
end;