b.cpp:
----
struct elem { };
void foobar(elem*, elem*) {}
----
a.d:
----
struct elem { }
extern(C++)void foobar(elem*, elem*);
void main(){
elem *a;
foobar(a, a);
}
----
Compile with:
$ gcc -c b.cpp -ob.o
$ dmd a.d b.o
This gives linking errors, as dmd does not mangle foobar properly. According to nm, the correct mangle (found in b.cpp) is:
_Z6foobarP4elem
But dmd mangles it as:
_Z6foobarP4elemS_
Again, this is a blocker for ddmd on linux.
Comment #1 by ellery-newcomer — 2010-04-03T14:58:02Z
What version of gcc do you use? with version 4.4.3, I get
_Z6foobarP4elemS0_
from nm b.o
(as well as a __gxx_personality_v0, which causes more problems)
and dmd 1.058 doesn't seem to want to mangle foobar at all.
Comment #2 by robert — 2010-04-03T15:01:50Z
I'm using gcc 4.4.3 too, and dmd 1.x won't mangle it as dmd 1.x does not support C++ name mangling. Even with the mangle you give it doesn't match what dmd outputs.
Comment #3 by 2korden — 2010-04-12T06:02:09Z
Rising the severity as it is indeed a blocker
Comment #4 by robert — 2010-04-23T14:01:13Z
The following patch seems to fix the issue, I haven't tested to see if this breaks mangling in other cases though:
--- cppmangle.c 2010-03-18 18:58:06.000000000 +0000
+++ cppmangle.c 2010-04-23 21:59:47.000000000 +0100
@@ -69,11 +69,10 @@
{
if (p == components.data[i])
{
- /* Sequence is S_, S0_, .., S9_, SA_, ..., SZ_, S10_, ...
+ /* Sequence is S0_, .., S9_, SA_, ..., SZ_, S10_, ...
*/
buf->writeByte('S');
- if (i)
- writeBase36(buf, i - 1);
+ writeBase36(buf, i);
buf->writeByte('_');
return 1;
}
Comment #5 by robert — 2010-04-24T11:24:44Z
It seems there are other cases that this patch breaks, so there's obviously a different way of fixing this.
Comment #6 by luk.wrzosek — 2010-11-03T21:24:34Z
In DMD complex types 'save-points' are created in wrong order. This patch should fix the issue.
I believe also that there is much more work needed in c++ mangling. The is no easy way to call external C++ function from DMD when one of its arguments types is long. The equivalent of long from C/C++ in D is int, but it is being mangled differently, so cannot be linked after compilation faze.
Index: cppmangle.c
===================================================================
--- cppmangle.c (wersja 737)
+++ cppmangle.c (kopia robocza)
@@ -43,6 +43,10 @@
static Array components;
int substitute(OutBuffer *buf, void *p);
+
+ int exist(void *p);
+
+ void store(void *p);
};
Array CppMangleState::components;
@@ -82,6 +86,23 @@
return 0;
}
+int CppMangleState::exist(void *p)
+{
+ for (size_t i = 0; i < components.dim; i++)
+ {
+ if (p == components.data[i])
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void CppMangleState::store(void *p)
+{
+ components.push(p);
+}
+
void source_name(OutBuffer *buf, Dsymbol *s)
{
char *name = s->ident->toChars();
@@ -266,19 +287,25 @@
void TypePointer::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
- if (!cms->substitute(buf, this))
+ if (!cms->exist(this))
{ buf->writeByte('P');
next->toCppMangle(buf, cms);
+ cms->store(this);
}
+ else
+ cms->substitute(buf, this);
}
void TypeReference::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
- if (!cms->substitute(buf, this))
+ if (!cms->exist(this))
{ buf->writeByte('R');
next->toCppMangle(buf, cms);
+ cms->store(this);
}
+ else
+ cms->substitute(buf, this);
}
Comment #7 by doob — 2010-11-04T02:02:34Z
(In reply to comment #6)
> In DMD complex types 'save-points' are created in wrong order. This patch
> should fix the issue.
> I believe also that there is much more work needed in c++ mangling. The is no
> easy way to call external C++ function from DMD when one of its arguments types
> is long. The equivalent of long from C/C++ in D is int, but it is being mangled
> differently, so cannot be linked after compilation faze.
The size of long in C/C++ depends on if the system is 64bit or not and what data model is used. To make the explanation short: On Windows long is 32 bits and on Unix-like systems long is 64 bits.
Comment #8 by luk.wrzosek — 2010-11-08T08:44:55Z
AFAIK it is not so general. On my Linux 32bit system long is 32bit.
Comment #9 by luk.wrzosek — 2010-11-08T08:50:17Z
Created attachment 805
Diff
Comment #10 by doob — 2010-11-08T08:53:43Z
(In reply to comment #8)
> AFAIK it is not so general. On my Linux 32bit system long is 32bit.
Maybe I was unclear but I was referring to 64bit systems. Lets try it once more:
32bit:
Windows - "long" will be 32 bits long
Unix-like - "long" will be 32 bits long
64bit:
Windows - "long" will be 32 bits long
Unix-like - "long" will be 64 bits long
Again, this is simplified explanation as can be seen in the reference below.
For reference: http://en.wikipedia.org/wiki/64-bit - The header is "Specific C-language data models"