Tools

## F Tools

### F.1 The compiler

This section is out-of-date.

#### General options

The Cyclone compiler has the following command-line options:

-help
  Print a short description of the command-line options.
-v
  Print compilation stages verbosely.
--version
  Print version number and exit.
-o file
  Set the output file name to file.
-Dname
  Define a macro named name for preprocessing.
-Dname=defn
  Give macro name the definition defn in preprocessing.
-Bdir
  Add dir to the list of directories to search for special compiler files.
-Idir
  Add dir to the list of directories to search for include files.
-Ldir
  Add dir to the list of directories to search for libraries.
-llib
  Link library lib into the final executable.
-c
  Produce an object (`.o`) file instead of an executable; do not link.
-x language
  Specify language for the following input files
-s
  Remove all symbol table and relocation information from the executable.
-O
  Optimize.
-O2
  A higher level of optimization.
-O3
  Even more optimization.
-p
  Compile for profiling with the `prof` tool.
-pg
  Compile for profiling with the `gprof` tool.
-pa
  Compile for profiling with the `aprof` tool.
-S
  Stop after producing assembly code.
-M
  Produce dependencies for inclusion in a makefile.
-MG
  When producing dependencies assume missing files are generated. Must be used with `-M`.
-MT file
  Make file be the target of any dependencies generated using the `-M` flag.
-E
  Stop after preprocessing.
-nogc
  Don't link in the garbage collector.

#### Developer options

In addition, the compiler has some options that are primarily of use to its developers:

-g
  Compile for debugging. This is bulletproof for compiler developers, as the debugging information reflects the C code that the Cyclone code is compiled to, and not the Cyclone code itself. To have a look at Cyclone code during debugging (but not very cleanly as of yet), also pass in --lineno (see below).
-stopafter-parse
  Stop after parsing.
-stopafter-tc
  Stop after type checking.
-stopafter-toc
  Stop after translation to C.
-ic
  Activate the link-checker.
-pp
  Pretty print.
-up
  Ugly print.
-tovc
  Avoid gcc extensions in the C output.
-save-temps
  Don't delete temporary files.
-save-c
  Don't delete temporary C files.
--lineno
  Insert `#line` directives in generated C code. This slows down compilation, but helps debugging. Works best when also using `-pp`.
--nochecks
  Disable all null and array bounds checks (still uses ``fat'' representation of `?` pointers).
--nonullchecks
  Disable null checks.
--noboundschecks
  Disable array bounds checks (still uses ``fat'' representation of `?` pointers).
-use-cpppath
  Indicate which preprocessor to use.
-no-cpp-precomp
  Disable smart preprocessing (mac only).
-nocyc
  Don't add the implicit namespace Cyc to variable names in the C output.
-noremoveunused
  Don't remove externed variables that aren't used.
-noexpandtypedefs
  Don't expand typedefs in pretty printing.
-printalltvars
  Print all type variables (even implicit default effects).
-printallkinds
  Always print kinds of type variables.
-printfullevars
  Print full information for evars (type debugging).

### F.2 The lexer generator

### F.3 The parser generator

### F.4 The allocation profiler, `aprof`

To get a profile of the allocation behavior of a Cyclone program, follow these steps:

1. Compile the program with the flag `-pa`. The resulting executable will be compiled to record allocation behavior. It will also be linked with a version of the standard library that records its allocation behavior. (If you get the message, ``can't find internal compiler file `libcyc_a.a`,'' then ask your system administrator to install the special version of the library.)
2. Execute the program as normal. As it executes, it will write to a file `amon.out` in the current working directory; if the file exists before execution, it will be overwritten.
3. Run the program `aprof`. This will examine `amon.out` and print a report on the allocation behavior of the program.

### F.5 The C interface tool, `buildlib`

`buildlib` is a tool that semi-automatically constructs a Cyclone interface to C code. It scans C header files and builds Cyclone header files and stub code so that Cyclone programs can call the C code. We use it to build the Cyclone interface to the C standard library (in much the same way that `gcc` uses the `fixincludes` program).
To use `buildlib`, you must construct a spec file that tells it what C headers to scan, and what functions and constants to extract from the headers. By convention, the names of spec files end in `.cys`. If `spec.cys` is a spec file, then `buildlib` is invoked by

      buildlib spec.cys

The output of `buildlib` is placed in a directory, `BUILDLIB.OUT`. The output consists of Cyclone header files and the stub files `cstubs.c` and `cycstubs.cyc`.

#### Spec files

The form of a spec file is given by the following grammar.

spec-file:
  (empty)
  spec spec-file

spec:
  header-name `:` directives `;`

directives:
  (empty)
  directive directives

directive:
  `cpp` `{` balanced-braces `}`
  `include` `{` ids `}`
  `hstub` idopt`{` balanced-braces `}`
  `cycstub` idopt`{` balanced-braces `}`
  `cstub` idopt`{` balanced-braces `}`

ids:
  (empty)
  id balanced-braces* ids

The non-terminal id refers to C identifiers, and header-name ranges over C header names (e.g., `stdio.h`, `sys/types.h`). We use balanced-braces to refer to any sequence of C tokens with balanced braces, ignoring braces inside of comments, strings, and character constants.

#### Directives

include
  The include directive is used to extract constants and type definitions from C header files and put them into the equivalent Cyclone header file. For example, here is part of the spec that we use to interface to C's `errno.h`:

        errno.h:
        include { E2BIG EACCES EADDRINUSE ... }

  The spec says that the Cyclone version of `errno.h` should use the C definitions of error constants like `E2BIG`. These are typically macro-defined as integers, but the integers can differ from system to system. We ensure that Cyclone uses the right constants by running buildlib on each system.
  For another example, our spec for `sys/types.h` reads, in part:

        sys/types.h:
        include { id_t mode_t off_t pid_t ... }

  Here the symbols are typedef names, and the result will be that the Cyclone header file contains the typedefs that define `id_t`, etc. Again, these can differ from system to system.
  You can use `include` to obtain not just constants (macros) and typedefs, but struct and union definitions as well. Furthermore, if a definition you `include` requires any other definitions that you do not explicitly `include`, those other definitions will be placed into the Cyclone header too. Moreover, for all such definitions, you can include an optional, expected Cyclonedefinition that is ``equivalent'' to the C definition on your system. By ``equivalent,'' we mean that your definition defines all of the same elements as the system definition (but possibly fewer), and each of these elements is ``representation-compatible'' in the sense that they use the same amount of storage when compiled. As example, here is our spec for `grp.h`:

      include {
        gid_t
        group {
          struct group {
            char @gr_name;
            char @gr_passwd;
            gid_t gr_gid;
            char ** @zeroterm gr_mem;
          };
        }
      }

  This provides richer information than the compatible definition on most systems. Here is the Linux definition:

      struct group {
        char *gr_name;
        char *gr_passwd;
        gid_t gr_gid;
        char **gr_mem;
      };

  The user definition refines the system definition by indicating that for `group` strings `gr_name` and `gr_passwd` must be non-NULL, and indicates that the array of strings `gr_mem`, is null-terminated. But note that the two definitions are representation-compatible in that they have the same run-time storage requirements. The Cyclone version provides more precise type information. You can provide user definitions for enumerated types and `typedef`'s as well.
  Some refinements (such as polymorphism), are not yet supported for user definitions. Also, `include` does not work for variable or function declarations. You have to use the `hstub` directive to add variable and function declarations to your Cyclone header.
cstub
  The `cstub` directive adds code (the balanced-braces) to the C stub file. If an optional id is used, then the code will be added to the stub file only if the id is declared by the C header. This is useful because every system defines a different subset of the C standard library.
cycstub
  The `cycstub` directive is like the `cstub` directive, except that the code is added to the Cyclone stub file.
hstub
  The `hstub` directive is like the `cstub` directive, except that the code is added to the Cyclone header file.
cpp
  The `cpp` directive is used to tell `buildlib` to scan some extra header files before scanning the header file of the spec. This is useful when a header file can't be parsed in isolation. For example, the standard C header `sys/resource.h` is supposed to define `struct timeval`, but on some systems, this is defined in `sys/types.h`, which must be included before `sys/resource.h` for that file to parse. This can be handled with a spec like the following:

        sys/resource.h:
        cpp {
          #include <sys/types.h>
        }
        ...

  This will cause `sys/types.h` to be scanned by `buildlib` before `sys/resource.h`.
  You can also use the `cpp` directive to directly specify anything that might appear in a C include file (e.g., macros).

#### Options

`buildlib` has the following options.

-d directory
  Use directory as the output directory instead of the default `BUILDLIB.OUT`.
-gather and -finish
  `buildlib` works in two phases. In the gather phase, `buildlib` grabs the C headers listed in the spec file from their normal locations in the C include tree, and stores them in a special format in the output directory. In the finish phase, `buildlib` uses the specially formatted C headers to build the Cyclone headers and stub files. The `-gather` flag tells `buildlib` to perform just the gather phase, and the `-finish` flag tells it to perform just the finish phase.
  `buildlib`'s two-phase strategy is intended to support cross compilation. A Cyclone compiler on one architecture can compile to a second architecture provided it has the other architecture's Cyclone header files. These headers can be generated on the first architecture from the output of the gather phase on the second architecture. This is more general than just having the second architecture's Cyclone headers, because it permits works even in the face of some changes in the spec file or `buildlib` itself (which would change the other architecture's Cyclone headers).
-gatherscript
  The `-gatherscript` flag tells `buildlib` to output a shell script that, when executed, performs `buildlib`'s gather phase. This is useful when porting Cyclone to an unsupported architecture, where `buildlib` itself does not yet work. The script can be executed on the unsupported architecture, and the result can be moved to a supported architecture, which can then cross-compile itself to the new architecture.