This is a bug report.
The context is that I have bindings that I want to translate with more friendly names and in a less C fashion. There's many to do so I wish to proceed gradually, which leads to an intermediate situation where the C definitions exists in two different modules.
LDC does not like that because it seems that IR names for extern(C) definitions are fully qualified.
Minimal reproduction on linux, file is named test.sh:
echo "module a;
extern(C):
struct S{}
S* create(){return null;} " > a.d
echo "module b;
extern(C):
struct S;
S* create();
void t(){auto s = create();}
" >b.d
echo "module c;
extern(C):
struct S;
S* create();
void main(){auto s = create();}
" > c.d
echo "================DMD================"
dmd a.d b.d c.d
echo "dmd is happy with that"
echo "================GDC================"
gdc a.d b.d c.d
echo "gdc is happy with that"
echo "================LDC================"
ldc2 a.d b.d c.d
which results in:
[xxxx@pc extern_c_irtype_bug]$ bash test.sh
================DMD================
dmd is happy with that
================GDC================
gdc is happy with that
================LDC================
b.d(4): Error: Function type does not match previously declared function with the same mangled name: create
b.d(4): Previous IR type: %c.S* ()
b.d(4): New IR type: %b.S* ()
Maybe that the IR name for extern(C) types should only include the last identifer ?