From 297f9b4d2bc30530ed20a3c884da929b35fcf56b Mon Sep 17 00:00:00 2001 From: skalogryz Date: Mon, 16 Aug 2010 13:42:06 +0000 Subject: [PATCH] chelper: added support for bitpacked structures git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1289 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- components/chelper/cparsertypes.pas | 3 ++- components/chelper/ctopasconvert.pas | 39 +++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/components/chelper/cparsertypes.pas b/components/chelper/cparsertypes.pas index 1c077d54b..742785150 100755 --- a/components/chelper/cparsertypes.pas +++ b/components/chelper/cparsertypes.pas @@ -341,7 +341,7 @@ type TStructTypeField = record v : TVarFuncEntity; - isbitted : Integer; + isbitted : Boolean; bits : TExpression; end; @@ -1870,6 +1870,7 @@ begin i:=st.AddField(v); if AParser.Token=':' then begin AParser.NextToken; + st.fields[i].isbitted:=True; st.fields[i].bits:=ParseCExpr(AParser); end; if AParser.Token=';' then AParser.NextToken; diff --git a/components/chelper/ctopasconvert.pas b/components/chelper/ctopasconvert.pas index a74682d70..5eef4c82b 100644 --- a/components/chelper/ctopasconvert.pas +++ b/components/chelper/ctopasconvert.pas @@ -20,6 +20,7 @@ unit ctopasconvert; {$mode objfpc}{$H+} + interface uses @@ -33,6 +34,7 @@ type TConvertSettings = class RecordsArePacked : Boolean; + UseBitPacked : Boolean; FuncsAreExternal : Boolean; EnumsAsConst : Boolean; UsedNames : TStringList; @@ -1231,15 +1233,43 @@ end; procedure TCodeConvertor.WriteStruct(st:TStructType); var - i : Integer; + i : Integer; + anybit : Boolean; + + x : TExpression; + bval : Int64; + xp : AnsiString; 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.IncIdent; - //todo: bit fields support + for i:=0 to length(st.fields)-1 do begin 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; wr.DecIdent; wr.W('end'); @@ -1540,6 +1570,7 @@ begin EnumsAsConst := True; FuncsAreExternal := True; RecordsArePacked := True; + UseBitPacked := True; DefaultCType := 'int'; FuncConv := 'cdecl';