jacob-carlborg / dstep

A tool for converting C and Objective-C headers to D modules
204 stars 37 forks source link

typedef <typeA> <typeB>; when typeA is not in scope #256

Open jblachly opened 3 years ago

jblachly commented 3 years ago

First, let me say that dstep is amazing and my first experience with it today has made me a believer.

Other than needed imports, I only had a single problem with a 1700+ line .h file :-O

Question

I have two C headers, with typeA defined in moduleA (say, modA.h defines struct typeA) and module B #includes this and uses a typedef:

typedef typeA typeB

When translating module B, I would have expected the declaration alias typeB = typeA, but instead (because typeA was not in scope), I got

alias typeB = _Anonymous_0

Is there a way for me to mitigate this, or is it intractable as things stand today?

Thanks again for this amazing time-saver.

jacob-carlborg commented 3 years ago

First, let me say that dstep is amazing and my first experience with it today has made me a believer.

Thanks.

Other than needed imports

Yeah, the imports are a known problem.

I only had a single problem with a 1700+ line .h file :-O

Cool 😃. It all depends on the C code. For example, the bindings to libclang that DStep is using are completely automatically generated by DStep itself. But for other headers it don't work as well.

I have two C headers, with typeA defined in moduleA (say, modA.h defines struct typeA) and module B #includes this and uses a typedef:

You could please show exactly how the two header files look like (with the relevant content).

When translating module B, I would have expected the declaration alias typeB = typeA, but instead (because typeA was not in scope), I got alias typeB = _Anonymous_0

symbols like _Anonymous_0 are generated from anonymous declarations in the C code. I would need to see the exact C code, in both header files.

Is there a way for me to mitigate this, or is it intractable as things stand today?

I would need to see the C code in both header files to tell for sure. But in general there are some limitations due to DStep only look at one file at the time.

I plan to try to do a whole project analysis, if a whole directory is passed to DStep, the might help here. That could automatically add imports as well.

jblachly commented 3 years ago

a.h:

typedef struct {
        int x;
        int y;
} A;

b.h:

#include "a.h"

typedef A B;

for completeness, c.c:

#include <stdio.h>
#include "b.h"

int main(void)
{
        printf("noop");
}

dstep -o . a.h b.h yields b.d:

extern (C):

alias B = _Anonymous_0;
jacob-carlborg commented 3 years ago

DStep used to generate code for a.h that looked like this:

extern (C):

struct _Anonymous_0
{
    int x;
    int y;
}

alias A = _Anonymous_0;

That is the most correct representation, but unnecessary. That has been fixed only generate a struct without the alias. But it seems other parts of the code was not updated.

jblachly commented 3 years ago

Other parts of dstep/lib-clang do seem to look across imports, however ; in another conversion I got a warning about duplicate symbols. So it is seems surprising that the _Anonymous_0 is necessary if b #includes a ?

jacob-carlborg commented 3 years ago

The anonymous symbol is not needed.

mw66 commented 2 years ago

@jblachly you can try my workaround: feed cpp generated single .i file to dstep

https://github.com/jacob-carlborg/dstep/issues/280#issuecomment-1148065013