Merge branches 'mdw/kwargs-fixes' and 'mdw/c11-fixes'
[sod] / src / class-output.lisp
index a975ebe..b2d1ec8 100644 (file)
   ;; We need each message's method entry type for this, so we need to dig it
   ;; out of the vtmsgs structure.  Indeed, the vtmsgs for this class contains
   ;; entries for precisely the messages we want to make macros for.
+  (when (some #'varargs-message-p (sod-class-messages class))
+    (one-off-output 'varargs-macros sequencer :early-decls
+                   (lambda (stream)
+                     (format stream
+                             "~%SOD__VARARGS_MACROS_PREAMBLE~%"))))
   (when (sod-class-messages class)
     (sequence-output (stream sequencer)
       ((class :message-macros)
                        (push name in-names)
                        (push name out-names)))))
             (when varargsp
-              (format stream "#if __STDC_VERSION__ >= 199901~%"))
+              (format stream "#ifdef SOD__HAVE_VARARGS_MACROS~%"))
             (format stream "#define ~A(~{~A~^, ~}) ~
                                   ~A->_vt->~A.~A(~{~A~^, ~})~%"
                     (message-macro-name class entry)
                              (reason (eql :h))
                              sequencer)
   (with-slots ((class %class) chain-head chain-tail) vtptr
-    (sequence-output (stream sequencer)
-      ((class :ichain chain-head :slots)
-       (format stream "  const struct ~A *_vt;~%"
-              (vtable-struct-tag chain-tail chain-head))))))
+    (when (eq class chain-tail)
+      (sequence-output (stream sequencer)
+       ((class :ichain chain-head :slots)
+        (format stream "  const struct ~A *_vt;~%"
+                (vtable-struct-tag chain-tail chain-head)))))))
 
 (defmethod hook-output progn ((islots islots) (reason (eql :h)) sequencer)
   (with-slots ((class %class) subclass slots) islots
-    (sequence-output (stream sequencer)
-      ((subclass :ichain (sod-class-chain-head class) :slots)
-       (format stream "  struct ~A ~A;~%"
-              (islots-struct-tag class)
-              (sod-class-nickname class))))))
+    (let ((head (sod-class-chain-head class)))
+      (when (eq head (sod-class-chain-head subclass))
+       (sequence-output (stream sequencer)
+         ((subclass :ichain (sod-class-chain-head class) :slots)
+          (format stream "  struct ~A ~A;~%"
+                  (islots-struct-tag class)
+                  (sod-class-nickname class))))))))
 
 ;;;--------------------------------------------------------------------------
 ;;; Vtable structure.
 
 (defmethod hook-output progn ((vtmsgs vtmsgs) (reason (eql :h)) sequencer)
   (with-slots ((class %class) subclass chain-head chain-tail) vtmsgs
-    (sequence-output (stream sequencer)
-      ((subclass :vtable chain-head :slots)
-       (format stream "  struct ~A ~A;~%"
-              (vtmsgs-struct-tag subclass class)
-              (sod-class-nickname class))))))
+    (when (eq subclass chain-tail)
+      (sequence-output (stream sequencer)
+       ((subclass :vtable chain-head :slots)
+        (format stream "  struct ~A ~A;~%"
+                (vtmsgs-struct-tag subclass class)
+                (sod-class-nickname class)))))))
 
 (defmethod hook-output progn
     ((vtmsgs vtmsgs) (reason (eql 'vtmsgs)) sequencer)
 (defmethod hook-output progn
     ((cptr class-pointer) (reason (eql :h)) sequencer)
   (with-slots ((class %class) chain-head metaclass meta-chain-head) cptr
-    (sequence-output (stream sequencer)
-      ((class :vtable chain-head :slots)
-       (format stream "  const ~A *~:[_class~;~:*_cls_~A~];~%"
-              metaclass
-              (and (sod-class-direct-superclasses meta-chain-head)
-                   (sod-class-nickname meta-chain-head)))))))
+    (when (eq chain-head (sod-class-chain-head class))
+      (sequence-output (stream sequencer)
+       ((class :vtable chain-head :slots)
+        (format stream "  const ~A *~:[_class~;~:*_cls_~A~];~%"
+                metaclass
+                (and (sod-class-direct-superclasses meta-chain-head)
+                     (sod-class-nickname meta-chain-head))))))))
 
 (defmethod hook-output progn ((boff base-offset) (reason (eql :h)) sequencer)
   (with-slots ((class %class) chain-head) boff
-    (sequence-output (stream sequencer)
-      ((class :vtable chain-head :slots)
-       (write-line "  size_t _base;" stream)))))
+    (when (eq chain-head (sod-class-chain-head class))
+      (sequence-output (stream sequencer)
+       ((class :vtable chain-head :slots)
+        (write-line "  size_t _base;" stream))))))
 
 (defmethod hook-output progn
     ((choff chain-offset) (reason (eql :h)) sequencer)
   (with-slots ((class %class) chain-head target-head) choff
-    (sequence-output (stream sequencer)
-      ((class :vtable chain-head :slots)
-       (format stream "  ptrdiff_t _off_~A;~%"
-              (sod-class-nickname target-head))))))
+    (when (eq chain-head (sod-class-chain-head class))
+      (sequence-output (stream sequencer)
+       ((class :vtable chain-head :slots)
+        (format stream "  ptrdiff_t _off_~A;~%"
+                (sod-class-nickname target-head)))))))
 
 ;;;--------------------------------------------------------------------------
 ;;; Implementation output.