mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 17:09:16 +02:00
* removed newn and disposen nodes, the code is now directly
inlined from pexpr * -an option that will write the secondpass nodes to the .s file, this requires EXTDEBUG define to actually write the info * fixed various internal errors and crashes due recent code changes
This commit is contained in:
parent
5ea6f2b824
commit
6320530bdd
@ -122,7 +122,7 @@ interface
|
|||||||
cs_gdb_dbx,cs_gdb_gsym,cs_gdb_heaptrc,cs_gdb_lineinfo,cs_checkpointer,
|
cs_gdb_dbx,cs_gdb_gsym,cs_gdb_heaptrc,cs_gdb_lineinfo,cs_checkpointer,
|
||||||
{ assembling }
|
{ assembling }
|
||||||
cs_asm_leave,cs_asm_extern,cs_asm_pipe,cs_asm_source,
|
cs_asm_leave,cs_asm_extern,cs_asm_pipe,cs_asm_source,
|
||||||
cs_asm_regalloc,cs_asm_tempalloc,
|
cs_asm_regalloc,cs_asm_tempalloc,cs_asm_nodes,
|
||||||
{ linking }
|
{ linking }
|
||||||
cs_link_extern,cs_link_static,cs_link_smart,cs_link_shared,cs_link_deffile,
|
cs_link_extern,cs_link_static,cs_link_smart,cs_link_shared,cs_link_deffile,
|
||||||
cs_link_strip,cs_link_staticflag,cs_link_on_target
|
cs_link_strip,cs_link_staticflag,cs_link_on_target
|
||||||
@ -253,7 +253,14 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.21 2002-03-24 19:05:59 carl
|
Revision 1.22 2002-04-21 19:02:03 peter
|
||||||
|
* removed newn and disposen nodes, the code is now directly
|
||||||
|
inlined from pexpr
|
||||||
|
* -an option that will write the secondpass nodes to the .s file, this
|
||||||
|
requires EXTDEBUG define to actually write the info
|
||||||
|
* fixed various internal errors and crashes due recent code changes
|
||||||
|
|
||||||
|
Revision 1.21 2002/03/24 19:05:59 carl
|
||||||
+ patch for SPARC from Mazen NEIFER
|
+ patch for SPARC from Mazen NEIFER
|
||||||
|
|
||||||
Revision 1.20 2002/01/24 18:25:48 peter
|
Revision 1.20 2002/01/24 18:25:48 peter
|
||||||
|
@ -63,7 +63,7 @@ implementation
|
|||||||
cginfo,cgbase,pass_2,
|
cginfo,cgbase,pass_2,
|
||||||
cpubase,
|
cpubase,
|
||||||
nmem,nld,ncnv,
|
nmem,nld,ncnv,
|
||||||
tainst,cga,cgobj,tgobj,n386ld,n386util,regvars,rgobj,rgcpu,cg64f32,cgcpu;
|
tainst,cga,cgobj,tgobj,n386ld,n386util,ncgutil,regvars,rgobj,rgcpu,cg64f32,cgcpu;
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
TI386CALLPARANODE
|
TI386CALLPARANODE
|
||||||
@ -133,6 +133,11 @@ implementation
|
|||||||
else if assigned(defcoll.paratype.def) and
|
else if assigned(defcoll.paratype.def) and
|
||||||
(defcoll.paratype.def.deftype=formaldef) then
|
(defcoll.paratype.def.deftype=formaldef) then
|
||||||
begin
|
begin
|
||||||
|
{ allow passing of a constant to a const formaldef }
|
||||||
|
if (defcoll.paratyp=vs_const) and
|
||||||
|
(left.location.loc=LOC_CONSTANT) then
|
||||||
|
location_force_mem(left.location);
|
||||||
|
|
||||||
{ allow @var }
|
{ allow @var }
|
||||||
inc(pushedparasize,4);
|
inc(pushedparasize,4);
|
||||||
if (left.nodetype=addrn) and
|
if (left.nodetype=addrn) and
|
||||||
@ -1477,7 +1482,14 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.46 2002-04-21 15:34:25 carl
|
Revision 1.47 2002-04-21 19:02:07 peter
|
||||||
|
* removed newn and disposen nodes, the code is now directly
|
||||||
|
inlined from pexpr
|
||||||
|
* -an option that will write the secondpass nodes to the .s file, this
|
||||||
|
requires EXTDEBUG define to actually write the info
|
||||||
|
* fixed various internal errors and crashes due recent code changes
|
||||||
|
|
||||||
|
Revision 1.46 2002/04/21 15:34:25 carl
|
||||||
* changeregsize -> rg.makeregsize
|
* changeregsize -> rg.makeregsize
|
||||||
|
|
||||||
Revision 1.45 2002/04/15 19:44:21 peter
|
Revision 1.45 2002/04/15 19:44:21 peter
|
||||||
|
@ -249,7 +249,15 @@ implementation
|
|||||||
end;
|
end;
|
||||||
LOC_REGISTER,LOC_CREGISTER :
|
LOC_REGISTER,LOC_CREGISTER :
|
||||||
begin
|
begin
|
||||||
cg.a_op_reg_reg(exprasmlist,OP_OR,left.location.size,left.location.register,left.location.register);
|
if left.location.size in [OS_64,OS_S64] then
|
||||||
|
begin
|
||||||
|
hregister:=cg.get_scratch_reg(exprasmlist);
|
||||||
|
cg.a_load_reg_reg(exprasmlist,OS_32,left.location.registerlow,hregister);
|
||||||
|
cg.a_op_reg_reg(exprasmlist,OP_OR,OS_32,left.location.registerhigh,hregister);
|
||||||
|
cg.free_scratch_reg(exprasmlist,hregister);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
cg.a_op_reg_reg(exprasmlist,OP_OR,left.location.size,left.location.register,left.location.register);
|
||||||
end;
|
end;
|
||||||
LOC_JUMP :
|
LOC_JUMP :
|
||||||
begin
|
begin
|
||||||
@ -364,7 +372,14 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.36 2002-04-21 15:35:23 carl
|
Revision 1.37 2002-04-21 19:02:07 peter
|
||||||
|
* removed newn and disposen nodes, the code is now directly
|
||||||
|
inlined from pexpr
|
||||||
|
* -an option that will write the secondpass nodes to the .s file, this
|
||||||
|
requires EXTDEBUG define to actually write the info
|
||||||
|
* fixed various internal errors and crashes due recent code changes
|
||||||
|
|
||||||
|
Revision 1.36 2002/04/21 15:35:23 carl
|
||||||
* changeregsize -> rg.makeregsize
|
* changeregsize -> rg.makeregsize
|
||||||
|
|
||||||
Revision 1.35 2002/04/19 15:39:35 peter
|
Revision 1.35 2002/04/19 15:39:35 peter
|
||||||
|
@ -30,18 +30,10 @@ interface
|
|||||||
node,nmem,ncgmem;
|
node,nmem,ncgmem;
|
||||||
|
|
||||||
type
|
type
|
||||||
ti386newnode = class(tnewnode)
|
|
||||||
procedure pass_2;override;
|
|
||||||
end;
|
|
||||||
|
|
||||||
ti386addrnode = class(tcgaddrnode)
|
ti386addrnode = class(tcgaddrnode)
|
||||||
procedure pass_2;override;
|
procedure pass_2;override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
ti386simplenewdisposenode = class(tsimplenewdisposenode)
|
|
||||||
procedure pass_2;override;
|
|
||||||
end;
|
|
||||||
|
|
||||||
ti386derefnode = class(tcgderefnode)
|
ti386derefnode = class(tcgderefnode)
|
||||||
procedure pass_2;override;
|
procedure pass_2;override;
|
||||||
end;
|
end;
|
||||||
@ -64,54 +56,6 @@ implementation
|
|||||||
cpuinfo,cpubase,
|
cpuinfo,cpubase,
|
||||||
cgobj,cga,tgobj,rgobj,ncgutil,n386util;
|
cgobj,cga,tgobj,rgobj,ncgutil,n386util;
|
||||||
|
|
||||||
{*****************************************************************************
|
|
||||||
TI386NEWNODE
|
|
||||||
*****************************************************************************}
|
|
||||||
|
|
||||||
procedure ti386newnode.pass_2;
|
|
||||||
var
|
|
||||||
pushed : tpushedsaved;
|
|
||||||
regstopush: tregisterset;
|
|
||||||
href : treference;
|
|
||||||
begin
|
|
||||||
if assigned(left) then
|
|
||||||
begin
|
|
||||||
secondpass(left);
|
|
||||||
location_copy(location,left.location);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
location_reset(location,LOC_REFERENCE,OS_ADDR);
|
|
||||||
|
|
||||||
regstopush := all_registers;
|
|
||||||
remove_non_regvars_from_loc(location,regstopush);
|
|
||||||
rg.saveusedregisters(exprasmlist,pushed,regstopush);
|
|
||||||
|
|
||||||
tg.gettempofsizereference(exprasmlist,pointer_size,location.reference);
|
|
||||||
|
|
||||||
{ determines the size of the mem block }
|
|
||||||
push_int(tpointerdef(resulttype.def).pointertype.def.size);
|
|
||||||
emit_push_lea_loc(location,false);
|
|
||||||
rg.saveregvars(exprasmlist,all_registers);
|
|
||||||
emitcall('FPC_GETMEM');
|
|
||||||
|
|
||||||
if tpointerdef(resulttype.def).pointertype.def.needs_inittable then
|
|
||||||
begin
|
|
||||||
reference_reset_symbol(href,tstoreddef(tpointerdef(resulttype.def).pointertype.def).get_rtti_label(initrtti),0);
|
|
||||||
emitpushreferenceaddr(href);
|
|
||||||
|
|
||||||
{ push pointer we just allocated, we need to initialize the
|
|
||||||
data located at that pointer not the pointer self (PFV) }
|
|
||||||
cg.a_param_loc(exprasmlist,location,1);
|
|
||||||
emitcall('FPC_INITIALIZE');
|
|
||||||
end;
|
|
||||||
rg.restoreusedregisters(exprasmlist,pushed);
|
|
||||||
{ may be load ESI }
|
|
||||||
maybe_loadself;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
TI386ADDRNODE
|
TI386ADDRNODE
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
@ -125,86 +69,6 @@ implementation
|
|||||||
location.segment:=left.location.reference.segment;
|
location.segment:=left.location.reference.segment;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{*****************************************************************************
|
|
||||||
TI386SIMPLENEWDISPOSENODE
|
|
||||||
*****************************************************************************}
|
|
||||||
|
|
||||||
procedure ti386simplenewdisposenode.pass_2;
|
|
||||||
|
|
||||||
var
|
|
||||||
regstopush: tregisterset;
|
|
||||||
pushed : tpushedsaved;
|
|
||||||
href : treference;
|
|
||||||
lefttemp: treference;
|
|
||||||
left_needs_initfinal: boolean;
|
|
||||||
|
|
||||||
procedure saveleft;
|
|
||||||
begin
|
|
||||||
tg.gettempofsizereference(exprasmlist,pointer_size,lefttemp);
|
|
||||||
cg.a_load_loc_ref(exprasmlist,left.location,lefttemp);
|
|
||||||
location_release(exprasmlist,left.location);
|
|
||||||
end;
|
|
||||||
|
|
||||||
begin
|
|
||||||
secondpass(left);
|
|
||||||
if codegenerror then
|
|
||||||
exit;
|
|
||||||
|
|
||||||
left_needs_initfinal:=tpointerdef(left.resulttype.def).pointertype.def.needs_inittable;
|
|
||||||
|
|
||||||
regstopush := all_registers;
|
|
||||||
remove_non_regvars_from_loc(left.location,regstopush);
|
|
||||||
rg.saveusedregisters(exprasmlist,pushed,regstopush);
|
|
||||||
rg.saveregvars(exprasmlist,all_registers);
|
|
||||||
|
|
||||||
{ call the mem handling procedures }
|
|
||||||
case nodetype of
|
|
||||||
simpledisposen:
|
|
||||||
begin
|
|
||||||
if left_needs_initfinal then
|
|
||||||
begin
|
|
||||||
reference_reset_symbol(href,tstoreddef(tpointerdef(left.resulttype.def).pointertype.def).get_rtti_label(initrtti),0);
|
|
||||||
emitpushreferenceaddr(href);
|
|
||||||
{ push pointer adress }
|
|
||||||
cg.a_param_loc(exprasmlist,left.location,1);
|
|
||||||
{ save left and free its registers }
|
|
||||||
saveleft;
|
|
||||||
emitcall('FPC_FINALIZE');
|
|
||||||
{ push left again as parameter for freemem }
|
|
||||||
emit_push_mem(lefttemp);
|
|
||||||
tg.ungetiftemp(exprasmlist,lefttemp);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
cg.a_param_loc(exprasmlist,left.location,1);
|
|
||||||
location_release(exprasmlist,left.location);
|
|
||||||
end;
|
|
||||||
emitcall('FPC_FREEMEM');
|
|
||||||
end;
|
|
||||||
simplenewn:
|
|
||||||
begin
|
|
||||||
{ determines the size of the mem block }
|
|
||||||
push_int(tpointerdef(left.resulttype.def).pointertype.def.size);
|
|
||||||
emit_push_lea_loc(left.location,true);
|
|
||||||
{ save left and free its registers }
|
|
||||||
if left_needs_initfinal then
|
|
||||||
saveleft;
|
|
||||||
emitcall('FPC_GETMEM');
|
|
||||||
if left_needs_initfinal then
|
|
||||||
begin
|
|
||||||
reference_reset_symbol(href,tstoreddef(tpointerdef(left.resulttype.def).pointertype.def).get_rtti_label(initrtti),0);
|
|
||||||
emitpushreferenceaddr(href);
|
|
||||||
emit_push_mem(lefttemp);
|
|
||||||
tg.ungetiftemp(exprasmlist,lefttemp);
|
|
||||||
emitcall('FPC_INITIALIZE');
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
rg.restoreusedregisters(exprasmlist,pushed);
|
|
||||||
{ may be load ESI }
|
|
||||||
maybe_loadself;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
TI386DEREFNODE
|
TI386DEREFNODE
|
||||||
@ -219,11 +83,11 @@ implementation
|
|||||||
if not tpointerdef(left.resulttype.def).is_far and
|
if not tpointerdef(left.resulttype.def).is_far and
|
||||||
(cs_gdb_heaptrc in aktglobalswitches) and
|
(cs_gdb_heaptrc in aktglobalswitches) and
|
||||||
(cs_checkpointer in aktglobalswitches) then
|
(cs_checkpointer in aktglobalswitches) then
|
||||||
begin
|
begin
|
||||||
emit_reg(
|
emit_reg(
|
||||||
A_PUSH,S_L,location.reference.base);
|
A_PUSH,S_L,location.reference.base);
|
||||||
emitcall('FPC_CHECKPOINTER');
|
emitcall('FPC_CHECKPOINTER');
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -655,15 +519,20 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
cnewnode:=ti386newnode;
|
|
||||||
csimplenewdisposenode:=ti386simplenewdisposenode;
|
|
||||||
caddrnode:=ti386addrnode;
|
caddrnode:=ti386addrnode;
|
||||||
cderefnode:=ti386derefnode;
|
cderefnode:=ti386derefnode;
|
||||||
cvecnode:=ti386vecnode;
|
cvecnode:=ti386vecnode;
|
||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.27 2002-04-20 21:37:07 carl
|
Revision 1.28 2002-04-21 19:02:07 peter
|
||||||
|
* removed newn and disposen nodes, the code is now directly
|
||||||
|
inlined from pexpr
|
||||||
|
* -an option that will write the secondpass nodes to the .s file, this
|
||||||
|
requires EXTDEBUG define to actually write the info
|
||||||
|
* fixed various internal errors and crashes due recent code changes
|
||||||
|
|
||||||
|
Revision 1.27 2002/04/20 21:37:07 carl
|
||||||
+ generic FPC_CHECKPOINTER
|
+ generic FPC_CHECKPOINTER
|
||||||
+ first parameter offset in stack now portable
|
+ first parameter offset in stack now portable
|
||||||
* rename some constants
|
* rename some constants
|
||||||
|
@ -899,7 +899,13 @@ implementation
|
|||||||
opsize:=bytes2Sxx[left.resulttype.def.size];
|
opsize:=bytes2Sxx[left.resulttype.def.size];
|
||||||
{ copy the case expression to a register }
|
{ copy the case expression to a register }
|
||||||
location_force_reg(left.location,def_cgsize(left.resulttype.def),false);
|
location_force_reg(left.location,def_cgsize(left.resulttype.def),false);
|
||||||
hregister:=left.location.register;
|
if opsize=S_Q then
|
||||||
|
begin
|
||||||
|
hregister:=left.location.registerlow;
|
||||||
|
hregister2:=left.location.registerhigh;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
hregister:=left.location.register;
|
||||||
if isjump then
|
if isjump then
|
||||||
begin
|
begin
|
||||||
truelabel:=otl;
|
truelabel:=otl;
|
||||||
@ -1030,7 +1036,14 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.24 2002-04-21 15:37:26 carl
|
Revision 1.25 2002-04-21 19:02:07 peter
|
||||||
|
* removed newn and disposen nodes, the code is now directly
|
||||||
|
inlined from pexpr
|
||||||
|
* -an option that will write the secondpass nodes to the .s file, this
|
||||||
|
requires EXTDEBUG define to actually write the info
|
||||||
|
* fixed various internal errors and crashes due recent code changes
|
||||||
|
|
||||||
|
Revision 1.24 2002/04/21 15:37:26 carl
|
||||||
* changeregsize -> rg.makeregsize
|
* changeregsize -> rg.makeregsize
|
||||||
|
|
||||||
Revision 1.23 2002/04/19 15:39:35 peter
|
Revision 1.23 2002/04/19 15:39:35 peter
|
||||||
|
@ -81,7 +81,6 @@ interface
|
|||||||
{ refs and deletenode can hook to this copy once they get copied too }
|
{ refs and deletenode can hook to this copy once they get copied too }
|
||||||
hookoncopy : ptempinfo;
|
hookoncopy : ptempinfo;
|
||||||
ref : treference;
|
ref : treference;
|
||||||
size : longint;
|
|
||||||
restype : ttype;
|
restype : ttype;
|
||||||
valid : boolean;
|
valid : boolean;
|
||||||
end;
|
end;
|
||||||
@ -91,6 +90,7 @@ interface
|
|||||||
ttempcreatenode = class(tnode)
|
ttempcreatenode = class(tnode)
|
||||||
size: longint;
|
size: longint;
|
||||||
tempinfo: ptempinfo;
|
tempinfo: ptempinfo;
|
||||||
|
persistent: boolean;
|
||||||
{ * persistent temps are used in manually written code where the temp }
|
{ * persistent temps are used in manually written code where the temp }
|
||||||
{ be usable among different statements and where you can manually say }
|
{ be usable among different statements and where you can manually say }
|
||||||
{ when the temp has to be freed (using a ttempdeletenode) }
|
{ when the temp has to be freed (using a ttempdeletenode) }
|
||||||
@ -103,8 +103,6 @@ interface
|
|||||||
function pass_1 : tnode; override;
|
function pass_1 : tnode; override;
|
||||||
function det_resulttype: tnode; override;
|
function det_resulttype: tnode; override;
|
||||||
function docompare(p: tnode): boolean; override;
|
function docompare(p: tnode): boolean; override;
|
||||||
protected
|
|
||||||
persistent: boolean;
|
|
||||||
end;
|
end;
|
||||||
ttempcreatenodeclass = class of ttempcreatenode;
|
ttempcreatenodeclass = class of ttempcreatenode;
|
||||||
|
|
||||||
@ -123,6 +121,9 @@ interface
|
|||||||
{ a node which removes a temp }
|
{ a node which removes a temp }
|
||||||
ttempdeletenode = class(tnode)
|
ttempdeletenode = class(tnode)
|
||||||
constructor create(const temp: ttempcreatenode);
|
constructor create(const temp: ttempcreatenode);
|
||||||
|
{ this will convert the persistant temp to a normal temp
|
||||||
|
for returning to the other nodes }
|
||||||
|
constructor create_normal_temp(const temp: ttempcreatenode);
|
||||||
function getcopy: tnode; override;
|
function getcopy: tnode; override;
|
||||||
function pass_1: tnode; override;
|
function pass_1: tnode; override;
|
||||||
function det_resulttype: tnode; override;
|
function det_resulttype: tnode; override;
|
||||||
@ -130,6 +131,7 @@ interface
|
|||||||
destructor destroy; override;
|
destructor destroy; override;
|
||||||
protected
|
protected
|
||||||
tempinfo: ptempinfo;
|
tempinfo: ptempinfo;
|
||||||
|
release_to_normal : boolean;
|
||||||
end;
|
end;
|
||||||
ttempdeletenodeclass = class of ttempdeletenode;
|
ttempdeletenodeclass = class of ttempdeletenode;
|
||||||
|
|
||||||
@ -143,6 +145,12 @@ interface
|
|||||||
ctemprefnode : ttemprefnodeclass;
|
ctemprefnode : ttemprefnodeclass;
|
||||||
ctempdeletenode : ttempdeletenodeclass;
|
ctempdeletenode : ttempdeletenodeclass;
|
||||||
|
|
||||||
|
{ Create a blocknode and statement node for multiple statements
|
||||||
|
generated internally by the parser }
|
||||||
|
function internalstatements(var laststatement:tstatementnode):tblocknode;
|
||||||
|
procedure addstatement(var laststatement:tstatementnode;n:tnode);
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
@ -153,6 +161,28 @@ implementation
|
|||||||
ncal,nflw,rgobj,cgbase
|
ncal,nflw,rgobj,cgbase
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
{*****************************************************************************
|
||||||
|
Helpers
|
||||||
|
*****************************************************************************}
|
||||||
|
|
||||||
|
function internalstatements(var laststatement:tstatementnode):tblocknode;
|
||||||
|
begin
|
||||||
|
{ create dummy initial statement }
|
||||||
|
laststatement := cstatementnode.create(nil,cnothingnode.create);
|
||||||
|
internalstatements := cblocknode.create(laststatement);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure addstatement(var laststatement:tstatementnode;n:tnode);
|
||||||
|
begin
|
||||||
|
if assigned(laststatement.left) then
|
||||||
|
internalerror(200204201);
|
||||||
|
laststatement.left:=cstatementnode.create(nil,n);
|
||||||
|
laststatement:=tstatementnode(laststatement.left);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
TFIRSTNOTHING
|
TFIRSTNOTHING
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
@ -239,6 +269,7 @@ implementation
|
|||||||
firstpass(right);
|
firstpass(right);
|
||||||
if codegenerror then
|
if codegenerror then
|
||||||
exit;
|
exit;
|
||||||
|
location.loc:=right.location.loc;
|
||||||
registers32:=right.registers32;
|
registers32:=right.registers32;
|
||||||
registersfpu:=right.registersfpu;
|
registersfpu:=right.registersfpu;
|
||||||
{$ifdef SUPPORT_MMX}
|
{$ifdef SUPPORT_MMX}
|
||||||
@ -306,6 +337,11 @@ implementation
|
|||||||
(tcallnode(hp.right).procdefinition.proctypeoption=potype_constructor)) and
|
(tcallnode(hp.right).procdefinition.proctypeoption=potype_constructor)) and
|
||||||
not(is_void(hp.right.resulttype.def)) then
|
not(is_void(hp.right.resulttype.def)) then
|
||||||
CGMessage(cg_e_illegal_expression);
|
CGMessage(cg_e_illegal_expression);
|
||||||
|
{ the resulttype of the block is the last type that is
|
||||||
|
returned. Normally this is a voidtype. But when the
|
||||||
|
compiler inserts a block of multiple statements then the
|
||||||
|
last entry can return a value }
|
||||||
|
resulttype:=hp.right.resulttype;
|
||||||
end;
|
end;
|
||||||
hp:=tstatementnode(hp.left);
|
hp:=tstatementnode(hp.left);
|
||||||
end;
|
end;
|
||||||
@ -389,6 +425,7 @@ implementation
|
|||||||
if hp.registersmmx>registersmmx then
|
if hp.registersmmx>registersmmx then
|
||||||
registersmmx:=hp.registersmmx;
|
registersmmx:=hp.registersmmx;
|
||||||
{$endif}
|
{$endif}
|
||||||
|
location.loc:=hp.location.loc;
|
||||||
inc(count);
|
inc(count);
|
||||||
hp:=tstatementnode(hp.left);
|
hp:=tstatementnode(hp.left);
|
||||||
end;
|
end;
|
||||||
@ -456,7 +493,6 @@ implementation
|
|||||||
new(tempinfo);
|
new(tempinfo);
|
||||||
fillchar(tempinfo^,sizeof(tempinfo^),0);
|
fillchar(tempinfo^,sizeof(tempinfo^),0);
|
||||||
tempinfo^.restype := _restype;
|
tempinfo^.restype := _restype;
|
||||||
tempinfo^.size := _size;
|
|
||||||
persistent := _persistent;
|
persistent := _persistent;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -470,7 +506,6 @@ implementation
|
|||||||
new(n.tempinfo);
|
new(n.tempinfo);
|
||||||
fillchar(n.tempinfo^,sizeof(n.tempinfo^),0);
|
fillchar(n.tempinfo^,sizeof(n.tempinfo^),0);
|
||||||
n.tempinfo^.restype := tempinfo^.restype;
|
n.tempinfo^.restype := tempinfo^.restype;
|
||||||
n.tempinfo^.size:=size;
|
|
||||||
|
|
||||||
{ signal the temprefs that the temp they point to has been copied, }
|
{ signal the temprefs that the temp they point to has been copied, }
|
||||||
{ so that if the refs get copied as well, they can hook themselves }
|
{ so that if the refs get copied as well, they can hook themselves }
|
||||||
@ -562,6 +597,16 @@ implementation
|
|||||||
begin
|
begin
|
||||||
inherited create(temprefn);
|
inherited create(temprefn);
|
||||||
tempinfo := temp.tempinfo;
|
tempinfo := temp.tempinfo;
|
||||||
|
release_to_normal := false;
|
||||||
|
if not temp.persistent then
|
||||||
|
internalerror(200204211);
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor ttempdeletenode.create_normal_temp(const temp: ttempcreatenode);
|
||||||
|
begin
|
||||||
|
inherited create(temprefn);
|
||||||
|
tempinfo := temp.tempinfo;
|
||||||
|
release_to_normal := true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ttempdeletenode.getcopy: tnode;
|
function ttempdeletenode.getcopy: tnode;
|
||||||
@ -620,7 +665,14 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.20 2002-04-04 19:05:57 peter
|
Revision 1.21 2002-04-21 19:02:03 peter
|
||||||
|
* removed newn and disposen nodes, the code is now directly
|
||||||
|
inlined from pexpr
|
||||||
|
* -an option that will write the secondpass nodes to the .s file, this
|
||||||
|
requires EXTDEBUG define to actually write the info
|
||||||
|
* fixed various internal errors and crashes due recent code changes
|
||||||
|
|
||||||
|
Revision 1.20 2002/04/04 19:05:57 peter
|
||||||
* removed unused units
|
* removed unused units
|
||||||
* use tlocation.size in cg.a_*loc*() routines
|
* use tlocation.size in cg.a_*loc*() routines
|
||||||
|
|
||||||
|
@ -94,6 +94,8 @@ interface
|
|||||||
begin
|
begin
|
||||||
rg.cleartempgen;
|
rg.cleartempgen;
|
||||||
secondpass(tstatementnode(hp).right);
|
secondpass(tstatementnode(hp).right);
|
||||||
|
{ Compiler inserted blocks can return values }
|
||||||
|
location_copy(location,tstatementnode(hp).right.location);
|
||||||
end;
|
end;
|
||||||
hp:=tstatementnode(hp).left;
|
hp:=tstatementnode(hp).left;
|
||||||
end;
|
end;
|
||||||
@ -223,7 +225,11 @@ interface
|
|||||||
begin
|
begin
|
||||||
{ do second pass on left node }
|
{ do second pass on left node }
|
||||||
if assigned(left) then
|
if assigned(left) then
|
||||||
secondpass(left);
|
begin
|
||||||
|
secondpass(left);
|
||||||
|
{ Compiler inserted blocks can return values }
|
||||||
|
location_copy(location,left.location);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
@ -255,7 +261,7 @@ interface
|
|||||||
if not tempinfo^.valid then
|
if not tempinfo^.valid then
|
||||||
internalerror(200108231);
|
internalerror(200108231);
|
||||||
{ set the temp's location }
|
{ set the temp's location }
|
||||||
location_reset(location,LOC_REFERENCE,int_cgsize(tempinfo^.size));
|
location_reset(location,LOC_REFERENCE,def_cgsize(tempinfo^.restype.def));
|
||||||
location.reference := tempinfo^.ref;
|
location.reference := tempinfo^.ref;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -265,7 +271,10 @@ interface
|
|||||||
|
|
||||||
procedure tcgtempdeletenode.pass_2;
|
procedure tcgtempdeletenode.pass_2;
|
||||||
begin
|
begin
|
||||||
tg.ungetpersistanttempreference(exprasmlist,tempinfo^.ref);
|
if release_to_normal then
|
||||||
|
tg.persistanttemptonormal(tempinfo^.ref.offset)
|
||||||
|
else
|
||||||
|
tg.ungetpersistanttempreference(exprasmlist,tempinfo^.ref);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -280,7 +289,14 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.12 2002-04-04 19:05:57 peter
|
Revision 1.13 2002-04-21 19:02:03 peter
|
||||||
|
* removed newn and disposen nodes, the code is now directly
|
||||||
|
inlined from pexpr
|
||||||
|
* -an option that will write the secondpass nodes to the .s file, this
|
||||||
|
requires EXTDEBUG define to actually write the info
|
||||||
|
* fixed various internal errors and crashes due recent code changes
|
||||||
|
|
||||||
|
Revision 1.12 2002/04/04 19:05:57 peter
|
||||||
* removed unused units
|
* removed unused units
|
||||||
* use tlocation.size in cg.a_*loc*() routines
|
* use tlocation.size in cg.a_*loc*() routines
|
||||||
|
|
||||||
|
@ -390,8 +390,15 @@ interface
|
|||||||
begin
|
begin
|
||||||
{ we reuse the old value }
|
{ we reuse the old value }
|
||||||
location_copy(location,left.location);
|
location_copy(location,left.location);
|
||||||
|
|
||||||
|
{ Floats should never be returned as LOC_CONSTANT, do the
|
||||||
|
moving to memory before the new size is set }
|
||||||
|
if (resulttype.def.deftype=floatdef) and
|
||||||
|
(location.loc=LOC_CONSTANT) then
|
||||||
|
location_force_mem(location);
|
||||||
|
|
||||||
{ but use the new size, but we don't know the size of all arrays }
|
{ but use the new size, but we don't know the size of all arrays }
|
||||||
location.size:=def_cgsize(resulttype.def)
|
location.size:=def_cgsize(resulttype.def);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -434,7 +441,14 @@ end.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.10 2002-04-19 15:39:34 peter
|
Revision 1.11 2002-04-21 19:02:03 peter
|
||||||
|
* removed newn and disposen nodes, the code is now directly
|
||||||
|
inlined from pexpr
|
||||||
|
* -an option that will write the secondpass nodes to the .s file, this
|
||||||
|
requires EXTDEBUG define to actually write the info
|
||||||
|
* fixed various internal errors and crashes due recent code changes
|
||||||
|
|
||||||
|
Revision 1.10 2002/04/19 15:39:34 peter
|
||||||
* removed some more routines from cga
|
* removed some more routines from cga
|
||||||
* moved location_force_reg/mem to ncgutil
|
* moved location_force_reg/mem to ncgutil
|
||||||
* moved arrayconstructnode secondpass to ncgld
|
* moved arrayconstructnode secondpass to ncgld
|
||||||
|
@ -298,6 +298,7 @@ implementation
|
|||||||
LOC_FPUREGISTER,
|
LOC_FPUREGISTER,
|
||||||
LOC_CFPUREGISTER :
|
LOC_CFPUREGISTER :
|
||||||
begin
|
begin
|
||||||
|
tg.gettempofsizereference(exprasmlist,TCGSize2Size[l.size],r);
|
||||||
cg.a_loadfpu_reg_ref(exprasmlist,l.size,l.register,r);
|
cg.a_loadfpu_reg_ref(exprasmlist,l.size,l.register,r);
|
||||||
location_reset(l,LOC_REFERENCE,l.size);
|
location_reset(l,LOC_REFERENCE,l.size);
|
||||||
l.reference:=r;
|
l.reference:=r;
|
||||||
@ -382,7 +383,14 @@ end.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.9 2002-04-21 15:24:38 carl
|
Revision 1.10 2002-04-21 19:02:03 peter
|
||||||
|
* removed newn and disposen nodes, the code is now directly
|
||||||
|
inlined from pexpr
|
||||||
|
* -an option that will write the secondpass nodes to the .s file, this
|
||||||
|
requires EXTDEBUG define to actually write the info
|
||||||
|
* fixed various internal errors and crashes due recent code changes
|
||||||
|
|
||||||
|
Revision 1.9 2002/04/21 15:24:38 carl
|
||||||
+ a_jmp_cond -> a_jmp_always (a_jmp_cond is NOT portable)
|
+ a_jmp_cond -> a_jmp_always (a_jmp_cond is NOT portable)
|
||||||
+ changeregsize -> rg.makeregsize
|
+ changeregsize -> rg.makeregsize
|
||||||
|
|
||||||
|
@ -1485,8 +1485,12 @@ implementation
|
|||||||
if convtype=tc_equal then
|
if convtype=tc_equal then
|
||||||
begin
|
begin
|
||||||
{ remove typeconv node if left is a const. For other nodes we can't
|
{ remove typeconv node if left is a const. For other nodes we can't
|
||||||
remove it because the secondpass can still depend on the old type (PFV) }
|
remove it because the secondpass can still depend on the old type (PFV)
|
||||||
if is_constnode(left) then
|
Conversions to float should also be left in the tree, because a float
|
||||||
|
is not possible in LOC_CONSTANT. The second_nothing routine will take
|
||||||
|
care of the conversion to LOC_REFERENCE }
|
||||||
|
if is_constnode(left) and
|
||||||
|
(resulttype.def.deftype<>floatdef) then
|
||||||
begin
|
begin
|
||||||
left.resulttype:=resulttype;
|
left.resulttype:=resulttype;
|
||||||
result:=left;
|
result:=left;
|
||||||
@ -1701,7 +1705,14 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.51 2002-04-06 18:10:42 jonas
|
Revision 1.52 2002-04-21 19:02:03 peter
|
||||||
|
* removed newn and disposen nodes, the code is now directly
|
||||||
|
inlined from pexpr
|
||||||
|
* -an option that will write the secondpass nodes to the .s file, this
|
||||||
|
requires EXTDEBUG define to actually write the info
|
||||||
|
* fixed various internal errors and crashes due recent code changes
|
||||||
|
|
||||||
|
Revision 1.51 2002/04/06 18:10:42 jonas
|
||||||
* several powerpc-related additions and fixes
|
* several powerpc-related additions and fixes
|
||||||
|
|
||||||
Revision 1.50 2002/04/04 19:05:58 peter
|
Revision 1.50 2002/04/04 19:05:58 peter
|
||||||
|
@ -275,14 +275,12 @@ implementation
|
|||||||
{ process methodpointer }
|
{ process methodpointer }
|
||||||
if assigned(left) then
|
if assigned(left) then
|
||||||
begin
|
begin
|
||||||
{ if only typenode then remove }
|
resulttypepass(left);
|
||||||
|
|
||||||
|
{ turn on the allowed flag, the secondpass
|
||||||
|
will handle the typen itself }
|
||||||
if left.nodetype=typen then
|
if left.nodetype=typen then
|
||||||
begin
|
ttypenode(left).allowed:=true;
|
||||||
left.free;
|
|
||||||
left:=nil;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
resulttypepass(left);
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
@ -915,7 +913,14 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.34 2002-04-02 17:11:29 peter
|
Revision 1.35 2002-04-21 19:02:04 peter
|
||||||
|
* removed newn and disposen nodes, the code is now directly
|
||||||
|
inlined from pexpr
|
||||||
|
* -an option that will write the secondpass nodes to the .s file, this
|
||||||
|
requires EXTDEBUG define to actually write the info
|
||||||
|
* fixed various internal errors and crashes due recent code changes
|
||||||
|
|
||||||
|
Revision 1.34 2002/04/02 17:11:29 peter
|
||||||
* tlocation,treference update
|
* tlocation,treference update
|
||||||
* LOC_CONSTANT added for better constant handling
|
* LOC_CONSTANT added for better constant handling
|
||||||
* secondadd splitted in multiple routines
|
* secondadd splitted in multiple routines
|
||||||
|
@ -40,19 +40,13 @@ interface
|
|||||||
tloadvmtnodeclass = class of tloadvmtnode;
|
tloadvmtnodeclass = class of tloadvmtnode;
|
||||||
|
|
||||||
thnewnode = class(tnode)
|
thnewnode = class(tnode)
|
||||||
constructor create;virtual;
|
objtype : ttype;
|
||||||
|
constructor create(t:ttype);virtual;
|
||||||
function pass_1 : tnode;override;
|
function pass_1 : tnode;override;
|
||||||
function det_resulttype:tnode;override;
|
function det_resulttype:tnode;override;
|
||||||
end;
|
end;
|
||||||
thnewnodeclass = class of thnewnode;
|
thnewnodeclass = class of thnewnode;
|
||||||
|
|
||||||
tnewnode = class(tunarynode)
|
|
||||||
constructor create(l : tnode);virtual;
|
|
||||||
function pass_1 : tnode;override;
|
|
||||||
function det_resulttype:tnode;override;
|
|
||||||
end;
|
|
||||||
tnewnodeclass = class of tnewnode;
|
|
||||||
|
|
||||||
thdisposenode = class(tunarynode)
|
thdisposenode = class(tunarynode)
|
||||||
constructor create(l : tnode);virtual;
|
constructor create(l : tnode);virtual;
|
||||||
function pass_1 : tnode;override;
|
function pass_1 : tnode;override;
|
||||||
@ -60,13 +54,6 @@ interface
|
|||||||
end;
|
end;
|
||||||
thdisposenodeclass = class of thdisposenode;
|
thdisposenodeclass = class of thdisposenode;
|
||||||
|
|
||||||
tsimplenewdisposenode = class(tunarynode)
|
|
||||||
constructor create(n : tnodetype;l : tnode);
|
|
||||||
function pass_1 : tnode;override;
|
|
||||||
function det_resulttype:tnode;override;
|
|
||||||
end;
|
|
||||||
tsimplenewdisposenodeclass = class of tsimplenewdisposenode;
|
|
||||||
|
|
||||||
taddrnode = class(tunarynode)
|
taddrnode = class(tunarynode)
|
||||||
getprocvardef : tprocvardef;
|
getprocvardef : tprocvardef;
|
||||||
constructor create(l : tnode);virtual;
|
constructor create(l : tnode);virtual;
|
||||||
@ -130,9 +117,7 @@ interface
|
|||||||
var
|
var
|
||||||
cloadvmtnode : tloadvmtnodeclass;
|
cloadvmtnode : tloadvmtnodeclass;
|
||||||
chnewnode : thnewnodeclass;
|
chnewnode : thnewnodeclass;
|
||||||
cnewnode : tnewnodeclass;
|
|
||||||
chdisposenode : thdisposenodeclass;
|
chdisposenode : thdisposenodeclass;
|
||||||
csimplenewdisposenode : tsimplenewdisposenodeclass;
|
|
||||||
caddrnode : taddrnodeclass;
|
caddrnode : taddrnodeclass;
|
||||||
cdoubleaddrnode : tdoubleaddrnodeclass;
|
cdoubleaddrnode : tdoubleaddrnodeclass;
|
||||||
cderefnode : tderefnodeclass;
|
cderefnode : tderefnodeclass;
|
||||||
@ -147,6 +132,7 @@ implementation
|
|||||||
globtype,systems,
|
globtype,systems,
|
||||||
cutils,verbose,globals,
|
cutils,verbose,globals,
|
||||||
symconst,symbase,types,
|
symconst,symbase,types,
|
||||||
|
nbas,
|
||||||
htypechk,pass_1,ncal,nld,ncon,ncnv,cgbase
|
htypechk,pass_1,ncal,nld,ncon,ncnv,cgbase
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -180,16 +166,19 @@ implementation
|
|||||||
THNEWNODE
|
THNEWNODE
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
|
||||||
constructor thnewnode.create;
|
constructor thnewnode.create(t:ttype);
|
||||||
begin
|
begin
|
||||||
inherited create(hnewn);
|
inherited create(hnewn);
|
||||||
|
objtype:=t;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function thnewnode.det_resulttype:tnode;
|
function thnewnode.det_resulttype:tnode;
|
||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
resulttype:=voidtype;
|
if objtype.def.deftype<>objectdef then
|
||||||
|
Message(parser_e_pointer_to_class_expected);
|
||||||
|
resulttype:=objtype;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -199,100 +188,6 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{*****************************************************************************
|
|
||||||
TNEWNODE
|
|
||||||
*****************************************************************************}
|
|
||||||
|
|
||||||
constructor tnewnode.create(l : tnode);
|
|
||||||
begin
|
|
||||||
inherited create(newn,l);
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function tnewnode.det_resulttype:tnode;
|
|
||||||
begin
|
|
||||||
result:=nil;
|
|
||||||
if assigned(left) then
|
|
||||||
resulttypepass(left);
|
|
||||||
resulttype:=voidtype;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function tnewnode.pass_1 : tnode;
|
|
||||||
{$ifdef NEW_COMPILERPROC}
|
|
||||||
var
|
|
||||||
temp : ttempcreatenode;
|
|
||||||
newstatement : tstatementnode;
|
|
||||||
newblock : tblocknode;
|
|
||||||
{$endif NEW_COMPILERPROC}
|
|
||||||
begin
|
|
||||||
result:=nil;
|
|
||||||
{$ifdef NEW_COMPILERPROC}
|
|
||||||
{ create the blocknode which will hold the generated statements + }
|
|
||||||
{ an initial dummy statement }
|
|
||||||
newstatement := cstatementnode.create(nil,cnothingnode.create);
|
|
||||||
newblock := cblocknode.create(newstatement);
|
|
||||||
|
|
||||||
{ create temp for result }
|
|
||||||
temp := ctempcreatenode.create(resulttype,
|
|
||||||
resulttype.size,true);
|
|
||||||
newstatement.left := cstatementnode.create(nil,temp);
|
|
||||||
|
|
||||||
{ create parameter }
|
|
||||||
sizepara := ccallparanode.create(cordconstnode.create
|
|
||||||
(tpointerdef(resulttype.def).pointertype.def.size,s32bittype),nil);
|
|
||||||
|
|
||||||
{ create the call and assign the result to dest }
|
|
||||||
{ the assignment will take care of rangechecking }
|
|
||||||
newstatement.left := cstatementnode.create(nil,cassignmentnode.create(
|
|
||||||
ctemprefnode.create(tempcode),
|
|
||||||
ccallnode.createintern('fpc_getmem',sizepara)));
|
|
||||||
newstatement := tstatementnode(newstatement.left);
|
|
||||||
|
|
||||||
if tpointerdef(resulttype.def).pointertype.def.needs_inittable then
|
|
||||||
begin
|
|
||||||
para := ccallparanode.create(cloadnode.create
|
|
||||||
(tpointerdef(resulttype.def).pointertype.def.size,s32bittype),
|
|
||||||
ccallparanode.create(cordconstnode.create
|
|
||||||
(tpointerdef(resulttype.def).pointertype.def.size,s32bittype),nil));
|
|
||||||
newstatement.left := cstatementnode.create(nil,cassignmentnode.create(
|
|
||||||
ctemprefnode.create(tempcode),
|
|
||||||
ccallnode.createintern('fpc_initialize',sizepara)));
|
|
||||||
newstatement := tstatementnode(newstatement.left);
|
|
||||||
new(r);
|
|
||||||
reset_reference(r^);
|
|
||||||
r^.symbol:=tstoreddef(tpointerdef(resulttype.def).pointertype.def).get_rtti_label(initrtti);
|
|
||||||
emitpushreferenceaddr(r^);
|
|
||||||
dispose(r);
|
|
||||||
{ push pointer we just allocated, we need to initialize the
|
|
||||||
data located at that pointer not the pointer self (PFV) }
|
|
||||||
emit_push_loc(location);
|
|
||||||
emitcall('FPC_INITIALIZE');
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ and return it }
|
|
||||||
result := newblock;
|
|
||||||
{$endif NEW_COMPILERPROC}
|
|
||||||
|
|
||||||
if assigned(left) then
|
|
||||||
begin
|
|
||||||
firstpass(left);
|
|
||||||
if codegenerror then
|
|
||||||
exit;
|
|
||||||
|
|
||||||
registers32:=left.registers32;
|
|
||||||
registersfpu:=left.registersfpu;
|
|
||||||
{$ifdef SUPPORT_MMX}
|
|
||||||
registersmmx:=left.registersmmx;
|
|
||||||
{$endif SUPPORT_MMX}
|
|
||||||
location.loc:=LOC_REGISTER
|
|
||||||
end
|
|
||||||
else
|
|
||||||
location.loc:=LOC_REFERENCE;
|
|
||||||
procinfo^.flags:=procinfo^.flags or pi_do_call;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
THDISPOSENODE
|
THDISPOSENODE
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
@ -309,6 +204,8 @@ implementation
|
|||||||
resulttypepass(left);
|
resulttypepass(left);
|
||||||
if codegenerror then
|
if codegenerror then
|
||||||
exit;
|
exit;
|
||||||
|
if (left.resulttype.def.deftype<>pointerdef) then
|
||||||
|
CGMessage1(type_e_pointer_type_expected,left.resulttype.def.typename);
|
||||||
resulttype:=tpointerdef(left.resulttype.def).pointertype;
|
resulttype:=tpointerdef(left.resulttype.def).pointertype;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -337,48 +234,6 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{*****************************************************************************
|
|
||||||
TSIMPLENEWDISPOSENODE
|
|
||||||
*****************************************************************************}
|
|
||||||
|
|
||||||
constructor tsimplenewdisposenode.create(n : tnodetype;l : tnode);
|
|
||||||
|
|
||||||
begin
|
|
||||||
inherited create(n,l);
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function tsimplenewdisposenode.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:=voidtype;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function tsimplenewdisposenode.pass_1 : tnode;
|
|
||||||
begin
|
|
||||||
result:=nil;
|
|
||||||
{ this cannot be in a register !! }
|
|
||||||
make_not_regable(left);
|
|
||||||
|
|
||||||
firstpass(left);
|
|
||||||
if codegenerror then
|
|
||||||
exit;
|
|
||||||
|
|
||||||
registers32:=left.registers32;
|
|
||||||
registersfpu:=left.registersfpu;
|
|
||||||
{$ifdef SUPPORT_MMX}
|
|
||||||
registersmmx:=left.registersmmx;
|
|
||||||
{$endif SUPPORT_MMX}
|
|
||||||
procinfo^.flags:=procinfo^.flags or pi_do_call;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
TADDRNODE
|
TADDRNODE
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
@ -1027,9 +882,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
cloadvmtnode := tloadvmtnode;
|
cloadvmtnode := tloadvmtnode;
|
||||||
chnewnode := thnewnode;
|
chnewnode := thnewnode;
|
||||||
cnewnode := tnewnode;
|
|
||||||
chdisposenode := thdisposenode;
|
chdisposenode := thdisposenode;
|
||||||
csimplenewdisposenode := tsimplenewdisposenode;
|
|
||||||
caddrnode := taddrnode;
|
caddrnode := taddrnode;
|
||||||
cdoubleaddrnode := tdoubleaddrnode;
|
cdoubleaddrnode := tdoubleaddrnode;
|
||||||
cderefnode := tderefnode;
|
cderefnode := tderefnode;
|
||||||
@ -1040,7 +893,14 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.28 2002-04-20 21:32:23 carl
|
Revision 1.29 2002-04-21 19:02:04 peter
|
||||||
|
* removed newn and disposen nodes, the code is now directly
|
||||||
|
inlined from pexpr
|
||||||
|
* -an option that will write the secondpass nodes to the .s file, this
|
||||||
|
requires EXTDEBUG define to actually write the info
|
||||||
|
* fixed various internal errors and crashes due recent code changes
|
||||||
|
|
||||||
|
Revision 1.28 2002/04/20 21:32:23 carl
|
||||||
+ generic FPC_CHECKPOINTER
|
+ generic FPC_CHECKPOINTER
|
||||||
+ first parameter offset in stack now portable
|
+ first parameter offset in stack now portable
|
||||||
* rename some constants
|
* rename some constants
|
||||||
|
@ -86,8 +86,6 @@ interface
|
|||||||
typen, {A type name. Used for i.e. typeof(obj).}
|
typen, {A type name. Used for i.e. typeof(obj).}
|
||||||
hnewn, {The new operation, constructor call.}
|
hnewn, {The new operation, constructor call.}
|
||||||
hdisposen, {The dispose operation with destructor call.}
|
hdisposen, {The dispose operation with destructor call.}
|
||||||
newn, {The new operation, constructor call.}
|
|
||||||
simpledisposen, {The dispose operation.}
|
|
||||||
setelementn, {A set element(s) (i.e. [a,b] and also [a..b]).}
|
setelementn, {A set element(s) (i.e. [a,b] and also [a..b]).}
|
||||||
setconstn, {A set constant (i.e. [1,2]).}
|
setconstn, {A set constant (i.e. [1,2]).}
|
||||||
blockn, {A block of statements.}
|
blockn, {A block of statements.}
|
||||||
@ -104,10 +102,8 @@ interface
|
|||||||
casen, {A case statement.}
|
casen, {A case statement.}
|
||||||
labeln, {A label.}
|
labeln, {A label.}
|
||||||
goton, {A goto statement.}
|
goton, {A goto statement.}
|
||||||
simplenewn, {The new operation.}
|
|
||||||
tryexceptn, {A try except block.}
|
tryexceptn, {A try except block.}
|
||||||
raisen, {A raise statement.}
|
raisen, {A raise statement.}
|
||||||
switchesn, {??? Currently unused...}
|
|
||||||
tryfinallyn, {A try finally statement.}
|
tryfinallyn, {A try finally statement.}
|
||||||
onn, { for an on statement in exception code }
|
onn, { for an on statement in exception code }
|
||||||
isn, {Represents the is operator.}
|
isn, {Represents the is operator.}
|
||||||
@ -175,8 +171,6 @@ interface
|
|||||||
'typen',
|
'typen',
|
||||||
'hnewn',
|
'hnewn',
|
||||||
'hdisposen',
|
'hdisposen',
|
||||||
'newn',
|
|
||||||
'simpledisposen',
|
|
||||||
'setelementn',
|
'setelementn',
|
||||||
'setconstn',
|
'setconstn',
|
||||||
'blockn',
|
'blockn',
|
||||||
@ -193,10 +187,8 @@ interface
|
|||||||
'casen',
|
'casen',
|
||||||
'labeln',
|
'labeln',
|
||||||
'goton',
|
'goton',
|
||||||
'simplenewn',
|
|
||||||
'tryexceptn',
|
'tryexceptn',
|
||||||
'raisen',
|
'raisen',
|
||||||
'switchesn',
|
|
||||||
'tryfinallyn',
|
'tryfinallyn',
|
||||||
'onn',
|
'onn',
|
||||||
'isn',
|
'isn',
|
||||||
@ -814,7 +806,14 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.23 2002-04-06 18:13:01 jonas
|
Revision 1.24 2002-04-21 19:02:04 peter
|
||||||
|
* removed newn and disposen nodes, the code is now directly
|
||||||
|
inlined from pexpr
|
||||||
|
* -an option that will write the secondpass nodes to the .s file, this
|
||||||
|
requires EXTDEBUG define to actually write the info
|
||||||
|
* fixed various internal errors and crashes due recent code changes
|
||||||
|
|
||||||
|
Revision 1.23 2002/04/06 18:13:01 jonas
|
||||||
* several powerpc-related additions and fixes
|
* several powerpc-related additions and fixes
|
||||||
|
|
||||||
Revision 1.22 2002/03/31 20:26:35 jonas
|
Revision 1.22 2002/03/31 20:26:35 jonas
|
||||||
|
@ -382,6 +382,7 @@ begin
|
|||||||
'l' : include(initglobalswitches,cs_asm_source);
|
'l' : include(initglobalswitches,cs_asm_source);
|
||||||
'r' : include(initglobalswitches,cs_asm_regalloc);
|
'r' : include(initglobalswitches,cs_asm_regalloc);
|
||||||
't' : include(initglobalswitches,cs_asm_tempalloc);
|
't' : include(initglobalswitches,cs_asm_tempalloc);
|
||||||
|
'n' : include(initglobalswitches,cs_asm_nodes);
|
||||||
'-' : initglobalswitches:=initglobalswitches -
|
'-' : initglobalswitches:=initglobalswitches -
|
||||||
[cs_asm_leave, cs_asm_source,cs_asm_regalloc, cs_asm_tempalloc];
|
[cs_asm_leave, cs_asm_source,cs_asm_regalloc, cs_asm_tempalloc];
|
||||||
else
|
else
|
||||||
@ -1345,6 +1346,7 @@ begin
|
|||||||
def_symbol('HAS_ADDR_STACK_ON_STACK');
|
def_symbol('HAS_ADDR_STACK_ON_STACK');
|
||||||
def_symbol('NOBOUNDCHECK');
|
def_symbol('NOBOUNDCHECK');
|
||||||
def_symbol('HASCOMPILERPROC');
|
def_symbol('HASCOMPILERPROC');
|
||||||
|
def_symbol('VALUEGETMEM');
|
||||||
def_symbol('VALUEFREEMEM');
|
def_symbol('VALUEFREEMEM');
|
||||||
|
|
||||||
{ some stuff for TP compatibility }
|
{ some stuff for TP compatibility }
|
||||||
@ -1656,7 +1658,14 @@ finalization
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.68 2002-04-20 21:32:24 carl
|
Revision 1.69 2002-04-21 19:02:04 peter
|
||||||
|
* removed newn and disposen nodes, the code is now directly
|
||||||
|
inlined from pexpr
|
||||||
|
* -an option that will write the secondpass nodes to the .s file, this
|
||||||
|
requires EXTDEBUG define to actually write the info
|
||||||
|
* fixed various internal errors and crashes due recent code changes
|
||||||
|
|
||||||
|
Revision 1.68 2002/04/20 21:32:24 carl
|
||||||
+ generic FPC_CHECKPOINTER
|
+ generic FPC_CHECKPOINTER
|
||||||
+ first parameter offset in stack now portable
|
+ first parameter offset in stack now portable
|
||||||
* rename some constants
|
* rename some constants
|
||||||
|
@ -47,7 +47,7 @@ procedure secondpass(var p : tnode);
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
{$ifdef logsecondpass}
|
{$ifdef EXTDEBUG}
|
||||||
cutils,
|
cutils,
|
||||||
{$endif}
|
{$endif}
|
||||||
globtype,systems,verbose,
|
globtype,systems,verbose,
|
||||||
@ -59,7 +59,7 @@ implementation
|
|||||||
SecondPass
|
SecondPass
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
|
||||||
{$ifdef logsecondpass}
|
{$ifdef EXTDEBUG}
|
||||||
procedure logsecond(ht:tnodetype; entry: boolean);
|
procedure logsecond(ht:tnodetype; entry: boolean);
|
||||||
const
|
const
|
||||||
secondnames: array[tnodetype] of string[13] =
|
secondnames: array[tnodetype] of string[13] =
|
||||||
@ -92,9 +92,8 @@ implementation
|
|||||||
'ordconst', {ordconstn}
|
'ordconst', {ordconstn}
|
||||||
'typeconv', {typeconvn}
|
'typeconv', {typeconvn}
|
||||||
'calln', {calln}
|
'calln', {calln}
|
||||||
'nothing-callp', {callparan}
|
'noth-callpar', {callparan}
|
||||||
'realconst', {realconstn}
|
'realconst', {realconstn}
|
||||||
'fixconst', {fixconstn}
|
|
||||||
'unaryminus', {unaryminusn}
|
'unaryminus', {unaryminusn}
|
||||||
'asm', {asmn}
|
'asm', {asmn}
|
||||||
'vecn', {vecn}
|
'vecn', {vecn}
|
||||||
@ -109,8 +108,6 @@ implementation
|
|||||||
'nothing-typen', {typen}
|
'nothing-typen', {typen}
|
||||||
'hnewn', {hnewn}
|
'hnewn', {hnewn}
|
||||||
'hdisposen', {hdisposen}
|
'hdisposen', {hdisposen}
|
||||||
'newn', {newn}
|
|
||||||
'simplenewDISP', {simpledisposen}
|
|
||||||
'setelement', {setelementn}
|
'setelement', {setelementn}
|
||||||
'setconst', {setconstn}
|
'setconst', {setconstn}
|
||||||
'blockn', {blockn}
|
'blockn', {blockn}
|
||||||
@ -127,22 +124,25 @@ implementation
|
|||||||
'case', {casen}
|
'case', {casen}
|
||||||
'label', {labeln}
|
'label', {labeln}
|
||||||
'goto', {goton}
|
'goto', {goton}
|
||||||
'simpleNEWdisp', {simplenewn}
|
|
||||||
'tryexcept', {tryexceptn}
|
'tryexcept', {tryexceptn}
|
||||||
'raise', {raisen}
|
'raise', {raisen}
|
||||||
'nothing-swtch', {switchesn}
|
|
||||||
'tryfinally', {tryfinallyn}
|
'tryfinally', {tryfinallyn}
|
||||||
'on', {onn}
|
'on', {onn}
|
||||||
'is', {isn}
|
'is', {isn}
|
||||||
'as', {asn}
|
'as', {asn}
|
||||||
'error-caret', {caretn}
|
'error-caret', {caretn}
|
||||||
'fail', {failn}
|
'fail', {failn}
|
||||||
'add-startstar', {starstarn}
|
'add-starstar', {starstarn}
|
||||||
'procinline', {procinlinen}
|
'procinline', {procinlinen}
|
||||||
'arrayconstruc', {arrayconstructn}
|
'arrayconstruc', {arrayconstructn}
|
||||||
'noth-arrcnstr', {arrayconstructrangen}
|
'noth-arrcnstr', {arrayconstructrangen}
|
||||||
|
'tempn',
|
||||||
|
'temprefn',
|
||||||
|
'addoptn',
|
||||||
'nothing-nothg', {nothingn}
|
'nothing-nothg', {nothingn}
|
||||||
'loadvmt' {loadvmtn}
|
'loadvmt', {loadvmtn}
|
||||||
|
'guidconstn',
|
||||||
|
'rttin'
|
||||||
);
|
);
|
||||||
var
|
var
|
||||||
p: pchar;
|
p: pchar;
|
||||||
@ -153,7 +153,7 @@ implementation
|
|||||||
p := strpnew('second'+secondnames[ht]+' (exit)');
|
p := strpnew('second'+secondnames[ht]+' (exit)');
|
||||||
exprasmlist.concat(tai_asm_comment.create(p));
|
exprasmlist.concat(tai_asm_comment.create(p));
|
||||||
end;
|
end;
|
||||||
{$endif logsecondpass}
|
{$endif EXTDEBUG}
|
||||||
|
|
||||||
procedure secondpass(var p : tnode);
|
procedure secondpass(var p : tnode);
|
||||||
var
|
var
|
||||||
@ -184,15 +184,13 @@ implementation
|
|||||||
{$ifdef EXTDEBUG}
|
{$ifdef EXTDEBUG}
|
||||||
oldloc:=p.location.loc;
|
oldloc:=p.location.loc;
|
||||||
p.location.loc:=LOC_INVALID;
|
p.location.loc:=LOC_INVALID;
|
||||||
|
if (cs_asm_nodes in aktglobalswitches) then
|
||||||
|
logsecond(p.nodetype,true);
|
||||||
{$endif EXTDEBUG}
|
{$endif EXTDEBUG}
|
||||||
{$ifdef logsecondpass}
|
|
||||||
logsecond(p.nodetype,true);
|
|
||||||
{$endif logsecondpass}
|
|
||||||
p.pass_2;
|
p.pass_2;
|
||||||
{$ifdef logsecondpass}
|
|
||||||
logsecond(p.nodetype,false);
|
|
||||||
{$endif logsecondpass}
|
|
||||||
{$ifdef EXTDEBUG}
|
{$ifdef EXTDEBUG}
|
||||||
|
if (cs_asm_nodes in aktglobalswitches) then
|
||||||
|
logsecond(p.nodetype,false);
|
||||||
if (not codegenerror) and
|
if (not codegenerror) and
|
||||||
(oldloc<>LOC_INVALID) and
|
(oldloc<>LOC_INVALID) and
|
||||||
(p.location.loc=LOC_INVALID) then
|
(p.location.loc=LOC_INVALID) then
|
||||||
@ -256,48 +254,51 @@ implementation
|
|||||||
{ only do secondpass if there are no errors }
|
{ only do secondpass if there are no errors }
|
||||||
if ErrorCount=0 then
|
if ErrorCount=0 then
|
||||||
begin
|
begin
|
||||||
|
{$ifdef OMITSTACKFRAME}
|
||||||
if (cs_regalloc in aktglobalswitches) and
|
if (cs_regalloc in aktglobalswitches) and
|
||||||
((procinfo^.flags and (pi_uses_asm or pi_uses_exceptions))=0) then
|
((procinfo^.flags and (pi_uses_asm or pi_uses_exceptions))=0) then
|
||||||
begin
|
begin
|
||||||
{ can we omit the stack frame ? }
|
{ can we omit the stack frame ? }
|
||||||
{ conditions:
|
{ conditions:
|
||||||
1. procedure (not main block)
|
1. procedure (not main block)
|
||||||
2. no constructor or destructor
|
2. no constructor or destructor
|
||||||
3. no call to other procedures
|
3. no call to other procedures
|
||||||
4. no interrupt handler
|
4. no interrupt handler
|
||||||
}
|
}
|
||||||
{!!!!!! this doesn work yet, because of problems with
|
{!!!!!! this doesn work yet, because of problems with
|
||||||
with linux and windows
|
with linux and windows
|
||||||
}
|
}
|
||||||
(*
|
(*
|
||||||
if assigned(aktprocsym) then
|
if assigned(aktprocsym) then
|
||||||
begin
|
begin
|
||||||
if not(assigned(procinfo^._class)) and
|
if not(assigned(procinfo^._class)) and
|
||||||
not(aktprocdef.proctypeoption in [potype_constructor,potype_destructor]) and
|
not(aktprocdef.proctypeoption in [potype_constructor,potype_destructor]) and
|
||||||
not(po_interrupt in aktprocdef.procoptions) and
|
not(po_interrupt in aktprocdef.procoptions) and
|
||||||
((procinfo^.flags and pi_do_call)=0) and
|
((procinfo^.flags and pi_do_call)=0) and
|
||||||
(lexlevel>=normal_function_level) then
|
(lexlevel>=normal_function_level) then
|
||||||
begin
|
begin
|
||||||
{ use ESP as frame pointer }
|
{ use ESP as frame pointer }
|
||||||
procinfo^.framepointer:=STACK_POINTER_REG;
|
procinfo^.framepointer:=STACK_POINTER_REG;
|
||||||
use_esp_stackframe:=true;
|
use_esp_stackframe:=true;
|
||||||
|
|
||||||
{ calc parameter distance new }
|
{ calc parameter distance new }
|
||||||
dec(procinfo^.framepointer_offset,4);
|
dec(procinfo^.framepointer_offset,4);
|
||||||
dec(procinfo^.selfpointer_offset,4);
|
dec(procinfo^.selfpointer_offset,4);
|
||||||
|
|
||||||
{ is this correct ???}
|
{ is this correct ???}
|
||||||
{ retoffset can be negativ for results in eax !! }
|
{ retoffset can be negativ for results in eax !! }
|
||||||
{ the value should be decreased only if positive }
|
{ the value should be decreased only if positive }
|
||||||
if procinfo^.retoffset>=0 then
|
if procinfo^.retoffset>=0 then
|
||||||
dec(procinfo^.retoffset,4);
|
dec(procinfo^.retoffset,4);
|
||||||
|
|
||||||
|
dec(procinfo^.para_offset,4);
|
||||||
|
aktprocdef.parast.address_fixup:=procinfo^.para_offset;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
*)
|
||||||
|
end;
|
||||||
|
{$endif OMITSTACKFRAME}
|
||||||
|
|
||||||
dec(procinfo^.para_offset,4);
|
|
||||||
aktprocdef.parast.address_fixup:=procinfo^.para_offset;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
*)
|
|
||||||
end;
|
|
||||||
{ process register variable stuff (JM) }
|
{ process register variable stuff (JM) }
|
||||||
assign_regvars(p);
|
assign_regvars(p);
|
||||||
load_regvars(procinfo^.aktentrycode,p);
|
load_regvars(procinfo^.aktentrycode,p);
|
||||||
@ -320,7 +321,14 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.25 2002-04-20 21:32:24 carl
|
Revision 1.26 2002-04-21 19:02:04 peter
|
||||||
|
* removed newn and disposen nodes, the code is now directly
|
||||||
|
inlined from pexpr
|
||||||
|
* -an option that will write the secondpass nodes to the .s file, this
|
||||||
|
requires EXTDEBUG define to actually write the info
|
||||||
|
* fixed various internal errors and crashes due recent code changes
|
||||||
|
|
||||||
|
Revision 1.25 2002/04/20 21:32:24 carl
|
||||||
+ generic FPC_CHECKPOINTER
|
+ generic FPC_CHECKPOINTER
|
||||||
+ first parameter offset in stack now portable
|
+ first parameter offset in stack now portable
|
||||||
* rename some constants
|
* rename some constants
|
||||||
|
@ -794,6 +794,7 @@ implementation
|
|||||||
p:=comp_expr(true);
|
p:=comp_expr(true);
|
||||||
if p.nodetype=stringconstn then
|
if p.nodetype=stringconstn then
|
||||||
begin
|
begin
|
||||||
|
stringdispose(aktclass.iidstr);
|
||||||
aktclass.iidstr:=stringdup(strpas(tstringconstnode(p).value_str)); { or upper? }
|
aktclass.iidstr:=stringdup(strpas(tstringconstnode(p).value_str)); { or upper? }
|
||||||
p.free;
|
p.free;
|
||||||
aktclass.isiidguidvalid:=string2guid(aktclass.iidstr^,aktclass.iidguid);
|
aktclass.isiidguidvalid:=string2guid(aktclass.iidstr^,aktclass.iidguid);
|
||||||
@ -1110,7 +1111,14 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.40 2002-04-19 15:46:02 peter
|
Revision 1.41 2002-04-21 19:02:04 peter
|
||||||
|
* removed newn and disposen nodes, the code is now directly
|
||||||
|
inlined from pexpr
|
||||||
|
* -an option that will write the secondpass nodes to the .s file, this
|
||||||
|
requires EXTDEBUG define to actually write the info
|
||||||
|
* fixed various internal errors and crashes due recent code changes
|
||||||
|
|
||||||
|
Revision 1.40 2002/04/19 15:46:02 peter
|
||||||
* mangledname rewrite, tprocdef.mangledname is now created dynamicly
|
* mangledname rewrite, tprocdef.mangledname is now created dynamicly
|
||||||
in most cases and not written to the ppu
|
in most cases and not written to the ppu
|
||||||
* add mangeledname_prefix() routine to generate the prefix of
|
* add mangeledname_prefix() routine to generate the prefix of
|
||||||
|
@ -329,7 +329,6 @@ implementation
|
|||||||
orgsp,sp:stringid;
|
orgsp,sp:stringid;
|
||||||
paramoffset:longint;
|
paramoffset:longint;
|
||||||
sym:tsym;
|
sym:tsym;
|
||||||
doinsert : boolean;
|
|
||||||
st : tsymtable;
|
st : tsymtable;
|
||||||
srsymtable : tsymtable;
|
srsymtable : tsymtable;
|
||||||
pdl : pprocdeflist;
|
pdl : pprocdeflist;
|
||||||
@ -478,7 +477,6 @@ implementation
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
doinsert:=true;
|
|
||||||
if assigned(aktprocsym) then
|
if assigned(aktprocsym) then
|
||||||
begin
|
begin
|
||||||
{ Check if overloaded is a procsym }
|
{ Check if overloaded is a procsym }
|
||||||
@ -498,8 +496,9 @@ implementation
|
|||||||
Message1(parser_e_overloaded_no_procedure,aktprocsym.realname)
|
Message1(parser_e_overloaded_no_procedure,aktprocsym.realname)
|
||||||
else
|
else
|
||||||
DuplicateSym(aktprocsym);
|
DuplicateSym(aktprocsym);
|
||||||
{ don't reinsert as that will generated another error }
|
{ rename the name to an unique name to avoid an
|
||||||
doinsert:=false;
|
error when inserting the symbol in the symtable }
|
||||||
|
orgsp:=orgsp+'$'+tostr(aktfilepos.line);
|
||||||
end;
|
end;
|
||||||
{ generate a new aktprocsym }
|
{ generate a new aktprocsym }
|
||||||
aktprocsym:=nil;
|
aktprocsym:=nil;
|
||||||
@ -537,8 +536,7 @@ implementation
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
aktprocsym:=tprocsym.create(orgsp);
|
aktprocsym:=tprocsym.create(orgsp);
|
||||||
if doinsert then
|
symtablestack.insert(aktprocsym);
|
||||||
symtablestack.insert(aktprocsym);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
st:=symtablestack;
|
st:=symtablestack;
|
||||||
@ -1908,23 +1906,31 @@ const
|
|||||||
|
|
||||||
{ insert otsym only in the right symtable }
|
{ insert otsym only in the right symtable }
|
||||||
if ((procinfo^.flags and pi_operator)<>0) and
|
if ((procinfo^.flags and pi_operator)<>0) and
|
||||||
assigned(otsym) and
|
assigned(otsym) then
|
||||||
not parse_only then
|
begin
|
||||||
begin
|
if not parse_only then
|
||||||
if ret_in_param(aprocdef.rettype.def) then
|
begin
|
||||||
begin
|
if ret_in_param(aprocdef.rettype.def) then
|
||||||
aprocdef.parast.insert(otsym);
|
begin
|
||||||
{ this increases the data size }
|
aprocdef.parast.insert(otsym);
|
||||||
{ correct this to get the right ret $value }
|
{ this increases the data size }
|
||||||
dec(aprocdef.parast.datasize,
|
{ correct this to get the right ret $value }
|
||||||
align(otsym.getpushsize,aktprocdef.parast.dataalignment));
|
dec(aprocdef.parast.datasize,
|
||||||
{ this allows to read the funcretoffset }
|
align(otsym.getpushsize,aktprocdef.parast.dataalignment));
|
||||||
otsym.address:=-4;
|
{ this allows to read the funcretoffset }
|
||||||
otsym.varspez:=vs_var;
|
otsym.address:=-4;
|
||||||
end
|
otsym.varspez:=vs_var;
|
||||||
else
|
end
|
||||||
aprocdef.localst.insert(otsym);
|
else
|
||||||
end;
|
aprocdef.localst.insert(otsym);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
{ this is not required anymore }
|
||||||
|
otsym.free;
|
||||||
|
otsym:=nil;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
proc_add_definition:=forwardfound;
|
proc_add_definition:=forwardfound;
|
||||||
end;
|
end;
|
||||||
@ -1932,7 +1938,14 @@ const
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.52 2002-04-20 21:32:24 carl
|
Revision 1.53 2002-04-21 19:02:04 peter
|
||||||
|
* removed newn and disposen nodes, the code is now directly
|
||||||
|
inlined from pexpr
|
||||||
|
* -an option that will write the secondpass nodes to the .s file, this
|
||||||
|
requires EXTDEBUG define to actually write the info
|
||||||
|
* fixed various internal errors and crashes due recent code changes
|
||||||
|
|
||||||
|
Revision 1.52 2002/04/20 21:32:24 carl
|
||||||
+ generic FPC_CHECKPOINTER
|
+ generic FPC_CHECKPOINTER
|
||||||
+ first parameter offset in stack now portable
|
+ first parameter offset in stack now portable
|
||||||
* rename some constants
|
* rename some constants
|
||||||
|
@ -220,6 +220,9 @@ implementation
|
|||||||
|
|
||||||
function new_dispose_statement(is_new:boolean) : tnode;
|
function new_dispose_statement(is_new:boolean) : tnode;
|
||||||
var
|
var
|
||||||
|
newstatement : tstatementnode;
|
||||||
|
temp : ttempcreatenode;
|
||||||
|
para : tcallparanode;
|
||||||
p,p2 : tnode;
|
p,p2 : tnode;
|
||||||
again : boolean; { dummy for do_proc_call }
|
again : boolean; { dummy for do_proc_call }
|
||||||
destructorname : stringid;
|
destructorname : stringid;
|
||||||
@ -293,11 +296,10 @@ implementation
|
|||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
if is_new then
|
if is_new then
|
||||||
p2:=chnewnode.create
|
p2:=chnewnode.create(tpointerdef(p.resulttype.def).pointertype)
|
||||||
else
|
else
|
||||||
p2:=chdisposenode.create(p);
|
p2:=chdisposenode.create(p);
|
||||||
do_resulttypepass(p2);
|
do_resulttypepass(p2);
|
||||||
p2.resulttype:=tpointerdef(p.resulttype.def).pointertype;
|
|
||||||
if is_new then
|
if is_new then
|
||||||
do_member_read(false,sym,p2,again)
|
do_member_read(false,sym,p2,again)
|
||||||
else
|
else
|
||||||
@ -329,8 +331,6 @@ implementation
|
|||||||
begin
|
begin
|
||||||
if (tcallnode(p2).procdefinition.proctypeoption<>potype_constructor) then
|
if (tcallnode(p2).procdefinition.proctypeoption<>potype_constructor) then
|
||||||
Message(parser_e_expr_have_to_be_constructor_call);
|
Message(parser_e_expr_have_to_be_constructor_call);
|
||||||
p2:=cnewnode.create(p2);
|
|
||||||
do_resulttypepass(p2);
|
|
||||||
p2.resulttype:=p.resulttype;
|
p2.resulttype:=p.resulttype;
|
||||||
p2:=cassignmentnode.create(p,p2);
|
p2:=cassignmentnode.create(p,p2);
|
||||||
end
|
end
|
||||||
@ -365,10 +365,57 @@ implementation
|
|||||||
Message(parser_e_no_new_dispose_on_void_pointers);
|
Message(parser_e_no_new_dispose_on_void_pointers);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ create statements with call to getmem+initialize or
|
||||||
|
finalize+freemem }
|
||||||
|
new_dispose_statement:=internalstatements(newstatement);
|
||||||
|
|
||||||
if is_new then
|
if is_new then
|
||||||
new_dispose_statement:=csimplenewdisposenode.create(simplenewn,p)
|
begin
|
||||||
|
{ create temp for result }
|
||||||
|
temp := ctempcreatenode.create(p.resulttype,p.resulttype.def.size,true);
|
||||||
|
addstatement(newstatement,temp);
|
||||||
|
|
||||||
|
{ create call to fpc_getmem }
|
||||||
|
para := ccallparanode.create(cordconstnode.create
|
||||||
|
(tpointerdef(p.resulttype.def).pointertype.def.size,s32bittype),nil);
|
||||||
|
addstatement(newstatement,cassignmentnode.create(
|
||||||
|
ctemprefnode.create(temp),
|
||||||
|
ccallnode.createintern('fpc_getmem',para)));
|
||||||
|
|
||||||
|
{ create call to fpc_initialize }
|
||||||
|
if tpointerdef(p.resulttype.def).pointertype.def.needs_inittable then
|
||||||
|
begin
|
||||||
|
para := ccallparanode.create(caddrnode.create(crttinode.create(
|
||||||
|
tstoreddef(tpointerdef(p.resulttype.def).pointertype.def),initrtti)),
|
||||||
|
ccallparanode.create(ctemprefnode.create
|
||||||
|
(temp),nil));
|
||||||
|
addstatement(newstatement,ccallnode.createintern('fpc_initialize',para));
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ copy the temp to the destination }
|
||||||
|
addstatement(newstatement,cassignmentnode.create(
|
||||||
|
p,
|
||||||
|
ctemprefnode.create(temp)));
|
||||||
|
|
||||||
|
{ release temp }
|
||||||
|
addstatement(newstatement,ctempdeletenode.create(temp));
|
||||||
|
end
|
||||||
else
|
else
|
||||||
new_dispose_statement:=csimplenewdisposenode.create(simpledisposen,p);
|
begin
|
||||||
|
{ create call to fpc_finalize }
|
||||||
|
if tpointerdef(p.resulttype.def).pointertype.def.needs_inittable then
|
||||||
|
begin
|
||||||
|
{ we need to use a copy of p here }
|
||||||
|
para := ccallparanode.create(caddrnode.create(crttinode.create
|
||||||
|
(tstoreddef(tpointerdef(p.resulttype.def).pointertype.def),initrtti)),
|
||||||
|
ccallparanode.create(p.getcopy,nil));
|
||||||
|
addstatement(newstatement,ccallnode.createintern('fpc_finalize',para));
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ create call to fpc_freemem }
|
||||||
|
para := ccallparanode.create(p,nil);
|
||||||
|
addstatement(newstatement,ccallnode.createintern('fpc_freemem',para));
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
consume(_RKLAMMER);
|
consume(_RKLAMMER);
|
||||||
@ -377,6 +424,10 @@ implementation
|
|||||||
|
|
||||||
function new_function : tnode;
|
function new_function : tnode;
|
||||||
var
|
var
|
||||||
|
newstatement : tstatementnode;
|
||||||
|
newblock : tblocknode;
|
||||||
|
temp : ttempcreatenode;
|
||||||
|
para : tcallparanode;
|
||||||
p1,p2 : tnode;
|
p1,p2 : tnode;
|
||||||
classh : tobjectdef;
|
classh : tobjectdef;
|
||||||
sym : tsym;
|
sym : tsym;
|
||||||
@ -399,26 +450,52 @@ implementation
|
|||||||
begin
|
begin
|
||||||
if (tpointerdef(p1.resulttype.def).pointertype.def.deftype=objectdef) and
|
if (tpointerdef(p1.resulttype.def).pointertype.def.deftype=objectdef) and
|
||||||
(oo_has_vmt in tobjectdef(tpointerdef(p1.resulttype.def).pointertype.def).objectoptions) then
|
(oo_has_vmt in tobjectdef(tpointerdef(p1.resulttype.def).pointertype.def).objectoptions) then
|
||||||
Message(parser_w_use_extended_syntax_for_objects);
|
Message(parser_w_use_extended_syntax_for_objects);
|
||||||
p2:=cnewnode.create(nil);
|
|
||||||
do_resulttypepass(p2);
|
{ create statements with call to getmem+initialize }
|
||||||
p2.resulttype:=p1.resulttype;
|
newblock:=internalstatements(newstatement);
|
||||||
|
|
||||||
|
{ create temp for result }
|
||||||
|
temp := ctempcreatenode.create(p1.resulttype,p1.resulttype.def.size,true);
|
||||||
|
addstatement(newstatement,temp);
|
||||||
|
|
||||||
|
{ create call to fpc_getmem }
|
||||||
|
para := ccallparanode.create(cordconstnode.create
|
||||||
|
(tpointerdef(p1.resulttype.def).pointertype.def.size,s32bittype),nil);
|
||||||
|
addstatement(newstatement,cassignmentnode.create(
|
||||||
|
ctemprefnode.create(temp),
|
||||||
|
ccallnode.createintern('fpc_getmem',para)));
|
||||||
|
|
||||||
|
{ create call to fpc_initialize }
|
||||||
|
if tpointerdef(p1.resulttype.def).pointertype.def.needs_inittable then
|
||||||
|
begin
|
||||||
|
para := ccallparanode.create(caddrnode.create(crttinode.create
|
||||||
|
(tstoreddef(tpointerdef(p1.resulttype.def).pointertype.def),initrtti)),
|
||||||
|
ccallparanode.create(ctemprefnode.create
|
||||||
|
(temp),nil));
|
||||||
|
addstatement(newstatement,ccallnode.createintern('fpc_initialize',para));
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ the last statement should return the value as
|
||||||
|
location and type, this is done be referencing the
|
||||||
|
temp and converting it first from a persistent temp to
|
||||||
|
normal temp }
|
||||||
|
addstatement(newstatement,ctempdeletenode.create_normal_temp(temp));
|
||||||
|
addstatement(newstatement,ctemprefnode.create(temp));
|
||||||
|
|
||||||
p1.destroy;
|
p1.destroy;
|
||||||
p1:=p2;
|
p1:=newblock;
|
||||||
consume(_RKLAMMER);
|
consume(_RKLAMMER);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
p2:=chnewnode.create;
|
p2:=chnewnode.create(tpointerdef(p1.resulttype.def).pointertype);
|
||||||
do_resulttypepass(p2);
|
do_resulttypepass(p2);
|
||||||
p2.resulttype:=tpointerdef(p1.resulttype.def).pointertype;
|
|
||||||
consume(_COMMA);
|
consume(_COMMA);
|
||||||
afterassignment:=false;
|
afterassignment:=false;
|
||||||
{ determines the current object defintion }
|
{ determines the current object defintion }
|
||||||
classh:=tobjectdef(p2.resulttype.def);
|
classh:=tobjectdef(p2.resulttype.def);
|
||||||
if classh.deftype<>objectdef then
|
if classh.deftype=objectdef then
|
||||||
Message(parser_e_pointer_to_class_expected)
|
|
||||||
else
|
|
||||||
begin
|
begin
|
||||||
{ check for an abstract class }
|
{ check for an abstract class }
|
||||||
if (oo_has_abstract in classh.objectoptions) then
|
if (oo_has_abstract in classh.objectoptions) then
|
||||||
@ -434,9 +511,11 @@ implementation
|
|||||||
(assigned(tcallnode(p2).procdefinition) and
|
(assigned(tcallnode(p2).procdefinition) and
|
||||||
(tcallnode(p2).procdefinition.proctypeoption<>potype_constructor)) then
|
(tcallnode(p2).procdefinition.proctypeoption<>potype_constructor)) then
|
||||||
Message(parser_e_expr_have_to_be_constructor_call);
|
Message(parser_e_expr_have_to_be_constructor_call);
|
||||||
end;
|
end
|
||||||
p2:=cnewnode.create(p2);
|
else
|
||||||
do_resulttypepass(p2);
|
Message(parser_e_pointer_to_class_expected);
|
||||||
|
{ constructors return boolean, update resulttype to return
|
||||||
|
the pointer to the object }
|
||||||
p2.resulttype:=p1.resulttype;
|
p2.resulttype:=p1.resulttype;
|
||||||
p1.destroy;
|
p1.destroy;
|
||||||
p1:=p2;
|
p1:=p2;
|
||||||
@ -2458,7 +2537,14 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.62 2002-04-16 16:11:17 peter
|
Revision 1.63 2002-04-21 19:02:05 peter
|
||||||
|
* removed newn and disposen nodes, the code is now directly
|
||||||
|
inlined from pexpr
|
||||||
|
* -an option that will write the secondpass nodes to the .s file, this
|
||||||
|
requires EXTDEBUG define to actually write the info
|
||||||
|
* fixed various internal errors and crashes due recent code changes
|
||||||
|
|
||||||
|
Revision 1.62 2002/04/16 16:11:17 peter
|
||||||
* using inherited; without a parent having the same function
|
* using inherited; without a parent having the same function
|
||||||
will do nothing like delphi
|
will do nothing like delphi
|
||||||
|
|
||||||
|
@ -991,8 +991,8 @@ implementation
|
|||||||
{ blockn support because a read/write is changed into a blocknode }
|
{ blockn support because a read/write is changed into a blocknode }
|
||||||
{ with a separate statement for each read/write operation (JM) }
|
{ with a separate statement for each read/write operation (JM) }
|
||||||
{ the same is true for val() if the third parameter is not 32 bit }
|
{ the same is true for val() if the third parameter is not 32 bit }
|
||||||
if not(p.nodetype in [nothingn,calln,assignn,breakn,inlinen,continuen,labeln,blockn,
|
if not(p.nodetype in [nothingn,calln,assignn,breakn,inlinen,
|
||||||
simplenewn,simpledisposen]) then
|
continuen,labeln,blockn]) then
|
||||||
Message(cg_e_illegal_expression);
|
Message(cg_e_illegal_expression);
|
||||||
|
|
||||||
{ specify that we don't use the value returned by the call }
|
{ specify that we don't use the value returned by the call }
|
||||||
@ -1213,7 +1213,14 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.53 2002-04-20 21:32:24 carl
|
Revision 1.54 2002-04-21 19:02:05 peter
|
||||||
|
* removed newn and disposen nodes, the code is now directly
|
||||||
|
inlined from pexpr
|
||||||
|
* -an option that will write the secondpass nodes to the .s file, this
|
||||||
|
requires EXTDEBUG define to actually write the info
|
||||||
|
* fixed various internal errors and crashes due recent code changes
|
||||||
|
|
||||||
|
Revision 1.53 2002/04/20 21:32:24 carl
|
||||||
+ generic FPC_CHECKPOINTER
|
+ generic FPC_CHECKPOINTER
|
||||||
+ first parameter offset in stack now portable
|
+ first parameter offset in stack now portable
|
||||||
* rename some constants
|
* rename some constants
|
||||||
|
@ -745,6 +745,8 @@ implementation
|
|||||||
prefix : string;
|
prefix : string;
|
||||||
begin
|
begin
|
||||||
prefix:='';
|
prefix:='';
|
||||||
|
if not assigned(st) then
|
||||||
|
internalerror(200204212);
|
||||||
{ sub procedures }
|
{ sub procedures }
|
||||||
while (st.symtabletype=localsymtable) do
|
while (st.symtabletype=localsymtable) do
|
||||||
begin
|
begin
|
||||||
@ -5468,7 +5470,14 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.72 2002-04-20 21:32:25 carl
|
Revision 1.73 2002-04-21 19:02:05 peter
|
||||||
|
* removed newn and disposen nodes, the code is now directly
|
||||||
|
inlined from pexpr
|
||||||
|
* -an option that will write the secondpass nodes to the .s file, this
|
||||||
|
requires EXTDEBUG define to actually write the info
|
||||||
|
* fixed various internal errors and crashes due recent code changes
|
||||||
|
|
||||||
|
Revision 1.72 2002/04/20 21:32:25 carl
|
||||||
+ generic FPC_CHECKPOINTER
|
+ generic FPC_CHECKPOINTER
|
||||||
+ first parameter offset in stack now portable
|
+ first parameter offset in stack now portable
|
||||||
* rename some constants
|
* rename some constants
|
||||||
|
Loading…
Reference in New Issue
Block a user