Diagnostics
Errors speak PaskalCPP. A mistake in PaskalCPP code is reported in PaskalCPP's words and types; what only C++ can judge is clang's or the linker's report, mapped back to the .pcpp file, line and column it came from.
Who reports a mistake
Every code names the part of the compiler that reports it:
| Prefix | Reported by |
|---|---|
LX | the lexer |
PR | the parser |
CD | the conditional directives (@ifdef and the others) |
SM | semantics |
EM | the emitter |
ZB | the build driver and the toolchain |
CMP | the compiler |
DB | the debugger |
The reference lists every code with its messages.
- A mistake on a PaskalCPP construct is reported by PaskalCPP: an unterminated string is LX0001, a missing
;PR0001 (expected ';', found 'LN'), a string assigned to an int32 SM0200, a call no overload takes SM0402. - What only C++ can judge is the toolchain's diagnostic, code ZB0016, with clang's or the linker's own message, mapped back to the .pcpp file, line and column: a bare name no declaration has (it may be a C/C++ name:
use of undeclared identifier 'LMissing'), a mistake in mixed C++, a symbol no library defines (at the line that calls it). Both targets print the same. - A check the compiler writes into the C++ for what clang decides (alignment, packed and overlay fields, printing a C/C++ value) is reported with its SM code, in PaskalCPP's words, at the PaskalCPP construct.
- clang's warnings are reported on a build that succeeds too, as warnings located in the .pcpp file.
How a report prints
A report is one line, [<LABEL>] <file>(<line>,<column>) <CODE>: <message>. The label is HINT, WARN, ERROR or FATAL (cyan, yellow, red and magenta on a console), and the file is its full path with forward slashes.
A note explains the report above it, indented two spaces: <file>(<line>,<column>): Note: <message>. SM0402, for example, gets one note per overload.
- Columns are printed in UTF-16 units, as the editor, VS Code and the language server count them, for PaskalCPP's reports and clang's mapped ones alike.
- A place with no column (the linker knows only the line) prints column 0:
(4,0). - Hints and warnings print as they are made, with their notes, between the build's status lines. Errors print together at the end, then
Failed., and pcpp exits 1. A build zig ran saysBuild failed with exit code <n>.first.
Hints and warnings never fail a build: the program builds and runs.
module exe diagnostics_warnings;
@message hint "diagnostics_warnings: a hint";
@message warn "diagnostics_warnings: a warning";
begin
println("octal {}", 010);
println("escape {}", "a\qb");
end.
octal 8
escape aqb
[Heap] Allocs: 0, Frees: 0, Leaked: 0
How many reports a build shows
pcpp stops at the first error: its budget is one error, and clang is asked for one error per C++ file (-Wfatal-errors); a budget above one asks clang for that many (-ferror-limit=<n>). The language server checks with a budget of 100.
- Only errors spend the budget: hints and warnings are always kept, and a fatal is kept past the budget.
- Nothing is emitted or built after a PaskalCPP error: the report comes right after
Compiling <file>, with no target or build lines.
One mistake, one report
- A diagnostic is reported once per build: the same file, line, column, level and message from a header several C++ files include is the first file's report, with its notes.
- What PaskalCPP has judged, clang never judges again: an unknown escape in a plain string is PR0021 and in a char PR0064, once, and the program gets the character itself (
"a\qb"printsaqb). - The line splice and comment warnings (LX0201 to LX0203) are the lexer's; clang's copies of them in the .pcpp file are dropped, so a build shows each once, on both targets.