Skip to content

Commit

Permalink
ir: Ignore constructors with bogus spellings.
Browse files Browse the repository at this point in the history
  • Loading branch information
emilio committed Feb 3, 2019
1 parent 892e2ec commit 1ea12aa
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 8 deletions.
24 changes: 17 additions & 7 deletions src/ir/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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 |
Expand Down Expand Up @@ -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()
{
Expand Down Expand Up @@ -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,
Expand Down
8 changes: 8 additions & 0 deletions tests/expectations/tests/issue-1464.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* automatically generated by rust-bindgen */

#![allow(
dead_code,
non_snake_case,
non_camel_case_types,
non_upper_case_globals
)]
7 changes: 7 additions & 0 deletions tests/headers/issue-1464.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

// Should not crash.
template <int Foo> class Bar {
public:
Bar();
~Bar();
};
2 changes: 1 addition & 1 deletion tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down

0 comments on commit 1ea12aa

Please sign in to comment.