Index: clang-tools-extra/trunk/clangd/ClangdServer.h =================================================================== --- clang-tools-extra/trunk/clangd/ClangdServer.h +++ clang-tools-extra/trunk/clangd/ClangdServer.h @@ -150,9 +150,14 @@ /// a vfs::FileSystem provided by \p FSProvider. Results of code /// completion/diagnostics also include a tag, that \p FSProvider returns /// along with the vfs::FileSystem. + /// When \p ResourceDir is set, it will be used to search for internal headers + /// (overriding defaults and -resource-dir compiler flag, if set). If \p + /// ResourceDir is None, ClangdServer will attempt to set it to a standard + /// location, obtained via CompilerInvocation::GetResourcePath. ClangdServer(GlobalCompilationDatabase &CDB, DiagnosticsConsumer &DiagConsumer, - FileSystemProvider &FSProvider, bool RunSynchronously); + FileSystemProvider &FSProvider, bool RunSynchronously, + llvm::Optional ResourceDir = llvm::None); /// Add a \p File to the list of tracked C++ files or update the contents if /// \p File is already tracked. Also schedules parsing of the AST for it on a @@ -199,6 +204,7 @@ FileSystemProvider &FSProvider; DraftStore DraftMgr; ClangdUnitStore Units; + std::string ResourceDir; std::shared_ptr PCHs; // WorkScheduler has to be the last member, because its destructor has to be // called before all other members to stop the worker thread that references Index: clang-tools-extra/trunk/clangd/ClangdServer.cpp =================================================================== --- clang-tools-extra/trunk/clangd/ClangdServer.cpp +++ clang-tools-extra/trunk/clangd/ClangdServer.cpp @@ -33,6 +33,11 @@ return std::vector(Result.begin(), Result.end()); } +std::string getStandardResourceDir() { + static int Dummy; // Just an address in this process. + return CompilerInvocation::GetResourcesPath("clangd", (void *)&Dummy); +} + } // namespace size_t clangd::positionToOffset(StringRef Code, Position P) { @@ -141,8 +146,10 @@ ClangdServer::ClangdServer(GlobalCompilationDatabase &CDB, DiagnosticsConsumer &DiagConsumer, FileSystemProvider &FSProvider, - bool RunSynchronously) + bool RunSynchronously, + llvm::Optional ResourceDir) : CDB(CDB), DiagConsumer(DiagConsumer), FSProvider(FSProvider), + ResourceDir(ResourceDir ? ResourceDir->str() : getStandardResourceDir()), PCHs(std::make_shared()), WorkScheduler(RunSynchronously) {} @@ -158,7 +165,7 @@ "No contents inside a file that was scheduled for reparse"); auto TaggedFS = FSProvider.getTaggedFileSystem(FileStr); Units.runOnUnit( - FileStr, *FileContents.Draft, CDB, PCHs, TaggedFS.Value, + FileStr, *FileContents.Draft, ResourceDir, CDB, PCHs, TaggedFS.Value, [&](ClangdUnit const &Unit) { DiagConsumer.onDiagnosticsReady( FileStr, make_tagged(Unit.getLocalDiagnostics(), TaggedFS.Tag)); @@ -201,8 +208,8 @@ // It would be nice to use runOnUnitWithoutReparse here, but we can't // guarantee the correctness of code completion cache here if we don't do the // reparse. - Units.runOnUnit(File, *OverridenContents, CDB, PCHs, TaggedFS.Value, - [&](ClangdUnit &Unit) { + Units.runOnUnit(File, *OverridenContents, ResourceDir, CDB, PCHs, + TaggedFS.Value, [&](ClangdUnit &Unit) { Result = Unit.codeComplete(*OverridenContents, Pos, TaggedFS.Value); }); Index: clang-tools-extra/trunk/clangd/ClangdUnit.h =================================================================== --- clang-tools-extra/trunk/clangd/ClangdUnit.h +++ clang-tools-extra/trunk/clangd/ClangdUnit.h @@ -44,7 +44,7 @@ /// would want to perform on parsed C++ files. class ClangdUnit { public: - ClangdUnit(PathRef FileName, StringRef Contents, + ClangdUnit(PathRef FileName, StringRef Contents, StringRef ResourceDir, std::shared_ptr PCHs, std::vector Commands, IntrusiveRefCntPtr VFS); Index: clang-tools-extra/trunk/clangd/ClangdUnit.cpp =================================================================== --- clang-tools-extra/trunk/clangd/ClangdUnit.cpp +++ clang-tools-extra/trunk/clangd/ClangdUnit.cpp @@ -19,6 +19,7 @@ using namespace clang; ClangdUnit::ClangdUnit(PathRef FileName, StringRef Contents, + StringRef ResourceDir, std::shared_ptr PCHs, std::vector Commands, IntrusiveRefCntPtr VFS) @@ -27,10 +28,7 @@ // Inject the resource dir. // FIXME: Don't overwrite it if it's already there. - static int Dummy; // Just an address in this process. - std::string ResourceDir = - CompilerInvocation::GetResourcesPath("clangd", (void *)&Dummy); - Commands.front().CommandLine.push_back("-resource-dir=" + ResourceDir); + Commands.front().CommandLine.push_back("-resource-dir=" + std::string(ResourceDir)); IntrusiveRefCntPtr Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions); Index: clang-tools-extra/trunk/clangd/ClangdUnitStore.h =================================================================== --- clang-tools-extra/trunk/clangd/ClangdUnitStore.h +++ clang-tools-extra/trunk/clangd/ClangdUnitStore.h @@ -30,12 +30,13 @@ /// store, ClangdUnit::reparse will be called with the new contents before /// running \p Action. template - void runOnUnit(PathRef File, StringRef FileContents, + void runOnUnit(PathRef File, StringRef FileContents, StringRef ResourceDir, GlobalCompilationDatabase &CDB, std::shared_ptr PCHs, IntrusiveRefCntPtr VFS, Func Action) { - runOnUnitImpl(File, FileContents, CDB, PCHs, /*ReparseBeforeAction=*/true, - VFS, std::forward(Action)); + runOnUnitImpl(File, FileContents, ResourceDir, CDB, PCHs, + /*ReparseBeforeAction=*/true, VFS, + std::forward(Action)); } /// Run specified \p Action on the ClangdUnit for \p File. @@ -44,18 +45,19 @@ /// store, the \p Action will be run directly on it. template void runOnUnitWithoutReparse(PathRef File, StringRef FileContents, + StringRef ResourceDir, GlobalCompilationDatabase &CDB, std::shared_ptr PCHs, IntrusiveRefCntPtr VFS, Func Action) { - runOnUnitImpl(File, FileContents, CDB, PCHs, /*ReparseBeforeAction=*/false, - VFS, std::forward(Action)); + runOnUnitImpl(File, FileContents, ResourceDir, CDB, PCHs, + /*ReparseBeforeAction=*/false, VFS, + std::forward(Action)); } /// Run the specified \p Action on the ClangdUnit for \p File. /// Unit for \p File should exist in the store. - template - void runOnExistingUnit(PathRef File, Func Action) { + template void runOnExistingUnit(PathRef File, Func Action) { std::lock_guard Lock(Mutex); auto It = OpenedFiles.find(File); @@ -71,7 +73,7 @@ /// Run specified \p Action on the ClangdUnit for \p File. template void runOnUnitImpl(PathRef File, StringRef FileContents, - GlobalCompilationDatabase &CDB, + StringRef ResourceDir, GlobalCompilationDatabase &CDB, std::shared_ptr PCHs, bool ReparseBeforeAction, IntrusiveRefCntPtr VFS, Func Action) { @@ -85,8 +87,9 @@ auto It = OpenedFiles.find(File); if (It == OpenedFiles.end()) { It = OpenedFiles - .insert(std::make_pair( - File, ClangdUnit(File, FileContents, PCHs, Commands, VFS))) + .insert(std::make_pair(File, ClangdUnit(File, FileContents, + ResourceDir, PCHs, + Commands, VFS))) .first; } else if (ReparseBeforeAction) { It->second.reparse(FileContents, VFS);