Skip to content

Use __BindegenComplex for C Complex #230

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 11, 2016

Conversation

jeanphilippeD
Copy link
Contributor

@jeanphilippeD jeanphilippeD commented Nov 8, 2016

Fix #72

C complex only exists for floating point types
C Complex are built in types

long double _Complex is not supported.
Long double would be an f128, runing generated binding test produces:
assertion failed: (left == right) (left: 16, right: 32)',
tests/expectations/tests/complex.rs:72
We test global long double _Complex because it does not require
layout tests.

Handle all the different way a complex can be present in
BindgenContext calling generated_bindegen_complex to indicate
that __BindgenContext will need to be added.

Copy link
Contributor

@emilio emilio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoa, looks neat!

I fear those are not the only places you need to check, so I'd rather move the flags to the context.

Apart from that, only a few comments, mostly nits.

Thanks for doing this!

@@ -1487,6 +1500,17 @@ impl ToRustTy for Type {
}
}
}
TypeKind::Complex(fk) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be able to call saw_complex just here, and remove the rest.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, nevermind, you don't have access to the result. Maybe worth moving that to the context inside a Cell<bool>, and checking that instead? Even better would be something like Cell<SeenFlags>, where SeenFlags is a bitflags!, but for now moving saw_union and saw_complex to BindgenContext is fine, the other can be a followup if you want.

Otherwise you'll need to check for virtually every possible type, function arguments, etc...

@@ -1487,6 +1500,17 @@ impl ToRustTy for Type {
}
}
}
TypeKind::Complex(fk) => {
use ir::ty::FloatKind;
let float_path = match fk {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that there's a new option to use c_float/c_double. You should probably respect that here, reusing the same code.

)
.unwrap();

let items = vec![
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: This is probably nicer in its own line: vec![complex_type], assuming rustfmt likes it.

CXType_Complex => {
let float_type = ty.elem_type()
.expect("Not able to resolve complex type?");
let float_kind = match float_type.kind() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably:

let float_kind = match float_type.kind() {
    CXType_Float => FloatKind::Float,
    CXType_Double => FloatKind::Double,
    CXType_LongDouble => FloatKind::LongDouble,
    _ => panic!("Non floating-type complex?"),
};

Or, you could also add a FloatKind::from_ty(Type) -> Option<FloatKind> function, though that might be overkill for this, so leaving a match is totally fine :)

@@ -384,6 +385,9 @@ pub enum TypeKind {
/// A floating point type.
Float(FloatKind),

/// A complex floating point type. complex only exist for floating point.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think /// A complex floating point type. is more than enough, since it implies "floating point", but I guess the second sentence doesn't harm. Please capitalize "Complex" if you keep it :)

@@ -0,0 +1 @@
double _Complex globalValue;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can probably stick that in tests/headers/complex.h if you prefer, though it's fine as is too :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With my fix it was possible to have saw_complex called for global, but not for member variables (or vice versa).
With your suggestion that won't be the case, but might be better to keep them separate.

COMPLEX_TEST(double, Double)
COMPLEX_TEST(float, Float)

// Not supported:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you mention here, instead of that, something like:

// FIXME: 128-byte-aligned in some machines, which we can't support right now in Rust.

COMPLEX_TEST(float, Float)

// Not supported:
//COMPLEX_TEST(long double, LongDouble)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a space after //

@jeanphilippeD
Copy link
Contributor Author

Thanks a lot for all you comments, they were very helpful.
I've also added a test for global long double _Complex since it does not do layout test.

Copy link
Contributor

@emilio emilio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only one thing about where to set the saw_complex flag, and two nits, otherwise looks great, thanks! 🎉

_ => panic!("Non floating-type complex?"),
};

self.saw_complex.set(true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... Probably we should only output it if we try to convert a rust type to a complex. It's likely, over all if you use whitelisting, that we end up parsing it but not generating output for it. Could you add a method to set this flag, and call it from to_rust_ty, where we generate the __BindgenComplex instead?

Note that to modify a Cell the context doesn't need to be mutable, so we can set it during codegen.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes a lot of sense.
Should I add a non white listed _Complex in whitelist_basic.hpp, or a new whitelist_complex.h?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any of those options work for me :)


/// Whether a complex was detected anywhere
pub fn saw_complex(&self) -> bool {
return self.saw_complex.get();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: no need for return, self.saw_complex.get() (without the semicolon) will do.

@@ -1560,6 +1561,33 @@ fn raw_type(ctx: &BindgenContext, name: &str) -> P<ast::Ty> {
}
}

fn float_kind_rust_type(ctx: &BindgenContext, fk: FloatKind) -> P<ast::Ty> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably we could move this (and raw_type) to the helper module, if you wish. Otherwise it's fine :).

@bors-servo
Copy link

☔ The latest upstream changes (presumably #233) made this pull request unmergeable. Please resolve the merge conflicts.

C complex only exists for floating point types.
C Complex are built in types

long double _Complex is not supported.
Long double would be an f128, runing generated binding test produces:
assertion failed: `(left == right)` (left: `16`, right: `32`)',
tests/expectations/tests/complex.rs:72
We test global long double _Complex because it does not require
layout tests.

Handle all the different way a complex can be present in
BindgenContext calling generated_bindegen_complex to indicate
that __BindgenContext will need to be added.
@jeanphilippeD
Copy link
Contributor Author

Updated the 'saw_complex' name to be a bit more specific considering it is stored in the context, but set and used in the mod.rs

@emilio
Copy link
Contributor

emilio commented Nov 11, 2016

Awesome! Thanks for the patch! :)

@bors-servo r+

@bors-servo
Copy link

📌 Commit b5d879a has been approved by emilio

@bors-servo
Copy link

⚡ Test exempted - status

@bors-servo bors-servo merged commit b5d879a into rust-lang:master Nov 11, 2016
bors-servo pushed a commit that referenced this pull request Nov 11, 2016
Use __BindegenComplex for C Complex

 Fix #72

C complex only exists for floating point types
C Complex are built in types

long double _Complex is not supported.
Long double would be an f128, runing generated binding test produces:
assertion failed: `(left == right)` (left: `16`, right: `32`)',
tests/expectations/tests/complex.rs:72
We test global long double _Complex because it does not require
layout tests.

Handle all the different way a complex can be present in
BindgenContext calling generated_bindegen_complex to indicate
that __BindgenContext will need to be added.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants