Skip to content

Commit cf13c2b

Browse files
committed
enum: Track dependencies properly in enumerations.
Fixes #1111
1 parent 307d1e9 commit cf13c2b

25 files changed

Lines changed: 582 additions & 90 deletions

src/bindgen/dependencies.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
use std::cmp::Ordering;
66
use std::collections::HashSet;
77

8-
use crate::bindgen::ir::{ItemContainer, Path};
8+
use crate::bindgen::{
9+
ir::{ItemContainer, Path},
10+
library::Library,
11+
};
912

1013
/// A dependency list is used for gathering what order to output the types.
1114
#[derive(Default)]
@@ -22,14 +25,33 @@ impl Dependencies {
2225
}
2326
}
2427

28+
pub fn add(&mut self, library: &Library, path: &Path) {
29+
let Some(items) = library.get_items(path) else {
30+
warn!(
31+
"Can't find {path}. This usually means that this type was incompatible or not found."
32+
);
33+
return;
34+
};
35+
if self.items.contains(path) {
36+
return;
37+
}
38+
self.items.insert(path.clone());
39+
for item in &items {
40+
item.deref().add_dependencies(library, self);
41+
}
42+
for item in items {
43+
self.order.push(item);
44+
}
45+
}
46+
2547
pub fn sort(&mut self) {
2648
// Sort untagged enums and opaque structs into their own layers because they don't
2749
// depend on each other or anything else.
2850
let ordering = |a: &ItemContainer, b: &ItemContainer| match (a, b) {
2951
(ItemContainer::Enum(x), ItemContainer::Enum(y))
3052
if x.tag.is_none() && y.tag.is_none() =>
3153
{
32-
x.path.cmp(&y.path)
54+
Ordering::Equal
3355
}
3456
(ItemContainer::Enum(x), _) if x.tag.is_none() => Ordering::Less,
3557
(_, ItemContainer::Enum(x)) if x.tag.is_none() => Ordering::Greater,

src/bindgen/ir/constant.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,27 @@ pub enum Literal {
117117
}
118118

119119
impl Literal {
120-
fn replace_self_with(&mut self, self_ty: &Path) {
120+
pub fn add_dependencies(&self, library: &Library, out: &mut Dependencies) {
121+
self.visit(&mut |lit| {
122+
match lit {
123+
Literal::Struct {
124+
ref path,
125+
export_name: _,
126+
fields: _,
127+
}
128+
| Literal::Path {
129+
associated_to: Some((ref path, _)),
130+
name: _,
131+
} => {
132+
out.add(library, path);
133+
}
134+
_ => {}
135+
}
136+
true
137+
});
138+
}
139+
140+
pub fn replace_self_with(&mut self, self_ty: &Path) {
121141
match *self {
122142
Literal::PostfixUnaryOp { ref mut value, .. } => {
123143
value.replace_self_with(self_ty);
@@ -579,6 +599,7 @@ impl Item for Constant {
579599

580600
fn add_dependencies(&self, library: &Library, out: &mut Dependencies) {
581601
self.ty.add_dependencies(library, out);
602+
self.value.add_dependencies(library, out);
582603
}
583604

584605
fn export_name(&self) -> &str {

src/bindgen/ir/enumeration.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,11 @@ impl EnumVariant {
105105
config: &Config,
106106
) -> Result<Self, String> {
107107
let discriminant = match variant.discriminant {
108-
Some((_, ref expr)) => Some(Literal::load(expr)?),
108+
Some((_, ref expr)) => {
109+
let mut discriminant = Literal::load(expr)?;
110+
discriminant.replace_self_with(self_path);
111+
Some(discriminant)
112+
}
109113
None => None,
110114
};
111115

@@ -258,6 +262,9 @@ impl EnumVariant {
258262
if let VariantBody::Body { ref body, .. } = self.body {
259263
body.add_dependencies(library, out);
260264
}
265+
if let Some(ref d) = self.discriminant {
266+
d.add_dependencies(library, out);
267+
}
261268
}
262269

263270
fn resolve_declaration_types(&mut self, resolver: &DeclarationTypeResolver) {

src/bindgen/ir/ty.rs

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -701,23 +701,7 @@ impl Type {
701701
}
702702
let path = generic.path();
703703
if !generic_params.iter().any(|param| param.name() == path) {
704-
if let Some(items) = library.get_items(path) {
705-
if !out.items.contains(path) {
706-
out.items.insert(path.clone());
707-
708-
for item in &items {
709-
item.deref().add_dependencies(library, out);
710-
}
711-
for item in items {
712-
out.order.push(item);
713-
}
714-
}
715-
} else {
716-
warn!(
717-
"Can't find {path}. This usually means that this type was incompatible or \
718-
not found."
719-
);
720-
}
704+
out.add(library, path);
721705
}
722706
}
723707
Type::Primitive(_) => {}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
root;
3+
};

tests/expectations/cfg.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,22 @@ DEF M_32 = 0
1212
#include <stdint.h>
1313
#include <stdlib.h>
1414

15-
#if (defined(PLATFORM_WIN) || defined(M_32))
16-
enum BarType {
15+
#if (defined(PLATFORM_UNIX) && defined(X11))
16+
enum FooType {
1717
A,
1818
B,
1919
C,
2020
};
21-
typedef uint32_t BarType;
21+
typedef uint32_t FooType;
2222
#endif
2323

24-
#if (defined(PLATFORM_UNIX) && defined(X11))
25-
enum FooType {
24+
#if (defined(PLATFORM_WIN) || defined(M_32))
25+
enum BarType {
2626
A,
2727
B,
2828
C,
2929
};
30-
typedef uint32_t FooType;
30+
typedef uint32_t BarType;
3131
#endif
3232

3333
typedef struct {

tests/expectations/cfg.compat.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ DEF M_32 = 0
1212
#include <stdint.h>
1313
#include <stdlib.h>
1414

15-
#if (defined(PLATFORM_WIN) || defined(M_32))
16-
enum BarType
15+
#if (defined(PLATFORM_UNIX) && defined(X11))
16+
enum FooType
1717
#ifdef __cplusplus
1818
: uint32_t
1919
#endif // __cplusplus
@@ -23,12 +23,12 @@ enum BarType
2323
C,
2424
};
2525
#ifndef __cplusplus
26-
typedef uint32_t BarType;
26+
typedef uint32_t FooType;
2727
#endif // __cplusplus
2828
#endif
2929

30-
#if (defined(PLATFORM_UNIX) && defined(X11))
31-
enum FooType
30+
#if (defined(PLATFORM_WIN) || defined(M_32))
31+
enum BarType
3232
#ifdef __cplusplus
3333
: uint32_t
3434
#endif // __cplusplus
@@ -38,7 +38,7 @@ enum FooType
3838
C,
3939
};
4040
#ifndef __cplusplus
41-
typedef uint32_t FooType;
41+
typedef uint32_t BarType;
4242
#endif // __cplusplus
4343
#endif
4444

tests/expectations/cfg.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,16 @@ DEF M_32 = 0
1313
#include <ostream>
1414
#include <new>
1515

16-
#if (defined(PLATFORM_WIN) || defined(M_32))
17-
enum class BarType : uint32_t {
16+
#if (defined(PLATFORM_UNIX) && defined(X11))
17+
enum class FooType : uint32_t {
1818
A,
1919
B,
2020
C,
2121
};
2222
#endif
2323

24-
#if (defined(PLATFORM_UNIX) && defined(X11))
25-
enum class FooType : uint32_t {
24+
#if (defined(PLATFORM_WIN) || defined(M_32))
25+
enum class BarType : uint32_t {
2626
A,
2727
B,
2828
C,

tests/expectations/cfg.pyx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,19 @@ cdef extern from *:
1515

1616
cdef extern from *:
1717

18-
IF (PLATFORM_WIN or M_32):
18+
IF (PLATFORM_UNIX and X11):
1919
cdef enum:
2020
A,
2121
B,
2222
C,
23-
ctypedef uint32_t BarType;
23+
ctypedef uint32_t FooType;
2424

25-
IF (PLATFORM_UNIX and X11):
25+
IF (PLATFORM_WIN or M_32):
2626
cdef enum:
2727
A,
2828
B,
2929
C,
30-
ctypedef uint32_t FooType;
30+
ctypedef uint32_t BarType;
3131

3232
ctypedef struct Flags:
3333
uint8_t _0;

tests/expectations/cfg_both.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,22 @@ DEF M_32 = 0
1212
#include <stdint.h>
1313
#include <stdlib.h>
1414

15-
#if (defined(PLATFORM_WIN) || defined(M_32))
16-
enum BarType {
15+
#if (defined(PLATFORM_UNIX) && defined(X11))
16+
enum FooType {
1717
A,
1818
B,
1919
C,
2020
};
21-
typedef uint32_t BarType;
21+
typedef uint32_t FooType;
2222
#endif
2323

24-
#if (defined(PLATFORM_UNIX) && defined(X11))
25-
enum FooType {
24+
#if (defined(PLATFORM_WIN) || defined(M_32))
25+
enum BarType {
2626
A,
2727
B,
2828
C,
2929
};
30-
typedef uint32_t FooType;
30+
typedef uint32_t BarType;
3131
#endif
3232

3333
typedef struct Flags {

0 commit comments

Comments
 (0)