@@ -123,6 +123,15 @@ static types::ID foldType(types::ID Lang) {
123
123
}
124
124
}
125
125
126
+ // Return the language standard that's activated by the /std:c++latest
127
+ // flag in clang-CL mode.
128
+ static LangStandard::Kind latestLangStandard () {
129
+ // FIXME: Have a single source of truth for the mapping from
130
+ // c++latest --> c++26 that's shared by the driver code
131
+ // (clang/lib/Driver/ToolChains/Clang.cpp) and this file.
132
+ return LangStandard::lang_cxx26;
133
+ }
134
+
126
135
// A CompileCommand that can be applied to another file.
127
136
struct TransferableCommand {
128
137
// Flags that should not apply to all files are stripped from CommandLine.
@@ -237,9 +246,16 @@ struct TransferableCommand {
237
246
// --std flag may only be transferred if the language is the same.
238
247
// We may consider "translating" these, e.g. c++11 -> c11.
239
248
if (Std != LangStandard::lang_unspecified && foldType (TargetType) == Type) {
240
- Result.CommandLine .emplace_back ((
241
- llvm::Twine (ClangCLMode ? " /std:" : " -std=" ) +
242
- LangStandard::getLangStandardForKind (Std).getName ()).str ());
249
+ const char *Spelling =
250
+ LangStandard::getLangStandardForKind (Std).getName ();
251
+ // In clang-cl mode, the latest standard is spelled 'c++latest' rather
252
+ // than e.g. 'c++26', and the driver does not accept the latter, so emit
253
+ // the spelling that the driver does accept.
254
+ if (ClangCLMode && Std == latestLangStandard ()) {
255
+ Spelling = " c++latest" ;
256
+ }
257
+ Result.CommandLine .emplace_back (
258
+ (llvm::Twine (ClangCLMode ? " /std:" : " -std=" ) + Spelling).str ());
243
259
}
244
260
Result.CommandLine .push_back (" --" );
245
261
Result.CommandLine .push_back (std::string (Filename));
@@ -296,8 +312,14 @@ struct TransferableCommand {
296
312
// Try to interpret the argument as '-std='.
297
313
std::optional<LangStandard::Kind> tryParseStdArg (const llvm::opt::Arg &Arg) {
298
314
using namespace driver ::options;
299
- if (Arg.getOption ().matches (ClangCLMode ? OPT__SLASH_std : OPT_std_EQ))
315
+ if (Arg.getOption ().matches (ClangCLMode ? OPT__SLASH_std : OPT_std_EQ)) {
316
+ // "c++latest" is not a recognized LangStandard, but it's accepted by
317
+ // the clang driver in CL mode.
318
+ if (ClangCLMode && StringRef (Arg.getValue ()) == " c++latest" ) {
319
+ return latestLangStandard ();
320
+ }
300
321
return LangStandard::getLangKind (Arg.getValue ());
322
+ }
301
323
return std::nullopt ;
302
324
}
303
325
};
0 commit comments