

                                    Testing


The short version:

$ ninja check


The slightly longer version:

We use the LLVM tools "lit" and "FileCheck", integrated with CMake. Since there
is little documentation on setting up the combination of those tools (apart from
the LLVM source code), here is an overview of the setup:

1. Tests are C or C++ source files in the "test" subdirectory of the project.
   They contain instructions for FileCheck in comments; see that tool's
   documentation.

2. We run the individual tests through lit, LLVM's configurable test runner. It
   finds each test file, performs some variable substitutions (see below), and
   runs the tests. The main source of configuration is "test/lit.cfg".

3. At configuration time, CMake creates an additional config file for lit,
   containing site-specific configuration such as the output directory of the
   build. The template is "test/lit.site.cfg.in".

4. CMake adds the "check" target, which invokes lit on the test suite. (It would
   be nice to call the target "test", but this is a reserved name in some
   versions of CMake, and the built-in test mechanism that it is reserved for
   doesn't track dependencies the way we need.)

Test files can use the following patterns:

%s             The test file itself.
%t             A temporary file.
%symcc         Invocation of clang with our custom pass loaded.
%filecheck     Invocation of FileCheck with the right arguments for the backend.

Since we support multiple symbolic backends, the tests must account for
different output from different backends. To this end, we rely on FileCheck's
prefix mechanism: test files use different prefixes to specify requirements on
different backends. The following prefixes are supported:

SIMPLE:   Active when we test with our own backend.
QSYM:     Active when we test with the QSYM backend.
ANY:      Always active.

The build system makes sure that "%filecheck" always expands to an invocation of
FileCheck that activates the right prefixes for the current build configuration.

Note that we run the tests only with the backend selected at configuration time,
so a full test requires building the project in multiple configurations. Also,
be aware that the backends write all log messages to standard error; therefore,
checks should not depend on the relative ordering of backend logs and messages
that the test program writes to standard output (use stderr instead).


                                Regression tests

In addition to the hand-written tests that exercise compiler functionality via C
code, we have a directory "test/regression" where we can collect LLVM bitcode
files that triggered bugs in real SymCC use. Generate the bitcode by running the
crashing compiler command with additional arguments "-emit-llvm -S -o-", pipe
the result through "opt -S -instnamer", and add a comment at the top to tell lit
how to compile it. The instruction naming is necessary because different LLVM
versions treat numbered (i.e., unnamed) instructions differently and may
complain if the numbering sequence doesn't match expectations.
