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 (push (cons quality raw-value
)
57 ;; Add any nonredundant entries from old POLICY.
58 (dolist (old-entry policy
)
59 (unless (assq (car old-entry
) result
)
60 (push old-entry result
)))
64 ;;; ANSI defines the declaration (FOO X Y) to be equivalent to
65 ;;; (TYPE FOO X Y) when FOO is a type specifier. This function
66 ;;; implements that by converting (FOO X Y) to (TYPE FOO X Y).
67 (defun canonized-decl-spec (decl-spec)
68 (let ((id (first decl-spec
)))
70 (error "The declaration identifier is not a symbol: ~S" id
))
71 (let ((id-is-type (info :type
:kind id
))
72 (id-is-declared-decl (info :declaration
:recognized id
)))
73 (cond ((and id-is-type id-is-declared-decl
)
75 "ambiguous declaration ~S:~% ~
76 ~S was declared as a DECLARATION, but is also a type name."
79 (cons 'type decl-spec
))
83 (defun sb!xc
:proclaim
(raw-form)
84 #+sb-xc
(/show0
"entering PROCLAIM, RAW-FORM=..")
85 #+sb-xc
(/hexstr raw-form
)
86 (let* ((form (canonized-decl-spec raw-form
))
92 (unless (symbolp name
)
93 (error "can't declare a non-symbol as SPECIAL: ~S" name
))
94 (when (constantp name
)
95 (error "can't declare a constant as SPECIAL: ~S" name
))
96 (clear-info :variable
:constant-value name
)
97 (setf (info :variable
:kind name
) :special
)))
99 (when *type-system-initialized
*
100 (let ((type (specifier-type (first args
))))
101 (dolist (name (rest args
))
102 (unless (symbolp name
)
103 (error "can't declare TYPE of a non-symbol: ~S" name
))
104 (when (eq (info :variable
:where-from name
) :declared
)
105 (let ((old-type (info :variable
:type name
)))
106 (when (type/= type old-type
)
107 (style-warn "The new TYPE proclamation~% ~S~@
108 for ~S does not match the old TYPE~@
110 type name old-type
))))
111 (setf (info :variable
:type name
) type
)
112 (setf (info :variable
:where-from name
) :declared
)))))
114 ;; FIXME: Since currently *TYPE-SYSTEM-INITIALIZED* is not set
115 ;; until many toplevel forms have run, this condition on
116 ;; PROCLAIM (FTYPE ..) (and on PROCLAIM (TYPE ..), above) means
117 ;; that valid PROCLAIMs in cold code could get lost. Probably
118 ;; the cleanest way to deal with this would be to initialize
119 ;; the type system completely in special cold init forms,
120 ;; before any ordinary toplevel forms run. Failing that, we
121 ;; could queue up PROCLAIMs to be done after the type system is
122 ;; initialized. Failing that, we could at least issue a warning
123 ;; when we have to ignore a PROCLAIM because the type system is
125 (when *type-system-initialized
*
126 (let ((ctype (specifier-type (first args
))))
127 (unless (csubtypep ctype
(specifier-type 'function
))
128 (error "not a function type: ~S" (first args
)))
129 (dolist (name (rest args
))
131 ;; KLUDGE: Something like the commented-out TYPE/=
132 ;; check here would be nice, but it has been
133 ;; commented out because TYPE/= doesn't support
134 ;; function types. It could probably be made to do
135 ;; so, but it might take some time, since function
136 ;; types involve values types, which aren't
137 ;; supported, and since the SUBTYPEP operator for
138 ;; FUNCTION types is rather broken, e.g.
139 ;; (SUBTYPEP '(FUNCTION (T BOOLEAN) NIL)
140 ;; '(FUNCTION (FIXNUM FIXNUM) NIL)) => T, T
143 (when (eq (info :function
:where-from name
) :declared
)
144 (let ((old-type (info :function
:type name
)))
145 (when (type/= ctype old-type
)
147 "new FTYPE proclamation~@
149 for ~S does not match old FTYPE proclamation~@
151 (list ctype name old-type
)))))
154 ;; Now references to this function shouldn't be warned
155 ;; about as undefined, since even if we haven't seen a
156 ;; definition yet, we know one is planned.
158 ;; Other consequences of we-know-you're-a-function-now
159 ;; are appropriate too, e.g. any MACRO-FUNCTION goes away.
160 (proclaim-as-fun-name name
)
161 (note-name-defined name
:function
)
163 ;; the actual type declaration
164 (setf (info :function
:type name
) ctype
165 (info :function
:where-from name
) :declared
)))))
168 (let ((class (specifier-type type
)))
169 (when (typep class
'sb
!xc
:class
)
170 (setf (class-state class
) :sealed
)
171 (let ((subclasses (class-subclasses class
)))
173 (dohash (subclass layout subclasses
)
174 (declare (ignore layout
))
175 (setf (class-state subclass
) :sealed
))))))))
177 (setq *policy
* (process-optimize-decl form
*policy
*)))
178 ((inline notinline maybe-inline
)
180 (proclaim-as-fun-name name
) ; since implicitly it is a function
181 (setf (info :function
:inlinep name
)
184 (notinline :notinline
)
185 (maybe-inline :maybe-inline
)))))
188 (unless (symbolp decl
)
189 (error "In~% ~S~%the declaration to be recognized is not a ~
192 (setf (info :declaration
:recognized decl
) t
)))
194 (unless (info :declaration
:recognized kind
)
195 (compiler-warn "unrecognized declaration ~S" raw-form
)))))
196 #+sb-xc
(/show0
"returning from PROCLAIM")