chelper: added support for bitpacked structures

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1289 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
skalogryz 2010-08-16 13:42:06 +00:00
parent dd80a33837
commit 297f9b4d2b
2 changed files with 37 additions and 5 deletions

View File

@ -341,7 +341,7 @@ type
TStructTypeField = record TStructTypeField = record
v : TVarFuncEntity; v : TVarFuncEntity;
isbitted : Integer; isbitted : Boolean;
bits : TExpression; bits : TExpression;
end; end;
@ -1870,6 +1870,7 @@ begin
i:=st.AddField(v); i:=st.AddField(v);
if AParser.Token=':' then begin if AParser.Token=':' then begin
AParser.NextToken; AParser.NextToken;
st.fields[i].isbitted:=True;
st.fields[i].bits:=ParseCExpr(AParser); st.fields[i].bits:=ParseCExpr(AParser);
end; end;
if AParser.Token=';' then AParser.NextToken; if AParser.Token=';' then AParser.NextToken;

View File

@ -20,6 +20,7 @@ unit ctopasconvert;
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
interface interface
uses uses
@ -33,6 +34,7 @@ type
TConvertSettings = class TConvertSettings = class
RecordsArePacked : Boolean; RecordsArePacked : Boolean;
UseBitPacked : Boolean;
FuncsAreExternal : Boolean; FuncsAreExternal : Boolean;
EnumsAsConst : Boolean; EnumsAsConst : Boolean;
UsedNames : TStringList; UsedNames : TStringList;
@ -1231,15 +1233,43 @@ end;
procedure TCodeConvertor.WriteStruct(st:TStructType); procedure TCodeConvertor.WriteStruct(st:TStructType);
var var
i : Integer; i : Integer;
anybit : Boolean;
x : TExpression;
bval : Int64;
xp : AnsiString;
begin begin
if cfg.RecordsArePacked then wr.W('packed '); anybit:=False;
for i:=0 to length(st.fields)-1 do
if st.fields[i].isbitted then begin
anybit:=True;
Break;
end;
if cfg.UseBitPacked and anybit then
wr.W('bitpacked ')
else if cfg.RecordsArePacked then
wr.W('packed ');
wr.Wln('record'); wr.Wln('record');
wr.IncIdent; wr.IncIdent;
//todo: bit fields support
for i:=0 to length(st.fields)-1 do begin for i:=0 to length(st.fields)-1 do begin
WriteLnCommentsBeforeOffset(st.fields[i].v.Offset); WriteLnCommentsBeforeOffset(st.fields[i].v.Offset);
WriteFuncOrVar(st.fields[i].v, False, True);
if cfg.UseBitPacked and st.fields[i].isbitted then begin
x:=st.fields[i].bits;
if isNumberExp(x, bval) then begin
bval:=(1 shl bval) - 1;
xp:=IntToStr(bval);
end else
xp:='((1 shl ('+PasExp(x)+'))-1)';
// returns true, if x is single number expression. V is the value of the number
wr.W( GetIdFromPart(st.fields[i].v.FirstName) + ' : 0..'+xp+';');
end else
WriteFuncOrVar(st.fields[i].v, False, True);
WriteLnCommentForOffset(st.fields[i].v.Offset);
end; end;
wr.DecIdent; wr.DecIdent;
wr.W('end'); wr.W('end');
@ -1540,6 +1570,7 @@ begin
EnumsAsConst := True; EnumsAsConst := True;
FuncsAreExternal := True; FuncsAreExternal := True;
RecordsArePacked := True; RecordsArePacked := True;
UseBitPacked := True;
DefaultCType := 'int'; DefaultCType := 'int';
FuncConv := 'cdecl'; FuncConv := 'cdecl';