diff --git a/changelog/cpp98.dd b/changelog/cpp98.dd new file mode 100644 index 000000000000..8ae68075ea48 --- /dev/null +++ b/changelog/cpp98.dd @@ -0,0 +1,64 @@ +Ddoc + +$(H2 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 -std=c++98 compiler switch. This + will also set the predefined version Cpp98. + 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.) + +$(H3 C++ Type Equivalence) + +$(H4 Cpp98 behavior:) + +$(TABLE +$(THEAD D , Posix , DMC++ Windows , VC++ Windows) + +$(TROW wchar , unsigned short , wchar_t , wchar_t) +$(TROW dchar , wchar_t , unsigned , unsigned) +$(TROW wchar_t , wchar_t , wchar_t , wchar_t) +$(TROW WCHAR , -- , wchar_t , wchar_t)) + +$(H4 New behavior:) + +$(TABLE +$(THEAD D , Posix , DMC++ Windows , VC++ Windows) + +$(TROW wchar , char16_t , wchar_t , char16_t) +$(TROW dchar , char32_t , unsigned , char32_t) +$(TROW wchar_t , wchar_t , wchar , wchar_t) +$(TROW WCHAR , -- , wchar , wchar_t)) + + +$(H3 Name Mangling:) + +$(H4 Cpp98 behavior:) + +$(TABLE +$(THEAD D , Posix , DMC++ Windows , VC++ Windows) + +$(TROW wchar , t , _Y , _W) +$(TROW dchar , w , I , I) +$(TROW wchar_t , w , _Y , _W)) + +$(H4 New behavior:) + +$(TABLE +$(THEAD D , Posix , DMC++ Windows , VC++ Windows) + +$(TROW wchar , Ds , _Y , _S) +$(TROW dchar , Di , I , _U) +$(TROW wchar_t , w , _Y , _W)) + diff --git a/src/dmd/cli.d b/src/dmd/cli.d index 86da9f5a5cbf..56b3e5e7033a 100644 --- a/src/dmd/cli.d +++ b/src/dmd/cli.d @@ -561,6 +561,14 @@ dmd -cov -unittest myprog.d `$(UNIX Generate shared library) $(WINDOWS Generate DLL library)`, ), + Option("std=", + "set compatiblity with ", + "Standards supported are: + $(UL + $(LI $(I c++98): Use older C++98 name mangling, + Predefines `Cpp98` $(LINK2 $(ROOT_DIR)spec/version.html#predefined-versions, version)) + )", + ), Option("transition=", "help with language change identified by 'id'", `Show additional info about language change identified by $(I id)`, diff --git a/src/dmd/cond.d b/src/dmd/cond.d index 36ab22db02c0..2f9a2d1d8970 100644 --- a/src/dmd/cond.d +++ b/src/dmd/cond.d @@ -664,6 +664,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 91581299f40c..ea7459b59545 100644 --- a/src/dmd/globals.d +++ b/src/dmd/globals.d @@ -148,6 +148,11 @@ struct Param bool fix16997; // fix integral promotions for unary + - ~ operators // 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 /** The --transition=safe switch should only be used to show code with * silent semantics changes related to @safe improvements. It should not be * used to hide a feature that will have to go through deprecate-then-error diff --git a/src/dmd/globals.h b/src/dmd/globals.h index cad7cae5f36b..ea737be4e95b 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 219f81add7f4..f7c6a8cfdbcf 100644 --- a/src/dmd/mars.d +++ b/src/dmd/mars.d @@ -1122,6 +1122,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"); @@ -2054,6 +2057,10 @@ bool parseCommandLine(const ref Strings arguments, const size_t argc, ref Param params.manual = true; return false; } + else if (arg == "-std=c++98") // https://dlang.org/dmd.html#switch-std + { + params.cpp98 = true; + } else if (arg == "-run") // https://dlang.org/dmd.html#switch-run { params.run = true; @@ -2190,6 +2197,14 @@ private void reconcileCommands(ref Param params, size_t numSrcFiles) params.useExceptions = false; } + /* TEMPORARILY set this to true until the runtime library is updated, + * in order to not leave the system in an unbuildable state. + */ + params.cpp98 = true; + + if (params.isWindows && !params.mscoff) + params.cpp98 = true; // DMC++ is a C++98 compiler + if (!params.obj || params.lib) params.link = false; 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..11e06f2f9ca9 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 @@ -279,6 +281,7 @@ Error: version identifier `CppRuntime_DigitalMars` is reserved and cannot be set Error: version identifier `CppRuntime_Gcc` is reserved and cannot be set Error: version identifier `CppRuntime_Microsoft` is reserved and cannot be set Error: version identifier `CppRuntime_Sun` is reserved and cannot be set +Error: version identifier `Cpp98` is reserved and cannot be set Error: version identifier `D_Coverage` is reserved and cannot be set Error: version identifier `D_Ddoc` is reserved and cannot be set Error: version identifier `D_InlineAsm_X86` is reserved and cannot be set