X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fdefmacro.lisp;h=92fbb48b1f08082410a79c04af52636cd42f2cf1;hb=82cd148d729c241e79c8df04b700beec1b7c55de;hp=aec98f0a63cb4b167569533b94f0cebe8c61c816;hpb=22b819c0cd0ca0ea5be52ba280b9e9e0b8e86210;p=sbcl.git diff --git a/src/code/defmacro.lisp b/src/code/defmacro.lisp index aec98f0..92fbb48 100644 --- a/src/code/defmacro.lisp +++ b/src/code/defmacro.lisp @@ -33,70 +33,64 @@ name)) (with-unique-names (whole environment) (multiple-value-bind (new-body local-decs doc) - (parse-defmacro lambda-list whole body name 'defmacro - :environment environment) - (let ((def `(lambda (,whole ,environment) - ,@local-decs - (block ,name - ,new-body))) - ;; if we want to move over to list-style names - ;; [e.g. (DEFMACRO FOO), maybe to support some XREF-like - ;; functionality] here might be a good place to start. - (debug-name (debug-namify "DEFMACRO ~S" name))) - `(eval-when (:compile-toplevel :load-toplevel :execute) - (sb!c::%defmacro ',name #',def ',lambda-list ,doc ,debug-name))))))) + (parse-defmacro lambda-list whole body name 'defmacro + :environment environment) + (let ((def `(#+sb-xc-host lambda + ;; Use a named-lambda rather than a lambda so that + ;; proper xref information can be stored. Use a + ;; list-based name, since otherwise the compiler + ;; will momentarily assume that it names a normal + ;; function, and report spurious warnings about + ;; redefinition a macro as a function, and then + ;; vice versa. + #-sb-xc-host named-lambda #-sb-xc-host (defmacro ,name) + (,whole ,environment) + ,@local-decs + ,new-body)) + (debug-name (sb!c::debug-name 'macro-function name))) + `(progn + (eval-when (:compile-toplevel :load-toplevel :execute) + (sb!c::%defmacro ',name #',def ',lambda-list ,doc ',debug-name + (sb!c:source-location))))))))) (macrolet ((def (times set-p) `(eval-when (,@times) - (defun sb!c::%defmacro (name definition lambda-list doc debug-name) + (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)))) - (ecase (info :function :kind name) - ((nil)) - (:function - ;; (remhash name *free-funs*) - (undefine-fun-name name) - (style-warn - "~S is being redefined as a macro when it was ~ - previously ~(~A~) to be a function." - name - (info :function :where-from name))) - (:macro) - (:special-form - (error "The special form ~S can't be redefined as a macro." - name))) - (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) - ;; 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. - (style-warn "redefining ~S in DEFMACRO" name)) - (setf (sb!xc:macro-function name) definition - (fdocumentation name 'function) doc) - ,(when set-p - `(case (widetag-of definition) - (#.sb!vm:closure-header-widetag - (setf (%simple-fun-arglist (%closure-fun definition)) - lambda-list - (%simple-fun-name (%closure-fun definition)) - debug-name)) - ((#.sb!vm:simple-fun-header-widetag - #.sb!vm:closure-fun-header-widetag) - (setf (%simple-fun-arglist definition) lambda-list - (%simple-fun-name definition) debug-name)))) + '((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)