summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-05-01 16:06:19 -0500
committerGitHub <noreply@github.com>2017-05-01 16:06:19 -0500
commit6cfb0ec4b8e304732b56618f386d4557ae8ff4cb (patch)
treee6a16be361dd89e2b3feff8b52e8cac541674d2d
parentf1e78336d374c4b50586c57243270cc7bdab1cd0 (diff)
parent8c588b3449621b39d8d42ab0008e93801cba6138 (diff)
Auto merge of #680 - emilio:nested-ns, r=fitzgen
ir: Support nested namespace specifiers. Fixes #677
-rw-r--r--src/ir/context.rs15
-rw-r--r--tests/expectations/tests/issue-677-nested-ns-specifier.rs20
-rw-r--r--tests/headers/issue-677-nested-ns-specifier.hpp5
3 files changed, 38 insertions, 2 deletions
diff --git a/src/ir/context.rs b/src/ir/context.rs
index 4d4a78d2..3d3e9fcd 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -1264,7 +1264,7 @@ impl<'ctx> BindgenContext<'ctx> {
}
/// Tokenizes a namespace cursor in order to get the name and kind of the
- /// namespace,
+ /// namespace.
fn tokenize_namespace(&self,
cursor: &clang::Cursor)
-> (Option<String>, ModuleKind) {
@@ -1280,6 +1280,7 @@ impl<'ctx> BindgenContext<'ctx> {
let mut kind = ModuleKind::Normal;
let mut found_namespace_keyword = false;
let mut module_name = None;
+
while let Some(token) = iter.next() {
match &*token.spelling {
"inline" => {
@@ -1287,7 +1288,17 @@ impl<'ctx> BindgenContext<'ctx> {
assert!(kind != ModuleKind::Inline);
kind = ModuleKind::Inline;
}
- "namespace" => {
+ // The double colon allows us to handle nested namespaces like
+ // namespace foo::bar { }
+ //
+ // libclang still gives us two namespace cursors, which is cool,
+ // but the tokenization of the second begins with the double
+ // colon. That's ok, so we only need to handle the weird
+ // tokenization here.
+ //
+ // Fortunately enough, inline nested namespace specifiers aren't
+ // a thing, and are invalid C++ :)
+ "namespace" | "::" => {
found_namespace_keyword = true;
}
"{" => {
diff --git a/tests/expectations/tests/issue-677-nested-ns-specifier.rs b/tests/expectations/tests/issue-677-nested-ns-specifier.rs
new file mode 100644
index 00000000..44d9904a
--- /dev/null
+++ b/tests/expectations/tests/issue-677-nested-ns-specifier.rs
@@ -0,0 +1,20 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
+pub mod root {
+ #[allow(unused_imports)]
+ use self::super::root;
+ pub mod foo {
+ #[allow(unused_imports)]
+ use self::super::super::root;
+ pub mod bar {
+ #[allow(unused_imports)]
+ use self::super::super::super::root;
+ pub type bar = ::std::os::raw::c_int;
+ }
+ }
+}
diff --git a/tests/headers/issue-677-nested-ns-specifier.hpp b/tests/headers/issue-677-nested-ns-specifier.hpp
new file mode 100644
index 00000000..ef2cea82
--- /dev/null
+++ b/tests/headers/issue-677-nested-ns-specifier.hpp
@@ -0,0 +1,5 @@
+// bindgen-flags: --enable-cxx-namespaces -- -std=c++14
+
+namespace foo::bar {
+ typedef int bar;
+}