(M-31582): Separate JSP-586E, C4-466C and U+84A6.
[chise/xemacs-chise.git] / src / lisp.h
index 327cdb6..64d2044 100644 (file)
@@ -193,20 +193,42 @@ void xfree (void *);
 # endif /* GNUC */
 #endif
 
+/* No type has a greater alignment requirement than max_align_t.
+   (except perhaps for types we don't use, like long double) */
+typedef union
+{
+  struct { long l; } l;
+  struct { void *p; } p;
+  struct { void (*f)(void); } f;
+  struct { double d; } d;
+} max_align_t;
+
 #ifndef ALIGNOF
 # if defined (__GNUC__) && (__GNUC__ >= 2)
-#  define ALIGNOF(x) __alignof__ (x)
+/* gcc has an extension that gives us exactly what we want. */
+#  define ALIGNOF(type) __alignof__ (type)
+# elif ! defined (__cplusplus)
+/* The following is mostly portable, except that:
+   - it doesn't work for inside out declarations like void (*) (void).
+     (so just call ALIGNOF with a typedef'ed name)
+   - it doesn't work with C++.  The C++ committee has decided,
+     in its infinite wisdom, that:
+     "Types must be declared in declarations, not in expressions." */
+#  define ALIGNOF(type) offsetof (struct { char c; type member; }, member)
 # else
-#  define ALIGNOF(x) sizeof (x)
+/* C++ is annoying, but it has a big bag of tricks.
+   The following doesn't have the "inside out" declaration bug C does. */
+template<class T> struct alignment_trick { char c; T member; };
+#  define ALIGNOF(type) offsetof (alignment_trick<type>, member)
 # endif
-#endif
+#endif /* ALIGNOF */
 
 #define ALIGN_SIZE(len, unit) \
   ((((len) + (unit) - 1) / (unit)) * (unit))
 
 /* #### Yuck, this is kind of evil */
 #define ALIGN_PTR(ptr, unit) \
-  ((void *) ALIGN_SIZE ((long) (ptr), unit))
+  ((void *) ALIGN_SIZE ((size_t) (ptr), unit))
 
 #ifndef DO_NOTHING
 #define DO_NOTHING do {} while (0)
@@ -1178,14 +1200,28 @@ void set_string_char (Lisp_String *s, Charcount i, Emchar c);
 
 #endif /* not MULE */
 
-/* Return the true size of a struct with a variable-length array field.  */
-#define FLEXIBLE_ARRAY_STRUCT_SIZEOF(flexible_array_structtype,                \
-                                    flexible_array_field,              \
-                                    flexible_array_length)             \
-  (offsetof (flexible_array_structtype, flexible_array_field) +                \
-   (offsetof (flexible_array_structtype, flexible_array_field[1]) -    \
-    offsetof (flexible_array_structtype, flexible_array_field[0])) *   \
-   (flexible_array_length))
+/* Return the true aligned size of a struct whose last member is a
+   variable-length array field.  (this is known as the "struct hack") */
+/* Implementation: in practice, structtype and fieldtype usually have
+   the same alignment, but we can't be sure.  We need to use
+   ALIGN_SIZE to be absolutely sure of getting the correct alignment.
+   To help the compiler's optimizer, we use a ternary expression that
+   only a very stupid compiler would fail to correctly simplify. */
+#define FLEXIBLE_ARRAY_STRUCT_SIZEOF(structtype,       \
+                                    fieldtype,         \
+                                    fieldname,         \
+                                    array_length)      \
+(ALIGNOF (structtype) == ALIGNOF (fieldtype)           \
+ ? (offsetof (structtype, fieldname) +                 \
+    (offsetof (structtype, fieldname[1]) -             \
+     offsetof (structtype, fieldname[0])) *            \
+    (array_length))                                    \
+ : (ALIGN_SIZE                                         \
+    ((offsetof (structtype, fieldname) +               \
+      (offsetof (structtype, fieldname[1]) -           \
+       offsetof (structtype, fieldname[0])) *          \
+      (array_length)),                                 \
+     ALIGNOF (structtype))))
 
 /*------------------------------ vector --------------------------------*/
 
@@ -2237,10 +2273,6 @@ typedef unsigned long uintptr_t;
 void release_breathing_space (void);
 Lisp_Object noseeum_cons (Lisp_Object, Lisp_Object);
 Lisp_Object make_vector (size_t, Lisp_Object);
-#ifdef HAVE_GGC
-Lisp_Object make_older_vector (size_t, Lisp_Object);
-void make_vector_newer (Lisp_Object);
-#endif
 Lisp_Object vector1 (Lisp_Object);
 Lisp_Object vector2 (Lisp_Object, Lisp_Object);
 Lisp_Object vector3 (Lisp_Object, Lisp_Object, Lisp_Object);