1use clap::Parser;
2use std::path::PathBuf;
3
4mod bugpoint;
5mod cat;
6mod compile;
7mod disasm;
8mod interpret;
9mod print_cfg;
10mod run;
11mod utils;
12
13#[cfg(feature = "souper-harvest")]
14mod souper_harvest;
15
16#[derive(Parser)]
18enum Commands {
19 Test(TestOptions),
20 Run(run::Options),
21 Interpret(interpret::Options),
22 Cat(cat::Options),
23 PrintCfg(print_cfg::Options),
24 Compile(compile::Options),
25 Pass(PassOptions),
26 Bugpoint(bugpoint::Options),
27
28 #[cfg(feature = "souper-harvest")]
29 SouperHarvest(souper_harvest::Options),
30 #[cfg(not(feature = "souper-harvest"))]
31 SouperHarvest(CompiledWithoutSupportOptions),
32}
33
34#[derive(Parser)]
36struct TestOptions {
37 #[arg(short, long)]
39 verbose: bool,
40
41 #[arg(short = 'T')]
43 time_passes: bool,
44
45 #[arg(required = true)]
47 files: Vec<PathBuf>,
48}
49
50#[derive(Parser)]
52struct PassOptions {
53 #[arg(short, long)]
55 verbose: bool,
56
57 #[arg(short = 'T')]
59 time_passes: bool,
60
61 file: PathBuf,
63
64 target: String,
66
67 #[arg(required = true)]
69 passes: Vec<String>,
70}
71
72#[derive(Parser)]
74struct CompiledWithoutSupportOptions {}
75
76fn main() -> anyhow::Result<()> {
77 pretty_env_logger::init();
78
79 match Commands::parse() {
80 Commands::Cat(c) => cat::run(&c)?,
81 Commands::Run(r) => run::run(&r)?,
82 Commands::Interpret(i) => interpret::run(&i)?,
83 Commands::PrintCfg(p) => print_cfg::run(&p)?,
84 Commands::Compile(c) => compile::run(&c)?,
85 Commands::Bugpoint(b) => bugpoint::run(&b)?,
86
87 #[cfg(feature = "souper-harvest")]
88 Commands::SouperHarvest(s) => souper_harvest::run(&s)?,
89 #[cfg(not(feature = "souper-harvest"))]
90 Commands::SouperHarvest(_) => anyhow::bail!(
91 "Error: clif-util was compiled without support for the `souper-harvest` \
92 subcommand",
93 ),
94
95 Commands::Test(t) => {
96 cranelift_filetests::run(
97 t.verbose,
98 t.time_passes,
99 &t.files
100 .iter()
101 .map(|f| f.display().to_string())
102 .collect::<Vec<_>>(),
103 )?;
104 }
105 Commands::Pass(p) => {
106 cranelift_filetests::run_passes(
107 p.verbose,
108 p.time_passes,
109 &p.passes,
110 &p.target,
111 &p.file.display().to_string(),
112 )?;
113 }
114 }
115
116 Ok(())
117}
118
119#[test]
120fn verify_cli() {
121 use clap::CommandFactory;
122 Commands::command().debug_assert()
123}