diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/codegen/mod.rs | 4 | ||||
-rw-r--r-- | src/ir/comp.rs | 2 | ||||
-rw-r--r-- | src/ir/context.rs | 4 | ||||
-rw-r--r-- | src/ir/item.rs | 4 | ||||
-rw-r--r-- | src/ir/named.rs | 4 | ||||
-rw-r--r-- | src/ir/template.rs | 142 | ||||
-rw-r--r-- | src/ir/ty.rs | 145 | ||||
-rw-r--r-- | src/uses.rs | 2 |
8 files changed, 153 insertions, 154 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 0785f2fd..a5df8945 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -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::{TemplateParameters, Type, TypeKind}; +use ir::template::{AsNamed, TemplateInstantiation, TemplateParameters}; +use ir::ty::{Type, TypeKind}; use ir::var::Var; use std::borrow::Cow; diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 8a796e5e..80c51b8f 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -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::TemplateParameters; +use super::template::TemplateParameters; use clang; use parse::{ClangItemParser, ParseError}; use std::cell::Cell; diff --git a/src/ir/context.rs b/src/ir/context.rs index 6cf3cdcd..60ea90c6 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -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, TemplateParameters, Type, TypeKind}; +use super::ty::{FloatKind, Type, TypeKind}; use BindgenOptions; use cexpr; use callbacks::ParseCallbacks; diff --git a/src/ir/item.rs b/src/ir/item.rs index 5d95130f..20451bbc 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -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::{TemplateParameters, Type, TypeKind}; +use super::ty::{Type, TypeKind}; use clang; use clang_sys; use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult}; diff --git a/src/ir/named.rs b/src/ir/named.rs index 1493b170..82fd674c 100644 --- a/src/ir/named.rs +++ b/src/ir/named.rs @@ -128,9 +128,9 @@ use super::context::{BindgenContext, ItemId}; use super::item::{Item, ItemSet}; -use super::template::{AsNamed, TemplateInstantiation}; +use super::template::{AsNamed, TemplateInstantiation, TemplateParameters}; use super::traversal::{EdgeKind, Trace}; -use super::ty::{TemplateParameters, TypeKind}; +use super::ty::TypeKind; use std::collections::{HashMap, HashSet}; use std::fmt; diff --git a/src/ir/template.rs b/src/ir/template.rs index 3484a9c6..d2996330 100644 --- a/src/ir/template.rs +++ b/src/ir/template.rs @@ -29,12 +29,152 @@ use super::context::{BindgenContext, ItemId}; use super::derive::{CanDeriveCopy, CanDeriveDebug}; -use super::item::Item; +use super::item::{Item, ItemAncestors}; use super::layout::Layout; use super::traversal::{EdgeKind, Trace, Tracer}; use clang; use parse::ClangItemParser; +/// Template declaration (and such declaration's template parameters) related +/// methods. +/// +/// This trait's methods distinguish between `None` and `Some([])` for +/// declarations that are not templates and template declarations with zero +/// parameters, in general. +/// +/// Consider this example: +/// +/// ```c++ +/// template <typename T, typename U> +/// class Foo { +/// T use_of_t; +/// U use_of_u; +/// +/// template <typename V> +/// using Bar = V*; +/// +/// class Inner { +/// T x; +/// U y; +/// Bar<int> z; +/// }; +/// +/// template <typename W> +/// class Lol { +/// // No use of W, but here's a use of T. +/// T t; +/// }; +/// +/// template <typename X> +/// class Wtf { +/// // X is not used because W is not used. +/// Lol<X> lololol; +/// }; +/// }; +/// +/// class Qux { +/// int y; +/// }; +/// ``` +/// +/// The following table depicts the results of each trait method when invoked on +/// each of the declarations above: +/// +/// +------+----------------------+--------------------------+------------------------+---- +/// |Decl. | self_template_params | num_self_template_params | all_template_parameters| ... +/// +------+----------------------+--------------------------+------------------------+---- +/// |Foo | Some([T, U]) | Some(2) | Some([T, U]) | ... +/// |Bar | Some([V]) | Some(1) | Some([T, U, V]) | ... +/// |Inner | None | None | Some([T, U]) | ... +/// |Lol | Some([W]) | Some(1) | Some([T, U, W]) | ... +/// |Wtf | Some([X]) | Some(1) | Some([T, U, X]) | ... +/// |Qux | None | None | None | ... +/// +------+----------------------+--------------------------+------------------------+---- +/// +/// ----+------+-----+----------------------+ +/// ... |Decl. | ... | used_template_params | +/// ----+------+-----+----------------------+ +/// ... |Foo | ... | Some([T, U]) | +/// ... |Bar | ... | Some([V]) | +/// ... |Inner | ... | None | +/// ... |Lol | ... | Some([T]) | +/// ... |Wtf | ... | Some([T]) | +/// ... |Qux | ... | None | +/// ----+------+-----+----------------------+ +pub trait TemplateParameters { + /// 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 as well as template-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 self_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_self_template_params(&self, ctx: &BindgenContext) -> Option<usize> { + self.self_template_params(ctx).map(|params| params.len()) + } + + /// Get the complete set of template parameters that can affect this + /// declaration. + /// + /// Note that this item doesn't need to be a template declaration itself for + /// `Some` to be returned here (in contrast to `self_template_params`). If + /// this item is a member of a template declaration, then the parent's + /// template parameters are included here. + /// + /// In the example above, `Inner` depends on both of the `T` and `U` type + /// parameters, even though it is not itself a template declaration and + /// therefore has no type parameters itself. Perhaps it helps to think about + /// how we would fully reference such a member type in C++: + /// `Foo<int,char>::Inner`. `Foo` *must* be instantiated with template + /// arguments before we can gain access to the `Inner` member type. + fn all_template_params(&self, ctx: &BindgenContext) -> Option<Vec<ItemId>> + where Self: ItemAncestors, + { + let each_self_params: Vec<Vec<_>> = self.ancestors(ctx) + .filter_map(|id| id.self_template_params(ctx)) + .collect(); + if each_self_params.is_empty() { + None + } else { + Some(each_self_params.into_iter() + .rev() + .flat_map(|params| params) + .collect()) + } + } + + /// Get only the set of template parameters that this item uses. This is a + /// subset of `all_template_params` and does not necessarily contain any of + /// `self_template_params`. + fn used_template_params(&self, ctx: &BindgenContext) -> Option<Vec<ItemId>> + where Self: AsRef<ItemId>, + { + assert!(ctx.in_codegen_phase(), + "template parameter usage is not computed until codegen"); + + let id = *self.as_ref(); + ctx.resolve_item(id) + .all_template_params(ctx) + .map(|all_params| { + all_params.into_iter() + .filter(|p| ctx.uses_template_parameter(id, *p)) + .collect() + }) + } +} + /// A trait for things which may or may not be a named template type parameter. pub trait AsNamed { /// Any extra information the implementor might need to make this decision. diff --git a/src/ir/ty.rs b/src/ir/ty.rs index 0b1cf558..9fabf980 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -7,10 +7,10 @@ use super::dot::DotAttributes; use super::enum_ty::Enum; use super::function::FunctionSig; use super::int::IntKind; -use super::item::{Item, ItemAncestors}; +use super::item::Item; use super::layout::{Layout, Opaque}; use super::objc::ObjCInterface; -use super::template::{AsNamed, TemplateInstantiation}; +use super::template::{AsNamed, TemplateInstantiation, TemplateParameters}; use super::traversal::{EdgeKind, Trace, Tracer}; use clang::{self, Cursor}; use parse::{ClangItemParser, ParseError, ParseResult}; @@ -18,147 +18,6 @@ use std::cell::Cell; use std::io; use std::mem; -/// Template declaration (and such declaration's template parameters) related -/// methods. -/// -/// This trait's methods distinguish between `None` and `Some([])` for -/// declarations that are not templates and template declarations with zero -/// parameters, in general. -/// -/// Consider this example: -/// -/// ```c++ -/// template <typename T, typename U> -/// class Foo { -/// T use_of_t; -/// U use_of_u; -/// -/// template <typename V> -/// using Bar = V*; -/// -/// class Inner { -/// T x; -/// U y; -/// Bar<int> z; -/// }; -/// -/// template <typename W> -/// class Lol { -/// // No use of W, but here's a use of T. -/// T t; -/// }; -/// -/// template <typename X> -/// class Wtf { -/// // X is not used because W is not used. -/// Lol<X> lololol; -/// }; -/// }; -/// -/// class Qux { -/// int y; -/// }; -/// ``` -/// -/// The following table depicts the results of each trait method when invoked on -/// each of the declarations above: -/// -/// +------+----------------------+--------------------------+------------------------+---- -/// |Decl. | self_template_params | num_self_template_params | all_template_parameters| ... -/// +------+----------------------+--------------------------+------------------------+---- -/// |Foo | Some([T, U]) | Some(2) | Some([T, U]) | ... -/// |Bar | Some([V]) | Some(1) | Some([T, U, V]) | ... -/// |Inner | None | None | Some([T, U]) | ... -/// |Lol | Some([W]) | Some(1) | Some([T, U, W]) | ... -/// |Wtf | Some([X]) | Some(1) | Some([T, U, X]) | ... -/// |Qux | None | None | None | ... -/// +------+----------------------+--------------------------+------------------------+---- -/// -/// ----+------+-----+----------------------+ -/// ... |Decl. | ... | used_template_params | -/// ----+------+-----+----------------------+ -/// ... |Foo | ... | Some([T, U]) | -/// ... |Bar | ... | Some([V]) | -/// ... |Inner | ... | None | -/// ... |Lol | ... | Some([T]) | -/// ... |Wtf | ... | Some([T]) | -/// ... |Qux | ... | None | -/// ----+------+-----+----------------------+ - -pub trait TemplateParameters { - /// 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 as well as template-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 self_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_self_template_params(&self, ctx: &BindgenContext) -> Option<usize> { - self.self_template_params(ctx).map(|params| params.len()) - } - - /// Get the complete set of template parameters that can affect this - /// declaration. - /// - /// Note that this item doesn't need to be a template declaration itself for - /// `Some` to be returned here (in contrast to `self_template_params`). If - /// this item is a member of a template declaration, then the parent's - /// template parameters are included here. - /// - /// In the example above, `Inner` depends on both of the `T` and `U` type - /// parameters, even though it is not itself a template declaration and - /// therefore has no type parameters itself. Perhaps it helps to think about - /// how we would fully reference such a member type in C++: - /// `Foo<int,char>::Inner`. `Foo` *must* be instantiated with template - /// arguments before we can gain access to the `Inner` member type. - fn all_template_params(&self, ctx: &BindgenContext) -> Option<Vec<ItemId>> - where Self: ItemAncestors, - { - let each_self_params: Vec<Vec<_>> = self.ancestors(ctx) - .filter_map(|id| id.self_template_params(ctx)) - .collect(); - if each_self_params.is_empty() { - None - } else { - Some(each_self_params.into_iter() - .rev() - .flat_map(|params| params) - .collect()) - } - } - - /// Get only the set of template parameters that this item uses. This is a - /// subset of `all_template_params` and does not necessarily contain any of - /// `self_template_params`. - fn used_template_params(&self, ctx: &BindgenContext) -> Option<Vec<ItemId>> - where Self: AsRef<ItemId>, - { - assert!(ctx.in_codegen_phase(), - "template parameter usage is not computed until codegen"); - - let id = *self.as_ref(); - ctx.resolve_item(id) - .all_template_params(ctx) - .map(|all_params| { - all_params.into_iter() - .filter(|p| ctx.uses_template_parameter(id, *p)) - .collect() - }) - } -} - /// The base representation of a type in bindgen. /// /// A type has an optional name, which if present cannot be empty, a `layout` diff --git a/src/uses.rs b/src/uses.rs index 40344dd6..fee2be24 100644 --- a/src/uses.rs +++ b/src/uses.rs @@ -37,7 +37,7 @@ use ir::context::BindgenContext; use ir::item::{Item, ItemAncestors, ItemCanonicalName}; -use ir::ty::TemplateParameters; +use ir::template::TemplateParameters; use std::io; // Like `canonical_path`, except we always take namespaces into account, ignore |