aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/parse/rust-parse.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/parse/rust-parse.cc')
-rw-r--r--gcc/rust/parse/rust-parse.cc73
1 files changed, 73 insertions, 0 deletions
diff --git a/gcc/rust/parse/rust-parse.cc b/gcc/rust/parse/rust-parse.cc
index fdad97c..e78de51 100644
--- a/gcc/rust/parse/rust-parse.cc
+++ b/gcc/rust/parse/rust-parse.cc
@@ -46,4 +46,77 @@ along with GCC; see the file COPYING3. If not see
namespace Rust {
+std::string
+extract_module_path (const AST::AttrVec &inner_attrs,
+ const AST::AttrVec &outer_attrs, const std::string &name)
+{
+ AST::Attribute path_attr = AST::Attribute::create_empty ();
+ for (const auto &attr : inner_attrs)
+ {
+ if (attr.get_path ().as_string () == "path")
+ {
+ path_attr = attr;
+ break;
+ }
+ }
+
+ // Here, we found a path attribute, but it has no associated string. This is
+ // invalid
+ if (!path_attr.is_empty () && !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 name;
+ }
+
+ for (const 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 name;
+
+ // 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 name;
+ }
+
+ auto path_value = path_attr.get_attr_input ().as_string ();
+
+ // At this point, the 'path' is of the following format: '= "<file.rs>"'
+ // We need to remove the equal sign and only keep the actual filename.
+ // In order to do this, we can simply go through the string until we find
+ // a character that is not an equal sign or whitespace
+ auto filename_begin = path_value.find_first_not_of ("=\t ");
+
+ auto path = path_value.substr (filename_begin);
+
+ // 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;
+}
+
} // namespace Rust