summaryrefslogtreecommitdiff
path: root/libbindgen/src
diff options
context:
space:
mode:
Diffstat (limited to 'libbindgen/src')
-rw-r--r--libbindgen/src/codegen/mod.rs54
-rw-r--r--libbindgen/src/ir/context.rs4
-rw-r--r--libbindgen/src/ir/function.rs3
-rw-r--r--libbindgen/src/ir/item.rs97
-rw-r--r--libbindgen/src/ir/ty.rs33
5 files changed, 131 insertions, 60 deletions
diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs
index 6c8a36f7..c8cd4cdf 100644
--- a/libbindgen/src/codegen/mod.rs
+++ b/libbindgen/src/codegen/mod.rs
@@ -33,7 +33,8 @@ fn root_import(ctx: &BindgenContext) -> P<ast::Item> {
assert!(ctx.options().enable_cxx_namespaces, "Somebody messed it up");
let root = ctx.root_module().canonical_name(ctx);
let root_ident = ctx.rust_ident(&root);
- quote_item!(ctx.ext_cx(), use $root_ident;).unwrap()
+ quote_item!(ctx.ext_cx(), #[allow(unused_imports)] use $root_ident;)
+ .unwrap()
}
struct CodegenResult {
@@ -217,6 +218,7 @@ trait CodeGenerator {
fn codegen(&self,
ctx: &BindgenContext,
result: &mut CodegenResult,
+ whitelisted_items: &ItemSet,
extra: &Self::Extra);
}
@@ -226,6 +228,7 @@ impl CodeGenerator for Item {
fn codegen(&self,
ctx: &BindgenContext,
result: &mut CodegenResult,
+ whitelisted_items: &ItemSet,
_extra: &()) {
if self.is_hidden(ctx) || result.seen(self.id()) {
debug!("<Item as CodeGenerator>::codegen: Ignoring hidden or seen: \
@@ -244,18 +247,18 @@ impl CodeGenerator for Item {
return;
}
- module.codegen(ctx, result, self);
+ module.codegen(ctx, result, whitelisted_items, self);
}
ItemKind::Function(ref fun) => {
if !ctx.options().ignore_functions {
- fun.codegen(ctx, result, self);
+ fun.codegen(ctx, result, whitelisted_items, self);
}
}
ItemKind::Var(ref var) => {
- var.codegen(ctx, result, self);
+ var.codegen(ctx, result, whitelisted_items, self);
}
ItemKind::Type(ref ty) => {
- ty.codegen(ctx, result, self);
+ ty.codegen(ctx, result, whitelisted_items, self);
}
}
}
@@ -267,12 +270,14 @@ impl CodeGenerator for Module {
fn codegen(&self,
ctx: &BindgenContext,
result: &mut CodegenResult,
+ whitelisted_items: &ItemSet,
item: &Item) {
debug!("<Module as CodeGenerator>::codegen: item = {:?}", item);
if !ctx.options().enable_cxx_namespaces {
for child in self.children() {
- ctx.resolve_item(*child).codegen(ctx, result, &());
+ ctx.resolve_item(*child)
+ .codegen(ctx, result, whitelisted_items, &());
}
return;
}
@@ -280,7 +285,10 @@ impl CodeGenerator for Module {
let inner_items = result.inner(|result| {
result.push(root_import(ctx));
for child in self.children() {
- ctx.resolve_item(*child).codegen(ctx, result, &());
+ if whitelisted_items.contains(child) {
+ ctx.resolve_item(*child)
+ .codegen(ctx, result, whitelisted_items, &());
+ }
}
});
@@ -304,6 +312,7 @@ impl CodeGenerator for Var {
fn codegen(&self,
ctx: &BindgenContext,
result: &mut CodegenResult,
+ _whitelisted_items: &ItemSet,
item: &Item) {
use ir::var::VarType;
debug!("<Var as CodeGenerator>::codegen: item = {:?}", item);
@@ -394,6 +403,7 @@ impl CodeGenerator for Type {
fn codegen(&self,
ctx: &BindgenContext,
result: &mut CodegenResult,
+ whitelisted_items: &ItemSet,
item: &Item) {
debug!("<Type as CodeGenerator>::codegen: item = {:?}", item);
@@ -415,12 +425,15 @@ impl CodeGenerator for Type {
// converted to rust types in fields, arguments, and such.
return;
}
- TypeKind::Comp(ref ci) => ci.codegen(ctx, result, item),
+ TypeKind::Comp(ref ci) => {
+ ci.codegen(ctx, result, whitelisted_items, item)
+ }
TypeKind::TemplateAlias(inner, _) => {
// NB: The inner Alias will pick the correct
// applicable_template_args.
let inner_item = ctx.resolve_item(inner);
- inner_item.expect_type().codegen(ctx, result, inner_item);
+ inner_item.expect_type()
+ .codegen(ctx, result, whitelisted_items, inner_item);
}
TypeKind::Alias(ref spelling, inner) => {
let inner_item = ctx.resolve_item(inner);
@@ -478,7 +491,9 @@ impl CodeGenerator for Type {
let typedef = generics.build().build_ty(inner_rust_type);
result.push(typedef)
}
- TypeKind::Enum(ref ei) => ei.codegen(ctx, result, item),
+ TypeKind::Enum(ref ei) => {
+ ei.codegen(ctx, result, whitelisted_items, item)
+ }
ref u @ TypeKind::UnresolvedTypeRef(..) => {
unreachable!("Should have been resolved after parsing {:?}!", u)
}
@@ -513,6 +528,7 @@ impl<'a> CodeGenerator for Vtable<'a> {
fn codegen(&self,
ctx: &BindgenContext,
result: &mut CodegenResult,
+ _whitelisted_items: &ItemSet,
item: &Item) {
assert_eq!(item.id(), self.item_id);
// For now, generate an empty struct, later we should generate function
@@ -646,6 +662,7 @@ impl CodeGenerator for CompInfo {
fn codegen(&self,
ctx: &BindgenContext,
result: &mut CodegenResult,
+ whitelisted_items: &ItemSet,
item: &Item) {
use aster::struct_field::StructFieldBuilder;
@@ -732,7 +749,7 @@ impl CodeGenerator for CompInfo {
if self.needs_explicit_vtable(ctx) {
let vtable =
Vtable::new(item.id(), self.methods(), self.base_members());
- vtable.codegen(ctx, result, item);
+ vtable.codegen(ctx, result, whitelisted_items, item);
let vtable_type = vtable.to_rust_ty(ctx).to_ptr(true, ctx.span());
@@ -1051,7 +1068,7 @@ impl CodeGenerator for CompInfo {
for ty in self.inner_types() {
let child_item = ctx.resolve_item(*ty);
// assert_eq!(child_item.parent_id(), item.id());
- child_item.codegen(ctx, result, &());
+ child_item.codegen(ctx, result, whitelisted_items, &());
}
// NOTE: Some unexposed attributes (like alignment attributes) may
@@ -1064,7 +1081,8 @@ impl CodeGenerator for CompInfo {
if applicable_template_args.is_empty() && !self.found_unknown_attr() {
for var in self.inner_vars() {
- ctx.resolve_item(*var).codegen(ctx, result, &());
+ ctx.resolve_item(*var)
+ .codegen(ctx, result, whitelisted_items, &());
}
if let Some(layout) = layout {
@@ -1094,6 +1112,7 @@ impl CodeGenerator for CompInfo {
&mut methods,
&mut method_names,
result,
+ whitelisted_items,
item);
}
}
@@ -1145,6 +1164,7 @@ trait MethodCodegen {
methods: &mut Vec<ast::ImplItem>,
method_names: &mut HashMap<String, usize>,
result: &mut CodegenResult,
+ whitelisted_items: &ItemSet,
parent: &Item);
}
@@ -1154,6 +1174,7 @@ impl MethodCodegen for Method {
methods: &mut Vec<ast::ImplItem>,
method_names: &mut HashMap<String, usize>,
result: &mut CodegenResult,
+ whitelisted_items: &ItemSet,
_parent: &Item) {
if ctx.options().ignore_methods {
return;
@@ -1163,7 +1184,8 @@ impl MethodCodegen for Method {
return; // FIXME
}
// First of all, output the actual function.
- ctx.resolve_item(self.signature()).codegen(ctx, result, &());
+ ctx.resolve_item(self.signature())
+ .codegen(ctx, result, whitelisted_items, &());
let function_item = ctx.resolve_item(self.signature());
let function = function_item.expect_function();
@@ -1411,6 +1433,7 @@ impl CodeGenerator for Enum {
fn codegen(&self,
ctx: &BindgenContext,
result: &mut CodegenResult,
+ _whitelisted_items: &ItemSet,
item: &Item) {
debug!("<Enum as CodeGenerator>::codegen: item = {:?}", item);
@@ -1852,6 +1875,7 @@ impl CodeGenerator for Function {
fn codegen(&self,
ctx: &BindgenContext,
result: &mut CodegenResult,
+ _whitelisted_items: &ItemSet,
item: &Item) {
debug!("<Function as CodeGenerator>::codegen: item = {:?}", item);
@@ -1963,7 +1987,7 @@ pub fn codegen(context: &mut BindgenContext) -> Vec<P<ast::Item>> {
// need to take responsibility for generating it.
if item.is_toplevel(context) ||
!ancestor_is_whitelisted(context, &whitelisted_items, id) {
- item.codegen(context, &mut result, &());
+ item.codegen(context, &mut result, &whitelisted_items, &());
}
}
diff --git a/libbindgen/src/ir/context.rs b/libbindgen/src/ir/context.rs
index bda3e3c8..7c643f04 100644
--- a/libbindgen/src/ir/context.rs
+++ b/libbindgen/src/ir/context.rs
@@ -938,7 +938,9 @@ impl<'ctx> BindgenContext<'ctx> {
let name = item.canonical_name(self);
match *item.kind() {
- ItemKind::Module(..) => false,
+ ItemKind::Module(..) => {
+ self.options().enable_cxx_namespaces
+ }
ItemKind::Function(_) => {
self.options().whitelisted_functions.matches(&name)
}
diff --git a/libbindgen/src/ir/function.rs b/libbindgen/src/ir/function.rs
index 60bd1e5b..5a864cfc 100644
--- a/libbindgen/src/ir/function.rs
+++ b/libbindgen/src/ir/function.rs
@@ -150,7 +150,8 @@ impl FunctionSig {
CXCursor_CXXMethod => {
// For CXCursor_FunctionDecl, cursor.args() is the reliable way
// to get parameter names and types.
- cursor.args().expect("It cannot be None because we are in a method/function")
+ cursor.args()
+ .unwrap()
.iter()
.map(|arg| {
let arg_ty = arg.cur_type();
diff --git a/libbindgen/src/ir/item.rs b/libbindgen/src/ir/item.rs
index 176eca14..32e3c4c5 100644
--- a/libbindgen/src/ir/item.rs
+++ b/libbindgen/src/ir/item.rs
@@ -1,6 +1,7 @@
//! Bindgen's core intermediate representation type.
use clang;
+use clangll;
use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult};
use std::cell::{Cell, RefCell};
use std::fmt::Write;
@@ -527,7 +528,10 @@ impl Item {
}
/// Get the target item id for name generation.
- fn name_target(&self, ctx: &BindgenContext, for_name_checking: bool) -> ItemId {
+ fn name_target(&self,
+ ctx: &BindgenContext,
+ for_name_checking: bool)
+ -> ItemId {
let mut item = self;
loop {
match *item.kind() {
@@ -535,24 +539,31 @@ impl Item {
match *ty.kind() {
// If we're a template specialization, our name is our
// parent's name.
- TypeKind::Comp(ref ci) if ci.is_template_specialization() => {
- item = ctx.resolve_item(ci.specialized_template().unwrap());
- },
+ TypeKind::Comp(ref ci)
+ if ci.is_template_specialization() => {
+ let specialized =
+ ci.specialized_template().unwrap();
+ item = ctx.resolve_item(specialized);
+ }
// Same as above.
TypeKind::ResolvedTypeRef(inner) |
TypeKind::TemplateRef(inner, _) => {
item = ctx.resolve_item(inner);
}
- // Template aliases use their inner alias type's name if we
- // are checking names for whitelisting/replacement/etc.
- TypeKind::TemplateAlias(inner, _) if for_name_checking => {
+ // Template aliases use their inner alias type's name if
+ // we are checking names for
+ // whitelisting/replacement/etc.
+ TypeKind::TemplateAlias(inner, _)
+ if for_name_checking => {
item = ctx.resolve_item(inner);
- assert_eq!(item.id(), item.name_target(ctx, for_name_checking));
+ assert_eq!(item.id(),
+ item.name_target(ctx,
+ for_name_checking));
return item.id();
}
_ => return item.id(),
}
- },
+ }
_ => return item.id(),
}
}
@@ -580,9 +591,7 @@ impl Item {
let func = item.expect_function();
func.name() == func_name
})
- .enumerate()
- .find(|&(_, ref method)| method.signature() == self.id())
- .map(|(idx, _)| idx);
+ .position(|method| method.signature() == self.id());
}
}
@@ -595,24 +604,33 @@ impl Item {
/// The `for_name_checking` boolean parameter informs us whether we are
/// asking for the name in order to do a whitelisting/replacement/etc check
/// or if we are instead using it for code generation.
- fn base_name(&self, ctx: &BindgenContext, for_name_checking: bool) -> String {
+ fn base_name(&self,
+ ctx: &BindgenContext,
+ for_name_checking: bool)
+ -> String {
match *self.kind() {
ItemKind::Var(ref var) => var.name().to_owned(),
ItemKind::Module(ref module) => {
module.name()
.map(ToOwned::to_owned)
- .unwrap_or_else(|| format!("_bindgen_mod_{}", self.exposed_id(ctx)))
- },
+ .unwrap_or_else(|| {
+ format!("_bindgen_mod_{}", self.exposed_id(ctx))
+ })
+ }
ItemKind::Type(ref ty) => {
let name = match *ty.kind() {
- TypeKind::ResolvedTypeRef(..) =>
- panic!("should have resolved this in name_target()"),
- TypeKind::TemplateAlias(..) if !for_name_checking => Some(""),
- TypeKind::TemplateAlias(..) => None,
+ TypeKind::ResolvedTypeRef(..) => {
+ panic!("should have resolved this in name_target()")
+ }
+ TypeKind::TemplateAlias(..) => {
+ if for_name_checking { None } else { Some("") }
+ }
_ => ty.name(),
};
name.map(ToOwned::to_owned)
- .unwrap_or_else(|| format!("_bindgen_ty_{}", self.exposed_id(ctx)))
+ .unwrap_or_else(|| {
+ format!("_bindgen_ty_{}", self.exposed_id(ctx))
+ })
}
ItemKind::Function(ref fun) => {
let mut name = fun.name().to_owned();
@@ -624,7 +642,7 @@ impl Item {
}
name
- },
+ }
}
}
@@ -716,6 +734,31 @@ impl Item {
}
}
+// An utility function to handle recursing inside nested types.
+fn visit_child(cur: clang::Cursor,
+ id: ItemId,
+ ty: &clang::Type,
+ parent_id: Option<ItemId>,
+ ctx: &mut BindgenContext,
+ result: &mut Result<ItemId, ParseError>)
+ -> clangll::Enum_CXChildVisitResult {
+ use clangll::*;
+ if result.is_ok() {
+ return CXChildVisit_Break;
+ }
+
+ *result = Item::from_ty_with_id(id, ty, Some(cur), parent_id, ctx);
+
+ match *result {
+ Ok(..) => CXChildVisit_Break,
+ Err(ParseError::Recurse) => {
+ cur.visit(|c| visit_child(c, id, ty, parent_id, ctx, result));
+ CXChildVisit_Continue
+ }
+ Err(ParseError::Continue) => CXChildVisit_Continue,
+ }
+}
+
impl ClangItemParser for Item {
fn builtin_type(kind: TypeKind,
is_const: bool,
@@ -1005,17 +1048,7 @@ impl ClangItemParser for Item {
}
location.visit(|cur| {
- use clangll::*;
- result = Item::from_ty_with_id(id,
- ty,
- Some(cur),
- parent_id,
- ctx);
- match result {
- Ok(..) => CXChildVisit_Break,
- Err(ParseError::Recurse) => CXChildVisit_Recurse,
- Err(ParseError::Continue) => CXChildVisit_Continue,
- }
+ visit_child(cur, id, ty, parent_id, ctx, &mut result)
});
if valid_decl {
diff --git a/libbindgen/src/ir/ty.rs b/libbindgen/src/ir/ty.rs
index 60611b8d..7f01e388 100644
--- a/libbindgen/src/ir/ty.rs
+++ b/libbindgen/src/ir/ty.rs
@@ -685,30 +685,41 @@ impl Type {
CXCursor_TemplateRef => {
let referenced = location.referenced().unwrap();
let referenced_ty = referenced.cur_type();
- let referenced_declaration =
- Some(referenced_ty.declaration());
+
+ debug!("TemplateRef: location = {:?}; referenced = \
+ {:?}; referenced_ty = {:?}",
+ location,
+ referenced,
+ referenced_ty);
return Self::from_clang_ty(potential_id,
&referenced_ty,
- referenced_declaration,
+ Some(referenced),
parent_id,
ctx);
}
CXCursor_TypeRef => {
let referenced = location.referenced().unwrap();
let referenced_ty = referenced.cur_type();
- let referenced_declaration =
- Some(referenced_ty.declaration());
+ let declaration = referenced_ty.declaration();
+
+ debug!("TypeRef: location = {:?}; referenced = \
+ {:?}; referenced_ty = {:?}",
+ location,
+ referenced,
+ referenced_ty);
let item =
- Item::from_ty_or_ref_with_id(
- potential_id,
- referenced_ty,
- referenced_declaration,
- parent_id,
- ctx);
+ Item::from_ty_or_ref_with_id(potential_id,
+ referenced_ty,
+ Some(declaration),
+ parent_id,
+ ctx);
return Ok(ParseResult::AlreadyResolved(item));
}
+ CXCursor_NamespaceRef => {
+ return Err(ParseError::Continue);
+ }
_ => {
if ty.kind() == CXType_Unexposed {
warn!("Unexposed type {:?}, recursing inside, \