summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2019-02-03 14:38:35 +0100
committerEmilio Cobos Álvarez <emilio@crisal.io>2019-02-03 14:54:58 +0100
commit1ea12aa2dfbfcb27ef102ec8a001a3a05175004f (patch)
tree378b003ed04262a957238929501ea645adab9d64
parent892e2ec117f817d5a439dfb39104b2be4678cd0b (diff)
ir: Ignore constructors with bogus spellings.
-rw-r--r--src/ir/function.rs24
-rw-r--r--tests/expectations/tests/issue-1464.rs8
-rw-r--r--tests/headers/issue-1464.hpp7
-rw-r--r--tests/tests.rs2
4 files changed, 33 insertions, 8 deletions
diff --git a/src/ir/function.rs b/src/ir/function.rs
index acbfe707..fae6e056 100644
--- a/src/ir/function.rs
+++ b/src/ir/function.rs
@@ -337,7 +337,8 @@ impl FunctionSig {
debug!("FunctionSig::from_ty {:?} {:?}", ty, cursor);
// Skip function templates
- if cursor.kind() == CXCursor_FunctionTemplate {
+ let kind = cursor.kind();
+ if kind == CXCursor_FunctionTemplate {
return Err(ParseError::Continue);
}
@@ -347,13 +348,22 @@ impl FunctionSig {
return Err(ParseError::Continue);
}
+ // Constructors of non-type template parameter classes for some reason
+ // include the template parameter in their name. Just skip them, since
+ // we don't handle well non-type template parameters anyway.
+ if (kind == CXCursor_Constructor || kind == CXCursor_Destructor) &&
+ spelling.contains('<')
+ {
+ return Err(ParseError::Continue);
+ }
+
let cursor = if cursor.is_valid() {
*cursor
} else {
ty.declaration()
};
- let mut args: Vec<_> = match cursor.kind() {
+ let mut args: Vec<_> = match kind {
CXCursor_FunctionDecl |
CXCursor_Constructor |
CXCursor_CXXMethod |
@@ -397,9 +407,9 @@ impl FunctionSig {
let must_use =
ctx.options().enable_function_attribute_detection &&
cursor.has_simple_attr("warn_unused_result");
- let is_method = cursor.kind() == CXCursor_CXXMethod;
- let is_constructor = cursor.kind() == CXCursor_Constructor;
- let is_destructor = cursor.kind() == CXCursor_Destructor;
+ let is_method = kind == CXCursor_CXXMethod;
+ let is_constructor = kind == CXCursor_Constructor;
+ let is_destructor = kind == CXCursor_Destructor;
if (is_constructor || is_destructor || is_method) &&
cursor.lexical_parent() != cursor.semantic_parent()
{
@@ -442,8 +452,8 @@ impl FunctionSig {
}
}
- let ty_ret_type = if cursor.kind() == CXCursor_ObjCInstanceMethodDecl ||
- cursor.kind() == CXCursor_ObjCClassMethodDecl
+ let ty_ret_type = if kind == CXCursor_ObjCInstanceMethodDecl ||
+ kind == CXCursor_ObjCClassMethodDecl
{
ty.ret_type().or_else(|| cursor.ret_type()).ok_or(
ParseError::Continue,
diff --git a/tests/expectations/tests/issue-1464.rs b/tests/expectations/tests/issue-1464.rs
new file mode 100644
index 00000000..d6776794
--- /dev/null
+++ b/tests/expectations/tests/issue-1464.rs
@@ -0,0 +1,8 @@
+/* automatically generated by rust-bindgen */
+
+#![allow(
+ dead_code,
+ non_snake_case,
+ non_camel_case_types,
+ non_upper_case_globals
+)]
diff --git a/tests/headers/issue-1464.hpp b/tests/headers/issue-1464.hpp
new file mode 100644
index 00000000..d34d0fe3
--- /dev/null
+++ b/tests/headers/issue-1464.hpp
@@ -0,0 +1,7 @@
+
+// Should not crash.
+template <int Foo> class Bar {
+public:
+ Bar();
+ ~Bar();
+};
diff --git a/tests/tests.rs b/tests/tests.rs
index 93b8971b..0966f877 100644
--- a/tests/tests.rs
+++ b/tests/tests.rs
@@ -207,7 +207,7 @@ fn compare_generated_header(
expectation_file.write_all(actual.as_bytes())?;
}
- Err(Error::new(ErrorKind::Other, "Header and binding differ!"))
+ Err(Error::new(ErrorKind::Other, "Header and binding differ! Run with BINDGEN_OVERWRITE_EXPECTED=1 in the environment to automatically overwrite the expectation."))
}
fn create_bindgen_builder(header: &PathBuf) -> Result<Option<Builder>, Error> {