* 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:
peter 2002-04-21 19:02:03 +00:00
parent 5ea6f2b824
commit 6320530bdd
20 changed files with 472 additions and 451 deletions

View File

@ -122,7 +122,7 @@ interface
cs_gdb_dbx,cs_gdb_gsym,cs_gdb_heaptrc,cs_gdb_lineinfo,cs_checkpointer,
{ assembling }
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 }
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
@ -253,7 +253,14 @@ implementation
end.
{
$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
Revision 1.20 2002/01/24 18:25:48 peter

View File

@ -63,7 +63,7 @@ implementation
cginfo,cgbase,pass_2,
cpubase,
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
@ -133,6 +133,11 @@ implementation
else if assigned(defcoll.paratype.def) and
(defcoll.paratype.def.deftype=formaldef) then
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 }
inc(pushedparasize,4);
if (left.nodetype=addrn) and
@ -1477,7 +1482,14 @@ begin
end.
{
$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
Revision 1.45 2002/04/15 19:44:21 peter

View File

@ -249,7 +249,15 @@ implementation
end;
LOC_REGISTER,LOC_CREGISTER :
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;
LOC_JUMP :
begin
@ -364,7 +372,14 @@ begin
end.
{
$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
Revision 1.35 2002/04/19 15:39:35 peter

View File

@ -30,18 +30,10 @@ interface
node,nmem,ncgmem;
type
ti386newnode = class(tnewnode)
procedure pass_2;override;
end;
ti386addrnode = class(tcgaddrnode)
procedure pass_2;override;
end;
ti386simplenewdisposenode = class(tsimplenewdisposenode)
procedure pass_2;override;
end;
ti386derefnode = class(tcgderefnode)
procedure pass_2;override;
end;
@ -64,54 +56,6 @@ implementation
cpuinfo,cpubase,
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
*****************************************************************************}
@ -125,86 +69,6 @@ implementation
location.segment:=left.location.reference.segment;
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
@ -219,11 +83,11 @@ implementation
if not tpointerdef(left.resulttype.def).is_far and
(cs_gdb_heaptrc in aktglobalswitches) and
(cs_checkpointer in aktglobalswitches) then
begin
emit_reg(
A_PUSH,S_L,location.reference.base);
emitcall('FPC_CHECKPOINTER');
end;
begin
emit_reg(
A_PUSH,S_L,location.reference.base);
emitcall('FPC_CHECKPOINTER');
end;
end;
@ -655,15 +519,20 @@ implementation
begin
cnewnode:=ti386newnode;
csimplenewdisposenode:=ti386simplenewdisposenode;
caddrnode:=ti386addrnode;
cderefnode:=ti386derefnode;
cvecnode:=ti386vecnode;
end.
{
$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
+ first parameter offset in stack now portable
* rename some constants

View File

@ -899,7 +899,13 @@ implementation
opsize:=bytes2Sxx[left.resulttype.def.size];
{ copy the case expression to a register }
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
begin
truelabel:=otl;
@ -1030,7 +1036,14 @@ begin
end.
{
$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
Revision 1.23 2002/04/19 15:39:35 peter

View File

@ -81,7 +81,6 @@ interface
{ refs and deletenode can hook to this copy once they get copied too }
hookoncopy : ptempinfo;
ref : treference;
size : longint;
restype : ttype;
valid : boolean;
end;
@ -91,6 +90,7 @@ interface
ttempcreatenode = class(tnode)
size: longint;
tempinfo: ptempinfo;
persistent: boolean;
{ * persistent temps are used in manually written code where the temp }
{ be usable among different statements and where you can manually say }
{ when the temp has to be freed (using a ttempdeletenode) }
@ -103,8 +103,6 @@ interface
function pass_1 : tnode; override;
function det_resulttype: tnode; override;
function docompare(p: tnode): boolean; override;
protected
persistent: boolean;
end;
ttempcreatenodeclass = class of ttempcreatenode;
@ -123,6 +121,9 @@ interface
{ a node which removes a temp }
ttempdeletenode = class(tnode)
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 pass_1: tnode; override;
function det_resulttype: tnode; override;
@ -130,6 +131,7 @@ interface
destructor destroy; override;
protected
tempinfo: ptempinfo;
release_to_normal : boolean;
end;
ttempdeletenodeclass = class of ttempdeletenode;
@ -143,6 +145,12 @@ interface
ctemprefnode : ttemprefnodeclass;
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
uses
@ -153,6 +161,28 @@ implementation
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
*****************************************************************************}
@ -239,6 +269,7 @@ implementation
firstpass(right);
if codegenerror then
exit;
location.loc:=right.location.loc;
registers32:=right.registers32;
registersfpu:=right.registersfpu;
{$ifdef SUPPORT_MMX}
@ -306,6 +337,11 @@ implementation
(tcallnode(hp.right).procdefinition.proctypeoption=potype_constructor)) and
not(is_void(hp.right.resulttype.def)) then
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;
hp:=tstatementnode(hp.left);
end;
@ -389,6 +425,7 @@ implementation
if hp.registersmmx>registersmmx then
registersmmx:=hp.registersmmx;
{$endif}
location.loc:=hp.location.loc;
inc(count);
hp:=tstatementnode(hp.left);
end;
@ -456,7 +493,6 @@ implementation
new(tempinfo);
fillchar(tempinfo^,sizeof(tempinfo^),0);
tempinfo^.restype := _restype;
tempinfo^.size := _size;
persistent := _persistent;
end;
@ -470,7 +506,6 @@ implementation
new(n.tempinfo);
fillchar(n.tempinfo^,sizeof(n.tempinfo^),0);
n.tempinfo^.restype := tempinfo^.restype;
n.tempinfo^.size:=size;
{ 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 }
@ -562,6 +597,16 @@ implementation
begin
inherited create(temprefn);
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;
function ttempdeletenode.getcopy: tnode;
@ -620,7 +665,14 @@ begin
end.
{
$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
* use tlocation.size in cg.a_*loc*() routines

View File

@ -94,6 +94,8 @@ interface
begin
rg.cleartempgen;
secondpass(tstatementnode(hp).right);
{ Compiler inserted blocks can return values }
location_copy(location,tstatementnode(hp).right.location);
end;
hp:=tstatementnode(hp).left;
end;
@ -223,7 +225,11 @@ interface
begin
{ do second pass on left node }
if assigned(left) then
secondpass(left);
begin
secondpass(left);
{ Compiler inserted blocks can return values }
location_copy(location,left.location);
end;
end;
{*****************************************************************************
@ -255,7 +261,7 @@ interface
if not tempinfo^.valid then
internalerror(200108231);
{ 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;
end;
@ -265,7 +271,10 @@ interface
procedure tcgtempdeletenode.pass_2;
begin
tg.ungetpersistanttempreference(exprasmlist,tempinfo^.ref);
if release_to_normal then
tg.persistanttemptonormal(tempinfo^.ref.offset)
else
tg.ungetpersistanttempreference(exprasmlist,tempinfo^.ref);
end;
@ -280,7 +289,14 @@ begin
end.
{
$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
* use tlocation.size in cg.a_*loc*() routines

View File

@ -390,8 +390,15 @@ interface
begin
{ we reuse the old value }
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 }
location.size:=def_cgsize(resulttype.def)
location.size:=def_cgsize(resulttype.def);
end;
@ -434,7 +441,14 @@ end.
{
$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
* moved location_force_reg/mem to ncgutil
* moved arrayconstructnode secondpass to ncgld

View File

@ -298,6 +298,7 @@ implementation
LOC_FPUREGISTER,
LOC_CFPUREGISTER :
begin
tg.gettempofsizereference(exprasmlist,TCGSize2Size[l.size],r);
cg.a_loadfpu_reg_ref(exprasmlist,l.size,l.register,r);
location_reset(l,LOC_REFERENCE,l.size);
l.reference:=r;
@ -382,7 +383,14 @@ end.
{
$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)
+ changeregsize -> rg.makeregsize

View File

@ -1485,8 +1485,12 @@ implementation
if convtype=tc_equal then
begin
{ 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) }
if is_constnode(left) then
remove it because the secondpass can still depend on the old type (PFV)
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
left.resulttype:=resulttype;
result:=left;
@ -1701,7 +1705,14 @@ begin
end.
{
$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
Revision 1.50 2002/04/04 19:05:58 peter

View File

@ -275,14 +275,12 @@ implementation
{ process methodpointer }
if assigned(left) then
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
begin
left.free;
left:=nil;
end
else
resulttypepass(left);
ttypenode(left).allowed:=true;
end;
end;
else
@ -915,7 +913,14 @@ begin
end.
{
$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
* LOC_CONSTANT added for better constant handling
* secondadd splitted in multiple routines

View File

@ -40,19 +40,13 @@ interface
tloadvmtnodeclass = class of tloadvmtnode;
thnewnode = class(tnode)
constructor create;virtual;
objtype : ttype;
constructor create(t:ttype);virtual;
function pass_1 : tnode;override;
function det_resulttype:tnode;override;
end;
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)
constructor create(l : tnode);virtual;
function pass_1 : tnode;override;
@ -60,13 +54,6 @@ interface
end;
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)
getprocvardef : tprocvardef;
constructor create(l : tnode);virtual;
@ -130,9 +117,7 @@ interface
var
cloadvmtnode : tloadvmtnodeclass;
chnewnode : thnewnodeclass;
cnewnode : tnewnodeclass;
chdisposenode : thdisposenodeclass;
csimplenewdisposenode : tsimplenewdisposenodeclass;
caddrnode : taddrnodeclass;
cdoubleaddrnode : tdoubleaddrnodeclass;
cderefnode : tderefnodeclass;
@ -147,6 +132,7 @@ implementation
globtype,systems,
cutils,verbose,globals,
symconst,symbase,types,
nbas,
htypechk,pass_1,ncal,nld,ncon,ncnv,cgbase
;
@ -180,16 +166,19 @@ implementation
THNEWNODE
*****************************************************************************}
constructor thnewnode.create;
constructor thnewnode.create(t:ttype);
begin
inherited create(hnewn);
objtype:=t;
end;
function thnewnode.det_resulttype:tnode;
begin
result:=nil;
resulttype:=voidtype;
if objtype.def.deftype<>objectdef then
Message(parser_e_pointer_to_class_expected);
resulttype:=objtype;
end;
@ -199,100 +188,6 @@ implementation
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
*****************************************************************************}
@ -309,6 +204,8 @@ implementation
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;
@ -337,48 +234,6 @@ implementation
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
*****************************************************************************}
@ -1027,9 +882,7 @@ implementation
begin
cloadvmtnode := tloadvmtnode;
chnewnode := thnewnode;
cnewnode := tnewnode;
chdisposenode := thdisposenode;
csimplenewdisposenode := tsimplenewdisposenode;
caddrnode := taddrnode;
cdoubleaddrnode := tdoubleaddrnode;
cderefnode := tderefnode;
@ -1040,7 +893,14 @@ begin
end.
{
$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
+ first parameter offset in stack now portable
* rename some constants

View File

@ -86,8 +86,6 @@ interface
typen, {A type name. Used for i.e. typeof(obj).}
hnewn, {The new operation, constructor 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]).}
setconstn, {A set constant (i.e. [1,2]).}
blockn, {A block of statements.}
@ -104,10 +102,8 @@ interface
casen, {A case statement.}
labeln, {A label.}
goton, {A goto statement.}
simplenewn, {The new operation.}
tryexceptn, {A try except block.}
raisen, {A raise statement.}
switchesn, {??? Currently unused...}
tryfinallyn, {A try finally statement.}
onn, { for an on statement in exception code }
isn, {Represents the is operator.}
@ -175,8 +171,6 @@ interface
'typen',
'hnewn',
'hdisposen',
'newn',
'simpledisposen',
'setelementn',
'setconstn',
'blockn',
@ -193,10 +187,8 @@ interface
'casen',
'labeln',
'goton',
'simplenewn',
'tryexceptn',
'raisen',
'switchesn',
'tryfinallyn',
'onn',
'isn',
@ -814,7 +806,14 @@ implementation
end.
{
$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
Revision 1.22 2002/03/31 20:26:35 jonas

View File

@ -382,6 +382,7 @@ begin
'l' : include(initglobalswitches,cs_asm_source);
'r' : include(initglobalswitches,cs_asm_regalloc);
't' : include(initglobalswitches,cs_asm_tempalloc);
'n' : include(initglobalswitches,cs_asm_nodes);
'-' : initglobalswitches:=initglobalswitches -
[cs_asm_leave, cs_asm_source,cs_asm_regalloc, cs_asm_tempalloc];
else
@ -1345,6 +1346,7 @@ begin
def_symbol('HAS_ADDR_STACK_ON_STACK');
def_symbol('NOBOUNDCHECK');
def_symbol('HASCOMPILERPROC');
def_symbol('VALUEGETMEM');
def_symbol('VALUEFREEMEM');
{ some stuff for TP compatibility }
@ -1379,7 +1381,7 @@ begin
else
internalerror(1295969);
end;
{ get default messagefile }
{$ifdef Delphi}
@ -1656,7 +1658,14 @@ finalization
end.
{
$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
+ first parameter offset in stack now portable
* rename some constants

View File

@ -47,7 +47,7 @@ procedure secondpass(var p : tnode);
implementation
uses
{$ifdef logsecondpass}
{$ifdef EXTDEBUG}
cutils,
{$endif}
globtype,systems,verbose,
@ -59,7 +59,7 @@ implementation
SecondPass
*****************************************************************************}
{$ifdef logsecondpass}
{$ifdef EXTDEBUG}
procedure logsecond(ht:tnodetype; entry: boolean);
const
secondnames: array[tnodetype] of string[13] =
@ -92,9 +92,8 @@ implementation
'ordconst', {ordconstn}
'typeconv', {typeconvn}
'calln', {calln}
'nothing-callp', {callparan}
'noth-callpar', {callparan}
'realconst', {realconstn}
'fixconst', {fixconstn}
'unaryminus', {unaryminusn}
'asm', {asmn}
'vecn', {vecn}
@ -109,8 +108,6 @@ implementation
'nothing-typen', {typen}
'hnewn', {hnewn}
'hdisposen', {hdisposen}
'newn', {newn}
'simplenewDISP', {simpledisposen}
'setelement', {setelementn}
'setconst', {setconstn}
'blockn', {blockn}
@ -127,22 +124,25 @@ implementation
'case', {casen}
'label', {labeln}
'goto', {goton}
'simpleNEWdisp', {simplenewn}
'tryexcept', {tryexceptn}
'raise', {raisen}
'nothing-swtch', {switchesn}
'tryfinally', {tryfinallyn}
'on', {onn}
'is', {isn}
'as', {asn}
'error-caret', {caretn}
'fail', {failn}
'add-startstar', {starstarn}
'add-starstar', {starstarn}
'procinline', {procinlinen}
'arrayconstruc', {arrayconstructn}
'noth-arrcnstr', {arrayconstructrangen}
'tempn',
'temprefn',
'addoptn',
'nothing-nothg', {nothingn}
'loadvmt' {loadvmtn}
'loadvmt', {loadvmtn}
'guidconstn',
'rttin'
);
var
p: pchar;
@ -153,7 +153,7 @@ implementation
p := strpnew('second'+secondnames[ht]+' (exit)');
exprasmlist.concat(tai_asm_comment.create(p));
end;
{$endif logsecondpass}
{$endif EXTDEBUG}
procedure secondpass(var p : tnode);
var
@ -184,15 +184,13 @@ implementation
{$ifdef EXTDEBUG}
oldloc:=p.location.loc;
p.location.loc:=LOC_INVALID;
if (cs_asm_nodes in aktglobalswitches) then
logsecond(p.nodetype,true);
{$endif EXTDEBUG}
{$ifdef logsecondpass}
logsecond(p.nodetype,true);
{$endif logsecondpass}
p.pass_2;
{$ifdef logsecondpass}
logsecond(p.nodetype,false);
{$endif logsecondpass}
{$ifdef EXTDEBUG}
if (cs_asm_nodes in aktglobalswitches) then
logsecond(p.nodetype,false);
if (not codegenerror) and
(oldloc<>LOC_INVALID) and
(p.location.loc=LOC_INVALID) then
@ -256,48 +254,51 @@ implementation
{ only do secondpass if there are no errors }
if ErrorCount=0 then
begin
{$ifdef OMITSTACKFRAME}
if (cs_regalloc in aktglobalswitches) and
((procinfo^.flags and (pi_uses_asm or pi_uses_exceptions))=0) then
begin
{ can we omit the stack frame ? }
{ conditions:
1. procedure (not main block)
2. no constructor or destructor
3. no call to other procedures
4. no interrupt handler
}
{!!!!!! this doesn work yet, because of problems with
with linux and windows
}
(*
if assigned(aktprocsym) then
begin
if not(assigned(procinfo^._class)) and
not(aktprocdef.proctypeoption in [potype_constructor,potype_destructor]) and
not(po_interrupt in aktprocdef.procoptions) and
((procinfo^.flags and pi_do_call)=0) and
(lexlevel>=normal_function_level) then
begin
{ use ESP as frame pointer }
procinfo^.framepointer:=STACK_POINTER_REG;
use_esp_stackframe:=true;
{ can we omit the stack frame ? }
{ conditions:
1. procedure (not main block)
2. no constructor or destructor
3. no call to other procedures
4. no interrupt handler
}
{!!!!!! this doesn work yet, because of problems with
with linux and windows
}
(*
if assigned(aktprocsym) then
begin
if not(assigned(procinfo^._class)) and
not(aktprocdef.proctypeoption in [potype_constructor,potype_destructor]) and
not(po_interrupt in aktprocdef.procoptions) and
((procinfo^.flags and pi_do_call)=0) and
(lexlevel>=normal_function_level) then
begin
{ use ESP as frame pointer }
procinfo^.framepointer:=STACK_POINTER_REG;
use_esp_stackframe:=true;
{ calc parameter distance new }
dec(procinfo^.framepointer_offset,4);
dec(procinfo^.selfpointer_offset,4);
{ calc parameter distance new }
dec(procinfo^.framepointer_offset,4);
dec(procinfo^.selfpointer_offset,4);
{ is this correct ???}
{ retoffset can be negativ for results in eax !! }
{ the value should be decreased only if positive }
if procinfo^.retoffset>=0 then
dec(procinfo^.retoffset,4);
{ is this correct ???}
{ retoffset can be negativ for results in eax !! }
{ the value should be decreased only if positive }
if procinfo^.retoffset>=0 then
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) }
assign_regvars(p);
load_regvars(procinfo^.aktentrycode,p);
@ -320,7 +321,14 @@ implementation
end.
{
$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
+ first parameter offset in stack now portable
* rename some constants

View File

@ -794,6 +794,7 @@ implementation
p:=comp_expr(true);
if p.nodetype=stringconstn then
begin
stringdispose(aktclass.iidstr);
aktclass.iidstr:=stringdup(strpas(tstringconstnode(p).value_str)); { or upper? }
p.free;
aktclass.isiidguidvalid:=string2guid(aktclass.iidstr^,aktclass.iidguid);
@ -1110,7 +1111,14 @@ implementation
end.
{
$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
in most cases and not written to the ppu
* add mangeledname_prefix() routine to generate the prefix of

View File

@ -329,7 +329,6 @@ implementation
orgsp,sp:stringid;
paramoffset:longint;
sym:tsym;
doinsert : boolean;
st : tsymtable;
srsymtable : tsymtable;
pdl : pprocdeflist;
@ -478,7 +477,6 @@ implementation
end;
end;
doinsert:=true;
if assigned(aktprocsym) then
begin
{ Check if overloaded is a procsym }
@ -498,8 +496,9 @@ implementation
Message1(parser_e_overloaded_no_procedure,aktprocsym.realname)
else
DuplicateSym(aktprocsym);
{ don't reinsert as that will generated another error }
doinsert:=false;
{ rename the name to an unique name to avoid an
error when inserting the symbol in the symtable }
orgsp:=orgsp+'$'+tostr(aktfilepos.line);
end;
{ generate a new aktprocsym }
aktprocsym:=nil;
@ -537,8 +536,7 @@ implementation
end
else
aktprocsym:=tprocsym.create(orgsp);
if doinsert then
symtablestack.insert(aktprocsym);
symtablestack.insert(aktprocsym);
end;
st:=symtablestack;
@ -1908,23 +1906,31 @@ const
{ insert otsym only in the right symtable }
if ((procinfo^.flags and pi_operator)<>0) and
assigned(otsym) and
not parse_only then
begin
if ret_in_param(aprocdef.rettype.def) then
begin
aprocdef.parast.insert(otsym);
{ this increases the data size }
{ correct this to get the right ret $value }
dec(aprocdef.parast.datasize,
align(otsym.getpushsize,aktprocdef.parast.dataalignment));
{ this allows to read the funcretoffset }
otsym.address:=-4;
otsym.varspez:=vs_var;
end
else
aprocdef.localst.insert(otsym);
end;
assigned(otsym) then
begin
if not parse_only then
begin
if ret_in_param(aprocdef.rettype.def) then
begin
aprocdef.parast.insert(otsym);
{ this increases the data size }
{ correct this to get the right ret $value }
dec(aprocdef.parast.datasize,
align(otsym.getpushsize,aktprocdef.parast.dataalignment));
{ this allows to read the funcretoffset }
otsym.address:=-4;
otsym.varspez:=vs_var;
end
else
aprocdef.localst.insert(otsym);
end
else
begin
{ this is not required anymore }
otsym.free;
otsym:=nil;
end;
end;
proc_add_definition:=forwardfound;
end;
@ -1932,7 +1938,14 @@ const
end.
{
$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
+ first parameter offset in stack now portable
* rename some constants

View File

@ -220,6 +220,9 @@ implementation
function new_dispose_statement(is_new:boolean) : tnode;
var
newstatement : tstatementnode;
temp : ttempcreatenode;
para : tcallparanode;
p,p2 : tnode;
again : boolean; { dummy for do_proc_call }
destructorname : stringid;
@ -293,11 +296,10 @@ implementation
else
begin
if is_new then
p2:=chnewnode.create
p2:=chnewnode.create(tpointerdef(p.resulttype.def).pointertype)
else
p2:=chdisposenode.create(p);
do_resulttypepass(p2);
p2.resulttype:=tpointerdef(p.resulttype.def).pointertype;
if is_new then
do_member_read(false,sym,p2,again)
else
@ -329,8 +331,6 @@ implementation
begin
if (tcallnode(p2).procdefinition.proctypeoption<>potype_constructor) then
Message(parser_e_expr_have_to_be_constructor_call);
p2:=cnewnode.create(p2);
do_resulttypepass(p2);
p2.resulttype:=p.resulttype;
p2:=cassignmentnode.create(p,p2);
end
@ -365,10 +365,57 @@ implementation
Message(parser_e_no_new_dispose_on_void_pointers);
end;
{ create statements with call to getmem+initialize or
finalize+freemem }
new_dispose_statement:=internalstatements(newstatement);
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
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;
consume(_RKLAMMER);
@ -377,6 +424,10 @@ implementation
function new_function : tnode;
var
newstatement : tstatementnode;
newblock : tblocknode;
temp : ttempcreatenode;
para : tcallparanode;
p1,p2 : tnode;
classh : tobjectdef;
sym : tsym;
@ -399,26 +450,52 @@ implementation
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);
p2:=cnewnode.create(nil);
do_resulttypepass(p2);
p2.resulttype:=p1.resulttype;
Message(parser_w_use_extended_syntax_for_objects);
{ create statements with call to getmem+initialize }
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:=p2;
p1:=newblock;
consume(_RKLAMMER);
end
else
begin
p2:=chnewnode.create;
p2:=chnewnode.create(tpointerdef(p1.resulttype.def).pointertype);
do_resulttypepass(p2);
p2.resulttype:=tpointerdef(p1.resulttype.def).pointertype;
consume(_COMMA);
afterassignment:=false;
{ determines the current object defintion }
classh:=tobjectdef(p2.resulttype.def);
if classh.deftype<>objectdef then
Message(parser_e_pointer_to_class_expected)
else
if classh.deftype=objectdef then
begin
{ check for an abstract class }
if (oo_has_abstract in classh.objectoptions) then
@ -434,9 +511,11 @@ implementation
(assigned(tcallnode(p2).procdefinition) and
(tcallnode(p2).procdefinition.proctypeoption<>potype_constructor)) then
Message(parser_e_expr_have_to_be_constructor_call);
end;
p2:=cnewnode.create(p2);
do_resulttypepass(p2);
end
else
Message(parser_e_pointer_to_class_expected);
{ constructors return boolean, update resulttype to return
the pointer to the object }
p2.resulttype:=p1.resulttype;
p1.destroy;
p1:=p2;
@ -2458,7 +2537,14 @@ implementation
end.
{
$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
will do nothing like delphi

View File

@ -991,8 +991,8 @@ implementation
{ blockn support because a read/write is changed into a blocknode }
{ with a separate statement for each read/write operation (JM) }
{ 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,
simplenewn,simpledisposen]) then
if not(p.nodetype in [nothingn,calln,assignn,breakn,inlinen,
continuen,labeln,blockn]) then
Message(cg_e_illegal_expression);
{ specify that we don't use the value returned by the call }
@ -1071,7 +1071,7 @@ implementation
{# Optimize the assembler block by removing all references
which are via the frame pointer by replacing them with
references via the stack pointer.
This is only available to certain cpu targets where
the frame pointer saving must be done explicitly.
}
@ -1178,8 +1178,8 @@ implementation
following conditions are met:
- if the are no local variables
- no reference to the result variable (refcount<=1)
- result is not stored as parameter
- target processor has optional frame pointer save
- result is not stored as parameter
- target processor has optional frame pointer save
(vm, i386, vm only currently)
}
if (po_assembler in aktprocdef.procoptions) and
@ -1213,7 +1213,14 @@ implementation
end.
{
$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
+ first parameter offset in stack now portable
* rename some constants

View File

@ -745,6 +745,8 @@ implementation
prefix : string;
begin
prefix:='';
if not assigned(st) then
internalerror(200204212);
{ sub procedures }
while (st.symtabletype=localsymtable) do
begin
@ -5468,7 +5470,14 @@ implementation
end.
{
$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
+ first parameter offset in stack now portable
* rename some constants