-;;; Ordinarily this definition of SB!C:%DEFMACRO as an ordinary
-;;; function is not used: the parallel (but different) definition as
-;;; an IR1 transform takes precedence. However, this definition is
-;;; still useful in the target interpreter, and in the
-;;; cross-compilation host.
-(defun sb!c::%defmacro (name definition lambda-list doc)
- (try-to-rename-interpreted-function-as-macro definition name lambda-list)
- (sb!c::%%defmacro name definition doc))
-
-;;; (called by SB!C::%DEFMACRO)
-(eval-when (:compile-toplevel :load-toplevel :execute)
- (defun sb!c::%%defmacro (name definition doc)
- ;; Old note (ca. 1985, maybe:-): "Eventually %%DEFMACRO should deal with
- ;; clearing old compiler information for the functional value."
- (clear-info :function :where-from name)
- ;; FIXME: It would be nice to warn about DEFMACRO of an
- ;; already-defined macro, but that's slightly hard to do because
- ;; in common usage DEFMACRO is defined at compile time and then
- ;; redefined at load time. We'd need to make a distinction between
- ;; the defined-at-compile-time state and the defined-at-load-time
- ;; state to make this work. (Trying to warn about duplicate DEFTYPEs
- ;; runs into the same problem.)
- #+nil (when (sb!xc:macro-function name)
- (style-warn "redefining ~S in DEFMACRO" name))
- (setf (sb!xc:macro-function name) definition
- (fdocumentation name 'function) doc)
- name))
+(macrolet
+ ((def (times set-p)
+ `(eval-when (,@times)
+ (defun sb!c::%defmacro (name definition lambda-list doc debug-name
+ source-location)
+ ;; old note (ca. 1985, maybe:-): "Eventually %%DEFMACRO
+ ;; should deal with clearing old compiler information for
+ ;; the functional value."
+ ,@(unless set-p
+ '((declare (ignore lambda-list debug-name doc))))
+ (let ((kind (info :function :kind name)))
+ ;; Check for special form before package locks.
+ (when (eq :special-form kind)
+ (error "The special operator ~S can't be redefined as a macro."
+ name))
+ (with-single-package-locked-error (:symbol name "defining ~S as a macro")
+ (when (eq :function kind)
+ (style-warn
+ "~S is being redefined as a macro when it was ~
+ previously ~(~A~) to be a function."
+ name (info :function :where-from name))
+ (undefine-fun-name name))
+ (clear-info :function :where-from name)
+ #-sb-xc-host
+ (when (fboundp name)
+ ;; Someday we could check for macro arguments
+ ;; being incompatibly redefined. Doing this right
+ ;; will involve finding the old macro lambda-list
+ ;; and comparing it with the new one.
+ (warn 'sb!kernel::redefinition-with-defmacro
+ :name name
+ :new-function definition
+ :new-location source-location))
+ (setf (sb!xc:macro-function name) definition)
+ ,(when set-p
+ `(setf (%fun-doc definition) doc
+ (%fun-lambda-list definition) lambda-list
+ (%fun-name definition) debug-name))))
+ name))))
+ (progn
+ (def (:load-toplevel :execute) #-sb-xc-host t #+sb-xc-host nil)
+ (def (#-sb-xc :compile-toplevel) nil)))