Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion clang-tools-extra/clangd/CompileCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,8 @@ void CommandMangler::operator()(tooling::CompileCommand &Command,
if (auto *DashDash =
ArgList.getLastArgNoClaim(driver::options::OPT__DASH_DASH)) {
auto DashDashIndex = DashDash->getIndex() + 1; // +1 accounts for Cmd[0]
for (unsigned I = DashDashIndex; I < Cmd.size(); ++I)
// Another +1 so we don't treat the `--` itself as an input.
for (unsigned I = DashDashIndex + 1; I < Cmd.size(); ++I)
SawInput(Cmd[I]);
Cmd.resize(DashDashIndex);
}
Expand Down
19 changes: 19 additions & 0 deletions clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,25 @@ TEST(CommandMangler, RespectsOriginalSysroot) {
Not(HasSubstr(testPath("fake/sysroot"))));
}
}

TEST(CommandMangler, StdLatestFlag) {
const auto Mangler = CommandMangler::forTests();
tooling::CompileCommand Cmd;
Cmd.CommandLine = {"clang-cl", "/std:c++latest", "--", "/Users/foo.cc"};
Mangler(Cmd, "/Users/foo.cc");
// Check that the /std:c++latest flag is not dropped
EXPECT_THAT(llvm::join(Cmd.CommandLine, " "), HasSubstr("/std:c++latest"));
}

TEST(CommandMangler, StdLatestFlag_Inference) {
const auto Mangler = CommandMangler::forTests();
tooling::CompileCommand Cmd;
Cmd.CommandLine = {"clang-cl", "/std:c++latest", "--", "/Users/foo.cc"};
Mangler(Cmd, "/Users/foo.hpp");
// Check that the /std:c++latest flag is not dropped during inference
EXPECT_THAT(llvm::join(Cmd.CommandLine, " "), HasSubstr("/std:c++latest"));
}

} // namespace
} // namespace clangd
} // namespace clang
30 changes: 26 additions & 4 deletions clang/lib/Tooling/InterpolatingCompilationDatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,15 @@ static types::ID foldType(types::ID Lang) {
}
}

// Return the language standard that's activated by the /std:c++latest
// flag in clang-CL mode.
static LangStandard::Kind latestLangStandard() {
// FIXME: Have a single source of truth for the mapping from
// c++latest --> c++26 that's shared by the driver code
// (clang/lib/Driver/ToolChains/Clang.cpp) and this file.
return LangStandard::lang_cxx26;
}

// A CompileCommand that can be applied to another file.
struct TransferableCommand {
// Flags that should not apply to all files are stripped from CommandLine.
Expand Down Expand Up @@ -237,9 +246,16 @@ struct TransferableCommand {
// --std flag may only be transferred if the language is the same.
// We may consider "translating" these, e.g. c++11 -> c11.
if (Std != LangStandard::lang_unspecified && foldType(TargetType) == Type) {
Result.CommandLine.emplace_back((
llvm::Twine(ClangCLMode ? "/std:" : "-std=") +
LangStandard::getLangStandardForKind(Std).getName()).str());
const char *Spelling =
LangStandard::getLangStandardForKind(Std).getName();
// In clang-cl mode, the latest standard is spelled 'c++latest' rather
// than e.g. 'c++26', and the driver does not accept the latter, so emit
// the spelling that the driver does accept.
if (ClangCLMode && Std == latestLangStandard()) {
Spelling = "c++latest";
}
Result.CommandLine.emplace_back(
(llvm::Twine(ClangCLMode ? "/std:" : "-std=") + Spelling).str());
}
Result.CommandLine.push_back("--");
Result.CommandLine.push_back(std::string(Filename));
Expand Down Expand Up @@ -296,8 +312,14 @@ struct TransferableCommand {
// Try to interpret the argument as '-std='.
std::optional<LangStandard::Kind> tryParseStdArg(const llvm::opt::Arg &Arg) {
using namespace driver::options;
if (Arg.getOption().matches(ClangCLMode ? OPT__SLASH_std : OPT_std_EQ))
if (Arg.getOption().matches(ClangCLMode ? OPT__SLASH_std : OPT_std_EQ)) {
// "c++latest" is not a recognized LangStandard, but it's accepted by
// the clang driver in CL mode.
if (ClangCLMode && StringRef(Arg.getValue()) == "c++latest") {
return latestLangStandard();
}
return LangStandard::getLangKind(Arg.getValue());
}
return std::nullopt;
}
};
Expand Down