diff options
-rw-r--r-- | gcc/rust/lang.opt | 42 | ||||
-rw-r--r-- | gcc/rust/rust-session-manager.cc | 36 | ||||
-rw-r--r-- | gcc/rust/rust-session-manager.h | 25 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/frust-compile-until.rs | 7 |
4 files changed, 107 insertions, 3 deletions
diff --git a/gcc/rust/lang.opt b/gcc/rust/lang.opt index 1f6855e..bb3b998 100644 --- a/gcc/rust/lang.opt +++ b/gcc/rust/lang.opt @@ -113,6 +113,48 @@ Rust Joined RejectNegative o Rust Joined Separate + +frust-compile-until= +Rust Joined RejectNegative Enum(frust_compile_until) Var(flag_rust_compile_until) +-frust-compile-until=[ast|attributecheck|expansion|nameresolution|lowering|typecheck|privacy|unsafety|const|copimlation|end] When to stop in the pipeline when compiling Rust code + +Enum +Name(frust_compile_until) Type(int) UnknownError(unknown rust compile-until %qs) + +EnumValue +Enum(frust_compile_until) String(ast) Value(0) + +EnumValue +Enum(frust_compile_until) String(attributecheck) Value(1) + +EnumValue +Enum(frust_compile_until) String(expansion) Value(2) + +EnumValue +Enum(frust_compile_until) String(nameresolution) Value(3) + +EnumValue +Enum(frust_compile_until) String(lowering) Value(4) + +EnumValue +Enum(frust_compile_until) String(typecheck) Value(5) + +EnumValue +Enum(frust_compile_until) String(privacy) Value(6) + +EnumValue +Enum(frust_compile_until) String(unsafety) Value(7) + +EnumValue +Enum(frust_compile_until) String(const) Value(8) + +EnumValue +Enum(frust_compile_until) String(compilation) Value(9) + +EnumValue +Enum(frust_compile_until) String(end) Value(10) + + ; Documented in common.opt ; This comment is to ensure we retain the blank line above. diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc index fc66b69..a6291a3 100644 --- a/gcc/rust/rust-session-manager.cc +++ b/gcc/rust/rust-session-manager.cc @@ -223,7 +223,9 @@ Session::handle_option ( case OPT_frust_edition_: options.set_edition (flag_rust_edition); break; - + case OPT_frust_compile_until_: + options.set_compile_step (flag_rust_compile_until); + break; case OPT_frust_metadata_output_: options.set_metadata_output (arg); break; @@ -425,6 +427,8 @@ Session::compile_crate (const char *filename) return; } + auto last_step = options.get_compile_until (); + // parse file here /* create lexer and parser - these are file-specific and so aren't instance * variables */ @@ -481,7 +485,7 @@ Session::compile_crate (const char *filename) // If -fsyntax-only was passed, we can just skip the remaining passes. // Parsing errors are already emitted in `parse_crate()` - if (flag_syntax_only) + if (flag_syntax_only || last_step == CompileOptions::CompileStep::Ast) return; // register plugins pipeline stage @@ -500,8 +504,14 @@ Session::compile_crate (const char *filename) // TODO: what do I dump here? injected crate names? } + if (last_step == CompileOptions::CompileStep::AttributeCheck) + return; + Analysis::AttributeChecker ().go (parsed_crate); + if (last_step == CompileOptions::CompileStep::Expansion) + return; + // expansion pipeline stage expansion (parsed_crate); rust_debug ("\033[0;31mSUCCESSFULLY FINISHED EXPANSION \033[0m"); @@ -514,6 +524,9 @@ Session::compile_crate (const char *filename) rust_debug ("END POST-EXPANSION AST DUMP"); } + if (last_step == CompileOptions::CompileStep::NameResolution) + return; + // resolution pipeline stage Resolver::NameResolution::Resolve (parsed_crate); if (options.dump_option_enabled (CompileOptions::RESOLUTION_DUMP)) @@ -524,6 +537,9 @@ Session::compile_crate (const char *filename) if (saw_errors ()) return; + if (last_step == CompileOptions::CompileStep::Lowering) + return; + // lower AST to HIR std::unique_ptr<HIR::Crate> lowered = HIR::ASTLowering::Resolve (parsed_crate); @@ -541,6 +557,9 @@ Session::compile_crate (const char *filename) dump_hir_pretty (hir); } + if (last_step == CompileOptions::CompileStep::TypeCheck) + return; + // type resolve Resolver::TypeResolution::Resolve (hir); if (options.dump_option_enabled (CompileOptions::TYPE_RESOLUTION_DUMP)) @@ -551,17 +570,30 @@ Session::compile_crate (const char *filename) if (saw_errors ()) return; + if (last_step == CompileOptions::CompileStep::Privacy) + return; + // Various HIR error passes. The privacy pass happens before the unsafe checks Privacy::Resolver::resolve (hir); if (saw_errors ()) return; + if (last_step == CompileOptions::CompileStep::Unsafety) + return; + HIR::UnsafeChecker ().go (hir); + + if (last_step == CompileOptions::CompileStep::Const) + return; + HIR::ConstChecker ().go (hir); if (saw_errors ()) return; + if (last_step == CompileOptions::CompileStep::Compilation) + return; + // do compile to gcc generic Compile::Context ctx (backend); Compile::CompileCrate::Compile (hir, &ctx); diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h index b3724c5..6ecd513 100644 --- a/gcc/rust/rust-session-manager.h +++ b/gcc/rust/rust-session-manager.h @@ -199,6 +199,22 @@ struct CompileOptions } edition = Edition::E2015; + enum class CompileStep + { + Ast, + AttributeCheck, + Expansion, + NameResolution, + Lowering, + TypeCheck, + Privacy, + Unsafety, + Const, + Compilation, + End, + } compile_until + = CompileStep::End; + bool dump_option_enabled (DumpOption option) const { return dump_options.find (option) != dump_options.end (); @@ -239,7 +255,14 @@ struct CompileOptions edition = static_cast<Edition> (raw_edition); } - const Edition &get_edition () { return edition; } + const Edition &get_edition () const { return edition; } + + void set_compile_step (int raw_step) + { + compile_until = static_cast<CompileStep> (raw_step); + } + + const CompileStep &get_compile_until () const { return compile_until; } void set_metadata_output (const std::string &path) { diff --git a/gcc/testsuite/rust/compile/frust-compile-until.rs b/gcc/testsuite/rust/compile/frust-compile-until.rs new file mode 100644 index 0000000..7bb3932 --- /dev/null +++ b/gcc/testsuite/rust/compile/frust-compile-until.rs @@ -0,0 +1,7 @@ +// { dg-additional-options "-frust-compile-until=unsafety" } + +unsafe fn foo() {} + +fn main() { + foo() +} |