Feat: add -S flag to emit LLVM IR

`-S` stops the pipeline after IR emission and writes the `.ll` file
directly to the output path (default `<stem>.ll`). It implies `-c`
(no main required). Combined with `-o`, the IR goes to the specified
path.

Pipeline summary:
  (none)  →  emit → opt → llc → cc  →  executable
  -c      →  emit → opt → llc       →  <stem>.o
  -S      →  emit                   →  <stem>.ll

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-11 20:28:24 +01:00
parent c2fc83b74b
commit f836f279de
2 changed files with 42 additions and 34 deletions

View File

@@ -27,6 +27,10 @@ pub fn print_help() {
" {} Compile to object file (no `main` required, no linking)",
"-c".bold(),
);
println!(
" {} Emit LLVM IR and stop (implies `-c`)",
"-S".bold(),
);
println!(
" {} {} Write output to <file>",
"-o".bold(),
@@ -68,6 +72,8 @@ pub struct Opts {
pub files: Vec<String>,
/// `-c`: compile to object file without requiring a `main` entry point.
pub no_main: bool,
/// `-S`: emit LLVM IR text and stop (implies `-c`).
pub emit_ir: bool,
/// `-o <file>`: write final output to this path.
pub output: Option<String>,
}
@@ -75,6 +81,7 @@ pub struct Opts {
pub fn parse_args() -> Opts {
let mut files = Vec::new();
let mut no_main = false;
let mut emit_ir = false;
let mut output: Option<String> = None;
let mut args = std::env::args().skip(1).peekable();
@@ -89,6 +96,7 @@ pub fn parse_args() -> Opts {
process::exit(0);
}
"-c" => no_main = true,
"-S" => { emit_ir = true; no_main = true; }
"-o" => match args.next() {
Some(path) => output = Some(path),
None => fatal("option `-o` requires an argument"),
@@ -104,9 +112,5 @@ pub fn parse_args() -> Opts {
fatal("no input files — at least one source file is required");
}
Opts {
files,
no_main,
output,
}
Opts { files, no_main, emit_ir, output }
}