freebasic / fbfrog

FreeBASIC binding creation tool
Other
34 stars 17 forks source link

Automatic forward declarations? #4

Open rversteegen opened 3 years ago

rversteegen commented 3 years ago

Currently, fbfrog ignores forward struct declarations by default, if no definition of the struct appears later:

struct Typ;
extern Typ *x;

translates to

extern x as Typ ptr

whereas if struct Typ {int a;}; appears later you get

type Typ as Typ_
extern x as Typ ptr

type Typ_
    a as long
end type

Without the definition, adding -addforwarddecl Type is necessary to get a working translation.

Why not add a forward declaration automatically if there is a C declaration but no definition; is it not desirable for some reason, or is it simply not implemented? The only reason to avoid doing so that I can think of is if there's another header that fbfrog wasn't given which will have already defined it. But that would be the exception, not the norm, accommodated with a -noforwarddecl option.

dkl commented 3 years ago

Here's a comment that should explain that: https://github.com/freebasic/fbfrog/blob/f0ec0ded7e8d2f04120c95bfbb7b785b30f267b8/src/highlevel.bas#L3011 But if it's more annoying than useful, then it's the wrong default. It would be interesting to run all of fbbindings with the opposite default and without the -addforwarddecl options, to see how many -noforwarddecl options would be needed.

rversteegen commented 3 years ago

Ah, thanks. There's also another comment here that discusses the issue:

https://github.com/freebasic/fbfrog/blob/f0ec0ded7e8d2f04120c95bfbb7b785b30f267b8/src/highlevel.bas#L1453

Since FILE, etc, in standard headers are the main reason for this behaviour I think you could say the problem is that fbfrog doesn't know what's in them. If we added minimal include/fbfrog/stdio.h, etc headers which only declared common structs then there may be minimal need for -noforwarddecl. I would also argue that -fbfroginclude for standard headers could be the default: translating system headers is a special case for which automatic inclusion could be disabled (-nofbfrogincludes), and likely no end user is ever going to be doing so.

I'm currently testing it in fbbindings. It's 263 -addforwarddecl's that can all be removed, and it also reveals more that are missing from various headers. There are about 204 forward declarations introduced (109 unique ones), the majority of which are common ones from crt/posix, winapi or opengl although most occur only 1-2 times:

> git diff inc/ | grep "+\s*type.* as " | sed -e 's/+\s*//' | sort | uniq --count | sort -n | tail -n 20
      2 type HWND as HWND_
      2 type iconv_t as iconv_t_
      2 type SOCKET as SOCKET_
      2 type timeval as timeval_
      2 type UBYTE as UBYTE_
      2 type UINT as UINT_
      2 type ULONG as ULONG_
      2 type USHORT as USHORT_
      2 type z_stream as z_stream_
      3 type iovec as iovec_
      3 type LONG as LONG_
      3 type lua_State as lua_State_
      3 type off_t as off_t_
      3 type stat as stat_
      4 type HDC as HDC_
      5 type tm as tm_
      6 type jmp_buf as jmp_buf_
     12 type time_t as time_t_
     22 type va_list as va_list_
     24 type FILE as FILE_

Come to think of it, wouldn't the real solution be to modify fbc to allow

type T as T

type T
    a as integer
end type

Why not?