From 5e9ce88dafbaa0bf72a7c7c3ce11a8d827ab3200 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Mon, 28 Sep 2015 14:34:36 -0700 Subject: [PATCH 1/5] implement bitsize pragma for bitfields --- compiler/ast.nim | 1 + compiler/ccgtypes.nim | 2 ++ compiler/pragmas.nim | 7 ++++++- compiler/wordrecg.nim | 2 ++ tests/pragmas/tbitsize.nim | 7 +++++++ 5 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 tests/pragmas/tbitsize.nim diff --git a/compiler/ast.nim b/compiler/ast.nim index 4001e896e3..9db5a4e34f 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -784,6 +784,7 @@ type tab*: TStrTable # interface table for modules of skLet, skVar, skField, skForVar: guard*: PSym + bitsize*: BiggestInt else: nil magic*: TMagic typ*: PType diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 84d02d1da6..1ed9ce1139 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -441,6 +441,8 @@ proc genRecordFieldsAux(m: BModule, n: PNode, elif fieldType.kind == tySequence: # we need to use a weak dependency here for trecursive_table. addf(result, "$1 $2;$n", [getTypeDescWeak(m, field.loc.t, check), sname]) + elif field.bitsize != 0: + addf(result, "$1 $2:$3;$n", [getTypeDescAux(m, field.loc.t, check), sname, rope($field.bitsize)]) else: # don't use fieldType here because we need the # tyGenericInst for C++ template support diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 1c51251fe7..ba05b2792a 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -56,7 +56,7 @@ const wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked, wBorrow, wGcSafe} fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern, - wImportCpp, wImportObjC, wError, wGuard} + wImportCpp, wImportObjC, wError, wGuard, wBitsize} varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl, wMagic, wHeader, wDeprecated, wCompilerproc, wDynlib, wExtern, wImportCpp, wImportObjC, wError, wNoInit, wCompileTime, wGlobal, @@ -844,6 +844,11 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, if sym == nil: pragmaLockStmt(c, it) elif sym.typ == nil: invalidPragma(it) else: sym.typ.lockLevel = pragmaLocks(c, it) + of wBitsize: + if sym == nil or sym.kind != skField or it.kind != nkExprColonExpr: + invalidPragma(it) + else: + sym.bitsize = expectIntLit(c, it) of wGuard: if sym == nil or sym.kind notin {skVar, skLet, skField}: invalidPragma(it) diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index 23f012ea50..d1e5438f3d 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -82,6 +82,7 @@ type wStdIn, wStdOut, wStdErr, wInOut, wByCopy, wByRef, wOneWay, + wBitsize, TSpecialWords* = set[TSpecialWord] @@ -168,6 +169,7 @@ const "stdin", "stdout", "stderr", "inout", "bycopy", "byref", "oneway", + "bitsize", ] proc findStr*(a: openArray[string], s: string): int = diff --git a/tests/pragmas/tbitsize.nim b/tests/pragmas/tbitsize.nim new file mode 100644 index 0000000000..d2c646ef74 --- /dev/null +++ b/tests/pragmas/tbitsize.nim @@ -0,0 +1,7 @@ +type + bits* = object + flag* {.bitsize: 1.}: cint + opts* {.bitsize: 4.}: cint + +var b: bits +echo b.flag From 0679340b52e521306c3d5dc44ba94d7eaacdb662 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Tue, 29 Sep 2015 14:39:20 -0700 Subject: [PATCH 2/5] switch to bitsize:int --- compiler/ast.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 9db5a4e34f..25958f580b 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -784,7 +784,7 @@ type tab*: TStrTable # interface table for modules of skLet, skVar, skField, skForVar: guard*: PSym - bitsize*: BiggestInt + bitsize*: int else: nil magic*: TMagic typ*: PType From fa404dc532f61b78bd0e714c121b41ba8fc15ca7 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Tue, 29 Sep 2015 14:53:34 -0700 Subject: [PATCH 3/5] better assertions for bitfield behavior --- tests/pragmas/tbitsize.nim | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/tests/pragmas/tbitsize.nim b/tests/pragmas/tbitsize.nim index d2c646ef74..b9b478a7f1 100644 --- a/tests/pragmas/tbitsize.nim +++ b/tests/pragmas/tbitsize.nim @@ -1,7 +1,18 @@ type bits* = object - flag* {.bitsize: 1.}: cint + flag* {.bitsize: 1.}: cuint opts* {.bitsize: 4.}: cint -var b: bits -echo b.flag +var + b: bits + +assert b.flag == 0 +b.flag = 1 +assert b.flag == 1 +b.flag = 2 +assert b.flag == 0 + +b.opts = 7 +assert b.opts == 7 +b.opts = 9 +assert b.opts == -7 From 8450ee9d5998e12158b590120321760a8f4b85d9 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Wed, 30 Sep 2015 11:42:50 -0700 Subject: [PATCH 4/5] ensure generated c-code matches --- tests/pragmas/tbitsize.nim | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/pragmas/tbitsize.nim b/tests/pragmas/tbitsize.nim index b9b478a7f1..7a44944d24 100644 --- a/tests/pragmas/tbitsize.nim +++ b/tests/pragmas/tbitsize.nim @@ -1,3 +1,7 @@ +discard """ +ccodeCheck: "\\i @'unsigned int flag:1;' .*" +""" + type bits* = object flag* {.bitsize: 1.}: cuint From 8c8646773024ea740c4c9f090619ddaf61bc16f0 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Wed, 30 Sep 2015 12:29:32 -0700 Subject: [PATCH 5/5] document new bitsize pragma --- doc/manual/pragmas.txt | 18 ++++++++++++++++++ web/news.txt | 2 ++ 2 files changed, 20 insertions(+) diff --git a/doc/manual/pragmas.txt b/doc/manual/pragmas.txt index 68a88f865a..f89194c9ad 100644 --- a/doc/manual/pragmas.txt +++ b/doc/manual/pragmas.txt @@ -531,6 +531,24 @@ Implementation Specific Pragmas This section describes additional pragmas that the current Nim implementation supports but which should not be seen as part of the language specification. +Bitsize pragma +-------------- + +The ``bitsize`` pragma is for object field members. It declares the field as +a bitfield in C/C++. + +.. code-block:: Nim + type + mybitfield = object + flag {.bitsize:1.}: cuint + +generates: + +.. code-block:: C + struct mybitfield { + unsigned int flag:1; + }; + Volatile pragma --------------- diff --git a/web/news.txt b/web/news.txt index cfa40c65ca..33ceac49e4 100644 --- a/web/news.txt +++ b/web/news.txt @@ -108,6 +108,8 @@ News - The compiler finally considers symbol binding rules in templates and generics for overloaded ``[]``, ``[]=``, ``{}``, ``{}=`` operators (issue `#2599 `_). + - The compiler now supports a `bitsize pragma `_ + for constructing bitfields. Language Additions