-
Notifications
You must be signed in to change notification settings - Fork 0
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
How to treat structs and newtypes #306
Comments
Related to #189 |
This sounds good to me.
This sounds good to me. Perhaps we could generate a
Another option is to translate a C
This sounds good to me. |
struct foo { int x; int y; };
typedef double foo; I agree that we should just translate normally and let the conflicting definitions of a |
typedef struct _linked_list {
int x;
struct _linked_list* next; /* linked_list doesn't exist here yet */
} linked_list; In the default name manglers, such leading underscores are dropped.
There is a trade-off between safety and taste/style, and we deliberately chose to create Haskell-style type constructor names at the expense of safety. A user who encounters such an issue should create a custom name mangler that handles the types of names in their C code. Perhaps we need to reconsider this decision? data C_LinkedList = MkC_LinkedList { x :: Int, next :: Ptr C_LinkedList } We can implement this suggestion by handling a leading underscore as a special case. If we do this, should it be done for all names or just type constructors? |
struct foo {
int x;
struct {
int y;
int z;
};
}; struct foo {
int x;
struct bar {
int y;
int z;
};
}; Oh! I missed these cases! Context For the first case, perhaps something like the following context would work? data TypeConstrContext =
...
| -- | Context for anonymous structures/unions for unnamed fields
AnonUnnamedFieldTypeConstrContext {
-- | Closest named ancestor type context
ctxAnonUnnamedFieldTypeConstrAncestorCtx :: TypeConstrContext
, -- | Preorder index (1-based) of unnamed fields in the root type
ctxAnonUnnamedFieldTypeConstrIdx :: Word
} For the second case, it seems like we could translate to data TypeConstrContext =
...
| -- | Context for named structures/unions for unnamed fields
UnnamedFieldTypeConstrContext {
-- | Closest named ancestor type context
ctxUnnamedFieldTypeConstrAncestorCtx :: TypeConstrContext
, -- | C name for the type
ctxUnnamedFieldTypeConstrCName :: CName
} |
That was already decided in #173 in favour of |
Let's discuss these case by case. no-struct-name no-field-name struct foo {
int x;
struct {
int y;
int z;
};
}; We should flatten here: struct-name no-field-name struct foo {
int x;
struct bar {
int y;
int z;
};
};
int fun1(struct bar x); This is an utterly bizarre example 😬 This definition of no-struct-name field-name struct foo {
int x;
struct {
int y;
int z;
} bar;
}; Here we should generate a nested struct: the name (already implemented in the current name mangler) is struct-name field-name struct foo {
int x;
struct bar {
int y;
int z;
} baz;
}; Similar to the previous case, but it will be |
Regarding |
An example for myself struct foo {
struct {
int z;
} *x;
};
int main() {
struct foo f = {0};
f.x->z = 42; // segfaults as accessing nullptr, but valid C anyway
return 0;
} The no-struct-name field-name can be wrapped in pointers and arrays. |
How to treat structs and newtypes, there are various cases explained below;
and I suggest:
rust-bindgen
):typedef struct s { ... } t
generate only onedata
declration whenthere is no name
s
ors
andt
are the same name; otherwise (whens
andt
are different),generate a
data
declration for struct, andnewtype
fortypedef
.The nested structs is not as closely related to two first bulled points,
but it does affect what name mangling have to support (i.e. does it need to support no-struct-name no-field-name or not).
The original issue is that C allows us to do
Currently we'd create two type definitions (
CFoo
). So does `rust-bindgen:which is wrong. A valid reasoning is that the above C example
is invalid as C++:
So how to deal with these errors: I suggest that we follow
rust-bindgen
example and not complicate matters.
When we have
it's reasonable to generate
data Foo = MkFoo { fooX :: Int, fooY :: Int }
.Also when we have
it's reasonable to generate only
data Foo = MkFoo { foo X :: Int, fooY :: Int }
.Note: this only is reasonable if we treat
struct foo
andtypedef ... foo
as the same: If we decide to treat them differently, we would need to generate a type forstruct foo
and a (new)type fortypedef ... foo
, i.e.:A third variant is when struct tag and newtype name differ:
this is not uncommon in C, as you have to write:
rust-bindgen
doesn't try to be too smart here, and generates:and I suggest that we similarly generate
Note: rust-bindgen uses
type
alias for newtypes)Note: @TravisCardwell we need to make sure that underscore-difference does result in different Haskell names, as above example is not uncommon. See e.g. https://stackoverflow.com/a/32405369 where from I borrowed the example.
We could be smart and do just
using the typedef name, but than we'd really need a lookup table
to convert possible
struct _linked_list
usages (in function signatures)to the newtype name. Not impossible, but it's an additional complexity.
Note: this is consistent even if the C code has forward declrations,
and splits struct definition and typedef:
In this case we can think that we omit the
typedef
definition,when it doesn't introduce a new name!
Nested (possibly anonymous and unnamed) structures: even for
no-struct-name no-field-name
rust-bindgen
generatessimilarly struct-name no-field-name
results into
what's interesting is that
struct bar
name is manged withfoo
,though in C in doesn't need to (and looks like
rust-bindgen
has some name mangling type-lookup table).(And this code is valid in C++ too).
then no-struct-name field-name
is converted to
Note: no field name used in generated type,
rust-bindgen
could be smarter hereThe last case, struct-name field-name:
So for nested structures I suggest that we again follow
rust-bindgen
,and always create a separate structure for them, even in no-struct-name no-field-name case.
This will be uniform approach.
The text was updated successfully, but these errors were encountered: