diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/comp.rs | 18 | ||||
-rw-r--r-- | src/ir/context.rs | 2 | ||||
-rw-r--r-- | src/ir/item.rs | 28 | ||||
-rw-r--r-- | src/ir/ty.rs | 58 |
4 files changed, 99 insertions, 7 deletions
diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 1ca39559..80372cab 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -5,7 +5,7 @@ use super::context::{BindgenContext, ItemId}; use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault}; use super::item::Item; use super::layout::Layout; -use super::ty::Type; +use super::ty::{TemplateDeclaration, Type}; use super::type_collector::{ItemSet, TypeCollector}; use clang; use parse::{ClangItemParser, ParseError}; @@ -564,10 +564,8 @@ impl CompInfo { }); ci.is_anonymous = cursor.is_anonymous(); ci.template_args = match ty.template_args() { - // In forward declarations and not specializations, - // etc, they are in - // the ast, we'll meet them in - // CXCursor_TemplateTypeParameter + // In forward declarations and not specializations, etc, they are in + // the ast, we'll meet them in CXCursor_TemplateTypeParameter None => vec![], Some(arg_types) => { let num_arg_types = arg_types.len(); @@ -916,6 +914,16 @@ impl CompInfo { } } +impl TemplateDeclaration for CompInfo { + fn template_params(&self, _ctx: &BindgenContext) -> Option<Vec<ItemId>> { + if self.template_args.is_empty() { + None + } else { + Some(self.template_args.clone()) + } + } +} + impl CanDeriveDebug for CompInfo { type Extra = Option<Layout>; diff --git a/src/ir/context.rs b/src/ir/context.rs index a7482394..edf42ec8 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -5,7 +5,7 @@ use super::int::IntKind; use super::item::{Item, ItemCanonicalPath}; use super::item_kind::ItemKind; use super::module::{Module, ModuleKind}; -use super::ty::{FloatKind, Type, TypeKind}; +use super::ty::{FloatKind, TemplateDeclaration, Type, TypeKind}; use super::type_collector::{ItemSet, TypeCollector}; use BindgenOptions; use cexpr; diff --git a/src/ir/item.rs b/src/ir/item.rs index f3d7a644..3ce228b6 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -6,7 +6,7 @@ use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault}; use super::function::Function; use super::item_kind::ItemKind; use super::module::Module; -use super::ty::{Type, TypeKind}; +use super::ty::{TemplateDeclaration, Type, TypeKind}; use super::type_collector::{ItemSet, TypeCollector}; use clang; use clang_sys; @@ -902,6 +902,32 @@ impl Item { } } +impl TemplateDeclaration for ItemId { + fn template_params(&self, ctx: &BindgenContext) -> Option<Vec<ItemId>> { + ctx.resolve_item_fallible(*self) + .and_then(|item| item.template_params(ctx)) + } +} + +impl TemplateDeclaration for Item { + fn template_params(&self, ctx: &BindgenContext) -> Option<Vec<ItemId>> { + self.kind.template_params(ctx) + } +} + +impl TemplateDeclaration for ItemKind { + fn template_params(&self, ctx: &BindgenContext) -> Option<Vec<ItemId>> { + match *self { + ItemKind::Type(ref ty) => ty.template_params(ctx), + // TODO FITZGEN: shouldn't functions be able to have free template + // params? + ItemKind::Module(_) | + ItemKind::Function(_) | + ItemKind::Var(_) => None, + } + } +} + // An utility function to handle recursing inside nested types. fn visit_child(cur: clang::Cursor, id: ItemId, diff --git a/src/ir/ty.rs b/src/ir/ty.rs index a2a65623..0c90547e 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -14,6 +14,29 @@ use clang::{self, Cursor}; use parse::{ClangItemParser, ParseError, ParseResult}; use std::mem; +/// Template declaration related methods. +pub trait TemplateDeclaration { + /// Get the set of `ItemId`s that make up this template declaration's free + /// template parameters. + /// + /// Note that these might *not* all be named types: C++ allows + /// constant-value template parameters. Of course, Rust does not allow + /// generic parameters to be anything but types, so we must treat them as + /// opaque, and avoid instantiating them. + fn template_params(&self, ctx: &BindgenContext) -> Option<Vec<ItemId>>; + + /// Get the number of free template parameters this template declaration + /// has. + /// + /// Implementations *may* return `Some` from this method when + /// `template_params` returns `None`. This is useful when we only have + /// partial information about the template declaration, such as when we are + /// in the middle of parsing it. + fn num_template_params(&self, ctx: &BindgenContext) -> Option<usize> { + self.template_params(ctx).map(|params| params.len()) + } +} + /// The base representation of a type in bindgen. /// /// A type has an optional name, which if present cannot be empty, a `layout` @@ -438,6 +461,41 @@ fn is_invalid_named_type_empty_name() { } +impl TemplateDeclaration for Type { + fn template_params(&self, ctx: &BindgenContext) -> Option<Vec<ItemId>> { + self.kind.template_params(ctx) + } +} + +impl TemplateDeclaration for TypeKind { + fn template_params(&self, ctx: &BindgenContext) -> Option<Vec<ItemId>> { + match *self { + TypeKind::ResolvedTypeRef(id) => { + ctx.resolve_type(id).template_params(ctx) + } + TypeKind::Comp(ref comp) => comp.template_params(ctx), + TypeKind::TemplateAlias(_, ref args) => Some(args.clone()), + + TypeKind::TemplateInstantiation(..) | + TypeKind::Void | + TypeKind::NullPtr | + TypeKind::Int(_) | + TypeKind::Float(_) | + TypeKind::Complex(_) | + TypeKind::Array(..) | + TypeKind::Function(_) | + TypeKind::Enum(_) | + TypeKind::Pointer(_) | + TypeKind::BlockPointer | + TypeKind::Reference(_) | + TypeKind::UnresolvedTypeRef(..) | + TypeKind::Named | + TypeKind::Alias(_) | + TypeKind::ObjCInterface(_) => None, + } + } +} + impl CanDeriveDebug for Type { type Extra = (); |