diff options
author | CohenArthur <arthur.cohen@epita.fr> | 2021-08-25 13:51:49 +0200 |
---|---|---|
committer | CohenArthur <arthur.cohen@epita.fr> | 2021-08-25 14:18:01 +0200 |
commit | c3f146d98df60106138c4ca2f0775e7c713a57f3 (patch) | |
tree | a7a465f826eaec21a23f52d927464af68113c8bf /gcc | |
parent | 5b509a775f91da0678875ac381a655fd2ba1fd48 (diff) | |
download | gcc-c3f146d98df60106138c4ca2f0775e7c713a57f3.zip gcc-c3f146d98df60106138c4ca2f0775e7c713a57f3.tar.gz gcc-c3f146d98df60106138c4ca2f0775e7c713a57f3.tar.bz2 |
module: Allow external module path to come from #[path] attribute
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/ast/rust-ast-full-test.cc | 54 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast.h | 2 |
2 files changed, 50 insertions, 6 deletions
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc index 6033ce9..c18d4c4 100644 --- a/gcc/rust/ast/rust-ast-full-test.cc +++ b/gcc/rust/ast/rust-ast-full-test.cc @@ -4061,17 +4061,59 @@ file_exists (const std::string path) return access (path.c_str (), F_OK) != -1; } -// FIXME: This function should also check if the module has a `path` outer -// attribute and fetch the path from here in that case, i.e: -// ``` -// #[path="<dir>/<subdir>/<file>.rs"] -// mod <mod_name>; -// ``` +static std::string +filename_from_path_attribute (std::vector<Attribute> &outer_attrs) +{ + Attribute path_attr = Attribute::create_empty (); + for (auto attr : outer_attrs) + { + if (attr.get_path ().as_string () == "path") + { + path_attr = attr; + break; + } + } + + // We didn't find a path attribute. This is not an error, there simply isn't + // one present + if (path_attr.is_empty ()) + return ""; + + // Here, we found a path attribute, but it has no associated string. This is + // invalid + if (!path_attr.has_attr_input ()) + { + rust_error_at ( + path_attr.get_locus (), + // Split the format string so that -Wformat-diag does not complain... + "path attributes must contain a filename: '%s'", "#[path = \"file\"]"); + return ""; + } + + auto path = path_attr.get_attr_input ().as_string (); + + // On windows, the path might mix '/' and '\' separators. Replace the + // UNIX-like separators by MSDOS separators to make sure the path will resolve + // properly. + // + // Source: rustc compiler + // (https://github.com/rust-lang/rust/blob/9863bf51a52b8e61bcad312f81b5193d53099f9f/compiler/rustc_expand/src/module.rs#L174) +#if defined(HAVE_DOS_BASED_FILE_SYSTEM) + path.replace ('/', '\\'); +#endif /* HAVE_DOS_BASED_FILE_SYSTEM */ + + return path_attr.get_attr_input ().as_string (); +} + std::string Module::get_filename () { rust_assert (kind == Module::ModuleKind::UNLOADED); + auto path_string = filename_from_path_attribute (get_outer_attrs ()); + if (!path_string.empty ()) + return path_string; + // This corresponds to the path of the file 'including' the module. So the // file that contains the 'mod <file>;' directive std::string including_fname (outer_filename); diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index e376488..1efcc86 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -457,6 +457,8 @@ public: Location get_locus () const { return locus; } + AttrInput &get_attr_input () const { return *attr_input; } + /* e.g.: #![crate_type = "lib"] #[test] |