Add a new class slot `align', holding the instance layout alignment.
authorMark Wooding <mdw@distorted.org.uk>
Tue, 15 Dec 2015 19:15:23 +0000 (19:15 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 29 May 2016 14:08:43 +0000 (15:08 +0100)
Or at least a conservative approximation of it.

doc/structures.tex
lib/sod-structs.3
lib/sod.h
src/builtin.lisp

index d379c99..b63a336 100644 (file)
@@ -139,6 +139,7 @@ recommended.
        const char *name; \\
        const char *nick; \\
        size_t initsz; \\
+       size_t align; \\
        void *(*imprint)(void *@<p>); \\
        void *(*init)(void *@<p>); \\
        size_t n_supers; \\
@@ -167,6 +168,8 @@ recommended.
 
   \item[initsz] The size in bytes required to store an instance of the class.
 
+  \item[align] A sufficient alignment for the class's instance storage.
+
   \item[imprint] A pointer to a function: given a pointer @<p> to at least
     @<initsz> bytes of appropriately aligned memory, `imprint' this memory it
     so that it becomes a minimally functional instance of the class: all of
index a6c9db2..5624d33 100644 (file)
@@ -95,6 +95,7 @@ struct SodObject__ilayout {
 \h'8n'const char *name;
 \h'8n'const char *nick;
 \h'8n'size_t initsz;
+\h'8n'size_t align;
 \h'8n'void *(*imprint)(void *\fIp\fB);
 \h'8n'void *(*init)(void *\fIp\fB);
 \h'8n'size_t n_supers;
@@ -253,6 +254,9 @@ A pointer to the class's nickname.
 .B size_t initsz;
 The size in bytes required to store an instance of the class.
 .TP
+.B size_t align;
+A sufficient alignment for the class's instance storage.
+.TP
 .BI "void *(*imprint)(void *" p );
 A pointer to a function:
 given a pointer
index 360afa8..943ed4b 100644 (file)
--- a/lib/sod.h
+++ b/lib/sod.h
 
 /*----- Preliminary utilities ---------------------------------------------*/
 
+/* Various hacks for checking compiler versions. */
+#define SOD__GCC_P(maj, min)                                           \
+       (__GNUC__ > (maj) || (__GNUC__ == (maj) && __GNUC_MINOR__ >= (min)))
+
+#ifdef __GNUC__
+#  define SOD__EXTENSION __extension__
+#else
+#  define SOD__EXTENSION
+#endif
+
 /* --- @SOD__HAVE_VARARGS_MACROS@ --- *
  *
  * Use:                Defined if the compiler supports C99-style variadic macros.
@@ -49,7 +59,7 @@
 
 #  define SOD__HAVE_VARARGS_MACROS
 
-#elif __GNUC__ >= 3
+#elif SOD__GCC_P(3, 0)
    /* We're using GCC, which is trying to deny it but we don't believe it.
     * Unfortunately there's a fly in the ointment: if `-pedantic' -- or,
     * worse, `-pedantic-errors' -- is set, then GCC will warn about these
 /* We're going to want to make use of this ourselves. */
 SOD__VARARGS_MACROS_PREAMBLE
 
+/* --- @SOD__ALIGNOF@ --- *
+ *
+ * Arguments:  @type@ = a C type name, consisting of declaration specifiers
+ *                     and `*[QUALIFIERS]' declarator operators
+ *
+ * Returns:    A sufficient alignment for objects of the given @type@, as a
+ *             @size_t@.
+ */
+
+#if __STDC_VERSION__ >= 201112
+#  define SOD__ALIGNOF(type) _Alignof(type)
+#elif SOD__GCC_P(4, 7)
+#  define SOD__ALIGNOF(type) __extension__ _Alignof(type)
+#elif defined(__GNUC__)
+#  define SOD__ALIGNOF(type) __alignof__(type)
+#else
+#  define SOD__ALIGNOF(type)                                           \
+offsetof(struct { char sod__x; type sod__y; }, sod__y)
+#endif
+
 /* --- @SOD__CAR@ --- *
  *
  * Arguments:  @...@ = a nonempty list of arguments
index 1c14f19..fbef93b 100644 (file)
@@ -85,6 +85,9 @@
 (define-class-slot "initsz" (class) size-t
   (format nil "sizeof(struct ~A)" (ilayout-struct-tag class)))
 
+(define-class-slot "align" (class) size-t
+  (format nil "SOD__ALIGNOF(struct ~A)" (ilayout-struct-tag class)))
+
 (define-class-slot "imprint" (class stream)
     (* (fun (* void) ("/*p*/" (* void))))
   (format nil "~A__imprint" class)