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:
metagn
2025-04-12 18:55:11 +03:00
committed by GitHub
parent 334f96c05a
commit 1ef9a656d2
4 changed files with 35 additions and 10 deletions

View File

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

View File

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

View File

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

@@ -0,0 +1,10 @@
{.emit: """
typedef struct Foo {
NI64 a;
NI64 b;
} Foo;
""".}
type Foo {.importc: "Foo", size: 16.} = object
var x: Foo