Skip to content

Commit

Permalink
cppmangle.d: Fix substitution logic in writeBasicType()
Browse files Browse the repository at this point in the history
Specifically fixes nullptr_t and target-specific mangling.

Later on, this will also work for char16_t and char32_t as well.
  • Loading branch information
ibuclaw committed Dec 26, 2018
1 parent 45b0e1c commit d4f55d4
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 60 deletions.
109 changes: 49 additions & 60 deletions src/dmd/cppmangle.d
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import dmd.root.rootobject;
import dmd.target;
import dmd.tokens;
import dmd.typesem;
import dmd.utils;
import dmd.visitor;


Expand Down Expand Up @@ -1081,26 +1082,24 @@ private final class CppMangleVisitor : Visitor
}

/******
* Write out 1 or 2 character basic type mangling.
* Write out basic type mangling.
* Handle const and substitutions.
* Params:
* t = type to mangle
* p = if not 0, then character prefix
* c = mangling character
* str = mangling string
* builtin = true if handling C++ builtin type
*/
void writeBasicType(Type t, char p, char c)
void writeBasicType(Type t, const(char)[] str, bool builtin)
{
if (p || t.isConst())
if (!builtin || t.isConst())
{
if (substitute(t))
return;
else
append(t);
}
CV_qualifiers(t);
if (p)
buf.writeByte(p);
buf.writeByte(c);
buf.writestring(str);
}


Expand Down Expand Up @@ -1221,7 +1220,10 @@ extern(C++):
if (t.isImmutable() || t.isShared())
return error(t);

writeBasicType(t, 'D', 'n');
version (all)
writeBasicType(t, "Dn", true); // Gnu ABI v.7
else
writeBasicType(t, "Dn", false); // Gnu ABI v.6
}

override void visit(TypeBasic t)
Expand Down Expand Up @@ -1259,58 +1261,45 @@ extern(C++):
* Ds char16_t
* u <source-name> # vendor extended type
*/
char c;
char p = 0;

// Handle any target-specific basic types.
if (auto tm = target.cppTypeMangle(t))
{
bool builtin = (t.ty == Tvoid || t.ty == Tbool || t.isintegral() || t.isreal());
writeBasicType(t, tm.toDString(), builtin);
return;
}

switch (t.ty)
{
case Tvoid: c = 'v'; break;
case Tint8: c = 'a'; break;
case Tuns8: c = 'h'; break;
case Tint16: c = 's'; break;
case Tuns16: c = 't'; break;
case Tint32: c = 'i'; break;
case Tuns32: c = 'j'; break;
case Tfloat32: c = 'f'; break;
case Tint64:
c = target.c_longsize == 8 ? 'l' : 'x';
break;
case Tuns64:
c = target.c_longsize == 8 ? 'm' : 'y';
break;
case Tint128: c = 'n'; break;
case Tuns128: c = 'o'; break;
case Tfloat64: c = 'd'; break;
case Tfloat80: c = 'e'; break;
case Tbool: c = 'b'; break;
case Tchar: c = 'c'; break;
case Twchar: c = 't'; break; // unsigned short (perhaps use 'Ds' ?
case Tdchar: c = 'w'; break; // wchar_t (UTF-32) (perhaps use 'Di' ?
case Timaginary32: p = 'G'; c = 'f'; break; // 'G' means imaginary
case Timaginary64: p = 'G'; c = 'd'; break;
case Timaginary80: p = 'G'; c = 'e'; break;
case Tcomplex32: p = 'C'; c = 'f'; break; // 'C' means complex
case Tcomplex64: p = 'C'; c = 'd'; break;
case Tcomplex80: p = 'C'; c = 'e'; break;
case Tvoid: return writeBasicType(t, "v", true);
case Tint8: return writeBasicType(t, "a", true);
case Tuns8: return writeBasicType(t, "h", true);
case Tint16: return writeBasicType(t, "s", true);
case Tuns16: return writeBasicType(t, "t", true);
case Tint32: return writeBasicType(t, "i", true);
case Tuns32: return writeBasicType(t, "j", true);
case Tfloat32: return writeBasicType(t, "f", true);
case Tint64: return writeBasicType(t, target.c_longsize == 8 ? "l" : "x", true);
case Tuns64: return writeBasicType(t, target.c_longsize == 8 ? "m" : "y", true);
case Tint128: return writeBasicType(t, "n", true);
case Tuns128: return writeBasicType(t, "o", true);
case Tfloat64: return writeBasicType(t, "d", true);
case Tfloat80: return writeBasicType(t, "e", true);
case Tbool: return writeBasicType(t, "b", true);
case Tchar: return writeBasicType(t, "c", true);
case Twchar: return writeBasicType(t, "t", true); // unsigned short (perhaps use "Ds" ?
case Tdchar: return writeBasicType(t, "w", true); // wchar_t (UTF-32) (perhaps use "Di" ?
case Timaginary32: return writeBasicType(t, "Gf", false); // 'G' means imaginary
case Timaginary64: return writeBasicType(t, "Gd", false);
case Timaginary80: return writeBasicType(t, "Ge", false);
case Tcomplex32: return writeBasicType(t, "Cf", false); // 'C' means complex
case Tcomplex64: return writeBasicType(t, "Cd", false);
case Tcomplex80: return writeBasicType(t, "Ce", false);

default:
// Handle any target-specific basic types.
if (auto tm = target.cppTypeMangle(t))
{
// Only do substitution for mangles that are longer than 1 character.
if (tm[1] != 0 || t.isConst())
{
if (substitute(t))
return;
else
append(t);
}
CV_qualifiers(t);
buf.writestring(tm);
return;
}
return error(t);
}
writeBasicType(t, p, c);
}

override void visit(TypeVector t)
Expand Down Expand Up @@ -1443,15 +1432,15 @@ extern(C++):
const id = t.sym.ident;
//printf("enum id = '%s'\n", id.toChars());
if (id == Id.__c_long)
return writeBasicType(t, 0, 'l');
return writeBasicType(t, "l", true);
else if (id == Id.__c_ulong)
return writeBasicType(t, 0, 'm');
return writeBasicType(t, "m", true);
else if (id == Id.__c_wchar_t)
return writeBasicType(t, 0, 'w');
return writeBasicType(t, "w", true);
else if (id == Id.__c_longlong)
return writeBasicType(t, 0, 'x');
return writeBasicType(t, "x", true);
else if (id == Id.__c_ulonglong)
return writeBasicType(t, 0, 'y');
return writeBasicType(t, "y", true);

doSymbol(t);
}
Expand Down
13 changes: 13 additions & 0 deletions test/runnable/cppa.d
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,18 @@ void test16()
static assert(0);
}

/****************************************/

alias nullptr_t = typeof(null);

extern (C++) void testnull(nullptr_t);
extern (C++) void testnullnull(nullptr_t, nullptr_t);

void test17()
{
testnull(null);
testnullnull(null, null);
}

/****************************************/

Expand Down Expand Up @@ -1611,6 +1623,7 @@ void main()
test13289();
test15();
test16();
test17();
func13707();
func13932(S13932!(-1)(0));
foo13337(S13337());
Expand Down
13 changes: 13 additions & 0 deletions test/runnable/extra-files/cppb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,19 @@ unsigned long testul(unsigned long ul)

/******************************************/

void testnull(nullptr_t n)
{
assert(n == NULL);
}

void testnullnull(nullptr_t n1, nullptr_t n2)
{
assert(n1 == NULL);
assert(n2 == NULL);
}

/******************************************/

struct S13707
{
void* a;
Expand Down

0 comments on commit d4f55d4

Please sign in to comment.