|
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