diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2019-11-15 20:24:14 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-15 20:24:14 +0100 |
commit | 58f3e07b1a84b2cbe1c1fab690b8dd6b9ed5a296 (patch) | |
tree | ef7096e37cb19c340c4bdeb04b4ae2e6bb5ec1d2 | |
parent | 9c46526cfa928f884b06ea78f3f7304bdc626ed1 (diff) | |
download | Nim-58f3e07b1a84b2cbe1c1fab690b8dd6b9ed5a296.tar.gz |
fixes and changes the recently introduced 'alignas' to be 'align' (#12666)
* fixes and changes the recently introduced 'alignas' to be 'align' * more improvements
-rw-r--r-- | changelog.md | 4 | ||||
-rw-r--r-- | compiler/cgen.nim | 10 | ||||
-rw-r--r-- | compiler/pragmas.nim | 4 | ||||
-rw-r--r-- | doc/manual.rst | 27 | ||||
-rw-r--r-- | lib/nimbase.h | 7 | ||||
-rw-r--r-- | tests/misc/globalalignas.nim | 6 | ||||
-rw-r--r-- | tests/misc/talignas.nim | 26 | ||||
-rw-r--r-- | tests/misc/tillegalalignas.nim | 2 | ||||
-rw-r--r-- | tests/misc/tsizeof.nim | 8 |
9 files changed, 50 insertions, 44 deletions
diff --git a/changelog.md b/changelog.md index 2ff0cdf29..9f30fea8e 100644 --- a/changelog.md +++ b/changelog.md @@ -58,8 +58,8 @@ ## Language additions -- `alignas` pragma can now be used similar to the `alignas` - declaration modifier in C/C++. +- An `align` pragma can now be used for variables and object fields, similar + to the `alignas` declaration modifier in C/C++. ## Language changes diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 0e88c39d8..cfd1aeb24 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -479,8 +479,8 @@ proc localVarDecl(p: BProc; n: PNode): Rope = if s.loc.k == locNone: fillLoc(s.loc, locLocalVar, n, mangleLocalName(p, s), OnStack) if s.kind == skLet: incl(s.loc.flags, lfNoDeepCopy) - if s.kind in {skLet, skVar} and s.alignment > 0: - result.addf("alignas($1) ", [rope(s.alignment)]) + if s.kind in {skLet, skVar, skField, skForVar} and s.alignment > 0: + result.addf("NIM_ALIGN($1) ", [rope(s.alignment)]) result.add getTypeDesc(p.module, s.typ) if s.constraint.isNil: if sfRegister in s.flags: add(result, " register") @@ -533,7 +533,7 @@ proc assignGlobalVar(p: BProc, n: PNode) = var td = getTypeDesc(p.module, s.loc.t) if s.constraint.isNil: if s.kind in {skLet, skVar, skField, skForVar} and s.alignment > 0: - decl.addf "alignas($1) ", [rope(s.alignment)] + decl.addf "NIM_ALIGN($1) ", [rope(s.alignment)] if p.hcrOn: add(decl, "static ") elif sfImportc in s.flags: add(decl, "extern ") add(decl, td) @@ -1195,8 +1195,8 @@ proc genVarPrototype(m: BModule, n: PNode) = declareThreadVar(m, sym, true) else: incl(m.declaredThings, sym.id) - if sym.alignment > 0: - m.s[cfsVars].addf "alignas($1) ", [rope(sym.alignment)] + if sym.kind in {skLet, skVar, skField, skForVar} and sym.alignment > 0: + m.s[cfsVars].addf "NIM_ALIGN($1) ", [rope(sym.alignment)] add(m.s[cfsVars], if m.hcrOn: "static " else: "extern ") add(m.s[cfsVars], getTypeDesc(m, sym.loc.t)) if m.hcrOn: add(m.s[cfsVars], "*") diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 24394bf97..e43004bf8 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -20,7 +20,7 @@ const const declPragmas = {wImportc, wImportObjC, wImportCpp, wImportJs, wExportc, wExportCpp, - wExportNims, wExtern, wDeprecated, wNodecl, wError, wUsed, wAlignas} + wExportNims, wExtern, wDeprecated, wNodecl, wError, wUsed, wAlign} ## common pragmas for declarations, to a good approximation procPragmas* = declPragmas + {FirstCallConv..LastCallConv, wMagic, wNoSideEffect, wSideEffect, wNoreturn, wDynlib, wHeader, @@ -815,7 +815,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, sym.typ.align = floatInt64Align(c.config) else: localError(c.config, it.info, "size may only be 1, 2, 4 or 8") - of wAlignas: + of wAlign: let alignment = expectIntLit(c, it) if alignment == 0: discard diff --git a/doc/manual.rst b/doc/manual.rst index 71bfb1e2b..c869b391f 100644 --- a/doc/manual.rst +++ b/doc/manual.rst @@ -6433,38 +6433,39 @@ generates: unsigned int flag:1; }; -Alignas pragma --------------- -The ``alignas`` pragma is for variables and object field members. It -modifies the alignment requirement of the thing being declared. The -argument must be a constant power of 2 or 0. Valid non-zero -alignments that are weaker than another alignas pragmas on the same -declaration are ignored. Alignments that are weaker that the -alignment requirement of the type are ignored. ``alignas(0)`` is -always ignored. +Align pragma +------------ + +The `align`:idx: pragma is for variables and object field members. It +modifies the alignment requirement of the entity being declared. The +argument must be a constant power of 2. Valid non-zero +alignments that are weaker than nother align pragmas on the same +declaration are ignored. Alignments that are weaker that the +alignment requirement of the type are ignored. .. code-block:: Nim type sseType = object - sseData {.alignas(16).}: array[4,float32] + sseData {.align(16).}: array[4,float32] # every object will be aligned to 128-byte boundary Data = object x: char - cacheline {.alignas(128).}: array[128, char] # over-aligned array of char, + cacheline {.align(128).}: array[128, char] # over-aligned array of char, proc main() = echo "sizeof(Data) = ", sizeof(Data), " (1 byte + 127 bytes padding + 128-byte array)" # output: sizeof(Data) = 256 (1 byte + 127 bytes padding + 128-byte array) echo "alignment of sseType is ", alignof(sseType) # output: alignment of sseType is 16 - var d {.alignas(2048).}: Data # this instance of data is aligned even stricter + var d {.align(2048).}: Data # this instance of data is aligned even stricter main() -This pragma has no effect on nimvm or the js backend. +This pragma has no effect for the JS backend. + Volatile pragma --------------- diff --git a/lib/nimbase.h b/lib/nimbase.h index fb6861ec7..732d3975f 100644 --- a/lib/nimbase.h +++ b/lib/nimbase.h @@ -256,7 +256,6 @@ __clang__ #include <limits.h> #include <stddef.h> -#include <stdalign.h> /* C99 compiler? */ #if (defined(__STD_VERSION__) && (__STD_VERSION__ >= 199901)) @@ -467,6 +466,12 @@ typedef int Nim_and_C_compiler_disagree_on_target_architecture[sizeof(NI) == siz # define NIM_EXTERNC #endif +#if defined(_MSC_VER) +# define NIM_ALIGN(x) __declspec(align(x)) +#else +# define NIM_ALIGN(x) __attribute__((aligned(x))) +#endif + /* ---------------- platform specific includes ----------------------- */ /* VxWorks related includes */ diff --git a/tests/misc/globalalignas.nim b/tests/misc/globalalignas.nim index cc2a4cacb..15f564733 100644 --- a/tests/misc/globalalignas.nim +++ b/tests/misc/globalalignas.nim @@ -1,3 +1,3 @@ -var myglobal1* {.alignas(128).}: int32 -var myglobal2* {.alignas(128).}: int32 -var myglobal3* {.alignas(128).}: int32 +var myglobal1* {.align(128).}: int32 +var myglobal2* {.align(128).}: int32 +var myglobal3* {.align(128).}: int32 diff --git a/tests/misc/talignas.nim b/tests/misc/talignas.nim index fdf11c662..50a3eb962 100644 --- a/tests/misc/talignas.nim +++ b/tests/misc/talignas.nim @@ -1,7 +1,7 @@ discard """ -ccodeCheck: "\\i @'alignas(128) NI mylocal1' .*" +ccodeCheck: "\\i @'NIM_ALIGN(128) NI mylocal1' .*" target: "c cpp" -output: "alignas ok" +output: "align ok" """ # This is for Azure. The keyword ``alignof`` only exists in ``c++11`` @@ -11,14 +11,14 @@ when defined(cpp) and not defined(windows): import globalalignas -var toplevel1 {.alignas: 32.} : int32 -var toplevel2 {.alignas: 32.} : int32 -var toplevel3 {.alignas: 32.} : int32 +var toplevel1 {.align: 32.} : int32 +var toplevel2 {.align: 32.} : int32 +var toplevel3 {.align: 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 + var myvar1 {.global, align(64).}: int = 123 + var myvar2 {.global, align(64).}: int = 123 + var myvar3 {.global, align(64).}: int = 123 doAssert (cast[uint](addr(myglobal1)) and 127) == 0 doAssert (cast[uint](addr(myglobal2)) and 127) == 0 @@ -32,15 +32,15 @@ proc foobar() = 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 + # test multiple align expressions + var mylocal1 {.align(0), align(128), align(32).}: int = 123 + var mylocal2 {.align(128), align(0), align(32).}: int = 123 + var mylocal3 {.align(0), align(32), align(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" + echo "align ok" foobar() diff --git a/tests/misc/tillegalalignas.nim b/tests/misc/tillegalalignas.nim index 7a9b031fb..56721f2ea 100644 --- a/tests/misc/tillegalalignas.nim +++ b/tests/misc/tillegalalignas.nim @@ -4,4 +4,4 @@ errormsg: "power of two or 0 expected" """ proc foobar() = - let something {.alignas(33).} = 123 + let something {.align(33).} = 123 diff --git a/tests/misc/tsizeof.nim b/tests/misc/tsizeof.nim index 9bcdcb374..a2a9fe59e 100644 --- a/tests/misc/tsizeof.nim +++ b/tests/misc/tsizeof.nim @@ -336,10 +336,10 @@ testinstance: a: int32 b: T - # this type mixes `packed` with `alignas`. + # this type mixes `packed` with `align`. MyCustomAlignPackedObject {.objectconfig.} = object a: char - b {.alignas: 32.}: int32 # alignas overrides `packed` for this field. + b {.align: 32.}: int32 # align overrides `packed` for this field. c: char d: int32 # unaligned @@ -496,11 +496,11 @@ type MyCustomAlignUnion {.union.} = object c: char - a {.alignas: 32.}: int + a {.align: 32.}: int MyCustomAlignObject = object c: char - a {.alignas: 32.}: int + a {.align: 32.}: int doAssert sizeof(MyUnionType) == 4 doAssert sizeof(MyCustomAlignUnion) == 32 |