[clang-tools-extra] e9b7fe8 - [clangd] [Modules] Use ASTReader directly in IsModuleFileUpToDate (#113879)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 30 18:32:04 PDT 2024
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
More information about the cfe-commits
mailing list