;; 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.