Add alignment to hsc2hs template
authorRyanGlScott <ryan.gl.scott@gmail.com>
Sat, 19 Dec 2015 00:31:24 +0000 (01:31 +0100)
committerThomas Miedema <thomasmiedema@gmail.com>
Sat, 19 Dec 2015 00:39:17 +0000 (01:39 +0100)
Previously, calculating alignment values was commonly done by defining a
custom macro via `#let`:

```
(y__); }, y__)
```

Not only is this tedious, but it also doesn't work in cross-compilation
mode (see #10272). It makes sense to define this in `hsc2hs` for symmetry
with `#size`, `#poke`, `#peek`, etc., as well as to make it easier to
cross-compile `.hsc` files.

Fixes #4340.

Reviewed By: thomie, erikd

Differential Revision: https://phabricator.haskell.org/D1436

GHC Trac Issues: #4340, #10272

CrossCodegen.hs
DirectCodegen.hs
template-hsc.h

index 30bb438..7b26dc7 100644 (file)
@@ -217,6 +217,8 @@ outputSpecial output (z@ZCursor {zCursor=Special pos@(SourcePos file line)  key
        "const" -> outputConst value show
        "offset" -> outputConst ("offsetof(" ++ value ++ ")") (\i -> "(" ++ show i ++ ")")
        "size" -> outputConst ("sizeof(" ++ value ++ ")") (\i -> "(" ++ show i ++ ")")
+       "alignment" -> outputConst (alignment value)
+                                  (\i -> "(" ++ show i ++ ")")
        "peek" -> outputConst ("offsetof(" ++ value ++ ")")
                              (\i -> "(\\hsc_ptr -> peekByteOff hsc_ptr " ++ show i ++ ")")
        "poke" -> outputConst ("offsetof(" ++ value ++ ")")
@@ -281,6 +283,7 @@ outValidityCheck s@(Special pos key value) uniq =
        "const" -> checkValidConst value
        "offset" -> checkValidConst ("offsetof(" ++ value ++ ")")
        "size" -> checkValidConst ("sizeof(" ++ value ++ ")")
+       "alignment" -> checkValidConst (alignment value)
        "peek" -> checkValidConst ("offsetof(" ++ value ++ ")")
        "poke" -> checkValidConst ("offsetof(" ++ value ++ ")")
        "ptr" -> checkValidConst ("offsetof(" ++ value ++ ")")
@@ -439,6 +442,10 @@ stringify = go False . dropWhile isSpace
                     then ' ' : x : go False xs
                     else x : go False xs
 
+-- For #{alignment} codegen; mimic's template-hsc.h's hsc_alignment
+alignment :: String -> String
+alignment t = "offsetof(struct {char x__; " ++ t ++ " (y__); }, y__)"
+
 computeEnum :: ZCursor Token -> TestMonad String
 computeEnum z@(ZCursor (Special _ _ enumText) _ _) =
     case parseEnum enumText of
index c6f428d..37564ee 100644 (file)
@@ -54,7 +54,7 @@ outputDirect config outName outDir outBase name toks = do
 
     when (cCrossSafe config) $
         forM_ specials (\ (SourcePos file line,key,_) ->
-            when (not $ key `elem` ["const","offset","size","peek","poke","ptr",
+            when (not $ key `elem` ["const","offset","size","alignment","peek","poke","ptr",
                                     "type","enum","error","warning","include","define","undef",
                                     "if","ifdef","ifndef", "elif","else","endif"]) $
              die (file ++ ":" ++ show line ++ " directive \"" ++ key ++ "\" is not safe for cross-compilation"))
index b27faee..edc90c2 100644 (file)
@@ -85,6 +85,9 @@ void *hsc_stdout(void);
 #define hsc_size(t...) \
     hsc_printf("(%ld)", (long) sizeof(t));
 
+#define hsc_alignment(t...) \
+    hsc_printf("(%ld)", (long) offsetof(struct {char x__; t (y__); }, y__));
+
 #define hsc_enum(t, f, print_name, x)                   \
     print_name;                                         \
     hsc_printf (" :: %s\n", #t);                        \