Author: Chuanqi Xu Date: 2024-10-31T09:32:01+08:00 New Revision: e9b7fe8e5a5819cb632d02529712535ca1b83f02
URL: https://github.com/llvm/llvm-project/commit/e9b7fe8e5a5819cb632d02529712535ca1b83f02 DIFF: https://github.com/llvm/llvm-project/commit/e9b7fe8e5a5819cb632d02529712535ca1b83f02.diff LOG: [clangd] [Modules] Use ASTReader directly in IsModuleFileUpToDate (#113879) @kadircet mentioned in https://github.com/llvm/llvm-project/commit/448d8fa880be5cae0f63c3b248f07f647013a5a4#diff-fb3ba8a781117ff04736f951a274812cb7ad1678f9d71d4d91870b711ab45da0L285 that: > this is definitely a functional change, clangd is used in environments that solely relies on VFS, and doesn't depend on ASTUnit at all. > right now this is both introducing a dependency on ASTUnit, and making all the logical IO physical instead. can you instead use the regular compiler utilities in clangd, and get the astreader from CompilerInstance directly, which is VFS-aware, and doesn't depend on ASTUnit ? This tries to resolve the problem by creating ASTReader directly and use VFS to create the FileManager. Added: Modified: clang-tools-extra/clangd/ModulesBuilder.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/ModulesBuilder.cpp b/clang-tools-extra/clangd/ModulesBuilder.cpp index 1eeff468ef1236..97f67ddf5495a2 100644 --- a/clang-tools-extra/clangd/ModulesBuilder.cpp +++ b/clang-tools-extra/clangd/ModulesBuilder.cpp @@ -12,6 +12,7 @@ #include "clang/Frontend/FrontendAction.h" #include "clang/Frontend/FrontendActions.h" #include "clang/Serialization/ASTReader.h" +#include "clang/Serialization/InMemoryModuleCache.h" namespace clang { namespace clangd { @@ -127,50 +128,68 @@ struct ModuleFile { std::string ModuleFilePath; }; -bool IsModuleFileUpToDate( - PathRef ModuleFilePath, - const PrerequisiteModules &RequisiteModules) { -IntrusiveRefCntPtr<DiagnosticsEngine> Diags = - CompilerInstance::createDiagnostics(new DiagnosticOptions()); - +bool IsModuleFileUpToDate(PathRef ModuleFilePath, + const PrerequisiteModules &RequisiteModules, + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) { auto HSOpts = std::make_shared<HeaderSearchOptions>(); RequisiteModules.adjustHeaderSearchOptions(*HSOpts); HSOpts->ForceCheckCXX20ModulesInputFiles = true; HSOpts->ValidateASTInputFilesContent = true; + clang::clangd::IgnoreDiagnostics IgnoreDiags; + IntrusiveRefCntPtr<DiagnosticsEngine> Diags = + CompilerInstance::createDiagnostics(new DiagnosticOptions, &IgnoreDiags, + /*ShouldOwnClient=*/false); + + LangOptions LangOpts; + LangOpts.SkipODRCheckInGMF = true; + + FileManager FileMgr(FileSystemOptions(), VFS); + + SourceManager SourceMgr(*Diags, FileMgr); + + HeaderSearch HeaderInfo(HSOpts, SourceMgr, *Diags, LangOpts, + /*Target=*/nullptr); + + TrivialModuleLoader ModuleLoader; + Preprocessor PP(std::make_shared<PreprocessorOptions>(), *Diags, LangOpts, + SourceMgr, HeaderInfo, ModuleLoader); + + IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache = new InMemoryModuleCache; PCHContainerOperations PCHOperations; - std::unique_ptr<ASTUnit> Unit = ASTUnit::LoadFromASTFile( - ModuleFilePath.str(), PCHOperations.getRawReader(), ASTUnit::LoadASTOnly, - Diags, FileSystemOptions(), std::move(HSOpts)); + ASTReader Reader(PP, *ModuleCache, /*ASTContext=*/nullptr, + PCHOperations.getRawReader(), {}); - if (!Unit) - return false; + // We don't need any listener here. By default it will use a validator + // listener. + Reader.setListener(nullptr); - auto Reader = Unit->getASTReader(); - if (!Reader) + if (Reader.ReadAST(ModuleFilePath, serialization::MK_MainFile, + SourceLocation(), + ASTReader::ARR_None) != ASTReader::Success) return false; bool UpToDate = true; - Reader->getModuleManager().visit([&](serialization::ModuleFile &MF) -> bool { - Reader->visitInputFiles( + Reader.getModuleManager().visit([&](serialization::ModuleFile &MF) -> bool { + Reader.visitInputFiles( MF, /*IncludeSystem=*/false, /*Complain=*/false, [&](const serialization::InputFile &IF, bool isSystem) { if (!IF.getFile() || IF.isOutOfDate()) UpToDate = false; }); - return !UpToDate; }); - return UpToDate; } bool IsModuleFilesUpToDate( llvm::SmallVector<PathRef> ModuleFilePaths, - const PrerequisiteModules &RequisiteModules) { - return llvm::all_of(ModuleFilePaths, [&RequisiteModules](auto ModuleFilePath) { - return IsModuleFileUpToDate(ModuleFilePath, RequisiteModules); - }); + const PrerequisiteModules &RequisiteModules, + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) { + return llvm::all_of( + ModuleFilePaths, [&RequisiteModules, VFS](auto ModuleFilePath) { + return IsModuleFileUpToDate(ModuleFilePath, RequisiteModules, VFS); + }); } // StandalonePrerequisiteModules - stands for PrerequisiteModules for which all @@ -347,7 +366,7 @@ bool StandalonePrerequisiteModules::canReuse( SmallVector<StringRef> BMIPaths; for (auto &MF : RequiredModules) BMIPaths.push_back(MF.ModuleFilePath); - return IsModuleFilesUpToDate(BMIPaths, *this); + return IsModuleFilesUpToDate(BMIPaths, *this, VFS); } } // namespace clangd _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits