summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rustfmt.toml1
-rwxr-xr-xsrc/clang.rs7
-rwxr-xr-xsrc/codegen/mod.rs104
-rw-r--r--src/ir/comp.rs112
-rw-r--r--src/ir/context.rs14
-rw-r--r--src/ir/item.rs169
-rw-r--r--src/ir/ty.rs155
-rw-r--r--src/ir/var.rs38
8 files changed, 340 insertions, 260 deletions
diff --git a/rustfmt.toml b/rustfmt.toml
index 6677939b..96d4ae47 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -1,6 +1,5 @@
max_width = 80
format_strings = false
-wrap_comments = true
fn_brace_style = "SameLineWhere"
item_brace_style = "SameLineWhere"
struct_lit_multiline_style = "ForceMulti"
diff --git a/src/clang.rs b/src/clang.rs
index 24d9e45e..e1bb1059 100755
--- a/src/clang.rs
+++ b/src/clang.rs
@@ -1259,7 +1259,12 @@ pub fn kind_to_str(x: Enum_CXCursorKind) -> &'static str {
CXCursor_TemplateTemplateParameter => "TemplateTemplateParameter",
CXCursor_FunctionTemplate => "FunctionTemplate",
CXCursor_ClassTemplate => "ClassTemplate",
- CXCursor_ClassTemplatePartialSpecialization => "ClassTemplatePartialSpecialization",
+ CXCursor_ClassTemplatePartialSpecialization => {
+ // FIXME: Ugly hack for rustfmt, should go away!
+ //
+ // I plan to convert this into an enum right away anyway, though.
+ return "ClassTemplatePartialSpecialization";
+ }
CXCursor_NamespaceAlias => "NamespaceAlias",
CXCursor_UsingDirective => "UsingDirective",
CXCursor_UsingDeclaration => "UsingDeclaration",
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index a4d717d3..57173904 100755
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -1,9 +1,10 @@
mod helpers;
+
use aster;
+
use ir::annotations::FieldAccessorKind;
use ir::comp::{CompInfo, CompKind, Field, Method};
-
use ir::context::BindgenContext;
use ir::enum_ty::Enum;
use ir::function::{Function, FunctionSig};
@@ -16,13 +17,12 @@ use ir::ty::{Type, TypeKind};
use ir::type_collector::{ItemSet, TypeCollector};
use ir::var::Var;
use self::helpers::{BlobTyBuilder, attributes};
+
use std::borrow::Cow;
use std::collections::HashSet;
use std::collections::hash_map::{Entry, HashMap};
use std::mem;
-
use std::ops;
-
use syntax::abi::Abi;
use syntax::ast;
use syntax::codemap::{Span, respan};
@@ -40,8 +40,7 @@ struct CodegenResult {
saw_union: bool,
items_seen: HashSet<ItemId>,
/// The set of generated function/var names, needed because in C/C++ is
- /// legal to
- /// do something like:
+ /// legal to do something like:
///
/// ```c++
/// extern "C" {
@@ -400,7 +399,8 @@ impl CodeGenerator for Type {
if template_arg.is_named() {
let name = template_arg.name().unwrap();
if name.contains("typename ") {
- error!("Item contained `typename`'d template param: {:?}", item);
+ error!("Item contained `typename`'d template \
+ parameter: {:?}", item);
return;
}
generics =
@@ -541,18 +541,25 @@ impl<'a> Bitfield<'a> {
pub fn $getter_name(&self) -> $field_type {
unsafe {
::std::mem::transmute(
- ((self.$field_ident & ($mask as $bitfield_type)) >> $offset)
- as $int_type)
+ (
+ (self.$field_ident &
+ ($mask as $bitfield_type))
+ >> $offset
+ ) as $int_type
+ )
}
}
#[inline]
pub fn $setter_name(&mut self, val: $field_type) {
self.$field_ident &= !($mask as $bitfield_type);
- self.$field_ident |= (val as $int_type as $bitfield_type << $offset) & ($mask as $bitfield_type);
+ self.$field_ident |=
+ (val as $int_type as $bitfield_type << $offset) &
+ ($mask as $bitfield_type);
}
}
- ).unwrap();
+ )
+ .unwrap();
let items = match item.unwrap().node {
ast::ItemKind::Impl(_, _, _, _, _, items) => items,
@@ -639,6 +646,7 @@ impl CodeGenerator for CompInfo {
};
// Generate the vtable from the method list if appropriate.
+ //
// TODO: I don't know how this could play with virtual methods that are
// not in the list of methods found by us, we'll see. Also, could the
// order of the vtable pointers vary?
@@ -677,8 +685,9 @@ impl CodeGenerator for CompInfo {
continue;
}
- for (i, ty) in applicable_template_args.iter().enumerate() {
- if base_ty.signature_contains_named_type(ctx, ctx.resolve_type(*ty)) {
+ for (i, ty_id) in applicable_template_args.iter().enumerate() {
+ let template_arg_ty = ctx.resolve_type(*ty_id);
+ if base_ty.signature_contains_named_type(ctx, template_arg_ty) {
template_args_used[i] = true;
}
}
@@ -758,8 +767,9 @@ impl CodeGenerator for CompInfo {
continue;
}
- for (i, ty) in applicable_template_args.iter().enumerate() {
- if field_ty.signature_contains_named_type(ctx, ctx.resolve_type(*ty)) {
+ for (i, ty_id) in applicable_template_args.iter().enumerate() {
+ let template_arg = ctx.resolve_type(*ty_id);
+ if field_ty.signature_contains_named_type(ctx, template_arg) {
template_args_used[i] = true;
}
}
@@ -841,7 +851,8 @@ impl CodeGenerator for CompInfo {
}
#[inline]
- pub unsafe fn $mutable_getter_name(&mut self) -> &mut $ty {
+ pub unsafe fn $mutable_getter_name(&mut self)
+ -> &mut $ty {
&mut self.$field_name
}
}
@@ -931,9 +942,12 @@ impl CodeGenerator for CompInfo {
if !template_args_used[i] {
let name = ctx.resolve_type(*ty).name().unwrap();
let ident = ctx.rust_ident(name);
+ let phantom = quote_ty!(ctx.ext_cx(),
+ ::std::marker::PhantomData<$ident>);
let field =
- StructFieldBuilder::named(format!("_phantom_{}", i)).pub_()
- .build_ty(quote_ty!(ctx.ext_cx(), ::std::marker::PhantomData<$ident>));
+ StructFieldBuilder::named(format!("_phantom_{}", i))
+ .pub_()
+ .build_ty(phantom);
fields.push(field)
}
}
@@ -972,16 +986,18 @@ impl CodeGenerator for CompInfo {
// affect layout, so we're bad and pray to the gods for avoid sending
// all the tests to shit when parsing things like max_align_t.
if self.found_unknown_attr() {
- warn!("Type {} has an unkown attribute that may affect layout", canonical_name);
+ warn!("Type {} has an unkown attribute that may affect layout",
+ canonical_name);
}
+
if applicable_template_args.is_empty() && !self.found_unknown_attr() {
for var in self.inner_vars() {
ctx.resolve_item(*var).codegen(ctx, result, &());
}
if let Some(layout) = layout {
- let fn_name =
- ctx.rust_ident_raw(&format!("bindgen_test_layout_{}", canonical_name));
+ let fn_name = format!("bindgen_test_layout_{}", canonical_name);
+ let fn_name = ctx.rust_ident_raw(&fn_name);
let ident = ctx.rust_ident_raw(&canonical_name);
let size_of_expr =
quote_expr!(ctx.ext_cx(), ::std::mem::size_of::<$ident>());
@@ -1107,6 +1123,7 @@ impl MethodCodegen for Method {
};
assert!(!fndecl.inputs.is_empty());
+
// FIXME: use aster here.
fndecl.inputs[0] = ast::Arg {
ty: P(ast::Ty {
@@ -1123,9 +1140,11 @@ impl MethodCodegen for Method {
}),
pat: P(ast::Pat {
id: ast::DUMMY_NODE_ID,
- node: ast::PatKind::Ident(ast::BindingMode::ByValue(ast::Mutability::Immutable),
- respan(ctx.span(), ctx.ext_cx().ident_of("self")),
- None),
+ node: ast::PatKind::Ident(
+ ast::BindingMode::ByValue(ast::Mutability::Immutable),
+ respan(ctx.span(), ctx.ext_cx().ident_of("self")),
+ None
+ ),
span: ctx.span(),
}),
id: ast::DUMMY_NODE_ID,
@@ -1223,7 +1242,8 @@ impl CodeGenerator for Enum {
}
}
None => {
- warn!("Guessing type of enum! Forward declarations of enums shouldn't be legal!");
+ warn!("Guessing type of enum! Forward declarations of enums \
+ shouldn't be legal!");
IntKind::Int
}
};
@@ -1272,8 +1292,7 @@ impl CodeGenerator for Enum {
// Only to avoid recomputing every time.
enum_canonical_name: &str,
// May be the same as "variant" if it's because the
- // enum
- // is unnamed and we still haven't seen the value.
+ // enum is unnamed and we still haven't seen the value.
variant_name: &str,
referenced_name: &str,
enum_rust_ty: P<ast::Ty>,
@@ -1342,9 +1361,11 @@ impl CodeGenerator for Enum {
.canonical_name(ctx));
}
+ let parent_name = parent_canonical_name.as_ref()
+ .unwrap();
+
Cow::Owned(
- format!("{}_{}", parent_canonical_name.as_ref().unwrap(),
- variant_name))
+ format!("{}_{}", parent_name, variant_name))
};
add_constant(enum_ty,
@@ -1464,13 +1485,15 @@ impl ToRustTy for Type {
let mut inner_ty = inner.to_rust_ty(ctx).unwrap();
if let ast::TyKind::Path(_, ref mut path) = inner_ty.node {
+ let template_args = template_args.iter()
+ .map(|arg| arg.to_rust_ty(ctx))
+ .collect();
+
path.segments.last_mut().unwrap().parameters =
ast::PathParameters::AngleBracketed(
ast::AngleBracketedParameterData {
lifetimes: vec![],
- types: P::from_vec(template_args.iter().map(|arg| {
- arg.to_rust_ty(ctx)
- }).collect()),
+ types: P::from_vec(template_args),
bindings: P::from_vec(vec![]),
}
);
@@ -1498,7 +1521,8 @@ impl ToRustTy for Type {
Some(layout) => BlobTyBuilder::new(layout).build(),
None => {
warn!("Couldn't compute layout for a type with non \
- type template params or opaque, expect dragons!");
+ type template params or opaque, expect \
+ dragons!");
aster::AstBuilder::new().ty().unit()
}
};
@@ -1558,11 +1582,14 @@ impl ToRustTy for FunctionSig {
let arg_item = ctx.resolve_item(ty);
let arg_ty = arg_item.kind().expect_type();
- // From the C90 standard (http://c0x.coding-guidelines.com/6.7.5.3.html)
- // 1598 - A declaration of a parameter as “array of type” shall be
- // adjusted to “qualified pointer to type”, where the type qualifiers
- // (if any) are those specified within the [ and ] of the array type
- // derivation.
+ // From the C90 standard[1]:
+ //
+ // A declaration of a parameter as "array of type" shall be
+ // adjusted to "qualified pointer to type", where the type
+ // qualifiers (if any) are those specified within the [ and ] of
+ // the array type derivation.
+ //
+ // [1]: http://c0x.coding-guidelines.com/6.7.5.3.html
let arg_ty = if let TypeKind::Array(t, _) = *arg_ty.kind() {
t.to_rust_ty(ctx).to_ptr(arg_ty.is_const(), ctx.span())
} else {
@@ -1678,8 +1705,7 @@ pub fn codegen(context: &mut BindgenContext) -> Vec<P<ast::Item>> {
context.options().whitelisted_vars.is_empty() {
for (_item_id, item) in context.items() {
// Non-toplevel item parents are the responsible one for
- // generating
- // them.
+ // generating them.
if item.is_toplevel(context) {
item.codegen(context, &mut result, &());
}
diff --git a/src/ir/comp.rs b/src/ir/comp.rs
index 27094003..d55c24ca 100644
--- a/src/ir/comp.rs
+++ b/src/ir/comp.rs
@@ -275,22 +275,20 @@ impl CompInfo {
self.detect_derive_debug_cycle.set(true);
- let can_derive_debug = self.base_members.iter().all(|ty| {
- ctx.resolve_type(*ty)
- .can_derive_debug(ctx)
- }) &&
- self.template_args.iter().all(|ty| {
- ctx.resolve_type(*ty)
- .can_derive_debug(ctx)
- }) &&
- self.fields.iter().all(|field| {
- ctx.resolve_type(field.ty)
- .can_derive_debug(ctx)
- }) &&
- self.ref_template.map_or(true, |template| {
- ctx.resolve_type(template)
- .can_derive_debug(ctx)
- });
+ let can_derive_debug = {
+ self.base_members
+ .iter()
+ .all(|ty| ctx.resolve_type(*ty).can_derive_debug(ctx)) &&
+ self.template_args
+ .iter()
+ .all(|ty| ctx.resolve_type(*ty).can_derive_debug(ctx)) &&
+ self.fields
+ .iter()
+ .all(|f| ctx.resolve_type(f.ty).can_derive_debug(ctx)) &&
+ self.ref_template.map_or(true, |template| {
+ ctx.resolve_type(template).can_derive_debug(ctx)
+ })
+ };
self.detect_derive_debug_cycle.set(false);
@@ -301,9 +299,7 @@ impl CompInfo {
pub fn is_unsized(&self, ctx: &BindgenContext) -> bool {
!self.has_vtable(ctx) && self.fields.is_empty() &&
self.base_members.iter().all(|base| {
- ctx.resolve_type(*base)
- .canonical_type(ctx)
- .is_unsized(ctx)
+ ctx.resolve_type(*base).canonical_type(ctx).is_unsized(ctx)
}) &&
self.ref_template
.map_or(true, |template| ctx.resolve_type(template).is_unsized(ctx))
@@ -521,7 +517,7 @@ impl CompInfo {
let mut maybe_anonymous_struct_field = None;
cursor.visit(|cur, _other| {
if cur.kind() != CXCursor_FieldDecl {
- if let Some((ty, ref _clang_ty)) = maybe_anonymous_struct_field {
+ if let Some((ty, _)) = maybe_anonymous_struct_field {
let field = Field::new(None, ty, None, None, None, false);
ci.fields.push(field);
}
@@ -540,16 +536,24 @@ impl CompInfo {
CXChildVisit_Continue
});
if !used {
- let field = Field::new(None, ty, None, None, None, false);
+ let field = Field::new(None,
+ ty,
+ None,
+ None,
+ None,
+ false);
ci.fields.push(field);
}
- },
+ }
None => {}
}
let bit_width = cur.bit_width();
- let field_type =
- Item::from_ty_or_ref(cur.cur_type(), Some(*cur), Some(potential_id), ctx);
+ let field_type = Item::from_ty_or_ref(cur.cur_type(),
+ Some(*cur),
+ Some(potential_id),
+ ctx);
+
let comment = cur.raw_comment();
let annotations = Annotations::new(cur);
let name = cur.spelling();
@@ -562,8 +566,12 @@ impl CompInfo {
let name = if name.is_empty() { None } else { Some(name) };
- let field = Field::new(name, field_type, comment,
- annotations, bit_width, is_mutable);
+ let field = Field::new(name,
+ field_type,
+ comment,
+ annotations,
+ bit_width,
+ is_mutable);
ci.fields.push(field);
// No we look for things like attributes and stuff.
@@ -586,14 +594,16 @@ impl CompInfo {
CXCursor_ClassTemplate |
CXCursor_ClassDecl => {
let inner = Item::parse(*cur, Some(potential_id), ctx)
- .expect("Inner ClassDecl");
+ .expect("Inner ClassDecl");
if !ci.inner_types.contains(&inner) {
ci.inner_types.push(inner);
}
// A declaration of an union or a struct without name could
// also be an unnamed field, unfortunately.
- if cur.spelling().is_empty() && cur.kind() != CXCursor_EnumDecl {
- maybe_anonymous_struct_field = Some((inner, cur.cur_type()));
+ if cur.spelling().is_empty() &&
+ cur.kind() != CXCursor_EnumDecl {
+ let ty = cur.cur_type();
+ maybe_anonymous_struct_field = Some((inner, ty));
}
}
CXCursor_PackedAttr => {
@@ -608,18 +618,24 @@ impl CompInfo {
return CXChildVisit_Continue;
}
- let default_type =
- Item::from_ty(&cur.cur_type(), Some(*cur), Some(potential_id), ctx).ok();
- let param = Item::named_type(cur.spelling(), default_type,
- potential_id, ctx);
+ let default_type = Item::from_ty(&cur.cur_type(),
+ Some(*cur),
+ Some(potential_id),
+ ctx)
+ .ok();
+ let param = Item::named_type(cur.spelling(),
+ default_type,
+ potential_id,
+ ctx);
ci.template_args.push(param);
}
CXCursor_CXXBaseSpecifier => {
if !ci.has_vtable {
ci.has_vtable = cur.is_virtual_base();
}
- let type_id = Item::from_ty(&cur.cur_type(), None, None, ctx)
- .expect("BaseSpecifier");
+ let type_id =
+ Item::from_ty(&cur.cur_type(), None, None, ctx)
+ .expect("BaseSpecifier");
ci.base_members.push(type_id);
}
CXCursor_CXXMethod => {
@@ -668,9 +684,12 @@ impl CompInfo {
return CXChildVisit_Continue;
}
- // NB: This gets us an owned `Function`, not a `FunctionSig`.
- let method_signature = Item::parse(*cur, Some(potential_id), ctx)
- .expect("CXXMethod");
+ // NB: This gets us an owned `Function`, not a
+ // `FunctionSig`.
+ let method_signature =
+ Item::parse(*cur, Some(potential_id), ctx)
+ .expect("CXXMethod");
+
let is_const = cur.method_is_const();
let method_kind = if is_static {
MethodKind::Static
@@ -679,7 +698,11 @@ impl CompInfo {
} else {
MethodKind::Normal
};
- ci.methods.push(Method::new(method_kind, method_signature, is_const));
+
+ let method =
+ Method::new(method_kind, method_signature, is_const);
+
+ ci.methods.push(method);
}
CXCursor_Destructor => {
if cur.method_is_virtual() {
@@ -693,7 +716,8 @@ impl CompInfo {
}
CXCursor_VarDecl => {
let linkage = cur.linkage();
- if linkage != CXLinkage_External && linkage != CXLinkage_UniqueExternal {
+ if linkage != CXLinkage_External &&
+ linkage != CXLinkage_UniqueExternal {
return CXChildVisit_Continue;
}
@@ -703,7 +727,7 @@ impl CompInfo {
}
let item = Item::parse(*cur, Some(potential_id), ctx)
- .expect("VarDecl");
+ .expect("VarDecl");
ci.inner_vars.push(item);
}
// Intentionally not handled
@@ -713,8 +737,10 @@ impl CompInfo {
CXCursor_FunctionTemplate |
CXCursor_ConversionFunction => {}
_ => {
- warn!("unhandled composite member `{}` (kind {}) in `{}` ({})",
- cur.spelling(), cur.kind(), cursor.spelling(),
+ warn!("unhandled comp member `{}` (kind {}) in `{}` ({})",
+ cur.spelling(),
+ cur.kind(),
+ cursor.spelling(),
cur.location());
}
}
diff --git a/src/ir/context.rs b/src/ir/context.rs
index 5e29e0c9..273dc3e3 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -105,10 +105,15 @@ impl<'ctx> BindgenContext<'ctx> {
let index = clang::Index::new(false, true);
+ let parse_options =
+ clangll::CXTranslationUnit_DetailedPreprocessingRecord;
let translation_unit =
- clang::TranslationUnit::parse(&index, "", &options.clang_args, &[],
- clangll::CXTranslationUnit_DetailedPreprocessingRecord)
- .expect("null TranslationUnit received from `clang::TranslationUnit::parse`");
+ clang::TranslationUnit::parse(&index,
+ "",
+ &options.clang_args,
+ &[],
+ parse_options)
+ .expect("TranslationUnit::parse");
let root_module = Self::build_root_module();
let mut me = BindgenContext {
@@ -531,7 +536,8 @@ impl<'ctx> BindgenContext<'ctx> {
// That being said, this is not so common, so just error! and hope
// for the best, returning the previous type, who knows.
if old_args.len() != args.len() {
- error!("Found partial template specialization, expect dragons!");
+ error!("Found partial template specialization, \
+ expect dragons!");
return wrapping;
}
diff --git a/src/ir/item.rs b/src/ir/item.rs
index 6857bc70..4e893e35 100644
--- a/src/ir/item.rs
+++ b/src/ir/item.rs
@@ -80,10 +80,10 @@ impl TypeCollector for ItemId {
type Extra = ();
fn collect_types(&self,
- context: &BindgenContext,
+ ctx: &BindgenContext,
types: &mut ItemSet,
extra: &()) {
- context.resolve_item(*self).collect_types(context, types, extra);
+ ctx.resolve_item(*self).collect_types(ctx, types, extra);
}
}
@@ -91,18 +91,18 @@ impl TypeCollector for Item {
type Extra = ();
fn collect_types(&self,
- context: &BindgenContext,
+ ctx: &BindgenContext,
types: &mut ItemSet,
_extra: &()) {
- if self.is_hidden(context) || types.contains(&self.id()) {
+ if self.is_hidden(ctx) || types.contains(&self.id()) {
return;
}
match *self.kind() {
ItemKind::Type(ref ty) => {
types.insert(self.id());
- if !self.is_opaque(context) {
- ty.collect_types(context, types, self);
+ if !self.is_opaque(ctx) {
+ ty.collect_types(ctx, types, self);
}
}
_ => {} // FIXME.
@@ -329,8 +329,7 @@ impl Item {
/// Normally we could do this check just in the `Type` kind, but we also
/// need to check the `applicable_template_args` more generally, since we
/// could need a type transitively from our parent, see the test added in
- /// <https://github.
- /// com/servo/rust-bindgen/pull/85/commits/2a3f93074dd2898669dbbce6e97e5cc4405d7cb1>
+ /// commit 2a3f93074dd2898669dbbce6e97e5cc4405d7cb1.
///
/// It's kind of unfortunate (in the sense that it's a sort of complex
/// process), but I think it should get all the cases.
@@ -498,9 +497,12 @@ impl Item {
let base_name = match *self.kind() {
ItemKind::Type(ref ty) => {
match *ty.kind() {
- // If we're a template specialization, our name is our parent's
- TypeKind::Comp(ref ci) if ci.is_template_specialization() => {
- return ci.specialized_template().unwrap().canonical_name(ctx);
+ // If we're a template specialization, our name is our
+ // parent's.
+ TypeKind::Comp(ref ci)
+ if ci.is_template_specialization() => {
+ return ci.specialized_template().unwrap()
+ .canonical_name(ctx);
},
// Same as above
TypeKind::ResolvedTypeRef(inner) |
@@ -524,7 +526,10 @@ impl Item {
// would be needed.
TypeKind::TemplateAlias(inner, _) => {
if for_name_checking {
- return ctx.resolve_item(inner).real_canonical_name(ctx, count_namespaces, false);
+ return ctx.resolve_item(inner)
+ .real_canonical_name(ctx,
+ count_namespaces,
+ false);
}
Some("")
}
@@ -608,8 +613,11 @@ impl Item {
ctx: &BindgenContext)
-> String {
lazy_static! {
- static ref RE_ENDS_WITH_BINDGEN_TY: Regex = Regex::new(r"_bindgen_ty(_\d+)+$").unwrap();
- static ref RE_ENDS_WITH_BINDGEN_MOD: Regex = Regex::new(r"_bindgen_mod(_\d+)+$").unwrap();
+ static ref RE_ENDS_WITH_BINDGEN_TY: Regex =
+ Regex::new(r"_bindgen_ty(_\d+)+$").unwrap();
+
+ static ref RE_ENDS_WITH_BINDGEN_MOD: Regex =
+ Regex::new(r"_bindgen_mod(_\d+)+$").unwrap();
}
let (re, kind) = match *self.kind() {
@@ -687,7 +695,7 @@ impl ClangItemParser for Item {
fn parse(cursor: clang::Cursor,
parent_id: Option<ItemId>,
- context: &mut BindgenContext)
+ ctx: &mut BindgenContext)
-> Result<ItemId, ParseError> {
use ir::function::Function;
use ir::module::Module;
@@ -701,15 +709,18 @@ impl ClangItemParser for Item {
let comment = cursor.raw_comment();
let annotations = Annotations::new(&cursor);
- let current_module = context.current_module();
+ let current_module = ctx.current_module();
+ let relevant_parent_id = parent_id.unwrap_or(current_module);
+
macro_rules! try_parse {
($what:ident) => {
- match $what::parse(cursor, context) {
+ match $what::parse(cursor, ctx) {
Ok(ParseResult::New(item, declaration)) => {
let id = ItemId::next();
- context.add_item(Item::new(id, comment, annotations,
- parent_id.unwrap_or(current_module),
- ItemKind::$what(item)),
+
+ ctx.add_item(Item::new(id, comment, annotations,
+ relevant_parent_id,
+ ItemKind::$what(item)),
declaration,
Some(cursor));
return Ok(id);
@@ -747,7 +758,7 @@ impl ClangItemParser for Item {
match Self::from_ty(&applicable_cursor.cur_type(),
Some(applicable_cursor),
parent_id,
- context) {
+ ctx) {
Ok(ty) => return Ok(ty),
Err(ParseError::Recurse) => return Err(ParseError::Recurse),
Err(ParseError::Continue) => {}
@@ -781,13 +792,13 @@ impl ClangItemParser for Item {
fn from_ty_or_ref(ty: clang::Type,
location: Option<clang::Cursor>,
parent_id: Option<ItemId>,
- context: &mut BindgenContext)
+ ctx: &mut BindgenContext)
-> ItemId {
Self::from_ty_or_ref_with_id(ItemId::next(),
ty,
location,
parent_id,
- context)
+ ctx)
}
/// Parse a C++ type. If we find a reference to a type that has not been
@@ -804,7 +815,7 @@ impl ClangItemParser for Item {
ty: clang::Type,
location: Option<clang::Cursor>,
parent_id: Option<ItemId>,
- context: &mut BindgenContext)
+ ctx: &mut BindgenContext)
-> ItemId {
debug!("from_ty_or_ref_with_id: {:?} {:?}, {:?}, {:?}",
potential_id,
@@ -812,19 +823,19 @@ impl ClangItemParser for Item {
location,
parent_id);
- if context.collected_typerefs() {
+ if ctx.collected_typerefs() {
debug!("refs already collected, resolving directly");
return Self::from_ty_with_id(potential_id,
&ty,
location,
parent_id,
- context)
+ ctx)
.expect("Unable to resolve type");
}
- if let Some(ty) = context.builtin_or_resolved_ty(potential_id,
- parent_id, &ty,
- location) {
+ if let Some(ty) = ctx.builtin_or_resolved_ty(potential_id,
+ parent_id, &ty,
+ location) {
debug!("{:?} already resolved: {:?}", ty, location);
return ty;
}
@@ -833,17 +844,17 @@ impl ClangItemParser for Item {
let is_const = ty.is_const();
let kind = TypeKind::UnresolvedTypeRef(ty, location, parent_id);
- let current_module = context.current_module();
- context.add_item(Item::new(potential_id,
- None,
- None,
- parent_id.unwrap_or(current_module),
- ItemKind::Type(Type::new(None,
- None,
- kind,
- is_const))),
- Some(clang::Cursor::null()),
- None);
+ let current_module = ctx.current_module();
+ ctx.add_item(Item::new(potential_id,
+ None,
+ None,
+ parent_id.unwrap_or(current_module),
+ ItemKind::Type(Type::new(None,
+ None,
+ kind,
+ is_const))),
+ Some(clang::Cursor::null()),
+ None);
potential_id
}
@@ -851,9 +862,9 @@ impl ClangItemParser for Item {
fn from_ty(ty: &clang::Type,
location: Option<clang::Cursor>,
parent_id: Option<ItemId>,
- context: &mut BindgenContext)
+ ctx: &mut BindgenContext)
-> Result<ItemId, ParseError> {
- Self::from_ty_with_id(ItemId::next(), ty, location, parent_id, context)
+ Self::from_ty_with_id(ItemId::next(), ty, location, parent_id, ctx)
}
/// This is one of the trickiest methods you'll find (probably along with
@@ -868,7 +879,7 @@ impl ClangItemParser for Item {
ty: &clang::Type,
location: Option<clang::Cursor>,
parent_id: Option<ItemId>,
- context: &mut BindgenContext)
+ ctx: &mut BindgenContext)
-> Result<ItemId, ParseError> {
use clangll::*;
@@ -887,13 +898,14 @@ impl ClangItemParser for Item {
let annotations = Annotations::new(&decl)
.or_else(|| location.as_ref().and_then(|l| Annotations::new(l)));
- if let Some(ref replaced) = annotations.as_ref()
- .and_then(|a| a.use_instead_of()) {
- context.replace(replaced, id);
+ if let Some(ref annotations) = annotations {
+ if let Some(ref replaced) = annotations.use_instead_of() {
+ ctx.replace(replaced, id);
+ }
}
if let Some(ty) =
- context.builtin_or_resolved_ty(id, parent_id, ty, location) {
+ ctx.builtin_or_resolved_ty(id, parent_id, ty, location) {
return Ok(ty);
}
@@ -911,7 +923,7 @@ impl ClangItemParser for Item {
};
if valid_decl {
- if let Some(&(_, item_id)) = context.currently_parsed_types
+ if let Some(&(_, item_id)) = ctx.currently_parsed_types
.iter()
.find(|&&(d, _)| d == declaration_to_look_for) {
debug!("Avoiding recursion parsing type: {:?}", ty);
@@ -919,22 +931,23 @@ impl ClangItemParser for Item {
}
}
- let current_module = context.current_module();
+ let current_module = ctx.current_module();
if valid_decl {
- context.currently_parsed_types.push((declaration_to_look_for, id));
+ ctx.currently_parsed_types.push((declaration_to_look_for, id));
}
- let result = Type::from_clang_ty(id, ty, location, parent_id, context);
+ let result = Type::from_clang_ty(id, ty, location, parent_id, ctx);
+ let relevant_parent_id = parent_id.unwrap_or(current_module);
let ret = match result {
Ok(ParseResult::AlreadyResolved(ty)) => Ok(ty),
Ok(ParseResult::New(item, declaration)) => {
- context.add_item(Item::new(id,
- comment,
- annotations,
- parent_id.unwrap_or(current_module),
- ItemKind::Type(item)),
- declaration,
- location);
+ ctx.add_item(Item::new(id,
+ comment,
+ annotations,
+ relevant_parent_id,
+ ItemKind::Type(item)),
+ declaration,
+ location);
Ok(id)
}
Err(ParseError::Continue) => Err(ParseError::Continue),
@@ -949,7 +962,7 @@ impl ClangItemParser for Item {
// logic with ir::context, so we should refactor that.
if valid_decl {
let (popped_decl, _) =
- context.currently_parsed_types.pop().unwrap();
+ ctx.currently_parsed_types.pop().unwrap();
assert_eq!(popped_decl, declaration_to_look_for);
}
@@ -959,7 +972,7 @@ impl ClangItemParser for Item {
ty,
Some(*cur),
parent_id,
- context);
+ ctx);
match result {
Ok(..) => CXChildVisit_Break,
Err(ParseError::Recurse) => CXChildVisit_Recurse,
@@ -968,7 +981,7 @@ impl ClangItemParser for Item {
});
if valid_decl {
- context.currently_parsed_types
+ ctx.currently_parsed_types
.push((declaration_to_look_for, id));
}
}
@@ -982,10 +995,11 @@ impl ClangItemParser for Item {
// It's harmless, but if we restrict that, then
// tests/headers/nsStyleAutoArray.hpp crashes.
if let Err(ParseError::Recurse) = result {
- Ok(Self::named_type_with_id(id, ty.spelling(),
+ Ok(Self::named_type_with_id(id,
+ ty.spelling(),
None,
- parent_id.unwrap_or(context.current_module()),
- context))
+ relevant_parent_id,
+ ctx))
} else {
result
}
@@ -993,8 +1007,7 @@ impl ClangItemParser for Item {
};
if valid_decl {
- let (popped_decl, _) =
- context.currently_parsed_types.pop().unwrap();
+ let (popped_decl, _) = ctx.currently_parsed_types.pop().unwrap();
assert_eq!(popped_decl, declaration_to_look_for);
}
@@ -1012,7 +1025,7 @@ impl ClangItemParser for Item {
name: S,
default: Option<ItemId>,
parent_id: ItemId,
- context: &mut BindgenContext)
+ ctx: &mut BindgenContext)
-> ItemId
where S: Into<String>,
{
@@ -1020,13 +1033,13 @@ impl ClangItemParser for Item {
// and tests/headers/variadic_tname.hpp
let name = name.into().replace("const ", "").replace(".", "");
- context.add_item(Item::new(id,
- None,
- None,
- parent_id,
- ItemKind::Type(Type::named(name, default))),
- None,
- None);
+ ctx.add_item(Item::new(id,
+ None,
+ None,
+ parent_id,
+ ItemKind::Type(Type::named(name, default))),
+ None,
+ None);
id
}
@@ -1034,15 +1047,11 @@ impl ClangItemParser for Item {
fn named_type<S>(name: S,
default: Option<ItemId>,
parent_id: ItemId,
- context: &mut BindgenContext)
+ ctx: &mut BindgenContext)
-> ItemId
where S: Into<String>,
{
- Self::named_type_with_id(ItemId::next(),
- name,
- default,
- parent_id,
- context)
+ Self::named_type_with_id(ItemId::next(), name, default, parent_id, ctx)
}
}
diff --git a/src/ir/ty.rs b/src/ir/ty.rs
index bab50024..4d26cdff 100644
--- a/src/ir/ty.rs
+++ b/src/ir/ty.rs
@@ -460,7 +460,7 @@ impl Type {
TypeKind::Pointer(..) => false,
TypeKind::UnresolvedTypeRef(..) => {
- unreachable!("Should have been resolved after parsing!")
+ unreachable!("Should have been resolved after parsing!");
}
}
}
@@ -477,17 +477,26 @@ impl Type {
ctx: &mut BindgenContext)
-> Result<ParseResult<Self>, ParseError> {
use clangll::*;
- if let Some(ty) =
- ctx.builtin_or_resolved_ty(potential_id, parent_id, ty, location) {
- debug!("{:?} already resolved: {:?}", ty, location);
- return Ok(ParseResult::AlreadyResolved(ty));
+ {
+ let already_resolved =
+ ctx.builtin_or_resolved_ty(potential_id,
+ parent_id,
+ ty,
+ location);
+ if let Some(ty) = already_resolved {
+ debug!("{:?} already resolved: {:?}", ty, location);
+ return Ok(ParseResult::AlreadyResolved(ty));
+ }
}
let layout = ty.fallible_layout().ok();
let cursor = ty.declaration();
let mut name = cursor.spelling();
- debug!("from_clang_ty: {:?}, ty: {:?}, loc: {:?}", potential_id, ty, location);
+ debug!("from_clang_ty: {:?}, ty: {:?}, loc: {:?}",
+ potential_id,
+ ty,
+ location);
debug!("currently_parsed_types: {:?}", ctx.currently_parsed_types);
let canonical_ty = ty.canonical_type();
@@ -502,19 +511,17 @@ impl Type {
ctx);
}
CXType_Unexposed | CXType_Invalid => {
- // For some reason Clang doesn't give us any hint
- // in some situations where we should generate a
- // function pointer (see
- // tests/headers/func_ptr_in_struct.h), so we do a
- // guess here trying to see if it has a valid return
- // type.
+ // For some reason Clang doesn't give us any hint in some
+ // situations where we should generate a function pointer (see
+ // tests/headers/func_ptr_in_struct.h), so we do a guess here
+ // trying to see if it has a valid return type.
if ty.ret_type().is_some() {
- let signature =
- try!(FunctionSig::from_ty(ty, &location.unwrap_or(cursor), ctx));
+ let signature = try!(FunctionSig::from_ty(ty,
+ &location.unwrap_or(cursor),
+ ctx));
TypeKind::Function(signature)
// Same here, with template specialisations we can safely
- // assume
- // this is a Comp(..)
+ // assume this is a Comp(..)
} else if ty.template_args().map_or(false, |x| x.len() > 0) {
debug!("Template specialization: {:?}", ty);
let complex =
@@ -543,11 +550,13 @@ impl Type {
location.visit(|cur, _| {
match cur.kind() {
CXCursor_TypeAliasDecl => {
- debug_assert!(cur.cur_type().kind() == CXType_Typedef);
- inner = Item::from_ty(&cur.cur_type(),
- Some(*cur),
- Some(potential_id),
- ctx);
+ debug_assert!(cur.cur_type().kind() ==
+ CXType_Typedef);
+ inner =
+ Item::from_ty(&cur.cur_type(),
+ Some(*cur),
+ Some(potential_id),
+ ctx);
}
CXCursor_TemplateTypeParameter => {
// See the comment in src/ir/comp.rs
@@ -560,11 +569,13 @@ impl Type {
Item::from_ty(&cur.cur_type(),
Some(*cur),
Some(potential_id),
- ctx).ok();
+ ctx)
+ .ok();
let param =
Item::named_type(cur.spelling(),
default_type,
- potential_id, ctx);
+ potential_id,
+ ctx);
args.push(param);
}
_ => {}
@@ -573,7 +584,8 @@ impl Type {
});
if inner.is_err() {
- error!("Failed to parse templated type alias {:?}", location);
+ error!("Failed to parse templated alias {:?}",
+ location);
return Err(ParseError::Continue);
}
@@ -592,24 +604,37 @@ impl Type {
}
CXCursor_TemplateRef => {
let referenced = location.referenced();
+ let referenced_ty = referenced.cur_type();
+ let referenced_declaration =
+ Some(referenced_ty.declaration());
+
return Self::from_clang_ty(potential_id,
- &referenced.cur_type(),
- Some(referenced.cur_type().declaration()),
+ &referenced_ty,
+ referenced_declaration,
parent_id,
ctx);
}
CXCursor_TypeRef => {
let referenced = location.referenced();
- return Ok(ParseResult::AlreadyResolved(
- Item::from_ty_or_ref_with_id(potential_id,
- referenced.cur_type(),
- Some(referenced.cur_type().declaration()),
- parent_id,
- ctx)));
+ let referenced_ty = referenced.cur_type();
+ let referenced_declaration =
+ Some(referenced_ty.declaration());
+
+ let item =
+ Item::from_ty_or_ref_with_id(
+ potential_id,
+ referenced_ty,
+ referenced_declaration,
+ parent_id,
+ ctx);
+ return Ok(ParseResult::AlreadyResolved(item));
}
_ => {
if ty.kind() == CXType_Unexposed {
- warn!("Unexposed type {:?}, recursing inside, loc: {:?}", ty, location);
+ warn!("Unexposed type {:?}, recursing inside, \
+ loc: {:?}",
+ ty,
+ location);
return Err(ParseError::Recurse);
}
@@ -643,16 +668,12 @@ impl Type {
return Err(ParseError::Continue);
}
}
- // NOTE: We don't resolve pointers eagerly because the
- // pointee type
- // might not have been parsed, and if it contains templates
- // or
- // something else we might get confused, see the comment
- // inside
+ // NOTE: We don't resolve pointers eagerly because the pointee type
+ // might not have been parsed, and if it contains templates or
+ // something else we might get confused, see the comment inside
// TypeRef.
//
- // We might need to, though, if the context is already in
- // the
+ // We might need to, though, if the context is already in the
// process of resolving them.
CXType_MemberPointer |
CXType_Pointer => {
@@ -663,8 +684,7 @@ impl Type {
TypeKind::Pointer(inner)
}
CXType_BlockPointer => TypeKind::BlockPointer,
- // XXX: RValueReference is most likely wrong, but I don't
- // think we
+ // XXX: RValueReference is most likely wrong, but I don't think we
// can even add bindings for that, so huh.
CXType_RValueReference |
CXType_LValueReference => {
@@ -678,19 +698,18 @@ impl Type {
CXType_VariableArray |
CXType_DependentSizedArray |
CXType_IncompleteArray => {
- let inner =
- Item::from_ty(ty.elem_type()
- .as_ref()
- .expect("Not an appropriate type?"),
- location,
- parent_id,
- ctx)
- .expect("Not able to resolve array element?");
+ let inner = Item::from_ty(ty.elem_type().as_ref().unwrap(),
+ location,
+ parent_id,
+ ctx)
+ .expect("Not able to resolve array element?");
TypeKind::Pointer(inner)
}
CXType_FunctionNoProto |
CXType_FunctionProto => {
- let signature = try!(FunctionSig::from_ty(ty, &location.unwrap_or(cursor), ctx));
+ let signature = try!(FunctionSig::from_ty(ty,
+ &location.unwrap_or(cursor),
+ ctx));
TypeKind::Function(signature)
}
CXType_Typedef => {
@@ -709,37 +728,29 @@ impl Type {
.expect("Not a complex type?");
TypeKind::Comp(complex)
}
- // FIXME: We stub vectors as arrays since in 99% of the
- // cases the
- // layout is going to be correct, and there's no way we can
- // generate
+ // FIXME: We stub vectors as arrays since in 99% of the cases the
+ // layout is going to be correct, and there's no way we can generate
// vector types properly in Rust for now.
//
// That being said, that should be fixed eventually.
CXType_Vector |
CXType_ConstantArray => {
- let inner =
- Item::from_ty(ty.elem_type()
- .as_ref()
- .expect("Not an appropriate type?"),
- location,
- parent_id,
- ctx)
- .expect("Not able to resolve array element?");
+ let inner = Item::from_ty(ty.elem_type().as_ref().unwrap(),
+ location,
+ parent_id,
+ ctx)
+ .expect("Not able to resolve array element?");
TypeKind::Array(inner, ty.num_elements().unwrap())
}
// A complex number is always a real and an imaginary part,
// so
// represent that as a two-item array.
CXType_Complex => {
- let inner =
- Item::from_ty(ty.elem_type()
- .as_ref()
- .expect("Not an appropriate type?"),
- location,
- parent_id,
- ctx)
- .expect("Not able to resolve array element?");
+ let inner = Item::from_ty(ty.elem_type().as_ref().unwrap(),
+ location,
+ parent_id,
+ ctx)
+ .expect("Not able to resolve array element?");
TypeKind::Array(inner, 2)
}
#[cfg(not(feature="llvm_stable"))]
diff --git a/src/ir/var.rs b/src/ir/var.rs
index 6d9b61e1..216d8185 100644
--- a/src/ir/var.rs
+++ b/src/ir/var.rs
@@ -70,14 +70,17 @@ impl Var {
impl ClangSubItemParser for Var {
fn parse(cursor: clang::Cursor,
- context: &mut BindgenContext)
+ ctx: &mut BindgenContext)
-> Result<ParseResult<Self>, ParseError> {
use clangll::*;
match cursor.kind() {
CXCursor_MacroDefinition => {
- let value = match parse_int_literal_tokens(&cursor, context.translation_unit()) {
- None => return Err(ParseError::Continue),
+ let value = parse_int_literal_tokens(&cursor,
+ ctx.translation_unit());
+
+ let value = match value {
Some(v) => v,
+ None => return Err(ParseError::Continue),
};
let name = cursor.spelling();
@@ -86,24 +89,20 @@ impl ClangSubItemParser for Var {
return Err(ParseError::Continue);
}
- if context.parsed_macro(&name) {
+ if ctx.parsed_macro(&name) {
warn!("Duplicated macro definition: {}", name);
return Err(ParseError::Continue);
}
- context.note_parsed_macro(name.clone());
+ ctx.note_parsed_macro(name.clone());
let ty = if value < 0 {
- Item::builtin_type(TypeKind::Int(IntKind::Int),
- true,
- context)
+ Item::builtin_type(TypeKind::Int(IntKind::Int), true, ctx)
} else if value.abs() > u32::max_value() as i64 {
Item::builtin_type(TypeKind::Int(IntKind::ULongLong),
true,
- context)
+ ctx)
} else {
- Item::builtin_type(TypeKind::Int(IntKind::UInt),
- true,
- context)
+ Item::builtin_type(TypeKind::Int(IntKind::UInt), true, ctx)
};
Ok(ParseResult::New(Var::new(name,
@@ -125,20 +124,19 @@ impl ClangSubItemParser for Var {
// XXX this is redundant, remove!
let is_const = ty.is_const();
- let ty = Item::from_ty(&ty, Some(cursor), None, context)
+ let ty = Item::from_ty(&ty, Some(cursor), None, ctx)
.expect("Unable to resolve constant type?");
// Note: Ty might not be totally resolved yet, see
// tests/headers/inner_const.hpp
//
// That's fine because in that case we know it's not a literal.
- let value = context.safe_resolve_type(ty)
- .and_then(|t| t.safe_canonical_type(context)).and_then(|t| {
- if t.is_integer() {
- get_integer_literal_from_cursor(&cursor, context.translation_unit())
- } else {
- None
- }
+ let value = ctx.safe_resolve_type(ty)
+ .and_then(|t| t.safe_canonical_type(ctx))
+ .and_then(|t| if t.is_integer() { Some(t) } else { None })
+ .and_then(|_| {
+ get_integer_literal_from_cursor(&cursor,
+ ctx.translation_unit())
});
let mangling = cursor_mangling(&cursor);