ir: Add support for Self in enum variant bodies.
This commit is contained in:
@@ -48,11 +48,12 @@ fn value_from_expr(val: &syn::Expr) -> Option<i64> {
|
||||
}
|
||||
|
||||
impl EnumVariant {
|
||||
pub fn load(
|
||||
fn load(
|
||||
is_tagged: bool,
|
||||
variant: &syn::Variant,
|
||||
generic_params: GenericParams,
|
||||
mod_cfg: Option<&Cfg>,
|
||||
self_path: &Path,
|
||||
) -> Result<Self, String> {
|
||||
let discriminant = match variant.discriminant {
|
||||
Some((_, ref expr)) => match value_from_expr(expr) {
|
||||
@@ -65,6 +66,7 @@ impl EnumVariant {
|
||||
fn parse_fields(
|
||||
is_tagged: bool,
|
||||
fields: &syn::punctuated::Punctuated<syn::Field, syn::token::Comma>,
|
||||
self_path: &Path,
|
||||
) -> Result<Vec<(String, Type, Documentation)>, String> {
|
||||
let mut res = Vec::new();
|
||||
|
||||
@@ -77,7 +79,8 @@ impl EnumVariant {
|
||||
}
|
||||
|
||||
for (i, field) in fields.iter().enumerate() {
|
||||
if let Some(ty) = Type::load(&field.ty)? {
|
||||
if let Some(mut ty) = Type::load(&field.ty)? {
|
||||
ty.replace_self_with(self_path);
|
||||
res.push((
|
||||
match field.ident {
|
||||
Some(ref ident) => ident.to_string(),
|
||||
@@ -99,7 +102,7 @@ impl EnumVariant {
|
||||
Some(Struct::new(
|
||||
path,
|
||||
generic_params,
|
||||
parse_fields(is_tagged, &fields.named)?,
|
||||
parse_fields(is_tagged, &fields.named, self_path)?,
|
||||
is_tagged,
|
||||
true,
|
||||
None,
|
||||
@@ -115,7 +118,7 @@ impl EnumVariant {
|
||||
Some(Struct::new(
|
||||
path,
|
||||
generic_params,
|
||||
parse_fields(is_tagged, &fields.unnamed)?,
|
||||
parse_fields(is_tagged, &fields.unnamed, self_path)?,
|
||||
is_tagged,
|
||||
true,
|
||||
None,
|
||||
@@ -260,6 +263,7 @@ impl Enum {
|
||||
return Err("Enum is marked with #[repr(align(...))] or #[repr(packed)].".to_owned());
|
||||
}
|
||||
|
||||
let path = Path::new(item.ident.to_string());
|
||||
let generic_params = GenericParams::new(&item.generics);
|
||||
|
||||
let mut variants = Vec::new();
|
||||
@@ -271,6 +275,7 @@ impl Enum {
|
||||
variant,
|
||||
generic_params.clone(),
|
||||
mod_cfg,
|
||||
&path,
|
||||
)?;
|
||||
is_tagged = is_tagged || variant.body.is_some();
|
||||
variants.push(variant);
|
||||
@@ -284,12 +289,12 @@ impl Enum {
|
||||
}
|
||||
}
|
||||
|
||||
let path = Path::new(item.ident.to_string());
|
||||
let tag = if is_tagged {
|
||||
Some("Tag".to_string())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(Enum::new(
|
||||
path,
|
||||
generic_params,
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct Foo_Bar {
|
||||
const int32_t *something;
|
||||
} Foo_Bar;
|
||||
|
||||
enum Bar_Tag {
|
||||
Min,
|
||||
Max,
|
||||
Other,
|
||||
};
|
||||
typedef uint8_t Bar_Tag;
|
||||
|
||||
typedef struct Min_Body {
|
||||
Bar_Tag tag;
|
||||
Foo_Bar _0;
|
||||
} Min_Body;
|
||||
|
||||
typedef struct Max_Body {
|
||||
Bar_Tag tag;
|
||||
Foo_Bar _0;
|
||||
} Max_Body;
|
||||
|
||||
typedef union Bar {
|
||||
Bar_Tag tag;
|
||||
Min_Body min;
|
||||
Max_Body max;
|
||||
} Bar;
|
||||
|
||||
void root(Bar b);
|
||||
@@ -0,0 +1,47 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct Foo_Bar {
|
||||
const int32_t *something;
|
||||
} Foo_Bar;
|
||||
|
||||
enum Bar_Tag
|
||||
#ifdef __cplusplus
|
||||
: uint8_t
|
||||
#endif // __cplusplus
|
||||
{
|
||||
Min,
|
||||
Max,
|
||||
Other,
|
||||
};
|
||||
#ifndef __cplusplus
|
||||
typedef uint8_t Bar_Tag;
|
||||
#endif // __cplusplus
|
||||
|
||||
typedef struct Min_Body {
|
||||
Bar_Tag tag;
|
||||
Foo_Bar _0;
|
||||
} Min_Body;
|
||||
|
||||
typedef struct Max_Body {
|
||||
Bar_Tag tag;
|
||||
Foo_Bar _0;
|
||||
} Max_Body;
|
||||
|
||||
typedef union Bar {
|
||||
Bar_Tag tag;
|
||||
Min_Body min;
|
||||
Max_Body max;
|
||||
} Bar;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
void root(Bar b);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
@@ -0,0 +1,33 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct {
|
||||
const int32_t *something;
|
||||
} Foo_Bar;
|
||||
|
||||
enum Bar_Tag {
|
||||
Min,
|
||||
Max,
|
||||
Other,
|
||||
};
|
||||
typedef uint8_t Bar_Tag;
|
||||
|
||||
typedef struct {
|
||||
Bar_Tag tag;
|
||||
Foo_Bar _0;
|
||||
} Min_Body;
|
||||
|
||||
typedef struct {
|
||||
Bar_Tag tag;
|
||||
Foo_Bar _0;
|
||||
} Max_Body;
|
||||
|
||||
typedef union {
|
||||
Bar_Tag tag;
|
||||
Min_Body min;
|
||||
Max_Body max;
|
||||
} Bar;
|
||||
|
||||
void root(Bar b);
|
||||
@@ -0,0 +1,47 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct {
|
||||
const int32_t *something;
|
||||
} Foo_Bar;
|
||||
|
||||
enum Bar_Tag
|
||||
#ifdef __cplusplus
|
||||
: uint8_t
|
||||
#endif // __cplusplus
|
||||
{
|
||||
Min,
|
||||
Max,
|
||||
Other,
|
||||
};
|
||||
#ifndef __cplusplus
|
||||
typedef uint8_t Bar_Tag;
|
||||
#endif // __cplusplus
|
||||
|
||||
typedef struct {
|
||||
Bar_Tag tag;
|
||||
Foo_Bar _0;
|
||||
} Min_Body;
|
||||
|
||||
typedef struct {
|
||||
Bar_Tag tag;
|
||||
Foo_Bar _0;
|
||||
} Max_Body;
|
||||
|
||||
typedef union {
|
||||
Bar_Tag tag;
|
||||
Min_Body min;
|
||||
Max_Body max;
|
||||
} Bar;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
void root(Bar b);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
@@ -0,0 +1,39 @@
|
||||
#include <cstdarg>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <new>
|
||||
|
||||
template<typename T>
|
||||
struct Foo {
|
||||
const int32_t *something;
|
||||
};
|
||||
|
||||
union Bar {
|
||||
enum class Tag : uint8_t {
|
||||
Min,
|
||||
Max,
|
||||
Other,
|
||||
};
|
||||
|
||||
struct Min_Body {
|
||||
Tag tag;
|
||||
Foo<Bar> _0;
|
||||
};
|
||||
|
||||
struct Max_Body {
|
||||
Tag tag;
|
||||
Foo<Bar> _0;
|
||||
};
|
||||
|
||||
struct {
|
||||
Tag tag;
|
||||
};
|
||||
Min_Body min;
|
||||
Max_Body max;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
void root(Bar b);
|
||||
|
||||
} // extern "C"
|
||||
@@ -0,0 +1,33 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct Foo_Bar {
|
||||
const int32_t *something;
|
||||
};
|
||||
|
||||
enum Bar_Tag {
|
||||
Min,
|
||||
Max,
|
||||
Other,
|
||||
};
|
||||
typedef uint8_t Bar_Tag;
|
||||
|
||||
struct Min_Body {
|
||||
Bar_Tag tag;
|
||||
struct Foo_Bar _0;
|
||||
};
|
||||
|
||||
struct Max_Body {
|
||||
Bar_Tag tag;
|
||||
struct Foo_Bar _0;
|
||||
};
|
||||
|
||||
union Bar {
|
||||
enum Bar_Tag tag;
|
||||
struct Min_Body min;
|
||||
struct Max_Body max;
|
||||
};
|
||||
|
||||
void root(union Bar b);
|
||||
@@ -0,0 +1,47 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct Foo_Bar {
|
||||
const int32_t *something;
|
||||
};
|
||||
|
||||
enum Bar_Tag
|
||||
#ifdef __cplusplus
|
||||
: uint8_t
|
||||
#endif // __cplusplus
|
||||
{
|
||||
Min,
|
||||
Max,
|
||||
Other,
|
||||
};
|
||||
#ifndef __cplusplus
|
||||
typedef uint8_t Bar_Tag;
|
||||
#endif // __cplusplus
|
||||
|
||||
struct Min_Body {
|
||||
Bar_Tag tag;
|
||||
struct Foo_Bar _0;
|
||||
};
|
||||
|
||||
struct Max_Body {
|
||||
Bar_Tag tag;
|
||||
struct Foo_Bar _0;
|
||||
};
|
||||
|
||||
union Bar {
|
||||
enum Bar_Tag tag;
|
||||
struct Min_Body min;
|
||||
struct Max_Body max;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
void root(union Bar b);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
@@ -0,0 +1,15 @@
|
||||
#[repr(C)]
|
||||
pub struct Foo<T> {
|
||||
something: *const i32,
|
||||
phantom: std::marker::PhantomData<T>,
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
pub enum Bar {
|
||||
Min(Foo<Self>),
|
||||
Max(Foo<Self>),
|
||||
Other,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn root(b: Bar) {}
|
||||
Reference in New Issue
Block a user