diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/rust-session-manager.cc | 46 | ||||
-rw-r--r-- | gcc/rust/rust-session-manager.h | 40 |
2 files changed, 80 insertions, 6 deletions
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc index ec99be7..1a6afd7 100644 --- a/gcc/rust/rust-session-manager.cc +++ b/gcc/rust/rust-session-manager.cc @@ -54,7 +54,28 @@ const char *kHIRDumpFile = "gccrs.hir.dump"; const char *kHIRTypeResolutionDumpFile = "gccrs.type-resolution.dump"; const char *kTargetOptionsDumpFile = "gccrs.target-options.dump"; -const std::string kDefaultCrateName = "example"; +const std::string kDefaultCrateName = "rust_out"; + +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); + + // find the base filename + if (path_sep != std::string::npos) + crate.erase (0, path_sep + 1); + + // find the file stem name (remove file extension) + size_t ext_position = crate.find_last_of ('.'); + if (ext_position != std::string::npos) + crate.erase (ext_position); + + return crate; +} // Implicitly enable a target_feature (and recursively enable dependencies). void @@ -311,10 +332,6 @@ Session::init () // setup backend to GCC GIMPLE backend = rust_get_backend (); - - // set the default crate name if crate name was unset - if (options.crate_name.empty ()) - options.set_crate_name (kDefaultCrateName); } /* Initialise default options. Actually called before handle_option, unlike init @@ -479,6 +496,25 @@ Session::enable_dump (std::string arg) void Session::parse_files (int num_files, const char **files) { + rust_assert (num_files > 0); + + if (options.crate_name.empty ()) + { + /* HACK: We use the first file to infer the crate name, which might be + * incorrect: since rustc only allows one file to be supplied in the + * command-line */ + auto crate_name = infer_crate_name (files[0]); + rust_debug_loc (Location (), "inferred crate name: %s", + crate_name.c_str ()); + if (!options.set_crate_name (crate_name)) + { + rust_inform (Location (), + "crate name inferred from the input file %<%s%>", + files[0]); + return; + } + } + auto mappings = Analysis::Mappings::get (); CrateNum crate_num = mappings->setup_crate_mappings (options.crate_name); mappings->set_current_crate (crate_num); diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h index 8fcc5dd..d4fae27 100644 --- a/gcc/rust/rust-session-manager.h +++ b/gcc/rust/rust-session-manager.h @@ -41,6 +41,8 @@ namespace HIR { struct Crate; } +const size_t kMaxNameLength = 64; + /* Data related to target, most useful for conditional compilation and * whatever. */ struct TargetOptions @@ -212,9 +214,45 @@ struct CompileOptions enable_dump_option (DumpOption::TYPE_RESOLUTION_DUMP); } + /* Validate the crate name using the ASCII rules + TODO: Support Unicode version of the rules */ + bool validate_crate_name (const std::string &crate_name) + { + if (crate_name.empty ()) + { + rust_error_at (Location (), "crate name cannot be empty"); + return false; + } + if (crate_name.length () > kMaxNameLength) + { + rust_error_at (Location (), "crate name cannot exceed %ld characters", + kMaxNameLength); + return false; + } + for (auto &c : crate_name) + { + if (!(ISALNUM (c) || c == '_' || c == '-')) + { + rust_error_at (Location (), + "invalid character %<%c%> in crate name: %<%s%>", c, + crate_name.c_str ()); + return false; + } + } + return true; + } + bool set_crate_name (std::string name) { - // TODO: validate the crate name? + if (!validate_crate_name (name)) + return false; + + /* Replace all the '-' symbols with '_' per Rust rules */ + for (auto &c : name) + { + if (c == '-') + c = '_'; + } crate_name = std::move (name); return true; } |