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 29, 2018
1 parent 6095730 commit b472d0b
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 3 deletions.
41 changes: 38 additions & 3 deletions src/dmd/cppmangle.d
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,40 @@ private final class CppMangleVisitor : Visitor
!getQualifier(s)); // at global level
}

/************************
* Determine if type is a C++ fundamental type.
* Params:
* t = type to check
* Returns:
* true if it is a fundamental type
*/
static bool isFundamentalType(Type t)
{
// First check the target whether some specific ABI is being followed.
bool isFundamental = void;
if (target.cppFundamentalType(t, isFundamental))
return isFundamental;

// Peel off enum type from special types.
if (auto te = t.isTypeEnum())
{
if (te.isSpecial())
t = te.memType();
}

// Fundamental arithmetic types:
// 1. integral types: bool, char, int, ...
// 2. floating point types: float, double, real
// 3. void
// 4. null pointer: std::nullptr_t (since C++11)
if (t.ty == Tvoid || t.ty == Tbool)
return true;
else if (t.ty == Tnull && global.params.cplusplus >= CppStdRevision.cpp11)
return true;
else
return t.isTypeBasic() && (t.isintegral() || t.isreal());
}

/******************************
* Write the mangled representation of a template argument.
* Params:
Expand Down Expand Up @@ -1090,7 +1124,8 @@ private final class CppMangleVisitor : Visitor
*/
void writeBasicType(Type t, char p, char c)
{
if (p || t.isConst())
// Only do substitutions for non-fundamental types.
if (!isFundamentalType(t) || t.isConst())
{
if (substitute(t))
return;
Expand Down Expand Up @@ -1296,8 +1331,8 @@ extern(C++):
// 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())
// Only do substitutions for non-fundamental types.
if (!isFundamentalType(t) || t.isConst())
{
if (substitute(t))
return;
Expand Down
13 changes: 13 additions & 0 deletions src/dmd/target.d
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,19 @@ struct Target
return t;
}

/**
* Checks whether type is a vendor-specific fundamental type.
* Params:
* t = type to inspect
* isFundamental = where to store result
* Returns:
* true if isFundamental was set by function
*/
extern (C++) bool cppFundamentalType(const Type t, ref bool isFundamental)
{
return false;
}

/**
* Default system linkage for the target.
* Returns:
Expand Down
14 changes: 14 additions & 0 deletions test/runnable/cppa.d
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,19 @@ void test16()
static assert(0);
}

/****************************************/
/+ FIXME: Requires C++11 compiler.
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 +1624,7 @@ void main()
test13289();
test15();
test16();
//test17();
func13707();
func13932(S13932!(-1)(0));
foo13337(S13337());
Expand Down
14 changes: 14 additions & 0 deletions test/runnable/extra-files/cppb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,20 @@ unsigned long testul(unsigned long ul)
return ul + sizeof(unsigned long);
}

/******************************************/
/* FIXME: Requires C++11 compiler.
void testnull(nullptr_t n)
{
assert(n == NULL);
}
void testnullnull(nullptr_t n1, nullptr_t n2)
{
assert(n1 == NULL);
assert(n2 == NULL);
}
*/

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

struct S13707
Expand Down

0 comments on commit b472d0b

Please sign in to comment.