diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index ae8b92394443a632ab599fc2c5177747e4d94e22..a3d7906255861a74afae93fe3d9d8ce65fee021d 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -162,6 +162,9 @@ def warn_pch_access_control : Error< def warn_pch_char_signed : Error< "char was %select{unsigned|signed}0 in the PCH file but " "is currently %select{unsigned|signed}1">; +def warn_pch_short_wchar : Error< + "-fshort-wchar was %select{disabled|enabled}0 in the PCH file but " + "is currently %select{disabled|enabled}1">; def err_not_a_pch_file : Error< "'%0' does not appear to be a precompiled header file">, DefaultFatal; diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index d4d3fe50eba06b471b1402f1f5f4a6e184e2e08e..a63edd57fb2c429439ab6161f90a6a60d4863bd3 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -83,6 +83,7 @@ public: unsigned AccessControl : 1; // Whether C++ access control should // be enabled. unsigned CharIsSigned : 1; // Whether char is a signed or unsigned type + unsigned ShortWChar : 1; // Force wchar_t to be unsigned short int. unsigned OpenCL : 1; // OpenCL C99 language extensions. @@ -159,6 +160,7 @@ public: NoInline = 0; CharIsSigned = 1; + ShortWChar = 0; MainFileName = 0; } diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index e61ef9265cfb3f3e35978664b597bc1980957273..23c753260ed41a0bfa53acf3e7d16064954b007b 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -346,6 +346,11 @@ public: /// options. virtual void getDefaultLangOptions(LangOptions &Opts) {} + /// setForcedLangOptions - Set forced language options. + /// Apply changes to the target information with respect to certain + /// language options which change the target configuration. + virtual void setForcedLangOptions(LangOptions &Opts); + /// getDefaultFeatures - Get the default set of target features for /// the \args CPU; this should include all legal feature strings on /// the target. diff --git a/clang/include/clang/Driver/Options.def b/clang/include/clang/Driver/Options.def index 5370114ee82430eaa292fa42abfa513b080d73f9..d47b0e94e237299b4d8f9e0ddd3850e900ca5fcc 100644 --- a/clang/include/clang/Driver/Options.def +++ b/clang/include/clang/Driver/Options.def @@ -463,6 +463,7 @@ OPTION("-fprofile-arcs", fprofile_arcs, Flag, f_Group, INVALID, "", 0, 0, 0) OPTION("-fprofile-generate", fprofile_generate, Flag, f_Group, INVALID, "", 0, 0, 0) OPTION("-framework", framework, Separate, INVALID, INVALID, "l", 0, 0, 0) OPTION("-frtti", frtti, Flag, f_Group, INVALID, "", 0, 0, 0) +OPTION("-fshort-wchar", fshort_wchar, Flag, f_Group, INVALID, "", 0, 0, 0) OPTION("-fshow-source-location", fshow_source_location, Flag, f_Group, INVALID, "", 0, 0, 0) OPTION("-fsigned-bitfields", fsigned_bitfields, Flag, f_Group, INVALID, "", 0, 0, 0) OPTION("-fsigned-char", fsigned_char, Flag, f_Group, INVALID, "", 0, 0, 0) diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 12caf0c8e512e9e7d0fadcada9c681f1d6b54638..e965b9aec369f18f15d03324dbc03edb9873b826 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/TargetInfo.h" +#include "clang/Basic/LangOptions.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/STLExtras.h" #include @@ -124,6 +125,15 @@ bool TargetInfo::isTypeSigned(IntType T) const { }; } +/// setForcedLangOptions - Set forced language options. +/// Apply changes to the target information with respect to certain +/// language options which change the target configuration. +void TargetInfo::setForcedLangOptions(LangOptions &Opts) { + if (Opts.ShortWChar) { + WCharType = UnsignedShort; + WCharWidth = WCharAlign = 16; + } +} //===----------------------------------------------------------------------===// diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 808c31c64828360a59a5ccccef6fe627d4d4e5a9..c35ad7c5ea52e4e7b3bbf74d6bbf0706553a6c44 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -922,6 +922,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fsigned-char=0"); } + // -fshort-wchar default varies depending on platform; only + // pass if specified. + if (Arg *A = Args.getLastArg(options::OPT_fshort_wchar)) { + if (A->getOption().matches(options::OPT_fshort_wchar)) + CmdArgs.push_back("-fshort-wchar"); + } + // -fno-pascal-strings is default, only pass non-default. If the tool chain // happened to translate to -mpascal-strings, we want to back translate here. // diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index 26f426ba329b7b3c6e5055377ad219448459110f..a812604e395e7344c532c70a275278b488798442 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -104,6 +104,7 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) { PARSE_LANGOPT_IMPORTANT(NoInline, diag::warn_pch_no_inline); PARSE_LANGOPT_IMPORTANT(AccessControl, diag::warn_pch_access_control); PARSE_LANGOPT_IMPORTANT(CharIsSigned, diag::warn_pch_char_signed); + PARSE_LANGOPT_IMPORTANT(ShortWChar, diag::warn_pch_short_wchar); if ((PPLangOpts.getGCMode() != 0) != (LangOpts.getGCMode() != 0)) { Reader.Diag(diag::warn_pch_gc_mode) << LangOpts.getGCMode() << PPLangOpts.getGCMode(); @@ -1741,6 +1742,7 @@ bool PCHReader::ParseLanguageOptions( PARSE_LANGOPT(NoInline); PARSE_LANGOPT(AccessControl); PARSE_LANGOPT(CharIsSigned); + PARSE_LANGOPT(ShortWChar); LangOpts.setGCMode((LangOptions::GCMode)Record[Idx]); ++Idx; LangOpts.setVisibilityMode((LangOptions::VisibilityMode)Record[Idx]); diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index de56166125edb36edc441e3987836a9b7343a3dc..436428b3755271b02b21ccae8e4ef485d44fec07 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -765,6 +765,7 @@ void PCHWriter::WriteLanguageOptions(const LangOptions &LangOpts) { // be enabled. Record.push_back(LangOpts.CharIsSigned); // Whether char is a signed or // unsigned type + Record.push_back(LangOpts.ShortWChar); // force wchar_t to be unsigned short Record.push_back(LangOpts.getGCMode()); Record.push_back(LangOpts.getVisibilityMode()); Record.push_back(LangOpts.getStackProtectorMode()); diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c index 8266f7762398b1a6c1aebb1d081b3228d3a250a7..7aecbac49c2fcb6aa36e48786eee53a1d0f7810a 100644 --- a/clang/test/Driver/clang_f_opts.c +++ b/clang/test/Driver/clang_f_opts.c @@ -2,10 +2,11 @@ // RUN: grep -F '"-fblocks"' %t && // RUN: grep -F '"--fmath-errno=1"' %t && // RUN: grep -F '"-fpascal-strings"' %t && -// RUN: clang -### -S -x c /dev/null -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings -fno-blocks -fno-builtin -fno-math-errno -fno-common -fno-pascal-strings -fno-show-source-location %s 2> %t && +// RUN: clang -### -S -x c /dev/null -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings -fno-blocks -fno-builtin -fno-math-errno -fno-common -fno-pascal-strings -fno-show-source-location -fshort-wchar %s 2> %t && // RUN: grep -F '"-fblocks=0"' %t && // RUN: grep -F '"-fbuiltin=0"' %t && // RUN: grep -F '"-fno-common"' %t && // RUN: grep -F '"--fmath-errno=0"' %t && // RUN: grep -F '"-fno-show-source-location"' %t && +// RUN: grep -F '"-fshort-wchar"' %t && // RUN: true diff --git a/clang/test/Sema/wchar.c b/clang/test/Sema/wchar.c index 16376009ab13a26e9020668d116c4d7639f07b31..bf1996b4aa25b345643be4e8defd99ebe0c76a06 100644 --- a/clang/test/Sema/wchar.c +++ b/clang/test/Sema/wchar.c @@ -1,12 +1,20 @@ -// RUN: clang-cc %s -fsyntax-only -verify +// RUN: clang-cc %s -fsyntax-only -verify && +// RUN: clang-cc %s -fsyntax-only -fshort-wchar -verify -DSHORT_WCHAR + #include - + +#if defined(_WIN32) || defined(_M_IX86) || defined(__CYGWIN__) \ + || defined(_M_X64) || defined(SHORT_WCHAR) + #define WCHAR_T_TYPE unsigned short +#else + #define WCHAR_T_TYPE int +#endif + int check_wchar_size[sizeof(*L"") == sizeof(wchar_t) ? 1 : -1]; - + void foo() { - int t1[] = L"x"; + WCHAR_T_TYPE t1[] = L"x"; wchar_t tab[] = L"x"; - - int t2[] = "x"; // expected-error {{initialization}} + WCHAR_T_TYPE t2[] = "x"; // expected-error {{initialization}} char t3[] = L"x"; // expected-error {{initialization}} } diff --git a/clang/tools/clang-cc/clang-cc.cpp b/clang/tools/clang-cc/clang-cc.cpp index 26ba42d670027900bc2e765cd3bca94f780e22a8..a7e8f51a3a6d49cf9736faebeee4517f279408b0 100644 --- a/clang/tools/clang-cc/clang-cc.cpp +++ b/clang/tools/clang-cc/clang-cc.cpp @@ -611,6 +611,10 @@ static llvm::cl::opt CharIsSigned("fsigned-char", llvm::cl::desc("Force char to be a signed/unsigned type")); +static llvm::cl::opt +ShortWChar("fshort-wchar", + llvm::cl::desc("Force wchar_t to be a short unsigned int")); + static llvm::cl::opt Trigraphs("trigraphs", llvm::cl::desc("Process trigraph sequences")); @@ -813,6 +817,8 @@ static void InitializeLanguageStandard(LangOptions &Options, LangKind LK, Options.Blocks = EnableBlocks; if (CharIsSigned.getPosition()) Options.CharIsSigned = CharIsSigned; + if (ShortWChar.getPosition()) + Options.ShortWChar = ShortWChar; if (!AllowBuiltins) Options.NoBuiltin = 1; @@ -877,6 +883,8 @@ static void InitializeLanguageStandard(LangOptions &Options, LangKind LK, if (MainFileName.getPosition()) Options.setMainFileName(MainFileName.c_str()); + + Target->setForcedLangOptions(Options); } //===----------------------------------------------------------------------===//