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 ;;; Look up some symbols in *FREE-VARS*, returning the var
23 ;;; structures for any which exist. If any of the names aren't
24 ;;; symbols, we complain.
25 (declaim (ftype (function (list) list) get-old-vars))
26 (defun get-old-vars (names)
28 (dolist (name names (vars))
29 (unless (symbolp name)
30 (compiler-error "The name ~S is not a symbol." name))
31 (let ((old (gethash name *free-vars*)))
32 (when old (vars old))))))
34 ;;; Return a new POLICY containing the policy information represented
35 ;;; by the optimize declaration SPEC. Any parameters not specified are
36 ;;; defaulted from the POLICY argument.
37 (declaim (ftype (function (list policy) policy) process-optimize-decl))
38 (defun process-optimize-decl (spec policy)
40 ;; Add new entries from SPEC.
41 (dolist (q-and-v-or-just-q (cdr spec))
42 (multiple-value-bind (quality raw-value)
43 (if (atom q-and-v-or-just-q)
44 (values q-and-v-or-just-q 3)
45 (destructuring-bind (quality raw-value) q-and-v-or-just-q
46 (values quality raw-value)))
47 (cond ((not (policy-quality-name-p quality))
48 (compiler-warn "ignoring unknown optimization quality ~
51 ((not (typep raw-value 'policy-quality))
52 (compiler-warn "ignoring bad optimization value ~S in ~S"
55 ;; we can't do this yet, because CLOS macros expand
56 ;; into code containing INHIBIT-WARNINGS.
58 (when (eql quality 'sb!ext:inhibit-warnings)
59 (compiler-style-warn "~S is deprecated: use ~S instead"
60 quality 'sb!ext:muffle-conditions))
61 (push (cons quality raw-value)
63 ;; Add any nonredundant entries from old POLICY.
64 (dolist (old-entry policy)
65 (unless (assq (car old-entry) result)
66 (push old-entry result)))
70 (declaim (ftype (function (list list) list)
71 process-handle-conditions-decl))
72 (defun process-handle-conditions-decl (spec list)
73 (let ((new (copy-alist list)))
74 (dolist (clause (cdr spec))
75 (destructuring-bind (typespec restart-name) clause
76 (let ((ospec (rassoc restart-name new :test #'eq)))
80 (type-union (specifier-type (car ospec))
81 (specifier-type typespec))))
82 (push (cons (type-specifier (specifier-type typespec))
86 (declaim (ftype (function (list list) list)
87 process-muffle-conditions-decl))
88 (defun process-muffle-conditions-decl (spec list)
89 (process-handle-conditions-decl
90 (cons 'handle-conditions
91 (mapcar (lambda (x) (list x 'muffle-warning)) (cdr spec)))
94 (declaim (ftype (function (list list) list)
95 process-unhandle-conditions-decl))
96 (defun process-unhandle-conditions-decl (spec list)
97 (let ((new (copy-alist list)))
98 (dolist (clause (cdr spec))
99 (destructuring-bind (typespec restart-name) clause
100 (let ((ospec (rassoc restart-name new :test #'eq)))
102 (let ((type-specifier
105 (specifier-type (car ospec))
106 (specifier-type `(not ,typespec))))))
108 (setf (car ospec) type-specifier)
110 (delete restart-name new :test #'eq :key #'cdr))))
114 (declaim (ftype (function (list list) list)
115 process-unmuffle-conditions-decl))
116 (defun process-unmuffle-conditions-decl (spec list)
117 (process-unhandle-conditions-decl
118 (cons 'unhandle-conditions
119 (mapcar (lambda (x) (list x 'muffle-warning)) (cdr spec)))
122 ;;; ANSI defines the declaration (FOO X Y) to be equivalent to
123 ;;; (TYPE FOO X Y) when FOO is a type specifier. This function
124 ;;; implements that by converting (FOO X Y) to (TYPE FOO X Y).
125 (defun canonized-decl-spec (decl-spec)
126 (let ((id (first decl-spec)))
128 (error "The declaration identifier is not a symbol: ~S" id))
129 (let ((id-is-type (info :type :kind id))
130 (id-is-declared-decl (info :declaration :recognized id)))
131 (cond ((and id-is-type id-is-declared-decl)
133 "ambiguous declaration ~S:~% ~
134 ~S was declared as a DECLARATION, but is also a type name."
137 (cons 'type decl-spec))
141 (defvar *queued-proclaims*) ; initialized in !COLD-INIT-FORMS
143 (!begin-collecting-cold-init-forms)
144 (!cold-init-forms (setf *queued-proclaims* nil))
145 (!defun-from-collected-cold-init-forms !early-proclaim-cold-init)
147 (defun sb!xc:proclaim (raw-form)
148 #+sb-xc (/show0 "entering PROCLAIM, RAW-FORM=..")
149 #+sb-xc (/hexstr raw-form)
150 (let* ((form (canonized-decl-spec raw-form))
156 (unless (symbolp name)
157 (error "can't declare a non-symbol as SPECIAL: ~S" name))
158 (when (constantp name)
159 (error "can't declare a constant as SPECIAL: ~S" name))
160 (clear-info :variable :constant-value name)
161 (setf (info :variable :kind name) :special)))
163 (if *type-system-initialized*
164 (let ((type (specifier-type (first args))))
165 (dolist (name (rest args))
166 (unless (symbolp name)
167 (error "can't declare TYPE of a non-symbol: ~S" name))
168 (when (eq (info :variable :where-from name) :declared)
169 (let ((old-type (info :variable :type name)))
170 (when (type/= type old-type)
171 (style-warn "The new TYPE proclamation~% ~S~@
172 for ~S does not match the old TYPE~@
174 type name old-type))))
175 (setf (info :variable :type name) type)
176 (setf (info :variable :where-from name) :declared)))
177 (push raw-form *queued-proclaims*)))
179 (if *type-system-initialized*
180 (let ((ctype (specifier-type (first args))))
181 (unless (csubtypep ctype (specifier-type 'function))
182 (error "not a function type: ~S" (first args)))
183 (dolist (name (rest args))
184 (when (eq (info :function :where-from name) :declared)
185 (let ((old-type (info :function :type name)))
186 (when (type/= ctype old-type)
188 "new FTYPE proclamation~@
190 for ~S does not match old FTYPE proclamation~@
192 ctype name old-type))))
194 ;; Now references to this function shouldn't be warned
195 ;; about as undefined, since even if we haven't seen a
196 ;; definition yet, we know one is planned.
198 ;; Other consequences of we-know-you're-a-function-now
199 ;; are appropriate too, e.g. any MACRO-FUNCTION goes away.
200 (proclaim-as-fun-name name)
201 (note-name-defined name :function)
203 ;; the actual type declaration
204 (setf (info :function :type name) ctype
205 (info :function :where-from name) :declared)))
206 (push raw-form *queued-proclaims*)))
209 (let ((class (specifier-type type)))
210 (when (typep class 'classoid)
211 (setf (classoid-state class) :sealed)
212 (let ((subclasses (classoid-subclasses class)))
214 (dohash (subclass layout subclasses)
215 (declare (ignore layout))
216 (setf (classoid-state subclass) :sealed))))))))
218 (setq *policy* (process-optimize-decl form *policy*)))
220 (setq *handled-conditions*
221 (process-muffle-conditions-decl form *handled-conditions*)))
223 (setq *handled-conditions*
224 (process-unmuffle-conditions-decl form *handled-conditions*)))
225 ((inline notinline maybe-inline)
227 (proclaim-as-fun-name name) ; since implicitly it is a function
228 (setf (info :function :inlinep name)
231 (notinline :notinline)
232 (maybe-inline :maybe-inline)))))
235 (unless (symbolp decl)
236 (error "In~% ~S~%the declaration to be recognized is not a ~
239 (setf (info :declaration :recognized decl) t)))
241 (unless (info :declaration :recognized kind)
242 (compiler-warn "unrecognized declaration ~S" raw-form)))))
243 #+sb-xc (/show0 "returning from PROCLAIM")