2018-04-20 19:35:17 +08:00
|
|
|
//===-- GlobalCompilationDatabaseTests.cpp ----------------------*- C++ -*-===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// 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
|
2018-04-20 19:35:17 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "GlobalCompilationDatabase.h"
|
|
|
|
|
2021-01-21 01:35:11 +08:00
|
|
|
#include "Config.h"
|
2020-04-22 20:24:12 +08:00
|
|
|
#include "Matchers.h"
|
2018-04-20 19:35:17 +08:00
|
|
|
#include "TestFS.h"
|
[clangd] Move non-clang base pieces into separate support/ lib. NFCI
Summary:
This enforces layering, reduces a sprawling clangd/ directory, and makes life
easier for embedders.
Reviewers: kbobyrev
Subscribers: mgorny, ilya-biryukov, javed.absar, MaskRay, jkorous, arphaman, jfb, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D79014
2020-04-28 23:49:17 +08:00
|
|
|
#include "support/Path.h"
|
2020-12-04 16:09:03 +08:00
|
|
|
#include "support/ThreadsafeFS.h"
|
2019-07-19 00:13:23 +08:00
|
|
|
#include "clang/Tooling/CompilationDatabase.h"
|
2019-07-11 17:54:31 +08:00
|
|
|
#include "llvm/ADT/Optional.h"
|
2020-12-04 16:09:03 +08:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
2019-07-11 17:54:31 +08:00
|
|
|
#include "llvm/ADT/SmallString.h"
|
2018-04-20 19:35:17 +08:00
|
|
|
#include "llvm/ADT/StringExtras.h"
|
2019-07-11 17:54:31 +08:00
|
|
|
#include "llvm/ADT/StringRef.h"
|
|
|
|
#include "llvm/Support/FileSystem.h"
|
|
|
|
#include "llvm/Support/FormatVariadic.h"
|
|
|
|
#include "llvm/Support/MemoryBuffer.h"
|
|
|
|
#include "llvm/Support/Path.h"
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2018-04-20 19:35:17 +08:00
|
|
|
#include "gmock/gmock.h"
|
|
|
|
#include "gtest/gtest.h"
|
2020-12-04 16:09:03 +08:00
|
|
|
#include <chrono>
|
2019-07-11 17:54:31 +08:00
|
|
|
#include <fstream>
|
|
|
|
#include <string>
|
2018-04-20 19:35:17 +08:00
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
namespace clangd {
|
|
|
|
namespace {
|
[clangd] Adjust compile commands to be applicable for tooling
Summary:
As can be seen in https://github.com/llvm-mirror/clang/blob/master/lib/Tooling/Tooling.cpp#L385
clang tool invocations adjust commands normally like this. In clangd we have
different code paths for invoking a frontend action(preamble builds, ast builds,
background index, clangd-indexer) they all work on the same GlobalCompilationDatabase
abstraction, but later on are subject to different modifications.
This patch makes sure all of the clangd actions make use of the same compile
commands before invocation.
Enables background-index to work on chromium codebase(since they had dependency
file output in their compile commands).
Reviewers: gribozavr, hokein
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59086
llvm-svn: 355669
2019-03-08 16:38:25 +08:00
|
|
|
using ::testing::AllOf;
|
|
|
|
using ::testing::Contains;
|
2018-04-20 19:35:17 +08:00
|
|
|
using ::testing::ElementsAre;
|
2019-01-07 20:35:02 +08:00
|
|
|
using ::testing::EndsWith;
|
2019-07-19 00:13:23 +08:00
|
|
|
using ::testing::HasSubstr;
|
2019-07-11 17:54:31 +08:00
|
|
|
using ::testing::IsEmpty;
|
[clangd] Adjust compile commands to be applicable for tooling
Summary:
As can be seen in https://github.com/llvm-mirror/clang/blob/master/lib/Tooling/Tooling.cpp#L385
clang tool invocations adjust commands normally like this. In clangd we have
different code paths for invoking a frontend action(preamble builds, ast builds,
background index, clangd-indexer) they all work on the same GlobalCompilationDatabase
abstraction, but later on are subject to different modifications.
This patch makes sure all of the clangd actions make use of the same compile
commands before invocation.
Enables background-index to work on chromium codebase(since they had dependency
file output in their compile commands).
Reviewers: gribozavr, hokein
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59086
llvm-svn: 355669
2019-03-08 16:38:25 +08:00
|
|
|
using ::testing::Not;
|
2019-06-04 21:38:36 +08:00
|
|
|
using ::testing::StartsWith;
|
2019-07-11 17:54:31 +08:00
|
|
|
using ::testing::UnorderedElementsAre;
|
2018-04-20 19:35:17 +08:00
|
|
|
|
|
|
|
TEST(GlobalCompilationDatabaseTest, FallbackCommand) {
|
2020-12-04 16:09:03 +08:00
|
|
|
MockFS TFS;
|
|
|
|
DirectoryBasedGlobalCompilationDatabase DB(TFS);
|
2018-04-20 19:35:17 +08:00
|
|
|
auto Cmd = DB.getFallbackCommand(testPath("foo/bar.cc"));
|
|
|
|
EXPECT_EQ(Cmd.Directory, testPath("foo"));
|
[clangd] (take 2) Try harder to find a plausible `clang` as argv0, particularly on Mac.
Summary:
This was originally committed in 88bccded8fa169481fa367debf5ec615640635a1,
and reverted in 93f77617abba512d2861e2fc50ce385883f587b6.
This version is now much more testable: the "detect toolchain properties" part
is still not tested but also not active in tests.
All the command manipulation based on the detected properties is
directly tested, and also not active in other tests.
Fixes https://github.com/clangd/clangd/issues/211
Fixes https://github.com/clangd/clangd/issues/178
Reviewers: kbobyrev, ilya-biryukov
Subscribers: mgorny, ormris, cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71029
2019-11-30 02:37:48 +08:00
|
|
|
EXPECT_THAT(Cmd.CommandLine, ElementsAre("clang", testPath("foo/bar.cc")));
|
2018-04-20 19:35:17 +08:00
|
|
|
EXPECT_EQ(Cmd.Output, "");
|
|
|
|
|
|
|
|
// .h files have unknown language, so they are parsed liberally as obj-c++.
|
|
|
|
Cmd = DB.getFallbackCommand(testPath("foo/bar.h"));
|
[clangd] (take 2) Try harder to find a plausible `clang` as argv0, particularly on Mac.
Summary:
This was originally committed in 88bccded8fa169481fa367debf5ec615640635a1,
and reverted in 93f77617abba512d2861e2fc50ce385883f587b6.
This version is now much more testable: the "detect toolchain properties" part
is still not tested but also not active in tests.
All the command manipulation based on the detected properties is
directly tested, and also not active in other tests.
Fixes https://github.com/clangd/clangd/issues/211
Fixes https://github.com/clangd/clangd/issues/178
Reviewers: kbobyrev, ilya-biryukov
Subscribers: mgorny, ormris, cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71029
2019-11-30 02:37:48 +08:00
|
|
|
EXPECT_THAT(Cmd.CommandLine, ElementsAre("clang", "-xobjective-c++-header",
|
|
|
|
testPath("foo/bar.h")));
|
2019-06-18 19:54:17 +08:00
|
|
|
Cmd = DB.getFallbackCommand(testPath("foo/bar"));
|
[clangd] (take 2) Try harder to find a plausible `clang` as argv0, particularly on Mac.
Summary:
This was originally committed in 88bccded8fa169481fa367debf5ec615640635a1,
and reverted in 93f77617abba512d2861e2fc50ce385883f587b6.
This version is now much more testable: the "detect toolchain properties" part
is still not tested but also not active in tests.
All the command manipulation based on the detected properties is
directly tested, and also not active in other tests.
Fixes https://github.com/clangd/clangd/issues/211
Fixes https://github.com/clangd/clangd/issues/178
Reviewers: kbobyrev, ilya-biryukov
Subscribers: mgorny, ormris, cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71029
2019-11-30 02:37:48 +08:00
|
|
|
EXPECT_THAT(Cmd.CommandLine, ElementsAre("clang", "-xobjective-c++-header",
|
|
|
|
testPath("foo/bar")));
|
2018-04-20 19:35:17 +08:00
|
|
|
}
|
|
|
|
|
2019-01-07 23:45:19 +08:00
|
|
|
static tooling::CompileCommand cmd(llvm::StringRef File, llvm::StringRef Arg) {
|
2020-01-29 03:23:46 +08:00
|
|
|
return tooling::CompileCommand(
|
|
|
|
testRoot(), File, {"clang", std::string(Arg), std::string(File)}, "");
|
2018-11-02 21:09:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
class OverlayCDBTest : public ::testing::Test {
|
|
|
|
class BaseCDB : public GlobalCompilationDatabase {
|
|
|
|
public:
|
2019-01-07 23:45:19 +08:00
|
|
|
llvm::Optional<tooling::CompileCommand>
|
2019-07-11 17:54:31 +08:00
|
|
|
getCompileCommand(llvm::StringRef File) const override {
|
|
|
|
if (File == testPath("foo.cc"))
|
2018-11-02 21:09:36 +08:00
|
|
|
return cmd(File, "-DA=1");
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
2019-01-07 23:45:19 +08:00
|
|
|
tooling::CompileCommand
|
|
|
|
getFallbackCommand(llvm::StringRef File) const override {
|
2018-11-02 21:09:36 +08:00
|
|
|
return cmd(File, "-DA=2");
|
|
|
|
}
|
2019-07-11 17:54:31 +08:00
|
|
|
|
|
|
|
llvm::Optional<ProjectInfo> getProjectInfo(PathRef File) const override {
|
|
|
|
return ProjectInfo{testRoot()};
|
|
|
|
}
|
2018-11-02 21:09:36 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
protected:
|
2019-08-15 07:52:23 +08:00
|
|
|
OverlayCDBTest() : Base(std::make_unique<BaseCDB>()) {}
|
2018-11-02 21:09:36 +08:00
|
|
|
std::unique_ptr<GlobalCompilationDatabase> Base;
|
|
|
|
};
|
|
|
|
|
|
|
|
TEST_F(OverlayCDBTest, GetCompileCommand) {
|
[clangd] (take 2) Try harder to find a plausible `clang` as argv0, particularly on Mac.
Summary:
This was originally committed in 88bccded8fa169481fa367debf5ec615640635a1,
and reverted in 93f77617abba512d2861e2fc50ce385883f587b6.
This version is now much more testable: the "detect toolchain properties" part
is still not tested but also not active in tests.
All the command manipulation based on the detected properties is
directly tested, and also not active in other tests.
Fixes https://github.com/clangd/clangd/issues/211
Fixes https://github.com/clangd/clangd/issues/178
Reviewers: kbobyrev, ilya-biryukov
Subscribers: mgorny, ormris, cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71029
2019-11-30 02:37:48 +08:00
|
|
|
OverlayCDB CDB(Base.get());
|
[clangd] Adjust compile commands to be applicable for tooling
Summary:
As can be seen in https://github.com/llvm-mirror/clang/blob/master/lib/Tooling/Tooling.cpp#L385
clang tool invocations adjust commands normally like this. In clangd we have
different code paths for invoking a frontend action(preamble builds, ast builds,
background index, clangd-indexer) they all work on the same GlobalCompilationDatabase
abstraction, but later on are subject to different modifications.
This patch makes sure all of the clangd actions make use of the same compile
commands before invocation.
Enables background-index to work on chromium codebase(since they had dependency
file output in their compile commands).
Reviewers: gribozavr, hokein
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59086
llvm-svn: 355669
2019-03-08 16:38:25 +08:00
|
|
|
EXPECT_THAT(CDB.getCompileCommand(testPath("foo.cc"))->CommandLine,
|
|
|
|
AllOf(Contains(testPath("foo.cc")), Contains("-DA=1")));
|
2018-11-02 21:09:36 +08:00
|
|
|
EXPECT_EQ(CDB.getCompileCommand(testPath("missing.cc")), llvm::None);
|
|
|
|
|
|
|
|
auto Override = cmd(testPath("foo.cc"), "-DA=3");
|
|
|
|
CDB.setCompileCommand(testPath("foo.cc"), Override);
|
[clangd] Adjust compile commands to be applicable for tooling
Summary:
As can be seen in https://github.com/llvm-mirror/clang/blob/master/lib/Tooling/Tooling.cpp#L385
clang tool invocations adjust commands normally like this. In clangd we have
different code paths for invoking a frontend action(preamble builds, ast builds,
background index, clangd-indexer) they all work on the same GlobalCompilationDatabase
abstraction, but later on are subject to different modifications.
This patch makes sure all of the clangd actions make use of the same compile
commands before invocation.
Enables background-index to work on chromium codebase(since they had dependency
file output in their compile commands).
Reviewers: gribozavr, hokein
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59086
llvm-svn: 355669
2019-03-08 16:38:25 +08:00
|
|
|
EXPECT_THAT(CDB.getCompileCommand(testPath("foo.cc"))->CommandLine,
|
|
|
|
Contains("-DA=3"));
|
2018-11-02 21:09:36 +08:00
|
|
|
EXPECT_EQ(CDB.getCompileCommand(testPath("missing.cc")), llvm::None);
|
|
|
|
CDB.setCompileCommand(testPath("missing.cc"), Override);
|
[clangd] Adjust compile commands to be applicable for tooling
Summary:
As can be seen in https://github.com/llvm-mirror/clang/blob/master/lib/Tooling/Tooling.cpp#L385
clang tool invocations adjust commands normally like this. In clangd we have
different code paths for invoking a frontend action(preamble builds, ast builds,
background index, clangd-indexer) they all work on the same GlobalCompilationDatabase
abstraction, but later on are subject to different modifications.
This patch makes sure all of the clangd actions make use of the same compile
commands before invocation.
Enables background-index to work on chromium codebase(since they had dependency
file output in their compile commands).
Reviewers: gribozavr, hokein
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59086
llvm-svn: 355669
2019-03-08 16:38:25 +08:00
|
|
|
EXPECT_THAT(CDB.getCompileCommand(testPath("missing.cc"))->CommandLine,
|
|
|
|
Contains("-DA=3"));
|
2018-11-02 21:09:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(OverlayCDBTest, GetFallbackCommand) {
|
|
|
|
OverlayCDB CDB(Base.get(), {"-DA=4"});
|
2019-12-03 05:12:23 +08:00
|
|
|
EXPECT_THAT(CDB.getFallbackCommand(testPath("bar.cc")).CommandLine,
|
[clangd] (take 2) Try harder to find a plausible `clang` as argv0, particularly on Mac.
Summary:
This was originally committed in 88bccded8fa169481fa367debf5ec615640635a1,
and reverted in 93f77617abba512d2861e2fc50ce385883f587b6.
This version is now much more testable: the "detect toolchain properties" part
is still not tested but also not active in tests.
All the command manipulation based on the detected properties is
directly tested, and also not active in other tests.
Fixes https://github.com/clangd/clangd/issues/211
Fixes https://github.com/clangd/clangd/issues/178
Reviewers: kbobyrev, ilya-biryukov
Subscribers: mgorny, ormris, cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71029
2019-11-30 02:37:48 +08:00
|
|
|
ElementsAre("clang", "-DA=2", testPath("bar.cc"), "-DA=4"));
|
2018-11-02 21:09:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(OverlayCDBTest, NoBase) {
|
[clangd] (take 2) Try harder to find a plausible `clang` as argv0, particularly on Mac.
Summary:
This was originally committed in 88bccded8fa169481fa367debf5ec615640635a1,
and reverted in 93f77617abba512d2861e2fc50ce385883f587b6.
This version is now much more testable: the "detect toolchain properties" part
is still not tested but also not active in tests.
All the command manipulation based on the detected properties is
directly tested, and also not active in other tests.
Fixes https://github.com/clangd/clangd/issues/211
Fixes https://github.com/clangd/clangd/issues/178
Reviewers: kbobyrev, ilya-biryukov
Subscribers: mgorny, ormris, cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71029
2019-11-30 02:37:48 +08:00
|
|
|
OverlayCDB CDB(nullptr, {"-DA=6"});
|
2018-11-02 21:09:36 +08:00
|
|
|
EXPECT_EQ(CDB.getCompileCommand(testPath("bar.cc")), None);
|
|
|
|
auto Override = cmd(testPath("bar.cc"), "-DA=5");
|
|
|
|
CDB.setCompileCommand(testPath("bar.cc"), Override);
|
[clangd] Adjust compile commands to be applicable for tooling
Summary:
As can be seen in https://github.com/llvm-mirror/clang/blob/master/lib/Tooling/Tooling.cpp#L385
clang tool invocations adjust commands normally like this. In clangd we have
different code paths for invoking a frontend action(preamble builds, ast builds,
background index, clangd-indexer) they all work on the same GlobalCompilationDatabase
abstraction, but later on are subject to different modifications.
This patch makes sure all of the clangd actions make use of the same compile
commands before invocation.
Enables background-index to work on chromium codebase(since they had dependency
file output in their compile commands).
Reviewers: gribozavr, hokein
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59086
llvm-svn: 355669
2019-03-08 16:38:25 +08:00
|
|
|
EXPECT_THAT(CDB.getCompileCommand(testPath("bar.cc"))->CommandLine,
|
|
|
|
Contains("-DA=5"));
|
2018-11-02 21:09:36 +08:00
|
|
|
|
2019-12-03 05:12:23 +08:00
|
|
|
EXPECT_THAT(CDB.getFallbackCommand(testPath("foo.cc")).CommandLine,
|
[clangd] (take 2) Try harder to find a plausible `clang` as argv0, particularly on Mac.
Summary:
This was originally committed in 88bccded8fa169481fa367debf5ec615640635a1,
and reverted in 93f77617abba512d2861e2fc50ce385883f587b6.
This version is now much more testable: the "detect toolchain properties" part
is still not tested but also not active in tests.
All the command manipulation based on the detected properties is
directly tested, and also not active in other tests.
Fixes https://github.com/clangd/clangd/issues/211
Fixes https://github.com/clangd/clangd/issues/178
Reviewers: kbobyrev, ilya-biryukov
Subscribers: mgorny, ormris, cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71029
2019-11-30 02:37:48 +08:00
|
|
|
ElementsAre("clang", testPath("foo.cc"), "-DA=6"));
|
2018-11-02 21:09:36 +08:00
|
|
|
}
|
|
|
|
|
2018-11-20 18:56:03 +08:00
|
|
|
TEST_F(OverlayCDBTest, Watch) {
|
|
|
|
OverlayCDB Inner(nullptr);
|
|
|
|
OverlayCDB Outer(&Inner);
|
|
|
|
|
|
|
|
std::vector<std::vector<std::string>> Changes;
|
|
|
|
auto Sub = Outer.watch([&](const std::vector<std::string> &ChangedFiles) {
|
|
|
|
Changes.push_back(ChangedFiles);
|
|
|
|
});
|
|
|
|
|
|
|
|
Inner.setCompileCommand("A.cpp", tooling::CompileCommand());
|
|
|
|
Outer.setCompileCommand("B.cpp", tooling::CompileCommand());
|
|
|
|
Inner.setCompileCommand("A.cpp", llvm::None);
|
|
|
|
Outer.setCompileCommand("C.cpp", llvm::None);
|
|
|
|
EXPECT_THAT(Changes, ElementsAre(ElementsAre("A.cpp"), ElementsAre("B.cpp"),
|
|
|
|
ElementsAre("A.cpp"), ElementsAre("C.cpp")));
|
|
|
|
}
|
|
|
|
|
[clangd] Adjust compile commands to be applicable for tooling
Summary:
As can be seen in https://github.com/llvm-mirror/clang/blob/master/lib/Tooling/Tooling.cpp#L385
clang tool invocations adjust commands normally like this. In clangd we have
different code paths for invoking a frontend action(preamble builds, ast builds,
background index, clangd-indexer) they all work on the same GlobalCompilationDatabase
abstraction, but later on are subject to different modifications.
This patch makes sure all of the clangd actions make use of the same compile
commands before invocation.
Enables background-index to work on chromium codebase(since they had dependency
file output in their compile commands).
Reviewers: gribozavr, hokein
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59086
llvm-svn: 355669
2019-03-08 16:38:25 +08:00
|
|
|
TEST_F(OverlayCDBTest, Adjustments) {
|
[clangd] (take 2) Try harder to find a plausible `clang` as argv0, particularly on Mac.
Summary:
This was originally committed in 88bccded8fa169481fa367debf5ec615640635a1,
and reverted in 93f77617abba512d2861e2fc50ce385883f587b6.
This version is now much more testable: the "detect toolchain properties" part
is still not tested but also not active in tests.
All the command manipulation based on the detected properties is
directly tested, and also not active in other tests.
Fixes https://github.com/clangd/clangd/issues/211
Fixes https://github.com/clangd/clangd/issues/178
Reviewers: kbobyrev, ilya-biryukov
Subscribers: mgorny, ormris, cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71029
2019-11-30 02:37:48 +08:00
|
|
|
OverlayCDB CDB(Base.get(), {"-DFallback"},
|
|
|
|
[](const std::vector<std::string> &Cmd, llvm::StringRef File) {
|
|
|
|
auto Ret = Cmd;
|
|
|
|
Ret.push_back(
|
|
|
|
("-DAdjust_" + llvm::sys::path::filename(File)).str());
|
|
|
|
return Ret;
|
|
|
|
});
|
|
|
|
// Command from underlying gets adjusted.
|
[clangd] Adjust compile commands to be applicable for tooling
Summary:
As can be seen in https://github.com/llvm-mirror/clang/blob/master/lib/Tooling/Tooling.cpp#L385
clang tool invocations adjust commands normally like this. In clangd we have
different code paths for invoking a frontend action(preamble builds, ast builds,
background index, clangd-indexer) they all work on the same GlobalCompilationDatabase
abstraction, but later on are subject to different modifications.
This patch makes sure all of the clangd actions make use of the same compile
commands before invocation.
Enables background-index to work on chromium codebase(since they had dependency
file output in their compile commands).
Reviewers: gribozavr, hokein
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59086
llvm-svn: 355669
2019-03-08 16:38:25 +08:00
|
|
|
auto Cmd = CDB.getCompileCommand(testPath("foo.cc")).getValue();
|
[clangd] (take 2) Try harder to find a plausible `clang` as argv0, particularly on Mac.
Summary:
This was originally committed in 88bccded8fa169481fa367debf5ec615640635a1,
and reverted in 93f77617abba512d2861e2fc50ce385883f587b6.
This version is now much more testable: the "detect toolchain properties" part
is still not tested but also not active in tests.
All the command manipulation based on the detected properties is
directly tested, and also not active in other tests.
Fixes https://github.com/clangd/clangd/issues/211
Fixes https://github.com/clangd/clangd/issues/178
Reviewers: kbobyrev, ilya-biryukov
Subscribers: mgorny, ormris, cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71029
2019-11-30 02:37:48 +08:00
|
|
|
EXPECT_THAT(Cmd.CommandLine, ElementsAre("clang", "-DA=1", testPath("foo.cc"),
|
|
|
|
"-DAdjust_foo.cc"));
|
|
|
|
|
|
|
|
// Command from overlay gets adjusted.
|
|
|
|
tooling::CompileCommand BarCommand;
|
|
|
|
BarCommand.Filename = testPath("bar.cc");
|
|
|
|
BarCommand.CommandLine = {"clang++", "-DB=1", testPath("bar.cc")};
|
|
|
|
CDB.setCompileCommand(testPath("bar.cc"), BarCommand);
|
|
|
|
Cmd = CDB.getCompileCommand(testPath("bar.cc")).getValue();
|
|
|
|
EXPECT_THAT(
|
|
|
|
Cmd.CommandLine,
|
|
|
|
ElementsAre("clang++", "-DB=1", testPath("bar.cc"), "-DAdjust_bar.cc"));
|
|
|
|
|
|
|
|
// Fallback gets adjusted.
|
|
|
|
Cmd = CDB.getFallbackCommand("baz.cc");
|
|
|
|
EXPECT_THAT(Cmd.CommandLine, ElementsAre("clang", "-DA=2", "baz.cc",
|
|
|
|
"-DFallback", "-DAdjust_baz.cc"));
|
[clangd] Adjust compile commands to be applicable for tooling
Summary:
As can be seen in https://github.com/llvm-mirror/clang/blob/master/lib/Tooling/Tooling.cpp#L385
clang tool invocations adjust commands normally like this. In clangd we have
different code paths for invoking a frontend action(preamble builds, ast builds,
background index, clangd-indexer) they all work on the same GlobalCompilationDatabase
abstraction, but later on are subject to different modifications.
This patch makes sure all of the clangd actions make use of the same compile
commands before invocation.
Enables background-index to work on chromium codebase(since they had dependency
file output in their compile commands).
Reviewers: gribozavr, hokein
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59086
llvm-svn: 355669
2019-03-08 16:38:25 +08:00
|
|
|
}
|
|
|
|
|
2019-07-11 17:54:31 +08:00
|
|
|
TEST(GlobalCompilationDatabaseTest, DiscoveryWithNestedCDBs) {
|
|
|
|
const char *const CDBOuter =
|
|
|
|
R"cdb(
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"file": "a.cc",
|
|
|
|
"command": "",
|
|
|
|
"directory": "{0}",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"file": "build/gen.cc",
|
|
|
|
"command": "",
|
|
|
|
"directory": "{0}",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"file": "build/gen2.cc",
|
|
|
|
"command": "",
|
|
|
|
"directory": "{0}",
|
|
|
|
}
|
|
|
|
]
|
|
|
|
)cdb";
|
|
|
|
const char *const CDBInner =
|
|
|
|
R"cdb(
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"file": "gen.cc",
|
|
|
|
"command": "",
|
|
|
|
"directory": "{0}/build",
|
|
|
|
}
|
|
|
|
]
|
|
|
|
)cdb";
|
2021-01-12 00:14:26 +08:00
|
|
|
MockFS FS;
|
|
|
|
FS.Files[testPath("compile_commands.json")] =
|
|
|
|
llvm::formatv(CDBOuter, llvm::sys::path::convert_to_slash(testRoot()));
|
|
|
|
FS.Files[testPath("build/compile_commands.json")] =
|
|
|
|
llvm::formatv(CDBInner, llvm::sys::path::convert_to_slash(testRoot()));
|
2021-01-21 01:35:11 +08:00
|
|
|
FS.Files[testPath("foo/compile_flags.txt")] = "-DFOO";
|
2019-07-11 17:54:31 +08:00
|
|
|
|
|
|
|
// Note that gen2.cc goes missing with our following model, not sure this
|
|
|
|
// happens in practice though.
|
|
|
|
{
|
2021-01-21 01:35:11 +08:00
|
|
|
SCOPED_TRACE("Default ancestor scanning");
|
2021-01-12 00:14:26 +08:00
|
|
|
DirectoryBasedGlobalCompilationDatabase DB(FS);
|
2019-07-11 17:54:31 +08:00
|
|
|
std::vector<std::string> DiscoveredFiles;
|
|
|
|
auto Sub =
|
|
|
|
DB.watch([&DiscoveredFiles](const std::vector<std::string> Changes) {
|
|
|
|
DiscoveredFiles = Changes;
|
|
|
|
});
|
2019-07-11 18:41:58 +08:00
|
|
|
|
2021-01-12 00:14:26 +08:00
|
|
|
DB.getCompileCommand(testPath("build/../a.cc"));
|
2021-01-13 22:31:20 +08:00
|
|
|
ASSERT_TRUE(DB.blockUntilIdle(timeoutSeconds(10)));
|
2019-07-19 00:13:23 +08:00
|
|
|
EXPECT_THAT(DiscoveredFiles, UnorderedElementsAre(AllOf(
|
|
|
|
EndsWith("a.cc"), Not(HasSubstr("..")))));
|
2019-07-11 18:41:58 +08:00
|
|
|
DiscoveredFiles.clear();
|
2019-07-11 17:54:31 +08:00
|
|
|
|
2021-01-12 00:14:26 +08:00
|
|
|
DB.getCompileCommand(testPath("build/gen.cc"));
|
2021-01-13 22:31:20 +08:00
|
|
|
ASSERT_TRUE(DB.blockUntilIdle(timeoutSeconds(10)));
|
2019-07-11 17:54:31 +08:00
|
|
|
EXPECT_THAT(DiscoveredFiles, UnorderedElementsAre(EndsWith("gen.cc")));
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
2021-01-21 01:35:11 +08:00
|
|
|
SCOPED_TRACE("With config");
|
|
|
|
DirectoryBasedGlobalCompilationDatabase::Options Opts(FS);
|
|
|
|
Opts.ContextProvider = [&](llvm::StringRef Path) {
|
|
|
|
Config Cfg;
|
|
|
|
if (Path.endswith("a.cc")) {
|
|
|
|
// a.cc uses another directory's CDB, so it won't be discovered.
|
|
|
|
Cfg.CompileFlags.CDBSearch.Policy = Config::CDBSearchSpec::FixedDir;
|
|
|
|
Cfg.CompileFlags.CDBSearch.FixedCDBPath = testPath("foo");
|
|
|
|
} else if (Path.endswith("gen.cc")) {
|
|
|
|
// gen.cc has CDB search disabled, so it won't be discovered.
|
|
|
|
Cfg.CompileFlags.CDBSearch.Policy = Config::CDBSearchSpec::NoCDBSearch;
|
|
|
|
} else if (Path.endswith("gen2.cc")) {
|
|
|
|
// gen2.cc explicitly lists this directory, so it will be discovered.
|
|
|
|
Cfg.CompileFlags.CDBSearch.Policy = Config::CDBSearchSpec::FixedDir;
|
|
|
|
Cfg.CompileFlags.CDBSearch.FixedCDBPath = testRoot();
|
|
|
|
}
|
|
|
|
return Context::current().derive(Config::Key, std::move(Cfg));
|
|
|
|
};
|
|
|
|
DirectoryBasedGlobalCompilationDatabase DB(Opts);
|
|
|
|
std::vector<std::string> DiscoveredFiles;
|
|
|
|
auto Sub =
|
|
|
|
DB.watch([&DiscoveredFiles](const std::vector<std::string> Changes) {
|
|
|
|
DiscoveredFiles = Changes;
|
|
|
|
});
|
|
|
|
|
|
|
|
// Does not use the root CDB, so no broadcast.
|
|
|
|
auto Cmd = DB.getCompileCommand(testPath("build/../a.cc"));
|
|
|
|
ASSERT_TRUE(Cmd.hasValue());
|
|
|
|
EXPECT_THAT(Cmd->CommandLine, Contains("-DFOO")) << "a.cc uses foo/ CDB";
|
|
|
|
ASSERT_TRUE(DB.blockUntilIdle(timeoutSeconds(10)));
|
|
|
|
EXPECT_THAT(DiscoveredFiles, IsEmpty()) << "Root CDB not discovered yet";
|
|
|
|
|
|
|
|
// No special config for b.cc, so we trigger broadcast of the root CDB.
|
|
|
|
DB.getCompileCommand(testPath("b.cc"));
|
|
|
|
ASSERT_TRUE(DB.blockUntilIdle(timeoutSeconds(10)));
|
|
|
|
EXPECT_THAT(DiscoveredFiles, ElementsAre(testPath("build/gen2.cc")));
|
|
|
|
DiscoveredFiles.clear();
|
|
|
|
|
|
|
|
// No CDB search so no discovery/broadcast triggered for build/ CDB.
|
|
|
|
DB.getCompileCommand(testPath("build/gen.cc"));
|
|
|
|
ASSERT_TRUE(DB.blockUntilIdle(timeoutSeconds(10)));
|
|
|
|
EXPECT_THAT(DiscoveredFiles, IsEmpty());
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
SCOPED_TRACE("With custom compile commands dir");
|
2021-01-12 00:14:26 +08:00
|
|
|
DirectoryBasedGlobalCompilationDatabase::Options Opts(FS);
|
|
|
|
Opts.CompileCommandsDir = testRoot();
|
2020-12-04 16:09:03 +08:00
|
|
|
DirectoryBasedGlobalCompilationDatabase DB(Opts);
|
2019-07-11 17:54:31 +08:00
|
|
|
std::vector<std::string> DiscoveredFiles;
|
|
|
|
auto Sub =
|
|
|
|
DB.watch([&DiscoveredFiles](const std::vector<std::string> Changes) {
|
|
|
|
DiscoveredFiles = Changes;
|
|
|
|
});
|
2019-07-11 18:41:58 +08:00
|
|
|
|
2021-01-12 00:14:26 +08:00
|
|
|
DB.getCompileCommand(testPath("a.cc"));
|
2021-01-13 22:31:20 +08:00
|
|
|
ASSERT_TRUE(DB.blockUntilIdle(timeoutSeconds(10)));
|
2019-07-11 17:54:31 +08:00
|
|
|
EXPECT_THAT(DiscoveredFiles,
|
|
|
|
UnorderedElementsAre(EndsWith("a.cc"), EndsWith("gen.cc"),
|
|
|
|
EndsWith("gen2.cc")));
|
|
|
|
DiscoveredFiles.clear();
|
2019-07-11 18:41:58 +08:00
|
|
|
|
2021-01-12 00:14:26 +08:00
|
|
|
DB.getCompileCommand(testPath("build/gen.cc"));
|
2021-01-13 22:31:20 +08:00
|
|
|
ASSERT_TRUE(DB.blockUntilIdle(timeoutSeconds(10)));
|
2019-07-11 17:54:31 +08:00
|
|
|
EXPECT_THAT(DiscoveredFiles, IsEmpty());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-22 20:24:12 +08:00
|
|
|
TEST(GlobalCompilationDatabaseTest, BuildDir) {
|
2021-01-12 00:14:26 +08:00
|
|
|
MockFS FS;
|
2020-04-22 20:24:12 +08:00
|
|
|
auto Command = [&](llvm::StringRef Relative) {
|
2021-01-12 00:14:26 +08:00
|
|
|
DirectoryBasedGlobalCompilationDatabase::Options Opts(FS);
|
2020-12-04 16:09:03 +08:00
|
|
|
return DirectoryBasedGlobalCompilationDatabase(Opts)
|
2021-01-12 00:14:26 +08:00
|
|
|
.getCompileCommand(testPath(Relative))
|
2020-04-22 20:24:12 +08:00
|
|
|
.getValueOr(tooling::CompileCommand())
|
|
|
|
.CommandLine;
|
|
|
|
};
|
|
|
|
EXPECT_THAT(Command("x/foo.cc"), IsEmpty());
|
2020-12-04 16:09:03 +08:00
|
|
|
const char *const CDB =
|
|
|
|
R"cdb(
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"file": "{0}/x/foo.cc",
|
|
|
|
"command": "clang -DXYZZY {0}/x/foo.cc",
|
|
|
|
"directory": "{0}",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"file": "{0}/bar.cc",
|
|
|
|
"command": "clang -DXYZZY {0}/bar.cc",
|
|
|
|
"directory": "{0}",
|
|
|
|
}
|
|
|
|
]
|
|
|
|
)cdb";
|
2021-01-12 00:14:26 +08:00
|
|
|
FS.Files[testPath("x/build/compile_commands.json")] =
|
|
|
|
llvm::formatv(CDB, llvm::sys::path::convert_to_slash(testRoot()));
|
2020-04-22 20:24:12 +08:00
|
|
|
EXPECT_THAT(Command("x/foo.cc"), Contains("-DXYZZY"));
|
|
|
|
EXPECT_THAT(Command("bar.cc"), IsEmpty())
|
2020-12-04 16:09:03 +08:00
|
|
|
<< "x/build/compile_flags.json only applicable to x/";
|
2020-04-22 20:24:12 +08:00
|
|
|
}
|
|
|
|
|
2021-01-15 01:21:23 +08:00
|
|
|
TEST(GlobalCompilationDatabaseTest, CompileFlagsDirectory) {
|
|
|
|
MockFS FS;
|
|
|
|
FS.Files[testPath("x/compile_flags.txt")] = "-DFOO";
|
|
|
|
DirectoryBasedGlobalCompilationDatabase CDB(FS);
|
|
|
|
auto Commands = CDB.getCompileCommand(testPath("x/y.cpp"));
|
|
|
|
ASSERT_TRUE(Commands.hasValue());
|
|
|
|
EXPECT_THAT(Commands.getValue().CommandLine, Contains("-DFOO"));
|
|
|
|
// Make sure we pick the right working directory.
|
|
|
|
EXPECT_EQ(testPath("x"), Commands.getValue().Directory);
|
|
|
|
}
|
|
|
|
|
2021-01-21 01:35:11 +08:00
|
|
|
MATCHER_P(hasArg, Flag, "") {
|
|
|
|
if (!arg.hasValue()) {
|
|
|
|
*result_listener << "command is null";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!llvm::is_contained(arg->CommandLine, Flag)) {
|
2021-01-31 23:37:42 +08:00
|
|
|
*result_listener << "flags are " << printArgv(arg->CommandLine);
|
2021-01-21 01:35:11 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(GlobalCompilationDatabaseTest, Config) {
|
|
|
|
MockFS FS;
|
|
|
|
FS.Files[testPath("x/compile_flags.txt")] = "-DX";
|
|
|
|
FS.Files[testPath("x/y/z/compile_flags.txt")] = "-DZ";
|
|
|
|
|
|
|
|
Config::CDBSearchSpec Spec;
|
|
|
|
DirectoryBasedGlobalCompilationDatabase::Options Opts(FS);
|
|
|
|
Opts.ContextProvider = [&](llvm::StringRef Path) {
|
|
|
|
Config C;
|
|
|
|
C.CompileFlags.CDBSearch = Spec;
|
|
|
|
return Context::current().derive(Config::Key, std::move(C));
|
|
|
|
};
|
|
|
|
DirectoryBasedGlobalCompilationDatabase CDB(Opts);
|
|
|
|
|
|
|
|
// Default ancestor behavior.
|
|
|
|
EXPECT_FALSE(CDB.getCompileCommand(testPath("foo.cc")));
|
|
|
|
EXPECT_THAT(CDB.getCompileCommand(testPath("x/foo.cc")), hasArg("-DX"));
|
|
|
|
EXPECT_THAT(CDB.getCompileCommand(testPath("x/y/foo.cc")), hasArg("-DX"));
|
|
|
|
EXPECT_THAT(CDB.getCompileCommand(testPath("x/y/z/foo.cc")), hasArg("-DZ"));
|
|
|
|
|
|
|
|
Spec.Policy = Config::CDBSearchSpec::NoCDBSearch;
|
|
|
|
EXPECT_FALSE(CDB.getCompileCommand(testPath("foo.cc")));
|
|
|
|
EXPECT_FALSE(CDB.getCompileCommand(testPath("x/foo.cc")));
|
|
|
|
EXPECT_FALSE(CDB.getCompileCommand(testPath("x/y/foo.cc")));
|
|
|
|
EXPECT_FALSE(CDB.getCompileCommand(testPath("x/y/z/foo.cc")));
|
|
|
|
|
|
|
|
Spec.Policy = Config::CDBSearchSpec::FixedDir;
|
|
|
|
Spec.FixedCDBPath = testPath("w"); // doesn't exist
|
|
|
|
EXPECT_FALSE(CDB.getCompileCommand(testPath("foo.cc")));
|
|
|
|
EXPECT_FALSE(CDB.getCompileCommand(testPath("x/foo.cc")));
|
|
|
|
EXPECT_FALSE(CDB.getCompileCommand(testPath("x/y/foo.cc")));
|
|
|
|
EXPECT_FALSE(CDB.getCompileCommand(testPath("x/y/z/foo.cc")));
|
|
|
|
|
|
|
|
Spec.FixedCDBPath = testPath("x/y/z");
|
|
|
|
EXPECT_THAT(CDB.getCompileCommand(testPath("foo.cc")), hasArg("-DZ"));
|
|
|
|
EXPECT_THAT(CDB.getCompileCommand(testPath("x/foo.cc")), hasArg("-DZ"));
|
|
|
|
EXPECT_THAT(CDB.getCompileCommand(testPath("x/y/foo.cc")), hasArg("-DZ"));
|
|
|
|
EXPECT_THAT(CDB.getCompileCommand(testPath("x/y/z/foo.cc")), hasArg("-DZ"));
|
|
|
|
}
|
|
|
|
|
2019-07-19 00:13:23 +08:00
|
|
|
TEST(GlobalCompilationDatabaseTest, NonCanonicalFilenames) {
|
|
|
|
OverlayCDB DB(nullptr);
|
|
|
|
std::vector<std::string> DiscoveredFiles;
|
|
|
|
auto Sub =
|
|
|
|
DB.watch([&DiscoveredFiles](const std::vector<std::string> Changes) {
|
|
|
|
DiscoveredFiles = Changes;
|
|
|
|
});
|
|
|
|
|
|
|
|
llvm::SmallString<128> Root(testRoot());
|
|
|
|
llvm::sys::path::append(Root, "build", "..", "a.cc");
|
|
|
|
DB.setCompileCommand(Root.str(), tooling::CompileCommand());
|
|
|
|
EXPECT_THAT(DiscoveredFiles, UnorderedElementsAre(testPath("a.cc")));
|
|
|
|
DiscoveredFiles.clear();
|
|
|
|
|
|
|
|
llvm::SmallString<128> File(testRoot());
|
|
|
|
llvm::sys::path::append(File, "blabla", "..", "a.cc");
|
|
|
|
|
|
|
|
EXPECT_TRUE(DB.getCompileCommand(File));
|
[clangd] Always retrieve ProjectInfo from Base in OverlayCDB
Summary:
Clangd is returning current working directory for overriden commands.
This can cause inconsistencies between:
- header and the main files, as OverlayCDB only contains entries for the main
files it direct any queries for the headers to the base, creating a
discrepancy between the two.
- different clangd instances, as the results will be different depending on the
timing of execution of the query and override of the command. hence clangd
might see two different project infos for the same file between different
invocations.
- editors and the way user has invoked it, as current working directory of
clangd will depend on those, hence even when there's no underlying base CWD
might change depending on the editor, or the directory user has started the
editor in.
This patch gets rid of that discrepency by always directing queries to base or
returning llvm::None in absence of it.
For a sample bug see https://reviews.llvm.org/D83099#2154185.
Reviewers: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83934
2020-07-16 17:27:31 +08:00
|
|
|
EXPECT_FALSE(DB.getProjectInfo(File));
|
2019-07-19 00:13:23 +08:00
|
|
|
}
|
|
|
|
|
[clangd] Always retrieve ProjectInfo from Base in OverlayCDB
Summary:
Clangd is returning current working directory for overriden commands.
This can cause inconsistencies between:
- header and the main files, as OverlayCDB only contains entries for the main
files it direct any queries for the headers to the base, creating a
discrepancy between the two.
- different clangd instances, as the results will be different depending on the
timing of execution of the query and override of the command. hence clangd
might see two different project infos for the same file between different
invocations.
- editors and the way user has invoked it, as current working directory of
clangd will depend on those, hence even when there's no underlying base CWD
might change depending on the editor, or the directory user has started the
editor in.
This patch gets rid of that discrepency by always directing queries to base or
returning llvm::None in absence of it.
For a sample bug see https://reviews.llvm.org/D83099#2154185.
Reviewers: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D83934
2020-07-16 17:27:31 +08:00
|
|
|
TEST_F(OverlayCDBTest, GetProjectInfo) {
|
|
|
|
OverlayCDB DB(Base.get());
|
|
|
|
Path File = testPath("foo.cc");
|
|
|
|
Path Header = testPath("foo.h");
|
|
|
|
|
|
|
|
EXPECT_EQ(DB.getProjectInfo(File)->SourceRoot, testRoot());
|
|
|
|
EXPECT_EQ(DB.getProjectInfo(Header)->SourceRoot, testRoot());
|
|
|
|
|
|
|
|
// Shouldn't change after an override.
|
|
|
|
DB.setCompileCommand(File, tooling::CompileCommand());
|
|
|
|
EXPECT_EQ(DB.getProjectInfo(File)->SourceRoot, testRoot());
|
|
|
|
EXPECT_EQ(DB.getProjectInfo(Header)->SourceRoot, testRoot());
|
|
|
|
}
|
2018-04-20 19:35:17 +08:00
|
|
|
} // namespace
|
2020-12-04 16:09:03 +08:00
|
|
|
|
|
|
|
// Friend test has access to internals.
|
|
|
|
class DirectoryBasedGlobalCompilationDatabaseCacheTest
|
|
|
|
: public ::testing::Test {
|
|
|
|
protected:
|
|
|
|
std::shared_ptr<const tooling::CompilationDatabase>
|
|
|
|
lookupCDB(const DirectoryBasedGlobalCompilationDatabase &GDB,
|
|
|
|
llvm::StringRef Path,
|
|
|
|
std::chrono::steady_clock::time_point FreshTime) {
|
|
|
|
DirectoryBasedGlobalCompilationDatabase::CDBLookupRequest Req;
|
|
|
|
Req.FileName = Path;
|
|
|
|
Req.FreshTime = Req.FreshTimeMissing = FreshTime;
|
|
|
|
if (auto Result = GDB.lookupCDB(Req))
|
|
|
|
return std::move(Result->CDB);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Matches non-null CDBs which include the specified flag.
|
|
|
|
MATCHER_P2(hasFlag, Flag, Path, "") {
|
|
|
|
if (arg == nullptr)
|
|
|
|
return false;
|
|
|
|
auto Cmds = arg->getCompileCommands(Path);
|
|
|
|
if (Cmds.empty()) {
|
|
|
|
*result_listener << "yields no commands";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!llvm::is_contained(Cmds.front().CommandLine, Flag)) {
|
2021-01-31 23:37:42 +08:00
|
|
|
*result_listener << "flags are: " << printArgv(Cmds.front().CommandLine);
|
2020-12-04 16:09:03 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-03-22 18:18:18 +08:00
|
|
|
auto hasFlag(llvm::StringRef Flag) {
|
|
|
|
return hasFlag(Flag, "mock_file_name.cc");
|
|
|
|
}
|
2020-12-04 16:09:03 +08:00
|
|
|
|
|
|
|
TEST_F(DirectoryBasedGlobalCompilationDatabaseCacheTest, Cacheable) {
|
|
|
|
MockFS FS;
|
|
|
|
auto Stale = std::chrono::steady_clock::now() - std::chrono::minutes(1);
|
|
|
|
auto Fresh = std::chrono::steady_clock::now() + std::chrono::hours(24);
|
|
|
|
|
|
|
|
DirectoryBasedGlobalCompilationDatabase GDB(FS);
|
|
|
|
FS.Files["compile_flags.txt"] = "-DROOT";
|
|
|
|
auto Root = lookupCDB(GDB, testPath("foo/test.cc"), Stale);
|
|
|
|
EXPECT_THAT(Root, hasFlag("-DROOT"));
|
|
|
|
|
|
|
|
// Add a compilation database to a subdirectory - CDB loaded.
|
|
|
|
FS.Files["foo/compile_flags.txt"] = "-DFOO";
|
|
|
|
EXPECT_EQ(Root, lookupCDB(GDB, testPath("foo/test.cc"), Stale))
|
|
|
|
<< "cache still valid";
|
|
|
|
auto Foo = lookupCDB(GDB, testPath("foo/test.cc"), Fresh);
|
|
|
|
EXPECT_THAT(Foo, hasFlag("-DFOO")) << "new cdb loaded";
|
|
|
|
EXPECT_EQ(Foo, lookupCDB(GDB, testPath("foo/test.cc"), Stale))
|
|
|
|
<< "new cdb in cache";
|
|
|
|
|
|
|
|
// Mtime changed, but no content change - CDB not reloaded.
|
|
|
|
++FS.Timestamps["foo/compile_flags.txt"];
|
|
|
|
auto FooAgain = lookupCDB(GDB, testPath("foo/test.cc"), Fresh);
|
|
|
|
EXPECT_EQ(Foo, FooAgain) << "Same content, read but not reloaded";
|
|
|
|
// Content changed, but not size or mtime - CDB not reloaded.
|
|
|
|
FS.Files["foo/compile_flags.txt"] = "-DBAR";
|
|
|
|
auto FooAgain2 = lookupCDB(GDB, testPath("foo/test.cc"), Fresh);
|
|
|
|
EXPECT_EQ(Foo, FooAgain2) << "Same filesize, change not detected";
|
|
|
|
// Mtime change forces a re-read, and we notice the different content.
|
|
|
|
++FS.Timestamps["foo/compile_flags.txt"];
|
|
|
|
auto Bar = lookupCDB(GDB, testPath("foo/test.cc"), Fresh);
|
|
|
|
EXPECT_THAT(Bar, hasFlag("-DBAR")) << "refreshed with mtime change";
|
|
|
|
|
|
|
|
// Size and content both change - CDB reloaded.
|
|
|
|
FS.Files["foo/compile_flags.txt"] = "-DFOOBAR";
|
|
|
|
EXPECT_EQ(Bar, lookupCDB(GDB, testPath("foo/test.cc"), Stale))
|
|
|
|
<< "cache still valid";
|
|
|
|
auto FooBar = lookupCDB(GDB, testPath("foo/test.cc"), Fresh);
|
|
|
|
EXPECT_THAT(FooBar, hasFlag("-DFOOBAR")) << "cdb reloaded";
|
|
|
|
|
|
|
|
// compile_commands.json takes precedence over compile_flags.txt.
|
2020-12-18 22:11:08 +08:00
|
|
|
FS.Files["foo/compile_commands.json"] =
|
|
|
|
llvm::formatv(R"json([{
|
2021-03-22 18:18:18 +08:00
|
|
|
"file": "{0}/foo/mock_file.cc",
|
|
|
|
"command": "clang -DBAZ mock_file.cc",
|
2020-12-04 16:09:03 +08:00
|
|
|
"directory": "{0}/foo",
|
|
|
|
}])json",
|
2020-12-18 22:11:08 +08:00
|
|
|
llvm::sys::path::convert_to_slash(testRoot()));
|
2020-12-04 16:09:03 +08:00
|
|
|
EXPECT_EQ(FooBar, lookupCDB(GDB, testPath("foo/test.cc"), Stale))
|
|
|
|
<< "cache still valid";
|
|
|
|
auto Baz = lookupCDB(GDB, testPath("foo/test.cc"), Fresh);
|
2021-03-22 18:18:18 +08:00
|
|
|
EXPECT_THAT(Baz, hasFlag("-DBAZ", testPath("foo/mock_file.cc")))
|
2020-12-04 16:09:03 +08:00
|
|
|
<< "compile_commands overrides compile_flags";
|
|
|
|
|
|
|
|
// Removing compile_commands.json reveals compile_flags.txt again.
|
|
|
|
// However this *does* cause a CDB reload (we cache only one CDB per dir).
|
|
|
|
FS.Files.erase("foo/compile_commands.json");
|
|
|
|
auto FoobarAgain = lookupCDB(GDB, testPath("foo/test.cc"), Fresh);
|
|
|
|
EXPECT_THAT(FoobarAgain, hasFlag("-DFOOBAR")) << "reloaded compile_flags";
|
|
|
|
EXPECT_NE(FoobarAgain, FooBar) << "CDB discarded (shadowed within directory)";
|
|
|
|
|
|
|
|
// Removing the directory's CDB leaves the parent CDB active.
|
|
|
|
// The parent CDB is *not* reloaded (we cache the CDB per-directory).
|
|
|
|
FS.Files.erase("foo/compile_flags.txt");
|
|
|
|
EXPECT_EQ(Root, lookupCDB(GDB, testPath("foo/test.cc"), Fresh))
|
|
|
|
<< "CDB retained (shadowed by another directory)";
|
|
|
|
}
|
|
|
|
|
2018-04-20 19:35:17 +08:00
|
|
|
} // namespace clangd
|
|
|
|
} // namespace clang
|