;;;; This software is part of the SBCL system. See the README file for
;;;; more information.
;;;;
;;;; This software is derived from the CMU CL system, which was
;;;; written at Carnegie Mellon University and released into the
;;;; public domain. The software is in the public domain and is
;;;; provided with absolutely no warranty. See the COPYING and CREDITS
;;;; files for more information.
(in-package "SB-KERNEL")
(defun call-with-defining-class (kind name thunk)
(declare (ignorable kind name))
(with-single-package-locked-error
(:symbol name "defining ~S as a ~(~A~)" kind)
(funcall thunk)))
(defun preinform-compiler-about-class-type (name forthcoming-info)
;; Unless the type system already has an actual type attached to
;; NAME (in which case (1) writing a placeholder value over that
;; actual type as a compile-time side-effect would probably be a bad
;; idea and (2) anyway we don't need to modify it in order to make
;; NAME be recognized as a valid type name)
(when (and forthcoming-info (not (info :type :kind name)))
;; Tell the compiler to expect a class with the given NAME, by
;; writing a kind of minimal placeholder type information. This
;; placeholder will be overwritten later when the class is
;; defined.
(setf (info :type :kind name) :forthcoming-defclass-type)))
(symbol-macrolet
((reader-function-type (specifier-type '(function (t) t)))
(writer-function-type (specifier-type '(function (t t) t))))
(flet ((proclaim-ftype-for-name (kind name type)
(ecase kind
(condition
(proclaim `(ftype ,(type-specifier type) ,name)))
(class
(when (eq (info :function :where-from name) :assumed)
(sb-c:proclaim-ftype name type nil :defined))))))
(defun preinform-compiler-about-accessors (kind readers writers)
(flet ((inform (names type)
(mapc (lambda (name) (proclaim-ftype-for-name kind name type))
names)))
(inform readers reader-function-type)
(inform writers writer-function-type)))
(defun preinform-compiler-about-slot-functions (kind slots)
(flet ((inform (slots key type)
(mapc (lambda (slot)
(let ((name (funcall key slot)))
(proclaim-ftype-for-name kind name type)))
slots)))
(inform slots #'sb-pcl::slot-reader-name reader-function-type)
(inform slots #'sb-pcl::slot-boundp-name reader-function-type)
(inform slots #'sb-pcl::slot-writer-name writer-function-type)))))
(defun %%compiler-defclass (name readers writers slots)
;; ANSI says (Macro DEFCLASS, section 7.7) that DEFCLASS, if it
;; "appears as a top level form, the compiler must make the class
;; name be recognized as a valid type name in subsequent
;; declarations (as for deftype) and be recognized as a valid class
;; name for defmethod parameter specializers and for use as the
;; :metaclass option of a subsequent defclass."
(preinform-compiler-about-class-type name t)
(preinform-compiler-about-accessors 'class readers writers)
(preinform-compiler-about-slot-functions 'class slots))
(defun %compiler-defclass (name readers writers slots)
(call-with-defining-class
'class name
(lambda ()
(%%compiler-defclass name readers writers slots))))