Next: Limitations of the cross-referencing facility, Previous: Querying the cross-reference database, Up: Cross-Referencing Facility [Contents][Index]
In this section, we will illustrate use of the XREF facility on a number of simple examples.
Consider the following program fragment, that defines a global variable and a function.
(defvar *variable-one* 42) (defun function-one (x) (princ (* x *variable-one*)))
We save this code in a file named example.lisp
, enable
cross-referencing, clear any previous cross-reference information,
compile the file, and can then query the cross-reference database
(output has been modified for readability).
USER> (setf c:*record-xref-info* t) USER> (xref:init-xref-database) USER> (compile-file "example") USER> (xref:who-calls 'princ) (#<xref-context function-one in #p"example.lisp">) USER> (xref:who-references '*variable-one*) (#<xref-context function-one in #p"example.lisp">)
From this example, we see that the compiler has noted the call to the
global function princ
in function-one
, and the reference
to the global variable *variable-one*
.
Suppose that we add the following code to the previous file.
(defconstant +constant-one+ 1) (defstruct struct-one slot-one (slot-two +constant-one+ :type integer) (slot-three 42 :read-only t)) (defmacro with-different-one (&body body) `(let ((*variable-one* 666)) ,@body)) (defun get-variable-one () *variable-one*) (defun (setf get-variable-one) (new-value) (setq *variable-one* new-value))
In the following example, we detect references x and y.
% FIXME add function with LABELS, a binding, a set
The following function illustrates the effect that various forms of
optimization carried out by the CMUCL compiler can have on the
cross-references that are reported for a particular program. The
compiler is able to detect that the evaluated condition is always
false, and that the first clause of the if
will never be taken
(this optimization is called dead-code elimination). XREF will
therefore not register a call to the function sin
from the
function foo
. Likewise, no calls to the functions sqrt
and <
are registered, because the compiler has eliminated the
code that evaluates the condition. Finally, no call to the function
expt
is generated, because the compiler was able to evaluate
the result of the expression (expt 3 2)
at compile-time (though
a process called constant-folding).
;; zero call references are registered for this function! (defun constantly-nine (x) (if (< (sqrt x) 0) (sin x) (expt 3 2)))