From: Jakub Dupak Date: Thu, 19 Oct 2023 08:59:54 +0000 (+0200) Subject: gccrs: borrowck: Add CLI option for borrowck X-Git-Tag: basepoints/gcc-15~2062 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=206fc6de9827809cef89b95d1eeb55c5632dd66a;p=thirdparty%2Fgcc.git gccrs: borrowck: Add CLI option for borrowck gcc/rust/ChangeLog: * checks/errors/borrowck/rust-borrow-checker.cc (BorrowChecker::BorrowChecker): Opt dump. (BorrowChecker::go): Opt dump. * checks/errors/borrowck/rust-borrow-checker.h (class BorrowChecker): Opt dump. * lang.opt: Add compile until borrowcheck. * rust-session-manager.cc (Session::enable_dump): Add BIR. (Session::compile_crate): Handle new options. * rust-session-manager.h (struct CompileOptions): Add BIR. Signed-off-by: Jakub Dupak --- diff --git a/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc b/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc index a6086b8a6956..6c2922310423 100644 --- a/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc +++ b/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc @@ -22,8 +22,6 @@ namespace Rust { namespace HIR { -BorrowChecker::BorrowChecker () = default; - void BorrowChecker::go (HIR::Crate &crate) { diff --git a/gcc/rust/checks/errors/borrowck/rust-borrow-checker.h b/gcc/rust/checks/errors/borrowck/rust-borrow-checker.h index 7df5fe788a0b..549af3560e9b 100644 --- a/gcc/rust/checks/errors/borrowck/rust-borrow-checker.h +++ b/gcc/rust/checks/errors/borrowck/rust-borrow-checker.h @@ -26,8 +26,11 @@ namespace HIR { class BorrowChecker { + bool enable_dump_bir; + public: - BorrowChecker (); + explicit BorrowChecker (bool enable_dump_bir) + : enable_dump_bir (enable_dump_bir){}; /** Perform borrow-checking using polonius on an entire crate */ void go (HIR::Crate &crate); diff --git a/gcc/rust/lang.opt b/gcc/rust/lang.opt index 5b744f71577f..a02121fcf5c4 100644 --- a/gcc/rust/lang.opt +++ b/gcc/rust/lang.opt @@ -190,10 +190,13 @@ EnumValue Enum(frust_compile_until) String(const) Value(8) EnumValue -Enum(frust_compile_until) String(compilation) Value(9) +Enum(frust_compile_until) String(borrowcheck) Value(9) EnumValue -Enum(frust_compile_until) String(end) Value(10) +Enum(frust_compile_until) String(compilation) Value(10) + +EnumValue +Enum(frust_compile_until) String(end) Value(11) frust-name-resolution-2.0 Rust Var(flag_name_resolution_2_0) diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc index 3edd1ecb4ebe..8e69fc39aac5 100644 --- a/gcc/rust/rust-session-manager.cc +++ b/gcc/rust/rust-session-manager.cc @@ -16,47 +16,46 @@ // along with GCC; see the file COPYING3. If not see // . -#include "rust-session-manager.h" -#include "rust-diagnostics.h" -#include "rust-unsafe-checker.h" -#include "rust-lex.h" -#include "rust-parse.h" -#include "rust-macro-expand.h" -#include "rust-ast-resolve.h" +#include "rust-ast-dump.h" #include "rust-ast-lower.h" -#include "rust-hir-type-check.h" -#include "rust-privacy-check.h" +#include "rust-ast-resolve.h" +#include "rust-attribute-values.h" +#include "rust-attributes.h" +#include "rust-cfg-parser.h" +#include "rust-cfg-strip.h" +#include "rust-compile.h" #include "rust-const-checker.h" +#include "rust-diagnostics.h" +#include "rust-early-name-resolver-2.0.h" +#include "rust-early-name-resolver.h" +#include "rust-expand-visitor.h" +#include "rust-export-metadata.h" +#include "rust-extern-crate.h" #include "rust-feature-gate.h" -#include "rust-compile.h" -#include "rust-cfg-parser.h" -#include "rust-lint-scan-deadcode.h" -#include "rust-lint-unused-var.h" -#include "rust-readonly-check.h" #include "rust-hir-dump.h" -#include "rust-ast-dump.h" -#include "rust-export-metadata.h" +#include "rust-hir-type-check.h" #include "rust-imports.h" -#include "rust-extern-crate.h" -#include "rust-attributes.h" -#include "rust-early-name-resolver.h" +#include "rust-lex.h" +#include "rust-lint-scan-deadcode.h" +#include "rust-lint-unused-var.h" +#include "rust-macro-expand.h" #include "rust-name-resolution-context.h" -#include "rust-early-name-resolver-2.0.h" -#include "rust-cfg-strip.h" -#include "rust-expand-visitor.h" +#include "rust-parse.h" +#include "rust-privacy-check.h" +#include "rust-readonly-check.h" +#include "rust-session-manager.h" #include "rust-unicode.h" -#include "rust-attribute-values.h" +#include "rust-unsafe-checker.h" #include "input.h" +#include "rust-borrow-checker.h" +#include "rust-target.h" #include "selftest.h" #include "tm.h" -#include "rust-target.h" -extern bool -saw_errors (void); +extern bool saw_errors(void); -extern Linemap * -rust_get_linemap (); +extern Linemap *rust_get_linemap(); namespace Rust { @@ -73,75 +72,63 @@ const char *kTargetOptionsDumpFile = "gccrs.target-options.dump"; const std::string kDefaultCrateName = "rust_out"; const size_t kMaxNameLength = 64; -Session & -Session::get_instance () -{ +Session &Session::get_instance() { static Session instance; return instance; } -static std::string -infer_crate_name (const std::string &filename) -{ +static std::string infer_crate_name(const std::string &filename) { if (filename == "-") return kDefaultCrateName; - std::string crate = std::string (filename); - size_t path_sep = crate.find_last_of (file_separator); + std::string crate = std::string(filename); + size_t path_sep = crate.find_last_of(file_separator); // find the base filename if (path_sep != std::string::npos) - crate.erase (0, path_sep + 1); + crate.erase(0, path_sep + 1); // find the file stem name (remove file extension) - size_t ext_position = crate.find_last_of ('.'); + size_t ext_position = crate.find_last_of('.'); if (ext_position != std::string::npos) - crate.erase (ext_position); + crate.erase(ext_position); // Replace all the '-' symbols with '_' per Rust rules - for (auto &c : crate) - { - if (c == '-') - c = '_'; - } + for (auto &c : crate) { + if (c == '-') + c = '_'; + } return crate; } /* Validate the crate name using the ASCII rules */ -static bool -validate_crate_name (const std::string &crate_name, Error &error) -{ - tl::optional utf8_name_opt - = Utf8String::make_utf8_string (crate_name); - if (!utf8_name_opt.has_value ()) - { - error = Error (UNDEF_LOCATION, "crate name is not a valid UTF-8 string"); - return false; - } +static bool validate_crate_name(const std::string &crate_name, Error &error) { + tl::optional utf8_name_opt = + Utf8String::make_utf8_string(crate_name); + if (!utf8_name_opt.has_value()) { + error = Error(UNDEF_LOCATION, "crate name is not a valid UTF-8 string"); + return false; + } - std::vector uchars = utf8_name_opt->get_chars (); - if (uchars.empty ()) - { - error = Error (UNDEF_LOCATION, "crate name cannot be empty"); - return false; - } - if (uchars.size () > kMaxNameLength) - { - error = Error (UNDEF_LOCATION, "crate name cannot exceed %lu characters", - (unsigned long) kMaxNameLength); + std::vector uchars = utf8_name_opt->get_chars(); + if (uchars.empty()) { + error = Error(UNDEF_LOCATION, "crate name cannot be empty"); + return false; + } + if (uchars.size() > kMaxNameLength) { + error = Error(UNDEF_LOCATION, "crate name cannot exceed %lu characters", + (unsigned long)kMaxNameLength); + return false; + } + for (Codepoint &c : uchars) { + if (!(is_alphabetic(c.value) || is_numeric(c.value) || c.value == '_')) { + error = Error(UNDEF_LOCATION, + "invalid character %<%s%> in crate name: %<%s%>", + c.as_string().c_str(), crate_name.c_str()); return false; } - for (Codepoint &c : uchars) - { - if (!(is_alphabetic (c.value) || is_numeric (c.value) || c.value == '_')) - { - error = Error (UNDEF_LOCATION, - "invalid character %<%s%> in crate name: %<%s%>", - c.as_string ().c_str (), crate_name.c_str ()); - return false; - } - } + } return true; } @@ -152,392 +139,333 @@ Session::init () targetrustm.rust_cpu_info (); targetrustm.rust_os_info (); - // target-independent values that should exist in all targets - options.target_data.insert_key_value_pair ("target_pointer_width", - std::to_string (POINTER_SIZE)); - options.target_data.insert_key_value_pair ("target_endian", BYTES_BIG_ENDIAN - ? "big" - : "little"); + options.target_data.insert_key_value_pair("target_pointer_width", + std::to_string(POINTER_SIZE)); + options.target_data.insert_key_value_pair( + "target_endian", BYTES_BIG_ENDIAN ? "big" : "little"); // setup singleton linemap - linemap = rust_get_linemap (); + linemap = rust_get_linemap(); // setup backend to GCC GIMPLE - Backend::init (); + Backend::init(); // setup mappings class - mappings = Analysis::Mappings::get (); + mappings = Analysis::Mappings::get(); } /* Initialise default options. Actually called before handle_option, unlike init * itself. */ -void -Session::init_options () -{} +void Session::init_options() {} // Handle option selection. -bool -Session::handle_option ( - enum opt_code code, const char *arg, HOST_WIDE_INT value ATTRIBUTE_UNUSED, - int kind ATTRIBUTE_UNUSED, location_t loc ATTRIBUTE_UNUSED, - const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED) -{ +bool Session::handle_option( + enum opt_code code, const char *arg, HOST_WIDE_INT value ATTRIBUTE_UNUSED, + int kind ATTRIBUTE_UNUSED, location_t loc ATTRIBUTE_UNUSED, + const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED) { // used to store whether results of various stuff are successful bool ret = true; // Handles options as listed in lang.opt. - switch (code) - { - case OPT_I: - case OPT_L: { - // TODO: add search path - const std::string p = std::string (arg); - add_search_path (p); - } - break; - - case OPT_frust_extern_: { - std::string input (arg); - ret = handle_extern_option (input); - } - break; - case OPT_frust_crate_: - // set the crate name - if (arg != nullptr) - { - auto error = Error (UNDEF_LOCATION, std::string ()); - if ((ret = validate_crate_name (arg, error))) - { - options.set_crate_name (arg); - options.crate_name_set_manually = true; - } - else - { - rust_assert (!error.message.empty ()); - error.emit (); - } - } - else - ret = false; - break; - - case OPT_frust_dump_: - // enable dump and return whether this was successful - if (arg != nullptr) - { - ret = enable_dump (std::string (arg)); - } - else - { - ret = false; - } - break; - - case OPT_frust_mangling_: - Compile::Mangler::set_mangling (flag_rust_mangling); - break; - - case OPT_frust_cfg_: { - auto string_arg = std::string (arg); - ret = handle_cfg_option (string_arg); - break; + switch (code) { + case OPT_I: + case OPT_L: { + // TODO: add search path + const std::string p = std::string(arg); + add_search_path(p); + } break; + + case OPT_frust_extern_: { + std::string input(arg); + ret = handle_extern_option(input); + } break; + case OPT_frust_crate_: + // set the crate name + if (arg != nullptr) { + auto error = Error(UNDEF_LOCATION, std::string()); + if ((ret = validate_crate_name(arg, error))) { + options.set_crate_name(arg); + options.crate_name_set_manually = true; + } else { + rust_assert(!error.message.empty()); + error.emit(); } - case OPT_frust_crate_type_: - options.set_crate_type (flag_rust_crate_type); - break; - 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; - - default: - break; + } else + ret = false; + break; + + case OPT_frust_dump_: + // enable dump and return whether this was successful + if (arg != nullptr) { + ret = enable_dump(std::string(arg)); + } else { + ret = false; } + break; + + case OPT_frust_mangling_: + Compile::Mangler::set_mangling(flag_rust_mangling); + break; + + case OPT_frust_cfg_: { + auto string_arg = std::string(arg); + ret = handle_cfg_option(string_arg); + break; + } + case OPT_frust_crate_type_: + options.set_crate_type(flag_rust_crate_type); + break; + 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; + + default: + break; + } return ret; } -bool -Session::handle_extern_option (std::string &input) -{ - auto pos = input.find ('='); +bool Session::handle_extern_option(std::string &input) { + auto pos = input.find('='); if (std::string::npos == pos) return false; - std::string libname = input.substr (0, pos); - std::string path = input.substr (pos + 1); + std::string libname = input.substr(0, pos); + std::string path = input.substr(pos + 1); - extern_crates.insert ({libname, path}); + extern_crates.insert({libname, path}); return true; } -bool -Session::handle_cfg_option (std::string &input) -{ +bool Session::handle_cfg_option(std::string &input) { std::string key; std::string value; // Refactor this if needed - if (!parse_cfg_option (input, key, value)) - { - rust_error_at ( - UNDEF_LOCATION, - "invalid argument to %<-frust-cfg%>: Accepted formats are " - "%<-frust-cfg=key%> or %<-frust-cfg=key=\"value\"%> (quoted)"); - return false; - } + if (!parse_cfg_option(input, key, value)) { + rust_error_at( + UNDEF_LOCATION, + "invalid argument to %<-frust-cfg%>: Accepted formats are " + "%<-frust-cfg=key%> or %<-frust-cfg=key=\"value\"%> (quoted)"); + return false; + } - if (value.empty ()) + if (value.empty()) // rustc does not seem to error on dup key - options.target_data.insert_key (key); + options.target_data.insert_key(key); else - options.target_data.insert_key_value_pair (key, value); + options.target_data.insert_key_value_pair(key, value); return true; } /* Enables a certain dump depending on the name passed in. Returns true if * name is valid, false otherwise. */ -bool -Session::enable_dump (std::string arg) -{ - if (arg.empty ()) - { - rust_error_at ( - UNDEF_LOCATION, - "dump option was not given a name. choose %, %, " - "%, %, " - "%, %, %, %, " - "%, or %"); - return false; - } - - if (arg == "all") - { - options.enable_all_dump_options (); - } - else if (arg == "lex") - { - options.enable_dump_option (CompileOptions::LEXER_DUMP); - } - else if (arg == "ast-pretty") - { - options.enable_dump_option (CompileOptions::AST_DUMP_PRETTY); - } - else if (arg == "register_plugins") - { - options.enable_dump_option (CompileOptions::REGISTER_PLUGINS_DUMP); - } - else if (arg == "injection") - { - options.enable_dump_option (CompileOptions::INJECTION_DUMP); - } - else if (arg == "expansion") - { - options.enable_dump_option (CompileOptions::EXPANSION_DUMP); - } - else if (arg == "resolution") - { - options.enable_dump_option (CompileOptions::RESOLUTION_DUMP); - } - else if (arg == "target_options") - { - options.enable_dump_option (CompileOptions::TARGET_OPTION_DUMP); - } - else if (arg == "hir") - { - options.enable_dump_option (CompileOptions::HIR_DUMP); - } - else if (arg == "hir-pretty") - { - options.enable_dump_option (CompileOptions::HIR_DUMP_PRETTY); - } - else - { - rust_error_at ( - UNDEF_LOCATION, - "dump option %qs was unrecognised. choose %, %, " - "%, %, " - "%, %, %, %, " - "%, or %", - arg.c_str ()); - return false; - } +bool Session::enable_dump(std::string arg) { + if (arg.empty()) { + rust_error_at( + UNDEF_LOCATION, + "dump option was not given a name. choose %, %, " + "%, %, " + "%, %, %, %, " + "%, % or %"); + return false; + } + + if (arg == "all") { + options.enable_all_dump_options(); + } else if (arg == "lex") { + options.enable_dump_option(CompileOptions::LEXER_DUMP); + } else if (arg == "ast-pretty") { + options.enable_dump_option(CompileOptions::AST_DUMP_PRETTY); + } else if (arg == "register_plugins") { + options.enable_dump_option(CompileOptions::REGISTER_PLUGINS_DUMP); + } else if (arg == "injection") { + options.enable_dump_option(CompileOptions::INJECTION_DUMP); + } else if (arg == "expansion") { + options.enable_dump_option(CompileOptions::EXPANSION_DUMP); + } else if (arg == "resolution") { + options.enable_dump_option(CompileOptions::RESOLUTION_DUMP); + } else if (arg == "target_options") { + options.enable_dump_option(CompileOptions::TARGET_OPTION_DUMP); + } else if (arg == "hir") { + options.enable_dump_option(CompileOptions::HIR_DUMP); + } else if (arg == "hir-pretty") { + options.enable_dump_option(CompileOptions::HIR_DUMP_PRETTY); + } else if (arg == "bir") { + options.enable_dump_option(CompileOptions::BIR_DUMP); + } else { + rust_error_at( + UNDEF_LOCATION, + "dump option %qs was unrecognised. choose %, %, " + "%, %, " + "%, %, %, %, " + "%, or %", + arg.c_str()); + return false; + } return true; } /* Actual main entry point for front-end. Called from langhook to parse files. */ -void -Session::handle_input_files (int num_files, const char **files) -{ +void Session::handle_input_files(int num_files, const char **files) { if (num_files != 1) - rust_fatal_error (UNDEF_LOCATION, - "only one file may be specified on the command line"); + rust_fatal_error(UNDEF_LOCATION, + "only one file may be specified on the command line"); const auto &file = files[0]; - if (options.crate_name.empty ()) - { - auto filename = "-"; - if (num_files > 0) - filename = files[0]; - - auto crate_name = infer_crate_name (filename); - rust_debug ("inferred crate name: %s", crate_name.c_str ()); - // set the preliminary crate name here - // we will figure out the real crate name in `handle_crate_name` - options.set_crate_name (crate_name); - } + if (options.crate_name.empty()) { + auto filename = "-"; + if (num_files > 0) + filename = files[0]; + + auto crate_name = infer_crate_name(filename); + rust_debug("inferred crate name: %s", crate_name.c_str()); + // set the preliminary crate name here + // we will figure out the real crate name in `handle_crate_name` + options.set_crate_name(crate_name); + } - CrateNum crate_num = mappings->get_next_crate_num (options.get_crate_name ()); - mappings->set_current_crate (crate_num); + CrateNum crate_num = mappings->get_next_crate_num(options.get_crate_name()); + mappings->set_current_crate(crate_num); - rust_debug ("Attempting to parse file: %s", file); - compile_crate (file); + rust_debug("Attempting to parse file: %s", file); + compile_crate(file); } -void -Session::handle_crate_name (const AST::Crate &parsed_crate) -{ - auto mappings = Analysis::Mappings::get (); +void Session::handle_crate_name(const AST::Crate &parsed_crate) { + auto mappings = Analysis::Mappings::get(); auto crate_name_changed = false; - auto error = Error (UNDEF_LOCATION, std::string ()); - - for (const auto &attr : parsed_crate.inner_attrs) - { - if (attr.get_path () != "crate_name") - continue; - if (!attr.has_attr_input ()) - { - rust_error_at (attr.get_locus (), - "% accepts one argument"); - continue; - } - - auto &literal - = static_cast (attr.get_attr_input ()); - const auto &msg_str = literal.get_literal ().as_string (); - if (!validate_crate_name (msg_str, error)) - { - error.locus = attr.get_locus (); - error.emit (); - continue; - } - - auto options = Session::get_instance ().options; - if (options.crate_name_set_manually && (options.crate_name != msg_str)) - { - rust_error_at (attr.get_locus (), - "%<-frust-crate-name%> and %<#[crate_name]%> are " - "required to match, but %qs does not match %qs", - options.crate_name.c_str (), msg_str.c_str ()); - } - crate_name_changed = true; - options.set_crate_name (msg_str); - mappings->set_crate_name (mappings->get_current_crate (), msg_str); + auto error = Error(UNDEF_LOCATION, std::string()); + + for (const auto &attr : parsed_crate.inner_attrs) { + if (attr.get_path() != "crate_name") + continue; + if (!attr.has_attr_input()) { + rust_error_at(attr.get_locus(), "% accepts one argument"); + continue; } - options.crate_name_set_manually |= crate_name_changed; - if (!options.crate_name_set_manually - && !validate_crate_name (options.crate_name, error)) - { - error.emit (); - rust_inform (linemap_position_for_column (line_table, 0), - "crate name inferred from this file"); + auto &literal = static_cast(attr.get_attr_input()); + const auto &msg_str = literal.get_literal().as_string(); + if (!validate_crate_name(msg_str, error)) { + error.locus = attr.get_locus(); + error.emit(); + continue; } + + auto options = Session::get_instance().options; + if (options.crate_name_set_manually && (options.crate_name != msg_str)) { + rust_error_at(attr.get_locus(), + "%<-frust-crate-name%> and %<#[crate_name]%> are " + "required to match, but %qs does not match %qs", + options.crate_name.c_str(), msg_str.c_str()); + } + crate_name_changed = true; + options.set_crate_name(msg_str); + mappings->set_crate_name(mappings->get_current_crate(), msg_str); + } + + options.crate_name_set_manually |= crate_name_changed; + if (!options.crate_name_set_manually && + !validate_crate_name(options.crate_name, error)) { + error.emit(); + rust_inform(linemap_position_for_column(line_table, 0), + "crate name inferred from this file"); + } } // Parses a single file with filename filename. -void -Session::compile_crate (const char *filename) -{ - if (!flag_rust_experimental - && !std::getenv ("GCCRS_INCOMPLETE_AND_EXPERIMENTAL_COMPILER_DO_NOT_USE")) - rust_fatal_error ( - UNDEF_LOCATION, "%s", - "gccrs is not yet able to compile Rust code " - "properly. Most of the errors produced will be gccrs' fault and not the " - "crate you are trying to compile. Because of this, please reports issues " - "to us directly instead of opening issues on said crate's " - "repository.\n\nOur github repository: " - "https://github.com/rust-gcc/gccrs\nOur bugzilla tracker: " - "https://gcc.gnu.org/bugzilla/" - "buglist.cgi?bug_status=__open__&component=rust&product=gcc\n\n" - "If you understand this, and understand that the binaries produced might " - "not behave accordingly, you may attempt to use gccrs in an experimental " - "manner by passing the following flag:\n\n" - "`-frust-incomplete-and-experimental-compiler-do-not-use`\n\nor by " - "defining the following environment variable (any value will " - "do)\n\nGCCRS_INCOMPLETE_AND_EXPERIMENTAL_COMPILER_DO_NOT_USE\n\nFor " - "cargo-gccrs, this means passing\n\n" - "GCCRS_EXTRA_ARGS=\"-frust-incomplete-and-experimental-compiler-do-not-" - "use\"\n\nas an environment variable."); - - RAIIFile file_wrap (filename); - if (!file_wrap.ok ()) - { - rust_error_at (UNDEF_LOCATION, "cannot open filename %s: %m", filename); - return; - } +void Session::compile_crate(const char *filename) { + if (!flag_rust_experimental && + !std::getenv("GCCRS_INCOMPLETE_AND_EXPERIMENTAL_COMPILER_DO_NOT_USE")) + rust_fatal_error( + UNDEF_LOCATION, "%s", + "gccrs is not yet able to compile Rust code " + "properly. Most of the errors produced will be gccrs' fault and not " + "the " + "crate you are trying to compile. Because of this, please reports " + "issues " + "to us directly instead of opening issues on said crate's " + "repository.\n\nOur github repository: " + "https://github.com/rust-gcc/gccrs\nOur bugzilla tracker: " + "https://gcc.gnu.org/bugzilla/" + "buglist.cgi?bug_status=__open__&component=rust&product=gcc\n\n" + "If you understand this, and understand that the binaries produced " + "might " + "not behave accordingly, you may attempt to use gccrs in an " + "experimental " + "manner by passing the following flag:\n\n" + "`-frust-incomplete-and-experimental-compiler-do-not-use`\n\nor by " + "defining the following environment variable (any value will " + "do)\n\nGCCRS_INCOMPLETE_AND_EXPERIMENTAL_COMPILER_DO_NOT_USE\n\nFor " + "cargo-gccrs, this means passing\n\n" + "GCCRS_EXTRA_ARGS=\"-frust-incomplete-and-experimental-compiler-do-not-" + "use\"\n\nas an environment variable."); + + RAIIFile file_wrap(filename); + if (!file_wrap.ok()) { + rust_error_at(UNDEF_LOCATION, "cannot open filename %s: %m", filename); + return; + } - auto last_step = options.get_compile_until (); + auto last_step = options.get_compile_until(); // parse file here /* create lexer and parser - these are file-specific and so aren't instance * variables */ tl::optional dump_lex_opt = tl::nullopt; std::ofstream dump_lex_stream; - if (options.dump_option_enabled (CompileOptions::LEXER_DUMP)) - { - dump_lex_stream.open (kLexDumpFile); - if (dump_lex_stream.fail ()) - rust_error_at (UNKNOWN_LOCATION, "cannot open %s:%m; ignored", - kLexDumpFile); - - dump_lex_opt = dump_lex_stream; - } + if (options.dump_option_enabled(CompileOptions::LEXER_DUMP)) { + dump_lex_stream.open(kLexDumpFile); + if (dump_lex_stream.fail()) + rust_error_at(UNKNOWN_LOCATION, "cannot open %s:%m; ignored", + kLexDumpFile); - Lexer lex (filename, std::move (file_wrap), linemap, dump_lex_opt); + dump_lex_opt = dump_lex_stream; + } - if (!lex.input_source_is_valid_utf8 ()) - { - rust_error_at (UNKNOWN_LOCATION, - "cannot read %s; stream did not contain valid UTF-8", - filename); - return; - } + Lexer lex(filename, std::move(file_wrap), linemap, dump_lex_opt); + + if (!lex.input_source_is_valid_utf8()) { + rust_error_at(UNKNOWN_LOCATION, + "cannot read %s; stream did not contain valid UTF-8", + filename); + return; + } - Parser parser (lex); + Parser parser(lex); // generate crate from parser - std::unique_ptr ast_crate = parser.parse_crate (); + std::unique_ptr ast_crate = parser.parse_crate(); // handle crate name - handle_crate_name (*ast_crate.get ()); + handle_crate_name(*ast_crate.get()); // dump options except lexer dump - if (options.dump_option_enabled (CompileOptions::AST_DUMP_PRETTY)) - { - dump_ast_pretty (*ast_crate.get ()); - } - if (options.dump_option_enabled (CompileOptions::TARGET_OPTION_DUMP)) - { - options.target_data.dump_target_options (); - } - - if (saw_errors ()) + if (options.dump_option_enabled(CompileOptions::AST_DUMP_PRETTY)) { + dump_ast_pretty(*ast_crate.get()); + } + if (options.dump_option_enabled(CompileOptions::TARGET_OPTION_DUMP)) { + options.target_data.dump_target_options(); + } + + if (saw_errors()) return; // setup the mappings for this AST - CrateNum current_crate = mappings->get_current_crate (); - AST::Crate &parsed_crate - = mappings->insert_ast_crate (std::move (ast_crate), current_crate); + CrateNum current_crate = mappings->get_current_crate(); + AST::Crate &parsed_crate = + mappings->insert_ast_crate(std::move(ast_crate), current_crate); /* basic pipeline: * - lex @@ -553,7 +481,7 @@ Session::compile_crate (const char *filename) * maybe buffered lints) * TODO not done */ - rust_debug ("\033[0;31mSUCCESSFULLY PARSED CRATE \033[0m"); + rust_debug("\033[0;31mSUCCESSFULLY PARSED CRATE \033[0m"); // If -fsyntax-only was passed, we can just skip the remaining passes. // Parsing errors are already emitted in `parse_crate()` @@ -561,105 +489,105 @@ Session::compile_crate (const char *filename) return; // register plugins pipeline stage - register_plugins (parsed_crate); - rust_debug ("\033[0;31mSUCCESSFULLY REGISTERED PLUGINS \033[0m"); - if (options.dump_option_enabled (CompileOptions::REGISTER_PLUGINS_DUMP)) - { - // TODO: what do I dump here? - } + register_plugins(parsed_crate); + rust_debug("\033[0;31mSUCCESSFULLY REGISTERED PLUGINS \033[0m"); + if (options.dump_option_enabled(CompileOptions::REGISTER_PLUGINS_DUMP)) { + // TODO: what do I dump here? + } // injection pipeline stage - injection (parsed_crate); - rust_debug ("\033[0;31mSUCCESSFULLY FINISHED INJECTION \033[0m"); - if (options.dump_option_enabled (CompileOptions::INJECTION_DUMP)) - { - // TODO: what do I dump here? injected crate names? - } + injection(parsed_crate); + rust_debug("\033[0;31mSUCCESSFULLY FINISHED INJECTION \033[0m"); + if (options.dump_option_enabled(CompileOptions::INJECTION_DUMP)) { + // TODO: what do I dump here? injected crate names? + } if (last_step == CompileOptions::CompileStep::AttributeCheck) return; - Analysis::AttributeChecker ().go (parsed_crate); + 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"); - if (options.dump_option_enabled (CompileOptions::EXPANSION_DUMP)) - { - // dump AST with expanded stuff - rust_debug ("BEGIN POST-EXPANSION AST DUMP"); - dump_ast_pretty (parsed_crate, true); - rust_debug ("END POST-EXPANSION AST DUMP"); - } + expansion(parsed_crate); + rust_debug("\033[0;31mSUCCESSFULLY FINISHED EXPANSION \033[0m"); + if (options.dump_option_enabled(CompileOptions::EXPANSION_DUMP)) { + // dump AST with expanded stuff + rust_debug("BEGIN POST-EXPANSION AST DUMP"); + dump_ast_pretty(parsed_crate, true); + rust_debug("END POST-EXPANSION AST DUMP"); + } // feature gating - FeatureGate ().check (parsed_crate); + FeatureGate().check(parsed_crate); if (last_step == CompileOptions::CompileStep::NameResolution) return; // resolution pipeline stage - Resolver::NameResolution::Resolve (parsed_crate); + Resolver::NameResolution::Resolve(parsed_crate); - if (options.dump_option_enabled (CompileOptions::RESOLUTION_DUMP)) - { - // TODO: what do I dump here? resolved names? AST with resolved names? - } + if (options.dump_option_enabled(CompileOptions::RESOLUTION_DUMP)) { + // TODO: what do I dump here? resolved names? AST with resolved names? + } - if (saw_errors ()) + if (saw_errors()) return; if (last_step == CompileOptions::CompileStep::Lowering) return; // lower AST to HIR - std::unique_ptr lowered - = HIR::ASTLowering::Resolve (parsed_crate); - if (saw_errors ()) + std::unique_ptr lowered = HIR::ASTLowering::Resolve(parsed_crate); + if (saw_errors()) return; // add the mappings to it - HIR::Crate &hir = mappings->insert_hir_crate (std::move (lowered)); - if (options.dump_option_enabled (CompileOptions::HIR_DUMP)) - { - dump_hir (hir); - } - if (options.dump_option_enabled (CompileOptions::HIR_DUMP_PRETTY)) - { - dump_hir_pretty (hir); - } + HIR::Crate &hir = mappings->insert_hir_crate(std::move(lowered)); + if (options.dump_option_enabled(CompileOptions::HIR_DUMP)) { + dump_hir(hir); + } + if (options.dump_option_enabled(CompileOptions::HIR_DUMP_PRETTY)) { + dump_hir_pretty(hir); + } if (last_step == CompileOptions::CompileStep::TypeCheck) return; // type resolve - Resolver::TypeResolution::Resolve (hir); + Resolver::TypeResolution::Resolve(hir); - if (saw_errors ()) + 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 ()) + Privacy::Resolver::resolve(hir); + if (saw_errors()) return; if (last_step == CompileOptions::CompileStep::Unsafety) return; - HIR::UnsafeChecker ().go (hir); + HIR::UnsafeChecker().go(hir); if (last_step == CompileOptions::CompileStep::Const) return; - HIR::ConstChecker ().go (hir); + HIR::ConstChecker().go(hir); + + if (last_step == CompileOptions::CompileStep::BorrowCheck) + return; + + const bool dump_bir = + options.dump_option_enabled(CompileOptions::DumpOption::BIR_DUMP); + HIR::BorrowChecker(dump_bir).go(hir); - if (saw_errors ()) + if (saw_errors()) return; if (last_step == CompileOptions::CompileStep::Compilation) @@ -667,61 +595,49 @@ Session::compile_crate (const char *filename) // do compile to gcc generic Compile::Context ctx; - Compile::CompileCrate::Compile (hir, &ctx); + Compile::CompileCrate::Compile(hir, &ctx); // we can't do static analysis if there are errors to worry about - if (!saw_errors ()) - { - // lints - Analysis::ScanDeadcode::Scan (hir); - Analysis::UnusedVariables::Lint (ctx); - Analysis::ReadonlyCheck::Lint (ctx); - - // metadata - bool specified_emit_metadata - = flag_rust_embed_metadata || options.metadata_output_path_set (); - if (!specified_emit_metadata) - { - Metadata::PublicInterface::ExportTo ( - hir, Metadata::PublicInterface::expected_metadata_filename ()); - } - else - { - if (flag_rust_embed_metadata) - Metadata::PublicInterface::Export (hir); - if (options.metadata_output_path_set ()) - Metadata::PublicInterface::ExportTo ( - hir, options.get_metadata_output ()); - } + if (!saw_errors()) { + // lints + Analysis::ScanDeadcode::Scan(hir); + Analysis::UnusedVariables::Lint(ctx); + Analysis::ReadonlyCheck::Lint(ctx); + + // metadata + bool specified_emit_metadata = + flag_rust_embed_metadata || options.metadata_output_path_set(); + if (!specified_emit_metadata) { + Metadata::PublicInterface::ExportTo( + hir, Metadata::PublicInterface::expected_metadata_filename()); + } else { + if (flag_rust_embed_metadata) + Metadata::PublicInterface::Export(hir); + if (options.metadata_output_path_set()) + Metadata::PublicInterface::ExportTo(hir, options.get_metadata_output()); } + } // pass to GCC middle-end - ctx.write_to_backend (); + ctx.write_to_backend(); } -void -Session::register_plugins (AST::Crate &crate ATTRIBUTE_UNUSED) -{ - rust_debug ("ran register_plugins (with no body)"); +void Session::register_plugins(AST::Crate &crate ATTRIBUTE_UNUSED) { + rust_debug("ran register_plugins (with no body)"); } // TODO: move somewhere else -bool -contains_name (const AST::AttrVec &attrs, std::string name) -{ - for (const auto &attr : attrs) - { - if (attr.get_path () == name) - return true; - } +bool contains_name(const AST::AttrVec &attrs, std::string name) { + for (const auto &attr : attrs) { + if (attr.get_path() == name) + return true; + } return false; } -void -Session::injection (AST::Crate &crate) -{ - rust_debug ("started injection"); +void Session::injection(AST::Crate &crate) { + rust_debug("started injection"); // lint checks in future maybe? @@ -776,47 +692,40 @@ Session::injection (AST::Crate &crate) // crate injection std::vector names; - if (contains_name (crate.inner_attrs, "no_core")) - { - // no prelude - injected_crate_name = ""; + if (contains_name(crate.inner_attrs, "no_core")) { + // no prelude + injected_crate_name = ""; + } else if (contains_name(crate.inner_attrs, "no_std")) { + names.push_back("core"); + + if (!contains_name(crate.inner_attrs, "compiler_builtins")) { + names.push_back("compiler_builtins"); } - else if (contains_name (crate.inner_attrs, "no_std")) - { - names.push_back ("core"); - if (!contains_name (crate.inner_attrs, "compiler_builtins")) - { - names.push_back ("compiler_builtins"); - } + injected_crate_name = "core"; + } else { + names.push_back("std"); - injected_crate_name = "core"; - } - else - { - names.push_back ("std"); - - injected_crate_name = "std"; - } + injected_crate_name = "std"; + } // reverse iterate through names to insert crate items in "forward" order at // beginning of crate - for (auto it = names.rbegin (); it != names.rend (); ++it) - { - // create "macro use" attribute for use on extern crate item to enable - // loading macros from it - AST::Attribute attr (AST::SimplePath::from_str ( - Values::Attributes::MACRO_USE, UNDEF_LOCATION), - nullptr); - - // create "extern crate" item with the name - std::unique_ptr extern_crate ( - new AST::ExternCrate (*it, AST::Visibility::create_error (), - {std::move (attr)}, UNKNOWN_LOCATION)); - - // insert at beginning - // crate.items.insert (crate.items.begin (), std::move (extern_crate)); - } + for (auto it = names.rbegin(); it != names.rend(); ++it) { + // create "macro use" attribute for use on extern crate item to enable + // loading macros from it + AST::Attribute attr(AST::SimplePath::from_str(Values::Attributes::MACRO_USE, + UNDEF_LOCATION), + nullptr); + + // create "extern crate" item with the name + std::unique_ptr extern_crate( + new AST::ExternCrate(*it, AST::Visibility::create_error(), + {std::move(attr)}, UNKNOWN_LOCATION)); + + // insert at beginning + // crate.items.insert (crate.items.begin (), std::move (extern_crate)); + } // create use tree path // prelude is injected_crate_name @@ -850,13 +759,11 @@ Session::injection (AST::Crate &crate) // this crate type will have options affecting the metadata ouput - rust_debug ("finished injection"); + rust_debug("finished injection"); } -void -Session::expansion (AST::Crate &crate) -{ - rust_debug ("started expansion"); +void Session::expansion(AST::Crate &crate) { + rust_debug("started expansion"); /* rustc has a modification to windows PATH temporarily here, which may end * up being required */ @@ -871,53 +778,49 @@ Session::expansion (AST::Crate &crate) // create extctxt? from parse session, cfg, and resolver? /* expand by calling cxtctxt object's monotonic_expander's expand_crate * method. */ - MacroExpander expander (crate, cfg, *this); + MacroExpander expander(crate, cfg, *this); std::vector macro_errors; - while (!fixed_point_reached && iterations < cfg.recursion_limit) - { - CfgStrip ().go (crate); - // Errors might happen during cfg strip pass - if (saw_errors ()) - break; - - auto ctx = Resolver2_0::NameResolutionContext (); - - if (flag_name_resolution_2_0) - { - Resolver2_0::Early early (ctx); - early.go (crate); - macro_errors = early.get_macro_resolve_errors (); - } - else - Resolver::EarlyNameResolver ().go (crate); + while (!fixed_point_reached && iterations < cfg.recursion_limit) { + CfgStrip().go(crate); + // Errors might happen during cfg strip pass + if (saw_errors()) + break; - ExpandVisitor (expander).go (crate); + auto ctx = Resolver2_0::NameResolutionContext(); - fixed_point_reached = !expander.has_changed (); - expander.reset_changed_state (); - iterations++; + if (flag_name_resolution_2_0) { + Resolver2_0::Early early(ctx); + early.go(crate); + macro_errors = early.get_macro_resolve_errors(); + } else + Resolver::EarlyNameResolver().go(crate); - if (saw_errors ()) - break; - } + ExpandVisitor(expander).go(crate); + + fixed_point_reached = !expander.has_changed(); + expander.reset_changed_state(); + iterations++; + + if (saw_errors()) + break; + } // Fixed point reached: Emit unresolved macros error for (auto &error : macro_errors) - error.emit (); + error.emit(); - if (iterations == cfg.recursion_limit) - { - auto &last_invoc = expander.get_last_invocation (); - auto &last_def = expander.get_last_definition (); + if (iterations == cfg.recursion_limit) { + auto &last_invoc = expander.get_last_invocation(); + auto &last_def = expander.get_last_definition(); - rust_assert (last_def.has_value () && last_invoc.has_value ()); + rust_assert(last_def.has_value() && last_invoc.has_value()); - rich_location range (line_table, last_invoc->get_locus ()); - range.add_range (last_def->get_locus ()); + rich_location range(line_table, last_invoc->get_locus()); + range.add_range(last_def->get_locus()); - rust_error_at (range, "reached recursion limit"); - } + rust_error_at(range, "reached recursion limit"); + } // error reporting - check unused macros, get missing fragment specifiers @@ -927,288 +830,254 @@ Session::expansion (AST::Crate &crate) // maybe create macro crate if not rustdoc - rust_debug ("finished expansion"); + rust_debug("finished expansion"); } -void -Session::dump_ast_pretty (AST::Crate &crate, bool expanded) const -{ +void Session::dump_ast_pretty(AST::Crate &crate, bool expanded) const { std::ofstream out; if (expanded) - out.open (kASTPrettyDumpFileExpanded); + out.open(kASTPrettyDumpFileExpanded); else - out.open (kASTPrettyDumpFile); + out.open(kASTPrettyDumpFile); - if (out.fail ()) - { - rust_error_at (UNKNOWN_LOCATION, "cannot open %s:%m; ignored", - kASTDumpFile); - return; - } + if (out.fail()) { + rust_error_at(UNKNOWN_LOCATION, "cannot open %s:%m; ignored", kASTDumpFile); + return; + } - AST::Dump (out).go (crate); + AST::Dump(out).go(crate); - out.close (); + out.close(); } -void -Session::dump_hir (HIR::Crate &crate) const -{ +void Session::dump_hir(HIR::Crate &crate) const { std::ofstream out; - out.open (kHIRDumpFile); - if (out.fail ()) - { - rust_error_at (UNKNOWN_LOCATION, "cannot open %s:%m; ignored", - kHIRDumpFile); - return; - } + out.open(kHIRDumpFile); + if (out.fail()) { + rust_error_at(UNKNOWN_LOCATION, "cannot open %s:%m; ignored", kHIRDumpFile); + return; + } - out << crate.as_string (); - out.close (); + out << crate.as_string(); + out.close(); } -void -Session::dump_hir_pretty (HIR::Crate &crate) const -{ +void Session::dump_hir_pretty(HIR::Crate &crate) const { std::ofstream out; - out.open (kHIRPrettyDumpFile); - if (out.fail ()) - { - rust_error_at (UNKNOWN_LOCATION, "cannot open %s:%m; ignored", - kHIRPrettyDumpFile); - return; - } + out.open(kHIRPrettyDumpFile); + if (out.fail()) { + rust_error_at(UNKNOWN_LOCATION, "cannot open %s:%m; ignored", + kHIRPrettyDumpFile); + return; + } - HIR::Dump (out).go (crate); - out.close (); + HIR::Dump(out).go(crate); + out.close(); } // imports -NodeId -Session::load_extern_crate (const std::string &crate_name, location_t locus) -{ +NodeId Session::load_extern_crate(const std::string &crate_name, + location_t locus) { // has it already been loaded? CrateNum found_crate_num = UNKNOWN_CRATENUM; - bool found = mappings->lookup_crate_name (crate_name, found_crate_num); - if (found) - { - NodeId resolved_node_id = UNKNOWN_NODEID; - bool resolved - = mappings->crate_num_to_nodeid (found_crate_num, resolved_node_id); - rust_assert (resolved); - - return resolved_node_id; - } + bool found = mappings->lookup_crate_name(crate_name, found_crate_num); + if (found) { + NodeId resolved_node_id = UNKNOWN_NODEID; + bool resolved = + mappings->crate_num_to_nodeid(found_crate_num, resolved_node_id); + rust_assert(resolved); + + return resolved_node_id; + } std::string relative_import_path = ""; std::string import_name = crate_name; // The path to the extern crate might have been specified by the user using // -frust-extern - auto cli_extern_crate = extern_crates.find (crate_name); + auto cli_extern_crate = extern_crates.find(crate_name); std::pair, std::vector> - package_result; - if (cli_extern_crate != extern_crates.end ()) - { - auto path = cli_extern_crate->second; - package_result = Import::try_package_in_directory (path, locus); - } - else - { - package_result - = Import::open_package (import_name, locus, relative_import_path); - } - - auto stream = std::move (package_result.first); - auto proc_macros = std::move (package_result.second); - - if (stream == NULL // No stream and - && proc_macros.empty ()) // no proc macros - { - rust_error_at (locus, "failed to locate crate %<%s%>", - import_name.c_str ()); + package_result; + if (cli_extern_crate != extern_crates.end()) { + auto path = cli_extern_crate->second; + package_result = Import::try_package_in_directory(path, locus); + } else { + package_result = + Import::open_package(import_name, locus, relative_import_path); + } + + auto stream = std::move(package_result.first); + auto proc_macros = std::move(package_result.second); + + if (stream == NULL // No stream and + && proc_macros.empty()) // no proc macros + { + rust_error_at(locus, "failed to locate crate %<%s%>", import_name.c_str()); + return UNKNOWN_NODEID; + } + + auto extern_crate = + stream == nullptr + ? Imports::ExternCrate(crate_name, + proc_macros) // Import proc macros + : Imports::ExternCrate(*stream); // Import from stream + if (stream != nullptr) { + bool ok = extern_crate.load(locus); + if (!ok) { + rust_error_at(locus, "failed to load crate metadata"); return UNKNOWN_NODEID; } - - auto extern_crate - = stream == nullptr - ? Imports::ExternCrate (crate_name, - proc_macros) // Import proc macros - : Imports::ExternCrate (*stream); // Import from stream - if (stream != nullptr) - { - bool ok = extern_crate.load (locus); - if (!ok) - { - rust_error_at (locus, "failed to load crate metadata"); - return UNKNOWN_NODEID; - } - } + } // ensure the current vs this crate name don't collide - const std::string current_crate_name = mappings->get_current_crate_name (); - if (current_crate_name.compare (extern_crate.get_crate_name ()) == 0) - { - rust_error_at (locus, "current crate name %<%s%> collides with this", - current_crate_name.c_str ()); - return UNKNOWN_NODEID; - } + const std::string current_crate_name = mappings->get_current_crate_name(); + if (current_crate_name.compare(extern_crate.get_crate_name()) == 0) { + rust_error_at(locus, "current crate name %<%s%> collides with this", + current_crate_name.c_str()); + return UNKNOWN_NODEID; + } // setup mappings - CrateNum saved_crate_num = mappings->get_current_crate (); - CrateNum crate_num - = mappings->get_next_crate_num (extern_crate.get_crate_name ()); - mappings->set_current_crate (crate_num); + CrateNum saved_crate_num = mappings->get_current_crate(); + CrateNum crate_num = + mappings->get_next_crate_num(extern_crate.get_crate_name()); + mappings->set_current_crate(crate_num); // then lets parse this as a 2nd crate - Lexer lex (extern_crate.get_metadata (), linemap); - Parser parser (lex); - std::unique_ptr metadata_crate = parser.parse_crate (); + Lexer lex(extern_crate.get_metadata(), linemap); + Parser parser(lex); + std::unique_ptr metadata_crate = parser.parse_crate(); - AST::Crate &parsed_crate - = mappings->insert_ast_crate (std::move (metadata_crate), crate_num); + AST::Crate &parsed_crate = + mappings->insert_ast_crate(std::move(metadata_crate), crate_num); std::vector attribute_macros; std::vector derive_macros; std::vector bang_macros; - for (auto ¯o : extern_crate.get_proc_macros ()) - { - switch (macro.tag) - { - case ProcMacro::CUSTOM_DERIVE: - derive_macros.push_back (macro.payload.custom_derive); - break; - case ProcMacro::ATTR: - attribute_macros.push_back (macro.payload.attribute); - break; - case ProcMacro::BANG: - bang_macros.push_back (macro.payload.bang); - break; - default: - gcc_unreachable (); - } + for (auto ¯o : extern_crate.get_proc_macros()) { + switch (macro.tag) { + case ProcMacro::CUSTOM_DERIVE: + derive_macros.push_back(macro.payload.custom_derive); + break; + case ProcMacro::ATTR: + attribute_macros.push_back(macro.payload.attribute); + break; + case ProcMacro::BANG: + bang_macros.push_back(macro.payload.bang); + break; + default: + gcc_unreachable(); } + } - mappings->insert_attribute_proc_macros (crate_num, attribute_macros); - mappings->insert_bang_proc_macros (crate_num, bang_macros); - mappings->insert_derive_proc_macros (crate_num, derive_macros); + mappings->insert_attribute_proc_macros(crate_num, attribute_macros); + mappings->insert_bang_proc_macros(crate_num, bang_macros); + mappings->insert_derive_proc_macros(crate_num, derive_macros); // name resolve it - Resolver::NameResolution::Resolve (parsed_crate); + Resolver::NameResolution::Resolve(parsed_crate); // perform hir lowering - std::unique_ptr lowered - = HIR::ASTLowering::Resolve (parsed_crate); - HIR::Crate &hir = mappings->insert_hir_crate (std::move (lowered)); + std::unique_ptr lowered = HIR::ASTLowering::Resolve(parsed_crate); + HIR::Crate &hir = mappings->insert_hir_crate(std::move(lowered)); // perform type resolution - Resolver::TypeResolution::Resolve (hir); + Resolver::TypeResolution::Resolve(hir); // always restore the crate_num - mappings->set_current_crate (saved_crate_num); + mappings->set_current_crate(saved_crate_num); - return parsed_crate.get_node_id (); + return parsed_crate.get_node_id(); } // -void -TargetOptions::dump_target_options () const -{ +void TargetOptions::dump_target_options() const { std::ofstream out; - out.open (kTargetOptionsDumpFile); - if (out.fail ()) - { - rust_error_at (UNKNOWN_LOCATION, "cannot open %s:%m; ignored", - kTargetOptionsDumpFile); - return; - } + out.open(kTargetOptionsDumpFile); + if (out.fail()) { + rust_error_at(UNKNOWN_LOCATION, "cannot open %s:%m; ignored", + kTargetOptionsDumpFile); + return; + } - if (features.empty ()) - { - out << "No target options available!\n"; - } + if (features.empty()) { + out << "No target options available!\n"; + } - for (const auto &pairs : features) - { - for (const auto &value : pairs.second) - { - if (value.has_value ()) - out << pairs.first + ": \"" + value.value () + "\"\n"; - else - out << pairs.first + "\n"; - } + for (const auto &pairs : features) { + for (const auto &value : pairs.second) { + if (value.has_value()) + out << pairs.first + ": \"" + value.value() + "\"\n"; + else + out << pairs.first + "\n"; } + } - out.close (); + out.close(); } -void -TargetOptions::init_derived_values () -{ +void TargetOptions::init_derived_values() { // enable derived values based on target families - if (has_key_value_pair ("target_family", "unix")) - insert_key ("unix"); - if (has_key_value_pair ("target_family", "windows")) - insert_key ("windows"); + if (has_key_value_pair("target_family", "unix")) + insert_key("unix"); + if (has_key_value_pair("target_family", "windows")) + insert_key("windows"); // implicitly enable features - this should not be required in general - if (has_key_value_pair ("target_feature", "aes")) - enable_implicit_feature_reqs ("aes"); - if (has_key_value_pair ("target_feature", "avx")) - enable_implicit_feature_reqs ("sse4.2"); - if (has_key_value_pair ("target_feature", "avx2")) - enable_implicit_feature_reqs ("avx"); - if (has_key_value_pair ("target_feature", "pclmulqdq")) - enable_implicit_feature_reqs ("sse2"); - if (has_key_value_pair ("target_feature", "sha")) - enable_implicit_feature_reqs ("sse2"); - if (has_key_value_pair ("target_feature", "sse2")) - enable_implicit_feature_reqs ("sse"); - if (has_key_value_pair ("target_feature", "sse3")) - enable_implicit_feature_reqs ("sse2"); - if (has_key_value_pair ("target_feature", "sse4.1")) - enable_implicit_feature_reqs ("sse3"); - if (has_key_value_pair ("target_feature", "sse4.2")) - enable_implicit_feature_reqs ("sse4.1"); - if (has_key_value_pair ("target_feature", "ssse3")) - enable_implicit_feature_reqs ("sse3"); + if (has_key_value_pair("target_feature", "aes")) + enable_implicit_feature_reqs("aes"); + if (has_key_value_pair("target_feature", "avx")) + enable_implicit_feature_reqs("sse4.2"); + if (has_key_value_pair("target_feature", "avx2")) + enable_implicit_feature_reqs("avx"); + if (has_key_value_pair("target_feature", "pclmulqdq")) + enable_implicit_feature_reqs("sse2"); + if (has_key_value_pair("target_feature", "sha")) + enable_implicit_feature_reqs("sse2"); + if (has_key_value_pair("target_feature", "sse2")) + enable_implicit_feature_reqs("sse"); + if (has_key_value_pair("target_feature", "sse3")) + enable_implicit_feature_reqs("sse2"); + if (has_key_value_pair("target_feature", "sse4.1")) + enable_implicit_feature_reqs("sse3"); + if (has_key_value_pair("target_feature", "sse4.2")) + enable_implicit_feature_reqs("sse4.1"); + if (has_key_value_pair("target_feature", "ssse3")) + enable_implicit_feature_reqs("sse3"); } -void -TargetOptions::enable_implicit_feature_reqs (std::string feature) -{ +void TargetOptions::enable_implicit_feature_reqs(std::string feature) { if (feature == "aes") - enable_implicit_feature_reqs ("sse2"); + enable_implicit_feature_reqs("sse2"); else if (feature == "avx") - enable_implicit_feature_reqs ("sse4.2"); + enable_implicit_feature_reqs("sse4.2"); else if (feature == "avx2") - enable_implicit_feature_reqs ("avx"); + enable_implicit_feature_reqs("avx"); else if (feature == "fma") - enable_implicit_feature_reqs ("avx"); + enable_implicit_feature_reqs("avx"); else if (feature == "pclmulqdq") - enable_implicit_feature_reqs ("sse2"); + enable_implicit_feature_reqs("sse2"); else if (feature == "sha") - enable_implicit_feature_reqs ("sse2"); + enable_implicit_feature_reqs("sse2"); else if (feature == "sse2") - enable_implicit_feature_reqs ("sse"); + enable_implicit_feature_reqs("sse"); else if (feature == "sse3") - enable_implicit_feature_reqs ("sse2"); + enable_implicit_feature_reqs("sse2"); else if (feature == "sse4.1") - enable_implicit_feature_reqs ("sse3"); + enable_implicit_feature_reqs("sse3"); else if (feature == "sse4.2") - enable_implicit_feature_reqs ("sse4.1"); + enable_implicit_feature_reqs("sse4.1"); else if (feature == "ssse3") - enable_implicit_feature_reqs ("sse3"); + enable_implicit_feature_reqs("sse3"); - if (!has_key_value_pair ("target_feature", feature)) - { - insert_key_value_pair ("target_feature", feature); + if (!has_key_value_pair("target_feature", feature)) { + insert_key_value_pair("target_feature", feature); - rust_debug ("had to implicitly enable feature '%s'!", feature.c_str ()); - } + rust_debug("had to implicitly enable feature '%s'!", feature.c_str()); + } } // NOTEs: @@ -1309,34 +1178,32 @@ TargetOptions::enable_implicit_feature_reqs (std::string feature) #if CHECKING_P namespace selftest { -void -rust_crate_name_validation_test (void) -{ - auto error = Rust::Error (UNDEF_LOCATION, std::string ()); - ASSERT_TRUE (Rust::validate_crate_name ("example", error)); - ASSERT_TRUE (Rust::validate_crate_name ("abcdefg_1234", error)); - ASSERT_TRUE (Rust::validate_crate_name ("1", error)); - ASSERT_TRUE (Rust::validate_crate_name ("クレート", error)); - ASSERT_TRUE (Rust::validate_crate_name ("Sōkrátēs", error)); - ASSERT_TRUE (Rust::validate_crate_name ("惊吓", error)); +void rust_crate_name_validation_test(void) { + auto error = Rust::Error(UNDEF_LOCATION, std::string()); + ASSERT_TRUE(Rust::validate_crate_name("example", error)); + ASSERT_TRUE(Rust::validate_crate_name("abcdefg_1234", error)); + ASSERT_TRUE(Rust::validate_crate_name("1", error)); + ASSERT_TRUE(Rust::validate_crate_name("クレート", error)); + ASSERT_TRUE(Rust::validate_crate_name("Sōkrátēs", error)); + ASSERT_TRUE(Rust::validate_crate_name("惊吓", error)); // NOTE: - is not allowed in the crate name ... - ASSERT_FALSE (Rust::validate_crate_name ("abcdefg-1234", error)); - ASSERT_FALSE (Rust::validate_crate_name ("a+b", error)); - ASSERT_FALSE (Rust::validate_crate_name ("/a+b/", error)); - ASSERT_FALSE (Rust::validate_crate_name ("😸++", error)); - ASSERT_FALSE (Rust::validate_crate_name ("∀", error)); + ASSERT_FALSE(Rust::validate_crate_name("abcdefg-1234", error)); + ASSERT_FALSE(Rust::validate_crate_name("a+b", error)); + ASSERT_FALSE(Rust::validate_crate_name("/a+b/", error)); + ASSERT_FALSE(Rust::validate_crate_name("😸++", error)); + ASSERT_FALSE(Rust::validate_crate_name("∀", error)); /* Tests for crate name inference */ - ASSERT_EQ (Rust::infer_crate_name ("c.rs"), "c"); + ASSERT_EQ(Rust::infer_crate_name("c.rs"), "c"); // NOTE: ... but - is allowed when in the filename - ASSERT_EQ (Rust::infer_crate_name ("a-b.rs"), "a_b"); - ASSERT_EQ (Rust::infer_crate_name ("book.rs.txt"), "book.rs"); + ASSERT_EQ(Rust::infer_crate_name("a-b.rs"), "a_b"); + ASSERT_EQ(Rust::infer_crate_name("book.rs.txt"), "book.rs"); #if defined(HAVE_DOS_BASED_FILE_SYSTEM) - ASSERT_EQ (Rust::infer_crate_name ("a\\c\\a-b.rs"), "a_b"); + ASSERT_EQ(Rust::infer_crate_name("a\\c\\a-b.rs"), "a_b"); #else - ASSERT_EQ (Rust::infer_crate_name ("a/c/a-b.rs"), "a_b"); + ASSERT_EQ(Rust::infer_crate_name("a/c/a-b.rs"), "a_b"); #endif } } // namespace selftest diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h index 75c7b3860a0a..e95ed11416f7 100644 --- a/gcc/rust/rust-session-manager.h +++ b/gcc/rust/rust-session-manager.h @@ -221,6 +221,7 @@ struct CompileOptions TARGET_OPTION_DUMP, HIR_DUMP, HIR_DUMP_PRETTY, + BIR_DUMP, }; std::set dump_options; @@ -254,6 +255,7 @@ struct CompileOptions Privacy, Unsafety, Const, + BorrowCheck, Compilation, End, } compile_until @@ -277,6 +279,7 @@ struct CompileOptions enable_dump_option (DumpOption::TARGET_OPTION_DUMP); enable_dump_option (DumpOption::HIR_DUMP); enable_dump_option (DumpOption::HIR_DUMP_PRETTY); + enable_dump_option (DumpOption::BIR_DUMP); } void set_crate_name (std::string name)