================
@@ -546,6 +553,127 @@ dependencies::initializeScanInstanceDependencyCollector(
return MDC;
}
+struct SingleModuleWithAsyncModuleCompiles : PreprocessOnlyAction {
+ DependencyScanningService &Service;
+
+ SingleModuleWithAsyncModuleCompiles(DependencyScanningService &Service)
+ : Service(Service) {}
+
+ bool BeginSourceFileAction(CompilerInstance &CI) override;
+};
+
+/// The preprocessor callback that takes care of initiating an asynchronous
+/// module compilation if needed.
+struct AsyncModuleCompile : PPCallbacks {
+ CompilerInstance &CI;
+ DependencyScanningService &Service;
+
+ AsyncModuleCompile(CompilerInstance &CI, DependencyScanningService &Service)
+ : CI(CI), Service(Service) {}
+
+ void moduleLoadSkipped(Module *M) override {
+ M = M->getTopLevelModule();
+
+ HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
+ ModuleCache &ModCache = CI.getModuleCache();
+ std::string ModuleFileName = HS.getCachedModuleFileName(M);
+
+ uint64_t Timestamp = ModCache.getModuleTimestamp(ModuleFileName);
+ // Someone else already built/validated the PCM.
+ if (Timestamp > CI.getHeaderSearchOpts().BuildSessionTimestamp)
+ return;
+
+ if (!CI.getASTReader())
+ CI.createASTReader();
+ SmallVector<ASTReader::ImportedModule, 0> Imported;
+ // Only calling ReadASTCore() to avoid the expensive eager deserialization
+ // of the clang::Module objects in ReadAST().
+ // FIXME: Consider doing this in the new thread depending on how expensive
+ // the read turns out to be.
+ switch (CI.getASTReader()->ReadASTCore(
+ ModuleFileName, serialization::MK_ImplicitModule, SourceLocation(),
+ nullptr, Imported, {}, {}, {},
+ ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing |
+ ASTReader::ARR_TreatModuleWithErrorsAsOutOfDate)) {
+ case ASTReader::Success:
+ // We successfully read a valid, up-to-date PCM.
+ // FIXME: This could update the timestamp. Regular calls to
+ // ASTReader::ReadAST() would do so unless they encountered corrupted
+ // AST block, corrupted extension block, or did not read the expected
+ // top-level module.
+ return;
+ case ASTReader::OutOfDate:
+ case ASTReader::Missing:
+ // The most interesting case.
+ break;
+ default:
+ // Let the regular scan diagnose this.
+ return;
+ }
+
+ ModCache.prepareForGetLock(ModuleFileName);
+ auto Lock = ModCache.getLock(ModuleFileName);
+ bool Owned;
+ llvm::Error LockErr = Lock->tryLock().moveInto(Owned);
+ // Someone else is building the PCM right now.
+ if (!LockErr && !Owned)
+ return;
+ // We should build the PCM.
+ // FIXME: Pass the correct BaseFS to the worker FS.
+ auto VFS = llvm::makeIntrusiveRefCnt<DependencyScanningWorkerFilesystem>(
+ Service.getSharedCache(), llvm::vfs::getRealFileSystem());
----------------
jansvoboda11 wrote:
I'm okay with merging this with the hard-coded
`llvm::vfs::getRealFileSystem()`. It matches what we actually use in our
builds, so I think the only implication is that this mode isn't as nicely
unit-testable as the normal scan, which I'm fine with. I'll fix this in a
follow-up.
I wrapped the VFS in `createVFSFromCompilerInvocation()` though, to fix a crash
and respect VFS overlays.
https://github.com/llvm/llvm-project/pull/180047
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits