diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2017-02-15 18:01:25 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-15 18:01:25 -0800 |
commit | 6774efe9af2182e31ba1e11e14eee51ec63f5ab9 (patch) | |
tree | 5876846cf34e77bfc688b3f684615858e727b25d /src | |
parent | ac4971778b5823f94cbaf0188464790006e407c8 (diff) | |
parent | 70c61e1ebd1b0270953b8e33b74bfff578ccc82f (diff) |
Auto merge of #518 - pornel:typedefstruct, r=emilio
typedef struct {} name
Fixes #427
It looks like clang is doing the hard work of getting the right name from the typedef, but it falls back to arbitrary pretty-printed descriptions if it can't find a typedef. I couldn't find an API to check whether the name comes from a typedef, so I just filter out non-ident-like spellings.
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/ty.rs | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/src/ir/ty.rs b/src/ir/ty.rs index ec168f02..332ad236 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -311,19 +311,21 @@ impl Type { match self.kind { TypeKind::Named => { let name = self.name().expect("Unnamed named type?"); - let mut chars = name.chars(); - let first = chars.next().unwrap(); - let mut remaining = chars; - - let valid = (first.is_alphabetic() || first == '_') && - remaining.all(|c| c.is_alphanumeric() || c == '_'); - - !valid + !Self::is_valid_identifier(&name) } _ => false, } } + /// Checks whether the name looks like an identifier, + /// i.e. is alphanumeric (including '_') and does not start with a digit. + pub fn is_valid_identifier(name: &str) -> bool { + let mut chars = name.chars(); + let first_valid = chars.next().map(|c| c.is_alphabetic() || c == '_').unwrap_or(false); + + first_valid && chars.all(|c| c.is_alphanumeric() || c == '_') + } + /// See safe_canonical_type. pub fn canonical_type<'tr>(&'tr self, ctx: &'tr BindgenContext) @@ -454,7 +456,6 @@ fn is_invalid_named_type_unnamed() { } #[test] -#[should_panic] fn is_invalid_named_type_empty_name() { let ty = Type::new(Some("".into()), None, TypeKind::Named, false); assert!(ty.is_invalid_named_type()) @@ -1074,12 +1075,30 @@ impl Type { } CXType_Enum => { let enum_ = Enum::from_ty(ty, ctx).expect("Not an enum?"); + + if name.is_empty() { + let pretty_name = ty.spelling(); + if Self::is_valid_identifier(&pretty_name) { + name = pretty_name; + } + } + TypeKind::Enum(enum_) } CXType_Record => { let complex = CompInfo::from_ty(potential_id, ty, location, ctx) .expect("Not a complex type?"); + + if name.is_empty() { + // The pretty-printed name may contain typedefed name, + // but may also be "struct (anonymous at .h:1)" + let pretty_name = ty.spelling(); + if Self::is_valid_identifier(&pretty_name) { + name = pretty_name; + } + } + TypeKind::Comp(complex) } // FIXME: We stub vectors as arrays since in 99% of the cases the |