summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2019-11-15 20:24:14 +0100
committerGitHub <noreply@github.com>2019-11-15 20:24:14 +0100
commit58f3e07b1a84b2cbe1c1fab690b8dd6b9ed5a296 (patch)
treeef7096e37cb19c340c4bdeb04b4ae2e6bb5ec1d2
parent9c46526cfa928f884b06ea78f3f7304bdc626ed1 (diff)
downloadNim-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.md4
-rw-r--r--compiler/cgen.nim10
-rw-r--r--compiler/pragmas.nim4
-rw-r--r--doc/manual.rst27
-rw-r--r--lib/nimbase.h7
-rw-r--r--tests/misc/globalalignas.nim6
-rw-r--r--tests/misc/talignas.nim26
-rw-r--r--tests/misc/tillegalalignas.nim2
-rw-r--r--tests/misc/tsizeof.nim8
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