-g: debug info, in the compiler written in Finch

DWARF as LLVM metadata: a compile unit, a subprogram per function, a location on every call, a variable
for each local and parameter with types a debugger can open (structs with their fields, arrays and text
as ptr/len/cap, maps, enums with their variants, pointers, fixed arrays). Methods show self.

Use it with -O0, as the docs say: the optimizer inlines the program into main, which has no debug info.
boot.sh builds ten programs with -g -O0 and checks they still behave. 51 passed.
This commit is contained in:
Nexoniarz 2026-10-25 21:08:13 +01:00
commit 8c3b5b15b9
3 changed files with 341 additions and 10 deletions

View file

@ -136,6 +136,7 @@ fn main([]str args) -> int {
out := stem(file)
outGiven := false
shared := false
debug := false
opt := "-O2"
[]str extraLibs
[]str extraDirs
@ -161,8 +162,10 @@ fn main([]str args) -> int {
} else if a == "-I" && ai + 1 < args.len {
extraDirs.push(args[ai + 1])
ai += 1
} else if a == "-g" || a == "--target" {
print("error: '" + a + "' is not in the compiler written in Finch yet; the C++ one has it (branch before-bootstrap)")
} else if a == "-g" {
debug = true
} else if a == "--target" {
print("error: '--target' is not in the compiler written in Finch yet; the C++ one has it (branch before-bootstrap)")
return 1
} else if cmd == "run" {
progArgs.push(a)
@ -219,7 +222,7 @@ fn main([]str args) -> int {
print(err)
return 1
}
ir := gen.generate(loader.progs, loader.files, ci, shared)
ir := gen.generate(loader.progs, loader.files, ci, gen.Options(shared: shared, debug: debug, cwd: getenv("PWD")))
if cmd == "ir" {
print(ir)
return 0
@ -246,6 +249,9 @@ fn main([]str args) -> int {
if shared {
sharedFlags = " -shared -fPIC"
}
if debug {
sharedFlags = sharedFlags + " -g" // or clang drops the debug info that is in the IR
}
// the compiler of the IR is always a clang (CC may be gcc, which can't read it); FINCH_CC picks another clang
cc := getenv("FINCH_CC")
if cc.len == 0 {