summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ir/comp.rs18
-rw-r--r--src/ir/context.rs2
-rw-r--r--src/ir/item.rs28
-rw-r--r--src/ir/ty.rs58
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 = ();