1 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; The software is in the public domain and is provided with
5 ;;;; absolutely no warranty. See the COPYING and CREDITS files for
8 (defpackage :sb-cltl2-tests
9 (:use :sb-cltl2 :cl :sb-rt :sb-ext :sb-kernel :sb-int))
11 (in-package :sb-cltl2-tests)
15 (defmacro *x*-value ()
16 (declare (special *x*))
19 (deftest compiler-let.1
21 (compiler-let ((*x* :inner))
22 (list *x* (*x*-value))))
25 (defvar *expansions* nil)
26 (defmacro macroexpand-macro (arg)
27 (push arg *expansions*)
30 (deftest macroexpand-all.1
32 (macroexpand-all '(defmethod foo ((x fixnum)) (1+ x)))
36 (deftest macroexpand-all.2
37 (let ((*expansions* nil))
38 (macroexpand-all '(list (macroexpand-macro 1)
39 (let (macroexpand-macro :no)
40 (macroexpand-macro 2))))
41 (remove-duplicates (sort *expansions* #'<)))
44 (deftest macroexpand-all.3
45 (let ((*expansions* nil))
46 (compile nil '(lambda ()
47 (macrolet ((foo (key &environment env)
48 (macroexpand-all `(bar ,key) env)))
51 (push key *expansions*)
54 (remove-duplicates *expansions*))
58 (multiple-value-bind (expansion macro-p)
59 (macroexpand 'srlt env)
60 (when macro-p (eval expansion))))
61 (defmacro testr (&environment env)
62 `',(getf (smv env) nil))
64 (deftest macroexpand-all.4
65 (macroexpand-all '(symbol-macrolet ((srlt '(nil zool))) (testr)))
66 (symbol-macrolet ((srlt '(nil zool))) 'zool))
68 ;;;; DECLARATION-INFORMATION
70 (defmacro dinfo (thing &environment env)
71 `',(declaration-information thing env))
74 `(macrolet ((frob (suffix answer &optional declaration)
75 `(deftest ,(intern (concatenate 'string
76 "DECLARATION-INFORMATION."
79 (locally (declare ,@(when declaration
81 (cadr (assoc ',',x (dinfo optimize))))
84 (frob ".0" 0 (optimize (,x 0)))
85 (frob ".1" 1 (optimize (,x 1)))
86 (frob ".2" 2 (optimize (,x 2)))
87 (frob ".3" 3 (optimize (,x 3)))
88 (frob ".IMPLICIT" 3 (optimize ,x)))))
92 (def compilation-speed)
96 (deftest declaration-information.restrict-compiler-policy.1
97 (with-compilation-unit (:policy '(optimize) :override t)
98 (restrict-compiler-policy 'speed 3)
99 (eval '(cadr (assoc 'speed (dinfo optimize)))))
102 (deftest declaration-information.restrict-compiler-policy.2
103 (with-compilation-unit (:policy '(optimize) :override t)
104 (restrict-compiler-policy 'speed 3)
105 (locally (declare (optimize (speed 2)))
106 (cadr (assoc 'speed (dinfo optimize)))))
109 (deftest declaration-information.restrict-compiler-policy.3
110 (locally (declare (optimize (speed 2)))
111 (with-compilation-unit (:policy '(optimize) :override t)
112 (restrict-compiler-policy 'speed 3)
113 (cadr (assoc 'speed (dinfo optimize)))))
116 (deftest declaration-information.muffle-conditions.default
117 (dinfo sb-ext:muffle-conditions)
119 (deftest declaration-information.muffle-conditions.1
120 (locally (declare (sb-ext:muffle-conditions warning))
121 (dinfo sb-ext:muffle-conditions))
123 (deftest declaration-information.muffle-conditions.2
124 (let ((junk (dinfo sb-ext:muffle-conditions)))
125 (declare (sb-ext:muffle-conditions warning))
126 (locally (declare (sb-ext:unmuffle-conditions style-warning))
127 (let ((dinfo (dinfo sb-ext:muffle-conditions)))
130 (and (subtypep dinfo `(or (and warning (not style-warning))
131 (and ,junk (not style-warning))))
132 (subtypep '(and warning (not style-warning)) dinfo)))))))
136 (declaim (declaration fubar))
138 (deftest declaration-information.declaration
139 (if (member 'fubar (declaration-information 'declaration)) 'yay)
142 ;;;; VARIABLE-INFORMATION
146 (defmacro var-info (var &environment env)
147 (list 'quote (multiple-value-list (variable-information var env))))
149 (deftest variable-info.global-special/unbound
153 (deftest variable-info.global-special/unbound/extra-decl
154 (locally (declare (special *foo*))
158 (deftest variable-info.global-special/bound
163 (deftest variable-info.global-special/bound/extra-decl
165 (declare (special *foo*))
169 (deftest variable-info.local-special/unbound
170 (locally (declare (special x))
174 (deftest variable-info.local-special/bound
176 (declare (special x))
180 (deftest variable-info.local-special/shadowed
182 (declare (special x))
189 (deftest variable-info.local-special/shadows-lexical
192 (declare (special x))
196 (deftest variable-info.lexical
201 (deftest variable-info.lexical.type
205 (:lexical t ((type . fixnum))))
207 (deftest variable-info.lexical.type.2
211 (locally (declare (fixnum x))
212 (assert (plusp x)))))
215 (deftest variable-info.lexical.type.3
217 (locally (declare (fixnum x))
219 (:lexical t ((type . fixnum))))
221 (deftest variable-info.ignore
225 (:lexical t ((ignore . t))))
227 (deftest variable-info.symbol-macro/local
228 (symbol-macrolet ((x 8))
230 (:symbol-macro t nil))
232 (define-symbol-macro my-symbol-macro t)
234 (deftest variable-info.symbol-macro/global
235 (var-info my-symbol-macro)
236 (:symbol-macro nil nil))
238 (deftest variable-info.undefined
239 (var-info #:undefined)
242 (declaim (global this-is-global))
243 (deftest global-variable
244 (var-info this-is-global)
247 (defglobal this-is-global-too 42)
248 (deftest global-variable.2
249 (var-info this-is-global-too)
250 (:global nil ((always-bound . t))))
252 (sb-alien:define-alien-variable "errno" sb-alien:int)
253 (deftest alien-variable
257 ;;;; FUNCTION-INFORMATION
259 (defmacro fun-info (var &environment env)
260 (list 'quote (multiple-value-list (function-information var env))))
262 (defun my-global-fun (x) x)
264 (deftest function-info.global/no-ftype
265 (fun-info my-global-fun)
268 (declaim (ftype (function (cons) (values t &optional)) my-global-fun-2))
270 (defun my-global-fun-2 (x) x)
272 (deftest function-info.global/ftype
273 (fun-info my-global-fun-2)
274 (:function nil ((ftype function (cons) (values t &optional)))))
276 (defmacro my-macro (x) x)
278 (deftest function-info.macro
282 (deftest function-info.macrolet
283 (macrolet ((thingy () nil))
287 (deftest function-info.special-form
289 (:special-form nil nil))
291 (deftest function-info.notinline/local
293 (declare (notinline x))
296 (:function t ((inline . notinline))))
298 (declaim (notinline my-notinline))
299 (defun my-notinline (x) x)
301 (deftest function-info.notinline/global
302 (fun-info my-notinline)
303 (:function nil ((inline . notinline))))
305 (declaim (inline my-inline))
306 (defun my-inline (x) x)
308 (deftest function-info.inline/global
310 (:function nil ((inline . inline))))
312 (deftest function-information.known-inline
313 (locally (declare (inline identity))
315 (:function nil ((inline . inline)
316 (ftype function (t) (values t &optional)))))
318 (deftest function-information.ftype
320 (declare (ftype (sfunction (integer) integer) foo))
324 ((ftype function (integer) (values integer &optional)))))
326 ;;;;; AUGMENT-ENVIRONMENT
328 (defmacro ct (form &environment env)
329 (let ((toeval `(let ((lexenv (quote ,env)))
331 `(quote ,(eval toeval))))
334 (deftest augment-environment.variable1
335 (multiple-value-bind (kind local alist)
336 (variable-information
338 (augment-environment nil :variable (list 'x) :declare '((type integer x))))
339 (list kind local (cdr (assoc 'type alist))))
340 (:lexical t integer))
344 (deftest augment-environment.variable2
345 (identity (variable-information '*foo* (augment-environment nil :variable '(*foo*))))
348 (deftest augment-environment.variable3
349 (identity (variable-information 'foo (augment-environment nil :variable '(foo))))
352 (deftest augment-environment.variable.special1
353 (identity (variable-information 'x (augment-environment nil :variable '(x) :declare '((special x)))))
356 (deftest augment-environment.variable.special12
357 (locally (declare (special x))
359 (variable-information
361 (identity (augment-environment lexenv :variable '(x))))))
364 (deftest augment-environment.variable.special13
365 (let* ((e1 (augment-environment nil :variable '(x) :declare '((special x))))
366 (e2 (augment-environment e1 :variable '(x))))
367 (identity (variable-information 'x e2)))
370 (deftest augment-environment.variable.special.mask
371 (let* ((e1 (augment-environment nil :variable '(x) :declare '((ignore x))))
372 (e2 (augment-environment e1 :variable '(x))))
374 (nth 2 (multiple-value-list
375 (variable-information 'x e2)))))
378 (deftest augment-environment.variable.ignore
379 (variable-information
381 (augment-environment nil
383 :declare '((ignore x))))
388 (deftest augment-environment.function
389 (function-information
391 (augment-environment nil
393 :declare '((ftype (sfunction (integer) integer) foo))))
396 ((ftype function (integer) (values integer &optional))))
399 (deftest augment-environment.macro
400 (macroexpand '(mac feh)
403 :macro (list (list 'mac #'(lambda (form benv)
404 (declare (ignore env))
405 `(quote ,form ,form ,form))))))
406 (quote (mac feh) (mac feh) (mac feh))
409 (deftest augment-environment.symbol-macro
413 :symbol-macro (list (list 'sym '(foo bar baz)))))
417 (deftest augment-environment.macro2
418 (eval (macroexpand '(newcond
421 (augment-environment nil :macro (list (list 'newcond (macro-function 'cond))))))
425 (deftest augment-environment.nest
428 (let* ((e (augment-environment lexenv :variable '(y))))
430 (variable-information 'x e)
431 (variable-information 'y e)))))
434 (deftest augment-environment.nest2
435 (symbol-macrolet ((x "x"))
437 (let* ((e (augment-environment lexenv :variable '(y))))
440 (variable-information 'y e)))))
443 (deftest augment-environment.symbol-macro-var
444 (let ((e (augment-environment
446 :symbol-macro (list (list 'sym '(foo bar baz)))
448 (list (macroexpand 'sym e)
449 (variable-information 'x e)))
455 ;;;;; DEFINE-DECLARATION
457 (defmacro third-value (form)
458 (sb-int::with-unique-names (a b c)
459 `(multiple-value-bind (,a ,b ,c) ,form
460 (declare (ignore ,a ,b))
463 (deftest define-declaration.declare
465 (define-declaration zaphod (spec env)
466 (declare (ignore env))
467 (values :declare (cons 'zaphod spec)))
468 (locally (declare (zaphod beblebrox))
469 (locally (declare (zaphod and ford))
470 (ct (declaration-information 'zaphod lexenv)))))
474 (deftest define-declaration.declare2
476 (define-declaration zaphod (spec env)
477 (declare (ignore env))
478 (values :declare (cons 'zaphod spec)))
480 (declare (zaphod beblebrox)
482 (ct (declaration-information 'zaphod lexenv))))
485 (deftest define-declaration.variable
487 (define-declaration vogon (spec env)
488 (declare (ignore env))
489 (values :variable `((,(cadr spec) vogon-key vogon-value))))
490 (locally (declare (vogon poetry))
494 (variable-information
497 (vogon-key . vogon-value))
500 (deftest define-declaration.variable.special
502 (define-declaration vogon (spec env)
503 (declare (ignore env))
504 (values :variable `((,(cadr spec) vogon-key vogon-value))))
507 (declare (special x))
511 (variable-information 'x lexenv))))))
512 (vogon-key . vogon-value))
514 (deftest define-declaration.variable.special2
516 (define-declaration vogon (spec env)
517 (declare (ignore env))
518 (values :variable `((,(cadr spec) vogon-key vogon-value))))
520 (declare (special x))
525 (variable-information 'x lexenv))))))
526 (vogon-key . vogon-value))
528 (deftest define-declaration.variable.mask
530 (define-declaration vogon (spec env)
531 (declare (ignore env))
532 (values :variable `((,(cadr spec) vogon-key vogon-value))))
539 (third (multiple-value-list (variable-information 'x lexenv))))))))
542 (deftest define-declaration.variable.macromask
544 (define-declaration vogon (spec env)
545 (declare (ignore env))
546 (values :variable `((,(cadr spec) vogon-key vogon-value))))
549 (symbol-macrolet ((x 42))
553 (third (multiple-value-list (variable-information 'x lexenv))))))))
556 (deftest define-declaration.variable.macromask2
558 (define-declaration vogon (spec env)
559 (declare (ignore env))
560 (values :variable `((,(cadr spec) vogon-key vogon-value))))
561 (symbol-macrolet ((x 42))
568 (third (multiple-value-list (variable-information 'x lexenv))))))
572 (third (multiple-value-list (variable-information 'x lexenv))))))))
573 (nil (vogon-key . vogon-value)))
575 (deftest define-declaration.variable.mask2
577 (define-declaration vogon-a (spec env)
578 (declare (ignore env))
579 (values :variable `((,(cadr spec) vogon-key a))))
580 (define-declaration vogon-b (spec env)
581 (declare (ignore env))
582 (values :variable `((,(cadr spec) vogon-key b))))
584 (declare (vogon-a x))
586 (declare (vogon-b x)))
590 (third (multiple-value-list (variable-information 'x lexenv)))))))
593 (deftest define-declaration.variable.specialmask
595 (define-declaration vogon (spec env)
596 (declare (ignore env))
597 (values :variable `((,(cadr spec) vogon-key vogon-value))))
599 (declare (vogon *foo*))
604 (third (multiple-value-list (variable-information '*foo* lexenv))))))))
605 (vogon-key . vogon-value))
609 (deftest define-declaration.function
611 (define-declaration sad (spec env)
612 (declare (ignore env))
613 (values :function `((,(cadr spec) emotional-state sad))))
614 (locally (declare (zaphod beblebrox))
615 (locally (declare (sad robot))
617 (assoc 'emotional-state
618 (third-value (function-information
621 (emotional-state . sad))
623 (deftest define-declaration.function.lexical
625 (define-declaration sad (spec env)
626 (declare (ignore env))
627 (values :function `((,(cadr spec) emotional-state sad))))
629 (locally (declare (sad robot))
631 (assoc 'emotional-state
632 (third-value (function-information
635 (emotional-state . sad))
638 (deftest define-declaration.function.lexical2
640 (define-declaration sad (spec env)
641 (declare (ignore env))
642 (values :function `((,(cadr spec) emotional-state sad))))
643 (labels ((robot nil))
644 (declare (sad robot))
646 (assoc 'emotional-state
647 (third-value (function-information
650 (emotional-state . sad))
652 (deftest define-declaration.function.mask
654 (define-declaration sad (spec env)
655 (declare (ignore env))
656 (values :function `((,(cadr spec) emotional-state sad))))
657 (labels ((robot nil))
658 (declare (sad robot))
659 (labels ((robot nil))
661 (assoc 'emotional-state
662 (third-value (function-information
668 (deftest define-declaration.function.mask2
670 (define-declaration sad (spec env)
671 (declare (ignore env))
672 (values :function `((,(cadr spec) emotional-state sad))))
674 (declare (sad robot))
675 (labels ((robot nil))
677 (assoc 'emotional-state
678 (third-value (function-information
683 (deftest define-declaration.function2
685 (define-declaration happy (spec env)
686 (declare (ignore env))
687 (values :function `((,(cadr spec) emotional-state happy))))
688 (locally (declare (zaphod beblebrox))
689 (locally (declare (sad robot))
690 (locally (declare (happy robot))
692 (assoc 'emotional-state
693 (third-value (function-information
696 (emotional-state . happy))
698 (deftest macroexpand-all.special-binding
699 (let ((form '(macrolet ((v (x &environment env)
700 (sb-cltl2:variable-information x env)))
703 (declare (special x))
706 (eval (sb-cltl2:macroexpand-all form))))
707 ((:special :special) (:special :special)))
709 (deftest macroexpand-all.symbol-macro-shadowed
710 (let ((form '(macrolet ((v (x &environment env)
711 (macroexpand x env)))
712 (symbol-macrolet ((x :bad))
717 (eval (sb-cltl2:macroexpand-all form))))