diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5604,7 +5604,7 @@ HelpText<"Set runtime encoding, supports only UTF-8">, Alias; def _SLASH_std : CLCompileJoined<"std:">, - HelpText<"Set C++ version (c++14,c++17,c++latest)">; + HelpText<"Set language version (c++14,c++17,c++latest,c11,c17)">; def _SLASH_U : CLJoinedOrSeparate<"U">, HelpText<"Undefine macro">, MetaVarName<"">, Alias; def _SLASH_validate_charset : CLFlag<"validate-charset">, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5204,6 +5204,7 @@ // // If a std is supplied, only add -trigraphs if it follows the // option. + bool ImplyVCPPCVer = false; bool ImplyVCPPCXXVer = false; const Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi); if (Std) { @@ -5228,9 +5229,13 @@ // doesn't match. For the time being just ignore this for C++ inputs; // eventually we want to do all the standard defaulting here instead of // splitting it between the driver and clang -cc1. - if (!types::isCXX(InputType)) - Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ, "-std=", - /*Joined=*/true); + if (!types::isCXX(InputType)) { + if (!Args.hasArg(options::OPT__SLASH_std)) { + Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ, "-std=", + /*Joined=*/true); + } else + ImplyVCPPCVer = true; + } else if (IsWindowsMSVC) ImplyVCPPCXXVer = true; @@ -5848,6 +5853,20 @@ Args.MakeArgString("-fms-compatibility-version=" + MSVT.getAsString())); bool IsMSVC2015Compatible = MSVT.getMajor() >= 19; + if (ImplyVCPPCVer) { + StringRef LanguageStandard; + if (const Arg *StdArg = Args.getLastArg(options::OPT__SLASH_std)) { + Std = StdArg; + LanguageStandard = llvm::StringSwitch(StdArg->getValue()) + .Case("c11", "-std=c11") + .Case("c17", "-std=c17") + .Default(""); + if (LanguageStandard.empty()) + D.Diag(clang::diag::warn_drv_unused_argument) + << StdArg->getAsString(Args); + } + CmdArgs.push_back(LanguageStandard.data()); + } if (ImplyVCPPCXXVer) { StringRef LanguageStandard; if (const Arg *StdArg = Args.getLastArg(options::OPT__SLASH_std)) { diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c @@ -337,6 +337,9 @@ // RUN: %clang_cl -c -### /Zc:char8_t- -- %s 2>&1 | FileCheck -check-prefix CHECK-CHAR8_T_ %s // CHECK-CHAR8_T_: "-fno-char8_t" +// RUN: %clang_cl -c -### /std:c11 -- %s 2>&1 | FileCheck -check-prefix CHECK-C11 %s +// CHECK-C11: -std=c11 + // For some warning ids, we can map from MSVC warning to Clang warning. // RUN: %clang_cl -wd4005 -wd4100 -wd4910 -wd4996 -### -- %s 2>&1 | FileCheck -check-prefix=Wno %s // Wno: "-cc1"