Merge pull request #3384 from tmm1/bitsize-pragma

Implement bitsize pragma for bitfields
This commit is contained in:
Andreas Rumpf 2015-10-01 09:11:17 +02:00
commit a3550d1314
7 changed files with 53 additions and 1 deletions

View file

@ -784,6 +784,7 @@ type
tab*: TStrTable # interface table for modules tab*: TStrTable # interface table for modules
of skLet, skVar, skField, skForVar: of skLet, skVar, skField, skForVar:
guard*: PSym guard*: PSym
bitsize*: int
else: nil else: nil
magic*: TMagic magic*: TMagic
typ*: PType typ*: PType

View file

@ -441,6 +441,8 @@ proc genRecordFieldsAux(m: BModule, n: PNode,
elif fieldType.kind == tySequence: elif fieldType.kind == tySequence:
# we need to use a weak dependency here for trecursive_table. # we need to use a weak dependency here for trecursive_table.
addf(result, "$1 $2;$n", [getTypeDescWeak(m, field.loc.t, check), sname]) 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: else:
# don't use fieldType here because we need the # don't use fieldType here because we need the
# tyGenericInst for C++ template support # tyGenericInst for C++ template support

View file

@ -56,7 +56,7 @@ const
wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked, wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked,
wBorrow, wGcSafe} wBorrow, wGcSafe}
fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern, fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern,
wImportCpp, wImportObjC, wError, wGuard} wImportCpp, wImportObjC, wError, wGuard, wBitsize}
varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl, varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl,
wMagic, wHeader, wDeprecated, wCompilerproc, wDynlib, wExtern, wMagic, wHeader, wDeprecated, wCompilerproc, wDynlib, wExtern,
wImportCpp, wImportObjC, wError, wNoInit, wCompileTime, wGlobal, 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) if sym == nil: pragmaLockStmt(c, it)
elif sym.typ == nil: invalidPragma(it) elif sym.typ == nil: invalidPragma(it)
else: sym.typ.lockLevel = pragmaLocks(c, 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: of wGuard:
if sym == nil or sym.kind notin {skVar, skLet, skField}: if sym == nil or sym.kind notin {skVar, skLet, skField}:
invalidPragma(it) invalidPragma(it)

View file

@ -82,6 +82,7 @@ type
wStdIn, wStdOut, wStdErr, wStdIn, wStdOut, wStdErr,
wInOut, wByCopy, wByRef, wOneWay, wInOut, wByCopy, wByRef, wOneWay,
wBitsize,
TSpecialWords* = set[TSpecialWord] TSpecialWords* = set[TSpecialWord]
@ -168,6 +169,7 @@ const
"stdin", "stdout", "stderr", "stdin", "stdout", "stderr",
"inout", "bycopy", "byref", "oneway", "inout", "bycopy", "byref", "oneway",
"bitsize",
] ]
proc findStr*(a: openArray[string], s: string): int = proc findStr*(a: openArray[string], s: string): int =

View file

@ -531,6 +531,24 @@ Implementation Specific Pragmas
This section describes additional pragmas that the current Nim implementation This section describes additional pragmas that the current Nim implementation
supports but which should not be seen as part of the language specification. 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 Volatile pragma
--------------- ---------------

View file

@ -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

View file

@ -108,6 +108,8 @@ News
- The compiler finally considers symbol binding rules in templates and - The compiler finally considers symbol binding rules in templates and
generics for overloaded ``[]``, ``[]=``, ``{}``, ``{}=`` operators generics for overloaded ``[]``, ``[]=``, ``{}``, ``{}=`` operators
(issue `#2599 <https://github.com/nim-lang/Nim/issues/2599>`_). (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 Language Additions