Hush some globaldb noise when building the cross-compiler.
[sbcl.git] / src / compiler / defconstant.lisp
blob162619cb0cfa8f015f1834b21d9d9bec06501ad5
1 ;;;; This software is part of the SBCL system. See the README file for
2 ;;;; more information.
3 ;;;;
4 ;;;; This software is derived from the CMU CL system, which was
5 ;;;; written at Carnegie Mellon University and released into the
6 ;;;; public domain. The software is in the public domain and is
7 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
8 ;;;; files for more information.
10 (in-package "SB!IMPL")
12 ;;; We need a mechanism different from the usual SYMBOL-VALUE during cross-
13 ;;; compilation so we don't clobber the host Lisp's manifest constants.
14 ;;; This was formerly done using the globaldb, so emulate exactly the
15 ;;; calls to UNCROSS in (SETF INFO) and INFO because that works just fine.
16 ;;; Also, as noted in 'constantp.lisp'
17 ;;; "KLUDGE: superficially, this might look good enough..."
18 ;;; we should enforce that we not wrongly look at a host constant where
19 ;;; a target constant is intended. This specialized accessor, in lieu of INFO
20 ;;; facilitates implementing something like that, though in fact ir1tran is
21 ;;; already able to generate some warnings about host constant usage.
22 #+sb-xc-host
23 (progn
24 (defun (setf sb!c::xc-constant-value) (newval sym)
25 (setf (get (uncross sym) :sb-xc-constant-val) newval))
26 (defun sb!c::xc-constant-value (sym) ; return 2 values as does (INFO ...)
27 (multiple-value-bind (indicator value foundp)
28 (get-properties (symbol-plist (uncross sym)) '(:sb-xc-constant-val))
29 (declare (ignore indicator))
30 (values value (not (null foundp))))))
32 (def!macro sb!xc:defconstant (name value &optional (doc nil docp))
33 #!+sb-doc
34 "Define a global constant, saying that the value is constant and may be
35 compiled into code. If the variable already has a value, and this is not
36 EQL to the new value, the code is not portable (undefined behavior). The
37 third argument is an optional documentation string for the variable."
38 `(eval-when (:compile-toplevel :load-toplevel :execute)
39 (sb!c::%defconstant ',name ,value (sb!c:source-location)
40 ,@(and docp
41 `(,doc)))))
43 (declaim (ftype (function (symbol t &optional t t) (values null &optional))
44 about-to-modify-symbol-value))
45 ;;; the guts of DEFCONSTANT
46 (defun sb!c::%defconstant (name value source-location &optional (doc nil docp))
47 #+sb-xc-host (declare (ignore doc docp))
48 (unless (symbolp name)
49 (error "The constant name is not a symbol: ~S" name))
50 (when (looks-like-name-of-special-var-p name)
51 (style-warn 'asterisks-around-constant-variable-name
52 :format-control "defining ~S as a constant"
53 :format-arguments (list name)))
54 (sb!c:with-source-location (source-location)
55 (setf (info :source-location :constant name) source-location))
56 (let ((kind (info :variable :kind name)))
57 (case kind
58 (:constant
59 ;; Note: This behavior (discouraging any non-EQL modification)
60 ;; is unpopular, but it is specified by ANSI (i.e. ANSI says a
61 ;; non-EQL change has undefined consequences). If people really
62 ;; want bindings which are constant in some sense other than
63 ;; EQL, I suggest either just using DEFVAR (which is usually
64 ;; appropriate, despite the un-mnemonic name), or defining
65 ;; something like the DEFCONSTANT-EQX macro used in SBCL (which
66 ;; is occasionally more appropriate). -- WHN 2001-12-21
67 (if (boundp name)
68 (if (typep name '(or boolean keyword))
69 ;; Non-continuable error.
70 (about-to-modify-symbol-value name 'defconstant)
71 (let ((old (symbol-value name)))
72 (unless (eql value old)
73 (multiple-value-bind (ignore aborted)
74 (with-simple-restart (abort "Keep the old value.")
75 (cerror "Go ahead and change the value."
76 'defconstant-uneql
77 :name name
78 :old-value old
79 :new-value value))
80 (declare (ignore ignore))
81 (when aborted
82 (return-from sb!c::%defconstant name))))))
83 (warn "redefining a MAKUNBOUND constant: ~S" name)))
84 (:unknown
85 ;; (This is OK -- undefined variables are of this kind. So we
86 ;; don't warn or error or anything, just fall through.)
88 (t (warn "redefining ~(~A~) ~S to be a constant" kind name))))
89 ;; We ought to be consistent in treating any change of :VARIABLE :KIND
90 ;; as a continuable error. The above CASE expression pre-dates the
91 ;; existence of symbol-macros (I believe), but at a bare minimum,
92 ;; INFO should return NIL for its second value if requesting the
93 ;; :macro-expansion of something that is getting defined as constant.
94 (clear-info :variable :macro-expansion name)
95 (clear-info :source-location :symbol-macro name)
96 #-sb-xc-host
97 (progn
98 (when docp
99 (setf (fdocumentation name 'variable) doc))
100 (%set-symbol-value name value))
101 #+sb-xc-host
102 (progn
103 ;; Redefining our cross-compilation host's CL symbols would be poor form.
105 ;; FIXME: Having to check this and then not treat it as a fatal error
106 ;; seems like a symptom of things being pretty broken. It's also a problem
107 ;; in and of itself, since it makes it too easy for cases of using the
108 ;; cross-compilation host Lisp's CL constant values in the target Lisp to
109 ;; slip by. I got backed into this because the cross-compiler translates
110 ;; DEFCONSTANT SB!XC:FOO into DEFCONSTANT CL:FOO. It would be good to
111 ;; unscrew the cross-compilation package hacks so that that translation
112 ;; doesn't happen. Perhaps: * Replace SB-XC with SB-CL. SB-CL exports all
113 ;; the symbols which ANSI requires to be exported from CL. * Make a
114 ;; nickname SB!CL which behaves like SB!XC. * Go through the
115 ;; loaded-on-the-host code making every target definition be in SB-CL.
116 ;; E.g. DEFMACRO-MUNDANELY DEFCONSTANT becomes DEFMACRO-MUNDANELY
117 ;; SB!CL:DEFCONSTANT. * Make IN-TARGET-COMPILATION-MODE do UNUSE-PACKAGE
118 ;; CL and USE-PACKAGE SB-CL in each of the target packages (then undo it
119 ;; on exit). * Make the cross-compiler's implementation of EVAL-WHEN
120 ;; (:COMPILE-TOPLEVEL) do UNCROSS. (This may not require any change.) *
121 ;; Hack GENESIS as necessary so that it outputs SB-CL stuff as COMMON-LISP
122 ;; stuff. * Now the code here can assert that the symbol being defined
123 ;; isn't in the cross-compilation host's CL package.
124 (unless (eql (find-symbol (symbol-name name) :cl) name)
125 ;; KLUDGE: In the cross-compiler, we use the cross-compilation host's
126 ;; DEFCONSTANT macro instead of just (SETF SYMBOL-VALUE), in order to
127 ;; get whatever blessing the cross-compilation host may expect for a
128 ;; global (SETF SYMBOL-VALUE). (CMU CL, at least around 2.4.19,
129 ;; generated full WARNINGs for code -- e.g. DEFTYPE expanders -- which
130 ;; referred to symbols which had been set by (SETF SYMBOL-VALUE). I
131 ;; doubt such warnings are ANSI-compliant, but I'm not sure, so I've
132 ;; written this in a way that CMU CL will tolerate and which ought to
133 ;; work elsewhere too.) -- WHN 2001-03-24
134 (eval `(defconstant ,name ',value)))
135 ;; It would certainly be awesome if this was only needed for symbols
136 ;; in CL. Unfortunately, that is not the case. Maybe some are moved
137 ;; back in CL later on?
138 (setf (sb!c::xc-constant-value name) value))
139 (setf (info :variable :kind name) :constant)
140 name)