aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Tooling/InterpolatingCompilationDatabase.cpp')
-rw-r--r--clang/lib/Tooling/InterpolatingCompilationDatabase.cpp41
1 files changed, 22 insertions, 19 deletions
diff --git a/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp b/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp
index fa61560e5123..c1e25c41f719 100644
--- a/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp
+++ b/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp
@@ -43,9 +43,11 @@
//===----------------------------------------------------------------------===//
#include "clang/Basic/LangStandard.h"
+#include "clang/Driver/Driver.h"
#include "clang/Driver/Options.h"
#include "clang/Driver/Types.h"
#include "clang/Tooling/CompilationDatabase.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringExtras.h"
@@ -134,8 +136,7 @@ struct TransferableCommand {
bool ClangCLMode;
TransferableCommand(CompileCommand C)
- : Cmd(std::move(C)), Type(guessType(Cmd.Filename)),
- ClangCLMode(checkIsCLMode(Cmd.CommandLine)) {
+ : Cmd(std::move(C)), Type(guessType(Cmd.Filename)) {
std::vector<std::string> OldArgs = std::move(Cmd.CommandLine);
Cmd.CommandLine.clear();
@@ -145,6 +146,9 @@ struct TransferableCommand {
SmallVector<const char *, 16> TmpArgv;
for (const std::string &S : OldArgs)
TmpArgv.push_back(S.c_str());
+ ClangCLMode = !TmpArgv.empty() &&
+ driver::IsClangCL(driver::getDriverMode(
+ TmpArgv.front(), llvm::makeArrayRef(TmpArgv).slice(1)));
ArgList = {TmpArgv.begin(), TmpArgv.end()};
}
@@ -177,6 +181,10 @@ struct TransferableCommand {
Opt.matches(OPT__SLASH_Fo))))
continue;
+ // ...including when the inputs are passed after --.
+ if (Opt.matches(OPT__DASH_DASH))
+ break;
+
// Strip -x, but record the overridden language.
if (const auto GivenType = tryParseTypeArg(*Arg)) {
Type = *GivenType;
@@ -204,8 +212,10 @@ struct TransferableCommand {
}
// Produce a CompileCommand for \p filename, based on this one.
- CompileCommand transferTo(StringRef Filename) const {
- CompileCommand Result = Cmd;
+ // (This consumes the TransferableCommand just to avoid copying Cmd).
+ CompileCommand transferTo(StringRef Filename) && {
+ CompileCommand Result = std::move(Cmd);
+ Result.Heuristic = "inferred from " + Result.Filename;
Result.Filename = std::string(Filename);
bool TypeCertain;
auto TargetType = guessType(Filename, &TypeCertain);
@@ -233,25 +243,13 @@ struct TransferableCommand {
llvm::Twine(ClangCLMode ? "/std:" : "-std=") +
LangStandard::getLangStandardForKind(Std).getName()).str());
}
+ if (Filename.startswith("-") || (ClangCLMode && Filename.startswith("/")))
+ Result.CommandLine.push_back("--");
Result.CommandLine.push_back(std::string(Filename));
- Result.Heuristic = "inferred from " + Cmd.Filename;
return Result;
}
private:
- // Determine whether the given command line is intended for the CL driver.
- static bool checkIsCLMode(ArrayRef<std::string> CmdLine) {
- // First look for --driver-mode.
- for (StringRef S : llvm::reverse(CmdLine)) {
- if (S.consume_front("--driver-mode="))
- return S == "cl";
- }
-
- // Otherwise just check the clang executable file name.
- return !CmdLine.empty() &&
- llvm::sys::path::stem(CmdLine.front()).endswith_lower("cl");
- }
-
// Map the language from the --std flag to that of the -x flag.
static types::ID toType(Language Lang) {
switch (Lang) {
@@ -521,7 +519,7 @@ public:
Inner->getCompileCommands(Index.chooseProxy(Filename, foldType(Lang)));
if (ProxyCommands.empty())
return {};
- return {TransferableCommand(ProxyCommands[0]).transferTo(Filename)};
+ return {transferCompileCommand(std::move(ProxyCommands.front()), Filename)};
}
std::vector<std::string> getAllFiles() const override {
@@ -544,5 +542,10 @@ inferMissingCompileCommands(std::unique_ptr<CompilationDatabase> Inner) {
return std::make_unique<InterpolatingCompilationDatabase>(std::move(Inner));
}
+tooling::CompileCommand transferCompileCommand(CompileCommand Cmd,
+ StringRef Filename) {
+ return TransferableCommand(std::move(Cmd)).transferTo(Filename);
+}
+
} // namespace tooling
} // namespace clang