* C record packing fixed to also check first entry of the record

if bigger than the recordalignment itself
  * variant record alignment uses alignment per variant and saves the
    highest alignment value
This commit is contained in:
peter 2000-06-18 18:11:32 +00:00
parent 9fc6896bf9
commit d55672bd95
6 changed files with 111 additions and 32 deletions

View File

@ -326,7 +326,7 @@ unit pdecl;
pconstsym : ptypedconstsym; pconstsym : ptypedconstsym;
{ maxsize contains the max. size of a variant } { maxsize contains the max. size of a variant }
{ startvarrec contains the start of the variant part of a record } { startvarrec contains the start of the variant part of a record }
maxsize,startvarrec : longint; maxsize,maxalignment,startvarrecalign,startvarrecsize : longint;
pt : ptree; pt : ptree;
begin begin
old_block_type:=block_type; old_block_type:=block_type;
@ -649,6 +649,7 @@ unit pdecl;
if is_record and (token=_CASE) then if is_record and (token=_CASE) then
begin begin
maxsize:=0; maxsize:=0;
maxalignment:=0;
consume(_CASE); consume(_CASE);
s:=pattern; s:=pattern;
getsym(s,false); getsym(s,false);
@ -665,7 +666,8 @@ unit pdecl;
if not(is_ordinal(casetype.def)) or is_64bitint(casetype.def) then if not(is_ordinal(casetype.def)) or is_64bitint(casetype.def) then
Message(type_e_ordinal_expr_expected); Message(type_e_ordinal_expr_expected);
consume(_OF); consume(_OF);
startvarrec:=symtablestack^.datasize; startvarrecsize:=symtablestack^.datasize;
startvarrecalign:=symtablestack^.dataalignment;
repeat repeat
repeat repeat
pt:=comp_expr(true); pt:=comp_expr(true);
@ -688,8 +690,10 @@ unit pdecl;
consume(_RKLAMMER); consume(_RKLAMMER);
{ calculates maximal variant size } { calculates maximal variant size }
maxsize:=max(maxsize,symtablestack^.datasize); maxsize:=max(maxsize,symtablestack^.datasize);
maxalignment:=max(maxalignment,symtablestack^.dataalignment);
{ the items of the next variant are overlayed } { the items of the next variant are overlayed }
symtablestack^.datasize:=startvarrec; symtablestack^.datasize:=startvarrecsize;
symtablestack^.dataalignment:=startvarrecalign;
if (token<>_END) and (token<>_RKLAMMER) then if (token<>_END) and (token<>_RKLAMMER) then
consume(_SEMICOLON) consume(_SEMICOLON)
else else
@ -697,6 +701,7 @@ unit pdecl;
until (token=_END) or (token=_RKLAMMER); until (token=_END) or (token=_RKLAMMER);
{ at last set the record size to that of the biggest variant } { at last set the record size to that of the biggest variant }
symtablestack^.datasize:=maxsize; symtablestack^.datasize:=maxsize;
symtablestack^.dataalignment:=maxalignment;
end; end;
block_type:=old_block_type; block_type:=old_block_type;
end; end;
@ -1208,7 +1213,13 @@ unit pdecl;
end. end.
{ {
$Log$ $Log$
Revision 1.185 2000-06-11 06:59:36 peter Revision 1.186 2000-06-18 18:11:32 peter
* C record packing fixed to also check first entry of the record
if bigger than the recordalignment itself
* variant record alignment uses alignment per variant and saves the
highest alignment value
Revision 1.185 2000/06/11 06:59:36 peter
* support procvar directive without ; before the directives * support procvar directive without ; before the directives
Revision 1.184 2000/06/09 21:34:40 peter Revision 1.184 2000/06/09 21:34:40 peter

View File

@ -114,7 +114,8 @@ type
po_exports, { Procedure has export directive (needed for OS/2) } po_exports, { Procedure has export directive (needed for OS/2) }
po_external, { Procedure is external (in other object or lib)} po_external, { Procedure is external (in other object or lib)}
po_savestdregs, { save std regs cdecl and stdcall need that ! } po_savestdregs, { save std regs cdecl and stdcall need that ! }
po_saveregisters { save all registers } po_saveregisters, { save all registers }
po_overload { procedure is declared with overload directive }
); );
tprocoptions=set of tprocoption; tprocoptions=set of tprocoption;
@ -214,7 +215,13 @@ implementation
end. end.
{ {
$Log$ $Log$
Revision 1.12 2000-06-02 21:15:49 pierre Revision 1.13 2000-06-18 18:11:32 peter
* C record packing fixed to also check first entry of the record
if bigger than the recordalignment itself
* variant record alignment uses alignment per variant and saves the
highest alignment value
Revision 1.12 2000/06/02 21:15:49 pierre
+ vo_is_exported for bug0317 fix + vo_is_exported for bug0317 fix
Revision 1.11 2000/03/19 14:56:38 florian Revision 1.11 2000/03/19 14:56:38 florian

View File

@ -2112,8 +2112,33 @@
function trecorddef.alignment:longint; function trecorddef.alignment:longint;
var
l : longint;
hp : pvarsym;
begin begin
alignment:=symtable^.dataalignment; { also check the first symbol for it's size, because a
packed record has dataalignment of 1, but the first
sym could be a longint which should be aligned on 4 bytes,
this is compatible with C record packing (PFV) }
hp:=pvarsym(symtable^.symindex^.first);
if assigned(hp) then
begin
l:=hp^.vartype.def^.size;
if l>symtable^.dataalignment then
begin
if l>=4 then
alignment:=4
else
if l>=2 then
alignment:=2
else
alignment:=1;
end
else
alignment:=symtable^.dataalignment;
end
else
alignment:=symtable^.dataalignment;
end; end;
{$ifdef GDB} {$ifdef GDB}
@ -4061,7 +4086,13 @@ Const local_symtable_index : longint = $8001;
{ {
$Log$ $Log$
Revision 1.200 2000-06-02 18:48:47 florian Revision 1.201 2000-06-18 18:11:32 peter
* C record packing fixed to also check first entry of the record
if bigger than the recordalignment itself
* variant record alignment uses alignment per variant and saves the
highest alignment value
Revision 1.200 2000/06/02 18:48:47 florian
+ fieldtable support for classes + fieldtable support for classes
Revision 1.199 2000/04/01 14:17:08 peter Revision 1.199 2000/04/01 14:17:08 peter

View File

@ -1322,16 +1322,19 @@
if (aktpackrecords=packrecord_C) then if (aktpackrecords=packrecord_C) then
begin begin
varalign:=vartype.def^.alignment; varalign:=vartype.def^.alignment;
if varalign=0 then if (owner^.dataalignment<4) then
begin begin
if (owner^.dataalignment<4) then if varalign=0 then
begin begin
if (l>=4) then if (l>=4) then
owner^.dataalignment:=4 owner^.dataalignment:=4
else else
if (owner^.dataalignment<2) and (l>=2) then if (owner^.dataalignment<2) and (l>=2) then
owner^.dataalignment:=2; owner^.dataalignment:=2;
end; end
else
if varalign>owner^.dataalignment then
owner^.dataalignment:=varalign;
end; end;
end end
else else
@ -2163,7 +2166,13 @@
{ {
$Log$ $Log$
Revision 1.148 2000-06-02 21:16:42 pierre Revision 1.149 2000-06-18 18:11:32 peter
* C record packing fixed to also check first entry of the record
if bigger than the recordalignment itself
* variant record alignment uses alignment per variant and saves the
highest alignment value
Revision 1.148 2000/06/02 21:16:42 pierre
* vo_is_exported needs init_global also * vo_is_exported needs init_global also
Revision 1.147 2000/06/01 19:09:56 peter Revision 1.147 2000/06/01 19:09:56 peter

View File

@ -319,7 +319,13 @@
{ {
$Log$ $Log$
Revision 1.50 2000-05-18 17:05:17 peter Revision 1.51 2000-06-18 18:11:32 peter
* C record packing fixed to also check first entry of the record
if bigger than the recordalignment itself
* variant record alignment uses alignment per variant and saves the
highest alignment value
Revision 1.50 2000/05/18 17:05:17 peter
* fixed size of const parameters in asm readers * fixed size of const parameters in asm readers
Revision 1.49 2000/05/03 14:34:05 pierre Revision 1.49 2000/05/03 14:34:05 pierre

View File

@ -179,7 +179,7 @@ unit symtable;
next : psymtable; next : psymtable;
defowner : pdef; { for records and objects } defowner : pdef; { for records and objects }
{ alignment used in this symtable } { alignment used in this symtable }
alignment : longint; { alignment : longint; }
{ only used for parameter symtable to determine the offset relative } { only used for parameter symtable to determine the offset relative }
{ to the frame pointer and for local inline } { to the frame pointer and for local inline }
address_fixup : longint; address_fixup : longint;
@ -212,7 +212,7 @@ unit symtable;
procedure check_forwards; procedure check_forwards;
procedure checklabels; procedure checklabels;
{ change alignment for args only parasymtable } { change alignment for args only parasymtable }
procedure set_alignment(_alignment : byte); procedure set_alignment(_alignment : longint);
{ find arg having offset only parasymtable } { find arg having offset only parasymtable }
function find_at_offset(l : longint) : pvarsym; function find_at_offset(l : longint) : pvarsym;
{$ifdef CHAINPROCSYMS} {$ifdef CHAINPROCSYMS}
@ -1414,7 +1414,10 @@ implementation
name:=nil; name:=nil;
address_fixup:=0; address_fixup:=0;
datasize:=0; datasize:=0;
dataalignment:=1; if t=parasymtable then
dataalignment:=4
else
dataalignment:=1;
new(symindex,init(indexgrowsize)); new(symindex,init(indexgrowsize));
new(defindex,init(indexgrowsize)); new(defindex,init(indexgrowsize));
if symtabletype<>withsymtable then if symtabletype<>withsymtable then
@ -1424,7 +1427,6 @@ implementation
end end
else else
symsearch:=nil; symsearch:=nil;
alignment:=def_alignment;
end; end;
@ -1660,7 +1662,10 @@ implementation
{ reset } { reset }
defowner:=nil; defowner:=nil;
name:=nil; name:=nil;
alignment:=def_alignment; if typ=parasymtable then
dataalignment:=4
else
dataalignment:=1;
datasize:=0; datasize:=0;
address_fixup:= 0; address_fixup:= 0;
unitid:=0; unitid:=0;
@ -1854,9 +1859,12 @@ implementation
begin begin
{ in TP and Delphi you can have a local with the { in TP and Delphi you can have a local with the
same name as the function, the function is then hidden for same name as the function, the function is then hidden for
the user. (Under delphi it can still be accessed using result) (PFV) } the user. (Under delphi it can still be accessed using result),
if (hsym^.typ=funcretsym) and but don't allow hiding of RESULT }
(m_tp in aktmodeswitches) then if (m_tp in aktmodeswitches) and
(hsym^.typ=funcretsym) and
not((m_result in aktmodeswitches) and
(hsym^.name='RESULT')) then
hsym^.owner^.rename(hsym^.name,'hidden'+hsym^.name) hsym^.owner^.rename(hsym^.name,'hidden'+hsym^.name)
else else
begin begin
@ -1875,8 +1883,11 @@ implementation
if assigned(hsym) then if assigned(hsym) then
begin begin
{ a parameter and the function can have the same { a parameter and the function can have the same
name in TP and Delphi } name in TP and Delphi, but RESULT not }
if (sym^.typ=funcretsym) then if (m_tp in aktmodeswitches) and
(sym^.typ=funcretsym) and
not((m_result in aktmodeswitches) and
(sym^.name='RESULT')) then
sym^.setname('hidden'+sym^.name) sym^.setname('hidden'+sym^.name)
else else
begin begin
@ -2174,14 +2185,12 @@ implementation
foreach({$ifndef TP}@{$endif}labeldefined); foreach({$ifndef TP}@{$endif}labeldefined);
end; end;
procedure tsymtable.set_alignment(_alignment : byte); procedure tsymtable.set_alignment(_alignment : longint);
var var
sym : pvarsym; sym : pvarsym;
l : longint; l : longint;
begin begin
{ this can not be done if there is an dataalignment:=_alignment;
hasharray ! }
alignment:=_alignment;
if (symtabletype<>parasymtable) then if (symtabletype<>parasymtable) then
internalerror(1111); internalerror(1111);
sym:=pvarsym(symindex^.first); sym:=pvarsym(symindex^.first);
@ -2191,7 +2200,7 @@ implementation
begin begin
l:=sym^.getpushsize; l:=sym^.getpushsize;
sym^.address:=datasize; sym^.address:=datasize;
datasize:=align(datasize+l,alignment); datasize:=align(datasize+l,dataalignment);
sym:=pvarsym(sym^.next); sym:=pvarsym(sym^.next);
end; end;
end; end;
@ -2925,7 +2934,13 @@ implementation
end. end.
{ {
$Log$ $Log$
Revision 1.99 2000-06-14 19:00:58 peter Revision 1.100 2000-06-18 18:11:32 peter
* C record packing fixed to also check first entry of the record
if bigger than the recordalignment itself
* variant record alignment uses alignment per variant and saves the
highest alignment value
Revision 1.99 2000/06/14 19:00:58 peter
* rename the result of a function to hide it instead of using setname * rename the result of a function to hide it instead of using setname
Revision 1.98 2000/06/14 16:51:18 peter Revision 1.98 2000/06/14 16:51:18 peter