## tests for -d:checkAbi used by addAbiCheck via NIM_STATIC_ASSERT {.emit:"""/*TYPESECTION*/ struct Foo1{ int a; }; struct Foo2{ int a; }; enum Foo3{k1, k2}; typedef enum Foo3 Foo3b; typedef enum Foo4{k3, k4} Foo4; typedef int Foo5[3]; typedef struct Foo6{ int a1; bool a2; double a3; struct Foo6* a4; } Foo6; """.} template ensureCgen(T: typedesc) = ## ensures cgen var a {.volatile.}: T block: type Foo1Alias{.importc: "struct Foo1", size: sizeof(cint).} = object a: cint ensureCgen Foo1Alias block: type Foo3Alias{.importc: "enum Foo3", size: sizeof(cint).} = enum k1, k2 ensureCgen Foo3Alias block: type Foo3bAlias{.importc: "Foo3b", size: sizeof(cint).} = enum k1, k2 ensureCgen Foo3bAlias block: type Foo3b{.importc, size: sizeof(cint).} = enum k1, k2 ensureCgen Foo3b static: doAssert Foo3b.sizeof == cint.sizeof block: type Foo4{.importc, size: sizeof(cint).} = enum k3, k4 # adding entries should not yield duplicate ABI checks, as enforced by # `typeABICache`. # Currently the test doesn't check for this but you can inspect the cgen'd file ensureCgen Foo4 ensureCgen Foo4 ensureCgen Foo4 block: type Foo5{.importc.} = array[3, cint] ensureCgen Foo5 block: type Foo5{.importc.} = array[3, cint] ensureCgen Foo5 block: # CT sizeof type Foo6GT = object # grountruth a1: cint a2: bool a3: cfloat a4: ptr Foo6GT type Foo6{.importc, completeStruct.} = object a1: cint a2: bool a3: cfloat a4: ptr Foo6 static: doAssert compiles(static(Foo6.sizeof)) static: doAssert Foo6.sizeof == Foo6GT.sizeof static: doAssert (Foo6, int, array[2, Foo6]).sizeof == (Foo6GT, int, array[2, Foo6GT]).sizeof block: type GoodImportcType {.importc: "signed char", nodecl.} = char # "good" in sense the sizeof will match ensureCgen GoodImportcType block: type Foo6{.importc.} = object a1: cint doAssert compiles(Foo6.sizeof) static: doAssert not compiles(static(Foo6.sizeof)) when defined caseBad: # Each case below should give a static cgen assert fail message block: type BadImportcType {.importc: "unsigned char", nodecl.} = uint64 # "sizeof" check will fail ensureCgen BadImportcType block: type Foo2AliasBad{.importc: "struct Foo2", size: 1.} = object a: cint ensureCgen Foo2AliasBad block: type Foo5{.importc.} = array[4, cint] ensureCgen Foo5 block: type Foo5{.importc.} = array[3, bool] ensureCgen Foo5 block: type Foo6{.importc:"struct Foo6", completeStruct.} = object a1: cint # a2: bool # missing this should trigger assert fail a3: cfloat a4: ptr Foo6 ensureCgen Foo6 when false: block: # pre-existing BUG: this should give a CT error in semcheck because `size` # disagrees with `array[3, cint]` type Foo5{.importc, size: 1.} = array[3, cint] ensureCgen Foo5