implemented alignas pragma (#12643)
* implemented alignas pragma * fix bootstrap * generate c++ compatible syntax for alignas * Make it work. * Multiple alignof expressions. Implement top level alignof.
This commit is contained in:
parent
84861eb48a
commit
0496a666e2
13 changed files with 153 additions and 19 deletions
3
tests/misc/globalalignas.nim
Normal file
3
tests/misc/globalalignas.nim
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
var myglobal1* {.alignas(128).}: int32
|
||||
var myglobal2* {.alignas(128).}: int32
|
||||
var myglobal3* {.alignas(128).}: int32
|
||||
46
tests/misc/talignas.nim
Normal file
46
tests/misc/talignas.nim
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
discard """
|
||||
ccodeCheck: "\\i @'alignas(128) NI mylocal1' .*"
|
||||
target: "c cpp"
|
||||
output: "alignas ok"
|
||||
"""
|
||||
|
||||
# This is for Azure. The keyword ``alignof`` only exists in ``c++11``
|
||||
# and newer. On Azure gcc does not default to c++11 yet.
|
||||
when defined(cpp) and not defined(windows):
|
||||
{.passC: "-std=c++11".}
|
||||
|
||||
import globalalignas
|
||||
|
||||
var toplevel1 {.alignas: 32.} : int32
|
||||
var toplevel2 {.alignas: 32.} : int32
|
||||
var toplevel3 {.alignas: 32.} : int32
|
||||
|
||||
proc foobar() =
|
||||
var myvar1 {.global, alignas(64).}: int = 123
|
||||
var myvar2 {.global, alignas(64).}: int = 123
|
||||
var myvar3 {.global, alignas(64).}: int = 123
|
||||
|
||||
doAssert (cast[uint](addr(myglobal1)) and 127) == 0
|
||||
doAssert (cast[uint](addr(myglobal2)) and 127) == 0
|
||||
doAssert (cast[uint](addr(myglobal3)) and 127) == 0
|
||||
|
||||
doAssert (cast[uint](addr(myvar1)) and 63) == 0
|
||||
doAssert (cast[uint](addr(myvar2)) and 63) == 0
|
||||
doAssert (cast[uint](addr(myvar3)) and 63) == 0
|
||||
|
||||
doAssert (cast[uint](addr(toplevel1)) and 31) == 0
|
||||
doAssert (cast[uint](addr(toplevel2)) and 31) == 0
|
||||
doAssert (cast[uint](addr(toplevel3)) and 31) == 0
|
||||
|
||||
# test multiple alignas expressions
|
||||
var mylocal1 {.alignas(0), alignas(128), alignas(32).}: int = 123
|
||||
var mylocal2 {.alignas(128), alignas(0), alignas(32).}: int = 123
|
||||
var mylocal3 {.alignas(0), alignas(32), alignas(128).}: int = 123
|
||||
|
||||
doAssert (cast[uint](addr(mylocal1)) and 127) == 0
|
||||
doAssert (cast[uint](addr(mylocal2)) and 127) == 0
|
||||
doAssert (cast[uint](addr(mylocal3)) and 127) == 0
|
||||
|
||||
echo "alignas ok"
|
||||
|
||||
foobar()
|
||||
7
tests/misc/tillegalalignas.nim
Normal file
7
tests/misc/tillegalalignas.nim
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
discard """
|
||||
cmd: "nim check $options $file"
|
||||
errormsg: "power of two or 0 expected"
|
||||
"""
|
||||
|
||||
proc foobar() =
|
||||
let something {.alignas(33).} = 123
|
||||
|
|
@ -8,8 +8,8 @@ macros api OK
|
|||
'''
|
||||
"""
|
||||
|
||||
# This is for travis. The keyword ``alignof`` only exists in ``c++11``
|
||||
# and newer. On travis gcc does not default to c++11 yet.
|
||||
# This is for Azure. The keyword ``alignof`` only exists in ``c++11``
|
||||
# and newer. On Azure gcc does not default to c++11 yet.
|
||||
when defined(cpp) and not defined(windows):
|
||||
{.passC: "-std=c++11".}
|
||||
|
||||
|
|
@ -75,7 +75,7 @@ proc strAlign(arg: string): string =
|
|||
result &= ' '
|
||||
|
||||
macro c_offsetof(a: typed, b: untyped): int32 =
|
||||
## Buffet proof implementation that works on actual offsetof operator
|
||||
## Bullet proof implementation that works on actual offsetof operator
|
||||
## in the c backend. Assuming of course this implementation is
|
||||
## correct.
|
||||
let bliteral =
|
||||
|
|
@ -89,7 +89,7 @@ macro c_offsetof(a: typed, b: untyped): int32 =
|
|||
res
|
||||
|
||||
macro c_sizeof(a: typed): int32 =
|
||||
## Buffet proof implementation that works using the sizeof operator
|
||||
## Bullet proof implementation that works using the sizeof operator
|
||||
## in the c backend. Assuming of course this implementation is
|
||||
## correct.
|
||||
result = quote do:
|
||||
|
|
@ -98,7 +98,7 @@ macro c_sizeof(a: typed): int32 =
|
|||
res
|
||||
|
||||
macro c_alignof(arg: untyped): untyped =
|
||||
## Buffet proof implementation that works on actual alignment
|
||||
## Bullet proof implementation that works on actual alignment
|
||||
## behavior measured at runtime.
|
||||
let typeSym = genSym(nskType, "AlignTestType"&arg.repr)
|
||||
result = quote do:
|
||||
|
|
@ -313,7 +313,7 @@ testinstance:
|
|||
b: int8
|
||||
c: int8
|
||||
|
||||
PaddingOfSetEnum33 = object
|
||||
PaddingOfSetEnum33 {.objectconfig.} = object
|
||||
cause: int8
|
||||
theSet: set[MyEnum33]
|
||||
|
||||
|
|
@ -332,10 +332,17 @@ testinstance:
|
|||
c: char
|
||||
|
||||
# from issue 4763
|
||||
GenericObject[T] = object
|
||||
GenericObject[T] {.objectconfig.} = object
|
||||
a: int32
|
||||
b: T
|
||||
|
||||
# this type mixes `packed` with `alignas`.
|
||||
MyCustomAlignPackedObject {.objectconfig.} = object
|
||||
a: char
|
||||
b {.alignas: 32.}: int32 # alignas overrides `packed` for this field.
|
||||
c: char
|
||||
d: int32 # unaligned
|
||||
|
||||
const trivialSize = sizeof(TrivialType) # needs to be able to evaluate at compile time
|
||||
|
||||
proc main(): void =
|
||||
|
|
@ -350,6 +357,7 @@ testinstance:
|
|||
var ro : RootObj
|
||||
var go : GenericObject[int64]
|
||||
var po : PaddingOfSetEnum33
|
||||
var capo: MyCustomAlignPackedObject
|
||||
|
||||
var
|
||||
e1: Enum1
|
||||
|
|
@ -368,8 +376,7 @@ testinstance:
|
|||
else:
|
||||
doAssert sizeof(SimpleAlignment) > 10
|
||||
|
||||
testSizeAlignOf(t,a,b,c,d,e,f,g,ro,go,po, e1, e2, e4, e8, eoa, eob)
|
||||
|
||||
testSizeAlignOf(t,a,b,c,d,e,f,g,ro,go,po, e1, e2, e4, e8, eoa, eob, capo)
|
||||
|
||||
type
|
||||
WithBitsize {.objectconfig.} = object
|
||||
|
|
@ -433,6 +440,11 @@ testinstance:
|
|||
testOffsetOf(RecursiveStuff, d1)
|
||||
testOffsetOf(RecursiveStuff, d2)
|
||||
|
||||
testOffsetOf(MyCustomAlignPackedObject, a)
|
||||
testOffsetOf(MyCustomAlignPackedObject, b)
|
||||
testOffsetOf(MyCustomAlignPackedObject, c)
|
||||
testOffsetOf(MyCustomAlignPackedObject, d)
|
||||
|
||||
echo "body executed" # sanity check to ensure this logic isn't skipped entirely
|
||||
|
||||
|
||||
|
|
@ -482,7 +494,24 @@ type
|
|||
a: int32
|
||||
b: float32
|
||||
|
||||
MyCustomAlignUnion {.union.} = object
|
||||
c: char
|
||||
a {.alignas: 32.}: int
|
||||
|
||||
MyCustomAlignObject = object
|
||||
c: char
|
||||
a {.alignas: 32.}: int
|
||||
|
||||
doAssert sizeof(MyUnionType) == 4
|
||||
doAssert sizeof(MyCustomAlignUnion) == 32
|
||||
doAssert alignof(MyCustomAlignUnion) == 32
|
||||
doAssert sizeof(MyCustomAlignObject) == 64
|
||||
doAssert alignof(MyCustomAlignObject) == 32
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
##########################################
|
||||
# bug #9794
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue