aboutsummaryrefslogtreecommitdiff
path: root/AGENTS/ARCH/DRIVER.md
blob: 974c0dc6ea0f6706ddf1574762bba5cb28ef280f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

# Driver behavior

Driver behavior (`tools/driver/main.cc`). CodeGen-side unit and entry-point invariants are in
[CONVENTIONS/EXCEPTIONS_AND_UNITS.md](../CONVENTIONS/EXCEPTIONS_AND_UNITS.md); diagnostic
style is in [CONVENTIONS/SYMBOLS_AND_ERRORS.md](../CONVENTIONS/SYMBOLS_AND_ERRORS.md).

- One or more source files, with optional `-S`, `-o path`, `-r`, `-no-std` and
  `-fdiagnostics-color[=auto|always|never]` / `-fno-diagnostics-color`; options may appear among inputs.
  Each input is preprocessed independently before parsing. PP_* switches are file-local;
  masked source retains line numbers, and SourceUnit owns the per-line __LIB map. INCLUDE paths are relative to the including file,
  matched against command-line inputs with fs::equivalent. The driver rejects repeated
  inputs and computes transitive symbol visibility; cycles do not copy statements.
  CodeGen records owners for signatures, types and exported constants/globals and filters
  lookup by the current unit. Cross-file duplicate definitions are errors; distinct explicit OVERLOAD signatures may share a name.
  The entry file contains the only top-level code, or parameterless FUNCTION MAIN
  returning INTEGER; MAIN plus top-level code and builds without either entry are errors.
  SourceUnit borrows parsed statements for compilation. Type names are reserved across
  all units before payloads are completed, with included units visited first.
  GLOBAL declarations and literal initializers are emitted before function bodies.
  Own constants retain source-order visibility; imported constants are visible from the start.
  No stdin source input. Missing input, including no arguments, prints
  `cpsc: fatal error: no input files` and `compilation terminated.`, then returns 1.
- `-h` anywhere in the arguments prints one documentation pointer to stdout and
  returns 0 without compiling: `man 1 cpsc` on Unix/macOS, or
  Start Menu > cpsc > cpsc Help on Windows (selected by `_WIN32`).
- Output is written only after successful parsing, code generation and module
  verification. Diagnostics stay on stderr; source errors preserve existing output.
  Native linking uses a staged file beside the output and renames it on success.
- `-S` selects textual IR; otherwise output is a native executable. Without `-o`,
  replace the entry source extension with `.ll`, or with `.exe` on Windows / `.out` elsewhere
  for an executable, beside the source.
  `-o` paths are used literally and never select the format. `-r` alone saves nothing;
  either `-S` or `-o` requests saving before execution.
- Lexer, Parser and CodeGen track error flags (`hadError()`); any error, including
  invalid IR from `verifyModule`, makes the driver return 1. File/argument errors
  also return 1. Ordinary compiler errors use `error:`; failures that prevent
  compilation, such as file I/O errors, use `fatal error:`. The driver prints
  `compilation terminated.` once on compilation failure, including argument errors.
  Lexer/parser/codegen diagnostics use the gcc layout `<path>:<line>: error: <message>`
  (Diagnostics.h), with the path as given on the command line; driver-level errors
  use `cpsc: error:` / `cpsc: fatal error:`. Every label comes from
  `cps::diagnosticPrefix`, which emits gcc's default colors when
  `cps::DiagnosticColors` is set. The driver scans the color options right after
  `-h`, before any other diagnostic; the last valid one wins, and `auto` requires a
  terminal stderr (Unix: `TERM` set and not `dumb`; Windows: a console that accepts
  VT sequences). `compilation terminated.` and lld's own output are not colored.
  Execution-stage failures do not print that line. Check the exit code rather
  than grepping stderr.
- Successful compilation overwrites the output, but paths aliasing any input source
  (including symlinks/hard links) are rejected.
- In PATH mode (`tools/driver/PathRunner.cc`, built only in that mode), `-r`
  executes PATH's `lli` using LLVM Support process APIs, with inherited
  stdin/stdout/stderr and no shell. Missing lli is rejected before
  compiling or writing output. The selected `lli --version` must identify LLVM 23
  and succeed within five seconds; other or unrecognized versions fail before
  source compilation. Without `-r`, no external tools are checked; clang/clang++
  are never invoked or checked by this mode. Process-launch/crash failures return 1.
  `-r` alone uses temporary IR removed on return, including execution failure.
- In NONE mode, `-r` returns 1 before compiling or writing output; native and IR
  compilation remain available. Only EMBEDDED uses the in-process execution engine.
- Both execution modes return the program's exit status and inherit standard
  streams. `-r -o` saves a binary; adding `-S` saves IR instead. Saved output is
  kept on execution failure. Execution still uses the configured runner.
  EMBEDDED disables stdout buffering before JIT initialization so pipe clients
  receive output during execution, including on Windows's shared host CRT.