-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clangd] [Modules] Use ASTReader directly in IsModuleFileUpToDate #113879
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clangd @llvm/pr-subscribers-clang-tools-extra Author: Chuanqi Xu (ChuanqiXu9) Changes@kadircet mentioned in 448d8fa#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 ? But I like ASTUnit since I feel it is a better abstract here. For compiler instance, we need to provide the compiler invocation. But for the purpose here. we're just trying to open the BMI file to verify if the source files are out of date or not. We don't need compiler invocation here completely. So I prefer ASTUnit here especially clangd already depends on clangFrontend already so I feel like I didn't introduce a new dependency. Then I added the Full diff: https://github.com/llvm/llvm-project/pull/113879.diff 1 Files Affected:
diff --git a/clang-tools-extra/clangd/ModulesBuilder.cpp b/clang-tools-extra/clangd/ModulesBuilder.cpp
index 1eeff468ef1236..25f9ab6631fca7 100644
--- a/clang-tools-extra/clangd/ModulesBuilder.cpp
+++ b/clang-tools-extra/clangd/ModulesBuilder.cpp
@@ -127,10 +127,10 @@ struct ModuleFile {
std::string ModuleFilePath;
};
-bool IsModuleFileUpToDate(
- PathRef ModuleFilePath,
- const PrerequisiteModules &RequisiteModules) {
-IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
+bool IsModuleFileUpToDate(PathRef ModuleFilePath,
+ const PrerequisiteModules &RequisiteModules,
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
+ IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(new DiagnosticOptions());
auto HSOpts = std::make_shared<HeaderSearchOptions>();
@@ -141,7 +141,11 @@ IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
PCHContainerOperations PCHOperations;
std::unique_ptr<ASTUnit> Unit = ASTUnit::LoadFromASTFile(
ModuleFilePath.str(), PCHOperations.getRawReader(), ASTUnit::LoadASTOnly,
- Diags, FileSystemOptions(), std::move(HSOpts));
+ Diags, FileSystemOptions(), std::move(HSOpts),
+ /*LangOpts=*/nullptr, /*OnlyLocalDecls=*/false,
+ /*CaptureDiagnostics=*/CaptureDiagsKind::None,
+ /*AllowASTWithCompilerErrors=*/false, /*UserFilesAreVolatile=*/false,
+ VFS);
if (!Unit)
return false;
@@ -167,10 +171,12 @@ IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
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 +353,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
|
It isn't at all about having this dependency in terms of "build graph", but rather about mental complexity and maintenance burden of that. Clangd already has its own primitives for dealing with preambles, keeping ASTcontexts alive and even handling modules (and soon also module caches!). ASTUnit has its own way of doing all of these. So if we introduced any semantic dependency here, everytime someone is chaging those core primitives in clangd will need to think about how all of these going to interact with each other. Moreover, if this was sent with a review, I would've surely objected to that.
We already have the compiler invocation available. I am not sure about the implications of loading a PCM with a "vanilla" compiler instance (that's what ASTUnit does underneath, creates a preprocessor, astcontext, diagsengine, ... with default options), I'd be much more comfortable if we created that ASTReader and loaded the AST with some relevant compilerinvocation that describes user's intent. But you definitely know much more about modules, if you think that's fine, i think we can always create that astreader directly here, without a compilerinstance as well. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(need to write something here apparently)
(Update too quickly) |
✅ With the latest revision this PR passed the C/C++ code formatter. |
return false; | ||
|
||
auto Reader = Unit->getASTReader(); | ||
auto Reader = Clang.getASTReader(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think we should call Clang.createASTReader()
first. I don't see any of the previous call creating that.
b6abb73
to
99e1989
Compare
I like the idea more. (so I typed 'updated too quickly') The most important reason I did the previous change is, I think the compiler invocation and compiler instance are not needed to check if source files recorded in BMI are out dated or not. They are fake parameters here. I feel they are redundant and want to get rid of that. And now you pointed out that, actually ASTUnit may be redundant too and what we need actually is the ASTReader only. I like the idea. (Although it introduces the codes a little bit longer) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks!
|
||
if (!Unit) | ||
return false; | ||
Reader.setListener(std::make_unique<PPIntializer>(PP)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we really need a Listener? and where's PPIntializer
defined?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad. It was not updated. I guess I had a typo when verify it by typing check-clangd
into check-clang
: (
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks, lgtm!
Thanks : ) |
…vm#113879) @kadircet mentioned in llvm@448d8fa#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.
…vm#113879) @kadircet mentioned in llvm@448d8fa#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.
@kadircet mentioned in 448d8fa#diff-fb3ba8a781117ff04736f951a274812cb7ad1678f9d71d4d91870b711ab45da0L285 that:
This tries to resolve the problem by creating ASTReader directly and use VFS to create the FileManager.
// Original comments
But I like ASTUnit since I feel it is a better abstract here. For compiler instance, we need to provide the compiler invocation. But for the purpose here. we're just trying to open the BMI file to verify if the source files are out of date or not. We don't need compiler invocation here completely. So I prefer ASTUnit here especially clangd already depends on clangFrontend already so I feel like I didn't introduce a new dependency.
Then I added the
VFS
argument toASTUnit
to address the Virtual/Physical FS problem.