mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-06 04:57:49 +00:00
allow setting arbitrary size for importc types (#24868)
split from #24204, closes #7674 The `{.size.}` pragma no longer restricts the given size to 1, 2, 4 or 8 if it is used for an imported type. This is not tested very thoroughly but there's no obvious reason to disallow it.
This commit is contained in:
@@ -947,15 +947,19 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||
of wSize:
|
||||
if sym.typ == nil: invalidPragma(c, it)
|
||||
var size = expectIntLit(c, it)
|
||||
case size
|
||||
of 1, 2, 4:
|
||||
sym.typ.size = size
|
||||
sym.typ.align = int16 size
|
||||
of 8:
|
||||
sym.typ.size = 8
|
||||
sym.typ.align = floatInt64Align(c.config)
|
||||
if sfImportc in sym.flags:
|
||||
# no restrictions on size for imported types
|
||||
setImportedTypeSize(c.config, sym.typ, size)
|
||||
else:
|
||||
localError(c.config, it.info, "size may only be 1, 2, 4 or 8")
|
||||
case size
|
||||
of 1, 2, 4:
|
||||
sym.typ.size = size
|
||||
sym.typ.align = int16 size
|
||||
of 8:
|
||||
sym.typ.size = 8
|
||||
sym.typ.align = floatInt64Align(c.config)
|
||||
else:
|
||||
localError(c.config, it.info, "size may only be 1, 2, 4 or 8")
|
||||
of wAlign:
|
||||
let alignment = expectIntLit(c, it)
|
||||
if isPowerOfTwo(alignment) and alignment > 0:
|
||||
|
||||
@@ -1515,6 +1515,17 @@ proc getSize*(conf: ConfigRef; typ: PType): BiggestInt =
|
||||
computeSizeAlign(conf, typ)
|
||||
result = typ.size
|
||||
|
||||
proc setImportedTypeSize*(conf: ConfigRef, t: PType, size: int) =
|
||||
t.size = size
|
||||
if tfPacked in t.flags or size <= 1:
|
||||
t.align = 1
|
||||
elif size <= 2:
|
||||
t.align = 2
|
||||
elif size <= 4:
|
||||
t.align = 4
|
||||
else:
|
||||
t.align = floatInt64Align(conf)
|
||||
|
||||
proc isConcept*(t: PType): bool=
|
||||
case t.kind
|
||||
of tyConcept: true
|
||||
|
||||
@@ -7815,6 +7815,8 @@ The `size pragma` allows specifying the size of the enum type.
|
||||
doAssert sizeof(EventType) == sizeof(uint32)
|
||||
```
|
||||
|
||||
When used for enum types, the `size pragma` accepts only the values 1, 2, 4 or 8.
|
||||
|
||||
The `size pragma` can also specify the size of an `importc` incomplete object type
|
||||
so that one can get the size of it at compile time even if it was declared without fields.
|
||||
|
||||
@@ -7827,8 +7829,6 @@ so that one can get the size of it at compile time even if it was declared witho
|
||||
echo sizeof(AtomicFlag)
|
||||
```
|
||||
|
||||
The `size pragma` accepts only the values 1, 2, 4 or 8.
|
||||
|
||||
|
||||
Align pragma
|
||||
------------
|
||||
|
||||
10
tests/c/timportedsize.nim
Normal file
10
tests/c/timportedsize.nim
Normal file
@@ -0,0 +1,10 @@
|
||||
{.emit: """
|
||||
typedef struct Foo {
|
||||
NI64 a;
|
||||
NI64 b;
|
||||
} Foo;
|
||||
""".}
|
||||
|
||||
type Foo {.importc: "Foo", size: 16.} = object
|
||||
|
||||
var x: Foo
|
||||
Reference in New Issue
Block a user