diff options
-rw-r--r-- | compiler/ast.nim | 1 | ||||
-rw-r--r-- | compiler/ccgtypes.nim | 2 | ||||
-rw-r--r-- | compiler/pragmas.nim | 7 | ||||
-rw-r--r-- | compiler/wordrecg.nim | 2 | ||||
-rw-r--r-- | doc/manual/pragmas.txt | 18 | ||||
-rw-r--r-- | tests/pragmas/tbitsize.nim | 22 | ||||
-rw-r--r-- | web/news.txt | 2 |
7 files changed, 53 insertions, 1 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 4001e896e..25958f580 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*: int else: nil magic*: TMagic typ*: PType diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 84d02d1da..1ed9ce113 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 1c51251fe..ba05b2792 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 23f012ea5..d1e5438f3 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/doc/manual/pragmas.txt b/doc/manual/pragmas.txt index 68a88f865..f89194c9a 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/tests/pragmas/tbitsize.nim b/tests/pragmas/tbitsize.nim new file mode 100644 index 000000000..7a44944d2 --- /dev/null +++ b/tests/pragmas/tbitsize.nim @@ -0,0 +1,22 @@ +discard """ +ccodeCheck: "\\i @'unsigned int flag:1;' .*" +""" + +type + bits* = object + flag* {.bitsize: 1.}: cuint + opts* {.bitsize: 4.}: cint + +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 diff --git a/web/news.txt b/web/news.txt index cfa40c65c..33ceac49e 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 <https://github.com/nim-lang/Nim/issues/2599>`_). + - The compiler now supports a `bitsize pragma <docs/manual.html#pragmas-bitsize-pragma>`_ + for constructing bitfields. Language Additions |