summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/bindings/python/tests/cindex/test_cdb.py14
-rw-r--r--clang/include/clang/Tooling/CompilationDatabase.h6
-rw-r--r--clang/lib/Tooling/CMakeLists.txt1
-rw-r--r--clang/lib/Tooling/GuessTargetAndModeCompilationDatabase.cpp57
-rw-r--r--clang/lib/Tooling/JSONCompilationDatabase.cpp6
-rw-r--r--clang/unittests/Tooling/CompilationDatabaseTest.cpp36
6 files changed, 110 insertions, 10 deletions
diff --git a/clang/bindings/python/tests/cindex/test_cdb.py b/clang/bindings/python/tests/cindex/test_cdb.py
index e2a48f14cde..99bc72143be 100644
--- a/clang/bindings/python/tests/cindex/test_cdb.py
+++ b/clang/bindings/python/tests/cindex/test_cdb.py
@@ -63,15 +63,16 @@ class TestCDB(unittest.TestCase):
expected = [
{ 'wd': '/home/john.doe/MyProject',
'file': '/home/john.doe/MyProject/project.cpp',
- 'line': ['clang++', '-o', 'project.o', '-c',
+ 'line': ['clang++', '--driver-mode=g++', '-o', 'project.o', '-c',
'/home/john.doe/MyProject/project.cpp']},
{ 'wd': '/home/john.doe/MyProjectA',
'file': '/home/john.doe/MyProject/project2.cpp',
- 'line': ['clang++', '-o', 'project2.o', '-c',
+ 'line': ['clang++', '--driver-mode=g++', '-o', 'project2.o', '-c',
'/home/john.doe/MyProject/project2.cpp']},
{ 'wd': '/home/john.doe/MyProjectB',
'file': '/home/john.doe/MyProject/project2.cpp',
- 'line': ['clang++', '-DFEATURE=1', '-o', 'project2-feature.o', '-c',
+ 'line': ['clang++', '--driver-mode=g++', '-DFEATURE=1', '-o',
+ 'project2-feature.o', '-c',
'/home/john.doe/MyProject/project2.cpp']},
]
@@ -89,7 +90,7 @@ class TestCDB(unittest.TestCase):
self.assertEqual(len(cmds), 1)
self.assertEqual(cmds[0].directory, os.path.dirname(file))
self.assertEqual(cmds[0].filename, file)
- expected = [ 'clang++', '-o', 'project.o', '-c',
+ expected = [ 'clang++', '--driver-mode=g++', '-o', 'project.o', '-c',
'/home/john.doe/MyProject/project.cpp']
for arg, exp in zip(cmds[0].arguments, expected):
self.assertEqual(arg, exp)
@@ -101,10 +102,11 @@ class TestCDB(unittest.TestCase):
self.assertEqual(len(cmds), 2)
expected = [
{ 'wd': '/home/john.doe/MyProjectA',
- 'line': ['clang++', '-o', 'project2.o', '-c',
+ 'line': ['clang++', '--driver-mode=g++', '-o', 'project2.o', '-c',
'/home/john.doe/MyProject/project2.cpp']},
{ 'wd': '/home/john.doe/MyProjectB',
- 'line': ['clang++', '-DFEATURE=1', '-o', 'project2-feature.o', '-c',
+ 'line': ['clang++', '--driver-mode=g++', '-DFEATURE=1', '-o',
+ 'project2-feature.o', '-c',
'/home/john.doe/MyProject/project2.cpp']}
]
for i in range(len(cmds)):
diff --git a/clang/include/clang/Tooling/CompilationDatabase.h b/clang/include/clang/Tooling/CompilationDatabase.h
index 01f6e679a05..dea046a2dc7 100644
--- a/clang/include/clang/Tooling/CompilationDatabase.h
+++ b/clang/include/clang/Tooling/CompilationDatabase.h
@@ -213,6 +213,12 @@ private:
std::unique_ptr<CompilationDatabase>
inferMissingCompileCommands(std::unique_ptr<CompilationDatabase>);
+/// Returns a wrapped CompilationDatabase that will add -target and -mode flags
+/// to commandline when they can be deduced from argv[0] of commandline returned
+/// by underlying database.
+std::unique_ptr<CompilationDatabase>
+inferTargetAndDriverMode(std::unique_ptr<CompilationDatabase> Base);
+
} // namespace tooling
} // namespace clang
diff --git a/clang/lib/Tooling/CMakeLists.txt b/clang/lib/Tooling/CMakeLists.txt
index 6ed2f25acda..5a380fb8cce 100644
--- a/clang/lib/Tooling/CMakeLists.txt
+++ b/clang/lib/Tooling/CMakeLists.txt
@@ -17,6 +17,7 @@ add_clang_library(clangTooling
Execution.cpp
FileMatchTrie.cpp
FixIt.cpp
+ GuessTargetAndModeCompilationDatabase.cpp
InterpolatingCompilationDatabase.cpp
JSONCompilationDatabase.cpp
Refactoring.cpp
diff --git a/clang/lib/Tooling/GuessTargetAndModeCompilationDatabase.cpp b/clang/lib/Tooling/GuessTargetAndModeCompilationDatabase.cpp
new file mode 100644
index 00000000000..ac3faf1b01f
--- /dev/null
+++ b/clang/lib/Tooling/GuessTargetAndModeCompilationDatabase.cpp
@@ -0,0 +1,57 @@
+//===- GuessTargetAndModeCompilationDatabase.cpp --------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/CompilationDatabase.h"
+#include "clang/Tooling/Tooling.h"
+#include <memory>
+
+namespace clang {
+namespace tooling {
+
+namespace {
+class TargetAndModeAdderDatabase : public CompilationDatabase {
+public:
+ TargetAndModeAdderDatabase(std::unique_ptr<CompilationDatabase> Base)
+ : Base(std::move(Base)) {
+ assert(this->Base != nullptr);
+ }
+
+ std::vector<std::string> getAllFiles() const override {
+ return Base->getAllFiles();
+ }
+
+ std::vector<CompileCommand> getAllCompileCommands() const override {
+ return addTargetAndMode(Base->getAllCompileCommands());
+ }
+
+ std::vector<CompileCommand>
+ getCompileCommands(StringRef FilePath) const override {
+ return addTargetAndMode(Base->getCompileCommands(FilePath));
+ }
+
+private:
+ std::vector<CompileCommand>
+ addTargetAndMode(std::vector<CompileCommand> Cmds) const {
+ for (auto &Cmd : Cmds) {
+ if (Cmd.CommandLine.empty())
+ continue;
+ addTargetAndModeForProgramName(Cmd.CommandLine, Cmd.CommandLine.front());
+ }
+ return Cmds;
+ }
+ std::unique_ptr<CompilationDatabase> Base;
+};
+} // namespace
+
+std::unique_ptr<CompilationDatabase>
+inferTargetAndDriverMode(std::unique_ptr<CompilationDatabase> Base) {
+ return llvm::make_unique<TargetAndModeAdderDatabase>(std::move(Base));
+}
+
+} // namespace tooling
+} // namespace clang
diff --git a/clang/lib/Tooling/JSONCompilationDatabase.cpp b/clang/lib/Tooling/JSONCompilationDatabase.cpp
index 0ee9d174b44..76a82b0fd9b 100644
--- a/clang/lib/Tooling/JSONCompilationDatabase.cpp
+++ b/clang/lib/Tooling/JSONCompilationDatabase.cpp
@@ -14,7 +14,9 @@
#include "clang/Basic/LLVM.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/CompilationDatabasePluginRegistry.h"
+#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -165,7 +167,9 @@ class JSONCompilationDatabasePlugin : public CompilationDatabasePlugin {
llvm::sys::path::append(JSONDatabasePath, "compile_commands.json");
auto Base = JSONCompilationDatabase::loadFromFile(
JSONDatabasePath, ErrorMessage, JSONCommandLineSyntax::AutoDetect);
- return Base ? inferMissingCompileCommands(std::move(Base)) : nullptr;
+ return Base ? inferTargetAndDriverMode(
+ inferMissingCompileCommands(std::move(Base)))
+ : nullptr;
}
};
diff --git a/clang/unittests/Tooling/CompilationDatabaseTest.cpp b/clang/unittests/Tooling/CompilationDatabaseTest.cpp
index 19b797a0a64..d86c9bf79a2 100644
--- a/clang/unittests/Tooling/CompilationDatabaseTest.cpp
+++ b/clang/unittests/Tooling/CompilationDatabaseTest.cpp
@@ -9,10 +9,12 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclGroup.h"
#include "clang/Frontend/FrontendAction.h"
+#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/FileMatchTrie.h"
#include "clang/Tooling/JSONCompilationDatabase.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/TargetSelect.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@@ -632,7 +634,7 @@ struct MemCDB : public CompilationDatabase {
}
};
-class InterpolateTest : public ::testing::Test {
+class MemDBTest : public ::testing::Test {
protected:
// Adds an entry to the underlying compilation database.
// A flag is injected: -D <File>, so the command used can be identified.
@@ -658,6 +660,11 @@ protected:
return Result.str();
}
+ MemCDB::EntryMap Entries;
+};
+
+class InterpolateTest : public MemDBTest {
+protected:
// Look up the command from a relative path, and return it in string form.
// The input file is not included in the returned command.
std::string getCommand(llvm::StringRef F) {
@@ -693,8 +700,6 @@ protected:
llvm::sys::path::native(Result, llvm::sys::path::Style::posix);
return Result.str();
}
-
- MemCDB::EntryMap Entries;
};
TEST_F(InterpolateTest, Nearby) {
@@ -804,5 +809,30 @@ TEST(CompileCommandTest, EqualityOperator) {
EXPECT_TRUE(CCRef != CCTest);
}
+class TargetAndModeTest : public MemDBTest {
+public:
+ TargetAndModeTest() { llvm::InitializeAllTargetInfos(); }
+
+protected:
+ // Look up the command from a relative path, and return it in string form.
+ std::string getCommand(llvm::StringRef F) {
+ auto Results = inferTargetAndDriverMode(llvm::make_unique<MemCDB>(Entries))
+ ->getCompileCommands(path(F));
+ if (Results.empty())
+ return "none";
+ return llvm::join(Results[0].CommandLine, " ");
+ }
+};
+
+TEST_F(TargetAndModeTest, TargetAndMode) {
+ add("foo.cpp", "clang-cl", "");
+ add("bar.cpp", "x86_64-linux-clang", "");
+
+ EXPECT_EQ(getCommand("foo.cpp"),
+ "clang-cl --driver-mode=cl foo.cpp -D foo.cpp");
+ EXPECT_EQ(getCommand("bar.cpp"),
+ "x86_64-linux-clang -target x86_64-linux bar.cpp -D bar.cpp");
+}
+
} // end namespace tooling
} // end namespace clang
OpenPOWER on IntegriCloud