diff --git a/changelog/cpp98.dd b/changelog/cpp98.dd new file mode 100644 index 000000000000..4acb5af1ea9c --- /dev/null +++ b/changelog/cpp98.dd @@ -0,0 +1,57 @@ +## Transition to C++11 character types + + With C++11 comes the advent of changed character type mangling. + D's default behavior is now to conform to this. However, this + will break existing code. Therefore, the old behavior can be + retained by using the -version=Cpp98 compiler switch. + For Win32 compilations using Digital Mars C++, -version=Cpp98 will + be predefined. + + Of particular note is the new difference between wchar and wchar_t on + Windows. This will manifest itself as compile errors when + interfacing wchar* with wchar_t* code when calling the Windows API. + A cast will resolve the issue. + + Going forward we recommend using WCHAR instead of wchar or wchar_t + when interfacing to Windows API functions. (WCHAR is Microsoft + Windows' 16 bit character type.) + +### C++ Type Equivalence + +#### Cpp98 behavior: + + D Posix DMC++ Windows VC++ Windows + + wchar unsigned short wchar_t wchar_t + dchar wchar_t unsigned unsigned + wchar_t wchar_t wchar_t wchar_t + WCHAR -- wchar_t wchar_t + +#### New behavior: + + D Posix DMC++ Windows VC++ Windows + + wchar char16_t wchar_t char16_t + dchar char32_t unsigned char32_t + wchar_t wchar_t wchar wchar_t + WCHAR -- wchar wchar_t + + +### Name Mangling: + +#### Cpp98 behavior: + + D Posix DMC++ Windows VC++ Windows + + wchar t _Y _W + dchar w I I + wchar_t w _Y _W + +#### New behavior: + + D Posix DMC++ Windows VC++ Windows + + wchar Ds _Y _S + dchar Di I _U + wchar_t w _Y _W + diff --git a/src/dmd/cond.d b/src/dmd/cond.d index ef823db9abc1..189dc9de89c3 100644 --- a/src/dmd/cond.d +++ b/src/dmd/cond.d @@ -658,6 +658,7 @@ extern (C++) final class VersionCondition : DVCondition case "CppRuntime_Gcc": case "CppRuntime_Microsoft": case "CppRuntime_Sun": + case "Cpp98": case "unittest": case "assert": case "all": diff --git a/src/dmd/globals.d b/src/dmd/globals.d index 6e475694229e..5e5e24e13004 100644 --- a/src/dmd/globals.d +++ b/src/dmd/globals.d @@ -149,6 +149,7 @@ struct Param // https://issues.dlang.org/show_bug.cgi?id=16997 bool fixAliasThis; // if the current scope has an alias this, check it before searching upper scopes bool vsafe; // use enhanced @safe checking + bool cpp98; // follow C++98 type system issues rather than C++11 bool ehnogc; // use @nogc exception handling bool dtorFields; // destruct fields of partially constructed objects // https://issues.dlang.org/show_bug.cgi?id=14246 diff --git a/src/dmd/globals.h b/src/dmd/globals.h index 336deae5481c..43c1ba0b614e 100644 --- a/src/dmd/globals.h +++ b/src/dmd/globals.h @@ -123,7 +123,8 @@ struct Param bool fix16997; // fix integral promotions for unary + - ~ operators // https://issues.dlang.org/show_bug.cgi?id=16997 bool vsafe; // use enhanced @safe checking - bool ehnogc; // use @nogc exception handling + bool cpp98; // follow C++98 type system issues rather than C++11 + bool ehnogc; // use @nogc exception handling bool dtorFields; // destruct fields of partially constructed objects // https://issues.dlang.org/show_bug.cgi?id=14246 bool showGaggedErrors; // print gagged errors anyway diff --git a/src/dmd/mars.d b/src/dmd/mars.d index 8e70f9728a11..8b574aff3cb6 100644 --- a/src/dmd/mars.d +++ b/src/dmd/mars.d @@ -387,6 +387,8 @@ private int tryMain(size_t argc, const(char)** argv) global.params.useExceptions = false; } + if (global.params.isWindows && !global.params.mscoff) + global.params.cpp98 = true; // DMC++ is a C++98 compiler if (!global.params.obj || global.params.lib) global.params.link = false; @@ -1235,6 +1237,9 @@ void addDefaultVersionIdentifiers(const ref Param params) VersionCondition.addPredefinedGlobalIdent("D_Version2"); VersionCondition.addPredefinedGlobalIdent("all"); + if (params.cpp98) + VersionCondition.addPredefinedGlobalIdent("Cpp98"); + if (params.cpu >= CPU.sse2) { VersionCondition.addPredefinedGlobalIdent("D_SIMD"); @@ -2053,9 +2058,14 @@ bool parseCommandLine(const ref Strings arguments, const size_t argc, ref Param } else if (Identifier.isValidIdentifier(p + 9)) { - if (!params.versionids) - params.versionids = new Array!(const(char)*); - params.versionids.push(p + 9); + if (strcmp(p + 9, "Cpp98") == 0) // -version=Cpp98 + params.cpp98 = true; // version will be set in addDefaultVersionIdentifiers() + else + { + if (!params.versionids) + params.versionids = new Array!(const(char)*); + params.versionids.push(p + 9); + } } else goto Lerror; diff --git a/test/fail_compilation/reserved_version.d b/test/fail_compilation/reserved_version.d index 050d8167c0e0..c0b501701402 100644 --- a/test/fail_compilation/reserved_version.d +++ b/test/fail_compilation/reserved_version.d @@ -105,6 +105,7 @@ fail_compilation/reserved_version.d(206): Error: version identifier `CppRuntime_ fail_compilation/reserved_version.d(207): Error: version identifier `CppRuntime_Gcc` is reserved and cannot be set fail_compilation/reserved_version.d(208): Error: version identifier `CppRuntime_Microsoft` is reserved and cannot be set fail_compilation/reserved_version.d(209): Error: version identifier `CppRuntime_Sun` is reserved and cannot be set +fail_compilation/reserved_version.d(210): Error: version identifier `Cpp98` is reserved and cannot be set --- */ @@ -216,6 +217,7 @@ version = CppRuntime_DigitalMars; version = CppRuntime_Gcc; version = CppRuntime_Microsoft; version = CppRuntime_Sun; +version = Cpp98; // This should work though debug = DigitalMars; @@ -300,6 +302,7 @@ debug = CppRuntime_DigitalMars; debug = CppRuntime_Gcc; debug = CppRuntime_Microsoft; debug = CppRuntime_Sun; +debug = Cpp98; debug = D_Coverage; debug = D_Ddoc; debug = D_InlineAsm_X86; diff --git a/test/fail_compilation/reserved_version_switch.d b/test/fail_compilation/reserved_version_switch.d index 0259273f89e7..cc968806c40a 100644 --- a/test/fail_compilation/reserved_version_switch.d +++ b/test/fail_compilation/reserved_version_switch.d @@ -82,6 +82,7 @@ // REQUIRED_ARGS: -version=CppRuntime_Gcc // REQUIRED_ARGS: -version=CppRuntime_Microsoft // REQUIRED_ARGS: -version=CppRuntime_Sun +// REQUIRED_ARGS: -version=Cpp98 // REQUIRED_ARGS: -version=D_Coverage // REQUIRED_ARGS: -version=D_Ddoc // REQUIRED_ARGS: -version=D_InlineAsm_X86 @@ -178,6 +179,7 @@ // REQUIRED_ARGS: -debug=CppRuntime_Gcc // REQUIRED_ARGS: -debug=CppRuntime_Microsoft // REQUIRED_ARGS: -debug=CppRuntime_Sun +// REQUIRED_ARGS: -debug=Cpp98 // REQUIRED_ARGS: -debug=D_Coverage // REQUIRED_ARGS: -debug=D_Ddoc // REQUIRED_ARGS: -debug=D_InlineAsm_X86