* sym.insert_in_data removed

* symtable.insertvardata/insertconstdata added
  * removed insert_in_data call from symtable.insert, it needs to be
    called separatly. This allows to deref the address calculation
  * procedures now calculate the parast addresses after the procedure
    directives are parsed. This fixes the cdecl parast problem
  * push_addr_param has an extra argument that specifies if cdecl is used
    or not
This commit is contained in:
peter 2002-08-25 19:25:18 +00:00
parent 8a43a12934
commit a28f75ed03
19 changed files with 631 additions and 426 deletions

View File

@ -1461,7 +1461,7 @@ end;
end
else
MemInfo.Size:=getsize;
MemInfo.PushSize:=getpushsize;
MemInfo.PushSize:=getpushsize(false);
Symbol^.SetMemInfo(MemInfo);
end;
constsym :
@ -2125,7 +2125,17 @@ begin
end.
{
$Log$
Revision 1.26 2002-07-02 06:09:08 michael
Revision 1.27 2002-08-25 19:25:18 peter
* sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be
called separatly. This allows to deref the address calculation
* procedures now calculate the parast addresses after the procedure
directives are parsed. This fixes the cdecl parast problem
* push_addr_param has an extra argument that specifies if cdecl is used
or not
Revision 1.26 2002/07/02 06:09:08 michael
+ Patch from peter to fix snapshots
Revision 1.25 2002/05/18 13:34:05 peter

View File

@ -114,7 +114,7 @@ implementation
{ handle varargs first, because defcoll is not valid }
if (nf_varargs_para in flags) then
begin
if paramanager.push_addr_param(left.resulttype.def) then
if paramanager.push_addr_param(left.resulttype.def,is_cdecl) then
begin
inc(pushedparasize,4);
cg.a_paramaddr_ref(exprasmlist,left.location.reference,paralocdummy);
@ -214,8 +214,7 @@ implementation
is_array_of_const(defcoll.paratype.def))
) or
(
paramanager.push_addr_param(resulttype.def) and
not is_cdecl
paramanager.push_addr_param(resulttype.def,is_cdecl)
) then
begin
if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
@ -1315,7 +1314,17 @@ begin
end.
{
$Log$
Revision 1.66 2002-08-23 16:14:49 peter
Revision 1.67 2002-08-25 19:25:21 peter
* sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be
called separatly. This allows to deref the address calculation
* procedures now calculate the parast addresses after the procedure
directives are parsed. This fixes the cdecl parast problem
* push_addr_param has an extra argument that specifies if cdecl is used
or not
Revision 1.66 2002/08/23 16:14:49 peter
* tempgen cleanup
* tt_noreuse temp type added that will be used in genentrycode

View File

@ -116,7 +116,7 @@ implementation
{ handle varargs first, because defcoll is not valid }
if (nf_varargs_para in flags) then
begin
if paramanager.push_addr_param(left.resulttype.def) then
if paramanager.push_addr_param(left.resulttype.def,is_cdecl) then
begin
inc(pushedparasize,4);
cg.a_paramaddr_ref(exprasmlist,left.location.reference,defcoll.paraloc);
@ -216,8 +216,7 @@ implementation
is_array_of_const(defcoll.paratype.def))
) or
(
paramanager.push_addr_param(resulttype.def) and
not is_cdecl
paramanager.push_addr_param(resulttype.def,is_cdecl)
) then
begin
if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
@ -1476,7 +1475,17 @@ begin
end.
{
$Log$
Revision 1.15 2002-08-23 16:14:48 peter
Revision 1.16 2002-08-25 19:25:18 peter
* sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be
called separatly. This allows to deref the address calculation
* procedures now calculate the parast addresses after the procedure
directives are parsed. This fixes the cdecl parast problem
* push_addr_param has an extra argument that specifies if cdecl is used
or not
Revision 1.15 2002/08/23 16:14:48 peter
* tempgen cleanup
* tt_noreuse temp type added that will be used in genentrycode

View File

@ -52,7 +52,7 @@ implementation
uses
systems,
verbose,globals,
verbose,globtype,globals,
symconst,symtype,symdef,symsym,symtable,defbase,paramgr,
ncnv,ncon,nmem,
aasmbase,aasmtai,aasmcpu,regvars,
@ -68,6 +68,7 @@ implementation
var
intreg,
hregister : tregister;
is_cdecl,
freereg : boolean;
symtabletype : tsymtabletype;
i : longint;
@ -248,13 +249,16 @@ implementation
end;
end;
end;
{ cdecl procedure }
is_cdecl:=(symtabletype=parasymtable) and
(tprocdef(symtable.defowner).proccalloption in [pocall_cdecl,pocall_cppdecl]);
{ in case call by reference, then calculate. Open array
is always an reference! }
if (tvarsym(symtableentry).varspez in [vs_var,vs_out]) or
is_open_array(tvarsym(symtableentry).vartype.def) or
is_array_of_const(tvarsym(symtableentry).vartype.def) or
((tvarsym(symtableentry).varspez=vs_const) and
paramanager.push_addr_param(tvarsym(symtableentry).vartype.def)) then
paramanager.push_addr_param(tvarsym(symtableentry).vartype.def,is_cdecl)) then
begin
if hregister=R_NO then
hregister:=rg.getaddressregister(exprasmlist);
@ -940,7 +944,17 @@ begin
end.
{
$Log$
Revision 1.25 2002-08-23 16:14:48 peter
Revision 1.26 2002-08-25 19:25:18 peter
* sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be
called separatly. This allows to deref the address calculation
* procedures now calculate the parast addresses after the procedure
directives are parsed. This fixes the cdecl parast problem
* push_addr_param has an extra argument that specifies if cdecl is used
or not
Revision 1.25 2002/08/23 16:14:48 peter
* tempgen cleanup
* tt_noreuse temp type added that will be used in genentrycode

View File

@ -737,7 +737,7 @@ implementation
begin
{ call by value open array ? }
if is_cdecl and
paramanager.push_addr_param(p.resulttype.def) then
paramanager.push_addr_param(p.resulttype.def,false) then
begin
if not (p.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
internalerror(200204241);
@ -839,7 +839,7 @@ implementation
list:=taasmoutput(arg);
if (tsym(p).typ=varsym) and
(tvarsym(p).varspez=vs_value) and
(paramanager.push_addr_param(tvarsym(p).vartype.def)) then
(paramanager.push_addr_param(tvarsym(p).vartype.def,false)) then
begin
reference_reset_base(href1,procinfo.framepointer,tvarsym(p).address+procinfo.para_offset);
if is_open_array(tvarsym(p).vartype.def) or
@ -1732,7 +1732,17 @@ implementation
end.
{
$Log$
Revision 1.42 2002-08-24 18:38:26 peter
Revision 1.43 2002-08-25 19:25:18 peter
* sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be
called separatly. This allows to deref the address calculation
* procedures now calculate the parast addresses after the procedure
directives are parsed. This fixes the cdecl parast problem
* push_addr_param has an extra argument that specifies if cdecl is used
or not
Revision 1.42 2002/08/24 18:38:26 peter
* really use tt_noreuse for exception frame buffers
Revision 1.41 2002/08/23 16:14:49 peter

View File

@ -396,7 +396,7 @@ implementation
{ we need a register for call by reference parameters }
if (tvarsym(symtableentry).varspez in [vs_var,vs_out]) or
((tvarsym(symtableentry).varspez=vs_const) and
paramanager.push_addr_param(tvarsym(symtableentry).vartype.def)) or
paramanager.push_addr_param(tvarsym(symtableentry).vartype.def,false)) or
{ call by value open arrays are also indirect addressed }
is_open_array(tvarsym(symtableentry).vartype.def) then
registers32:=1;
@ -1120,7 +1120,17 @@ begin
end.
{
$Log$
Revision 1.53 2002-08-19 19:36:43 peter
Revision 1.54 2002-08-25 19:25:19 peter
* sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be
called separatly. This allows to deref the address calculation
* procedures now calculate the parast addresses after the procedure
directives are parsed. This fixes the cdecl parast problem
* push_addr_param has an extra argument that specifies if cdecl is used
or not
Revision 1.53 2002/08/19 19:36:43 peter
* More fixes for cross unit inlining, all tnodes are now implemented
* Moved pocall_internconst to po_internconst because it is not a
calling type at all and it conflicted when inlining of these small

View File

@ -56,7 +56,7 @@ unit paramgr;
{# Returns true if a parameter is too large to copy and only
the address is pushed
}
function push_addr_param(def : tdef) : boolean;virtual;
function push_addr_param(def : tdef;is_cdecl:boolean) : boolean;virtual;
{# Returns a structure giving the information on
the storage of the parameter (which must be
an integer parameter)
@ -138,7 +138,7 @@ unit paramgr;
{ true if a parameter is too large to copy and only the address is pushed }
function tparamanager.push_addr_param(def : tdef) : boolean;
function tparamanager.push_addr_param(def : tdef;is_cdecl:boolean) : boolean;
begin
push_addr_param:=false;
if never_copy_const_param then
@ -150,9 +150,13 @@ unit paramgr;
formaldef :
push_addr_param:=true;
recorddef :
push_addr_param:=(def.size>pointer_size);
push_addr_param:=(not is_cdecl) and (def.size>pointer_size);
arraydef :
push_addr_param:=((tarraydef(def).highrange>=tarraydef(def).lowrange) and (def.size>pointer_size)) or
push_addr_param:=(
(tarraydef(def).highrange>=tarraydef(def).lowrange) and
(def.size>pointer_size) and
(not is_cdecl)
) or
is_open_array(def) or
is_array_of_const(def) or
is_array_constructor(def);
@ -161,9 +165,9 @@ unit paramgr;
stringdef :
push_addr_param:=tstringdef(def).string_typ in [st_shortstring,st_longstring];
procvardef :
push_addr_param:=(po_methodpointer in tprocvardef(def).procoptions);
push_addr_param:=(not is_cdecl) and (po_methodpointer in tprocvardef(def).procoptions);
setdef :
push_addr_param:=(tsetdef(def).settype<>smallset);
push_addr_param:=(not is_cdecl) and (tsetdef(def).settype<>smallset);
end;
end;
end;
@ -302,7 +306,17 @@ end.
{
$Log$
Revision 1.14 2002-08-17 22:09:47 florian
Revision 1.15 2002-08-25 19:25:19 peter
* sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be
called separatly. This allows to deref the address calculation
* procedures now calculate the parast addresses after the procedure
directives are parsed. This fixes the cdecl parast problem
* push_addr_param has an extra argument that specifies if cdecl is used
or not
Revision 1.14 2002/08/17 22:09:47 florian
* result type handling in tcgcal.pass_2 overhauled
* better tnode.dowrite
* some ppc stuff fixed

View File

@ -195,6 +195,7 @@ implementation
sym:=ttypedconstsym.createtype(orgname,tt,(cs_typed_const_writable in aktlocalswitches));
akttokenpos:=storetokenpos;
symtablestack.insert(sym);
symtablestack.insertconstdata(sym);
{ procvar can have proc directives }
if (tt.def.deftype=procvardef) then
begin
@ -616,7 +617,17 @@ implementation
end.
{
$Log$
Revision 1.52 2002-08-12 15:08:40 carl
Revision 1.53 2002-08-25 19:25:19 peter
* sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be
called separatly. This allows to deref the address calculation
* procedures now calculate the parast addresses after the procedure
directives are parsed. This fixes the cdecl parast problem
* push_addr_param has an extra argument that specifies if cdecl is used
or not
Revision 1.52 2002/08/12 15:08:40 carl
+ stab register indexes for powerpc (moved from gdb to cpubase)
+ tprocessor enumeration moved to cpuinfo
+ linker in target_info is now a class

View File

@ -46,6 +46,7 @@ interface
procedure parse_proc_directives(var pdflags:word);
procedure handle_calling_convention(sym:tprocsym;def:tabstractprocdef);
procedure calc_parasymtable_addresses(def:tprocdef);
procedure parse_proc_head(options:tproctypeoption);
procedure parse_proc_dec;
@ -282,7 +283,8 @@ implementation
{ but I suppose the comment is wrong and }
{ it means that the address of var parameters can be placed }
{ in a register (FK) }
if (varspez in [vs_var,vs_const,vs_out]) and paramanager.push_addr_param(tt.def) then
if (varspez in [vs_var,vs_const,vs_out]) and
paramanager.push_addr_param(tt.def,false) then
include(vs.varoptions,vo_regable);
{ insert the sym in the parasymtable }
@ -291,7 +293,7 @@ implementation
{ do we need a local copy? Then rename the varsym, do this after the
insert so the dup id checking is done correctly }
if (varspez=vs_value) and
paramanager.push_addr_param(tt.def) and
paramanager.push_addr_param(tt.def,aktprocdef.proccalloption in [pocall_cdecl,pocall_cppdecl]) and
not(is_open_array(tt.def) or is_array_of_const(tt.def)) then
tprocdef(aktprocdef).parast.rename(vs.name,'val'+vs.name);
@ -1462,14 +1464,10 @@ const
procedure handle_calling_convention(sym:tprocsym;def:tabstractprocdef);
var
st,parast : tsymtable;
lastps,
highps,ps : tsym;
begin
{ set the default calling convention }
if def.proccalloption=pocall_none then
def.proccalloption:=aktdefproccall;
def.proccalloption:=aktdefproccall;
case def.proccalloption of
pocall_cdecl :
begin
@ -1485,8 +1483,8 @@ const
internalerror(200110234);
{ do not copy on local !! }
tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}resetvaluepara,nil);
{ Adjust positions of args for cdecl or stdcall }
tparasymtable(tprocdef(def).parast).set_alignment(std_param_align);
{ Adjust alignment to match cdecl or stdcall }
tprocdef(def).parast.dataalignment:=std_param_align;
end;
end;
pocall_cppdecl :
@ -1505,18 +1503,19 @@ const
internalerror(200110235);
{ do not copy on local !! }
tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}resetvaluepara,nil);
{ Adjust positions of args for cdecl or stdcall }
tparasymtable(tprocdef(def).parast).set_alignment(std_param_align);
{ Adjust alignment to match cdecl or stdcall }
tprocdef(def).parast.dataalignment:=std_param_align;
end;
end;
pocall_stdcall :
begin
include(def.procoptions,po_savestdregs);
if (def.deftype=procdef) and
assigned(tprocdef(def).parast) then
if (def.deftype=procdef) then
begin
{ Adjust positions of args for cdecl or stdcall }
tparasymtable(tprocdef(def).parast).set_alignment(std_param_align);
if not assigned(tprocdef(def).parast) then
internalerror(200110236);
{ Adjust alignment to match cdecl or stdcall }
tprocdef(def).parast.dataalignment:=std_param_align;
end;
end;
pocall_safecall :
@ -1533,44 +1532,6 @@ const
pocall_pascal :
begin
include(def.procoptions,po_leftright);
if def.deftype=procdef then
begin
st:=tparasymtable.create;
st.symindex.noclear:=true;
parast:=tprocdef(def).parast;
highps:=nil;
lastps:=nil;
while assigned(parast.symindex.first) and (lastps<>tsym(parast.symindex.first)) do
begin
ps:=tsym(parast.symindex.first);
while assigned(ps.indexnext) and (tsym(ps.indexnext)<>lastps) do
ps:=tsym(ps.indexnext);
{ Wait with inserting the high value, it needs to be inserted
after the corresponding parameter }
if Copy(ps.name,1,4)='high' then
highps:=ps
else
begin
{ recalculate the corrected offset by inserting it into
the new symtable and then reset the owner back }
ps.owner:=st;
tstoredsym(ps).insert_in_data;
ps.owner:=parast;
{ add also the high tree if it was saved }
if assigned(highps) then
begin
highps.owner:=st;
tstoredsym(highps).insert_in_data;
highps.owner:=parast;
highps:=nil;
end;
end;
lastps:=ps;
end;
st.free;
if assigned(highps) then
internalerror(200205111);
end;
end;
pocall_register :
begin
@ -1602,7 +1563,7 @@ const
{ do not copy on local !! }
tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}resetvaluepara,nil);
{ Adjust positions of args for cdecl or stdcall }
tparasymtable(tprocdef(def).parast).set_alignment(std_param_align);
tprocdef(def).parast.dataalignment:=std_param_align;
end;
end;
pocall_inline :
@ -1623,6 +1584,59 @@ const
end;
procedure calc_parasymtable_addresses(def:tprocdef);
var
lastps,
highps,ps : tsym;
st : tsymtable;
begin
st:=def.parast;
if po_leftright in def.procoptions then
begin
{ pushed in reversed order, left to right }
highps:=nil;
lastps:=nil;
while assigned(st.symindex.first) and (lastps<>tsym(st.symindex.first)) do
begin
ps:=tsym(st.symindex.first);
while assigned(ps.indexnext) and (tsym(ps.indexnext)<>lastps) do
ps:=tsym(ps.indexnext);
if ps.typ=varsym then
begin
{ Wait with inserting the high value, it needs to be inserted
after the corresponding parameter }
if Copy(ps.name,1,4)='high' then
highps:=ps
else
begin
st.insertvardata(ps);
{ add also the high tree if it was saved }
if assigned(highps) then
begin
st.insertvardata(highps);
highps:=nil;
end;
end;
end;
lastps:=ps;
end;
if assigned(highps) then
internalerror(200208257);
end
else
begin
{ pushed in normal order, right to left }
ps:=tsym(st.symindex.first);
while assigned(ps) do
begin
if ps.typ=varsym then
st.insertvardata(ps);
ps:=tsym(ps.indexnext);
end;
end;
end;
procedure parse_proc_directives(var pdflags:word);
{
Parse the procedure directives. It does not matter if procedure directives
@ -1662,6 +1676,9 @@ const
break;
end;
handle_calling_convention(aktprocsym,aktprocdef);
{ calculate addresses in parasymtable }
if aktprocdef.deftype=procdef then
calc_parasymtable_addresses(aktprocdef);
end;
@ -1944,16 +1961,15 @@ const
if paramanager.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);
begin
aprocdef.localst.insert(otsym);
aprocdef.localst.insertvardata(otsym);
end;
end
else
begin
@ -1969,7 +1985,17 @@ const
end.
{
$Log$
Revision 1.67 2002-08-25 11:33:06 peter
Revision 1.68 2002-08-25 19:25:20 peter
* sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be
called separatly. This allows to deref the address calculation
* procedures now calculate the parast addresses after the procedure
directives are parsed. This fixes the cdecl parast problem
* push_addr_param has an extra argument that specifies if cdecl is used
or not
Revision 1.67 2002/08/25 11:33:06 peter
* also check the paratypes when a forward was found
Revision 1.66 2002/08/19 19:36:44 peter

View File

@ -67,7 +67,7 @@ implementation
var
s : string;
filepos : tfileposinfo;
ss : tvarsym;
ss,ss2 : tvarsym;
begin
filepos:=akttokenpos;
while not sc.empty do
@ -81,8 +81,14 @@ implementation
if (st.symtabletype=objectsymtable) and
(sp_static in current_object_option) then
begin
s:='$'+lower(st.name^)+'_'+upper(s);
st.defowner.owner.insert(tvarsym.create(s,tt));
ss2:=tvarsym.create('$'+lower(st.name^)+'_'+upper(s),tt);
st.defowner.owner.insert(ss2);
st.defowner.owner.insertvardata(ss2);
end
else
begin
{ external data is not possible here }
st.insertvardata(ss);
end;
end;
{$ifdef fixLeaksOnError}
@ -190,6 +196,7 @@ implementation
aktvarsym:=tvarsym.create_C(s,target_info.Cprefix+C_name,tt);
include(aktvarsym.varoptions,vo_is_external);
symtablestack.insert(aktvarsym);
{ external, so no insert in the data }
akttokenpos:=storetokenpos;
symdone:=true;
end;
@ -317,6 +324,7 @@ implementation
Message(parser_e_initialized_only_one_var);
tconstsym:=ttypedconstsym.createtype(s,tt,true);
symtablestack.insert(tconstsym);
symtablestack.insertconstdata(tconstsym);
akttokenpos:=storetokenpos;
consume(_EQUAL);
readtypedconst(tt,tconstsym,true);
@ -415,8 +423,11 @@ implementation
end;
if extern_aktvarsym then
include(aktvarsym.varoptions,vo_is_external);
{ insert in the stack/datasegment }
{ insert in the symtable }
symtablestack.insert(aktvarsym);
{ insert in the datasegment when it is not external }
if not extern_aktvarsym then
symtablestack.insertvardata(aktvarsym);
akttokenpos:=storetokenpos;
{ now we can insert it in the import lib if its a dll, or
add it to the externals }
@ -497,7 +508,9 @@ implementation
symtablestack:=symtablestack.next;
read_type(casetype,'');
symtablestack:=oldsymtablestack;
symtablestack.insert(tvarsym.create(s,casetype));
aktvarsym:=tvarsym.create(s,casetype);
symtablestack.insert(aktvarsym);
symtablestack.insertvardata(aktvarsym);
end;
if not(is_ordinal(casetype.def)) or is_64bitint(casetype.def) then
Message(type_e_ordinal_expr_expected);
@ -584,7 +597,17 @@ implementation
end.
{
$Log$
Revision 1.30 2002-07-29 21:23:44 florian
Revision 1.31 2002-08-25 19:25:20 peter
* sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be
called separatly. This allows to deref the address calculation
* procedures now calculate the parast addresses after the procedure
directives are parsed. This fixes the cdecl parast problem
* push_addr_param has an extra argument that specifies if cdecl is used
or not
Revision 1.30 2002/07/29 21:23:44 florian
* more fixes for the ppc
+ wrappers for the tcnvnode.first_* stuff introduced

View File

@ -1247,7 +1247,6 @@ implementation
begin
gen_main_procsym(current_module.modulename^+'_main',potype_proginit,st);
aktprocdef.aliasnames.insert(target_info.cprefix+current_module.modulename^+'_main');
aktprocdef.aliasnames.insert('PASCALMAIN');
{ this code is called from C so we need to save some
registers }
include(aktprocdef.procoptions,po_savestdregs);
@ -1388,7 +1387,17 @@ implementation
end.
{
$Log$
Revision 1.73 2002-08-18 20:06:25 peter
Revision 1.74 2002-08-25 19:25:20 peter
* sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be
called separatly. This allows to deref the address calculation
* procedures now calculate the parast addresses after the procedure
directives are parsed. This fixes the cdecl parast problem
* push_addr_param has an extra argument that specifies if cdecl is used
or not
Revision 1.73 2002/08/18 20:06:25 peter
* inlining is now also allowed in interface
* renamed write/load to ppuwrite/ppuload
* tnode storing in ppu

View File

@ -1089,6 +1089,7 @@ implementation
{ insert in local symtable }
{ but with another name, so that recursive calls are possible }
symtablestack.insert(aktprocdef.funcretsym);
symtablestack.insertvardata(aktprocdef.funcretsym);
symtablestack.rename(aktprocdef.funcretsym.name,'$result');
{ update the symtablesize back to 0 if there were no locals }
if not haslocals then
@ -1096,7 +1097,7 @@ implementation
{ set the used registers depending on the function result }
procinfo.update_usedinproc_result;
end;
{ force the asm statement }
if token<>_ASM then
@ -1144,7 +1145,17 @@ implementation
end.
{
$Log$
Revision 1.72 2002-08-17 09:23:40 florian
Revision 1.73 2002-08-25 19:25:20 peter
* sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be
called separatly. This allows to deref the address calculation
* procedures now calculate the parast addresses after the procedure
directives are parsed. This fixes the cdecl parast problem
* push_addr_param has an extra argument that specifies if cdecl is used
or not
Revision 1.72 2002/08/17 09:23:40 florian
* first part of procinfo rewrite
Revision 1.71 2002/08/16 14:24:58 carl
@ -1279,4 +1290,4 @@ end.
Revision 1.45 2002/01/24 18:25:49 peter
* implicit result variable generation for assembler routines
* removed m_tp modeswitch, use m_tp7 or not(m_fpc) instead
}
}

View File

@ -105,6 +105,7 @@ implementation
aktprocdef.funcretsym:=tfuncretsym.create(aktprocsym.name,aktprocdef.rettype);
{ insert in local symtable }
symtablestack.insert(aktprocdef.funcretsym);
symtablestack.insertvardata(aktprocdef.funcretsym);
akttokenpos:=storepos;
procinfo.set_result_offset;
@ -455,6 +456,7 @@ implementation
vs.fileinfo:=fileinfo;
vs.varspez:=varspez;
aktprocdef.localst.insert(vs);
aktprocdef.localst.insertvardata(vs);
include(vs.varoptions,vo_is_local_copy);
vs.varstate:=vs_assigned;
localvarsym:=vs;
@ -786,7 +788,17 @@ implementation
end.
{
$Log$
Revision 1.68 2002-08-17 09:23:41 florian
Revision 1.69 2002-08-25 19:25:20 peter
* sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be
called separatly. This allows to deref the address calculation
* procedures now calculate the parast addresses after the procedure
directives are parsed. This fixes the cdecl parast problem
* push_addr_param has an extra argument that specifies if cdecl is used
or not
Revision 1.68 2002/08/17 09:23:41 florian
* first part of procinfo rewrite
Revision 1.67 2002/08/16 14:24:59 carl
@ -933,4 +945,4 @@ end.
Revision 1.42 2002/01/19 15:12:34 peter
* check for unresolved forward classes in the interface
}
}

View File

@ -874,7 +874,7 @@ Begin
end;
if (tvarsym(sym).varspez=vs_var) or
((tvarsym(sym).varspez=vs_const) and
paramanager.push_addr_param(tvarsym(sym).vartype.def)) then
paramanager.push_addr_param(tvarsym(sym).vartype.def,false)) then
SetSize(pointer_size,false);
end;
localsymtable :
@ -914,7 +914,7 @@ Begin
end;
if (tvarsym(sym).varspez in [vs_var,vs_out]) or
((tvarsym(sym).varspez=vs_const) and
paramanager.push_addr_param(tvarsym(sym).vartype.def)) then
paramanager.push_addr_param(tvarsym(sym).vartype.def,false)) then
SetSize(pointer_size,false);
end;
end;
@ -1592,7 +1592,17 @@ end;
end.
{
$Log$
Revision 1.44 2002-08-17 09:23:41 florian
Revision 1.45 2002-08-25 19:25:20 peter
* sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be
called separatly. This allows to deref the address calculation
* procedures now calculate the parast addresses after the procedure
directives are parsed. This fixes the cdecl parast problem
* push_addr_param has an extra argument that specifies if cdecl is used
or not
Revision 1.44 2002/08/17 09:23:41 florian
* first part of procinfo rewrite
Revision 1.43 2002/08/16 14:24:59 carl

View File

@ -178,7 +178,7 @@ implementation
{ call by reference/const ? }
if (regvarinfo^.regvars[i].varspez in [vs_var,vs_out]) or
((regvarinfo^.regvars[i].varspez=vs_const) and
paramanager.push_addr_param(regvarinfo^.regvars[i].vartype.def)) then
paramanager.push_addr_param(regvarinfo^.regvars[i].vartype.def,false)) then
begin
regvarinfo^.regvars[i].reg:=varregs[i];
end
@ -316,7 +316,7 @@ implementation
hr.base:=procinfo.framepointer;
if (vsym.varspez in [vs_var,vs_out]) or
((vsym.varspez=vs_const) and
paramanager.push_addr_param(vsym.vartype.def)) then
paramanager.push_addr_param(vsym.vartype.def,false)) then
opsize := OS_ADDR
else
opsize := def_cgsize(vsym.vartype.def);
@ -469,7 +469,17 @@ end.
{
$Log$
Revision 1.40 2002-08-18 20:06:25 peter
Revision 1.41 2002-08-25 19:25:20 peter
* sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be
called separatly. This allows to deref the address calculation
* procedures now calculate the parast addresses after the procedure
directives are parsed. This fixes the cdecl parast problem
* push_addr_param has an extra argument that specifies if cdecl is used
or not
Revision 1.40 2002/08/18 20:06:25 peter
* inlining is now also allowed in interface
* renamed write/load to ppuwrite/ppuload
* tnode storing in ppu

View File

@ -116,6 +116,8 @@ interface
procedure foreach(proc2call : tnamedindexcallback;arg:pointer);
procedure foreach_static(proc2call : tnamedindexstaticcallback;arg:pointer);
procedure insert(sym : tsymentry);virtual;
procedure insertvardata(sym : tsymentry);virtual;abstract;
procedure insertconstdata(sym : tsymentry);virtual;abstract;
function search(const s : stringid) : tsymentry;
function speedsearch(const s : stringid;speedvalue : cardinal) : tsymentry;virtual;
procedure registerdef(p : tdefentry);
@ -304,14 +306,20 @@ implementation
begin
end;
end.
{
$Log$
Revision 1.6 2002-05-18 13:34:18 peter
Revision 1.7 2002-08-25 19:25:20 peter
* sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be
called separatly. This allows to deref the address calculation
* procedures now calculate the parast addresses after the procedure
directives are parsed. This fixes the cdecl parast problem
* push_addr_param has an extra argument that specifies if cdecl is used
or not
Revision 1.6 2002/05/18 13:34:18 peter
* readded missing revisions
Revision 1.5 2002/05/16 19:46:44 carl

View File

@ -3209,8 +3209,10 @@ implementation
var
pdc : TParaItem;
l : longint;
is_cdecl : boolean;
begin
l:=0;
is_cdecl:=(proccalloption in [pocall_cdecl,pocall_cppdecl]);
pdc:=TParaItem(Para.first);
while assigned(pdc) do
begin
@ -3218,7 +3220,7 @@ implementation
vs_out,
vs_var : inc(l,POINTER_SIZE);
vs_value,
vs_const : if paramanager.push_addr_param(pdc.paratype.def) then
vs_const : if paramanager.push_addr_param(pdc.paratype.def,is_cdecl) then
inc(l,POINTER_SIZE)
else
inc(l,pdc.paratype.def.size);
@ -5507,7 +5509,17 @@ implementation
end.
{
$Log$
Revision 1.90 2002-08-18 20:06:25 peter
Revision 1.91 2002-08-25 19:25:20 peter
* sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be
called separatly. This allows to deref the address calculation
* procedures now calculate the parast addresses after the procedure
directives are parsed. This fixes the cdecl parast problem
* push_addr_param has an extra argument that specifies if cdecl is used
or not
Revision 1.90 2002/08/18 20:06:25 peter
* inlining is now also allowed in interface
* renamed write/load to ppuwrite/ppuload
* tnode storing in ppu

View File

@ -63,7 +63,6 @@ interface
procedure ppuwrite(ppufile:tcompilerppufile);virtual;abstract;
procedure writesym(ppufile:tcompilerppufile);
procedure deref;override;
procedure insert_in_data;virtual;
{$ifdef GDB}
function stabstring : pchar;virtual;
procedure concatstabto(asmlist : taasmoutput);virtual;
@ -180,10 +179,9 @@ interface
procedure deref;override;
procedure generate_mangledname;override;
procedure set_mangledname(const s:string);
procedure insert_in_data;override;
function getsize : longint;
function getvaluesize : longint;
function getpushsize : longint;
function getpushsize(is_cdecl:boolean): longint;
{$ifdef GDB}
function stabstring : pchar;override;
procedure concatstabto(asmlist : taasmoutput);override;
@ -223,7 +221,6 @@ interface
destructor destroy;override;
procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure deref;override;
procedure insert_in_data;override;
{$ifdef GDB}
procedure concatstabto(asmlist : taasmoutput);override;
{$endif GDB}
@ -239,7 +236,6 @@ interface
procedure deref;override;
function mangledname : string;
procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure insert_in_data;override;
{$ifdef GDB}
procedure concatstabto(asmlist : taasmoutput);override;
{$endif GDB}
@ -256,7 +252,6 @@ interface
procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure deref;override;
function getsize:longint;
procedure insert_in_data;override;
{$ifdef GDB}
function stabstring : pchar;override;
{$endif GDB}
@ -537,12 +532,6 @@ implementation
end;
{ for most symbol types there is nothing to do at all }
procedure tstoredsym.insert_in_data;
begin
end;
{$ifdef GDB}
function tstoredsym.stabstring : pchar;
@ -1366,30 +1355,6 @@ implementation
end;
{$endif GDB}
procedure tfuncretsym.insert_in_data;
var
varalign,l : longint;
begin
{ if retoffset is already set then reuse it, this is needed
when inserting the result variable }
if procinfo.return_offset<>0 then
address:=procinfo.return_offset
else
begin
{ allocate space in local if ret in register }
if paramanager.ret_in_reg(returntype.def) then
begin
l:=returntype.def.size;
varalign:=size_2_align(l);
varalign:=used_align(varalign,aktalignment.localalignmin,owner.dataalignment);
address:=align(owner.datasize+l,varalign);
owner.datasize:=address;
procinfo.return_offset:=-address;
end;
end;
end;
{****************************************************************************
TABSOLUTESYM
****************************************************************************}
@ -1498,11 +1463,6 @@ implementation
end;
procedure tabsolutesym.insert_in_data;
begin
end;
{$ifdef GDB}
procedure tabsolutesym.concatstabto(asmlist : taasmoutput);
begin
@ -1639,8 +1599,9 @@ implementation
end;
function tvarsym.getpushsize : longint;
function tvarsym.getpushsize(is_cdecl:boolean) : longint;
begin
getpushsize:=-1;
if assigned(vartype.def) then
begin
case varspez of
@ -1650,205 +1611,21 @@ implementation
vs_value,
vs_const :
begin
if paramanager.push_addr_param(vartype.def) then
if paramanager.push_addr_param(vartype.def,is_cdecl) then
getpushsize:=pointer_size
else
getpushsize:=vartype.def.size;
end;
end;
end
else
getpushsize:=0;
end;
end;
procedure tvarsym.insert_in_data;
var
varalign,
l,modulo : longint;
storefilepos : tfileposinfo;
begin
if (vo_is_external in varoptions) then
exit;
{ handle static variables of objects especially }
if read_member and (owner.symtabletype=objectsymtable) and
(sp_static in symoptions) then
begin
{ the data filed is generated in parser.pas
with a tobject_FIELDNAME variable }
{ this symbol can't be loaded to a register }
exclude(varoptions,vo_regable);
exclude(varoptions,vo_fpuregable);
end
else
if not(read_member) then
begin
{ made problems with parameters etc. ! (FK) }
{ check for instance of an abstract object or class }
{
if (tvarsym(sym).definition.deftype=objectdef) and
((tobjectdef(tvarsym(sym).definition).options and oo_is_abstract)<>0) then
Message(sym_e_no_instance_of_abstract_object);
}
storefilepos:=aktfilepos;
aktfilepos:=akttokenpos;
if (vo_is_thread_var in varoptions) then
l:=pointer_size
else
l:=getvaluesize;
case owner.symtabletype of
stt_exceptsymtable:
{ can contain only one symbol, address calculated later }
;
localsymtable :
begin
varstate:=vs_declared;
varalign:=size_2_align(l);
varalign:=used_align(varalign,aktalignment.localalignmin,aktalignment.localalignmax);
{$ifdef powerpc}
{ on the powerpc, the local variables are accessed with a positiv offset }
address:=align(owner.datasize,varalign);
owner.datasize:=address+l;
{$else powerpc}
address:=align(owner.datasize+l,varalign);
owner.datasize:=address;
{$endif powerpc}
end;
staticsymtable :
begin
{ enable unitialized warning for local symbols }
varstate:=vs_declared;
varalign:=size_2_align(l);
varalign:=used_align(varalign,aktalignment.varalignmin,aktalignment.varalignmax);
address:=align(owner.datasize,varalign);
{ insert cut for smartlinking or alignment }
if (cs_create_smart in aktmoduleswitches) then
bssSegment.concat(Tai_cut.Create)
else if (address<>owner.datasize) then
bssSegment.concat(Tai_align.create(varalign));
owner.datasize:=address+l;
{$ifdef GDB}
if cs_debuginfo in aktmoduleswitches then
concatstabto(bsssegment);
{$endif GDB}
if (cs_create_smart in aktmoduleswitches) or
DLLSource or
(vo_is_exported in varoptions) or
(vo_is_C_var in varoptions) then
bssSegment.concat(Tai_datablock.Create_global(mangledname,l))
else
bssSegment.concat(Tai_datablock.Create(mangledname,l));
{Global variables (in implementation part of course)
*can* be loaded into registers, they just may not be
accessed from procedures. The lexlevel test in nld.pas,
Tloadnode.pass_1, should take care of this.
If for some reason you think it isn't safe, try isolating
and disabling those specific cases, because small programs
without procedures can be very speed critical. For example,
think of benchmarks and programming contests. Also, new
users often test the quality of the code the compiler
generates and they do that with small programs, we should
show them the full optimizing power. (DM)}
{exclude(varoptions,vo_regable);
exclude(varoptions,vo_fpuregable);}
end;
globalsymtable :
begin
varalign:=size_2_align(l);
varalign:=used_align(varalign,aktalignment.varalignmin,aktalignment.varalignmax);
address:=align(owner.datasize,varalign);
{ insert cut for smartlinking or alignment }
if (cs_create_smart in aktmoduleswitches) then
bssSegment.concat(Tai_cut.Create)
else if (address<>owner.datasize) then
bssSegment.concat(Tai_align.create(varalign));
owner.datasize:=address+l;
{$ifdef GDB}
if cs_debuginfo in aktmoduleswitches then
concatstabto(bsssegment);
{$endif GDB}
bssSegment.concat(Tai_datablock.Create_global(mangledname,l));
{ this symbol can't be loaded to a register }
exclude(varoptions,vo_regable);
exclude(varoptions,vo_fpuregable);
end;
recordsymtable,
objectsymtable :
begin
{ this symbol can't be loaded to a register }
exclude(varoptions,vo_regable);
exclude(varoptions,vo_fpuregable);
{ get the alignment size }
if (aktalignment.recordalignmax=-1) then
begin
varalign:=vartype.def.alignment;
if (varalign>4) and ((varalign mod 4)<>0) and
(vartype.def.deftype=arraydef) then
begin
Message1(sym_w_wrong_C_pack,vartype.def.typename);
end;
if varalign=0 then
varalign:=l;
if (owner.dataalignment<aktalignment.maxCrecordalign) then
begin
if (varalign>16) and (owner.dataalignment<32) then
owner.dataalignment:=32
else if (varalign>12) and (owner.dataalignment<16) then
owner.dataalignment:=16
{ 12 is needed for long double }
else if (varalign>8) and (owner.dataalignment<12) then
owner.dataalignment:=12
else if (varalign>4) and (owner.dataalignment<8) then
owner.dataalignment:=8
else if (varalign>2) and (owner.dataalignment<4) then
owner.dataalignment:=4
else if (varalign>1) and (owner.dataalignment<2) then
owner.dataalignment:=2;
end;
owner.dataalignment:=max(owner.dataalignment,aktalignment.maxCrecordalign);
end
else
varalign:=vartype.def.alignment;
if varalign=0 then
varalign:=size_2_align(l);
varalign:=used_align(varalign,aktalignment.recordalignmin,owner.dataalignment);
address:=align(owner.datasize,varalign);
owner.datasize:=address+l;
end;
parasymtable :
begin
{ here we need the size of a push instead of the
size of the data }
l:=getpushsize;
varalign:=size_2_align(l);
varstate:=vs_assigned;
{ we need the new datasize already aligned so we can't
use the align_address here }
address:=owner.datasize;
varalign:=used_align(varalign,owner.dataalignment,owner.dataalignment);
owner.datasize:=align(address+l,varalign);
end
else
begin
modulo:=owner.datasize and 3;
if (l>=4) and (modulo<>0) then
inc(owner.datasize,4-modulo)
else
if (l>=2) and ((modulo and 1)<>0) then
inc(owner.datasize);
address:=owner.datasize;
inc(owner.datasize,l);
end;
end;
aktfilepos:=storefilepos;
end;
end;
{$ifdef GDB}
function tvarsym.stabstring : pchar;
var
st : string;
is_cdecl : boolean;
begin
st:=tstoreddef(vartype.def).numberstring;
if (owner.symtabletype = objectsymtable) and
@ -1876,11 +1653,12 @@ implementation
end
else if (owner.symtabletype in [parasymtable,inlineparasymtable]) then
begin
is_cdecl:=(tprocdef(owner.defowner).proccalloption in [pocall_cdecl,pocall_cppdecl]);
case varspez of
vs_out,
vs_var : st := 'v'+st;
vs_value,
vs_const : if paramanager.push_addr_param(vartype.def) then
vs_const : if paramanager.push_addr_param(vartype.def,is_cdecl) then
st := 'v'+st { should be 'i' but 'i' doesn't work }
else
st := 'p'+st;
@ -1998,48 +1776,6 @@ implementation
end;
procedure ttypedconstsym.insert_in_data;
var
curconstsegment : taasmoutput;
address,l,varalign : longint;
storefilepos : tfileposinfo;
begin
storefilepos:=aktfilepos;
aktfilepos:=akttokenpos;
if is_writable then
curconstsegment:=datasegment
else
curconstsegment:=consts;
l:=getsize;
varalign:=size_2_align(l);
varalign:=used_align(varalign,aktalignment.constalignmin,aktalignment.constalignmax);
address:=align(owner.datasize,varalign);
{ insert cut for smartlinking or alignment }
if (cs_create_smart in aktmoduleswitches) then
curconstSegment.concat(Tai_cut.Create)
else if (address<>owner.datasize) then
curconstSegment.concat(Tai_align.create(varalign));
owner.datasize:=address+l;
{$ifdef GDB}
if cs_debuginfo in aktmoduleswitches then
concatstabto(curconstsegment);
{$endif GDB}
if (owner.symtabletype=globalsymtable) then
begin
if (owner.unitid=0) then
curconstSegment.concat(Tai_symbol.Createdataname_global(mangledname,getsize));
end
else
begin
if (cs_create_smart in aktmoduleswitches) or
DLLSource then
curconstSegment.concat(Tai_symbol.Createdataname_global(mangledname,getsize))
else
curconstSegment.concat(Tai_symbol.Createdataname(mangledname,getsize));
end;
aktfilepos:=storefilepos;
end;
{$ifdef GDB}
function ttypedconstsym.stabstring : pchar;
var
@ -2679,7 +2415,17 @@ implementation
end.
{
$Log$
Revision 1.56 2002-08-25 09:06:21 peter
Revision 1.57 2002-08-25 19:25:21 peter
* sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be
called separatly. This allows to deref the address calculation
* procedures now calculate the parast addresses after the procedure
directives are parsed. This fixes the cdecl parast problem
* push_addr_param has an extra argument that specifies if cdecl is used
or not
Revision 1.56 2002/08/25 09:06:21 peter
* fixed loop in concat_procdefs
Revision 1.55 2002/08/20 16:54:40 peter

View File

@ -29,13 +29,15 @@ interface
{ common }
cutils,cclasses,
{ global }
globtype,tokens,
cpuinfo,globtype,tokens,
{ symtable }
symconst,symbase,symtype,symdef,symsym,
{ ppu }
ppu,symppu,
{ assembler }
aasmbase,aasmtai
aasmbase,aasmtai,aasmcpu,
{ cg }
paramgr
;
@ -96,6 +98,7 @@ interface
procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure load_references(ppufile:tcompilerppufile;locals:boolean);override;
procedure write_references(ppufile:tcompilerppufile;locals:boolean);override;
procedure insertvardata(sym : tsymentry);override;
end;
trecordsymtable = class(tabstractrecordsymtable)
@ -122,14 +125,15 @@ interface
public
constructor create;
procedure insert(sym : tsymentry);override;
procedure insertvardata(sym : tsymentry);override;
procedure insertconstdata(sym : tsymentry);override;
end;
tparasymtable = class(tabstractlocalsymtable)
public
constructor create;
procedure insert(sym : tsymentry);override;
{ change alignment for args only parasymtable }
procedure set_alignment(_alignment : longint);
procedure insertvardata(sym : tsymentry);override;
end;
tabstractunitsymtable = class(tstoredsymtable)
@ -144,6 +148,8 @@ interface
{$ifdef GDB}
procedure concattypestabto(asmlist : taasmoutput);
{$endif GDB}
procedure insertvardata(sym : tsymentry);override;
procedure insertconstdata(sym : tsymentry);override;
end;
tglobalsymtable = class(tabstractunitsymtable)
@ -155,6 +161,7 @@ interface
procedure ppuload(ppufile:tcompilerppufile);override;
procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure insert(sym : tsymentry);override;
procedure insertvardata(sym : tsymentry);override;
{$ifdef GDB}
function getnewtypecount : word; override;
{$endif}
@ -168,6 +175,7 @@ interface
procedure load_references(ppufile:tcompilerppufile;locals:boolean);override;
procedure write_references(ppufile:tcompilerppufile;locals:boolean);override;
procedure insert(sym : tsymentry);override;
procedure insertvardata(sym : tsymentry);override;
end;
twithsymtable = class(tsymtable)
@ -281,10 +289,6 @@ implementation
;
var
in_loading : boolean; { remove !!! }
{*****************************************************************************
TStoredSymtable
*****************************************************************************}
@ -541,10 +545,6 @@ implementation
begin
{ set owner and sym indexnb }
sym.owner:=self;
{ writes the symbol in data segment if required }
{ also sets the datasize of owner }
if not in_loading then
tstoredsym(sym).insert_in_data;
{ check the current symtable }
hsym:=tsym(search(sym.name));
@ -830,7 +830,6 @@ implementation
procedure tstoredsymtable.chainoperators;
var
pd : pprocdeflist;
t : ttoken;
srsym : tsym;
srsymtable,
@ -931,6 +930,17 @@ implementation
{$endif}
procedure TStoredSymtable._needs_init_final(p : tnamedindexitem;arg:pointer);
begin
if (not b_needs_init_final) and
(tsym(p).typ=varsym) and
assigned(tvarsym(p).vartype.def) and
not is_class(tvarsym(p).vartype.def) and
tstoreddef(tvarsym(p).vartype.def).needs_inittable then
b_needs_init_final:=true;
end;
{ returns true, if p contains data which needs init/final code }
function tstoredsymtable.needs_init_final : boolean;
begin
@ -1000,14 +1010,53 @@ implementation
end;
procedure TStoredSymtable._needs_init_final(p : tnamedindexitem;arg:pointer);
procedure tabstractrecordsymtable.insertvardata(sym : tsymentry);
var
l,varalign : longint;
vardef : tdef;
begin
if (not b_needs_init_final) and
(tsym(p).typ=varsym) and
assigned(tvarsym(p).vartype.def) and
not is_class(tvarsym(p).vartype.def) and
tstoreddef(tvarsym(p).vartype.def).needs_inittable then
b_needs_init_final:=true;
if sym.typ<>varsym then
internalerror(200208251);
l:=tvarsym(sym).getvaluesize;
vardef:=tvarsym(sym).vartype.def;
{ this symbol can't be loaded to a register }
exclude(tvarsym(sym).varoptions,vo_regable);
exclude(tvarsym(sym).varoptions,vo_fpuregable);
{ get the alignment size }
if (aktalignment.recordalignmax=-1) then
begin
varalign:=vardef.alignment;
if (varalign>4) and
((varalign mod 4)<>0) and
(vardef.deftype=arraydef) then
Message1(sym_w_wrong_C_pack,vardef.typename);
if varalign=0 then
varalign:=l;
if (dataalignment<aktalignment.maxCrecordalign) then
begin
if (varalign>16) and (dataalignment<32) then
dataalignment:=32
else if (varalign>12) and (dataalignment<16) then
dataalignment:=16
{ 12 is needed for long double }
else if (varalign>8) and (dataalignment<12) then
dataalignment:=12
else if (varalign>4) and (dataalignment<8) then
dataalignment:=8
else if (varalign>2) and (dataalignment<4) then
dataalignment:=4
else if (varalign>1) and (dataalignment<2) then
dataalignment:=2;
end;
dataalignment:=max(dataalignment,aktalignment.maxCrecordalign);
end
else
varalign:=vardef.alignment;
if varalign=0 then
varalign:=size_2_align(l);
varalign:=used_align(varalign,aktalignment.recordalignmin,dataalignment);
tvarsym(sym).address:=align(datasize,varalign);
datasize:=tvarsym(sym).address+l;
end;
@ -1233,6 +1282,96 @@ implementation
end;
procedure tlocalsymtable.insertvardata(sym : tsymentry);
var
l,varalign : longint;
begin
if not(sym.typ in [varsym,funcretsym]) then
internalerror(200208255);
case sym.typ of
varsym :
begin
tvarsym(sym).varstate:=vs_declared;
l:=tvarsym(sym).getvaluesize;
varalign:=size_2_align(l);
varalign:=used_align(varalign,aktalignment.localalignmin,aktalignment.localalignmax);
{$ifdef powerpc}
{ on the powerpc, the local variables are accessed with a positiv offset }
tvarsym(sym).address:=align(datasize,varalign);
datasize:=tvarsym(sym).address+l;
{$else powerpc}
tvarsym(sym).address:=align(datasize+l,varalign);
datasize:=tvarsym(sym).address;
{$endif powerpc}
end;
funcretsym :
begin
{ if retoffset is already set then reuse it, this is needed
when inserting the result variable }
if procinfo.return_offset<>0 then
tfuncretsym(sym).address:=procinfo.return_offset
else
begin
{ allocate space in local if ret in register }
if paramanager.ret_in_reg(tfuncretsym(sym).returntype.def) then
begin
l:=tfuncretsym(sym).returntype.def.size;
varalign:=size_2_align(l);
varalign:=used_align(varalign,aktalignment.localalignmin,dataalignment);
tfuncretsym(sym).address:=align(datasize+l,varalign);
datasize:=tfuncretsym(sym).address;
procinfo.return_offset:=-tfuncretsym(sym).address;
end;
end;
end;
end;
end;
procedure tlocalsymtable.insertconstdata(sym : tsymentry);
var
storefilepos : tfileposinfo;
curconstsegment : taasmoutput;
address,l,varalign : longint;
begin
{ Note: this is the same code as tabstractunitsymtable.insertconstdata }
if sym.typ<>typedconstsym then
internalerror(200208254);
storefilepos:=aktfilepos;
aktfilepos:=tsym(sym).fileinfo;
if ttypedconstsym(sym).is_writable then
curconstsegment:=datasegment
else
curconstsegment:=consts;
l:=ttypedconstsym(sym).getsize;
varalign:=size_2_align(l);
varalign:=used_align(varalign,aktalignment.constalignmin,aktalignment.constalignmax);
address:=align(datasize,varalign);
{ insert cut for smartlinking or alignment }
if (cs_create_smart in aktmoduleswitches) then
curconstSegment.concat(Tai_cut.Create)
else if (address<>datasize) then
curconstSegment.concat(Tai_align.create(varalign));
datasize:=address+l;
{$ifdef GDB}
if cs_debuginfo in aktmoduleswitches then
concatstabto(curconstsegment);
{$endif GDB}
if (cs_create_smart in aktmoduleswitches) or
DLLSource then
begin
curconstSegment.concat(Tai_symbol.Createdataname_global(
ttypedconstsym(sym).mangledname,ttypedconstsym(sym).getsize));
end
else
begin
curconstSegment.concat(Tai_symbol.Createdataname(
ttypedconstsym(sym).mangledname,ttypedconstsym(sym).getsize));
end;
aktfilepos:=storefilepos;
end;
{****************************************************************************
TParaSymtable
****************************************************************************}
@ -1279,31 +1418,30 @@ implementation
end;
procedure tparasymtable.set_alignment(_alignment : longint);
procedure tparasymtable.insertvardata(sym : tsymentry);
var
sym : tvarsym;
l : longint;
l,varalign : longint;
is_cdecl : boolean;
begin
dataalignment:=_alignment;
sym:=tvarsym(symindex.first);
datasize:=0;
{ there can be only varsyms }
{ no, default parameters }
{ lead to constsyms as well (FK) }
while assigned(sym) do
begin
if sym.typ=varsym then
begin
l:=sym.getpushsize;
sym.address:=datasize;
datasize:=align(datasize+l,dataalignment);
end;
sym:=tvarsym(sym.indexnext);
end;
if sym.typ<>varsym then
internalerror(200208253);
{ retrieve cdecl status }
if defowner.deftype<>procdef then
internalerror(200208256);
is_cdecl:=(tprocdef(defowner).proccalloption in [pocall_cdecl,pocall_cppdecl]);
{ here we need the size of a push instead of the
size of the data }
l:=tvarsym(sym).getpushsize(is_cdecl);
varalign:=size_2_align(l);
tvarsym(sym).varstate:=vs_assigned;
{ we need the new datasize already aligned so we can't
use the align_address here }
tvarsym(sym).address:=datasize;
varalign:=used_align(varalign,dataalignment,dataalignment);
datasize:=align(tvarsym(sym).address+l,varalign);
end;
{****************************************************************************
TAbstractUnitSymtable
****************************************************************************}
@ -1322,6 +1460,88 @@ implementation
end;
procedure tabstractunitsymtable.insertvardata(sym : tsymentry);
var
l,varalign : longint;
storefilepos : tfileposinfo;
begin
if sym.typ<>varsym then
internalerror(200208252);
storefilepos:=aktfilepos;
aktfilepos:=tsym(sym).fileinfo;
if (vo_is_thread_var in tvarsym(sym).varoptions) then
l:=pointer_size
else
l:=tvarsym(sym).getvaluesize;
varalign:=size_2_align(l);
varalign:=used_align(varalign,aktalignment.varalignmin,aktalignment.varalignmax);
tvarsym(sym).address:=align(datasize,varalign);
{ insert cut for smartlinking or alignment }
if (cs_create_smart in aktmoduleswitches) then
bssSegment.concat(Tai_cut.Create)
else if (tvarsym(sym).address<>datasize) then
bssSegment.concat(Tai_align.create(varalign));
datasize:=tvarsym(sym).address+l;
{$ifdef GDB}
if cs_debuginfo in aktmoduleswitches then
concatstabto(bsssegment);
{$endif GDB}
if (symtabletype=globalsymtable) or
(cs_create_smart in aktmoduleswitches) or
DLLSource or
(vo_is_exported in tvarsym(sym).varoptions) or
(vo_is_C_var in tvarsym(sym).varoptions) then
bssSegment.concat(Tai_datablock.Create_global(tvarsym(sym).mangledname,l))
else
bssSegment.concat(Tai_datablock.Create(tvarsym(sym).mangledname,l));
aktfilepos:=storefilepos;
end;
procedure tabstractunitsymtable.insertconstdata(sym : tsymentry);
var
storefilepos : tfileposinfo;
curconstsegment : taasmoutput;
address,l,varalign : longint;
begin
if sym.typ<>typedconstsym then
internalerror(200208254);
storefilepos:=aktfilepos;
aktfilepos:=tsym(sym).fileinfo;
if ttypedconstsym(sym).is_writable then
curconstsegment:=datasegment
else
curconstsegment:=consts;
l:=ttypedconstsym(sym).getsize;
varalign:=size_2_align(l);
varalign:=used_align(varalign,aktalignment.constalignmin,aktalignment.constalignmax);
address:=align(datasize,varalign);
{ insert cut for smartlinking or alignment }
if (cs_create_smart in aktmoduleswitches) then
curconstSegment.concat(Tai_cut.Create)
else if (address<>datasize) then
curconstSegment.concat(Tai_align.create(varalign));
datasize:=address+l;
{$ifdef GDB}
if cs_debuginfo in aktmoduleswitches then
concatstabto(curconstsegment);
{$endif GDB}
if (symtabletype=globalsymtable) or
(cs_create_smart in aktmoduleswitches) or
DLLSource then
begin
curconstSegment.concat(Tai_symbol.Createdataname_global(
ttypedconstsym(sym).mangledname,ttypedconstsym(sym).getsize));
end
else
begin
curconstSegment.concat(Tai_symbol.Createdataname(
ttypedconstsym(sym).mangledname,ttypedconstsym(sym).getsize));
end;
aktfilepos:=storefilepos;
end;
{$ifdef GDB}
procedure tabstractunitsymtable.concattypestabto(asmlist : taasmoutput);
var prev_dbx_count : plongint;
@ -1451,6 +1671,15 @@ implementation
end;
procedure tstaticsymtable.insertvardata(sym : tsymentry);
begin
inherited insertvardata(sym);
{ enable unitialized warning for local symbols }
if sym.typ=varsym then
tvarsym(sym).varstate:=vs_declared;
end;
{****************************************************************************
TGlobalSymtable
****************************************************************************}
@ -1587,6 +1816,18 @@ implementation
end;
procedure tglobalsymtable.insertvardata(sym : tsymentry);
begin
inherited insertvardata(sym);
{ this symbol can't be loaded to a register }
if sym.typ=varsym then
begin
exclude(tvarsym(sym).varoptions,vo_regable);
exclude(tvarsym(sym).varoptions,vo_fpuregable);
end;
end;
{$ifdef GDB}
function tglobalsymtable.getnewtypecount : word;
begin
@ -2058,7 +2299,17 @@ implementation
end.
{
$Log$
Revision 1.68 2002-08-18 20:06:27 peter
Revision 1.69 2002-08-25 19:25:21 peter
* sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be
called separatly. This allows to deref the address calculation
* procedures now calculate the parast addresses after the procedure
directives are parsed. This fixes the cdecl parast problem
* push_addr_param has an extra argument that specifies if cdecl is used
or not
Revision 1.68 2002/08/18 20:06:27 peter
* inlining is now also allowed in interface
* renamed write/load to ppuwrite/ppuload
* tnode storing in ppu