1 ;;;; This file contains load-time support for declaration processing.
2 ;;;; In CMU CL it was split off from the compiler so that the compiler
3 ;;;; doesn't have to be in the cold load, but in SBCL the compiler is
4 ;;;; in the cold load again, so this might not be valuable.
6 ;;;; This software is part of the SBCL system. See the README file for
9 ;;;; This software is derived from the CMU CL system, which was
10 ;;;; written at Carnegie Mellon University and released into the
11 ;;;; public domain. The software is in the public domain and is
12 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
13 ;;;; files for more information.
17 ;;; A list of UNDEFINED-WARNING structures representing references to unknown
18 ;;; stuff which came up in a compilation unit.
19 (defvar *undefined-warnings*)
20 (declaim (list *undefined-warnings*))
22 ;;; Check that NAME is a valid function name, returning the name if
23 ;;; OK, and doing an error if not. In addition to checking for basic
24 ;;; well-formedness, we also check that symbol names are not NIL or
25 ;;; the name of a special form.
26 (defun check-function-name (name)
29 (unless (and (consp name) (consp (cdr name))
30 (null (cddr name)) (eq (car name) 'setf)
31 (symbolp (cadr name)))
32 (compiler-error "illegal function name: ~S" name))
35 (when (eq (info :function :kind name) :special-form)
36 (compiler-error "Special form is an illegal function name: ~S" name))
39 (compiler-error "illegal function name: ~S" name))))
41 ;;; This is called to do something about SETF functions that overlap
42 ;;; with SETF macros. Perhaps we should interact with the user to see
43 ;;; whether the macro should be blown away, but for now just give a
44 ;;; warning. Due to the weak semantics of the (SETF FUNCTION) name, we
45 ;;; can't assume that they aren't just naming a function (SETF FOO)
46 ;;; for the heck of it. NAME is already known to be well-formed.
47 (defun note-if-setf-function-and-macro (name)
49 (when (or (info :setf :inverse name)
50 (info :setf :expander name))
51 (compiler-style-warning
52 "defining as a SETF function a name that already has a SETF macro:~
57 ;;; Look up some symbols in *FREE-VARIABLES*, returning the var
58 ;;; structures for any which exist. If any of the names aren't
59 ;;; symbols, we complain.
60 (declaim (ftype (function (list) list) get-old-vars))
61 (defun get-old-vars (names)
63 (dolist (name names (vars))
64 (unless (symbolp name)
65 (compiler-error "The name ~S is not a symbol." name))
66 (let ((old (gethash name *free-variables*)))
67 (when old (vars old))))))
69 ;;; Return a new POLICY containing the policy information represented
70 ;;; by the optimize declaration SPEC. Any parameters not specified are
71 ;;; defaulted from the POLICY argument.
72 (declaim (ftype (function (list policy) policy) process-optimize-decl))
73 (defun process-optimize-decl (spec policy)
75 ;; Add new entries from SPEC.
76 (dolist (q-and-v-or-just-q (cdr spec))
77 (multiple-value-bind (quality raw-value)
78 (if (atom q-and-v-or-just-q)
79 (values q-and-v-or-just-q 3)
80 (destructuring-bind (quality raw-value) q-and-v-or-just-q
81 (values quality raw-value)))
82 (cond ((not (policy-quality-name-p quality))
83 (compiler-warning "ignoring unknown optimization quality ~
86 ((not (and (typep raw-value 'real) (<= 0 raw-value 3)))
87 (compiler-warning "ignoring bad optimization value ~S in ~S"
90 (push (cons quality (rational raw-value))
92 ;; Add any nonredundant entries from old POLICY.
93 (dolist (old-entry policy)
94 (unless (assq (car old-entry) result)
95 (push old-entry result)))
99 ;;; ANSI defines the declaration (FOO X Y) to be equivalent to
100 ;;; (TYPE FOO X Y) when FOO is a type specifier. This function
101 ;;; implements that by converting (FOO X Y) to (TYPE FOO X Y).
102 (defun canonized-decl-spec (decl-spec)
103 (let ((id (first decl-spec)))
105 (error "The declaration identifier is not a symbol: ~S" id))
106 (let ((id-is-type (info :type :kind id))
107 (id-is-declared-decl (info :declaration :recognized id)))
108 (cond ((and id-is-type id-is-declared-decl)
110 "ambiguous declaration ~S:~% ~
111 ~S was declared as a DECLARATION, but is also a type name."
114 (cons 'type decl-spec))
118 (defun sb!xc:proclaim (raw-form)
119 (let* ((form (canonized-decl-spec raw-form))
125 (unless (symbolp name)
126 (error "can't declare a non-symbol as SPECIAL: ~S" name))
127 (when (constantp name)
128 (error "can't declare a constant as SPECIAL: ~S" name))
129 (clear-info :variable :constant-value name)
130 (setf (info :variable :kind name) :special)))
132 (when *type-system-initialized*
133 (let ((type (specifier-type (first args))))
134 (dolist (name (rest args))
135 (unless (symbolp name)
136 (error "can't declare TYPE of a non-symbol: ~S" name))
137 (when (eq (info :variable :where-from name) :declared)
138 (let ((old-type (info :variable :type name)))
139 (when (type/= type old-type)
140 (style-warn "The new TYPE proclamation~% ~S~@
141 for ~S does not match the old TYPE~@
143 type name old-type))))
144 (setf (info :variable :type name) type)
145 (setf (info :variable :where-from name) :declared)))))
147 ;; FIXME: Since currently *TYPE-SYSTEM-INITIALIZED* is not set
148 ;; until many toplevel forms have run, this condition on
149 ;; PROCLAIM (FTYPE ..) (and on PROCLAIM (TYPE ..), above) means
150 ;; that valid PROCLAIMs in cold code could get lost. Probably
151 ;; the cleanest way to deal with this would be to initialize
152 ;; the type system completely in special cold init forms,
153 ;; before any ordinary toplevel forms run. Failing that, we
154 ;; could queue up PROCLAIMs to be done after the type system is
155 ;; initialized. Failing that, we could at least issue a warning
156 ;; when we have to ignore a PROCLAIM because the type system is
158 (when *type-system-initialized*
159 (let ((type (specifier-type (first args))))
160 (unless (csubtypep type (specifier-type 'function))
161 (error "not a function type: ~S" (first args)))
162 (dolist (name (rest args))
163 (cond ((info :function :accessor-for name)
164 ;; FIXME: This used to be a WARNING, which was
165 ;; clearly wrong, since it would cause warnings to
166 ;; be issued for conforming code, which is really
167 ;; annoying for people who use Lisp code to build
168 ;; Lisp systems (and check the return values from
169 ;; COMPILE and COMPILE-FILE). Changing it to a
170 ;; compiler note is somewhat better, since it's
171 ;; after all news about a limitation of the
172 ;; compiler, not a problem in the code. But even
173 ;; better would be to handle FTYPE proclamations
174 ;; for slot accessors, and since in the long run
175 ;; slot accessors should become more like other
176 ;; functions, this should eventually become
179 "~@<ignoring FTYPE proclamation for ~
180 slot accessor (currently unsupported): ~2I~_~S~:>"
184 ;; KLUDGE: Something like the commented-out TYPE/=
185 ;; check here would be nice, but it has been
186 ;; commented out because TYPE/= doesn't support
187 ;; function types. It could probably be made to do
188 ;; so, but it might take some time, since function
189 ;; types involve values types, which aren't
190 ;; supported, and since the SUBTYPEP operator for
191 ;; FUNCTION types is rather broken, e.g.
192 ;; (SUBTYPEP '(FUNCTION (T BOOLEAN) NIL)
193 ;; '(FUNCTION (FIXNUM FIXNUM) NIL)) => T, T
196 (when (eq (info :function :where-from name) :declared)
197 (let ((old-type (info :function :type name)))
198 (when (type/= type old-type)
199 (style-warn "new FTYPE proclamation~@
201 for ~S does not match old FTYPE proclamation~@
203 (list type name old-type)))))
205 (proclaim-as-function-name name)
206 (note-name-defined name :function)
207 (setf (info :function :type name) type
208 (info :function :where-from name) :declared)))))))
211 (let ((class (specifier-type type)))
212 (when (typep class 'class)
213 (setf (class-state class) :sealed)
214 (let ((subclasses (class-subclasses class)))
216 (dohash (subclass layout subclasses)
217 (declare (ignore layout))
218 (setf (class-state subclass) :sealed))))))))
220 (setq *policy* (process-optimize-decl form *policy*)))
222 (setq *interface-policy*
223 (process-optimize-decl form *interface-policy*)))
224 ((inline notinline maybe-inline)
226 (proclaim-as-function-name name)
227 (setf (info :function :inlinep name)
230 (notinline :notinline)
231 (maybe-inline :maybe-inline)))))
234 (unless (symbolp decl)
235 (error "In~% ~S~%the declaration to be recognized is not a ~
238 (setf (info :declaration :recognized decl) t)))
240 (unless (info :declaration :recognized kind)
241 (compiler-warning "unrecognized declaration ~S" raw-form)))))