Commit 4e481c13 authored by Ryan Hunt's avatar Ryan Hunt

Add dependencies for tagged enums

parent 6c9a5aae
......@@ -22,12 +22,14 @@ impl Dependencies {
}
pub fn sort(&mut self) {
// Sort enums and opaque structs into their own layers because they don't
// Sort untagged enums and opaque structs into their own layers because they don't
// depend on each other or anything else.
let ordering = |a: &ItemContainer, b: &ItemContainer| match (a, b) {
(&ItemContainer::Enum(ref x), &ItemContainer::Enum(ref y)) => x.name.cmp(&y.name),
(&ItemContainer::Enum(_), _) => Ordering::Less,
(_, &ItemContainer::Enum(_)) => Ordering::Greater,
(&ItemContainer::Enum(ref x), &ItemContainer::Enum(ref y)) if x.tag.is_none() && y.tag.is_none() => {
x.name.cmp(&y.name)
},
(&ItemContainer::Enum(ref x), _) if x.tag.is_none() => Ordering::Less,
(_, &ItemContainer::Enum(ref x)) if x.tag.is_none() => Ordering::Greater,
(&ItemContainer::OpaqueItem(ref x), &ItemContainer::OpaqueItem(ref y)) => {
x.name.cmp(&y.name)
......
......@@ -7,6 +7,8 @@ use std::io::Write;
use syn;
use bindgen::config::{Config, Language};
use bindgen::dependencies::Dependencies;
use bindgen::library::Library;
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, GenericPath, Item,
ItemContainer, Repr, Struct, Type};
use bindgen::rename::{IdentifierType, RenameRule};
......@@ -93,6 +95,12 @@ impl EnumVariant {
documentation: Documentation::load(&variant.attrs),
})
}
fn add_dependencies(&self, library: &Library, out: &mut Dependencies) {
if let &Some((_, ref item)) = &self.body {
item.add_dependencies(library, out);
}
}
}
impl Source for EnumVariant {
......@@ -124,12 +132,20 @@ impl Enum {
attrs: &Vec<syn::Attribute>,
mod_cfg: &Option<Cfg>,
) -> Result<Enum, String> {
let repr = Repr::load(attrs);
const VALID_REPR: &[Repr] = &[
Repr::C,
Repr::USize,
Repr::U32,
Repr::U16,
Repr::U8,
Repr::ISize,
Repr::I32,
Repr::I16,
Repr::I8,
];
if repr != Repr::C && repr != Repr::USize && repr != Repr::U32 && repr != Repr::U16
&& repr != Repr::U8 && repr != Repr::ISize && repr != Repr::I32
&& repr != Repr::I16 && repr != Repr::I8
{
let repr = Repr::load(attrs);
if !VALID_REPR.contains(&repr) {
return Err("Enum not marked with a valid repr(prim) or repr(C).".to_owned());
}
......@@ -193,6 +209,8 @@ impl Item for Enum {
}
fn rename_for_config(&mut self, config: &Config) {
config.export.rename(&mut self.name);
if config.language == Language::C && self.tag.is_some() {
// it makes sense to always prefix Tag with type name in C
let new_tag = format!("{}_Tag", self.name);
......@@ -253,6 +271,12 @@ impl Item for Enum {
.collect();
}
}
fn add_dependencies(&self, library: &Library, out: &mut Dependencies) {
for variant in &self.variants {
variant.add_dependencies(library, out);
}
}
}
impl Source for Enum {
......
......@@ -158,7 +158,14 @@ impl Item for Struct {
}
fn add_dependencies(&self, library: &Library, out: &mut Dependencies) {
for &(_, ref ty, _) in &self.fields {
let mut fields = self.fields.iter();
// If there is a tag field, skip it
if self.is_tagged {
fields.next();
}
for &(_, ref ty, _) in fields {
ty.add_dependencies_ignoring_generics(&self.generic_params, library, out);
}
}
......
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct {
float x;
float y;
float w;
float h;
} Rect;
typedef struct {
uint8_t r;
uint8_t g;
uint8_t b;
uint8_t a;
} Color;
enum DisplayItem_Tag {
Fill,
Image,
ClearScreen,
};
typedef uint8_t DisplayItem_Tag;
typedef struct {
DisplayItem_Tag tag;
Rect _0;
Color _1;
} Fill_Body;
typedef struct {
DisplayItem_Tag tag;
uint32_t id;
Rect bounds;
} Image_Body;
typedef union {
DisplayItem_Tag tag;
Fill_Body fill;
Image_Body image;
} DisplayItem;
bool push_item(DisplayItem item);
#include <cstdint>
#include <cstdlib>
struct Rect {
float x;
float y;
float w;
float h;
};
struct Color {
uint8_t r;
uint8_t g;
uint8_t b;
uint8_t a;
};
union DisplayItem {
enum class Tag : uint8_t {
Fill,
Image,
ClearScreen,
};
struct Fill_Body {
Tag tag;
Rect _0;
Color _1;
};
struct Image_Body {
Tag tag;
uint32_t id;
Rect bounds;
};
Tag tag;
Fill_Body fill;
Image_Body image;
};
extern "C" {
bool push_item(DisplayItem item);
} // extern "C"
......@@ -42,6 +42,8 @@ enum E {
};
typedef intptr_t E;
typedef struct Opaque Opaque;
enum F_Tag {
Foo,
Bar,
......@@ -89,6 +91,4 @@ typedef union {
};
} G;
typedef struct Opaque Opaque;
void root(Opaque *o, A a, B b, C c, D d, E e, F f, G g);
......@@ -36,6 +36,8 @@ enum class E : intptr_t {
e4 = 5,
};
struct Opaque;
union F {
enum class Tag : uint8_t {
Foo,
......@@ -82,8 +84,6 @@ struct G {
};
};
struct Opaque;
extern "C" {
void root(Opaque *o, A a, B b, C c, D d, E e, F f, G g);
......
#[repr(u8)]
pub enum DisplayItem {
Fill(Rect, Color),
Image { id: u32, bounds: Rect },
ClearScreen,
}
#[repr(C)]
pub struct Rect { x: f32, y: f32, w: f32, h: f32 }
#[repr(C)]
pub struct Color { r: u8, g: u8, b: u8, a: u8 }
#[no_mangle]
pub extern "C" fn push_item(item: DisplayItem) -> bool {
::std::mem::drop(item);
true
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment