Skip to content
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

conflicting type in typedef with same struct name, and functions using this typedef #50

Open
bew opened this issue Aug 15, 2017 · 3 comments

Comments

@bew
Copy link

bew commented Aug 15, 2017

typedef struct my_opaque_t my_opaque_t;
void my_func(my_opaque_t *obj);

Generates:

alias MyOpaqueT = Void         # first definition of `MyOpaqueT`
fun my_func(obj : MyOpaqueT)
type MyOpaqueT = Pointer(Void) # second definition of `MyOpaqueT`

I've made a little program to test this (bew/crystal_lib - test.cr):

Outputs:

# // typedef different names
# typedef struct my_opaque_struct my_opaque_t;
alias MyOpaqueStruct = Void    # note: it should be `MyOpaqueT`   ?

# // typedef different name, + func
# typedef struct my_opaque_struct my_opaque_t;
# void my_func(my_opaque_t *obj);
alias MyOpaqueStruct = Void
fun my_func(obj : MyOpaqueT)
type MyOpaqueT = Pointer(Void)


# // typedef same name
# typedef struct my_opaque_t my_opaque_t;
alias MyOpaqueT = Void

# // typedef same name, + func
# typedef struct my_opaque_t my_opaque_t;
# void my_func(my_opaque_t *obj);
alias MyOpaqueT = Void
fun my_func(obj : MyOpaqueT)
type MyOpaqueT = Pointer(Void)

We can see that the typedef generates the alias, and the function declaration generates the fun and the type.

Looking at the code, I've found that the type is generated when mapping the function argument: the argument type is parsed as a PointerType to a StructOrUnion. In the mapping of the pointer, a check is made for an opaque type, succeeds, then creates a new typedef with the same name as the alias.

I'm not sure how we could properly fix this, as I like the way it auto creates a type of Pointer(Void) for opaque types. Maybe we should rename the generated type and add Ptr (or _) at the end, to ensure there's no conflict.
The example would be:

# // typedef same name, + func
# typedef struct my_opaque_t my_opaque_t;
# void my_func(my_opaque_t *obj);
alias MyOpaqueT = Void
fun my_func(obj : MyOpaqueTPtr)
type MyOpaqueTPtr = Pointer(Void)
@olbat
Copy link
Contributor

olbat commented Aug 17, 2017

I'm not really sure how this issue should be fixed .but some has to be removed/renamed ...
(IMO it's a bad idea to typedef a struct with it's name but I've seen this kind of code in many libs)

Here is another example for the issue:

$ cat <<EOF > /tmp/test.h
struct SomeOpaque;
typedef int SomeOpaque;
SomeOpaque *some_function(struct SomeOpaque);
EOF

$ crystal run src/main.cr <<EOF
@[Include("/tmp/test.h", prefix: ["some"], remove_prefix: false)]
lib Test
end
EOF

lib Test
  fun some_function(x0 : SomeOpaque) : SomeOpaque*
  alias SomeOpaque = Void
  alias SomeOpaque = LibC::Int
end

@ziprandom
Copy link

any updates on this one? it renders crystal_lib unusable for me atm..

@WhoAteDaCake
Copy link

Yeah, still problematic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants