Next: , Previous: , Up: Cross-Referencing Facility   [Contents][Index]


12.3 Example usage

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)))

Next: Limitations of the cross-referencing facility, Previous: Querying the cross-reference database, Up: Cross-Referencing Facility   [Contents][Index]