22#include "llvm/ADT/StringRef.h"
23#include "llvm/Support/FileSystem.h"
24#include "llvm/Support/raw_ostream.h"
25#include "gmock/gmock.h"
26#include "gtest/gtest.h"
31MATCHER_P(named, Name,
"") {
return arg.Name == Name; }
35 GlobalScanningCounterProjectModules(
36 std::unique_ptr<ProjectModules> Underlying, std::atomic<unsigned> &Count)
37 : Underlying(std::move(Underlying)), Count(Count) {}
39 std::vector<std::string> getRequiredModules(
PathRef File)
override {
40 return Underlying->getRequiredModules(
File);
43 std::string getModuleNameForSource(
PathRef File)
override {
44 return Underlying->getModuleNameForSource(
File);
47 void setCommandMangler(CommandMangler Mangler)
override {
48 Underlying->setCommandMangler(std::move(Mangler));
51 std::string getSourceForModuleName(llvm::StringRef ModuleName,
52 PathRef RequiredSrcFile)
override {
54 return Underlying->getSourceForModuleName(ModuleName, RequiredSrcFile);
58 std::unique_ptr<ProjectModules> Underlying;
59 std::atomic<unsigned> &Count;
64 MockDirectoryCompilationDatabase(StringRef TestDir,
const ThreadsafeFS &TFS)
65 : MockCompilationDatabase(TestDir),
66 MockedCDBPtr(std::make_shared<MockClangCompilationDatabase>(*this)),
67 TFS(TFS), GlobalScanningCount(0) {
68 this->ExtraClangFlags.push_back(
"-std=c++20");
69 this->ExtraClangFlags.push_back(
"-c");
72 void addFile(llvm::StringRef
Path, llvm::StringRef Contents);
74 std::unique_ptr<ProjectModules> getProjectModules(
PathRef)
const override {
75 return std::make_unique<GlobalScanningCounterProjectModules>(
79 unsigned getGlobalScanningCount()
const {
return GlobalScanningCount; }
82 class MockClangCompilationDatabase :
public tooling::CompilationDatabase {
84 MockClangCompilationDatabase(MockDirectoryCompilationDatabase &MCDB)
87 std::vector<tooling::CompileCommand>
88 getCompileCommands(StringRef FilePath)
const override {
89 std::optional<tooling::CompileCommand> Cmd =
90 MCDB.getCompileCommand(FilePath);
95 std::vector<std::string> getAllFiles()
const override {
return Files; }
97 void AddFile(StringRef
File) { Files.push_back(
File.str()); }
100 MockDirectoryCompilationDatabase &MCDB;
101 std::vector<std::string> Files;
104 std::shared_ptr<MockClangCompilationDatabase> MockedCDBPtr;
105 const ThreadsafeFS &TFS;
107 mutable std::atomic<unsigned> GlobalScanningCount;
111void MockDirectoryCompilationDatabase::addFile(llvm::StringRef
Path,
112 llvm::StringRef Contents) {
113 ASSERT_FALSE(llvm::sys::path::is_absolute(Path));
116 llvm::sys::path::append(AbsPath, Path);
119 llvm::sys::fs::create_directories(llvm::sys::path::parent_path(AbsPath)));
122 llvm::raw_fd_ostream OS(AbsPath, EC);
126 MockedCDBPtr->AddFile(Path);
129class PrerequisiteModulesTests :
public ::testing::Test {
131 void SetUp()
override {
132 ASSERT_FALSE(llvm::sys::fs::createUniqueDirectory(
"modules-test", TestDir));
135 void TearDown()
override {
136 ASSERT_FALSE(llvm::sys::fs::remove_directories(TestDir));
142 std::string getFullPath(llvm::StringRef Path) {
143 SmallString<128> Result(TestDir);
144 llvm::sys::path::append(Result, Path);
145 EXPECT_TRUE(llvm::sys::fs::exists(Result.str()));
146 return Result.str().str();
149 ParseInputs getInputs(llvm::StringRef FileName,
150 const GlobalCompilationDatabase &CDB) {
151 std::string FullPathName = getFullPath(FileName);
154 std::optional<tooling::CompileCommand> Cmd =
155 CDB.getCompileCommand(FullPathName);
157 Inputs.CompileCommand = std::move(*Cmd);
160 if (
auto Contents = FS.
view(TestDir)->getBufferForFile(FullPathName))
161 Inputs.Contents = Contents->get()->getBuffer().str();
166 SmallString<256> TestDir;
171 DiagnosticConsumer DiagConsumer;
174TEST_F(PrerequisiteModulesTests, NonModularTest) {
175 MockDirectoryCompilationDatabase CDB(TestDir, FS);
177 CDB.addFile(
"foo.h", R
"cpp(
181 CDB.addFile("NonModular.cpp", R
"cpp(
188 ModulesBuilder Builder(CDB);
191 auto NonModularInfo =
192 Builder.buildPrerequisiteModulesFor(getFullPath(
"NonModular.cpp"), FS);
193 EXPECT_TRUE(NonModularInfo);
195 HeaderSearchOptions HSOpts;
196 NonModularInfo->adjustHeaderSearchOptions(HSOpts);
197 EXPECT_TRUE(HSOpts.PrebuiltModuleFiles.empty());
201 EXPECT_TRUE(NonModularInfo->canReuse(*Invocation, FS.view(TestDir)));
204TEST_F(PrerequisiteModulesTests, ModuleWithoutDepTest) {
205 MockDirectoryCompilationDatabase CDB(TestDir, FS);
207 CDB.addFile(
"foo.h", R
"cpp(
211 CDB.addFile("M.cppm", R
"cpp(
217 ModulesBuilder Builder(CDB);
219 auto MInfo = Builder.buildPrerequisiteModulesFor(getFullPath(
"M.cppm"), FS);
223 HeaderSearchOptions HSOpts;
224 MInfo->adjustHeaderSearchOptions(HSOpts);
225 EXPECT_TRUE(HSOpts.PrebuiltModuleFiles.empty());
229 EXPECT_TRUE(MInfo->canReuse(*Invocation, FS.view(TestDir)));
232TEST_F(PrerequisiteModulesTests, ModuleWithArgumentPatch) {
233 MockDirectoryCompilationDatabase CDB(TestDir, FS);
235 CDB.ExtraClangFlags.push_back(
"-invalid-unknown-flag");
237 CDB.addFile(
"Dep.cppm", R
"cpp(
241 CDB.addFile("M.cppm", R
"cpp(
248 auto ProjectModules = CDB.getProjectModules(getFullPath(
"M.cppm"));
250 ProjectModules->getRequiredModules(getFullPath(
"M.cppm")).empty());
253 ProjectModules->setCommandMangler([](tooling::CompileCommand &Command,
255 auto const It = llvm::find(Command.CommandLine,
"-invalid-unknown-flag");
256 Command.CommandLine.erase(It);
262 ProjectModules->getRequiredModules(getFullPath(
"M.cppm")).empty());
265TEST_F(PrerequisiteModulesTests, ModuleWithDepTest) {
266 MockDirectoryCompilationDatabase CDB(TestDir, FS);
268 CDB.addFile(
"foo.h", R
"cpp(
272 CDB.addFile("M.cppm", R
"cpp(
278 CDB.addFile("N.cppm", R
"cpp(
284 CDB.addFile("N-part.cppm", R
"cpp(
285// Different module name with filename intentionally.
289 ModulesBuilder Builder(CDB);
291 auto NInfo = Builder.buildPrerequisiteModulesFor(getFullPath(
"N.cppm"), FS);
294 ParseInputs NInput = getInputs(
"N.cppm", CDB);
295 std::unique_ptr<CompilerInvocation> Invocation =
298 EXPECT_TRUE(NInfo->canReuse(*Invocation, FS.view(TestDir)));
304 HeaderSearchOptions HSOpts;
305 NInfo->adjustHeaderSearchOptions(HSOpts);
307 EXPECT_TRUE(HSOpts.PrebuiltModuleFiles.count(
"M"));
308 EXPECT_TRUE(HSOpts.PrebuiltModuleFiles.count(
"N:Part"));
315 HeaderSearchOptions HSOpts;
316 HSOpts.PrebuiltModuleFiles[
"M"] =
"incorrect_path";
317 HSOpts.PrebuiltModuleFiles[
"N:Part"] =
"incorrect_path";
318 NInfo->adjustHeaderSearchOptions(HSOpts);
320 EXPECT_TRUE(StringRef(HSOpts.PrebuiltModuleFiles[
"M"]).ends_with(
".pcm"));
322 StringRef(HSOpts.PrebuiltModuleFiles[
"N:Part"]).ends_with(
".pcm"));
326TEST_F(PrerequisiteModulesTests, ReusabilityTest) {
327 MockDirectoryCompilationDatabase CDB(TestDir, FS);
329 CDB.addFile(
"foo.h", R
"cpp(
333 CDB.addFile("M.cppm", R
"cpp(
339 CDB.addFile("N.cppm", R
"cpp(
345 CDB.addFile("N-part.cppm", R
"cpp(
346// Different module name with filename intentionally.
350 ModulesBuilder Builder(CDB);
352 auto NInfo = Builder.buildPrerequisiteModulesFor(getFullPath(
"N.cppm"), FS);
356 ParseInputs NInput = getInputs(
"N.cppm", CDB);
357 std::unique_ptr<CompilerInvocation> Invocation =
359 EXPECT_TRUE(NInfo->canReuse(*Invocation, FS.view(TestDir)));
363 CDB.addFile(
"L.cppm", R
"cpp(
369 EXPECT_TRUE(NInfo->canReuse(*Invocation, FS.view(TestDir)));
371 CDB.addFile("bar.h", R
"cpp(
373inline void bar(int) {}
375 EXPECT_TRUE(NInfo->canReuse(*Invocation, FS.view(TestDir)));
380 CDB.addFile(
"M.cppm", R
"cpp(
386 EXPECT_FALSE(NInfo->canReuse(*Invocation, FS.view(TestDir)));
388 NInfo = Builder.buildPrerequisiteModulesFor(getFullPath("N.cppm"), FS);
389 EXPECT_TRUE(NInfo->canReuse(*Invocation, FS.view(TestDir)));
391 CDB.addFile(
"foo.h", R
"cpp(
393inline void foo(int) {}
395 EXPECT_FALSE(NInfo->canReuse(*Invocation, FS.view(TestDir)));
397 NInfo = Builder.buildPrerequisiteModulesFor(getFullPath("N.cppm"), FS);
398 EXPECT_TRUE(NInfo->canReuse(*Invocation, FS.view(TestDir)));
401 CDB.addFile(
"N-part.cppm", R
"cpp(
403// Intentioned to make it uncompilable.
404export int NPart = 4LIdjwldijaw
406 EXPECT_FALSE(NInfo->canReuse(*Invocation, FS.view(TestDir)));
407 NInfo = Builder.buildPrerequisiteModulesFor(getFullPath("N.cppm"), FS);
409 EXPECT_FALSE(NInfo->canReuse(*Invocation, FS.view(TestDir)));
411 CDB.addFile(
"N-part.cppm", R
"cpp(
413export int NPart = 43;
416 EXPECT_FALSE(NInfo->canReuse(*Invocation, FS.view(TestDir)));
417 NInfo = Builder.buildPrerequisiteModulesFor(getFullPath("N.cppm"), FS);
419 EXPECT_TRUE(NInfo->canReuse(*Invocation, FS.view(TestDir)));
423 CDB.addFile(
"N-part.cppm", R
"cpp(
425export int NPart = 43;
427 EXPECT_TRUE(NInfo->canReuse(*Invocation, FS.view(TestDir)));
429 CDB.addFile("N.cppm", R
"cpp(
437 EXPECT_TRUE(NInfo->canReuse(*Invocation, FS.view(TestDir)));
441TEST_F(PrerequisiteModulesTests, ParsedASTTest) {
442 MockDirectoryCompilationDatabase CDB(TestDir, FS);
444 CDB.addFile(
"A.cppm", R
"cpp(
449 CDB.addFile("Use.cpp", R
"cpp(
453 ModulesBuilder Builder(CDB);
455 ParseInputs Use = getInputs("Use.cpp", CDB);
456 Use.ModulesManager = &Builder;
458 std::unique_ptr<CompilerInvocation> CI =
466 EXPECT_TRUE(
Preamble->RequiredModules);
473 EXPECT_TRUE(
D.isFromASTFile());
477TEST_F(PrerequisiteModulesTests, CodeCompleteTest) {
478 MockDirectoryCompilationDatabase CDB(TestDir, FS);
480 CDB.addFile(
"A.cppm", R
"cpp(
485 llvm::StringLiteral UserContents = R"cpp(
492 CDB.addFile("Use.cpp", UserContents);
493 Annotations Test(UserContents);
495 ModulesBuilder Builder(CDB);
497 ParseInputs Use = getInputs(
"Use.cpp", CDB);
498 Use.ModulesManager = &Builder;
500 std::unique_ptr<CompilerInvocation> CI =
508 EXPECT_TRUE(
Preamble->RequiredModules);
510 auto Result =
codeComplete(getFullPath(
"Use.cpp"), Test.point(),
512 EXPECT_FALSE(Result.Completions.empty());
513 EXPECT_EQ(Result.Completions[0].Name,
"printA");
516TEST_F(PrerequisiteModulesTests, SignatureHelpTest) {
517 MockDirectoryCompilationDatabase CDB(TestDir, FS);
519 CDB.addFile(
"A.cppm", R
"cpp(
521export void printA(int a);
524 llvm::StringLiteral UserContents = R"cpp(
531 CDB.addFile("Use.cpp", UserContents);
532 Annotations Test(UserContents);
534 ModulesBuilder Builder(CDB);
536 ParseInputs Use = getInputs(
"Use.cpp", CDB);
537 Use.ModulesManager = &Builder;
539 std::unique_ptr<CompilerInvocation> CI =
547 EXPECT_TRUE(
Preamble->RequiredModules);
551 EXPECT_FALSE(Result.signatures.empty());
552 EXPECT_EQ(Result.signatures[0].label,
"printA(int a) -> void");
553 EXPECT_EQ(Result.signatures[0].parameters[0].labelString,
"int a");
556TEST_F(PrerequisiteModulesTests, ReusablePrerequisiteModulesTest) {
557 MockDirectoryCompilationDatabase CDB(TestDir, FS);
559 CDB.addFile(
"M.cppm", R
"cpp(
563 CDB.addFile("A.cppm", R
"cpp(
566export int A = 43 + M;
568 CDB.addFile("B.cppm", R
"cpp(
571export int B = 44 + M;
574 ModulesBuilder Builder(CDB);
576 auto AInfo = Builder.buildPrerequisiteModulesFor(getFullPath(
"A.cppm"), FS);
578 auto BInfo = Builder.buildPrerequisiteModulesFor(getFullPath(
"B.cppm"), FS);
580 HeaderSearchOptions HSOptsA(TestDir);
581 HeaderSearchOptions HSOptsB(TestDir);
582 AInfo->adjustHeaderSearchOptions(HSOptsA);
583 BInfo->adjustHeaderSearchOptions(HSOptsB);
585 EXPECT_FALSE(HSOptsA.PrebuiltModuleFiles.empty());
586 EXPECT_FALSE(HSOptsB.PrebuiltModuleFiles.empty());
589 EXPECT_EQ(HSOptsA.PrebuiltModuleFiles, HSOptsB.PrebuiltModuleFiles);
592 CDB.addFile(
"M.cppm", R
"cpp(
594export constexpr int M = 43;
597 ParseInputs AUse = getInputs("A.cppm", CDB);
598 AUse.ModulesManager = &Builder;
599 std::unique_ptr<CompilerInvocation> AInvocation =
601 EXPECT_FALSE(AInfo->canReuse(*AInvocation, FS.view(TestDir)));
603 ParseInputs BUse = getInputs(
"B.cppm", CDB);
604 AUse.ModulesManager = &Builder;
605 std::unique_ptr<CompilerInvocation> BInvocation =
607 EXPECT_FALSE(BInfo->canReuse(*BInvocation, FS.view(TestDir)));
610 Builder.buildPrerequisiteModulesFor(getFullPath(
"A.cppm"), FS);
612 Builder.buildPrerequisiteModulesFor(getFullPath(
"B.cppm"), FS);
613 EXPECT_TRUE(NewAInfo);
614 EXPECT_TRUE(NewBInfo);
615 HeaderSearchOptions NewHSOptsA(TestDir);
616 HeaderSearchOptions NewHSOptsB(TestDir);
617 NewAInfo->adjustHeaderSearchOptions(NewHSOptsA);
618 NewBInfo->adjustHeaderSearchOptions(NewHSOptsB);
620 EXPECT_FALSE(NewHSOptsA.PrebuiltModuleFiles.empty());
621 EXPECT_FALSE(NewHSOptsB.PrebuiltModuleFiles.empty());
623 EXPECT_EQ(NewHSOptsA.PrebuiltModuleFiles, NewHSOptsB.PrebuiltModuleFiles);
625 EXPECT_NE(NewHSOptsA.PrebuiltModuleFiles, HSOptsA.PrebuiltModuleFiles);
628TEST_F(PrerequisiteModulesTests, ScanningCacheTest) {
629 MockDirectoryCompilationDatabase CDB(TestDir, FS);
631 CDB.addFile(
"M.cppm", R
"cpp(
634 CDB.addFile("A.cppm", R
"cpp(
638 CDB.addFile("B.cppm", R
"cpp(
643 ModulesBuilder Builder(CDB);
645 Builder.buildPrerequisiteModulesFor(getFullPath("A.cppm"), FS);
646 Builder.buildPrerequisiteModulesFor(getFullPath(
"B.cppm"), FS);
647 EXPECT_EQ(CDB.getGlobalScanningCount(), 1u);
653TEST_F(PrerequisiteModulesTests, CanReuseWithHeadersInModuleUnit) {
654 MockDirectoryCompilationDatabase CDB(TestDir, FS);
657 CDB.addFile(
"header1.h", R
"cpp(
658inline int getValue() { return 42; }
662 CDB.addFile(
"M.cppm", R
"cpp(
666export int m_value = getValue();
670 CDB.addFile(
"N.cppm", R
"cpp(
677 CDB.addFile(
"N-part.cppm", R
"cpp(
681 ModulesBuilder Builder(CDB);
684 auto NInfo = Builder.buildPrerequisiteModulesFor(getFullPath(
"N.cppm"), FS);
687 ParseInputs NInput = getInputs(
"N.cppm", CDB);
688 std::unique_ptr<CompilerInvocation> Invocation =
692 EXPECT_TRUE(NInfo->canReuse(*Invocation, FS.view(TestDir)));
696 CDB.addFile(
"header1.h", R
"cpp(
697inline int getValue() { return 43; }
699 EXPECT_FALSE(NInfo->canReuse(*Invocation, FS.view(TestDir)));
702 NInfo = Builder.buildPrerequisiteModulesFor(getFullPath(
"N.cppm"), FS);
704 EXPECT_TRUE(NInfo->canReuse(*Invocation, FS.view(TestDir)));
707 CDB.addFile(
"M.cppm", R
"cpp(
711export int m_value = getValue();
712export int m_new_value = 10;
714 EXPECT_FALSE(NInfo->canReuse(*Invocation, FS.view(TestDir)));
717 NInfo = Builder.buildPrerequisiteModulesFor(getFullPath(
"N.cppm"), FS);
719 EXPECT_TRUE(NInfo->canReuse(*Invocation, FS.view(TestDir)));
722TEST_F(PrerequisiteModulesTests, PrebuiltModuleFileTest) {
723 MockDirectoryCompilationDatabase CDB(TestDir, FS);
725 CDB.addFile(
"M.cppm", R
"cpp(
729 CDB.addFile("U.cpp", R
"cpp(
734 ModulesBuilder Builder(CDB);
736 Builder.buildPrerequisiteModulesFor(getFullPath(
"U.cpp"), FS);
737 HeaderSearchOptions HS(TestDir);
738 ModuleInfo->adjustHeaderSearchOptions(HS);
740 CDB.ExtraClangFlags.push_back(
"-fmodule-file=M=" +
741 HS.PrebuiltModuleFiles[
"M"]);
742 ModulesBuilder Builder2(CDB);
744 Builder2.buildPrerequisiteModulesFor(getFullPath(
"U.cpp"), FS);
745 HeaderSearchOptions HS2(TestDir);
746 ModuleInfo2->adjustHeaderSearchOptions(HS2);
748 EXPECT_EQ(HS.PrebuiltModuleFiles, HS2.PrebuiltModuleFiles);
755TEST_F(PrerequisiteModulesTests, PrebuiltModuleFileWithRelativePath) {
756 MockDirectoryCompilationDatabase CDB(TestDir, FS);
758 CDB.addFile(
"M.cppm", R
"cpp(
760export int m_value = 42;
763 CDB.addFile("U.cpp", R
"cpp(
765int use() { return m_value; }
769 ModulesBuilder Builder(CDB);
771 Builder.buildPrerequisiteModulesFor(getFullPath(
"U.cpp"), FS);
772 ASSERT_TRUE(ModuleInfo);
774 HeaderSearchOptions HS(TestDir);
775 ModuleInfo->adjustHeaderSearchOptions(HS);
776 ASSERT_EQ(HS.PrebuiltModuleFiles.count(
"M"), 1u);
779 std::string OriginalBMPath = HS.PrebuiltModuleFiles[
"M"];
780 ASSERT_TRUE(llvm::sys::path::is_absolute(OriginalBMPath));
781 ASSERT_TRUE(llvm::sys::fs::exists(OriginalBMPath));
784 SmallString<256> BMSubDir(TestDir);
785 llvm::sys::path::append(BMSubDir,
"prebuilt_modules");
786 ASSERT_FALSE(llvm::sys::fs::create_directories(BMSubDir));
788 SmallString<256> NewBMPath(BMSubDir);
789 llvm::sys::path::append(NewBMPath,
"M.pcm");
792 ASSERT_FALSE(llvm::sys::fs::copy_file(OriginalBMPath, NewBMPath));
793 ASSERT_TRUE(llvm::sys::fs::exists(NewBMPath));
796 std::string RelativeBMPath =
797 llvm::StringRef(NewBMPath).drop_front(TestDir.size() + 1).str();
798 ASSERT_FALSE(RelativeBMPath.empty());
799 ASSERT_TRUE(llvm::sys::path::is_relative(RelativeBMPath));
802 MockDirectoryCompilationDatabase CDBWithRelativePath(TestDir, FS);
804 CDBWithRelativePath.addFile(
"M.cppm", R
"cpp(
806export int m_value = 42;
809 CDBWithRelativePath.addFile("U.cpp", R
"cpp(
811int use() { return m_value; }
815 CDBWithRelativePath.ExtraClangFlags.push_back(
"-fmodule-file=M=" +
819 ModulesBuilder BuilderWithRelativePath(CDBWithRelativePath);
820 auto ModuleInfo2 = BuilderWithRelativePath.buildPrerequisiteModulesFor(
821 getFullPath(
"U.cpp"), FS);
822 ASSERT_TRUE(ModuleInfo2);
824 HeaderSearchOptions HS2(TestDir);
825 ModuleInfo2->adjustHeaderSearchOptions(HS2);
828 ASSERT_EQ(HS2.PrebuiltModuleFiles.count(
"M"), 1u);
829 EXPECT_EQ(HS2.PrebuiltModuleFiles[
"M"], std::string(NewBMPath))
830 <<
"Expected absolute path: " << NewBMPath
831 <<
"\nGot: " << HS2.PrebuiltModuleFiles[
"M"]
832 <<
"\nRelative path used: " << RelativeBMPath;
835TEST_F(PrerequisiteModulesTests, ModuleImportThroughInclude) {
836 MockDirectoryCompilationDatabase CDB(TestDir, FS);
838 Annotations UseCpp(R
"cpp(
846 CDB.addFile("M.cppm", R
"cpp(
848export struct TypeFromModule {};
851 CDB.addFile("Header.hpp", R
"cpp(
853struct TypeFromHeader {};
856 CDB.addFile("Use.cpp", UseCpp.code());
858 ModulesBuilder Builder(CDB);
860 auto Inputs = getInputs(
"Use.cpp", CDB);
861 Inputs.ModulesManager = &Builder;
862 Inputs.Opts.SkipPreambleBuild =
true;
871 EXPECT_EQ(
Preamble->Preamble.getBounds().Size, 0u);
876 EXPECT_TRUE(
AST->getDiagnostics().empty());
878 auto Result =
codeComplete(getFullPath(
"Use.cpp"), UseCpp.point(),
880 EXPECT_THAT(Result.Completions,
881 testing::UnorderedElementsAre(named(
"TypeFromModule"),
882 named(
"TypeFromHeader")));
static cl::opt< std::string > Directory(cl::Positional, cl::Required, cl::desc("<Search Root Directory>"))
static std::optional< ParsedAST > build(llvm::StringRef Filename, const ParseInputs &Inputs, std::unique_ptr< clang::CompilerInvocation > CI, llvm::ArrayRef< Diag > CompilerInvocationDiags, std::shared_ptr< const PreambleData > Preamble)
Attempts to run Clang and store the parsed AST.
An interface to query the modules information in the project.
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > view(std::nullopt_t CWD) const
Obtain a vfs::FileSystem with an arbitrary initial working directory.
FIXME: Skip testing on windows temporarily due to the different escaping code mode.
TEST_F(BackgroundIndexTest, NoCrashOnErrorFile)
const NamedDecl & findDecl(ParsedAST &AST, llvm::StringRef QName)
std::unique_ptr< ProjectModules > scanningProjectModules(std::shared_ptr< const clang::tooling::CompilationDatabase > CDB, const ThreadsafeFS &TFS)
Providing modules information for the project by scanning every file.
std::unique_ptr< CompilerInvocation > buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D, std::vector< std::string > *CC1Args)
Builds compiler invocation that could be used to build AST or preamble.
std::shared_ptr< const PreambleData > buildPreamble(PathRef FileName, CompilerInvocation CI, const ParseInputs &Inputs, bool StoreInMemory, PreambleParsedCallback PreambleCallback, PreambleBuildStats *Stats)
Build a preamble for the new inputs unless an old one can be reused.
llvm::StringRef PathRef
A typedef to represent a ref to file path.
std::string Path
A typedef to represent a file path.
CodeCompleteResult codeComplete(PathRef FileName, Position Pos, const PreambleData *Preamble, const ParseInputs &ParseInput, CodeCompleteOptions Opts, SpeculativeFuzzyFind *SpecFuzzyFind)
Gets code completions at a specified Pos in FileName.
SignatureHelp signatureHelp(PathRef FileName, Position Pos, const PreambleData &Preamble, const ParseInputs &ParseInput, MarkupKind DocumentationFormat)
Get signature help at a specified Pos in FileName.