diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc index b53e56e65a2..d97525a590e 100644 --- a/gcc/d/d-lang.cc +++ b/gcc/d/d-lang.cc @@ -282,6 +282,9 @@ d_init_options (unsigned int, cl_decoded_option *decoded_options) global.params.betterC = false; global.params.allInst = false; + /* Default extern(C++) mangling to C++14. */ + global.params.cplusplus = CppStdRevisionCpp14; + global.params.linkswitches = new Strings (); global.params.libfiles = new Strings (); global.params.objfiles = new Strings (); diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc index de57d9256db..e0cfbafe0b9 100644 --- a/gcc/d/d-target.cc +++ b/gcc/d/d-target.cc @@ -385,6 +385,15 @@ Target::cppParameterType (Parameter *arg) return t; } +/* Checks whether TYPE is a vendor-specific fundamental type. Stores the result + in IS_FUNDAMENTAL and returns true if the parameter was set. */ + +bool +Target::cppFundamentalType (const Type *, bool &) +{ + return false; +} + /* Return the default system linkage for the target. */ LINK diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index cf5a22f070f..f58b620d844 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -fcc235e8e25f7758266f7874edd5abefb9943e0b +7423993c996ed9f73d6ba6d58f625ad3c778ca1d The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/dmd/cppmangle.c b/gcc/d/dmd/cppmangle.c index b991417c35e..9b24fd2c2e4 100644 --- a/gcc/d/dmd/cppmangle.c +++ b/gcc/d/dmd/cppmangle.c @@ -120,6 +120,40 @@ class CppMangleVisitor : public 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; + if (Target::cppFundamentalType(t, isFundamental)) + return isFundamental; + if (t->ty == Tenum) + { + // Peel off enum type from special types. + TypeEnum *te = (TypeEnum *)t; + if (te->sym->isSpecial()) + t = te->sym->getMemtype(Loc()); + } + + // 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 >= CppStdRevisionCpp11) + return true; + else + return t->isTypeBasic() && (t->isintegral() || t->isreal()); + } + /****************************** * Write the mangled representation of the template arguments. * Params: @@ -741,7 +775,8 @@ public: */ 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; @@ -767,6 +802,22 @@ public: if (t->isImmutable() || t->isShared()) return error(t); + // Handle any target-specific basic types. + if (const char *tm = Target::cppTypeMangle(t)) + { + // Only do substitutions for non-fundamental types. + if (!isFundamentalType(t) || t->isConst()) + { + if (substitute(t)) + return; + else + append(t); + } + CV_qualifiers(t); + buf->writestring(tm); + return; + } + /* : * v void * w wchar_t @@ -832,17 +883,6 @@ public: case Tcomplex80: p = 'C'; c = 'e'; break; default: - // Handle any target-specific basic types. - if (const char *tm = Target::cppTypeMangle(t)) - { - if (substitute(t)) - return; - else - append(t); - CV_qualifiers(t); - buf->writestring(tm); - return; - } return error(t); } writeBasicType(t, p, c); diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h index 6c37cca3236..e2d42c7b67b 100644 --- a/gcc/d/dmd/globals.h +++ b/gcc/d/dmd/globals.h @@ -55,6 +55,14 @@ enum CPU native // the machine the compiler is being run on }; +enum CppStdRevision +{ + CppStdRevisionCpp98 = 199711, + CppStdRevisionCpp11 = 201103, + CppStdRevisionCpp14 = 201402, + CppStdRevisionCpp17 = 201703 +}; + // Put command line switches in here struct Param { @@ -114,6 +122,7 @@ struct Param bool check10378; // check for issues transitioning to 10738 bool bug10378; // use pre-bugzilla 10378 search strategy bool vsafe; // use enhanced @safe checking + unsigned cplusplus; // version of C++ name mangling to support bool showGaggedErrors; // print gagged errors anyway CPU cpu; // CPU instruction set to target diff --git a/gcc/d/dmd/target.h b/gcc/d/dmd/target.h index 66be2014432..1729bc33ffa 100644 --- a/gcc/d/dmd/target.h +++ b/gcc/d/dmd/target.h @@ -71,5 +71,6 @@ struct Target static const char *cppTypeInfoMangle(ClassDeclaration *cd); static const char *cppTypeMangle(Type *t); static Type *cppParameterType(Parameter *p); + static bool cppFundamentalType(const Type *t, bool& isFundamental); static LINK systemLinkage(); }; diff --git a/gcc/testsuite/gdc.test/runnable/cppa.d b/gcc/testsuite/gdc.test/runnable/cppa.d index 82b93adf1f6..6b2bafbe7bc 100644 --- a/gcc/testsuite/gdc.test/runnable/cppa.d +++ b/gcc/testsuite/gdc.test/runnable/cppa.d @@ -619,6 +619,7 @@ else alias c_long_double myld; extern (C++) myld testld(myld); +extern (C++) myld testldld(myld, myld); void test15() @@ -626,6 +627,10 @@ void test15() myld ld = 5.0; ld = testld(ld); assert(ld == 6.0); + + myld ld2 = 5.0; + ld2 = testldld(ld2, ld2); + assert(ld2 == 6.0); } /****************************************/ diff --git a/gcc/testsuite/gdc.test/runnable/extra-files/cppb.cpp b/gcc/testsuite/gdc.test/runnable/extra-files/cppb.cpp index 7574c5fba72..587145c61c3 100644 --- a/gcc/testsuite/gdc.test/runnable/extra-files/cppb.cpp +++ b/gcc/testsuite/gdc.test/runnable/extra-files/cppb.cpp @@ -439,6 +439,12 @@ long double testld(long double ld) return ld + 1; } +long double testldld(long double ld1, long double ld2) +{ + assert(ld1 == 5); + return ld2 + 1; +} + long testl(long lng) { assert(lng == 5);