summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Fitzgerald <fitzgen@gmail.com>2016-12-02 13:43:54 -0800
committerNick Fitzgerald <fitzgen@gmail.com>2016-12-02 13:43:54 -0800
commit2c43aaef40ca43ed7be52ea738065bfbe3baae6c (patch)
treeeb608c272e948b4b4c7f5b0d86ff551324f1f882
parentb8014b1034ac486d3169e71d58e6387f8b1d25f1 (diff)
Do not treat parent struct as a module for nested structs
This fixes `ItemCanonicalPath` to return paths of the form `[module*, item]` rather than `[item*, item]`. That is, there will only be module names before the item's name, rather than also other arbitrary item names (such as parent structs). Fixes #311
-rw-r--r--libbindgen/src/ir/item.rs54
-rw-r--r--libbindgen/tests/expectations/tests/issue_311.rs38
-rw-r--r--libbindgen/tests/headers/issue_311.hpp5
3 files changed, 53 insertions, 44 deletions
diff --git a/libbindgen/src/ir/item.rs b/libbindgen/src/ir/item.rs
index c0555bca..76ab0d55 100644
--- a/libbindgen/src/ir/item.rs
+++ b/libbindgen/src/ir/item.rs
@@ -5,6 +5,7 @@ use clangll;
use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult};
use std::cell::{Cell, RefCell};
use std::fmt::Write;
+use std::iter;
use super::annotations::Annotations;
use super::context::{BindgenContext, ItemId};
use super::function::Function;
@@ -1181,50 +1182,15 @@ impl ItemCanonicalPath for Item {
return vec![self.canonical_name(ctx)];
}
- if self.id() == ctx.root_module() {
- match self.kind {
- ItemKind::Module(ref module) => {
- return vec![module.name().unwrap().into()]
- }
- _ => panic!("Something has wrong horribly wrong"),
- }
- }
-
- // TODO: This duplicates too much logic with real_canonical_name.
- if let ItemKind::Type(ref ty) = *self.kind() {
- match *ty.kind() {
- TypeKind::Comp(ref ci) if ci.is_template_specialization() => {
- return ci.specialized_template()
- .unwrap()
- .canonical_path(ctx);
- }
- TypeKind::ResolvedTypeRef(inner) |
- TypeKind::TemplateRef(inner, _) => {
- return inner.canonical_path(ctx);
- }
- TypeKind::Named(ref name, _) => {
- return vec![name.clone()];
- }
- _ => {}
- }
- }
-
- let mut parent_path = self.parent_id().canonical_path(&ctx);
- if parent_path.last()
- .map_or(false, |parent_name| parent_name.is_empty()) {
- // This only happens (or should only happen) when we're an alias,
- // and our parent is a templated alias, in which case the last
- // component of the path will be empty.
- let is_alias = match *self.expect_type().kind() {
- TypeKind::Alias(..) => true,
- _ => false,
- };
- debug_assert!(is_alias, "How can this ever happen?");
- parent_path.pop().unwrap();
- }
- parent_path.push(self.name(ctx).within_namespaces().get());
-
- parent_path
+ let target = ctx.resolve_item(self.name_target(ctx, false));
+ let mut path: Vec<_> = target.ancestors(ctx)
+ .chain(iter::once(ctx.root_module()))
+ .map(|id| ctx.resolve_item(id))
+ .filter(|item| item.is_module() || item.id() == target.id())
+ .map(|item| item.name(ctx).within_namespaces().get())
+ .collect();
+ path.reverse();
+ path
}
}
diff --git a/libbindgen/tests/expectations/tests/issue_311.rs b/libbindgen/tests/expectations/tests/issue_311.rs
new file mode 100644
index 00000000..f01a9d93
--- /dev/null
+++ b/libbindgen/tests/expectations/tests/issue_311.rs
@@ -0,0 +1,38 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+pub mod root {
+ #[allow(unused_imports)]
+ use self::super::root;
+ #[repr(C)]
+ #[derive(Debug, Copy)]
+ pub struct jsval_layout {
+ pub __bindgen_anon_1: root::jsval_layout__bindgen_ty_1,
+ }
+ #[repr(C)]
+ #[derive(Debug, Copy)]
+ pub struct jsval_layout__bindgen_ty_1 {
+ pub _address: u8,
+ }
+ #[test]
+ fn bindgen_test_layout_jsval_layout__bindgen_ty_1() {
+ assert_eq!(::std::mem::size_of::<jsval_layout__bindgen_ty_1>() ,
+ 1usize);
+ assert_eq!(::std::mem::align_of::<jsval_layout__bindgen_ty_1>() ,
+ 1usize);
+ }
+ impl Clone for jsval_layout__bindgen_ty_1 {
+ fn clone(&self) -> Self { *self }
+ }
+ #[test]
+ fn bindgen_test_layout_jsval_layout() {
+ assert_eq!(::std::mem::size_of::<jsval_layout>() , 1usize);
+ assert_eq!(::std::mem::align_of::<jsval_layout>() , 1usize);
+ }
+ impl Clone for jsval_layout {
+ fn clone(&self) -> Self { *self }
+ }
+}
diff --git a/libbindgen/tests/headers/issue_311.hpp b/libbindgen/tests/headers/issue_311.hpp
new file mode 100644
index 00000000..a8d7fd99
--- /dev/null
+++ b/libbindgen/tests/headers/issue_311.hpp
@@ -0,0 +1,5 @@
+// bindgen-flags: --enable-cxx-namespaces
+
+struct jsval_layout {
+ struct {};
+};