summaryrefslogtreecommitdiff
path: root/libbindgen/src/ir
diff options
context:
space:
mode:
Diffstat (limited to 'libbindgen/src/ir')
-rw-r--r--libbindgen/src/ir/comp.rs70
-rw-r--r--libbindgen/src/ir/function.rs13
-rw-r--r--libbindgen/src/ir/item.rs23
3 files changed, 69 insertions, 37 deletions
diff --git a/libbindgen/src/ir/comp.rs b/libbindgen/src/ir/comp.rs
index d2ace023..c351a152 100644
--- a/libbindgen/src/ir/comp.rs
+++ b/libbindgen/src/ir/comp.rs
@@ -23,6 +23,9 @@ pub enum CompKind {
/// The kind of C++ method.
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum MethodKind {
+ /// A constructor. We represent it as method for convenience, to avoid code
+ /// duplication.
+ Constructor,
/// A static method.
Static,
/// A normal method.
@@ -45,7 +48,7 @@ pub struct Method {
impl Method {
/// Construct a new `Method`.
- fn new(kind: MethodKind, signature: ItemId, is_const: bool) -> Self {
+ pub fn new(kind: MethodKind, signature: ItemId, is_const: bool) -> Self {
Method {
kind: kind,
signature: signature,
@@ -58,6 +61,11 @@ impl Method {
self.kind
}
+ /// Is this a constructor?
+ pub fn is_constructor(&self) -> bool {
+ self.kind == MethodKind::Constructor
+ }
+
/// Is this a virtual method?
pub fn is_virtual(&self) -> bool {
self.kind == MethodKind::Virtual
@@ -167,6 +175,9 @@ pub struct CompInfo {
/// The method declarations inside this class, if in C++ mode.
methods: Vec<Method>,
+ /// The different constructors this struct or class contains.
+ constructors: Vec<ItemId>,
+
/// Vector of classes this one inherits from.
base_members: Vec<ItemId>,
@@ -235,6 +246,7 @@ impl CompInfo {
fields: vec![],
template_args: vec![],
methods: vec![],
+ constructors: vec![],
base_members: vec![],
ref_template: None,
inner_types: vec![],
@@ -454,6 +466,10 @@ impl CompInfo {
&self.methods
}
+ pub fn constructors(&self) -> &[ItemId] {
+ &self.constructors
+ }
+
/// What kind of compound type is this?
pub fn kind(&self) -> CompKind {
self.kind
@@ -651,14 +667,15 @@ impl CompInfo {
.expect("BaseSpecifier");
ci.base_members.push(type_id);
}
+ CXCursor_Constructor |
+ CXCursor_Destructor |
CXCursor_CXXMethod => {
let is_virtual = cur.method_is_virtual();
let is_static = cur.method_is_static();
debug_assert!(!(is_static && is_virtual), "How?");
- if !ci.has_vtable {
- ci.has_vtable = is_virtual;
- }
+ ci.has_destructor |= cur.kind() == CXCursor_Destructor;
+ ci.has_vtable |= is_virtual;
let linkage = cur.linkage();
if linkage != CXLinkage_External {
@@ -699,30 +716,34 @@ impl CompInfo {
// NB: This gets us an owned `Function`, not a
// `FunctionSig`.
- let method_signature =
+ let 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
- } else if is_virtual {
- MethodKind::Virtual
- } else {
- MethodKind::Normal
- };
-
- let method =
- Method::new(method_kind, method_signature, is_const);
-
- ci.methods.push(method);
- }
- CXCursor_Destructor => {
- if cur.method_is_virtual() {
- // FIXME: Push to the method list?
- ci.has_vtable = true;
+ match cur.kind() {
+ CXCursor_Constructor => {
+ ci.constructors.push(signature);
+ }
+ // TODO(emilio): Bind the destructor?
+ CXCursor_Destructor => {},
+ CXCursor_CXXMethod => {
+ let is_const = cur.method_is_const();
+ let method_kind = if is_static {
+ MethodKind::Static
+ } else if is_virtual {
+ MethodKind::Virtual
+ } else {
+ MethodKind::Normal
+ };
+
+ let method = Method::new(method_kind,
+ signature,
+ is_const);
+
+ ci.methods.push(method);
+ }
+ _ => unreachable!("How can we see this here?"),
}
- ci.has_destructor = true;
}
CXCursor_NonTypeTemplateParameter => {
ci.has_non_type_template_params = true;
@@ -746,7 +767,6 @@ impl CompInfo {
// Intentionally not handled
CXCursor_CXXAccessSpecifier |
CXCursor_CXXFinalAttr |
- CXCursor_Constructor |
CXCursor_FunctionTemplate |
CXCursor_ConversionFunction => {}
_ => {
diff --git a/libbindgen/src/ir/function.rs b/libbindgen/src/ir/function.rs
index 5a864cfc..c4c26c62 100644
--- a/libbindgen/src/ir/function.rs
+++ b/libbindgen/src/ir/function.rs
@@ -147,6 +147,7 @@ impl FunctionSig {
};
let mut args: Vec<_> = match cursor.kind() {
CXCursor_FunctionDecl |
+ CXCursor_Constructor |
CXCursor_CXXMethod => {
// For CXCursor_FunctionDecl, cursor.args() is the reliable way
// to get parameter names and types.
@@ -184,10 +185,12 @@ impl FunctionSig {
}
};
- if cursor.kind() == CXCursor_CXXMethod {
- let is_const = cursor.method_is_const();
- let is_virtual = cursor.method_is_virtual();
- let is_static = cursor.method_is_static();
+ let is_method = cursor.kind() == CXCursor_CXXMethod;
+
+ if is_method || cursor.kind() == CXCursor_Constructor {
+ let is_const = is_method && cursor.method_is_const();
+ let is_virtual = is_method && cursor.method_is_virtual();
+ let is_static = is_method && cursor.method_is_static();
if !is_static && !is_virtual {
let class = Item::parse(cursor.semantic_parent(), None, ctx)
.expect("Expected to parse the class");
@@ -240,6 +243,8 @@ impl ClangSubItemParser for Function {
use clangll::*;
match cursor.kind() {
CXCursor_FunctionDecl |
+ CXCursor_Constructor |
+ CXCursor_Destructor |
CXCursor_CXXMethod => {}
_ => return Err(ParseError::Continue),
};
diff --git a/libbindgen/src/ir/item.rs b/libbindgen/src/ir/item.rs
index 6601216e..11ec7d99 100644
--- a/libbindgen/src/ir/item.rs
+++ b/libbindgen/src/ir/item.rs
@@ -654,19 +654,26 @@ impl Item {
/// Get the overload index for this method. If this is not a method, return
/// `None`.
- fn method_overload_index(&self, ctx: &BindgenContext) -> Option<usize> {
+ fn overload_index(&self, ctx: &BindgenContext) -> Option<usize> {
self.func_name().and_then(|func_name| {
let parent = ctx.resolve_item(self.parent_id());
if let ItemKind::Type(ref ty) = *parent.kind() {
if let TypeKind::Comp(ref ci) = *ty.kind() {
- return ci.methods()
+ // All the constructors have the same name, so no need to
+ // resolve and check.
+ return ci.constructors()
.iter()
- .filter(|method| {
- let item = ctx.resolve_item(method.signature());
- let func = item.expect_function();
- func.name() == func_name
+ .position(|c| *c == self.id())
+ .or_else(|| {
+ ci.methods()
+ .iter()
+ .filter(|m| {
+ let item = ctx.resolve_item(m.signature());
+ let func = item.expect_function();
+ func.name() == func_name
+ })
+ .position(|m| m.signature() == self.id())
})
- .position(|method| method.signature() == self.id());
}
}
@@ -704,7 +711,7 @@ impl Item {
ItemKind::Function(ref fun) => {
let mut name = fun.name().to_owned();
- if let Some(idx) = self.method_overload_index(ctx) {
+ if let Some(idx) = self.overload_index(ctx) {
if idx > 0 {
write!(&mut name, "{}", idx).unwrap();
}