[clang-tools-extra] 2dee4d4 - [clangd] Don't build clangdserver for (most) completion tests. NFC
Sam McCall via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 31 14:10:17 PDT 2020
Author: Sam McCall
Date: 2020-03-31T23:09:36+02:00
New Revision: 2dee4d44297220655786d3fddd471cdf99fa8e5a
URL: https://github.com/llvm/llvm-project/commit/2dee4d44297220655786d3fddd471cdf99fa8e5a
DIFF: https://github.com/llvm/llvm-project/commit/2dee4d44297220655786d3fddd471cdf99fa8e5a.diff
LOG: [clangd] Don't build clangdserver for (most) completion tests. NFC
Added:
Modified:
clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
clang-tools-extra/clangd/unittests/FindTargetTests.cpp
clang-tools-extra/clangd/unittests/TestTU.cpp
clang-tools-extra/clangd/unittests/TestTU.h
clang-tools-extra/clangd/unittests/TweakTesting.h
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
index 24197485f68a..06dccfa93956 100644
--- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -93,8 +93,9 @@ std::unique_ptr<SymbolIndex> memIndex(std::vector<Symbol> Symbols) {
return MemIndex::build(std::move(Slab).build(), RefSlab(), RelationSlab());
}
-CodeCompleteResult completions(ClangdServer &Server, llvm::StringRef TestCode,
- Position Point,
+// Runs code completion.
+// If IndexSymbols is non-empty, an index will be built and passed to opts.
+CodeCompleteResult completions(const TestTU &TU, Position Point,
std::vector<Symbol> IndexSymbols = {},
clangd::CodeCompleteOptions Opts = {}) {
std::unique_ptr<SymbolIndex> OverrideIndex;
@@ -104,49 +105,35 @@ CodeCompleteResult completions(ClangdServer &Server, llvm::StringRef TestCode,
Opts.Index = OverrideIndex.get();
}
- auto File = testPath("foo.cpp");
- runAddDocument(Server, File, TestCode);
- auto CompletionList =
- llvm::cantFail(runCodeComplete(Server, File, Point, Opts));
- return CompletionList;
-}
-
-CodeCompleteResult completions(ClangdServer &Server, llvm::StringRef Text,
- std::vector<Symbol> IndexSymbols = {},
- clangd::CodeCompleteOptions Opts = {},
- PathRef FilePath = "foo.cpp") {
- std::unique_ptr<SymbolIndex> OverrideIndex;
- if (!IndexSymbols.empty()) {
- assert(!Opts.Index && "both Index and IndexSymbols given!");
- OverrideIndex = memIndex(std::move(IndexSymbols));
- Opts.Index = OverrideIndex.get();
+ auto Inputs = TU.inputs();
+ IgnoreDiagnostics Diags;
+ auto CI = buildCompilerInvocation(Inputs, Diags);
+ if (!CI) {
+ ADD_FAILURE() << "Couldn't build CompilerInvocation";
+ return {};
}
-
- auto File = testPath(FilePath);
- Annotations Test(Text);
- runAddDocument(Server, File, Test.code());
- auto CompletionList =
- llvm::cantFail(runCodeComplete(Server, File, Test.point(), Opts));
- return CompletionList;
+ auto Preamble =
+ buildPreamble(testPath(TU.Filename), *CI, /*OldPreamble=*/nullptr, Inputs,
+ /*InMemory=*/true, /*Callback=*/nullptr);
+ return codeComplete(testPath(TU.Filename), Inputs.CompileCommand,
+ Preamble.get(), TU.Code, Point, Inputs.FS, Opts);
}
-// Builds a server and runs code completion.
-// If IndexSymbols is non-empty, an index will be built and passed to opts.
+// Runs code completion.
CodeCompleteResult completions(llvm::StringRef Text,
std::vector<Symbol> IndexSymbols = {},
clangd::CodeCompleteOptions Opts = {},
PathRef FilePath = "foo.cpp") {
- MockFSProvider FS;
- MockCompilationDatabase CDB;
+ Annotations Test(Text);
+ auto TU = TestTU::withCode(Test.code());
// To make sure our tests for completiopns inside templates work on Windows.
- CDB.ExtraClangFlags = {"-fno-delayed-template-parsing"};
- ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
- return completions(Server, Text, std::move(IndexSymbols), std::move(Opts),
- FilePath);
+ TU.ExtraArgs = {"-fno-delayed-template-parsing"};
+ TU.Filename = FilePath.str();
+ return completions(TU, Test.point(), std::move(IndexSymbols),
+ std::move(Opts));
}
-// Builds a server and runs code completion.
-// If IndexSymbols is non-empty, an index will be built and passed to opts.
+// Runs code completion without the clang parser.
CodeCompleteResult completionsNoCompile(llvm::StringRef Text,
std::vector<Symbol> IndexSymbols = {},
clangd::CodeCompleteOptions Opts = {},
@@ -669,53 +656,38 @@ TEST(CompletionTest, SemaIndexMergeWithLimit) {
}
TEST(CompletionTest, IncludeInsertionPreprocessorIntegrationTests) {
- MockFSProvider FS;
- MockCompilationDatabase CDB;
- std::string Subdir = testPath("sub");
- std::string SearchDirArg = (Twine("-I") + Subdir).str();
- CDB.ExtraClangFlags = {SearchDirArg.c_str()};
- std::string BarHeader = testPath("sub/bar.h");
- FS.Files[BarHeader] = "";
+ TestTU TU;
+ TU.ExtraArgs.push_back("-I" + testPath("sub"));
+ TU.AdditionalFiles["sub/bar.h"] = "";
+ auto BarURI = URI::create(testPath("sub/bar.h")).toString();
- ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
- auto BarURI = URI::create(BarHeader).toString();
Symbol Sym = cls("ns::X");
Sym.CanonicalDeclaration.FileURI = BarURI.c_str();
Sym.IncludeHeaders.emplace_back(BarURI, 1);
// Shoten include path based on search directory and insert.
- auto Results = completions(Server,
- R"cpp(
- int main() { ns::^ }
- )cpp",
- {Sym});
+ Annotations Test("int main() { ns::^ }");
+ TU.Code = Test.code().str();
+ auto Results = completions(TU, Test.point(), {Sym});
EXPECT_THAT(Results.Completions,
ElementsAre(AllOf(Named("X"), InsertInclude("\"bar.h\""))));
// Can be disabled via option.
CodeCompleteOptions NoInsertion;
NoInsertion.InsertIncludes = CodeCompleteOptions::NeverInsert;
- Results = completions(Server,
- R"cpp(
- int main() { ns::^ }
- )cpp",
- {Sym}, NoInsertion);
+ Results = completions(TU, Test.point(), {Sym}, NoInsertion);
EXPECT_THAT(Results.Completions,
ElementsAre(AllOf(Named("X"), Not(InsertInclude()))));
// Duplicate based on inclusions in preamble.
- Results = completions(Server,
- R"cpp(
+ Test = Annotations(R"cpp(
#include "sub/bar.h" // not shortest, so should only match resolved.
int main() { ns::^ }
- )cpp",
- {Sym});
+ )cpp");
+ TU.Code = Test.code().str();
+ Results = completions(TU, Test.point(), {Sym});
EXPECT_THAT(Results.Completions, ElementsAre(AllOf(Named("X"), Labeled("X"),
Not(InsertInclude()))));
}
TEST(CompletionTest, NoIncludeInsertionWhenDeclFoundInFile) {
- MockFSProvider FS;
- MockCompilationDatabase CDB;
-
- ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
Symbol SymX = cls("ns::X");
Symbol SymY = cls("ns::Y");
std::string BarHeader = testPath("bar.h");
@@ -725,8 +697,7 @@ TEST(CompletionTest, NoIncludeInsertionWhenDeclFoundInFile) {
SymX.IncludeHeaders.emplace_back("<bar>", 1);
SymY.IncludeHeaders.emplace_back("<bar>", 1);
// Shoten include path based on search directory and insert.
- auto Results = completions(Server,
- R"cpp(
+ auto Results = completions(R"cpp(
namespace ns {
class X;
class Y {};
@@ -740,34 +711,27 @@ TEST(CompletionTest, NoIncludeInsertionWhenDeclFoundInFile) {
}
TEST(CompletionTest, IndexSuppressesPreambleCompletions) {
- MockFSProvider FS;
- MockCompilationDatabase CDB;
- ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
-
- FS.Files[testPath("bar.h")] =
- R"cpp(namespace ns { struct preamble { int member; }; })cpp";
- auto File = testPath("foo.cpp");
Annotations Test(R"cpp(
#include "bar.h"
namespace ns { int local; }
void f() { ns::^; }
void f2() { ns::preamble().$2^; }
)cpp");
- runAddDocument(Server, File, Test.code());
- clangd::CodeCompleteOptions Opts = {};
+ auto TU = TestTU::withCode(Test.code());
+ TU.AdditionalFiles["bar.h"] =
+ R"cpp(namespace ns { struct preamble { int member; }; })cpp";
+ clangd::CodeCompleteOptions Opts = {};
auto I = memIndex({var("ns::index")});
Opts.Index = I.get();
- auto WithIndex = cantFail(runCodeComplete(Server, File, Test.point(), Opts));
+ auto WithIndex = completions(TU, Test.point(), {}, Opts);
EXPECT_THAT(WithIndex.Completions,
UnorderedElementsAre(Named("local"), Named("index")));
- auto ClassFromPreamble =
- cantFail(runCodeComplete(Server, File, Test.point("2"), Opts));
+ auto ClassFromPreamble = completions(TU, Test.point("2"), {}, Opts);
EXPECT_THAT(ClassFromPreamble.Completions, Contains(Named("member")));
Opts.Index = nullptr;
- auto WithoutIndex =
- cantFail(runCodeComplete(Server, File, Test.point(), Opts));
+ auto WithoutIndex = completions(TU, Test.point(), {}, Opts);
EXPECT_THAT(WithoutIndex.Completions,
UnorderedElementsAre(Named("local"), Named("preamble")));
}
@@ -811,7 +775,14 @@ TEST(CompletionTest, DynamicIndexIncludeInsertion) {
Server.addDocument(testPath("foo_impl.cpp"), FileContent);
// Wait for the dynamic index being built.
ASSERT_TRUE(Server.blockUntilIdleForTest());
- EXPECT_THAT(completions(Server, "Foo^ foo;").Completions,
+
+ auto File = testPath("foo.cpp");
+ Annotations Test("Foo^ foo;");
+ runAddDocument(Server, File, Test.code());
+ auto CompletionList =
+ llvm::cantFail(runCodeComplete(Server, File, Test.point(), {}));
+
+ EXPECT_THAT(CompletionList.Completions,
ElementsAre(AllOf(Named("Foo"), HasInclude("\"foo_header.h\""),
InsertInclude())));
}
@@ -892,13 +863,17 @@ TEST(CompletionTest, CommentsFromSystemHeaders) {
int foo();
)cpp";
- auto Results = completions(Server,
- R"cpp(
+ auto File = testPath("foo.cpp");
+ Annotations Test(R"cpp(
#include "foo.h"
int x = foo^
)cpp");
+ runAddDocument(Server, File, Test.code());
+ auto CompletionList =
+ llvm::cantFail(runCodeComplete(Server, File, Test.point(), {}));
+
EXPECT_THAT(
- Results.Completions,
+ CompletionList.Completions,
Contains(AllOf(Named("foo"), Doc("This comment should be retained!"))));
}
@@ -1064,15 +1039,19 @@ SignatureHelp signatures(llvm::StringRef Text, Position Point,
if (!IndexSymbols.empty())
Index = memIndex(IndexSymbols);
- MockFSProvider FS;
- MockCompilationDatabase CDB;
- ClangdServer::Options Opts = ClangdServer::optsForTest();
- Opts.StaticIndex = Index.get();
-
- ClangdServer Server(CDB, FS, Opts);
- auto File = testPath("foo.cpp");
- runAddDocument(Server, File, Text);
- return llvm::cantFail(runSignatureHelp(Server, File, Point));
+ auto TU = TestTU::withCode(Text);
+ auto Inputs = TU.inputs();
+ IgnoreDiagnostics Diags;
+ auto CI = buildCompilerInvocation(Inputs, Diags);
+ if (!CI) {
+ ADD_FAILURE() << "Couldn't build CompilerInvocation";
+ return {};
+ }
+ auto Preamble =
+ buildPreamble(testPath(TU.Filename), *CI, /*OldPreamble=*/nullptr, Inputs,
+ /*InMemory=*/true, /*Callback=*/nullptr);
+ return signatureHelp(testPath(TU.Filename), Inputs.CompileCommand,
+ Preamble.get(), Text, Point, Inputs.FS, Index.get());
}
SignatureHelp signatures(llvm::StringRef Text,
@@ -1546,14 +1525,7 @@ TEST(CompletionTest, DocumentationFromChangedFileCrash) {
}
TEST(CompletionTest, NonDocComments) {
- MockFSProvider FS;
- auto FooCpp = testPath("foo.cpp");
- FS.Files[FooCpp] = "";
-
- MockCompilationDatabase CDB;
- ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
-
- Annotations Source(R"cpp(
+ const char *Text = R"cpp(
// We ignore namespace comments, for rationale see CodeCompletionStrings.h.
namespace comments_ns {
}
@@ -1588,17 +1560,11 @@ TEST(CompletionTest, NonDocComments) {
int Struct<T>::comments_quux() {
int a = comments^;
}
- )cpp");
- // FIXME: Auto-completion in a template requires disabling delayed template
- // parsing.
- CDB.ExtraClangFlags.push_back("-fno-delayed-template-parsing");
- runAddDocument(Server, FooCpp, Source.code(), "null", WantDiagnostics::Yes);
- CodeCompleteResult Completions = cantFail(runCodeComplete(
- Server, FooCpp, Source.point(), clangd::CodeCompleteOptions()));
+ )cpp";
// We should not get any of those comments in completion.
EXPECT_THAT(
- Completions.Completions,
+ completions(Text).Completions,
UnorderedElementsAre(AllOf(Not(IsDocumented()), Named("comments_foo")),
AllOf(IsDocumented(), Named("comments_baz")),
AllOf(IsDocumented(), Named("comments_quux")),
@@ -1740,11 +1706,10 @@ TEST(CompletionTest, CodeCompletionContext) {
TEST(CompletionTest, FixItForArrowToDot) {
MockFSProvider FS;
MockCompilationDatabase CDB;
- ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
CodeCompleteOptions Opts;
Opts.IncludeFixIts = true;
- Annotations TestCode(
+ const char* Code =
R"cpp(
class Auxilary {
public:
@@ -1760,13 +1725,12 @@ TEST(CompletionTest, FixItForArrowToDot) {
ClassWithPtr x;
x[[->]]^;
}
- )cpp");
- auto Results =
- completions(Server, TestCode.code(), TestCode.point(), {}, Opts);
+ )cpp";
+ auto Results = completions(Code, {}, Opts);
EXPECT_EQ(Results.Completions.size(), 3u);
TextEdit ReplacementEdit;
- ReplacementEdit.range = TestCode.range();
+ ReplacementEdit.range = Annotations(Code).range();
ReplacementEdit.newText = ".";
for (const auto &C : Results.Completions) {
EXPECT_TRUE(C.FixIts.size() == 1u || C.Name == "AuxFunction");
@@ -1777,13 +1741,9 @@ TEST(CompletionTest, FixItForArrowToDot) {
}
TEST(CompletionTest, FixItForDotToArrow) {
- MockFSProvider FS;
- MockCompilationDatabase CDB;
- ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
-
CodeCompleteOptions Opts;
Opts.IncludeFixIts = true;
- Annotations TestCode(
+ const char* Code =
R"cpp(
class Auxilary {
public:
@@ -1799,13 +1759,12 @@ TEST(CompletionTest, FixItForDotToArrow) {
ClassWithPtr x;
x[[.]]^;
}
- )cpp");
- auto Results =
- completions(Server, TestCode.code(), TestCode.point(), {}, Opts);
+ )cpp";
+ auto Results = completions(Code, {}, Opts);
EXPECT_EQ(Results.Completions.size(), 3u);
TextEdit ReplacementEdit;
- ReplacementEdit.range = TestCode.range();
+ ReplacementEdit.range = Annotations(Code).range();
ReplacementEdit.newText = "->";
for (const auto &C : Results.Completions) {
EXPECT_TRUE(C.FixIts.empty() || C.Name == "AuxFunction");
@@ -1858,8 +1817,8 @@ TEST(CompletionTest, RenderWithFixItNonMerged) {
TEST(CompletionTest, CompletionTokenRange) {
MockFSProvider FS;
MockCompilationDatabase CDB;
- FS.Files["foo/abc/foo.h"] = "";
- ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
+ TestTU TU;
+ TU.AdditionalFiles["foo/abc/foo.h"] = "";
constexpr const char *TestCodes[] = {
R"cpp(
@@ -1891,10 +1850,10 @@ TEST(CompletionTest, CompletionTokenRange) {
};
for (const auto &Text : TestCodes) {
Annotations TestCode(Text);
- auto Results = completions(Server, TestCode.code(), TestCode.point());
-
+ TU.Code = TestCode.code().str();
+ auto Results = completions(TU, TestCode.point());
if (Results.Completions.size() != 1) {
- ADD_FAILURE() << "Results.Completions.size() != 1";
+ ADD_FAILURE() << "Results.Completions.size() != 1" << Text;
continue;
}
EXPECT_THAT(Results.Completions.front().CompletionTokenRange,
@@ -2247,13 +2206,12 @@ TEST(CompletionTest, InsertTheMostPopularHeader) {
}
TEST(CompletionTest, NoInsertIncludeIfOnePresent) {
- MockFSProvider FS;
- MockCompilationDatabase CDB;
-
- std::string FooHeader = testPath("foo.h");
- FS.Files[FooHeader] = "";
-
- ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
+ Annotations Test(R"cpp(
+ #include "foo.h"
+ Fun^
+ )cpp");
+ auto TU = TestTU::withCode(Test.code());
+ TU.AdditionalFiles["foo.h"] = "";
std::string DeclFile = URI::create(testPath("foo")).toString();
Symbol Sym = func("Func");
@@ -2262,7 +2220,7 @@ TEST(CompletionTest, NoInsertIncludeIfOnePresent) {
Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000);
EXPECT_THAT(
- completions(Server, "#include \"foo.h\"\nFun^", {Sym}).Completions,
+ completions(TU, Test.point(), {Sym}).Completions,
UnorderedElementsAre(
AllOf(Named("Func"), HasInclude("\"foo.h\""), Not(InsertInclude()))));
}
@@ -2279,20 +2237,15 @@ TEST(CompletionTest, MergeMacrosFromIndexAndSema) {
}
TEST(CompletionTest, MacroFromPreamble) {
- MockFSProvider FS;
- MockCompilationDatabase CDB;
- std::string FooHeader = testPath("foo.h");
- FS.Files[FooHeader] = "#define CLANGD_PREAMBLE_HEADER x\n";
- ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
- auto Results = completions(
- R"cpp(#include "foo.h"
- #define CLANGD_PREAMBLE_MAIN x
+ Annotations Test(R"cpp(#define CLANGD_PREAMBLE_MAIN x
int x = 0;
#define CLANGD_MAIN x
void f() { CLANGD_^ }
- )cpp",
- {func("CLANGD_INDEX")});
+ )cpp");
+ auto TU = TestTU::withCode(Test.code());
+ TU.HeaderCode = "#define CLANGD_PREAMBLE_HEADER x";
+ auto Results = completions(TU, Test.point(), {func("CLANGD_INDEX")});
// We should get results from the main file, including the preamble section.
// However no results from included files (the index should cover them).
EXPECT_THAT(Results.Completions,
@@ -2405,29 +2358,22 @@ TEST(SignatureHelpTest, ConstructorInitializeFields) {
}
TEST(CompletionTest, IncludedCompletionKinds) {
- MockFSProvider FS;
- MockCompilationDatabase CDB;
- std::string Subdir = testPath("sub");
- std::string SearchDirArg = (Twine("-I") + Subdir).str();
- CDB.ExtraClangFlags = {SearchDirArg.c_str()};
- std::string BarHeader = testPath("sub/bar.h");
- FS.Files[BarHeader] = "";
- ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
- auto Results = completions(Server,
- R"cpp(
- #include "^"
- )cpp");
+ Annotations Test(R"cpp(#include "^")cpp");
+ auto TU = TestTU::withCode(Test.code());
+ TU.AdditionalFiles["sub/bar.h"] = "";
+ TU.ExtraArgs.push_back("-I" + testPath("sub"));
+
+ auto Results = completions(TU, Test.point());
EXPECT_THAT(Results.Completions,
AllOf(Has("sub/", CompletionItemKind::Folder),
Has("bar.h\"", CompletionItemKind::File)));
}
TEST(CompletionTest, NoCrashAtNonAlphaIncludeHeader) {
- auto Results = completions(
+ completions(
R"cpp(
#include "./^"
)cpp");
- EXPECT_TRUE(Results.Completions.empty());
}
TEST(CompletionTest, NoAllScopesCompletionWhenQualified) {
diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index c38ccc3f9441..53d29a236a07 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -65,7 +65,7 @@ class TargetDeclTest : public ::testing::Test {
protected:
using Rel = DeclRelation;
std::string Code;
- std::vector<const char *> Flags;
+ std::vector<std::string> Flags;
// Asserts that `Code` has a marked selection of a node `NodeType`,
// and returns allTargetDecls() as PrintedDecl structs.
diff --git a/clang-tools-extra/clangd/unittests/TestTU.cpp b/clang-tools-extra/clangd/unittests/TestTU.cpp
index 909c125aed2e..dfcdb0884e27 100644
--- a/clang-tools-extra/clangd/unittests/TestTU.cpp
+++ b/clang-tools-extra/clangd/unittests/TestTU.cpp
@@ -20,7 +20,7 @@
namespace clang {
namespace clangd {
-ParsedAST TestTU::build() const {
+ParseInputs TestTU::inputs() const {
std::string FullFilename = testPath(Filename),
FullHeaderName = testPath(HeaderFilename),
ImportThunk = testPath("import_thunk.h");
@@ -34,25 +34,24 @@ ParsedAST TestTU::build() const {
Files[FullHeaderName] = HeaderCode;
Files[ImportThunk] = ThunkContents;
- std::vector<const char *> Cmd = {"clang"};
+ ParseInputs Inputs;
+ auto& Argv = Inputs.CompileCommand.CommandLine;
+ Argv = {"clang"};
// FIXME: this shouldn't need to be conditional, but it breaks a
// GoToDefinition test for some reason (getMacroArgExpandedLocation fails).
if (!HeaderCode.empty()) {
- Cmd.push_back("-include");
- Cmd.push_back(ImplicitHeaderGuard ? ImportThunk.c_str()
- : FullHeaderName.c_str());
+ Argv.push_back("-include");
+ Argv.push_back(ImplicitHeaderGuard ? ImportThunk : FullHeaderName);
// ms-compatibility changes the meaning of #import.
// The default is OS-dependent (on on windows), ensure it's off.
if (ImplicitHeaderGuard)
- Cmd.push_back("-fno-ms-compatibility");
+ Inputs.CompileCommand.CommandLine.push_back("-fno-ms-compatibility");
}
- Cmd.insert(Cmd.end(), ExtraArgs.begin(), ExtraArgs.end());
+ Argv.insert(Argv.end(), ExtraArgs.begin(), ExtraArgs.end());
// Put the file name at the end -- this allows the extra arg (-xc++) to
// override the language setting.
- Cmd.push_back(FullFilename.c_str());
- ParseInputs Inputs;
+ Argv.push_back(FullFilename);
Inputs.CompileCommand.Filename = FullFilename;
- Inputs.CompileCommand.CommandLine = {Cmd.begin(), Cmd.end()};
Inputs.CompileCommand.Directory = testRoot();
Inputs.Contents = Code;
Inputs.FS = buildTestFS(Files);
@@ -62,15 +61,20 @@ ParsedAST TestTU::build() const {
Inputs.Index = ExternalIndex;
if (Inputs.Index)
Inputs.Opts.SuggestMissingIncludes = true;
+ return Inputs;
+}
+
+ParsedAST TestTU::build() const {
+ auto Inputs = inputs();
StoreDiags Diags;
auto CI = buildCompilerInvocation(Inputs, Diags);
assert(CI && "Failed to build compilation invocation.");
auto Preamble =
- buildPreamble(FullFilename, *CI,
+ buildPreamble(testPath(Filename), *CI,
/*OldPreamble=*/nullptr, Inputs,
/*StoreInMemory=*/true, /*PreambleCallback=*/nullptr);
- auto AST =
- buildAST(FullFilename, std::move(CI), Diags.take(), Inputs, Preamble);
+ auto AST = buildAST(testPath(Filename), std::move(CI), Diags.take(), Inputs,
+ Preamble);
if (!AST.hasValue()) {
ADD_FAILURE() << "Failed to build code:\n" << Code;
llvm_unreachable("Failed to build TestTU!");
@@ -79,9 +83,17 @@ ParsedAST TestTU::build() const {
// This guards against accidental syntax errors silently subverting tests.
// error-ok is awfully primitive - using clang -verify would be nicer.
// Ownership and layering makes it pretty hard.
- if (llvm::none_of(Files, [](const auto &KV) {
- return llvm::StringRef(KV.second).contains("error-ok");
- })) {
+ bool ErrorOk = [&, this] {
+ llvm::StringLiteral Marker = "error-ok";
+ if (llvm::StringRef(Code).contains(Marker) ||
+ llvm::StringRef(HeaderCode).contains(Marker))
+ return true;
+ for (const auto& KV : this->AdditionalFiles)
+ if (llvm::StringRef(KV.second).contains(Marker))
+ return true;
+ return false;
+ }();
+ if (!ErrorOk) {
for (const auto &D : AST->getDiagnostics())
if (D.Severity >= DiagnosticsEngine::Error) {
ADD_FAILURE()
diff --git a/clang-tools-extra/clangd/unittests/TestTU.h b/clang-tools-extra/clangd/unittests/TestTU.h
index 4668543d5b4d..229f65a4b95c 100644
--- a/clang-tools-extra/clangd/unittests/TestTU.h
+++ b/clang-tools-extra/clangd/unittests/TestTU.h
@@ -17,6 +17,7 @@
#ifndef LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_TESTTU_H
#define LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_TESTTU_H
+#include "Compiler.h"
#include "ParsedAST.h"
#include "Path.h"
#include "index/Index.h"
@@ -54,7 +55,7 @@ struct TestTU {
llvm::StringMap<std::string> AdditionalFiles;
// Extra arguments for the compiler invocation.
- std::vector<const char *> ExtraArgs;
+ std::vector<std::string> ExtraArgs;
llvm::Optional<std::string> ClangTidyChecks;
llvm::Optional<std::string> ClangTidyWarningsAsErrors;
@@ -67,6 +68,7 @@ struct TestTU {
// By default, build() will report Error diagnostics as GTest errors.
// Suppress this behavior by adding an 'error-ok' comment to the code.
ParsedAST build() const;
+ ParseInputs inputs() const;
SymbolSlab headerSymbols() const;
std::unique_ptr<SymbolIndex> index() const;
};
diff --git a/clang-tools-extra/clangd/unittests/TweakTesting.h b/clang-tools-extra/clangd/unittests/TweakTesting.h
index 10186f859bae..c771149a72fc 100644
--- a/clang-tools-extra/clangd/unittests/TweakTesting.h
+++ b/clang-tools-extra/clangd/unittests/TweakTesting.h
@@ -66,7 +66,7 @@ class TweakTest : public ::testing::Test {
llvm::StringRef FileName = "TestTU.cpp";
// Extra flags passed to the compilation in apply().
- std::vector<const char *> ExtraArgs;
+ std::vector<std::string> ExtraArgs;
// Context in which snippets of code should be placed to run tweaks.
CodeContext Context = File;
More information about the cfe-commits
mailing list