mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-15 14:19:28 +02:00
* self moved to hidden parameter
* removed hdisposen,hnewn,selfn
This commit is contained in:
parent
cb49935ca1
commit
1a2eedd767
@ -416,6 +416,22 @@ implementation
|
||||
framepointer_offset:=procdef.parast.address_fixup;
|
||||
inc(procdef.parast.address_fixup,POINTER_SIZE);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure tprocinfo.after_header;
|
||||
var
|
||||
srsym : tvarsym;
|
||||
begin
|
||||
{ Retrieve function result offset }
|
||||
if assigned(procdef.funcretsym) then
|
||||
begin
|
||||
current_procinfo.return_offset:=tvarsym(procdef.funcretsym).address+
|
||||
tvarsym(procdef.funcretsym).owner.address_fixup;
|
||||
if tvarsym(procdef.funcretsym).owner.symtabletype=localsymtable then
|
||||
current_procinfo.return_offset:=tg.direction*current_procinfo.return_offset;
|
||||
end;
|
||||
{ retrieve offsets of self/vmt }
|
||||
if assigned(procdef._class) then
|
||||
begin
|
||||
if (po_containsself in procdef.procoptions) then
|
||||
@ -426,29 +442,37 @@ implementation
|
||||
{ self isn't pushed in nested procedure of methods }
|
||||
if (procdef.parast.symtablelevel=normal_function_level) then
|
||||
begin
|
||||
selfpointer_offset:=procdef.parast.address_fixup;
|
||||
inc(procdef.parast.address_fixup,POINTER_SIZE);
|
||||
srsym:=tvarsym(procdef.parast.search('self'));
|
||||
if not assigned(srsym) then
|
||||
internalerror(200305058);
|
||||
selfpointer_offset:=tvarsym(srsym).address+srsym.owner.address_fixup;
|
||||
end;
|
||||
|
||||
{ Special parameters for de-/constructors }
|
||||
case procdef.proctypeoption of
|
||||
potype_constructor :
|
||||
begin
|
||||
vmtpointer_offset:=procdef.parast.address_fixup;
|
||||
inc(procdef.parast.address_fixup,POINTER_SIZE);
|
||||
srsym:=tvarsym(procdef.parast.search('vmt'));
|
||||
if not assigned(srsym) then
|
||||
internalerror(200305058);
|
||||
vmtpointer_offset:=tvarsym(srsym).address+srsym.owner.address_fixup;
|
||||
end;
|
||||
potype_destructor :
|
||||
begin
|
||||
if is_object(procdef._class) then
|
||||
begin
|
||||
vmtpointer_offset:=procdef.parast.address_fixup;
|
||||
inc(procdef.parast.address_fixup,POINTER_SIZE);
|
||||
srsym:=tvarsym(procdef.parast.search('vmt'));
|
||||
if not assigned(srsym) then
|
||||
internalerror(200305058);
|
||||
vmtpointer_offset:=tvarsym(srsym).address+srsym.owner.address_fixup;
|
||||
end
|
||||
else
|
||||
if is_class(procdef._class) then
|
||||
begin
|
||||
inheritedflag_offset:=procdef.parast.address_fixup;
|
||||
inc(procdef.parast.address_fixup,POINTER_SIZE);
|
||||
srsym:=tvarsym(procdef.parast.search('vmt'));
|
||||
if not assigned(srsym) then
|
||||
internalerror(200305058);
|
||||
inheritedflag_offset:=tvarsym(srsym).address+srsym.owner.address_fixup;
|
||||
end
|
||||
else
|
||||
internalerror(200303261);
|
||||
@ -458,19 +482,6 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure tprocinfo.after_header;
|
||||
begin
|
||||
{ Retrieve function result offset }
|
||||
if assigned(procdef.funcretsym) then
|
||||
begin
|
||||
current_procinfo.return_offset:=tvarsym(procdef.funcretsym).address+
|
||||
tvarsym(procdef.funcretsym).owner.address_fixup;
|
||||
if tvarsym(procdef.funcretsym).owner.symtabletype=localsymtable then
|
||||
current_procinfo.return_offset:=tg.direction*current_procinfo.return_offset;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure tprocinfo.after_pass1;
|
||||
begin
|
||||
end;
|
||||
@ -630,7 +641,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.45 2003-04-27 11:21:32 peter
|
||||
Revision 1.46 2003-05-09 17:47:02 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.45 2003/04/27 11:21:32 peter
|
||||
* aktprocdef renamed to current_procdef
|
||||
* procinfo renamed to current_procinfo
|
||||
* procinfo will now be stored in current_module so it can be
|
||||
|
@ -1333,10 +1333,8 @@ unit cgobj;
|
||||
{ call the special incr function or the generic addref }
|
||||
if incrfunc<>'' then
|
||||
begin
|
||||
if loadref then
|
||||
a_param_ref(list,OS_ADDR,ref,paramanager.getintparaloc(1))
|
||||
else
|
||||
a_paramaddr_ref(list,ref,paramanager.getintparaloc(1));
|
||||
{ these functions get the pointer by value }
|
||||
a_param_ref(list,OS_ADDR,ref,paramanager.getintparaloc(1));
|
||||
a_call_name(list,incrfunc);
|
||||
end
|
||||
else
|
||||
@ -1882,7 +1880,11 @@ finalization
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.94 2003-05-01 12:23:46 jonas
|
||||
Revision 1.95 2003-05-09 17:47:02 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.94 2003/05/01 12:23:46 jonas
|
||||
* fix for op_reg_reg_reg in case the destination is the same as the first
|
||||
source register
|
||||
|
||||
|
@ -1058,84 +1058,102 @@ implementation
|
||||
|
||||
function compare_paras(paralist1,paralist2 : TLinkedList; acp : compare_type;allowdefaults:boolean):tequaltype;
|
||||
var
|
||||
def1,def2 : TParaItem;
|
||||
currpara1,
|
||||
currpara2 : TParaItem;
|
||||
eq,lowesteq : tequaltype;
|
||||
hpd : tprocdef;
|
||||
hpd : tprocdef;
|
||||
convtype : tconverttype;
|
||||
begin
|
||||
compare_paras:=te_incompatible;
|
||||
{ we need to parse the list from left-right so the
|
||||
not-default parameters are checked first }
|
||||
lowesteq:=high(tequaltype);
|
||||
def1:=TParaItem(paralist1.first);
|
||||
def2:=TParaItem(paralist2.first);
|
||||
while (assigned(def1)) and (assigned(def2)) do
|
||||
currpara1:=TParaItem(paralist1.first);
|
||||
currpara2:=TParaItem(paralist2.first);
|
||||
while (assigned(currpara1)) and (assigned(currpara2)) do
|
||||
begin
|
||||
eq:=te_incompatible;
|
||||
|
||||
{ Unique types must match exact }
|
||||
if ((df_unique in def1.paratype.def.defoptions) or (df_unique in def2.paratype.def.defoptions)) and
|
||||
(def1.paratype.def<>def2.paratype.def) then
|
||||
if ((df_unique in currpara1.paratype.def.defoptions) or (df_unique in currpara2.paratype.def.defoptions)) and
|
||||
(currpara1.paratype.def<>currpara2.paratype.def) then
|
||||
exit;
|
||||
|
||||
case acp of
|
||||
cp_value_equal_const :
|
||||
{ Handle hidden parameters separately, because self is
|
||||
defined as voidpointer for methodpointers }
|
||||
if (currpara1.is_hidden or
|
||||
currpara2.is_hidden) then
|
||||
begin
|
||||
eq:=te_equal;
|
||||
if not(vo_is_self in tvarsym(currpara1.parasym).varoptions) and
|
||||
not(vo_is_self in tvarsym(currpara2.parasym).varoptions) then
|
||||
begin
|
||||
if (
|
||||
(def1.paratyp<>def2.paratyp) and
|
||||
((def1.paratyp in [vs_var,vs_out]) or
|
||||
(def2.paratyp in [vs_var,vs_out]))
|
||||
) then
|
||||
exit;
|
||||
eq:=compare_defs(def1.paratype.def,def2.paratype.def,nothingn);
|
||||
if (currpara1.paratyp<>currpara2.paratyp) then
|
||||
exit;
|
||||
eq:=compare_defs(currpara1.paratype.def,currpara2.paratype.def,nothingn);
|
||||
end;
|
||||
cp_all :
|
||||
begin
|
||||
if (def1.paratyp<>def2.paratyp) then
|
||||
exit;
|
||||
eq:=compare_defs(def1.paratype.def,def2.paratype.def,nothingn);
|
||||
end;
|
||||
cp_procvar :
|
||||
begin
|
||||
if (def1.paratyp<>def2.paratyp) then
|
||||
exit;
|
||||
eq:=compare_defs_ext(def1.paratype.def,def2.paratype.def,nothingn,
|
||||
false,true,convtype,hpd);
|
||||
if (eq>te_incompatible) and
|
||||
(eq<te_equal) and
|
||||
not(
|
||||
(convtype in [tc_equal,tc_int_2_int]) and
|
||||
(def1.paratype.def.size=def2.paratype.def.size)
|
||||
end
|
||||
else
|
||||
begin
|
||||
case acp of
|
||||
cp_value_equal_const :
|
||||
begin
|
||||
if (
|
||||
(currpara1.paratyp<>currpara2.paratyp) and
|
||||
((currpara1.paratyp in [vs_var,vs_out]) or
|
||||
(currpara2.paratyp in [vs_var,vs_out]))
|
||||
) then
|
||||
begin
|
||||
eq:=te_incompatible;
|
||||
end;
|
||||
exit;
|
||||
eq:=compare_defs(currpara1.paratype.def,currpara2.paratype.def,nothingn);
|
||||
end;
|
||||
cp_all :
|
||||
begin
|
||||
if (currpara1.paratyp<>currpara2.paratyp) then
|
||||
exit;
|
||||
eq:=compare_defs(currpara1.paratype.def,currpara2.paratype.def,nothingn);
|
||||
end;
|
||||
cp_procvar :
|
||||
begin
|
||||
if (currpara1.paratyp<>currpara2.paratyp) then
|
||||
exit;
|
||||
eq:=compare_defs_ext(currpara1.paratype.def,currpara2.paratype.def,nothingn,
|
||||
false,true,convtype,hpd);
|
||||
if (eq>te_incompatible) and
|
||||
(eq<te_equal) and
|
||||
not(
|
||||
(convtype in [tc_equal,tc_int_2_int]) and
|
||||
(currpara1.paratype.def.size=currpara2.paratype.def.size)
|
||||
) then
|
||||
begin
|
||||
eq:=te_incompatible;
|
||||
end;
|
||||
end;
|
||||
else
|
||||
eq:=compare_defs(currpara1.paratype.def,currpara2.paratype.def,nothingn);
|
||||
end;
|
||||
else
|
||||
eq:=compare_defs(def1.paratype.def,def2.paratype.def,nothingn);
|
||||
end;
|
||||
end;
|
||||
{ check type }
|
||||
if eq=te_incompatible then
|
||||
exit;
|
||||
if eq<lowesteq then
|
||||
lowesteq:=eq;
|
||||
{ also check default value if both have it declared }
|
||||
if assigned(def1.defaultvalue) and
|
||||
assigned(def2.defaultvalue) then
|
||||
if assigned(currpara1.defaultvalue) and
|
||||
assigned(currpara2.defaultvalue) then
|
||||
begin
|
||||
if not equal_constsym(tconstsym(def1.defaultvalue),tconstsym(def2.defaultvalue)) then
|
||||
if not equal_constsym(tconstsym(currpara1.defaultvalue),tconstsym(currpara2.defaultvalue)) then
|
||||
exit;
|
||||
end;
|
||||
def1:=TParaItem(def1.next);
|
||||
def2:=TParaItem(def2.next);
|
||||
currpara1:=TParaItem(currpara1.next);
|
||||
currpara2:=TParaItem(currpara2.next);
|
||||
end;
|
||||
{ when both lists are empty then the parameters are equal. Also
|
||||
when one list is empty and the other has a parameter with default
|
||||
value assigned then the parameters are also equal }
|
||||
if ((def1=nil) and (def2=nil)) or
|
||||
if ((currpara1=nil) and (currpara2=nil)) or
|
||||
(allowdefaults and
|
||||
((assigned(def1) and assigned(def1.defaultvalue)) or
|
||||
(assigned(def2) and assigned(def2.defaultvalue)))) then
|
||||
((assigned(currpara1) and assigned(currpara1.defaultvalue)) or
|
||||
(assigned(currpara2) and assigned(currpara2.defaultvalue)))) then
|
||||
compare_paras:=lowesteq;
|
||||
end;
|
||||
|
||||
@ -1193,7 +1211,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.23 2003-04-23 20:16:04 peter
|
||||
Revision 1.24 2003-05-09 17:47:02 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.23 2003/04/23 20:16:04 peter
|
||||
+ added currency support based on int64
|
||||
+ is_64bit for use in cg units instead of is_64bitint
|
||||
* removed cgmessage from n386add, replace with internalerrors
|
||||
|
@ -59,7 +59,6 @@
|
||||
|
||||
{$ifdef powerpc}
|
||||
{$define callparatemp}
|
||||
{$define vs_hidden_self}
|
||||
{$endif powerpc}
|
||||
|
||||
{ FPU Emulator support }
|
||||
@ -74,7 +73,11 @@
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.18 2003-04-30 09:42:42 florian
|
||||
Revision 1.19 2003-05-09 17:47:02 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.18 2003/04/30 09:42:42 florian
|
||||
+ first changes to make self a hidden parameter
|
||||
|
||||
Revision 1.17 2003/04/24 22:29:57 florian
|
||||
|
@ -440,8 +440,8 @@ implementation
|
||||
|
||||
{ the nil as symtable signs firstcalln that this is
|
||||
an overloaded operator }
|
||||
inc(overloaded_operators[optoken].refs);
|
||||
ht:=ccallnode.create(nil,overloaded_operators[optoken],nil,nil);
|
||||
inc(tcallnode(ht).symtableprocentry.refs);
|
||||
{ we already know the procdef to use for equal, so it can
|
||||
skip the overload choosing in callnode.det_resulttype }
|
||||
if assigned(operpd) then
|
||||
@ -859,11 +859,6 @@ implementation
|
||||
CGMessagePos(hp.fileinfo,type_e_no_assign_to_addr);
|
||||
exit;
|
||||
end;
|
||||
selfn :
|
||||
begin
|
||||
valid_for_assign:=true;
|
||||
exit;
|
||||
end;
|
||||
calln :
|
||||
begin
|
||||
{ check return type }
|
||||
@ -998,7 +993,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.62 2003-04-27 11:21:32 peter
|
||||
Revision 1.63 2003-05-09 17:47:02 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.62 2003/04/27 11:21:32 peter
|
||||
* aktprocdef renamed to current_procdef
|
||||
* procinfo renamed to current_procinfo
|
||||
* procinfo will now be stored in current_module so it can be
|
||||
|
@ -190,6 +190,8 @@ begin
|
||||
3. global libary dir
|
||||
4. exe path of the compiler }
|
||||
found:=FindFile(s,'.'+source_info.DirSep,foundfile);
|
||||
if (not found) and (current_module.outputpath^<>'') then
|
||||
found:=FindFile(s,current_module.outputpath^,foundfile);
|
||||
if (not found) then
|
||||
found:=current_module.locallibrarysearchpath.FindFile(s,foundfile);
|
||||
if (not found) then
|
||||
@ -654,7 +656,11 @@ initialization
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.35 2003-04-26 09:16:07 peter
|
||||
Revision 1.36 2003-05-09 17:47:02 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.35 2003/04/26 09:16:07 peter
|
||||
* .o files belonging to the unit are first searched in the same dir
|
||||
as the .ppu
|
||||
|
||||
|
@ -65,6 +65,8 @@ interface
|
||||
{$ifdef EXTDEBUG}
|
||||
procedure candidates_dump_info(lvl:longint;procs:pcandidate);
|
||||
{$endif EXTDEBUG}
|
||||
function gen_self_tree:tnode;
|
||||
function gen_vmt_tree:tnode;
|
||||
procedure bind_paraitem;
|
||||
public
|
||||
{ the symbol containing the definition of the procedure }
|
||||
@ -89,6 +91,7 @@ interface
|
||||
{ only the processor specific nodes need to override this }
|
||||
{ constructor }
|
||||
constructor create(l:tnode; v : tprocsym;st : tsymtable; mp : tnode);virtual;
|
||||
constructor create_procvar(l,r:tnode);
|
||||
constructor createintern(const name: string; params: tnode);
|
||||
constructor createinternres(const name: string; params: tnode; const res: ttype);
|
||||
constructor createinternreturn(const name: string; params: tnode; returnnode : tnode);
|
||||
@ -112,7 +115,6 @@ interface
|
||||
function track_state_pass(exec_known:boolean):boolean;override;
|
||||
{$endif state_tracking}
|
||||
function docompare(p: tnode): boolean; override;
|
||||
procedure set_procvar(procvar:tnode);
|
||||
procedure printnodedata(var t:text);override;
|
||||
private
|
||||
{$ifdef callparatemp}
|
||||
@ -888,6 +890,20 @@ type
|
||||
end;
|
||||
|
||||
|
||||
constructor tcallnode.create_procvar(l,r:tnode);
|
||||
begin
|
||||
inherited create(calln,l,r);
|
||||
symtableprocentry:=nil;
|
||||
symtableproc:=nil;
|
||||
include(flags,nf_return_value_used);
|
||||
methodpointer:=nil;
|
||||
procdefinition:=nil;
|
||||
restypeset:=false;
|
||||
funcretnode:=nil;
|
||||
paralength:=-1;
|
||||
end;
|
||||
|
||||
|
||||
constructor tcallnode.createintern(const name: string; params: tnode);
|
||||
var
|
||||
srsym: tsym;
|
||||
@ -985,12 +1001,6 @@ type
|
||||
end;
|
||||
|
||||
|
||||
procedure tcallnode.set_procvar(procvar:tnode);
|
||||
begin
|
||||
right:=procvar;
|
||||
end;
|
||||
|
||||
|
||||
function tcallnode.getcopy : tnode;
|
||||
var
|
||||
n : tcallnode;
|
||||
@ -1070,7 +1080,7 @@ type
|
||||
}
|
||||
if assigned(methodpointer) and assigned(methodpointer.resulttype.def) then
|
||||
if (methodpointer.resulttype.def.deftype = classrefdef) and
|
||||
(methodpointer.nodetype in [typen,loadvmtn]) then
|
||||
(methodpointer.nodetype in [typen,loadvmtaddrn]) then
|
||||
begin
|
||||
if (tclassrefdef(methodpointer.resulttype.def).pointertype.def.deftype = objectdef) then
|
||||
objectdf := tobjectdef(tclassrefdef(methodpointer.resulttype.def).pointertype.def);
|
||||
@ -1573,6 +1583,131 @@ type
|
||||
end;
|
||||
|
||||
|
||||
function tcallnode.gen_self_tree:tnode;
|
||||
var
|
||||
selftree : tnode;
|
||||
begin
|
||||
selftree:=nil;
|
||||
|
||||
{ constructors }
|
||||
if (procdefinition.proctypeoption=potype_constructor) then
|
||||
begin
|
||||
if not(nf_inherited in flags) then
|
||||
begin
|
||||
{ push 0 as self when allocation is needed }
|
||||
if (methodpointer.resulttype.def.deftype=classrefdef) or
|
||||
(nf_new_call in flags) then
|
||||
selftree:=cpointerconstnode.create(0,voidpointertype)
|
||||
else
|
||||
begin
|
||||
if methodpointer.nodetype=typen then
|
||||
selftree:=load_self
|
||||
else
|
||||
selftree:=methodpointer.getcopy;
|
||||
end;
|
||||
end
|
||||
else
|
||||
selftree:=load_self;
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ Calling a static/class method from a non-static/class method,
|
||||
then we need to load self with the VMT }
|
||||
if (
|
||||
(po_classmethod in procdefinition.procoptions) and
|
||||
not(assigned(current_procdef) and
|
||||
(po_classmethod in current_procdef.procoptions))
|
||||
) or
|
||||
(
|
||||
(po_staticmethod in procdefinition.procoptions) and
|
||||
not(assigned(current_procdef) and
|
||||
(po_staticmethod in current_procdef.procoptions))
|
||||
) then
|
||||
begin
|
||||
if (procdefinition.deftype<>procdef) then
|
||||
internalerror(200305062);
|
||||
if (oo_has_vmt in tprocdef(procdefinition)._class.objectoptions) then
|
||||
begin
|
||||
if methodpointer.resulttype.def.deftype=classrefdef then
|
||||
selftree:=methodpointer.getcopy
|
||||
else
|
||||
selftree:=cloadvmtaddrnode.create(methodpointer.getcopy);
|
||||
end
|
||||
else
|
||||
selftree:=cpointerconstnode.create(0,voidpointertype);
|
||||
end
|
||||
else
|
||||
begin
|
||||
if methodpointer.nodetype=typen then
|
||||
selftree:=load_self
|
||||
else
|
||||
selftree:=methodpointer.getcopy;
|
||||
end;
|
||||
end;
|
||||
result:=selftree;
|
||||
end;
|
||||
|
||||
|
||||
function tcallnode.gen_vmt_tree:tnode;
|
||||
var
|
||||
vmttree : tnode;
|
||||
begin
|
||||
vmttree:=nil;
|
||||
if not(procdefinition.proctypeoption in [potype_constructor,potype_destructor]) then
|
||||
internalerror(200305051);
|
||||
|
||||
{ inherited call, no create/destroy }
|
||||
if (nf_inherited in flags) then
|
||||
vmttree:=cpointerconstnode.create(0,voidpointertype)
|
||||
else
|
||||
{ constructor with extended syntax called from new }
|
||||
if (nf_new_call in flags) then
|
||||
vmttree:=cloadvmtaddrnode.create(ctypenode.create(methodpointer.resulttype))
|
||||
else
|
||||
{ destructor with extended syntax called from dispose }
|
||||
if (nf_dispose_call in flags) then
|
||||
vmttree:=cloadvmtaddrnode.create(methodpointer.getcopy)
|
||||
else
|
||||
if (methodpointer.resulttype.def.deftype=classrefdef) then
|
||||
begin
|
||||
{ constructor call via classreference => allocate memory }
|
||||
if (procdefinition.proctypeoption=potype_constructor) and
|
||||
is_class(tclassrefdef(methodpointer.resulttype.def).pointertype.def) then
|
||||
vmttree:=methodpointer.getcopy
|
||||
else
|
||||
vmttree:=cpointerconstnode.create(0,voidpointertype);
|
||||
end
|
||||
else
|
||||
{ class }
|
||||
if is_class(methodpointer.resulttype.def) then
|
||||
begin
|
||||
{ destructor: release instance, flag(vmt)=1
|
||||
constructor: direct call, do nothing, leave vmt=0 }
|
||||
if (procdefinition.proctypeoption=potype_destructor) then
|
||||
begin
|
||||
{ do not release when called from member function
|
||||
without specifying self explicit }
|
||||
if (nf_member_call in flags) then
|
||||
vmttree:=cpointerconstnode.create(0,voidpointertype)
|
||||
else
|
||||
vmttree:=cpointerconstnode.create(1,voidpointertype);
|
||||
end
|
||||
else
|
||||
vmttree:=cpointerconstnode.create(0,voidpointertype);
|
||||
end
|
||||
else
|
||||
{ object }
|
||||
begin
|
||||
{ destructor: direct call, no dispose, vmt=0
|
||||
constructor: initialize object, load vmt }
|
||||
if (procdefinition.proctypeoption=potype_constructor) then
|
||||
vmttree:=cloadvmtaddrnode.create(ctypenode.create(methodpointer.resulttype))
|
||||
else
|
||||
vmttree:=cpointerconstnode.create(0,voidpointertype);
|
||||
end;
|
||||
result:=vmttree;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcallnode.bind_paraitem;
|
||||
var
|
||||
@ -1636,7 +1771,21 @@ type
|
||||
internalerror(200304082);
|
||||
{ we need the information of the next parameter }
|
||||
hiddentree:=gen_high_tree(pt.left,is_open_string(tparaitem(currpara.previous).paratype.def));
|
||||
end;
|
||||
end
|
||||
else
|
||||
if vo_is_self in tvarsym(currpara.parasym).varoptions then
|
||||
begin
|
||||
{$warning todo methodpointer}
|
||||
if (right=nil) then
|
||||
hiddentree:=gen_self_tree
|
||||
else
|
||||
hiddentree:=cnothingnode.create;
|
||||
end
|
||||
else
|
||||
if vo_is_vmt in tvarsym(currpara.parasym).varoptions then
|
||||
begin
|
||||
hiddentree:=gen_vmt_tree;
|
||||
end;
|
||||
{ add the hidden parameter }
|
||||
if not assigned(hiddentree) then
|
||||
internalerror(200304073);
|
||||
@ -1767,13 +1916,8 @@ type
|
||||
(symtableprocentry.procdef_count=1) then
|
||||
begin
|
||||
hpt:=cloadnode.create(tprocsym(symtableprocentry),symtableproc);
|
||||
if (symtableprocentry.owner.symtabletype=objectsymtable) then
|
||||
begin
|
||||
if assigned(methodpointer) then
|
||||
tloadnode(hpt).set_mp(methodpointer.getcopy)
|
||||
else
|
||||
tloadnode(hpt).set_mp(cselfnode.create(tobjectdef(symtableprocentry.owner.defowner)));
|
||||
end;
|
||||
if assigned(methodpointer) then
|
||||
tloadnode(hpt).set_mp(methodpointer.getcopy);
|
||||
resulttypepass(hpt);
|
||||
result:=hpt;
|
||||
end
|
||||
@ -1920,7 +2064,7 @@ type
|
||||
{ direct call to inherited abstract method, then we
|
||||
can already give a error in the compiler instead
|
||||
of a runtime error }
|
||||
if (methodpointer.nodetype=typen) and
|
||||
if (nf_inherited in flags) and
|
||||
(po_abstractmethod in procdefinition.procoptions) then
|
||||
CGMessage(cg_e_cant_call_abstract_method);
|
||||
|
||||
@ -1928,13 +2072,13 @@ type
|
||||
{ called in a con- or destructor then a warning }
|
||||
{ will be made }
|
||||
{ con- and destructors need a pointer to the vmt }
|
||||
if (methodpointer.nodetype=typen) and
|
||||
if (nf_inherited in flags) and
|
||||
(procdefinition.proctypeoption in [potype_constructor,potype_destructor]) and
|
||||
is_object(methodpointer.resulttype.def) and
|
||||
not(current_procdef.proctypeoption in [potype_constructor,potype_destructor]) then
|
||||
CGMessage(cg_w_member_cd_call_from_method);
|
||||
|
||||
if not(methodpointer.nodetype in [typen,hnewn]) then
|
||||
if methodpointer.nodetype<>typen then
|
||||
begin
|
||||
hpt:=methodpointer;
|
||||
while assigned(hpt) and (hpt.nodetype in [subscriptn,vecn]) do
|
||||
@ -1968,12 +2112,39 @@ type
|
||||
(tloadnode(hpt).symtableentry.typ=varsym) then
|
||||
tvarsym(tloadnode(hpt).symtableentry).varstate:=vs_used;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ When this is method the methodpointer must be available }
|
||||
if procdefinition.owner.symtabletype=objectsymtable then
|
||||
internalerror(200305061);
|
||||
end;
|
||||
|
||||
{ bind paraitems to the callparanodes and insert hidden parameters }
|
||||
aktcallprocdef:=procdefinition;
|
||||
bind_paraitem;
|
||||
|
||||
{ methodpointer is only needed for virtual calls, and
|
||||
it should then be loaded with the VMT }
|
||||
if (po_virtualmethod in procdefinition.procoptions) and
|
||||
not(assigned(methodpointer) and
|
||||
(methodpointer.nodetype=typen)) then
|
||||
begin
|
||||
if not assigned(methodpointer) then
|
||||
internalerror(200305063);
|
||||
if (methodpointer.resulttype.def.deftype<>classrefdef) then
|
||||
begin
|
||||
methodpointer:=cloadvmtaddrnode.create(methodpointer);
|
||||
resulttypepass(methodpointer);
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ not needed anymore }
|
||||
methodpointer.free;
|
||||
methodpointer:=nil;
|
||||
end;
|
||||
|
||||
{ insert type conversions for parameters }
|
||||
if assigned(left) then
|
||||
tcallparanode(left).insert_typeconv(true);
|
||||
@ -2214,29 +2385,18 @@ type
|
||||
if (methodpointer<>nil) then
|
||||
begin
|
||||
if methodpointer.nodetype<>typen then
|
||||
firstpass(methodpointer);
|
||||
begin
|
||||
firstpass(methodpointer);
|
||||
registersfpu:=max(methodpointer.registersfpu,registersfpu);
|
||||
registers32:=max(methodpointer.registers32,registers32);
|
||||
{$ifdef SUPPORT_MMX }
|
||||
registersmmx:=max(methodpointer.registersmmx,registersmmx);
|
||||
{$endif SUPPORT_MMX}
|
||||
end;
|
||||
|
||||
{ if we are calling the constructor }
|
||||
if procdefinition.proctypeoption in [potype_constructor] then
|
||||
if procdefinition.proctypeoption=potype_constructor then
|
||||
verifyabstractcalls;
|
||||
|
||||
case methodpointer.nodetype of
|
||||
{ but only, if this is not a supporting node }
|
||||
typen: ;
|
||||
{ we need one register for new return value PM }
|
||||
hnewn : if registers32=0 then
|
||||
registers32:=1;
|
||||
else
|
||||
begin
|
||||
{ this is not a good reason to accept it in FPC if we produce
|
||||
wrong code for it !!! (PM) }
|
||||
registersfpu:=max(methodpointer.registersfpu,registersfpu);
|
||||
registers32:=max(methodpointer.registers32,registers32);
|
||||
{$ifdef SUPPORT_MMX }
|
||||
registersmmx:=max(methodpointer.registersmmx,registersmmx);
|
||||
{$endif SUPPORT_MMX}
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
if inlined then
|
||||
@ -2517,7 +2677,11 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.148 2003-05-05 14:53:16 peter
|
||||
Revision 1.149 2003-05-09 17:47:02 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.148 2003/05/05 14:53:16 peter
|
||||
* vs_hidden replaced by is_hidden boolean
|
||||
|
||||
Revision 1.147 2003/04/27 11:21:33 peter
|
||||
|
@ -40,10 +40,7 @@ interface
|
||||
end;
|
||||
|
||||
tcgcallnode = class(tcallnode)
|
||||
private
|
||||
function push_self_and_vmt(needvmtreg:boolean):tregister;
|
||||
protected
|
||||
// funcretref : treference;
|
||||
refcountedtemp : treference;
|
||||
procedure handle_return_value(inlined:boolean);
|
||||
{# This routine is used to push the current frame pointer
|
||||
@ -148,6 +145,45 @@ implementation
|
||||
else
|
||||
push_value_para(exprasmlist,left,calloption,para_offset,para_alignment,paraitem.paraloc);
|
||||
end
|
||||
{ hidden parameters }
|
||||
else if paraitem.is_hidden then
|
||||
begin
|
||||
{ don't push a node that already generated a pointer type
|
||||
by address for implicit hidden parameters }
|
||||
if (vo_is_funcret in tvarsym(paraitem.parasym).varoptions) or
|
||||
(not(left.resulttype.def.deftype in [pointerdef,classrefdef]) and
|
||||
paramanager.push_addr_param(paraitem.paratype.def,calloption)) then
|
||||
begin
|
||||
if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
|
||||
internalerror(200305071);
|
||||
|
||||
inc(pushedparasize,POINTER_SIZE);
|
||||
if calloption=pocall_inline then
|
||||
begin
|
||||
{$ifdef newra}
|
||||
tmpreg:=rg.getaddressregister(exprasmlist);
|
||||
{$else}
|
||||
tmpreg:=cg.get_scratch_reg_address(exprasmlist);
|
||||
{$endif}
|
||||
cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,tmpreg);
|
||||
reference_reset_base(href,current_procinfo.framepointer,para_offset-pushedparasize);
|
||||
cg.a_load_reg_ref(exprasmlist,OS_ADDR,tmpreg,href);
|
||||
{$ifdef newra}
|
||||
rg.ungetregisterint(exprasmlist,tmpreg);
|
||||
{$else}
|
||||
cg.free_scratch_reg(exprasmlist,tmpreg);
|
||||
{$endif}
|
||||
end
|
||||
else
|
||||
cg.a_paramaddr_ref(exprasmlist,left.location.reference,paraitem.paraloc);
|
||||
location_release(exprasmlist,left.location);
|
||||
end
|
||||
else
|
||||
begin
|
||||
push_value_para(exprasmlist,left,calloption,
|
||||
para_offset,para_alignment,paraitem.paraloc);
|
||||
end;
|
||||
end
|
||||
{ filter array of const c styled args }
|
||||
else if is_array_of_const(left.resulttype.def) and (nf_cargs in left.flags) then
|
||||
begin
|
||||
@ -210,7 +246,7 @@ implementation
|
||||
{ passing self to a var parameter is allowed in
|
||||
TP and delphi }
|
||||
if not((left.location.loc=LOC_CREFERENCE) and
|
||||
(left.nodetype=selfn)) then
|
||||
is_self_node(left)) then
|
||||
internalerror(200106041);
|
||||
end;
|
||||
if (paraitem.paratyp=vs_out) and
|
||||
@ -241,16 +277,13 @@ implementation
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ open array must always push the address, this is needed to
|
||||
also push addr of small open arrays and with cdecl functions (PFV) }
|
||||
if (
|
||||
assigned(paraitem.paratype.def) and
|
||||
(is_open_array(paraitem.paratype.def) or
|
||||
is_array_of_const(paraitem.paratype.def))
|
||||
) or
|
||||
(
|
||||
paramanager.push_addr_param(resulttype.def,calloption)
|
||||
) then
|
||||
{ don't push a node that already generated a pointer type
|
||||
by address for implicit hidden parameters }
|
||||
if (not(
|
||||
paraitem.is_hidden and
|
||||
(left.resulttype.def.deftype in [pointerdef,classrefdef])
|
||||
) and
|
||||
paramanager.push_addr_param(paraitem.paratype.def,calloption)) then
|
||||
begin
|
||||
if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
|
||||
begin
|
||||
@ -341,328 +374,6 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function tcgcallnode.push_self_and_vmt(needvmtreg:boolean):tregister;
|
||||
var
|
||||
href : treference;
|
||||
vmtloc,selfloc : tlocation;
|
||||
self_is_vmt,
|
||||
vmtrefaddr,
|
||||
selfrefaddr : boolean;
|
||||
|
||||
procedure selfloc_to_register;
|
||||
var
|
||||
hregister : tregister;
|
||||
begin
|
||||
case selfloc.loc of
|
||||
LOC_REGISTER :
|
||||
hregister:=selfloc.register;
|
||||
LOC_CREFERENCE,
|
||||
LOC_REFERENCE :
|
||||
begin
|
||||
hregister:=rg.getaddressregister(exprasmlist);
|
||||
if selfrefaddr then
|
||||
begin
|
||||
cg.a_loadaddr_ref_reg(exprasmlist,selfloc.reference,hregister);
|
||||
selfrefaddr:=false;
|
||||
end
|
||||
else
|
||||
cg.a_load_ref_reg(exprasmlist,OS_ADDR,selfloc.reference,hregister);
|
||||
reference_release(exprasmlist,selfloc.reference);
|
||||
end;
|
||||
else
|
||||
internalerror(200303269);
|
||||
end;
|
||||
location_reset(selfloc,LOC_REGISTER,OS_ADDR);
|
||||
selfloc.register:=hregister;
|
||||
end;
|
||||
|
||||
begin
|
||||
result.enum:=R_INTREGISTER;
|
||||
result.number:=NR_NO;
|
||||
location_reset(vmtloc,LOC_CONSTANT,OS_ADDR);
|
||||
location_reset(selfloc,LOC_CONSTANT,OS_ADDR);
|
||||
vmtrefaddr:=false;
|
||||
selfrefaddr:=false;
|
||||
self_is_vmt:=false;
|
||||
|
||||
{ generate fake methodpointer node for withsymtable }
|
||||
if (symtableproc.symtabletype=withsymtable) then
|
||||
begin
|
||||
methodpointer:=cnothingnode.create;
|
||||
methodpointer.resulttype:=twithnode(twithsymtable(symtableproc).withnode).left.resulttype;
|
||||
end;
|
||||
|
||||
if assigned(methodpointer) then
|
||||
begin
|
||||
case methodpointer.nodetype of
|
||||
typen:
|
||||
begin
|
||||
if (sp_static in symtableprocentry.symoptions) then
|
||||
begin
|
||||
self_is_vmt:=true;
|
||||
if (oo_has_vmt in tobjectdef(methodpointer.resulttype.def).objectoptions) then
|
||||
begin
|
||||
location_reset(vmtloc,LOC_REFERENCE,OS_NO);
|
||||
reference_reset_symbol(vmtloc.reference,objectlibrary.newasmsymboldata(tobjectdef(methodpointer.resulttype.def).vmt_mangledname),0);
|
||||
vmtrefaddr:=true;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ normal member call, load self. Not for classes
|
||||
when we call the constructor }
|
||||
if not(
|
||||
is_class(methodpointer.resulttype.def) and
|
||||
(procdefinition.proctypeoption=potype_constructor) and
|
||||
(current_procdef.proctypeoption<>potype_constructor)
|
||||
) then
|
||||
begin
|
||||
location_reset(selfloc,LOC_REGISTER,OS_ADDR);
|
||||
selfloc.register:=cg.g_load_self(exprasmlist);
|
||||
end;
|
||||
end;
|
||||
|
||||
if (procdefinition.proctypeoption in [potype_constructor,potype_destructor]) then
|
||||
begin
|
||||
if is_object(methodpointer.resulttype.def) then
|
||||
begin
|
||||
{ reset self when calling constructor from destructor }
|
||||
if (procdefinition.proctypeoption=potype_constructor) and
|
||||
assigned(current_procdef) and
|
||||
(current_procdef.proctypeoption=potype_destructor) then
|
||||
begin
|
||||
location_release(exprasmlist,selfloc);
|
||||
location_reset(selfloc,LOC_CONSTANT,OS_ADDR);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
hnewn:
|
||||
begin
|
||||
{ constructor with extended syntax called from new }
|
||||
{ vmt }
|
||||
location_reset(vmtloc,LOC_REFERENCE,OS_ADDR);
|
||||
reference_reset_symbol(vmtloc.reference,objectlibrary.newasmsymboldata(tobjectdef(methodpointer.resulttype.def).vmt_mangledname),0);
|
||||
vmtrefaddr:=true;
|
||||
end;
|
||||
hdisposen:
|
||||
begin
|
||||
{ destructor with extended syntax called from dispose }
|
||||
{ hdisposen always deliver LOC_REFERENCE }
|
||||
secondpass(methodpointer);
|
||||
{ vmt }
|
||||
location_reset(vmtloc,LOC_REFERENCE,OS_ADDR);
|
||||
reference_reset_symbol(vmtloc.reference,objectlibrary.newasmsymboldata(tobjectdef(methodpointer.resulttype.def).vmt_mangledname),0);
|
||||
vmtrefaddr:=true;
|
||||
{ self, load in register first when it requires a virtual call }
|
||||
location_reset(selfloc,LOC_REFERENCE,OS_ADDR);
|
||||
selfloc.reference:=methodpointer.location.reference;
|
||||
selfrefaddr:=true;
|
||||
end;
|
||||
else
|
||||
begin
|
||||
{ call to an instance member }
|
||||
if (symtableproc.symtabletype<>withsymtable) then
|
||||
begin
|
||||
secondpass(methodpointer);
|
||||
case methodpointer.location.loc of
|
||||
LOC_CREGISTER,
|
||||
LOC_REGISTER:
|
||||
begin
|
||||
location_reset(selfloc,LOC_REGISTER,OS_ADDR);
|
||||
selfloc.register:=methodpointer.location.register;
|
||||
end;
|
||||
LOC_CREFERENCE,
|
||||
LOC_REFERENCE :
|
||||
begin
|
||||
location_reset(selfloc,LOC_REFERENCE,OS_ADDR);
|
||||
selfloc.reference:=methodpointer.location.reference;
|
||||
if (methodpointer.resulttype.def.deftype<>classrefdef) and
|
||||
not(is_class_or_interface(methodpointer.resulttype.def)) then
|
||||
selfrefaddr:=true;
|
||||
end;
|
||||
else
|
||||
internalerror(200303212);
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
location_reset(selfloc,LOC_REFERENCE,OS_ADDR);
|
||||
selfloc.reference:=twithnode(twithsymtable(symtableproc).withnode).withreference;
|
||||
if (nf_islocal in twithnode(twithsymtable(symtableproc).withnode).flags) and
|
||||
(twithsymtable(symtableproc).direct_with) and
|
||||
not(is_class_or_interface(twithnode(twithsymtable(symtableproc).withnode).left.resulttype.def)) then
|
||||
selfrefaddr:=true;
|
||||
end;
|
||||
|
||||
if (po_staticmethod in procdefinition.procoptions) or
|
||||
(po_classmethod in procdefinition.procoptions) then
|
||||
begin
|
||||
self_is_vmt:=true;
|
||||
{ classref are already loaded with VMT }
|
||||
if (methodpointer.resulttype.def.deftype=classrefdef) then
|
||||
location_copy(vmtloc,selfloc)
|
||||
else
|
||||
begin
|
||||
if (oo_has_vmt in tprocdef(procdefinition)._class.objectoptions) then
|
||||
begin
|
||||
{ load VMT from passed self }
|
||||
selfloc_to_register;
|
||||
cg.g_maybe_testself(exprasmlist,selfloc.register);
|
||||
location_copy(vmtloc,selfloc);
|
||||
reference_reset_base(href,vmtloc.register,tprocdef(procdefinition)._class.vmt_offset);
|
||||
cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,vmtloc.register);
|
||||
end;
|
||||
end;
|
||||
{ reset self }
|
||||
location_reset(selfloc,LOC_CONSTANT,OS_ADDR);
|
||||
end;
|
||||
|
||||
if (procdefinition.proctypeoption in [potype_constructor,potype_destructor]) then
|
||||
begin
|
||||
{ constructor call via classreference => allocate memory }
|
||||
if (methodpointer.resulttype.def.deftype=classrefdef) then
|
||||
begin
|
||||
if (procdefinition.proctypeoption=potype_constructor) and
|
||||
is_class(tclassrefdef(methodpointer.resulttype.def).pointertype.def) then
|
||||
begin
|
||||
self_is_vmt:=true;
|
||||
{ vmt load from provided methodpointer that
|
||||
was already loaded in selfloc }
|
||||
location_copy(vmtloc,selfloc);
|
||||
{ reset self }
|
||||
location_reset(selfloc,LOC_CONSTANT,OS_ADDR);
|
||||
end;
|
||||
end
|
||||
else
|
||||
{ class }
|
||||
if is_class(methodpointer.resulttype.def) then
|
||||
begin
|
||||
{ destructor: release instance, flag(vmt)=1
|
||||
constructor: direct call, do nothing, leave vmt=0 }
|
||||
if (procdefinition.proctypeoption=potype_destructor) then
|
||||
begin
|
||||
{ flag 1 for destructor: remove data }
|
||||
location_reset(vmtloc,LOC_CONSTANT,OS_ADDR);
|
||||
vmtloc.value:=1;
|
||||
end;
|
||||
end
|
||||
else
|
||||
{ object }
|
||||
begin
|
||||
{ destructor: direct call, no dispose, vmt=0
|
||||
constructor: initialize object, load vmt }
|
||||
if (procdefinition.proctypeoption=potype_constructor) then
|
||||
begin
|
||||
{ vmt }
|
||||
location_reset(vmtloc,LOC_REFERENCE,OS_ADDR);
|
||||
reference_reset_symbol(vmtloc.reference,objectlibrary.newasmsymboldata(
|
||||
tobjectdef(methodpointer.resulttype.def).vmt_mangledname),0);
|
||||
vmtrefaddr:=true;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else
|
||||
{ No methodpointer }
|
||||
begin
|
||||
if (po_staticmethod in procdefinition.procoptions) or
|
||||
(po_classmethod in procdefinition.procoptions) then
|
||||
begin
|
||||
self_is_vmt:=true;
|
||||
{ Load VMT from self? }
|
||||
if (
|
||||
(po_classmethod in procdefinition.procoptions) and
|
||||
not(assigned(current_procdef) and
|
||||
(po_classmethod in current_procdef.procoptions))
|
||||
) or
|
||||
(
|
||||
(po_staticmethod in procdefinition.procoptions) and
|
||||
not(assigned(current_procdef) and
|
||||
(po_staticmethod in current_procdef.procoptions))
|
||||
) then
|
||||
begin
|
||||
if (oo_has_vmt in tprocdef(procdefinition)._class.objectoptions) then
|
||||
begin
|
||||
{ load vmt from self passed to the current method }
|
||||
location_reset(vmtloc,LOC_REGISTER,OS_ADDR);
|
||||
vmtloc.register:=cg.g_load_self(exprasmlist);
|
||||
cg.g_maybe_testself(exprasmlist,vmtloc.register);
|
||||
reference_reset_base(href,vmtloc.register,tprocdef(procdefinition)._class.vmt_offset);
|
||||
cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,vmtloc.register);
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ self is already VMT }
|
||||
location_reset(vmtloc,LOC_REGISTER,OS_ADDR);
|
||||
vmtloc.register:=cg.g_load_self(exprasmlist);
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ member call, load self }
|
||||
location_reset(selfloc,LOC_REGISTER,OS_ADDR);
|
||||
selfloc.register:=cg.g_load_self(exprasmlist);
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Do we need to push the VMT as self for
|
||||
class methods and static methods? }
|
||||
if self_is_vmt then
|
||||
begin
|
||||
location_release(exprasmlist,selfloc);
|
||||
location_copy(selfloc,vmtloc);
|
||||
selfrefaddr:=vmtrefaddr;
|
||||
end;
|
||||
|
||||
{ when we need the vmt in a register then we already
|
||||
load self in a register so it can generate optimized code }
|
||||
if needvmtreg then
|
||||
selfloc_to_register;
|
||||
|
||||
{ constructor/destructor need vmt }
|
||||
if (procdefinition.proctypeoption in [potype_constructor,potype_destructor]) then
|
||||
begin
|
||||
if vmtrefaddr then
|
||||
cg.a_paramaddr_ref(exprasmlist,vmtloc.reference,paramanager.getintparaloc(2))
|
||||
else
|
||||
cg.a_param_loc(exprasmlist,vmtloc,paramanager.getintparaloc(2));
|
||||
end;
|
||||
if not self_is_vmt then
|
||||
location_release(exprasmlist,vmtloc);
|
||||
|
||||
{ push self }
|
||||
if selfrefaddr then
|
||||
cg.a_paramaddr_ref(exprasmlist,selfloc.reference,paramanager.getintparaloc(1))
|
||||
else
|
||||
cg.a_param_loc(exprasmlist,selfloc,paramanager.getintparaloc(1));
|
||||
|
||||
if needvmtreg then
|
||||
begin
|
||||
{ self should already be loaded in a register }
|
||||
if selfloc.register.number=NR_NO then
|
||||
internalerror(2003032611);
|
||||
|
||||
{ load vmt from self, this is already done
|
||||
for static/class methods }
|
||||
if not self_is_vmt then
|
||||
begin
|
||||
cg.g_maybe_testself(exprasmlist,selfloc.register);
|
||||
{ this is one point where we need vmt_offset (PM) }
|
||||
reference_reset_base(href,selfloc.register,tprocdef(procdefinition)._class.vmt_offset);
|
||||
cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,selfloc.register);
|
||||
end;
|
||||
|
||||
result:=selfloc.register;
|
||||
end
|
||||
else
|
||||
location_release(exprasmlist,selfloc);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgcallnode.push_framepointer;
|
||||
var
|
||||
href : treference;
|
||||
@ -866,7 +577,6 @@ implementation
|
||||
href : treference;
|
||||
hp : tnode;
|
||||
pp : tcallparanode;
|
||||
virtual_vmt_call,
|
||||
inlined : boolean;
|
||||
inlinecode : tprocinlinenode;
|
||||
store_parast_fixup,
|
||||
@ -875,8 +585,8 @@ implementation
|
||||
pop_size : longint;
|
||||
returnref,
|
||||
pararef : treference;
|
||||
accreg,
|
||||
vmtreg : tregister;
|
||||
vmtreg,
|
||||
accreg : tregister;
|
||||
oldaktcallnode : tcallnode;
|
||||
begin
|
||||
iolabel:=nil;
|
||||
@ -1022,18 +732,6 @@ implementation
|
||||
if inlined or
|
||||
(right=nil) then
|
||||
begin
|
||||
{ Virtual function call through VMT? }
|
||||
vmtreg.enum:=R_INTREGISTER;
|
||||
vmtreg.number:=NR_NO;
|
||||
virtual_vmt_call:=(po_virtualmethod in procdefinition.procoptions) and
|
||||
not(assigned(methodpointer) and
|
||||
(methodpointer.nodetype=typen));
|
||||
|
||||
{ push self/vmt for methods }
|
||||
if assigned(symtableproc) and
|
||||
(symtableproc.symtabletype in [withsymtable,objectsymtable]) then
|
||||
vmtreg:=push_self_and_vmt(virtual_vmt_call);
|
||||
|
||||
{ push base pointer ?}
|
||||
{ never when inlining, since if necessary, the base pointer }
|
||||
{ can/will be gottten from the current procedure's symtable }
|
||||
@ -1047,8 +745,13 @@ implementation
|
||||
rg.saveintregvars(exprasmlist,regs_to_push_int);
|
||||
rg.saveotherregvars(exprasmlist,regs_to_push_other);
|
||||
|
||||
if virtual_vmt_call then
|
||||
if (po_virtualmethod in procdefinition.procoptions) and
|
||||
assigned(methodpointer) then
|
||||
begin
|
||||
secondpass(methodpointer);
|
||||
location_force_reg(exprasmlist,methodpointer.location,OS_ADDR,false);
|
||||
vmtreg:=methodpointer.location.register;
|
||||
|
||||
{ virtual methods require an index }
|
||||
if tprocdef(procdefinition).extnumber=-1 then
|
||||
internalerror(200304021);
|
||||
@ -1067,7 +770,7 @@ implementation
|
||||
cg.a_call_ref(exprasmlist,href);
|
||||
|
||||
{ release self }
|
||||
rg.ungetregisterint(exprasmlist,vmtreg);
|
||||
rg.ungetaddressregister(exprasmlist,vmtreg);
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -1133,6 +836,11 @@ implementation
|
||||
begin
|
||||
{ the old pop_size was already included in pushedparasize }
|
||||
pop_size:=pushedparasize;
|
||||
{ for Cdecl functions we don't need to pop the funcret when it
|
||||
was pushed by para }
|
||||
if (procdefinition.proccalloption in [pocall_cdecl,pocall_cppdecl]) and
|
||||
paramanager.ret_in_param(procdefinition.rettype.def,procdefinition.proccalloption) then
|
||||
dec(pop_size,POINTER_SIZE);
|
||||
end;
|
||||
|
||||
{ Remove parameters/alignment from the stack }
|
||||
@ -1437,7 +1145,11 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.58 2003-05-05 14:53:16 peter
|
||||
Revision 1.59 2003-05-09 17:47:02 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.58 2003/05/05 14:53:16 peter
|
||||
* vs_hidden replaced by is_hidden boolean
|
||||
|
||||
Revision 1.57 2003/04/30 20:53:32 florian
|
||||
|
@ -57,7 +57,7 @@ implementation
|
||||
symconst,symdef,defutil,symsym,
|
||||
aasmbase,aasmtai,aasmcpu,
|
||||
cginfo,cgbase,pass_1,pass_2,
|
||||
cpubase,paramgr,
|
||||
cpuinfo,cpubase,paramgr,
|
||||
nbas,ncon,ncal,ncnv,nld,
|
||||
tgobj,ncgutil,cgobj,rgobj,rgcpu
|
||||
{$ifndef cpu64bit}
|
||||
@ -420,7 +420,7 @@ implementation
|
||||
addvalue,tcallparanode(left).left.location)
|
||||
else
|
||||
cg.a_op_const_loc(exprasmlist,addsubop[inlinenumber],
|
||||
addvalue,tcallparanode(left).left.location);
|
||||
aword(addvalue),tcallparanode(left).left.location);
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -682,7 +682,11 @@ end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.29 2003-05-01 12:27:08 jonas
|
||||
Revision 1.30 2003-05-09 17:47:02 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.29 2003/05/01 12:27:08 jonas
|
||||
* fixed include/exclude for normalsets
|
||||
|
||||
Revision 1.28 2003/04/27 11:21:33 peter
|
||||
|
@ -34,15 +34,7 @@ interface
|
||||
node,nmem;
|
||||
|
||||
type
|
||||
tcgloadvmtnode = class(tloadvmtnode)
|
||||
procedure pass_2;override;
|
||||
end;
|
||||
|
||||
tcghnewnode = class(thnewnode)
|
||||
procedure pass_2;override;
|
||||
end;
|
||||
|
||||
tcghdisposenode = class(thdisposenode)
|
||||
tcgloadvmtaddrnode = class(tloadvmtaddrnode)
|
||||
procedure pass_2;override;
|
||||
end;
|
||||
|
||||
@ -62,10 +54,6 @@ interface
|
||||
procedure pass_2;override;
|
||||
end;
|
||||
|
||||
tcgselfnode = class(tselfnode)
|
||||
procedure pass_2;override;
|
||||
end;
|
||||
|
||||
tcgwithnode = class(twithnode)
|
||||
procedure pass_2;override;
|
||||
end;
|
||||
@ -113,67 +101,68 @@ implementation
|
||||
TCGLOADNODE
|
||||
*****************************************************************************}
|
||||
|
||||
procedure tcgloadvmtnode.pass_2;
|
||||
procedure tcgloadvmtaddrnode.pass_2;
|
||||
var
|
||||
href : treference;
|
||||
|
||||
begin
|
||||
location_reset(location,LOC_REGISTER,OS_ADDR);
|
||||
location.register:=rg.getaddressregister(exprasmlist);
|
||||
{ on 80386, LEA is the same as mov imm32 }
|
||||
reference_reset_symbol(href,
|
||||
objectlibrary.newasmsymboldata(tobjectdef(tclassrefdef(resulttype.def).pointertype.def).vmt_mangledname),0);
|
||||
cg.a_loadaddr_ref_reg(exprasmlist,href,location.register);
|
||||
end;
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
TCGHNEWNODE
|
||||
*****************************************************************************}
|
||||
|
||||
procedure tcghnewnode.pass_2;
|
||||
begin
|
||||
location_reset(location,LOC_VOID,OS_NO);
|
||||
{ completely resolved in first pass now }
|
||||
end;
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
TCGHDISPOSENODE
|
||||
*****************************************************************************}
|
||||
|
||||
procedure tcghdisposenode.pass_2;
|
||||
begin
|
||||
location_reset(location,LOC_REFERENCE,def_cgsize(resulttype.def));
|
||||
|
||||
secondpass(left);
|
||||
if codegenerror then
|
||||
exit;
|
||||
|
||||
case left.location.loc of
|
||||
LOC_REGISTER:
|
||||
begin
|
||||
if not rg.isaddressregister(left.location.register) then
|
||||
begin
|
||||
location_release(exprasmlist,left.location);
|
||||
location.reference.base := rg.getaddressregister(exprasmlist);
|
||||
cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.register,
|
||||
location.reference.base);
|
||||
end
|
||||
else
|
||||
location.reference.base := left.location.register;
|
||||
end;
|
||||
LOC_CREGISTER,
|
||||
LOC_CREFERENCE,
|
||||
LOC_REFERENCE:
|
||||
begin
|
||||
location_release(exprasmlist,left.location);
|
||||
location.reference.base:=rg.getaddressregister(exprasmlist);
|
||||
cg.a_load_loc_reg(exprasmlist,left.location,location.reference.base);
|
||||
end;
|
||||
if (left.nodetype<>typen) then
|
||||
begin
|
||||
{ left contains self, load vmt from self }
|
||||
secondpass(left);
|
||||
if is_object(left.resulttype.def) then
|
||||
begin
|
||||
case left.location.loc of
|
||||
LOC_CREFERENCE,
|
||||
LOC_REFERENCE:
|
||||
begin
|
||||
location_release(exprasmlist,left.location);
|
||||
reference_reset_base(href,rg.getaddressregister(exprasmlist),tobjectdef(left.resulttype.def).vmt_offset);
|
||||
cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,href.base);
|
||||
end;
|
||||
else
|
||||
internalerror(200305056);
|
||||
end;
|
||||
end
|
||||
else
|
||||
internalerror(2002032217);
|
||||
end;
|
||||
begin
|
||||
case left.location.loc of
|
||||
LOC_REGISTER:
|
||||
begin
|
||||
if not rg.isaddressregister(left.location.register) then
|
||||
begin
|
||||
location_release(exprasmlist,left.location);
|
||||
reference_reset_base(href,rg.getaddressregister(exprasmlist),tobjectdef(left.resulttype.def).vmt_offset);
|
||||
cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.register,href.base);
|
||||
end
|
||||
else
|
||||
reference_reset_base(href,left.location.register,tobjectdef(left.resulttype.def).vmt_offset);
|
||||
end;
|
||||
LOC_CREGISTER,
|
||||
LOC_CREFERENCE,
|
||||
LOC_REFERENCE:
|
||||
begin
|
||||
location_release(exprasmlist,left.location);
|
||||
reference_reset_base(href,rg.getaddressregister(exprasmlist),tobjectdef(left.resulttype.def).vmt_offset);
|
||||
cg.a_load_loc_reg(exprasmlist,left.location,href.base);
|
||||
end;
|
||||
else
|
||||
internalerror(200305057);
|
||||
end;
|
||||
end;
|
||||
reference_release(exprasmlist,href);
|
||||
location.register:=rg.getaddressregister(exprasmlist);
|
||||
cg.g_maybe_testself(exprasmlist,href.base);
|
||||
cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,location.register);
|
||||
end
|
||||
else
|
||||
begin
|
||||
reference_reset_symbol(href,
|
||||
objectlibrary.newasmsymboldata(tobjectdef(tclassrefdef(resulttype.def).pointertype.def).vmt_mangledname),0);
|
||||
location.register:=rg.getaddressregister(exprasmlist);
|
||||
cg.a_loadaddr_ref_reg(exprasmlist,href,location.register);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
@ -342,26 +331,6 @@ implementation
|
||||
location.size:=def_cgsize(resulttype.def);
|
||||
end;
|
||||
|
||||
{*****************************************************************************
|
||||
TCGSELFNODE
|
||||
*****************************************************************************}
|
||||
|
||||
procedure tcgselfnode.pass_2;
|
||||
begin
|
||||
if (resulttype.def.deftype=classrefdef) or
|
||||
(is_class(resulttype.def) or
|
||||
(po_staticmethod in current_procdef.procoptions)) then
|
||||
begin
|
||||
location_reset(location,LOC_REGISTER,OS_ADDR);
|
||||
location.register:=cg.g_load_self(exprasmlist);
|
||||
end
|
||||
else
|
||||
begin
|
||||
location_reset(location,LOC_CREFERENCE,OS_ADDR);
|
||||
location.reference.base:=cg.g_load_self(exprasmlist);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
TCGWITHNODE
|
||||
@ -933,20 +902,21 @@ implementation
|
||||
|
||||
|
||||
begin
|
||||
cloadvmtnode:=tcgloadvmtnode;
|
||||
chnewnode:=tcghnewnode;
|
||||
chdisposenode:=tcghdisposenode;
|
||||
cloadvmtaddrnode:=tcgloadvmtaddrnode;
|
||||
caddrnode:=tcgaddrnode;
|
||||
cdoubleaddrnode:=tcgdoubleaddrnode;
|
||||
cderefnode:=tcgderefnode;
|
||||
csubscriptnode:=tcgsubscriptnode;
|
||||
cselfnode:=tcgselfnode;
|
||||
cwithnode:=tcgwithnode;
|
||||
cvecnode:=tcgvecnode;
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.50 2003-05-07 09:16:23 mazen
|
||||
Revision 1.51 2003-05-09 17:47:02 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.50 2003/05/07 09:16:23 mazen
|
||||
- non used units removed from uses clause
|
||||
|
||||
Revision 1.49 2003/04/27 11:21:33 peter
|
||||
|
@ -1722,7 +1722,8 @@ implementation
|
||||
if assigned(pd) then
|
||||
begin
|
||||
objectlibrary.getlabel(nodestroycall);
|
||||
reference_reset_base(href,current_procinfo.framepointer,current_procinfo.selfpointer_offset);
|
||||
{ check VMT pointer if this is an inherited constructor }
|
||||
reference_reset_base(href,current_procinfo.framepointer,current_procinfo.vmtpointer_offset);
|
||||
cg.a_cmp_const_ref_label(list,OS_ADDR,OC_EQ,0,href,nodestroycall);
|
||||
r:=cg.g_load_self(list);
|
||||
if is_class(current_procdef._class) then
|
||||
@ -2006,7 +2007,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.95 2003-04-29 07:28:52 michael
|
||||
Revision 1.96 2003-05-09 17:47:02 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.95 2003/04/29 07:28:52 michael
|
||||
+ Patch from peter to fix wrong pushing of ansistring function results in open array
|
||||
|
||||
Revision 1.94 2003/04/28 21:17:38 peter
|
||||
|
@ -1127,6 +1127,7 @@ implementation
|
||||
te_convert_operator :
|
||||
begin
|
||||
include(current_procinfo.flags,pi_do_call);
|
||||
inc(overloaded_operators[_assignment].refs);
|
||||
hp:=ccallnode.create(ccallparanode.create(left,nil),
|
||||
overloaded_operators[_assignment],nil,nil);
|
||||
{ tell explicitly which def we must use !! (PM) }
|
||||
@ -1177,7 +1178,7 @@ implementation
|
||||
if assigned(tcallnode(left).methodpointer) then
|
||||
tloadnode(hp).set_mp(tcallnode(left).methodpointer.getcopy)
|
||||
else
|
||||
tloadnode(hp).set_mp(cselfnode.create(tobjectdef(tcallnode(left).symtableprocentry.owner.defowner)));
|
||||
tloadnode(hp).set_mp(load_self);
|
||||
end;
|
||||
resulttypepass(hp);
|
||||
end;
|
||||
@ -1214,7 +1215,7 @@ implementation
|
||||
begin
|
||||
{ we can translate the typeconvnode to 'as' when
|
||||
typecasting to a class or interface }
|
||||
hp:=casnode.create(left,cloadvmtnode.create(ctypenode.create(resulttype)));
|
||||
hp:=casnode.create(left,cloadvmtaddrnode.create(ctypenode.create(resulttype)));
|
||||
left:=nil;
|
||||
result:=hp;
|
||||
exit;
|
||||
@ -1277,8 +1278,7 @@ implementation
|
||||
(left.resulttype.def.deftype=procvardef) and
|
||||
(not is_void(tprocvardef(left.resulttype.def).rettype.def)) then
|
||||
begin
|
||||
hp:=ccallnode.create(nil,nil,nil,nil);
|
||||
tcallnode(hp).set_procvar(left);
|
||||
hp:=ccallnode.create_procvar(nil,left);
|
||||
resulttypepass(hp);
|
||||
left:=hp;
|
||||
end;
|
||||
@ -2091,7 +2091,11 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.109 2003-04-27 11:21:33 peter
|
||||
Revision 1.110 2003-05-09 17:47:02 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.109 2003/04/27 11:21:33 peter
|
||||
* aktprocdef renamed to current_procdef
|
||||
* procinfo renamed to current_procinfo
|
||||
* procinfo will now be stored in current_module so it can be
|
||||
|
@ -483,8 +483,7 @@ implementation
|
||||
{ support writeln(procvar) }
|
||||
if (para.left.resulttype.def.deftype=procvardef) then
|
||||
begin
|
||||
p1:=ccallnode.create(nil,nil,nil,nil);
|
||||
tcallnode(p1).set_procvar(para.left);
|
||||
p1:=ccallnode.create_procvar(nil,para.left);
|
||||
resulttypepass(p1);
|
||||
para.left:=p1;
|
||||
end;
|
||||
@ -576,8 +575,7 @@ implementation
|
||||
{ support writeln(procvar) }
|
||||
if (para.left.resulttype.def.deftype=procvardef) then
|
||||
begin
|
||||
p1:=ccallnode.create(nil,nil,nil,nil);
|
||||
tcallnode(p1).set_procvar(para.left);
|
||||
p1:=ccallnode.create_procvar(nil,para.left);
|
||||
resulttypepass(p1);
|
||||
para.left:=p1;
|
||||
end;
|
||||
@ -2351,7 +2349,11 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.109 2003-04-27 11:21:33 peter
|
||||
Revision 1.110 2003-05-09 17:47:02 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.109 2003/04/27 11:21:33 peter
|
||||
* aktprocdef renamed to current_procdef
|
||||
* procinfo renamed to current_procinfo
|
||||
* procinfo will now be stored in current_module so it can be
|
||||
|
@ -128,6 +128,8 @@ interface
|
||||
|
||||
procedure load_procvar_from_calln(var p1:tnode);
|
||||
function load_high_value(vs:tvarsym):tnode;
|
||||
function load_self:tnode;
|
||||
function is_self_node(p:tnode):boolean;
|
||||
|
||||
|
||||
implementation
|
||||
@ -199,6 +201,28 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function load_self:tnode;
|
||||
var
|
||||
srsym : tsym;
|
||||
srsymtable : tsymtable;
|
||||
begin
|
||||
result:=nil;
|
||||
searchsym('self',srsym,srsymtable);
|
||||
if assigned(srsym) then
|
||||
result:=cloadnode.create(srsym,srsymtable)
|
||||
else
|
||||
CGMessage(cg_e_illegal_expression);
|
||||
end;
|
||||
|
||||
|
||||
function is_self_node(p:tnode):boolean;
|
||||
begin
|
||||
is_self_node:=(p.nodetype=loadn) and
|
||||
(tloadnode(p).symtableentry.typ=varsym) and
|
||||
(vo_is_self in tvarsym(tloadnode(p).symtableentry).varoptions);
|
||||
end;
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
TLOADNODE
|
||||
*****************************************************************************}
|
||||
@ -320,7 +344,23 @@ implementation
|
||||
if nf_absolute in flags then
|
||||
tvarsym(symtableentry).varstate:=vs_used
|
||||
else
|
||||
resulttype:=tvarsym(symtableentry).vartype;
|
||||
begin
|
||||
{ fix self type which is declared as voidpointer in the
|
||||
definition }
|
||||
if vo_is_self in tvarsym(symtableentry).varoptions then
|
||||
begin
|
||||
if (po_classmethod in tprocdef(symtableentry.owner.defowner).procoptions) or
|
||||
(po_staticmethod in tprocdef(symtableentry.owner.defowner).procoptions) then
|
||||
begin
|
||||
resulttype.setdef(tprocdef(symtableentry.owner.defowner)._class);
|
||||
resulttype.setdef(tclassrefdef.create(resulttype));
|
||||
end
|
||||
else
|
||||
resulttype.setdef(tprocdef(symtableentry.owner.defowner)._class);
|
||||
end
|
||||
else
|
||||
resulttype:=tvarsym(symtableentry).vartype;
|
||||
end;
|
||||
end;
|
||||
typedconstsym :
|
||||
if not(nf_absolute in flags) then
|
||||
@ -861,7 +901,7 @@ implementation
|
||||
hp : tarrayconstructornode;
|
||||
dovariant : boolean;
|
||||
htype : ttype;
|
||||
orgflags : tnodeflagset;
|
||||
orgflags : tnodeflags;
|
||||
begin
|
||||
dovariant:=(nf_forcevaria in flags) or tarraydef(resulttype.def).isvariant;
|
||||
result:=nil;
|
||||
@ -1127,7 +1167,11 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.90 2003-04-27 11:21:33 peter
|
||||
Revision 1.91 2003-05-09 17:47:02 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.90 2003/04/27 11:21:33 peter
|
||||
* aktprocdef renamed to current_procdef
|
||||
* procinfo renamed to current_procinfo
|
||||
* procinfo will now be stored in current_module so it can be
|
||||
|
@ -530,8 +530,9 @@ implementation
|
||||
minusdef:=nil;
|
||||
if assigned(overloaded_operators[_minus]) then
|
||||
minusdef:=overloaded_operators[_minus].search_procdef_unary_operator(left.resulttype.def);
|
||||
if minusdef<>nil then
|
||||
if assigned(minusdef) then
|
||||
begin
|
||||
inc(overloaded_operators[_minus].refs);
|
||||
t:=ccallnode.create(ccallparanode.create(left,nil),
|
||||
overloaded_operators[_minus],nil,nil);
|
||||
left:=nil;
|
||||
@ -705,6 +706,7 @@ implementation
|
||||
notdef:=overloaded_operators[_op_not].search_procdef_unary_operator(left.resulttype.def);
|
||||
if notdef<>nil then
|
||||
begin
|
||||
inc(overloaded_operators[_op_not].refs);
|
||||
t:=ccallnode.create(ccallparanode.create(left,nil),
|
||||
overloaded_operators[_op_not],nil,nil);
|
||||
left:=nil;
|
||||
@ -793,7 +795,11 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.47 2003-04-25 20:59:33 peter
|
||||
Revision 1.48 2003-05-09 17:47:02 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.47 2003/04/25 20:59:33 peter
|
||||
* removed funcretn,funcretsym, function result is now in varsym
|
||||
and aliases for result and function name are added using absolutesym
|
||||
* vs_hidden parameter for funcret passed in parameter
|
||||
|
@ -32,30 +32,12 @@ interface
|
||||
cpubase;
|
||||
|
||||
type
|
||||
tloadvmtnode = class(tunarynode)
|
||||
tloadvmtaddrnode = class(tunarynode)
|
||||
constructor create(l : tnode);virtual;
|
||||
function pass_1 : tnode;override;
|
||||
function det_resulttype:tnode;override;
|
||||
end;
|
||||
tloadvmtnodeclass = class of tloadvmtnode;
|
||||
|
||||
thnewnode = class(tnode)
|
||||
objtype : ttype;
|
||||
constructor create(t:ttype);virtual;
|
||||
constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
|
||||
procedure ppuwrite(ppufile:tcompilerppufile);override;
|
||||
procedure derefimpl;override;
|
||||
function pass_1 : tnode;override;
|
||||
function det_resulttype:tnode;override;
|
||||
end;
|
||||
thnewnodeclass = class of thnewnode;
|
||||
|
||||
thdisposenode = class(tunarynode)
|
||||
constructor create(l : tnode);virtual;
|
||||
function pass_1 : tnode;override;
|
||||
function det_resulttype:tnode;override;
|
||||
end;
|
||||
thdisposenodeclass = class of thdisposenode;
|
||||
tloadvmtaddrnodeclass = class of tloadvmtaddrnode;
|
||||
|
||||
taddrnode = class(tunarynode)
|
||||
getprocvardef : tprocvardef;
|
||||
@ -107,17 +89,6 @@ interface
|
||||
end;
|
||||
tvecnodeclass = class of tvecnode;
|
||||
|
||||
tselfnode = class(tnode)
|
||||
classdef : tdef; { objectdef or classrefdef }
|
||||
constructor create(_class : tdef);virtual;
|
||||
constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
|
||||
procedure ppuwrite(ppufile:tcompilerppufile);override;
|
||||
procedure derefimpl;override;
|
||||
function pass_1 : tnode;override;
|
||||
function det_resulttype:tnode;override;
|
||||
end;
|
||||
tselfnodeclass = class of tselfnode;
|
||||
|
||||
twithnode = class(tbinarynode)
|
||||
withsymtable : twithsymtable;
|
||||
tablecount : longint;
|
||||
@ -134,15 +105,12 @@ interface
|
||||
twithnodeclass = class of twithnode;
|
||||
|
||||
var
|
||||
cloadvmtnode : tloadvmtnodeclass;
|
||||
chnewnode : thnewnodeclass;
|
||||
chdisposenode : thdisposenodeclass;
|
||||
cloadvmtaddrnode : tloadvmtaddrnodeclass;
|
||||
caddrnode : taddrnodeclass;
|
||||
cdoubleaddrnode : tdoubleaddrnodeclass;
|
||||
cderefnode : tderefnodeclass;
|
||||
csubscriptnode : tsubscriptnodeclass;
|
||||
cvecnode : tvecnodeclass;
|
||||
cselfnode : tselfnodeclass;
|
||||
cwithnode : twithnodeclass;
|
||||
|
||||
implementation
|
||||
@ -156,118 +124,40 @@ implementation
|
||||
;
|
||||
|
||||
{*****************************************************************************
|
||||
TLOADVMTNODE
|
||||
TLOADVMTADDRNODE
|
||||
*****************************************************************************}
|
||||
|
||||
constructor tloadvmtnode.create(l : tnode);
|
||||
constructor tloadvmtaddrnode.create(l : tnode);
|
||||
begin
|
||||
inherited create(loadvmtn,l);
|
||||
inherited create(loadvmtaddrn,l);
|
||||
end;
|
||||
|
||||
function tloadvmtnode.det_resulttype:tnode;
|
||||
|
||||
function tloadvmtaddrnode.det_resulttype:tnode;
|
||||
begin
|
||||
result:=nil;
|
||||
resulttypepass(left);
|
||||
if codegenerror then
|
||||
exit;
|
||||
|
||||
if left.resulttype.def.deftype<>objectdef then
|
||||
Message(parser_e_pointer_to_class_expected);
|
||||
|
||||
resulttype.setdef(tclassrefdef.create(left.resulttype));
|
||||
end;
|
||||
|
||||
function tloadvmtnode.pass_1 : tnode;
|
||||
|
||||
function tloadvmtaddrnode.pass_1 : tnode;
|
||||
begin
|
||||
result:=nil;
|
||||
registers32:=1;
|
||||
expectloc:=LOC_REGISTER;
|
||||
end;
|
||||
|
||||
{*****************************************************************************
|
||||
THNEWNODE
|
||||
*****************************************************************************}
|
||||
|
||||
constructor thnewnode.create(t:ttype);
|
||||
begin
|
||||
inherited create(hnewn);
|
||||
objtype:=t;
|
||||
end;
|
||||
|
||||
|
||||
constructor thnewnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
|
||||
begin
|
||||
inherited ppuload(t,ppufile);
|
||||
ppufile.gettype(objtype);
|
||||
end;
|
||||
|
||||
|
||||
procedure thnewnode.ppuwrite(ppufile:tcompilerppufile);
|
||||
begin
|
||||
inherited ppuwrite(ppufile);
|
||||
ppufile.puttype(objtype);
|
||||
end;
|
||||
|
||||
|
||||
procedure thnewnode.derefimpl;
|
||||
begin
|
||||
inherited derefimpl;
|
||||
objtype.resolve;
|
||||
end;
|
||||
|
||||
|
||||
function thnewnode.det_resulttype:tnode;
|
||||
begin
|
||||
result:=nil;
|
||||
if objtype.def.deftype<>objectdef then
|
||||
Message(parser_e_pointer_to_class_expected);
|
||||
resulttype:=objtype;
|
||||
end;
|
||||
|
||||
|
||||
function thnewnode.pass_1 : tnode;
|
||||
begin
|
||||
result:=nil;
|
||||
expectloc:=LOC_VOID;
|
||||
end;
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
THDISPOSENODE
|
||||
*****************************************************************************}
|
||||
|
||||
constructor thdisposenode.create(l : tnode);
|
||||
begin
|
||||
inherited create(hdisposen,l);
|
||||
end;
|
||||
|
||||
|
||||
function thdisposenode.det_resulttype:tnode;
|
||||
begin
|
||||
result:=nil;
|
||||
resulttypepass(left);
|
||||
if codegenerror then
|
||||
exit;
|
||||
if (left.resulttype.def.deftype<>pointerdef) then
|
||||
CGMessage1(type_e_pointer_type_expected,left.resulttype.def.typename);
|
||||
resulttype:=tpointerdef(left.resulttype.def).pointertype;
|
||||
end;
|
||||
|
||||
|
||||
function thdisposenode.pass_1 : tnode;
|
||||
begin
|
||||
result:=nil;
|
||||
firstpass(left);
|
||||
if codegenerror then
|
||||
exit;
|
||||
|
||||
registers32:=left.registers32;
|
||||
registersfpu:=left.registersfpu;
|
||||
{$ifdef SUPPORT_MMX}
|
||||
registersmmx:=left.registersmmx;
|
||||
{$endif SUPPORT_MMX}
|
||||
if left.nodetype<>typen then
|
||||
begin
|
||||
firstpass(left);
|
||||
registers32:=left.registers32;
|
||||
end;
|
||||
if registers32<1 then
|
||||
registers32:=1;
|
||||
if left.expectloc=LOC_CREGISTER then
|
||||
inc(registers32);
|
||||
expectloc:=LOC_REFERENCE;
|
||||
end;
|
||||
|
||||
|
||||
@ -873,56 +763,6 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
TSELFNODE
|
||||
*****************************************************************************}
|
||||
|
||||
constructor tselfnode.create(_class : tdef);
|
||||
|
||||
begin
|
||||
inherited create(selfn);
|
||||
classdef:=_class;
|
||||
end;
|
||||
|
||||
constructor tselfnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
|
||||
begin
|
||||
inherited ppuload(t,ppufile);
|
||||
classdef:=tdef(ppufile.getderef);
|
||||
end;
|
||||
|
||||
|
||||
procedure tselfnode.ppuwrite(ppufile:tcompilerppufile);
|
||||
begin
|
||||
inherited ppuwrite(ppufile);
|
||||
ppufile.putderef(classdef);
|
||||
end;
|
||||
|
||||
|
||||
procedure tselfnode.derefimpl;
|
||||
begin
|
||||
inherited derefimpl;
|
||||
resolvedef(pointer(classdef));
|
||||
end;
|
||||
|
||||
|
||||
function tselfnode.det_resulttype:tnode;
|
||||
begin
|
||||
result:=nil;
|
||||
resulttype.setdef(classdef);
|
||||
end;
|
||||
|
||||
function tselfnode.pass_1 : tnode;
|
||||
begin
|
||||
result:=nil;
|
||||
if (resulttype.def.deftype=classrefdef) or
|
||||
is_class(resulttype.def) or
|
||||
(po_staticmethod in current_procdef.procoptions) then
|
||||
expectloc:=LOC_REGISTER
|
||||
else
|
||||
expectloc:=LOC_CREFERENCE;
|
||||
end;
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
TWITHNODE
|
||||
*****************************************************************************}
|
||||
@ -1047,20 +887,21 @@ implementation
|
||||
end;
|
||||
|
||||
begin
|
||||
cloadvmtnode := tloadvmtnode;
|
||||
chnewnode := thnewnode;
|
||||
chdisposenode := thdisposenode;
|
||||
cloadvmtaddrnode := tloadvmtaddrnode;
|
||||
caddrnode := taddrnode;
|
||||
cdoubleaddrnode := tdoubleaddrnode;
|
||||
cderefnode := tderefnode;
|
||||
csubscriptnode := tsubscriptnode;
|
||||
cvecnode := tvecnode;
|
||||
cselfnode := tselfnode;
|
||||
cwithnode := twithnode;
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.52 2003-05-05 14:53:16 peter
|
||||
Revision 1.53 2003-05-09 17:47:02 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.52 2003/05/05 14:53:16 peter
|
||||
* vs_hidden replaced by is_hidden boolean
|
||||
|
||||
Revision 1.51 2003/04/27 11:21:33 peter
|
||||
|
@ -81,15 +81,12 @@ interface
|
||||
vecn, {Represents array indexing}
|
||||
pointerconstn, {Represents a pointer constant}
|
||||
stringconstn, {Represents a string constant}
|
||||
selfn, {Represents the self parameter}
|
||||
notn, {Represents the not operator}
|
||||
inlinen, {Internal procedures (i.e. writeln)}
|
||||
niln, {Represents the nil pointer}
|
||||
errorn, {This part of the tree could not be
|
||||
parsed because of a compiler error}
|
||||
typen, {A type name. Used for i.e. typeof(obj)}
|
||||
hnewn, {The new operation, constructor call}
|
||||
hdisposen, {The dispose operation with destructor call}
|
||||
setelementn, {A set element(s) (i.e. [a,b] and also [a..b])}
|
||||
setconstn, {A set constant (i.e. [1,2])}
|
||||
blockn, {A block of statements}
|
||||
@ -121,7 +118,7 @@ interface
|
||||
tempdeleten, { for temps in the result/firstpass }
|
||||
addoptn, { added for optimizations where we cannot suppress }
|
||||
nothingn, {NOP, Do nothing}
|
||||
loadvmtn, {Load the address of the VMT of a class/object}
|
||||
loadvmtaddrn, {Load the address of the VMT of a class/object}
|
||||
guidconstn, {A GUID COM Interface constant }
|
||||
rttin {Rtti information so they can be accessed in result/firstpass}
|
||||
);
|
||||
@ -165,14 +162,11 @@ interface
|
||||
'vecn',
|
||||
'pointerconstn',
|
||||
'stringconstn',
|
||||
'selfn',
|
||||
'notn',
|
||||
'inlinen',
|
||||
'niln',
|
||||
'errorn',
|
||||
'typen',
|
||||
'hnewn',
|
||||
'hdisposen',
|
||||
'setelementn',
|
||||
'setconstn',
|
||||
'blockn',
|
||||
@ -204,13 +198,13 @@ interface
|
||||
'tempdeleten',
|
||||
'addoptn',
|
||||
'nothingn',
|
||||
'loadvmtn',
|
||||
'loadvmtaddrn',
|
||||
'guidconstn',
|
||||
'rttin');
|
||||
|
||||
type
|
||||
{ all boolean field of ttree are now collected in flags }
|
||||
tnodeflags = (
|
||||
tnodeflag = (
|
||||
nf_swapable, { tbinop operands can be swaped }
|
||||
nf_swaped, { tbinop operands are swaped }
|
||||
nf_error,
|
||||
@ -223,7 +217,11 @@ interface
|
||||
|
||||
{ flags used by tcallnode }
|
||||
nf_return_value_used,
|
||||
nf_inherited,
|
||||
nf_anon_inherited,
|
||||
nf_new_call,
|
||||
nf_dispose_call,
|
||||
nf_member_call, { called with implicit methodpointer tree }
|
||||
|
||||
{ flags used by tcallparanode }
|
||||
nf_varargs_para, { belongs this para to varargs }
|
||||
@ -265,12 +263,12 @@ interface
|
||||
nf_releasetemps
|
||||
);
|
||||
|
||||
tnodeflagset = set of tnodeflags;
|
||||
tnodeflags = set of tnodeflag;
|
||||
|
||||
const
|
||||
{ contains the flags which must be equal for the equality }
|
||||
{ of nodes }
|
||||
flagsequal : tnodeflagset = [nf_error];
|
||||
flagsequal : tnodeflags = [nf_error];
|
||||
|
||||
type
|
||||
tnodelist = class
|
||||
@ -291,7 +289,7 @@ interface
|
||||
{ this field is set by concattolist }
|
||||
parent : tnode;
|
||||
{ there are some properties about the node stored }
|
||||
flags : tnodeflagset;
|
||||
flags : tnodeflags;
|
||||
{ the number of registers needed to evalute the node }
|
||||
registers32,registersfpu : longint; { must be longint !!!! }
|
||||
{$ifdef SUPPORT_MMX}
|
||||
@ -314,7 +312,7 @@ interface
|
||||
procedure derefimpl;virtual;
|
||||
|
||||
{ toggles the flag }
|
||||
procedure toggleflag(f : tnodeflags);
|
||||
procedure toggleflag(f : tnodeflag);
|
||||
|
||||
{ the 1.1 code generator may override pass_1 }
|
||||
{ and it need not to implement det_* then }
|
||||
@ -584,7 +582,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure tnode.toggleflag(f : tnodeflags);
|
||||
procedure tnode.toggleflag(f : tnodeflag);
|
||||
begin
|
||||
if f in flags then
|
||||
exclude(flags,f)
|
||||
@ -630,7 +628,7 @@ implementation
|
||||
write(t,' ,resulttype = <nil>');
|
||||
writeln(t,', pos = (',fileinfo.line,',',fileinfo.column,')',
|
||||
', loc = ',tcgloc2str[location.loc],
|
||||
', inttgobj: = ',registers32,
|
||||
', intregs = ',registers32,
|
||||
', fpuregs = ',registersfpu);
|
||||
end;
|
||||
|
||||
@ -990,7 +988,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.58 2003-04-25 20:59:33 peter
|
||||
Revision 1.59 2003-05-09 17:47:02 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.58 2003/04/25 20:59:33 peter
|
||||
* removed funcretn,funcretsym, function result is now in varsym
|
||||
and aliases for result and function name are added using absolutesym
|
||||
* vs_hidden parameter for funcret passed in parameter
|
||||
|
@ -107,14 +107,11 @@ implementation
|
||||
'vecn', {vecn}
|
||||
'pointerconst',{pointerconstn}
|
||||
'stringconst', {stringconstn}
|
||||
'selfn', {selfn}
|
||||
'not', {notn}
|
||||
'inline', {inlinen}
|
||||
'niln', {niln}
|
||||
'error', {errorn}
|
||||
'nothing-typen', {typen}
|
||||
'hnewn', {hnewn}
|
||||
'hdisposen', {hdisposen}
|
||||
'setelement', {setelementn}
|
||||
'setconst', {setconstn}
|
||||
'blockn', {blockn}
|
||||
@ -306,7 +303,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.49 2003-04-27 11:21:33 peter
|
||||
Revision 1.50 2003-05-09 17:47:02 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.49 2003/04/27 11:21:33 peter
|
||||
* aktprocdef renamed to current_procdef
|
||||
* procinfo renamed to current_procinfo
|
||||
* procinfo will now be stored in current_module so it can be
|
||||
|
@ -230,7 +230,9 @@ implementation
|
||||
oldregisterdef:=registerdef;
|
||||
registerdef:=false;
|
||||
readprocdef:=tprocvardef.create(normal_function_level);
|
||||
include(readprocdef.procoptions,po_methodpointer);
|
||||
writeprocdef:=tprocvardef.create(normal_function_level);
|
||||
include(writeprocdef.procoptions,po_methodpointer);
|
||||
registerdef:=oldregisterdef;
|
||||
|
||||
if token<>_ID then
|
||||
@ -278,8 +280,7 @@ implementation
|
||||
varspez:=vs_value;
|
||||
sc.reset;
|
||||
repeat
|
||||
readvs:=tvarsym.create(orgpattern,generrortype);
|
||||
readvs.varspez:=varspez;
|
||||
readvs:=tvarsym.create(orgpattern,varspez,generrortype);
|
||||
readprocdef.parast.insert(readvs);
|
||||
sc.insert(readvs);
|
||||
consume(_ID);
|
||||
@ -307,7 +308,7 @@ implementation
|
||||
begin
|
||||
readprocdef.concatpara(nil,tt,readvs,nil,false);
|
||||
{ also update the writeprocdef }
|
||||
hvs:=tvarsym.create(readvs.realname,generrortype);
|
||||
hvs:=tvarsym.create(readvs.realname,vs_value,generrortype);
|
||||
writeprocdef.parast.insert(hvs);
|
||||
writeprocdef.concatpara(nil,tt,hvs,nil,false);
|
||||
readvs:=tvarsym(readvs.listnext);
|
||||
@ -344,10 +345,10 @@ implementation
|
||||
p.indextype.setdef(pt.resulttype.def);
|
||||
include(p.propoptions,ppo_indexed);
|
||||
{ concat a longint to the para templates }
|
||||
hvs:=tvarsym.create('$index',p.indextype);
|
||||
hvs:=tvarsym.create('$index',vs_value,p.indextype);
|
||||
readprocdef.parast.insert(hvs);
|
||||
readprocdef.concatpara(nil,p.indextype,hvs,nil,false);
|
||||
hvs:=tvarsym.create('$index',p.indextype);
|
||||
hvs:=tvarsym.create('$index',vs_value,p.indextype);
|
||||
writeprocdef.parast.insert(hvs);
|
||||
writeprocdef.concatpara(nil,p.indextype,hvs,nil,false);
|
||||
pt.free;
|
||||
@ -422,7 +423,7 @@ implementation
|
||||
{ write is a procedure with an extra value parameter
|
||||
of the of the property }
|
||||
writeprocdef.rettype:=voidtype;
|
||||
hvs:=tvarsym.create('$value',p.proptype);
|
||||
hvs:=tvarsym.create('$value',vs_value,p.proptype);
|
||||
writeprocdef.parast.insert(hvs);
|
||||
writeprocdef.concatpara(nil,p.proptype,hvs,nil,false);
|
||||
{ Insert hidden parameters }
|
||||
@ -557,7 +558,7 @@ implementation
|
||||
if (cs_constructor_name in aktglobalswitches) and
|
||||
(pd.procsym.name<>'DONE') then
|
||||
Message(parser_e_destructorname_must_be_done);
|
||||
if not(pd.Para.empty) and
|
||||
if not(pd.maxparacount=0) and
|
||||
(m_fpc in aktmodeswitches) then
|
||||
Message(parser_e_no_paras_for_destructor);
|
||||
consume(_SEMICOLON);
|
||||
@ -1145,7 +1146,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.64 2003-05-05 14:53:16 peter
|
||||
Revision 1.65 2003-05-09 17:47:02 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.64 2003/05/05 14:53:16 peter
|
||||
* vs_hidden replaced by is_hidden boolean
|
||||
|
||||
Revision 1.63 2003/04/27 11:21:33 peter
|
||||
|
@ -109,66 +109,94 @@ implementation
|
||||
akttokenpos:=tprocdef(pd).fileinfo;
|
||||
|
||||
{ Generate result variable accessing function result }
|
||||
vs:=tvarsym.create('$result',pd.rettype);
|
||||
vs:=tvarsym.create('$result',vs_var,pd.rettype);
|
||||
include(vs.varoptions,vo_is_funcret);
|
||||
pd.parast.insert(vs);
|
||||
pd.insertpara(vs.vartype,vs,nil,true);
|
||||
{ Store the this symbol as funcretsym for procedures }
|
||||
if pd.deftype=procdef then
|
||||
tprocdef(pd).funcretsym:=vs;
|
||||
|
||||
{ Handle like a var parameter }
|
||||
vs.varspez:=vs_var;
|
||||
pd.parast.insert(vs);
|
||||
{ Also insert a hidden parameter as first }
|
||||
pd.insertpara(vs.vartype,vs,nil,true);
|
||||
|
||||
akttokenpos:=storepos;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure insert_self_and_vmt_para(pd:tabstractprocdef);
|
||||
var
|
||||
storepos : tfileposinfo;
|
||||
vs : tvarsym;
|
||||
tt : ttype;
|
||||
vsp : tvarspez;
|
||||
begin
|
||||
if (pd.deftype=procvardef) and
|
||||
pd.is_methodpointer then
|
||||
pd.is_methodpointer then
|
||||
begin
|
||||
internalerror(200304301);
|
||||
if not(po_containsself in pd.procoptions) then
|
||||
begin
|
||||
{ Generate self variable }
|
||||
tt:=voidpointertype;
|
||||
vs:=tvarsym.create('$self',vs_value,tt);
|
||||
include(vs.varoptions,vo_is_self);
|
||||
{ Insert as hidden parameter }
|
||||
pd.parast.insert(vs);
|
||||
pd.insertpara(vs.vartype,vs,nil,true);
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (pd is tprocdef) and
|
||||
assigned(tprocdef(pd)._class) then
|
||||
if (pd.deftype=procdef) and
|
||||
assigned(tprocdef(pd)._class) and
|
||||
(pd.parast.symtablelevel=normal_function_level) then
|
||||
begin
|
||||
storepos:=akttokenpos;
|
||||
if pd.deftype=procdef then
|
||||
akttokenpos:=tprocdef(pd).fileinfo;
|
||||
akttokenpos:=tprocdef(pd).fileinfo;
|
||||
|
||||
{ Generate result variable accessing function result }
|
||||
tt.setdef(tprocdef(pd)._class);
|
||||
{ for unknwon reasons this doesn't work:
|
||||
tt.setdef(tprocdef(pd)._class.typedef);
|
||||
}
|
||||
vs:=tvarsym.create('$self',tt);
|
||||
include(vs.varoptions,vo_is_funcret);
|
||||
{ Store the this symbol as funcretsym for procedures }
|
||||
if pd.deftype=procdef then
|
||||
tprocdef(pd).funcretsym:=vs;
|
||||
{ Generate VMT variable for constructor/destructor }
|
||||
if pd.proctypeoption in [potype_constructor,potype_destructor] then
|
||||
begin
|
||||
{ can't use classrefdef as type because inheriting
|
||||
will then always file because of a type mismatch }
|
||||
tt:=voidpointertype;
|
||||
vs:=tvarsym.create('$vmt',vs_value,tt);
|
||||
include(vs.varoptions,vo_is_vmt);
|
||||
{ Insert as hidden parameter }
|
||||
pd.parast.insert(vs);
|
||||
pd.insertpara(vs.vartype,vs,nil,true);
|
||||
end;
|
||||
|
||||
{ Handle self of objects like a var parameter }
|
||||
if is_object(tprocdef(pd)._class) then
|
||||
vs.varspez:=vs_var;
|
||||
|
||||
pd.parast.insert(vs);
|
||||
{ Also insert a hidden parameter as first }
|
||||
pd.insertpara(vs.vartype,vs,nil,true);
|
||||
{ Generate self variable, for classes we need
|
||||
to use the generic voidpointer to be compatible with
|
||||
methodpointers.
|
||||
Only needed when there is no explicit self para }
|
||||
if not(po_containsself in pd.procoptions) then
|
||||
begin
|
||||
vsp:=vs_value;
|
||||
if (po_staticmethod in pd.procoptions) or
|
||||
(po_classmethod in pd.procoptions) then
|
||||
begin
|
||||
tt.setdef(tprocdef(pd)._class);
|
||||
tt.setdef(tclassrefdef.create(tt));
|
||||
end
|
||||
else
|
||||
begin
|
||||
if is_object(tprocdef(pd)._class) then
|
||||
vsp:=vs_var;
|
||||
tt.setdef(tprocdef(pd)._class);
|
||||
end;
|
||||
vs:=tvarsym.create('$self',vsp,tt);
|
||||
include(vs.varoptions,vo_is_self);
|
||||
{ Insert as hidden parameter }
|
||||
pd.parast.insert(vs);
|
||||
pd.insertpara(vs.vartype,vs,nil,true);
|
||||
end;
|
||||
|
||||
akttokenpos:=storepos;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure insert_funcret_local(pd:tprocdef);
|
||||
var
|
||||
storepos : tfileposinfo;
|
||||
@ -187,7 +215,7 @@ implementation
|
||||
when it is returning in a register }
|
||||
if not paramanager.ret_in_param(pd.rettype.def,pd.proccalloption) then
|
||||
begin
|
||||
vs:=tvarsym.create('$result',pd.rettype);
|
||||
vs:=tvarsym.create('$result',vs_value,pd.rettype);
|
||||
include(vs.varoptions,vo_is_funcret);
|
||||
pd.localst.insert(vs);
|
||||
pd.localst.insertvardata(vs);
|
||||
@ -232,8 +260,7 @@ implementation
|
||||
begin
|
||||
if assigned(currpara.parasym) then
|
||||
begin
|
||||
hvs:=tvarsym.create('$high'+tvarsym(currpara.parasym).name,s32bittype);
|
||||
hvs.varspez:=vs_const;
|
||||
hvs:=tvarsym.create('$high'+tvarsym(currpara.parasym).name,vs_const,s32bittype);
|
||||
include(hvs.varoptions,vo_is_high_value);
|
||||
tvarsym(currpara.parasym).owner.insert(hvs);
|
||||
tvarsym(currpara.parasym).highvarsym:=hvs;
|
||||
@ -313,6 +340,7 @@ implementation
|
||||
procedure check_self_para(pd:tabstractprocdef);
|
||||
var
|
||||
hpara : tparaitem;
|
||||
vs : tvarsym;
|
||||
begin
|
||||
hpara:=pd.selfpara;
|
||||
if assigned(hpara) and
|
||||
@ -331,6 +359,10 @@ implementation
|
||||
if compare_defs(hpara.paratype.def,tprocdef(pd)._class,nothingn)=te_incompatible then
|
||||
CGMessage2(type_e_incompatible_types,hpara.paratype.def.typename,tprocdef(pd)._class.typename);
|
||||
end;
|
||||
{ add an alias for $self which is for internal use }
|
||||
vs:=tabsolutesym.create_ref('$self',hpara.paratype,tstoredsym(hpara.parasym));
|
||||
include(vs.varoptions,vo_is_self);
|
||||
pd.parast.insert(vs);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -389,7 +421,7 @@ implementation
|
||||
{ read identifiers and insert with error type }
|
||||
sc.reset;
|
||||
repeat
|
||||
vs:=tvarsym.create(orgpattern,generrortype);
|
||||
vs:=tvarsym.create(orgpattern,varspez,generrortype);
|
||||
currparast.insert(vs);
|
||||
if assigned(vs.owner) then
|
||||
sc.insert(vs)
|
||||
@ -484,7 +516,6 @@ implementation
|
||||
begin
|
||||
{ update varsym }
|
||||
vs.vartype:=tt;
|
||||
vs.varspez:=varspez;
|
||||
{ For proc vars we only need the definitions }
|
||||
if not is_procvar then
|
||||
begin
|
||||
@ -501,8 +532,9 @@ implementation
|
||||
until not try_to_consume(_SEMICOLON);
|
||||
{ remove parasymtable from stack }
|
||||
sc.free;
|
||||
{ check for a self parameter, only for normal procedures. For
|
||||
procvars we need to wait until the 'of object' is parsed }
|
||||
{ check for a self parameter which is needed to allow message
|
||||
directive, only for normal procedures. For procvars we need
|
||||
to wait until the 'of object' is parsed }
|
||||
if not is_procvar then
|
||||
check_self_para(pd);
|
||||
{ reset object options }
|
||||
@ -1775,9 +1807,7 @@ const
|
||||
{ insert hidden high parameters }
|
||||
insert_hidden_para(pd);
|
||||
{ insert hidden self parameter }
|
||||
{$ifdef vs_hidden_self}
|
||||
insert_self_and_vmt_para(pd);
|
||||
{$endif vs_hidden_self}
|
||||
{ insert funcret parameter if required }
|
||||
insert_funcret_para(pd);
|
||||
|
||||
@ -2170,7 +2200,11 @@ const
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.121 2003-05-05 14:53:16 peter
|
||||
Revision 1.122 2003-05-09 17:47:03 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.121 2003/05/05 14:53:16 peter
|
||||
* vs_hidden replaced by is_hidden boolean
|
||||
|
||||
Revision 1.120 2003/04/30 09:42:42 florian
|
||||
|
@ -87,7 +87,7 @@ implementation
|
||||
if (symtablestack.symtabletype=objectsymtable) and
|
||||
(sp_static in current_object_option) then
|
||||
begin
|
||||
vs2:=tvarsym.create('$'+lower(symtablestack.name^)+'_'+vs.name,tt);
|
||||
vs2:=tvarsym.create('$'+lower(symtablestack.name^)+'_'+vs.name,vs_value,tt);
|
||||
symtablestack.defowner.owner.insert(vs2);
|
||||
symtablestack.defowner.owner.insertvardata(vs2);
|
||||
end
|
||||
@ -151,7 +151,7 @@ implementation
|
||||
sorg:=orgpattern;
|
||||
sc.reset;
|
||||
repeat
|
||||
vs:=tvarsym.create(orgpattern,generrortype);
|
||||
vs:=tvarsym.create(orgpattern,vs_value,generrortype);
|
||||
symtablestack.insert(vs);
|
||||
if assigned(vs.owner) then
|
||||
sc.insert(vs)
|
||||
@ -507,7 +507,7 @@ implementation
|
||||
symtablestack:=symtablestack.next;
|
||||
read_type(casetype,'');
|
||||
symtablestack:=oldsymtablestack;
|
||||
vs:=tvarsym.create(sorg,casetype);
|
||||
vs:=tvarsym.create(sorg,vs_value,casetype);
|
||||
symtablestack.insert(vs);
|
||||
symtablestack.insertvardata(vs);
|
||||
end;
|
||||
@ -560,7 +560,7 @@ implementation
|
||||
symtablestack.dataalignment:=maxalignment;
|
||||
uniontype.def:=uniondef;
|
||||
uniontype.sym:=nil;
|
||||
UnionSym:=tvarsym.create('case',uniontype);
|
||||
UnionSym:=tvarsym.create('$case',vs_value,uniontype);
|
||||
symtablestack:=symtablestack.next;
|
||||
{ we do NOT call symtablestack.insert
|
||||
on purpose PM }
|
||||
@ -602,7 +602,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.46 2003-04-25 20:59:33 peter
|
||||
Revision 1.47 2003-05-09 17:47:03 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.46 2003/04/25 20:59:33 peter
|
||||
* removed funcretn,funcretsym, function result is now in varsym
|
||||
and aliases for result and function name are added using absolutesym
|
||||
* vs_hidden parameter for funcret passed in parameter
|
||||
|
@ -46,7 +46,7 @@ interface
|
||||
function parse_paras(__colon,in_prop_paras : boolean) : tnode;
|
||||
|
||||
{ the ID token has to be consumed before calling this function }
|
||||
procedure do_member_read(getaddr : boolean;sym : tsym;var p1 : tnode;var again : boolean);
|
||||
procedure do_member_read(getaddr : boolean;sym : tsym;var p1 : tnode;var again : boolean;callnflags:tnodeflags);
|
||||
|
||||
{$ifdef int64funcresok}
|
||||
function get_intconst:TConstExprInt;
|
||||
@ -239,8 +239,7 @@ implementation
|
||||
(p.resulttype.def.deftype=procvardef) and
|
||||
(tprocvardef(p.resulttype.def).minparacount=0) then
|
||||
begin
|
||||
p1:=ccallnode.create(nil,nil,nil,nil);
|
||||
tcallnode(p1).set_procvar(p);
|
||||
p1:=ccallnode.create_procvar(nil,p);
|
||||
resulttypepass(p1);
|
||||
p:=p1;
|
||||
end;
|
||||
@ -315,13 +314,11 @@ implementation
|
||||
consume(_RKLAMMER);
|
||||
if p1.nodetype=typen then
|
||||
ttypenode(p1).allowed:=true;
|
||||
if (p1.resulttype.def.deftype = objectdef) or
|
||||
((p1.resulttype.def.deftype = classrefdef) and
|
||||
(p1.nodetype in [selfn,loadvmtn])) then
|
||||
if (p1.resulttype.def.deftype = objectdef) then
|
||||
statement_syssym:=geninlinenode(in_typeof_x,false,p1)
|
||||
else
|
||||
begin
|
||||
Message(type_e_mismatch);
|
||||
Message(parser_e_class_id_expected);
|
||||
p1.destroy;
|
||||
statement_syssym:=cerrornode.create;
|
||||
end;
|
||||
@ -634,19 +631,49 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function maybe_load_methodpointer(st:tsymtable;var p1:tnode):boolean;
|
||||
begin
|
||||
maybe_load_methodpointer:=false;
|
||||
if not assigned(p1) then
|
||||
begin
|
||||
case st.symtabletype of
|
||||
withsymtable :
|
||||
begin
|
||||
if (st.defowner.deftype=objectdef) then
|
||||
begin
|
||||
p1:=tnode(twithsymtable(st).withrefnode).getcopy;
|
||||
maybe_load_methodpointer:=true;
|
||||
end;
|
||||
end;
|
||||
objectsymtable :
|
||||
begin
|
||||
p1:=load_self;
|
||||
maybe_load_methodpointer:=true;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{ reads the parameter for a subroutine call }
|
||||
procedure do_proc_call(sym:tsym;st:tsymtable;getaddr:boolean;var again : boolean;var p1:tnode);
|
||||
var
|
||||
membercall,
|
||||
prevafterassn : boolean;
|
||||
hs,hs1 : tvarsym;
|
||||
vs : tvarsym;
|
||||
para,p2 : tnode;
|
||||
hst : tsymtable;
|
||||
currpara : tparaitem;
|
||||
aprocdef : tprocdef;
|
||||
begin
|
||||
prevafterassn:=afterassignment;
|
||||
afterassignment:=false;
|
||||
membercall:=false;
|
||||
aprocdef:=nil;
|
||||
|
||||
{ when it is a call to a member we need to load the
|
||||
methodpointer first }
|
||||
membercall:=maybe_load_methodpointer(st,p1);
|
||||
|
||||
{ When we are expecting a procvar we also need
|
||||
to get the address in some cases }
|
||||
if assigned(getprocvardef) then
|
||||
@ -666,34 +693,50 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
{ want we only determine the address of }
|
||||
{ a subroutine ? }
|
||||
if not(getaddr) then
|
||||
{ only need to get the address of the procedure? }
|
||||
if getaddr then
|
||||
begin
|
||||
{ Retrieve info which procvar to call. For tp_procvar the
|
||||
aprocdef is already loaded above so we can reuse it }
|
||||
if not assigned(aprocdef) and
|
||||
assigned(getprocvardef) then
|
||||
aprocdef:=Tprocsym(sym).search_procdef_byprocvardef(getprocvardef);
|
||||
|
||||
{ generate a methodcallnode or proccallnode }
|
||||
{ we shouldn't convert things like @tcollection.load }
|
||||
p2:=cloadnode.create_procvar(sym,aprocdef,st);
|
||||
if assigned(p1) then
|
||||
begin
|
||||
if (p1.nodetype<>typen) then
|
||||
tloadnode(p2).set_mp(p1)
|
||||
else
|
||||
p1.free;
|
||||
end;
|
||||
p1:=p2;
|
||||
|
||||
{ no postfix operators }
|
||||
again:=false;
|
||||
end
|
||||
else
|
||||
begin
|
||||
para:=nil;
|
||||
if anon_inherited then
|
||||
begin
|
||||
hst:=symtablestack;
|
||||
while assigned(hst) and (hst.symtabletype<>parasymtable) do
|
||||
hst:=hst.next;
|
||||
if assigned(hst) then
|
||||
if not assigned(current_procdef) then
|
||||
internalerror(200305054);
|
||||
currpara:=tparaitem(current_procdef.para.first);
|
||||
while assigned(currpara) do
|
||||
begin
|
||||
hs:=tvarsym(hst.symindex.first);
|
||||
while assigned(hs) do
|
||||
if not currpara.is_hidden then
|
||||
begin
|
||||
if hs.typ<>varsym then
|
||||
internalerror(54382953);
|
||||
vs:=tvarsym(currpara.parasym);
|
||||
{ if there is a localcopy then use that }
|
||||
if assigned(hs.localvarsym) then
|
||||
hs1:=hs.localvarsym
|
||||
else
|
||||
hs1:=hs;
|
||||
para:=ccallparanode.create(cloadnode.create(hs1,hs1.owner),para);
|
||||
hs:=tvarsym(hs.indexnext);
|
||||
if assigned(vs.localvarsym) then
|
||||
vs:=vs.localvarsym;
|
||||
para:=ccallparanode.create(cloadnode.create(vs,vs.owner),para);
|
||||
end;
|
||||
end
|
||||
else
|
||||
internalerror(54382954);
|
||||
currpara:=tparaitem(currpara.next);
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -704,47 +747,11 @@ implementation
|
||||
end;
|
||||
end;
|
||||
p1:=ccallnode.create(para,tprocsym(sym),st,p1);
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ address operator @: }
|
||||
if not assigned(p1) then
|
||||
begin
|
||||
case st.symtabletype of
|
||||
withsymtable :
|
||||
begin
|
||||
if (st.defowner.deftype=objectdef) then
|
||||
p1:=tnode(twithsymtable(st).withrefnode).getcopy;
|
||||
end;
|
||||
objectsymtable :
|
||||
begin
|
||||
{ we must provide a method pointer, if it isn't given, }
|
||||
{ it is self }
|
||||
p1:=cselfnode.create(tobjectdef(st.defowner));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Retrieve info which procvar to call. For tp_procvar the
|
||||
aprocdef is already loaded above so we can reuse it }
|
||||
if not assigned(aprocdef) and
|
||||
assigned(getprocvardef) then
|
||||
aprocdef:=Tprocsym(sym).search_procdef_byprocvardef(getprocvardef);
|
||||
|
||||
{ generate a methodcallnode or proccallnode }
|
||||
{ we shouldn't convert things like @tcollection.load }
|
||||
p2:=cloadnode.create_procvar(sym,aprocdef,st);
|
||||
if assigned(p1) then
|
||||
begin
|
||||
if (p1.nodetype<>typen) then
|
||||
tloadnode(p2).set_mp(p1)
|
||||
else
|
||||
p1.free;
|
||||
end;
|
||||
p1:=p2;
|
||||
|
||||
{ no postfix operators }
|
||||
again:=false;
|
||||
{ indicate if this call was generated by a member and
|
||||
no explicit self is used, this is needed to determine
|
||||
how to handle a destructor call (PFV) }
|
||||
if membercall then
|
||||
include(p1.flags,nf_member_call);
|
||||
end;
|
||||
afterassignment:=prevafterassn;
|
||||
end;
|
||||
@ -825,6 +832,7 @@ implementation
|
||||
var
|
||||
paras : tnode;
|
||||
p2 : tnode;
|
||||
membercall : boolean;
|
||||
begin
|
||||
paras:=nil;
|
||||
{ property parameters? read them only if the property really }
|
||||
@ -855,8 +863,11 @@ implementation
|
||||
procsym :
|
||||
begin
|
||||
{ generate the method call }
|
||||
membercall:=maybe_load_methodpointer(st,p1);
|
||||
p1:=ccallnode.create(paras,
|
||||
tprocsym(tpropertysym(sym).writeaccess.firstsym^.sym),st,p1);
|
||||
if membercall then
|
||||
include(tcallnode(p1).flags,nf_member_call);
|
||||
paras:=nil;
|
||||
consume(_ASSIGNMENT);
|
||||
{ read the expression }
|
||||
@ -905,7 +916,10 @@ implementation
|
||||
procsym :
|
||||
begin
|
||||
{ generate the method call }
|
||||
membercall:=maybe_load_methodpointer(st,p1);
|
||||
p1:=ccallnode.create(paras,tprocsym(tpropertysym(sym).readaccess.firstsym^.sym),st,p1);
|
||||
if membercall then
|
||||
include(tcallnode(p1).flags,nf_member_call);
|
||||
paras:=nil;
|
||||
include(p1.flags,nf_isproperty);
|
||||
end
|
||||
@ -930,7 +944,7 @@ implementation
|
||||
|
||||
|
||||
{ the ID token has to be consumed before calling this function }
|
||||
procedure do_member_read(getaddr : boolean;sym : tsym;var p1 : tnode;var again : boolean);
|
||||
procedure do_member_read(getaddr : boolean;sym : tsym;var p1 : tnode;var again : boolean;callnflags:tnodeflags);
|
||||
|
||||
var
|
||||
static_name : string;
|
||||
@ -967,6 +981,9 @@ implementation
|
||||
do_proc_call(sym,sym.owner,
|
||||
(getaddr and not(token in [_CARET,_POINT])),
|
||||
again,p1);
|
||||
{ add provided flags }
|
||||
if (p1.nodetype=calln) then
|
||||
p1.flags:=p1.flags+callnflags;
|
||||
{ we need to know which procedure is called }
|
||||
do_resulttypepass(p1);
|
||||
{ now we know the real method e.g. we can check for a class method }
|
||||
@ -1135,7 +1152,7 @@ implementation
|
||||
srsym:=searchsym_in_class(tobjectdef(htype.def),pattern);
|
||||
check_hints(srsym);
|
||||
consume(_ID);
|
||||
do_member_read(false,srsym,p1,again);
|
||||
do_member_read(false,srsym,p1,again,[]);
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -1159,7 +1176,7 @@ implementation
|
||||
else
|
||||
begin
|
||||
consume(_ID);
|
||||
do_member_read(getaddr,srsym,p1,again);
|
||||
do_member_read(getaddr,srsym,p1,again,[]);
|
||||
end;
|
||||
end;
|
||||
end
|
||||
@ -1183,7 +1200,7 @@ implementation
|
||||
else
|
||||
begin
|
||||
consume(_ID);
|
||||
do_member_read(getaddr,srsym,p1,again);
|
||||
do_member_read(getaddr,srsym,p1,again,[]);
|
||||
end;
|
||||
end
|
||||
else
|
||||
@ -1193,7 +1210,7 @@ implementation
|
||||
the type. For all other blocks we return
|
||||
a loadvmt node }
|
||||
if (block_type<>bt_type) then
|
||||
p1:=cloadvmtnode.create(p1);
|
||||
p1:=cloadvmtaddrnode.create(p1);
|
||||
end;
|
||||
end
|
||||
else
|
||||
@ -1579,7 +1596,7 @@ implementation
|
||||
else
|
||||
begin
|
||||
consume(_ID);
|
||||
do_member_read(getaddr,hsym,p1,again);
|
||||
do_member_read(getaddr,hsym,p1,again,[]);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -1602,7 +1619,7 @@ implementation
|
||||
else
|
||||
begin
|
||||
consume(_ID);
|
||||
do_member_read(getaddr,hsym,p1,again);
|
||||
do_member_read(getaddr,hsym,p1,again,[]);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -1635,25 +1652,24 @@ implementation
|
||||
again:=false
|
||||
else
|
||||
if (token=_LKLAMMER) or
|
||||
((tprocvardef(p1.resulttype.def).para.empty) and
|
||||
((tprocvardef(p1.resulttype.def).maxparacount=0) and
|
||||
(not((token in [_ASSIGNMENT,_UNEQUAL,_EQUAL]))) and
|
||||
(not afterassignment) and
|
||||
(not in_args)) then
|
||||
begin
|
||||
{ do this in a strange way }
|
||||
{ it's not a clean solution }
|
||||
p2:=p1;
|
||||
p1:=ccallnode.create(nil,nil,nil,nil);
|
||||
tcallnode(p1).set_procvar(p2);
|
||||
if try_to_consume(_LKLAMMER) then
|
||||
begin
|
||||
tcallnode(p1).left:=parse_paras(false,false);
|
||||
p2:=parse_paras(false,false);
|
||||
consume(_RKLAMMER);
|
||||
end;
|
||||
end
|
||||
else
|
||||
p2:=nil;
|
||||
p1:=ccallnode.create_procvar(p2,p1);
|
||||
{ proc():= is never possible }
|
||||
if token=_ASSIGNMENT then
|
||||
begin
|
||||
Message(cg_e_illegal_expression);
|
||||
p1.free;
|
||||
p1:=cerrornode.create;
|
||||
again:=false;
|
||||
end;
|
||||
@ -1738,14 +1754,7 @@ implementation
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (po_classmethod in current_procdef.procoptions) then
|
||||
begin
|
||||
{ self in class methods is a class reference type }
|
||||
htype.setdef(current_procdef._class);
|
||||
p1:=cselfnode.create(tclassrefdef.create(htype));
|
||||
end
|
||||
else
|
||||
p1:=cselfnode.create(current_procdef._class);
|
||||
p1:=load_self;
|
||||
postfixoperators(p1,again);
|
||||
end;
|
||||
end;
|
||||
@ -1784,15 +1793,14 @@ implementation
|
||||
if assigned(sym) then
|
||||
begin
|
||||
check_hints(sym);
|
||||
{ load the procdef from the inherited class and
|
||||
not from self }
|
||||
if sym.typ=procsym then
|
||||
begin
|
||||
htype.setdef(classh);
|
||||
p1:=ctypenode.create(htype);
|
||||
end;
|
||||
do_member_read(false,sym,p1,again);
|
||||
{ Add flag to indicate that inherited is used }
|
||||
if p1.nodetype=calln then
|
||||
include(p1.flags,nf_anon_inherited);
|
||||
do_member_read(false,sym,p1,again,[nf_inherited,nf_anon_inherited]);
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -2314,7 +2322,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.114 2003-05-01 07:59:42 florian
|
||||
Revision 1.115 2003-05-09 17:47:03 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.114 2003/05/01 07:59:42 florian
|
||||
* introduced defaultordconsttype to decribe the default size of ordinal constants
|
||||
on 64 bit CPUs it's equal to cs64bitdef while on 32 bit CPUs it's equal to s32bitdef
|
||||
+ added defines CPU32 and CPU64 for 32 bit and 64 bit CPUs
|
||||
|
@ -74,6 +74,7 @@ implementation
|
||||
destructorname : stringid;
|
||||
sym : tsym;
|
||||
classh : tobjectdef;
|
||||
callflag : tnodeflag;
|
||||
destructorpos,
|
||||
storepos : tfileposinfo;
|
||||
begin
|
||||
@ -140,20 +141,25 @@ implementation
|
||||
end
|
||||
else
|
||||
begin
|
||||
if is_new then
|
||||
p2:=chnewnode.create(tpointerdef(p.resulttype.def).pointertype)
|
||||
else
|
||||
p2:=chdisposenode.create(p);
|
||||
p2:=cderefnode.create(p.getcopy);
|
||||
do_resulttypepass(p2);
|
||||
if is_new then
|
||||
do_member_read(false,sym,p2,again)
|
||||
callflag:=nf_new_call
|
||||
else
|
||||
callflag:=nf_dispose_call;
|
||||
if is_new then
|
||||
do_member_read(false,sym,p2,again,[callflag])
|
||||
else
|
||||
begin
|
||||
if not(m_fpc in aktmodeswitches) then
|
||||
do_member_read(false,sym,p2,again)
|
||||
do_member_read(false,sym,p2,again,[callflag])
|
||||
else
|
||||
begin
|
||||
p2:=ccallnode.create(nil,tprocsym(sym),sym.owner,p2);
|
||||
if is_new then
|
||||
include(p2.flags,nf_new_call)
|
||||
else
|
||||
include(p2.flags,nf_dispose_call);
|
||||
{ support dispose(p,done()); }
|
||||
if try_to_consume(_LKLAMMER) then
|
||||
begin
|
||||
@ -168,7 +174,6 @@ implementation
|
||||
end;
|
||||
|
||||
{ we need the real called method }
|
||||
{ rg.cleartempgen;}
|
||||
do_resulttypepass(p2);
|
||||
|
||||
if p2.nodetype<>calln then
|
||||
@ -221,7 +226,7 @@ implementation
|
||||
|
||||
{ create statements with call to getmem+initialize or
|
||||
finalize+freemem }
|
||||
new_dispose_statement:=internalstatements(newstatement);
|
||||
new_dispose_statement:=internalstatements(newstatement,true);
|
||||
|
||||
if is_new then
|
||||
begin
|
||||
@ -292,22 +297,31 @@ implementation
|
||||
if p1.nodetype<>typen then
|
||||
begin
|
||||
Message(type_e_type_id_expected);
|
||||
consume_all_until(_RKLAMMER);
|
||||
consume(_RKLAMMER);
|
||||
p1.destroy;
|
||||
p1:=cerrornode.create;
|
||||
do_resulttypepass(p1);
|
||||
new_function:=cerrornode.create;
|
||||
exit;
|
||||
end;
|
||||
|
||||
if (p1.resulttype.def.deftype<>pointerdef) then
|
||||
Message1(type_e_pointer_type_expected,p1.resulttype.def.typename)
|
||||
else
|
||||
if token=_RKLAMMER then
|
||||
begin
|
||||
Message1(type_e_pointer_type_expected,p1.resulttype.def.typename);
|
||||
consume_all_until(_RKLAMMER);
|
||||
consume(_RKLAMMER);
|
||||
p1.destroy;
|
||||
new_function:=cerrornode.create;
|
||||
exit;
|
||||
end;
|
||||
|
||||
if try_to_consume(_RKLAMMER) then
|
||||
begin
|
||||
if (tpointerdef(p1.resulttype.def).pointertype.def.deftype=objectdef) and
|
||||
(oo_has_vmt in tobjectdef(tpointerdef(p1.resulttype.def).pointertype.def).objectoptions) then
|
||||
Message(parser_w_use_extended_syntax_for_objects);
|
||||
|
||||
{ create statements with call to getmem+initialize }
|
||||
newblock:=internalstatements(newstatement);
|
||||
newblock:=internalstatements(newstatement,true);
|
||||
|
||||
{ create temp for result }
|
||||
temp := ctempcreatenode.create(p1.resulttype,p1.resulttype.def.size,true);
|
||||
@ -339,40 +353,45 @@ implementation
|
||||
|
||||
p1.destroy;
|
||||
p1:=newblock;
|
||||
consume(_RKLAMMER);
|
||||
end
|
||||
else
|
||||
begin
|
||||
p2:=chnewnode.create(tpointerdef(p1.resulttype.def).pointertype);
|
||||
do_resulttypepass(p2);
|
||||
consume(_COMMA);
|
||||
afterassignment:=false;
|
||||
{ determines the current object defintion }
|
||||
classh:=tobjectdef(p2.resulttype.def);
|
||||
if classh.deftype=objectdef then
|
||||
if tpointerdef(p1.resulttype.def).pointertype.def.deftype<>objectdef then
|
||||
begin
|
||||
{ check for an abstract class }
|
||||
if (oo_has_abstract in classh.objectoptions) then
|
||||
Message(sym_e_no_instance_of_abstract_object);
|
||||
{ search the constructor also in the symbol tables of
|
||||
the parents }
|
||||
sym:=searchsym_in_class(classh,pattern);
|
||||
consume(_ID);
|
||||
do_member_read(false,sym,p2,again);
|
||||
{ we need to know which procedure is called }
|
||||
do_resulttypepass(p2);
|
||||
if (p2.nodetype<>calln) or
|
||||
(assigned(tcallnode(p2).procdefinition) and
|
||||
(tcallnode(p2).procdefinition.proctypeoption<>potype_constructor)) then
|
||||
Message(parser_e_expr_have_to_be_constructor_call);
|
||||
end
|
||||
else
|
||||
Message(parser_e_pointer_to_class_expected);
|
||||
Message(parser_e_pointer_to_class_expected);
|
||||
consume_all_until(_RKLAMMER);
|
||||
consume(_RKLAMMER);
|
||||
p1.destroy;
|
||||
new_function:=cerrornode.create;
|
||||
exit;
|
||||
end;
|
||||
classh:=tobjectdef(tpointerdef(p1.resulttype.def).pointertype.def);
|
||||
{ check for an abstract class }
|
||||
if (oo_has_abstract in classh.objectoptions) then
|
||||
Message(sym_e_no_instance_of_abstract_object);
|
||||
{ use the objectdef for loading the VMT }
|
||||
p2:=p1;
|
||||
p1:=ctypenode.create(tpointerdef(p1.resulttype.def).pointertype);
|
||||
do_resulttypepass(p1);
|
||||
{ search the constructor also in the symbol tables of
|
||||
the parents }
|
||||
afterassignment:=false;
|
||||
sym:=searchsym_in_class(classh,pattern);
|
||||
consume(_ID);
|
||||
do_member_read(false,sym,p1,again,[nf_new_call]);
|
||||
{ we need to know which procedure is called }
|
||||
do_resulttypepass(p1);
|
||||
if not(
|
||||
(p1.nodetype=calln) and
|
||||
assigned(tcallnode(p1).procdefinition) and
|
||||
(tcallnode(p1).procdefinition.proctypeoption=potype_constructor)
|
||||
) then
|
||||
Message(parser_e_expr_have_to_be_constructor_call);
|
||||
{ constructors return boolean, update resulttype to return
|
||||
the pointer to the object }
|
||||
p2.resulttype:=p1.resulttype;
|
||||
p1.destroy;
|
||||
p1:=p2;
|
||||
p1.resulttype:=p2.resulttype;
|
||||
p2.free;
|
||||
consume(_RKLAMMER);
|
||||
end;
|
||||
new_function:=p1;
|
||||
@ -465,7 +484,7 @@ implementation
|
||||
begin
|
||||
{ create statements with call initialize the arguments and
|
||||
call fpc_dynarr_setlength }
|
||||
newblock:=internalstatements(newstatement);
|
||||
newblock:=internalstatements(newstatement,true);
|
||||
|
||||
{ get temp for array of lengths }
|
||||
temp := ctempcreatenode.create(s32bittype,counter*s32bittype.def.size,true);
|
||||
@ -627,7 +646,7 @@ implementation
|
||||
end;
|
||||
|
||||
{ create statements with call }
|
||||
copynode:=internalstatements(newstatement);
|
||||
copynode:=internalstatements(newstatement,true);
|
||||
|
||||
if (counter=3) then
|
||||
begin
|
||||
@ -680,7 +699,15 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.11 2002-11-26 22:59:09 peter
|
||||
Revision 1.13 2003-05-09 17:47:03 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.12 2002/04/25 20:15:40 florian
|
||||
* block nodes within expressions shouldn't release the used registers,
|
||||
fixed using a flag till the new rg is ready
|
||||
|
||||
Revision 1.11 2002/11/26 22:59:09 peter
|
||||
* fix Copy(array,x,y)
|
||||
|
||||
Revision 1.10 2002/11/25 17:43:22 peter
|
||||
|
@ -597,11 +597,11 @@ implementation
|
||||
is_class(ttypesym(srsym).restype.def) then
|
||||
begin
|
||||
ot:=ttypesym(srsym).restype;
|
||||
sym:=tvarsym.create(objrealname,ot);
|
||||
sym:=tvarsym.create(objrealname,vs_value,ot);
|
||||
end
|
||||
else
|
||||
begin
|
||||
sym:=tvarsym.create(objrealname,generrortype);
|
||||
sym:=tvarsym.create(objrealname,vs_value,generrortype);
|
||||
if (srsym.typ=typesym) then
|
||||
Message1(type_e_class_type_expected,ttypesym(srsym).restype.def.typename)
|
||||
else
|
||||
@ -1131,7 +1131,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.95 2003-04-30 22:15:59 florian
|
||||
Revision 1.96 2003-05-09 17:47:03 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.95 2003/04/30 22:15:59 florian
|
||||
* some 64 bit adaptions in ncgadd
|
||||
* x86-64 now uses ncgadd
|
||||
* tparamanager.ret_in_acc doesn't return true anymore for a void-def
|
||||
|
@ -542,9 +542,8 @@ implementation
|
||||
if copy(name,1,3)='val' then
|
||||
begin
|
||||
pd:=tprocdef(owner.defowner);
|
||||
vs:=tvarsym.create(Copy(name,4,255),vartype);
|
||||
vs:=tvarsym.create(Copy(name,4,255),varspez,vartype);
|
||||
vs.fileinfo:=fileinfo;
|
||||
vs.varspez:=varspez;
|
||||
if not assigned(pd.localst) then
|
||||
pd.insert_localst;
|
||||
pd.localst.insert(vs);
|
||||
@ -843,7 +842,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.107 2003-04-27 11:21:34 peter
|
||||
Revision 1.108 2003-05-09 17:47:03 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.107 2003/04/27 11:21:34 peter
|
||||
* aktprocdef renamed to current_procdef
|
||||
* procinfo renamed to current_procinfo
|
||||
* procinfo will now be stored in current_module so it can be
|
||||
|
@ -198,12 +198,12 @@ implementation
|
||||
vmtsymtable:=trecordsymtable.create;
|
||||
vmttype.setdef(trecorddef.create(vmtsymtable));
|
||||
pvmttype.setdef(tpointerdef.create(vmttype));
|
||||
vmtsymtable.insert(tvarsym.create('$parent',pvmttype));
|
||||
vmtsymtable.insert(tvarsym.create('$length',s32bittype));
|
||||
vmtsymtable.insert(tvarsym.create('$mlength',s32bittype));
|
||||
vmtsymtable.insert(tvarsym.create('$parent',vs_value,pvmttype));
|
||||
vmtsymtable.insert(tvarsym.create('$length',vs_value,s32bittype));
|
||||
vmtsymtable.insert(tvarsym.create('$mlength',vs_value,s32bittype));
|
||||
vmtarraytype.setdef(tarraydef.create(0,1,s32bittype));
|
||||
tarraydef(vmtarraytype.def).setelementtype(voidpointertype);
|
||||
vmtsymtable.insert(tvarsym.create('$__pfn',vmtarraytype));
|
||||
vmtsymtable.insert(tvarsym.create('$__pfn',vs_value,vmtarraytype));
|
||||
addtype('$__vtbl_ptr_type',vmttype);
|
||||
addtype('$pvmt',pvmttype);
|
||||
vmtarraytype.setdef(tarraydef.create(0,1,s32bittype));
|
||||
@ -389,14 +389,11 @@ implementation
|
||||
nodeclass[vecn]:=cvecnode;
|
||||
nodeclass[pointerconstn]:=cpointerconstnode;
|
||||
nodeclass[stringconstn]:=cstringconstnode;
|
||||
nodeclass[selfn]:=cselfnode;
|
||||
nodeclass[notn]:=cnotnode;
|
||||
nodeclass[inlinen]:=cinlinenode;
|
||||
nodeclass[niln]:=cnilnode;
|
||||
nodeclass[errorn]:=cerrornode;
|
||||
nodeclass[typen]:=ctypenode;
|
||||
nodeclass[hnewn]:=chnewnode;
|
||||
nodeclass[hdisposen]:=chdisposenode;
|
||||
nodeclass[setelementn]:=csetelementnode;
|
||||
nodeclass[setconstn]:=csetconstnode;
|
||||
nodeclass[blockn]:=cblocknode;
|
||||
@ -428,7 +425,7 @@ implementation
|
||||
nodeclass[tempdeleten]:=ctempdeletenode;
|
||||
nodeclass[addoptn]:=caddnode;
|
||||
nodeclass[nothingn]:=cnothingnode;
|
||||
nodeclass[loadvmtn]:=cloadvmtnode;
|
||||
nodeclass[loadvmtaddrn]:=cloadvmtaddrnode;
|
||||
nodeclass[guidconstn]:=cguidconstnode;
|
||||
nodeclass[rttin]:=crttinode;
|
||||
end;
|
||||
@ -491,7 +488,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.48 2003-05-01 07:59:42 florian
|
||||
Revision 1.49 2003-05-09 17:47:03 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.48 2003/05/01 07:59:42 florian
|
||||
* introduced defaultordconsttype to decribe the default size of ordinal constants
|
||||
on 64 bit CPUs it's equal to cs64bitdef while on 32 bit CPUs it's equal to s32bitdef
|
||||
+ added defines CPU32 and CPU64 for 32 bit and 64 bit CPUs
|
||||
|
@ -237,7 +237,7 @@ implementation
|
||||
begin
|
||||
p:=comp_expr(true);
|
||||
case p.nodetype of
|
||||
loadvmtn:
|
||||
loadvmtaddrn:
|
||||
begin
|
||||
if not(tobjectdef(tclassrefdef(p.resulttype.def).pointertype.def).is_related(
|
||||
tobjectdef(tclassrefdef(t.def).pointertype.def))) then
|
||||
@ -1004,7 +1004,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.68 2003-04-30 20:53:32 florian
|
||||
Revision 1.69 2003-05-09 17:47:03 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.68 2003/04/30 20:53:32 florian
|
||||
* error when address of an abstract method is taken
|
||||
* fixed some x86-64 problems
|
||||
* merged some more x86-64 and i386 code
|
||||
|
@ -455,6 +455,7 @@ implementation
|
||||
var
|
||||
p : tnode;
|
||||
pd : tabstractprocdef;
|
||||
is_func,
|
||||
enumdupmsg : boolean;
|
||||
begin
|
||||
tt.reset;
|
||||
@ -593,33 +594,25 @@ implementation
|
||||
begin
|
||||
tt.setdef(object_dec(name,nil));
|
||||
end;
|
||||
_PROCEDURE:
|
||||
begin
|
||||
consume(_PROCEDURE);
|
||||
tt.setdef(tprocvardef.create(normal_function_level));
|
||||
if token=_LKLAMMER then
|
||||
parse_parameter_dec(tprocvardef(tt.def));
|
||||
if token=_OF then
|
||||
begin
|
||||
consume(_OF);
|
||||
consume(_OBJECT);
|
||||
include(tprocvardef(tt.def).procoptions,po_methodpointer);
|
||||
check_self_para(tprocvardef(tt.def));
|
||||
end;
|
||||
end;
|
||||
_PROCEDURE,
|
||||
_FUNCTION:
|
||||
begin
|
||||
consume(_FUNCTION);
|
||||
is_func:=(token=_FUNCTION);
|
||||
consume(token);
|
||||
pd:=tprocvardef.create(normal_function_level);
|
||||
if token=_LKLAMMER then
|
||||
parse_parameter_dec(pd);
|
||||
consume(_COLON);
|
||||
single_type(pd.rettype,hs,false);
|
||||
if is_func then
|
||||
begin
|
||||
consume(_COLON);
|
||||
single_type(pd.rettype,hs,false);
|
||||
end;
|
||||
if token=_OF then
|
||||
begin
|
||||
consume(_OF);
|
||||
consume(_OBJECT);
|
||||
include(pd.procoptions,po_methodpointer);
|
||||
check_self_para(pd);
|
||||
end;
|
||||
{ Add implicit hidden parameters and function result }
|
||||
calc_parast(pd);
|
||||
@ -635,7 +628,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.53 2003-04-27 11:21:34 peter
|
||||
Revision 1.54 2003-05-09 17:47:03 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.53 2003/04/27 11:21:34 peter
|
||||
* aktprocdef renamed to current_procdef
|
||||
* procinfo renamed to current_procinfo
|
||||
* procinfo will now be stored in current_module so it can be
|
||||
|
@ -248,6 +248,8 @@ type
|
||||
vo_is_exported,
|
||||
vo_is_high_value,
|
||||
vo_is_funcret,
|
||||
vo_is_self,
|
||||
vo_is_vmt,
|
||||
vo_is_result { special result variable }
|
||||
);
|
||||
tvaroptions=set of tvaroption;
|
||||
@ -350,7 +352,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.53 2003-05-05 14:53:16 peter
|
||||
Revision 1.54 2003-05-09 17:47:03 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.53 2003/05/05 14:53:16 peter
|
||||
* vs_hidden replaced by is_hidden boolean
|
||||
|
||||
Revision 1.52 2003/04/27 11:21:34 peter
|
||||
|
@ -3334,13 +3334,16 @@ implementation
|
||||
end;
|
||||
if assigned(hp.paratype.def.typesym) then
|
||||
begin
|
||||
s:=s+' ';
|
||||
if s<>'(' then
|
||||
s:=s+' ';
|
||||
hs:=hp.paratype.def.typesym.realname;
|
||||
if hs[1]<>'$' then
|
||||
s:=s+hp.paratype.def.typesym.realname
|
||||
else
|
||||
s:=s+hp.paratype.def.gettypename;
|
||||
end;
|
||||
end
|
||||
else
|
||||
s:=s+hp.paratype.def.gettypename;
|
||||
{ default value }
|
||||
if assigned(hp.defaultvalue) then
|
||||
begin
|
||||
@ -3643,6 +3646,9 @@ implementation
|
||||
var
|
||||
s : string;
|
||||
begin
|
||||
{$ifdef EXTDEBUG}
|
||||
showhidden:=true;
|
||||
{$endif EXTDEBUG}
|
||||
s:='';
|
||||
if assigned(_class) then
|
||||
begin
|
||||
@ -3660,8 +3666,7 @@ implementation
|
||||
|
||||
function tprocdef.is_methodpointer:boolean;
|
||||
begin
|
||||
result:=assigned(owner) and
|
||||
(owner.symtabletype=objectsymtable);
|
||||
result:=assigned(_class);
|
||||
end;
|
||||
|
||||
|
||||
@ -4287,7 +4292,13 @@ implementation
|
||||
function tprocvardef.gettypename : string;
|
||||
var
|
||||
s: string;
|
||||
showhidden : boolean;
|
||||
begin
|
||||
{$ifdef EXTDEBUG}
|
||||
showhidden:=true;
|
||||
{$else EXTDEBUG}
|
||||
showhidden:=false;
|
||||
{$endif EXTDEBUG}
|
||||
s:='<';
|
||||
if po_classmethod in procoptions then
|
||||
s := s+'class method type of'
|
||||
@ -4298,9 +4309,9 @@ implementation
|
||||
s := s+'procedure variable type of';
|
||||
if assigned(rettype.def) and
|
||||
(rettype.def<>voidtype.def) then
|
||||
s:=s+' function'+typename_paras(false)+':'+rettype.def.gettypename
|
||||
s:=s+' function'+typename_paras(showhidden)+':'+rettype.def.gettypename
|
||||
else
|
||||
s:=s+' procedure'+typename_paras(false);
|
||||
s:=s+' procedure'+typename_paras(showhidden);
|
||||
if po_methodpointer in procoptions then
|
||||
s := s+' of object';
|
||||
gettypename := s+';'+ProcCallOptionStr[proccalloption]+'>';
|
||||
@ -5751,7 +5762,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.140 2003-05-05 14:53:16 peter
|
||||
Revision 1.141 2003-05-09 17:47:03 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.140 2003/05/05 14:53:16 peter
|
||||
* vs_hidden replaced by is_hidden boolean
|
||||
|
||||
Revision 1.139 2003/05/01 07:59:43 florian
|
||||
|
@ -184,9 +184,9 @@ interface
|
||||
varstate : tvarstate;
|
||||
paraitem : tparaitem;
|
||||
notifications : Tlinkedlist;
|
||||
constructor create(const n : string;const tt : ttype);
|
||||
constructor create_dll(const n : string;const tt : ttype);
|
||||
constructor create_C(const n,mangled : string;const tt : ttype);
|
||||
constructor create(const n : string;vsp:tvarspez;const tt : ttype);
|
||||
constructor create_dll(const n : string;vsp:tvarspez;const tt : ttype);
|
||||
constructor create_C(const n,mangled : string;vsp:tvarspez;const tt : ttype);
|
||||
constructor ppuload(ppufile:tcompilerppufile);
|
||||
destructor destroy;override;
|
||||
procedure ppuwrite(ppufile:tcompilerppufile);override;
|
||||
@ -981,7 +981,8 @@ implementation
|
||||
p:=pdlistfirst;
|
||||
while p<>nil do
|
||||
begin
|
||||
if p^.def.para.empty and is_boolean(p^.def.rettype.def) then
|
||||
if (p^.def.maxparacount=0) and
|
||||
is_boolean(p^.def.rettype.def) then
|
||||
begin
|
||||
search_procdef_nopara_boolret:=p^.def;
|
||||
break;
|
||||
@ -1455,14 +1456,14 @@ implementation
|
||||
|
||||
constructor tabsolutesym.create(const n : string;const tt : ttype);
|
||||
begin
|
||||
inherited create(n,tt);
|
||||
inherited create(n,vs_value,tt);
|
||||
typ:=absolutesym;
|
||||
end;
|
||||
|
||||
|
||||
constructor tabsolutesym.create_ref(const n : string;const tt : ttype;sym:tstoredsym);
|
||||
begin
|
||||
inherited create(n,tt);
|
||||
inherited create(n,vs_value,tt);
|
||||
typ:=absolutesym;
|
||||
ref:=sym;
|
||||
end;
|
||||
@ -1577,13 +1578,13 @@ implementation
|
||||
TVARSYM
|
||||
****************************************************************************}
|
||||
|
||||
constructor tvarsym.create(const n : string;const tt : ttype);
|
||||
constructor tvarsym.create(const n : string;vsp:tvarspez;const tt : ttype);
|
||||
begin
|
||||
inherited create(n);
|
||||
typ:=varsym;
|
||||
vartype:=tt;
|
||||
_mangledname:=nil;
|
||||
varspez:=vs_value;
|
||||
varspez:=vsp;
|
||||
address:=0;
|
||||
localvarsym:=nil;
|
||||
highvarsym:=nil;
|
||||
@ -1605,16 +1606,16 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
constructor tvarsym.create_dll(const n : string;const tt : ttype);
|
||||
constructor tvarsym.create_dll(const n : string;vsp:tvarspez;const tt : ttype);
|
||||
begin
|
||||
tvarsym(self).create(n,tt);
|
||||
tvarsym(self).create(n,vsp,tt);
|
||||
include(varoptions,vo_is_dll_var);
|
||||
end;
|
||||
|
||||
|
||||
constructor tvarsym.create_C(const n,mangled : string;const tt : ttype);
|
||||
constructor tvarsym.create_C(const n,mangled : string;vsp:tvarspez;const tt : ttype);
|
||||
begin
|
||||
tvarsym(self).create(n,tt);
|
||||
tvarsym(self).create(n,vsp,tt);
|
||||
stringdispose(_mangledname);
|
||||
_mangledname:=stringdup(mangled);
|
||||
end;
|
||||
@ -2557,7 +2558,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.101 2003-05-05 14:53:16 peter
|
||||
Revision 1.102 2003-05-09 17:47:03 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.101 2003/05/05 14:53:16 peter
|
||||
* vs_hidden replaced by is_hidden boolean
|
||||
|
||||
Revision 1.100 2003/04/27 11:21:34 peter
|
||||
|
@ -784,6 +784,7 @@ begin
|
||||
readsymref;
|
||||
write (space,' Symbol : ');
|
||||
readsymref;
|
||||
writeln(space,' Is Hidden : ',(ppufile.getbyte<>0));
|
||||
write (space,' Location : ');
|
||||
writeln('<not yet implemented>');
|
||||
paraloclen:=ppufile.getbyte;
|
||||
@ -1937,7 +1938,11 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.41 2003-04-27 07:29:52 peter
|
||||
Revision 1.42 2003-05-09 17:47:03 peter
|
||||
* self moved to hidden parameter
|
||||
* removed hdisposen,hnewn,selfn
|
||||
|
||||
Revision 1.41 2003/04/27 07:29:52 peter
|
||||
* aktprocdef cleanup, aktprocdef is now always nil when parsing
|
||||
a new procdef declaration
|
||||
* aktprocsym removed
|
||||
|
Loading…
Reference in New Issue
Block a user