diff options
author | Nick Fitzgerald <fitzgen@gmail.com> | 2016-12-02 13:43:54 -0800 |
---|---|---|
committer | Nick Fitzgerald <fitzgen@gmail.com> | 2016-12-02 13:43:54 -0800 |
commit | 2c43aaef40ca43ed7be52ea738065bfbe3baae6c (patch) | |
tree | eb608c272e948b4b4c7f5b0d86ff551324f1f882 | |
parent | b8014b1034ac486d3169e71d58e6387f8b1d25f1 (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.rs | 54 | ||||
-rw-r--r-- | libbindgen/tests/expectations/tests/issue_311.rs | 38 | ||||
-rw-r--r-- | libbindgen/tests/headers/issue_311.hpp | 5 |
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 {}; +}; |