|
12 | 12 | #include "clang/Frontend/FrontendAction.h"
|
13 | 13 | #include "clang/Frontend/FrontendActions.h"
|
14 | 14 | #include "clang/Serialization/ASTReader.h"
|
| 15 | +#include "clang/Serialization/InMemoryModuleCache.h" |
15 | 16 |
|
16 | 17 | namespace clang {
|
17 | 18 | namespace clangd {
|
@@ -127,50 +128,68 @@ struct ModuleFile {
|
127 | 128 | std::string ModuleFilePath;
|
128 | 129 | };
|
129 | 130 |
|
130 |
| -bool IsModuleFileUpToDate( |
131 |
| - PathRef ModuleFilePath, |
132 |
| - const PrerequisiteModules &RequisiteModules) { |
133 |
| -IntrusiveRefCntPtr<DiagnosticsEngine> Diags = |
134 |
| - CompilerInstance::createDiagnostics(new DiagnosticOptions()); |
135 |
| - |
| 131 | +bool IsModuleFileUpToDate(PathRef ModuleFilePath, |
| 132 | + const PrerequisiteModules &RequisiteModules, |
| 133 | + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) { |
136 | 134 | auto HSOpts = std::make_shared<HeaderSearchOptions>();
|
137 | 135 | RequisiteModules.adjustHeaderSearchOptions(*HSOpts);
|
138 | 136 | HSOpts->ForceCheckCXX20ModulesInputFiles = true;
|
139 | 137 | HSOpts->ValidateASTInputFilesContent = true;
|
140 | 138 |
|
| 139 | + clang::clangd::IgnoreDiagnostics IgnoreDiags; |
| 140 | + IntrusiveRefCntPtr<DiagnosticsEngine> Diags = |
| 141 | + CompilerInstance::createDiagnostics(new DiagnosticOptions, &IgnoreDiags, |
| 142 | + /*ShouldOwnClient=*/false); |
| 143 | + |
| 144 | + LangOptions LangOpts; |
| 145 | + LangOpts.SkipODRCheckInGMF = true; |
| 146 | + |
| 147 | + FileManager FileMgr(FileSystemOptions(), VFS); |
| 148 | + |
| 149 | + SourceManager SourceMgr(*Diags, FileMgr); |
| 150 | + |
| 151 | + HeaderSearch HeaderInfo(HSOpts, SourceMgr, *Diags, LangOpts, |
| 152 | + /*Target=*/nullptr); |
| 153 | + |
| 154 | + TrivialModuleLoader ModuleLoader; |
| 155 | + Preprocessor PP(std::make_shared<PreprocessorOptions>(), *Diags, LangOpts, |
| 156 | + SourceMgr, HeaderInfo, ModuleLoader); |
| 157 | + |
| 158 | + IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache = new InMemoryModuleCache; |
141 | 159 | PCHContainerOperations PCHOperations;
|
142 |
| - std::unique_ptr<ASTUnit> Unit = ASTUnit::LoadFromASTFile( |
143 |
| - ModuleFilePath.str(), PCHOperations.getRawReader(), ASTUnit::LoadASTOnly, |
144 |
| - Diags, FileSystemOptions(), std::move(HSOpts)); |
| 160 | + ASTReader Reader(PP, *ModuleCache, /*ASTContext=*/nullptr, |
| 161 | + PCHOperations.getRawReader(), {}); |
145 | 162 |
|
146 |
| - if (!Unit) |
147 |
| - return false; |
| 163 | + // We don't need any listener here. By default it will use a validator |
| 164 | + // listener. |
| 165 | + Reader.setListener(nullptr); |
148 | 166 |
|
149 |
| - auto Reader = Unit->getASTReader(); |
150 |
| - if (!Reader) |
| 167 | + if (Reader.ReadAST(ModuleFilePath, serialization::MK_MainFile, |
| 168 | + SourceLocation(), |
| 169 | + ASTReader::ARR_None) != ASTReader::Success) |
151 | 170 | return false;
|
152 | 171 |
|
153 | 172 | bool UpToDate = true;
|
154 |
| - Reader->getModuleManager().visit([&](serialization::ModuleFile &MF) -> bool { |
155 |
| - Reader->visitInputFiles( |
| 173 | + Reader.getModuleManager().visit([&](serialization::ModuleFile &MF) -> bool { |
| 174 | + Reader.visitInputFiles( |
156 | 175 | MF, /*IncludeSystem=*/false, /*Complain=*/false,
|
157 | 176 | [&](const serialization::InputFile &IF, bool isSystem) {
|
158 | 177 | if (!IF.getFile() || IF.isOutOfDate())
|
159 | 178 | UpToDate = false;
|
160 | 179 | });
|
161 |
| - |
162 | 180 | return !UpToDate;
|
163 | 181 | });
|
164 |
| - |
165 | 182 | return UpToDate;
|
166 | 183 | }
|
167 | 184 |
|
168 | 185 | bool IsModuleFilesUpToDate(
|
169 | 186 | llvm::SmallVector<PathRef> ModuleFilePaths,
|
170 |
| - const PrerequisiteModules &RequisiteModules) { |
171 |
| - return llvm::all_of(ModuleFilePaths, [&RequisiteModules](auto ModuleFilePath) { |
172 |
| - return IsModuleFileUpToDate(ModuleFilePath, RequisiteModules); |
173 |
| - }); |
| 187 | + const PrerequisiteModules &RequisiteModules, |
| 188 | + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) { |
| 189 | + return llvm::all_of( |
| 190 | + ModuleFilePaths, [&RequisiteModules, VFS](auto ModuleFilePath) { |
| 191 | + return IsModuleFileUpToDate(ModuleFilePath, RequisiteModules, VFS); |
| 192 | + }); |
174 | 193 | }
|
175 | 194 |
|
176 | 195 | // StandalonePrerequisiteModules - stands for PrerequisiteModules for which all
|
@@ -347,7 +366,7 @@ bool StandalonePrerequisiteModules::canReuse(
|
347 | 366 | SmallVector<StringRef> BMIPaths;
|
348 | 367 | for (auto &MF : RequiredModules)
|
349 | 368 | BMIPaths.push_back(MF.ModuleFilePath);
|
350 |
| - return IsModuleFilesUpToDate(BMIPaths, *this); |
| 369 | + return IsModuleFilesUpToDate(BMIPaths, *this, VFS); |
351 | 370 | }
|
352 | 371 |
|
353 | 372 | } // namespace clangd
|
|
0 commit comments