Skip to content
10 changes: 6 additions & 4 deletions src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ use ir::item_kind::ItemKind;
use ir::layout::Layout;
use ir::module::Module;
use ir::objc::{ObjCInterface, ObjCMethod};
use ir::template::{AsNamed, TemplateInstantiation};
use ir::ty::{TemplateDeclaration, Type, TypeKind};
use ir::template::{AsNamed, TemplateInstantiation, TemplateParameters};
use ir::ty::{Type, TypeKind};
use ir::var::Var;

use std::borrow::Cow;
Expand Down Expand Up @@ -2647,8 +2647,10 @@ impl TryToRustTy for TemplateInstantiation {
// This can happen if we generated an opaque type for a partial
// template specialization, and we've hit an instantiation of
// that partial specialization.
extra_assert!(ctx.resolve_type_through_type_refs(decl)
.is_opaque());
extra_assert!(decl.into_resolver()
.through_type_refs()
.resolve(ctx)
.is_opaque(ctx));
return Err(error::Error::InstantiationOfOpaqueType);
}
};
Expand Down
4 changes: 2 additions & 2 deletions src/ir/comp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault};
use super::item::Item;
use super::layout::Layout;
use super::traversal::{EdgeKind, Trace, Tracer};
use super::ty::TemplateDeclaration;
use super::template::TemplateParameters;
use clang;
use parse::{ClangItemParser, ParseError};
use std::cell::Cell;
Expand Down Expand Up @@ -812,7 +812,7 @@ impl CompInfo {
}
}

impl TemplateDeclaration for CompInfo {
impl TemplateParameters for CompInfo {
fn self_template_params(&self,
_ctx: &BindgenContext)
-> Option<Vec<ItemId>> {
Expand Down
88 changes: 70 additions & 18 deletions src/ir/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ use super::item::{Item, ItemCanonicalPath, ItemSet};
use super::item_kind::ItemKind;
use super::module::{Module, ModuleKind};
use super::named::{UsedTemplateParameters, analyze};
use super::template::TemplateInstantiation;
use super::template::{TemplateInstantiation, TemplateParameters};
use super::traversal::{self, Edge, ItemTraversal};
use super::ty::{FloatKind, TemplateDeclaration, Type, TypeKind};
use super::ty::{FloatKind, Type, TypeKind};
use BindgenOptions;
use cexpr;
use callbacks::ParseCallbacks;
Expand Down Expand Up @@ -712,21 +712,6 @@ impl<'ctx> BindgenContext<'ctx> {
}
}

/// Resolve the given `ItemId` into a `Type`, and keep doing so while we see
/// `ResolvedTypeRef`s to other items until we get to the final `Type`.
pub fn resolve_type_through_type_refs(&self, item_id: ItemId) -> &Type {
assert!(self.collected_typerefs());

let mut id = item_id;
loop {
let ty = self.resolve_type(id);
match *ty.kind() {
TypeKind::ResolvedTypeRef(next_id) => id = next_id,
_ => return ty,
}
}
}

/// Get the current module.
pub fn current_module(&self) -> ItemId {
self.current_module
Expand Down Expand Up @@ -1420,6 +1405,73 @@ impl<'ctx> BindgenContext<'ctx> {
}
}

/// A builder struct for configuring item resolution options.
#[derive(Debug, Copy, Clone)]
pub struct ItemResolver {
id: ItemId,
through_type_refs: bool,
through_type_aliases: bool,
}

impl ItemId {
/// Create an `ItemResolver` from this item id.
pub fn into_resolver(self) -> ItemResolver {
self.into()
}
}

impl From<ItemId> for ItemResolver {
fn from(id: ItemId) -> ItemResolver {
ItemResolver::new(id)
}
}

impl ItemResolver {
/// Construct a new `ItemResolver` from the given id.
pub fn new(id: ItemId) -> ItemResolver {
ItemResolver {
id: id,
through_type_refs: false,
through_type_aliases: false,
}
}

/// Keep resolving through `Type::TypeRef` items.
pub fn through_type_refs(mut self) -> ItemResolver {
self.through_type_refs = true;
self
}

/// Keep resolving through `Type::Alias` items.
pub fn through_type_aliases(mut self) -> ItemResolver {
self.through_type_aliases = true;
self
}

/// Finish configuring and perform the actual item resolution.
pub fn resolve<'a, 'b>(self, ctx: &'a BindgenContext<'b>) -> &'a Item {
assert!(ctx.collected_typerefs());

let mut id = self.id;
loop {
let item = ctx.resolve_item(id);
let ty_kind = item.as_type().map(|t| t.kind());
match ty_kind {
Some(&TypeKind::ResolvedTypeRef(next_id)) if self.through_type_refs => {
id = next_id;
}
// We intentionally ignore template aliases here, as they are
// more complicated, and don't represent a simple renaming of
// some type.
Some(&TypeKind::Alias(next_id)) if self.through_type_aliases => {
id = next_id;
}
_ => return item,
}
}
}
}

/// A type that we are in the middle of parsing.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct PartialType {
Expand Down Expand Up @@ -1449,7 +1501,7 @@ impl PartialType {
}
}

impl TemplateDeclaration for PartialType {
impl TemplateParameters for PartialType {
fn self_template_params(&self,
_ctx: &BindgenContext)
-> Option<Vec<ItemId>> {
Expand Down
10 changes: 5 additions & 5 deletions src/ir/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use super::function::Function;
use super::item_kind::ItemKind;
use super::layout::Opaque;
use super::module::Module;
use super::template::AsNamed;
use super::template::{AsNamed, TemplateParameters};
use super::traversal::{EdgeKind, Trace, Tracer};
use super::ty::{TemplateDeclaration, Type, TypeKind};
use super::ty::{Type, TypeKind};
use clang;
use clang_sys;
use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult};
Expand Down Expand Up @@ -830,7 +830,7 @@ impl DotAttributes for Item {
}
}

impl TemplateDeclaration for ItemId {
impl TemplateParameters for ItemId {
fn self_template_params(&self,
ctx: &BindgenContext)
-> Option<Vec<ItemId>> {
Expand All @@ -839,15 +839,15 @@ impl TemplateDeclaration for ItemId {
}
}

impl TemplateDeclaration for Item {
impl TemplateParameters for Item {
fn self_template_params(&self,
ctx: &BindgenContext)
-> Option<Vec<ItemId>> {
self.kind.self_template_params(ctx)
}
}

impl TemplateDeclaration for ItemKind {
impl TemplateParameters for ItemKind {
fn self_template_params(&self,
ctx: &BindgenContext)
-> Option<Vec<ItemId>> {
Expand Down
Loading