From ef2ab645d8656417d790043cec0dbbb216e3baf3 Mon Sep 17 00:00:00 2001 From: "XU, Hui" Date: Sat, 3 Aug 2024 10:52:57 +0800 Subject: [PATCH] Update 3.1-frontend.md --- src/3.1-frontend.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/3.1-frontend.md b/src/3.1-frontend.md index cdc69f3..fd6b516 100644 --- a/src/3.1-frontend.md +++ b/src/3.1-frontend.md @@ -14,5 +14,25 @@ Cargo will automatically search the binaries named cargo-toolname from the paths Note that we cannot directly invoke rap in the first round but through cargo check because we need cargo to manage the project-level compilation and append detailed compilation options for launching rustc. However, we want to hook rustc execution and execute rap instead for analysis. Therefore, we set [RUSTC_WRAPPER](https://doc.rust-lang.org/cargo/reference/environment-variables.html) with the value of cargo-rap. In this way, cargo check will actually run `cargo-rap rustc appended_options`. We then dispath the execution to rap with appended options. ## Register Analysis Callbacks +Supposing the purpose is to execute a function named my_analysis, developers should design a new struct and implement the [Callbacks Trait](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/trait.Callbacks.html) for the struct. +``` +pub struct MyCallback {...} +impl Callbacks for MyCallback { + fn after_analysis<'tcx>(&mut self, compiler: &Compiler, queries: &'tcx Queries<'tcx>) -> Compilation { + compiler.session().abort_if_errors(); + queries.global_ctxt().unwrap().enter( + |tcx| my_analysis(tcx, *self) // the analysis function to execute after compilation. + ); + compiler.session().abort_if_errors(); + Compilation::Continue + } +} +``` +To execute the compiler and callback function, developers can employ the APIs [rustc_driver::RunCompiler](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/struct.RunCompiler.html) provided by Rust. +``` +let mut callback = MyCallback::default(); +let run_compiler = rustc_driver::RunCompiler::new(&args, callback); +let exit_code = rustc_driver::catch_with_exit_code(move || run_compiler.run()); +```