1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | #include "clang/Frontend/CompilerInstance.h" |
10 | #include "clang/AST/ASTConsumer.h" |
11 | #include "clang/AST/ASTContext.h" |
12 | #include "clang/AST/Decl.h" |
13 | #include "clang/Basic/CharInfo.h" |
14 | #include "clang/Basic/Diagnostic.h" |
15 | #include "clang/Basic/FileManager.h" |
16 | #include "clang/Basic/SourceManager.h" |
17 | #include "clang/Basic/Stack.h" |
18 | #include "clang/Basic/TargetInfo.h" |
19 | #include "clang/Basic/Version.h" |
20 | #include "clang/Config/config.h" |
21 | #include "clang/Frontend/ChainedDiagnosticConsumer.h" |
22 | #include "clang/Frontend/FrontendAction.h" |
23 | #include "clang/Frontend/FrontendActions.h" |
24 | #include "clang/Frontend/FrontendDiagnostic.h" |
25 | #include "clang/Frontend/LogDiagnosticPrinter.h" |
26 | #include "clang/Frontend/SerializedDiagnosticPrinter.h" |
27 | #include "clang/Frontend/TextDiagnosticPrinter.h" |
28 | #include "clang/Frontend/Utils.h" |
29 | #include "clang/Frontend/VerifyDiagnosticConsumer.h" |
30 | #include "clang/Lex/HeaderSearch.h" |
31 | #include "clang/Lex/Preprocessor.h" |
32 | #include "clang/Lex/PreprocessorOptions.h" |
33 | #include "clang/Sema/CodeCompleteConsumer.h" |
34 | #include "clang/Sema/Sema.h" |
35 | #include "clang/Serialization/ASTReader.h" |
36 | #include "clang/Serialization/GlobalModuleIndex.h" |
37 | #include "clang/Serialization/InMemoryModuleCache.h" |
38 | #include "llvm/ADT/Statistic.h" |
39 | #include "llvm/Support/BuryPointer.h" |
40 | #include "llvm/Support/CrashRecoveryContext.h" |
41 | #include "llvm/Support/Errc.h" |
42 | #include "llvm/Support/FileSystem.h" |
43 | #include "llvm/Support/Host.h" |
44 | #include "llvm/Support/LockFileManager.h" |
45 | #include "llvm/Support/MemoryBuffer.h" |
46 | #include "llvm/Support/Path.h" |
47 | #include "llvm/Support/Program.h" |
48 | #include "llvm/Support/Signals.h" |
49 | #include "llvm/Support/Timer.h" |
50 | #include "llvm/Support/raw_ostream.h" |
51 | #include <sys/stat.h> |
52 | #include <system_error> |
53 | #include <time.h> |
54 | #include <utility> |
55 | |
56 | using namespace clang; |
57 | |
58 | CompilerInstance::CompilerInstance( |
59 | std::shared_ptr<PCHContainerOperations> PCHContainerOps, |
60 | InMemoryModuleCache *SharedModuleCache) |
61 | : ModuleLoader( SharedModuleCache), |
62 | Invocation(new CompilerInvocation()), |
63 | ModuleCache(SharedModuleCache ? SharedModuleCache |
64 | : new InMemoryModuleCache), |
65 | ThePCHContainerOperations(std::move(PCHContainerOps)) {} |
66 | |
67 | CompilerInstance::~CompilerInstance() { |
68 | (0) . __assert_fail ("OutputFiles.empty() && \"Still output files in flight?\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/CompilerInstance.cpp", 68, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(OutputFiles.empty() && "Still output files in flight?"); |
69 | } |
70 | |
71 | void CompilerInstance::setInvocation( |
72 | std::shared_ptr<CompilerInvocation> Value) { |
73 | Invocation = std::move(Value); |
74 | } |
75 | |
76 | bool CompilerInstance::shouldBuildGlobalModuleIndex() const { |
77 | return (BuildGlobalModuleIndex || |
78 | (ModuleManager && ModuleManager->isGlobalIndexUnavailable() && |
79 | getFrontendOpts().GenerateGlobalModuleIndex)) && |
80 | !ModuleBuildFailed; |
81 | } |
82 | |
83 | void CompilerInstance::setDiagnostics(DiagnosticsEngine *Value) { |
84 | Diagnostics = Value; |
85 | } |
86 | |
87 | void CompilerInstance::setTarget(TargetInfo *Value) { Target = Value; } |
88 | void CompilerInstance::setAuxTarget(TargetInfo *Value) { AuxTarget = Value; } |
89 | |
90 | void CompilerInstance::setFileManager(FileManager *Value) { |
91 | FileMgr = Value; |
92 | } |
93 | |
94 | void CompilerInstance::setSourceManager(SourceManager *Value) { |
95 | SourceMgr = Value; |
96 | } |
97 | |
98 | void CompilerInstance::setPreprocessor(std::shared_ptr<Preprocessor> Value) { |
99 | PP = std::move(Value); |
100 | } |
101 | |
102 | void CompilerInstance::setASTContext(ASTContext *Value) { |
103 | Context = Value; |
104 | |
105 | if (Context && Consumer) |
106 | getASTConsumer().Initialize(getASTContext()); |
107 | } |
108 | |
109 | void CompilerInstance::setSema(Sema *S) { |
110 | TheSema.reset(S); |
111 | } |
112 | |
113 | void CompilerInstance::setASTConsumer(std::unique_ptr<ASTConsumer> Value) { |
114 | Consumer = std::move(Value); |
115 | |
116 | if (Context && Consumer) |
117 | getASTConsumer().Initialize(getASTContext()); |
118 | } |
119 | |
120 | void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) { |
121 | CompletionConsumer.reset(Value); |
122 | } |
123 | |
124 | std::unique_ptr<Sema> CompilerInstance::takeSema() { |
125 | return std::move(TheSema); |
126 | } |
127 | |
128 | IntrusiveRefCntPtr<ASTReader> CompilerInstance::getModuleManager() const { |
129 | return ModuleManager; |
130 | } |
131 | void CompilerInstance::setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader) { |
132 | (0) . __assert_fail ("ModuleCache.get() == &Reader->getModuleManager().getModuleCache() && \"Expected ASTReader to use the same PCM cache\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/CompilerInstance.cpp", 133, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ModuleCache.get() == &Reader->getModuleManager().getModuleCache() && |
133 | (0) . __assert_fail ("ModuleCache.get() == &Reader->getModuleManager().getModuleCache() && \"Expected ASTReader to use the same PCM cache\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/CompilerInstance.cpp", 133, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Expected ASTReader to use the same PCM cache"); |
134 | ModuleManager = std::move(Reader); |
135 | } |
136 | |
137 | std::shared_ptr<ModuleDependencyCollector> |
138 | CompilerInstance::getModuleDepCollector() const { |
139 | return ModuleDepCollector; |
140 | } |
141 | |
142 | void CompilerInstance::setModuleDepCollector( |
143 | std::shared_ptr<ModuleDependencyCollector> Collector) { |
144 | ModuleDepCollector = std::move(Collector); |
145 | } |
146 | |
147 | static void (const HeaderSearch &HS, |
148 | std::shared_ptr<ModuleDependencyCollector> MDC) { |
149 | SmallVector<std::string, 4> ; |
150 | HS.getHeaderMapFileNames(HeaderMapFileNames); |
151 | for (auto &Name : HeaderMapFileNames) |
152 | MDC->addFile(Name); |
153 | } |
154 | |
155 | static void collectIncludePCH(CompilerInstance &CI, |
156 | std::shared_ptr<ModuleDependencyCollector> MDC) { |
157 | const PreprocessorOptions &PPOpts = CI.getPreprocessorOpts(); |
158 | if (PPOpts.ImplicitPCHInclude.empty()) |
159 | return; |
160 | |
161 | StringRef PCHInclude = PPOpts.ImplicitPCHInclude; |
162 | FileManager &FileMgr = CI.getFileManager(); |
163 | const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude); |
164 | if (!PCHDir) { |
165 | MDC->addFile(PCHInclude); |
166 | return; |
167 | } |
168 | |
169 | std::error_code EC; |
170 | SmallString<128> DirNative; |
171 | llvm::sys::path::native(PCHDir->getName(), DirNative); |
172 | llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem(); |
173 | SimpleASTReaderListener Validator(CI.getPreprocessor()); |
174 | for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd; |
175 | Dir != DirEnd && !EC; Dir.increment(EC)) { |
176 | |
177 | |
178 | |
179 | if (!ASTReader::readASTFileControlBlock( |
180 | Dir->path(), FileMgr, CI.getPCHContainerReader(), |
181 | , Validator, |
182 | )) |
183 | MDC->addFile(Dir->path()); |
184 | } |
185 | } |
186 | |
187 | static void collectVFSEntries(CompilerInstance &CI, |
188 | std::shared_ptr<ModuleDependencyCollector> MDC) { |
189 | if (CI.getHeaderSearchOpts().VFSOverlayFiles.empty()) |
190 | return; |
191 | |
192 | |
193 | SmallVector<llvm::vfs::YAMLVFSEntry, 16> VFSEntries; |
194 | for (const std::string &VFSFile : CI.getHeaderSearchOpts().VFSOverlayFiles) { |
195 | llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer = |
196 | llvm::MemoryBuffer::getFile(VFSFile); |
197 | if (!Buffer) |
198 | return; |
199 | llvm::vfs::collectVFSFromYAML(std::move(Buffer.get()), |
200 | nullptr, VFSFile, VFSEntries); |
201 | } |
202 | |
203 | for (auto &E : VFSEntries) |
204 | MDC->addFile(E.VPath, E.RPath); |
205 | } |
206 | |
207 | |
208 | static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts, |
209 | const CodeGenOptions *CodeGenOpts, |
210 | DiagnosticsEngine &Diags) { |
211 | std::error_code EC; |
212 | std::unique_ptr<raw_ostream> StreamOwner; |
213 | raw_ostream *OS = &llvm::errs(); |
214 | if (DiagOpts->DiagnosticLogFile != "-") { |
215 | |
216 | auto FileOS = llvm::make_unique<llvm::raw_fd_ostream>( |
217 | DiagOpts->DiagnosticLogFile, EC, |
218 | llvm::sys::fs::F_Append | llvm::sys::fs::F_Text); |
219 | if (EC) { |
220 | Diags.Report(diag::warn_fe_cc_log_diagnostics_failure) |
221 | << DiagOpts->DiagnosticLogFile << EC.message(); |
222 | } else { |
223 | FileOS->SetUnbuffered(); |
224 | OS = FileOS.get(); |
225 | StreamOwner = std::move(FileOS); |
226 | } |
227 | } |
228 | |
229 | |
230 | auto Logger = llvm::make_unique<LogDiagnosticPrinter>(*OS, DiagOpts, |
231 | std::move(StreamOwner)); |
232 | if (CodeGenOpts) |
233 | Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags); |
234 | assert(Diags.ownsClient()); |
235 | Diags.setClient( |
236 | new ChainedDiagnosticConsumer(Diags.takeClient(), std::move(Logger))); |
237 | } |
238 | |
239 | static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts, |
240 | DiagnosticsEngine &Diags, |
241 | StringRef OutputFile) { |
242 | auto SerializedConsumer = |
243 | clang::serialized_diags::create(OutputFile, DiagOpts); |
244 | |
245 | if (Diags.ownsClient()) { |
246 | Diags.setClient(new ChainedDiagnosticConsumer( |
247 | Diags.takeClient(), std::move(SerializedConsumer))); |
248 | } else { |
249 | Diags.setClient(new ChainedDiagnosticConsumer( |
250 | Diags.getClient(), std::move(SerializedConsumer))); |
251 | } |
252 | } |
253 | |
254 | void CompilerInstance::createDiagnostics(DiagnosticConsumer *Client, |
255 | bool ShouldOwnClient) { |
256 | Diagnostics = createDiagnostics(&getDiagnosticOpts(), Client, |
257 | ShouldOwnClient, &getCodeGenOpts()); |
258 | } |
259 | |
260 | IntrusiveRefCntPtr<DiagnosticsEngine> |
261 | CompilerInstance::createDiagnostics(DiagnosticOptions *Opts, |
262 | DiagnosticConsumer *Client, |
263 | bool ShouldOwnClient, |
264 | const CodeGenOptions *CodeGenOpts) { |
265 | IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); |
266 | IntrusiveRefCntPtr<DiagnosticsEngine> |
267 | Diags(new DiagnosticsEngine(DiagID, Opts)); |
268 | |
269 | |
270 | |
271 | if (Client) { |
272 | Diags->setClient(Client, ShouldOwnClient); |
273 | } else |
274 | Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts)); |
275 | |
276 | |
277 | if (Opts->VerifyDiagnostics) |
278 | Diags->setClient(new VerifyDiagnosticConsumer(*Diags)); |
279 | |
280 | |
281 | if (!Opts->DiagnosticLogFile.empty()) |
282 | SetUpDiagnosticLog(Opts, CodeGenOpts, *Diags); |
283 | |
284 | if (!Opts->DiagnosticSerializationFile.empty()) |
285 | SetupSerializedDiagnostics(Opts, *Diags, |
286 | Opts->DiagnosticSerializationFile); |
287 | |
288 | |
289 | ProcessWarningOptions(*Diags, *Opts); |
290 | |
291 | return Diags; |
292 | } |
293 | |
294 | |
295 | |
296 | FileManager *CompilerInstance::createFileManager( |
297 | IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) { |
298 | if (!VFS) |
299 | VFS = FileMgr ? &FileMgr->getVirtualFileSystem() |
300 | : createVFSFromCompilerInvocation(getInvocation(), |
301 | getDiagnostics()); |
302 | (0) . __assert_fail ("VFS && \"FileManager has no VFS?\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/CompilerInstance.cpp", 302, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(VFS && "FileManager has no VFS?"); |
303 | FileMgr = new FileManager(getFileSystemOpts(), std::move(VFS)); |
304 | return FileMgr.get(); |
305 | } |
306 | |
307 | |
308 | |
309 | void CompilerInstance::createSourceManager(FileManager &FileMgr) { |
310 | SourceMgr = new SourceManager(getDiagnostics(), FileMgr); |
311 | } |
312 | |
313 | |
314 | |
315 | static void InitializeFileRemapping(DiagnosticsEngine &Diags, |
316 | SourceManager &SourceMgr, |
317 | FileManager &FileMgr, |
318 | const PreprocessorOptions &InitOpts) { |
319 | |
320 | for (const auto &RB : InitOpts.RemappedFileBuffers) { |
321 | |
322 | const FileEntry *FromFile = |
323 | FileMgr.getVirtualFile(RB.first, RB.second->getBufferSize(), 0); |
324 | if (!FromFile) { |
325 | Diags.Report(diag::err_fe_remap_missing_from_file) << RB.first; |
326 | if (!InitOpts.RetainRemappedFileBuffers) |
327 | delete RB.second; |
328 | continue; |
329 | } |
330 | |
331 | |
332 | |
333 | SourceMgr.overrideFileContents(FromFile, RB.second, |
334 | InitOpts.RetainRemappedFileBuffers); |
335 | } |
336 | |
337 | |
338 | for (const auto &RF : InitOpts.RemappedFiles) { |
339 | |
340 | const FileEntry *ToFile = FileMgr.getFile(RF.second); |
341 | if (!ToFile) { |
342 | Diags.Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second; |
343 | continue; |
344 | } |
345 | |
346 | |
347 | const FileEntry *FromFile = |
348 | FileMgr.getVirtualFile(RF.first, ToFile->getSize(), 0); |
349 | if (!FromFile) { |
350 | Diags.Report(diag::err_fe_remap_missing_from_file) << RF.first; |
351 | continue; |
352 | } |
353 | |
354 | |
355 | |
356 | SourceMgr.overrideFileContents(FromFile, ToFile); |
357 | } |
358 | |
359 | SourceMgr.setOverridenFilesKeepOriginalName( |
360 | InitOpts.RemappedFilesKeepOriginalName); |
361 | } |
362 | |
363 | |
364 | |
365 | void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) { |
366 | const PreprocessorOptions &PPOpts = getPreprocessorOpts(); |
367 | |
368 | |
369 | ModuleManager.reset(); |
370 | |
371 | |
372 | HeaderSearch * = |
373 | new HeaderSearch(getHeaderSearchOptsPtr(), getSourceManager(), |
374 | getDiagnostics(), getLangOpts(), &getTarget()); |
375 | PP = std::make_shared<Preprocessor>(Invocation->getPreprocessorOptsPtr(), |
376 | getDiagnostics(), getLangOpts(), |
377 | getSourceManager(), *HeaderInfo, *this, |
378 | , |
379 | , TUKind); |
380 | getTarget().adjust(getLangOpts()); |
381 | PP->Initialize(getTarget(), getAuxTarget()); |
382 | |
383 | if (PPOpts.DetailedRecord) |
384 | PP->createPreprocessingRecord(); |
385 | |
386 | |
387 | InitializeFileRemapping(PP->getDiagnostics(), PP->getSourceManager(), |
388 | PP->getFileManager(), PPOpts); |
389 | |
390 | |
391 | InitializePreprocessor(*PP, PPOpts, getPCHContainerReader(), |
392 | getFrontendOpts()); |
393 | |
394 | |
395 | |
396 | |
397 | const llvm::Triple * = &PP->getTargetInfo().getTriple(); |
398 | if (PP->getTargetInfo().getTriple().getOS() == llvm::Triple::CUDA && |
399 | PP->getAuxTargetInfo()) |
400 | HeaderSearchTriple = &PP->getAuxTargetInfo()->getTriple(); |
401 | |
402 | ApplyHeaderSearchOptions(PP->getHeaderSearchInfo(), getHeaderSearchOpts(), |
403 | PP->getLangOpts(), *HeaderSearchTriple); |
404 | |
405 | PP->setPreprocessedOutput(getPreprocessorOutputOpts().ShowCPP); |
406 | |
407 | if (PP->getLangOpts().Modules && PP->getLangOpts().ImplicitModules) |
408 | PP->getHeaderSearchInfo().setModuleCachePath(getSpecificModuleCachePath()); |
409 | |
410 | |
411 | const DependencyOutputOptions &DepOpts = getDependencyOutputOpts(); |
412 | if (!DepOpts.OutputFile.empty()) |
413 | TheDependencyFileGenerator.reset( |
414 | DependencyFileGenerator::CreateAndAttachToPreprocessor(*PP, DepOpts)); |
415 | if (!DepOpts.DOTOutputFile.empty()) |
416 | AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile, |
417 | getHeaderSearchOpts().Sysroot); |
418 | |
419 | |
420 | |
421 | if (!ModuleDepCollector && !DepOpts.ModuleDependencyOutputDir.empty()) { |
422 | ModuleDepCollector = std::make_shared<ModuleDependencyCollector>( |
423 | DepOpts.ModuleDependencyOutputDir); |
424 | } |
425 | |
426 | |
427 | |
428 | if (ModuleDepCollector) { |
429 | addDependencyCollector(ModuleDepCollector); |
430 | collectHeaderMaps(PP->getHeaderSearchInfo(), ModuleDepCollector); |
431 | collectIncludePCH(*this, ModuleDepCollector); |
432 | collectVFSEntries(*this, ModuleDepCollector); |
433 | } |
434 | |
435 | for (auto &Listener : DependencyCollectors) |
436 | Listener->attachToPreprocessor(*PP); |
437 | |
438 | |
439 | if (DepOpts.ShowHeaderIncludes) |
440 | AttachHeaderIncludeGen(*PP, DepOpts); |
441 | if (!DepOpts.HeaderIncludeOutputFile.empty()) { |
442 | StringRef OutputPath = DepOpts.HeaderIncludeOutputFile; |
443 | if (OutputPath == "-") |
444 | OutputPath = ""; |
445 | AttachHeaderIncludeGen(*PP, DepOpts, |
446 | , OutputPath, |
447 | ); |
448 | } |
449 | |
450 | if (DepOpts.ShowIncludesDest != ShowIncludesDestination::None) { |
451 | AttachHeaderIncludeGen(*PP, DepOpts, |
452 | , , |
453 | , ); |
454 | } |
455 | } |
456 | |
457 | std::string CompilerInstance::getSpecificModuleCachePath() { |
458 | |
459 | |
460 | SmallString<256> SpecificModuleCache(getHeaderSearchOpts().ModuleCachePath); |
461 | if (!SpecificModuleCache.empty() && !getHeaderSearchOpts().DisableModuleHash) |
462 | llvm::sys::path::append(SpecificModuleCache, |
463 | getInvocation().getModuleHash()); |
464 | return SpecificModuleCache.str(); |
465 | } |
466 | |
467 | |
468 | |
469 | void CompilerInstance::createASTContext() { |
470 | Preprocessor &PP = getPreprocessor(); |
471 | auto *Context = new ASTContext(getLangOpts(), PP.getSourceManager(), |
472 | PP.getIdentifierTable(), PP.getSelectorTable(), |
473 | PP.getBuiltinInfo()); |
474 | Context->InitBuiltinTypes(getTarget(), getAuxTarget()); |
475 | setASTContext(Context); |
476 | } |
477 | |
478 | |
479 | |
480 | void CompilerInstance::createPCHExternalASTSource( |
481 | StringRef Path, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors, |
482 | void *DeserializationListener, bool OwnDeserializationListener) { |
483 | bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0; |
484 | ModuleManager = createPCHExternalASTSource( |
485 | Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation, |
486 | AllowPCHWithCompilerErrors, getPreprocessor(), getModuleCache(), |
487 | getASTContext(), getPCHContainerReader(), |
488 | getFrontendOpts().ModuleFileExtensions, TheDependencyFileGenerator.get(), |
489 | DependencyCollectors, DeserializationListener, OwnDeserializationListener, |
490 | Preamble, getFrontendOpts().UseGlobalModuleIndex); |
491 | } |
492 | |
493 | IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource( |
494 | StringRef Path, StringRef Sysroot, bool DisablePCHValidation, |
495 | bool AllowPCHWithCompilerErrors, Preprocessor &PP, |
496 | InMemoryModuleCache &ModuleCache, ASTContext &Context, |
497 | const PCHContainerReader &PCHContainerRdr, |
498 | ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, |
499 | DependencyFileGenerator *DependencyFile, |
500 | ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors, |
501 | void *DeserializationListener, bool OwnDeserializationListener, |
502 | bool Preamble, bool UseGlobalModuleIndex) { |
503 | HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts(); |
504 | |
505 | IntrusiveRefCntPtr<ASTReader> Reader(new ASTReader( |
506 | PP, ModuleCache, &Context, PCHContainerRdr, Extensions, |
507 | Sysroot.empty() ? "" : Sysroot.data(), DisablePCHValidation, |
508 | AllowPCHWithCompilerErrors, false, |
509 | HSOpts.ModulesValidateSystemHeaders, UseGlobalModuleIndex)); |
510 | |
511 | |
512 | |
513 | Context.setExternalSource(Reader.get()); |
514 | |
515 | Reader->setDeserializationListener( |
516 | static_cast<ASTDeserializationListener *>(DeserializationListener), |
517 | OwnDeserializationListener); |
518 | |
519 | if (DependencyFile) |
520 | DependencyFile->AttachToASTReader(*Reader); |
521 | for (auto &Listener : DependencyCollectors) |
522 | Listener->attachToASTReader(*Reader); |
523 | |
524 | switch (Reader->ReadAST(Path, |
525 | Preamble ? serialization::MK_Preamble |
526 | : serialization::MK_PCH, |
527 | SourceLocation(), |
528 | ASTReader::ARR_None)) { |
529 | case ASTReader::Success: |
530 | |
531 | |
532 | PP.setPredefines(Reader->getSuggestedPredefines()); |
533 | return Reader; |
534 | |
535 | case ASTReader::Failure: |
536 | |
537 | break; |
538 | |
539 | case ASTReader::Missing: |
540 | case ASTReader::OutOfDate: |
541 | case ASTReader::VersionMismatch: |
542 | case ASTReader::ConfigurationMismatch: |
543 | case ASTReader::HadErrors: |
544 | |
545 | break; |
546 | } |
547 | |
548 | Context.setExternalSource(nullptr); |
549 | return nullptr; |
550 | } |
551 | |
552 | |
553 | |
554 | static bool EnableCodeCompletion(Preprocessor &PP, |
555 | StringRef Filename, |
556 | unsigned Line, |
557 | unsigned Column) { |
558 | |
559 | |
560 | const FileEntry *Entry = PP.getFileManager().getFile(Filename); |
561 | if (!Entry) { |
562 | PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file) |
563 | << Filename; |
564 | return true; |
565 | } |
566 | |
567 | |
568 | PP.SetCodeCompletionPoint(Entry, Line, Column); |
569 | return false; |
570 | } |
571 | |
572 | void CompilerInstance::createCodeCompletionConsumer() { |
573 | const ParsedSourceLocation &Loc = getFrontendOpts().CodeCompletionAt; |
574 | if (!CompletionConsumer) { |
575 | setCodeCompletionConsumer( |
576 | createCodeCompletionConsumer(getPreprocessor(), |
577 | Loc.FileName, Loc.Line, Loc.Column, |
578 | getFrontendOpts().CodeCompleteOpts, |
579 | llvm::outs())); |
580 | if (!CompletionConsumer) |
581 | return; |
582 | } else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName, |
583 | Loc.Line, Loc.Column)) { |
584 | setCodeCompletionConsumer(nullptr); |
585 | return; |
586 | } |
587 | |
588 | if (CompletionConsumer->isOutputBinary() && |
589 | llvm::sys::ChangeStdoutToBinary()) { |
590 | getPreprocessor().getDiagnostics().Report(diag::err_fe_stdout_binary); |
591 | setCodeCompletionConsumer(nullptr); |
592 | } |
593 | } |
594 | |
595 | void CompilerInstance::createFrontendTimer() { |
596 | FrontendTimerGroup.reset( |
597 | new llvm::TimerGroup("frontend", "Clang front-end time report")); |
598 | FrontendTimer.reset( |
599 | new llvm::Timer("frontend", "Clang front-end timer", |
600 | *FrontendTimerGroup)); |
601 | } |
602 | |
603 | CodeCompleteConsumer * |
604 | CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP, |
605 | StringRef Filename, |
606 | unsigned Line, |
607 | unsigned Column, |
608 | const CodeCompleteOptions &Opts, |
609 | raw_ostream &OS) { |
610 | if (EnableCodeCompletion(PP, Filename, Line, Column)) |
611 | return nullptr; |
612 | |
613 | |
614 | return new PrintingCodeCompleteConsumer(Opts, OS); |
615 | } |
616 | |
617 | void CompilerInstance::createSema(TranslationUnitKind TUKind, |
618 | CodeCompleteConsumer *CompletionConsumer) { |
619 | TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(), |
620 | TUKind, CompletionConsumer)); |
621 | |
622 | if (ExternalSemaSrc) { |
623 | TheSema->addExternalSource(ExternalSemaSrc.get()); |
624 | ExternalSemaSrc->InitializeSema(*TheSema); |
625 | } |
626 | } |
627 | |
628 | |
629 | |
630 | void CompilerInstance::addOutputFile(OutputFile &&OutFile) { |
631 | OutputFiles.push_back(std::move(OutFile)); |
632 | } |
633 | |
634 | void CompilerInstance::clearOutputFiles(bool EraseFiles) { |
635 | for (OutputFile &OF : OutputFiles) { |
636 | if (!OF.TempFilename.empty()) { |
637 | if (EraseFiles) { |
638 | llvm::sys::fs::remove(OF.TempFilename); |
639 | } else { |
640 | SmallString<128> NewOutFile(OF.Filename); |
641 | |
642 | |
643 | |
644 | FileMgr->FixupRelativePath(NewOutFile); |
645 | if (std::error_code ec = |
646 | llvm::sys::fs::rename(OF.TempFilename, NewOutFile)) { |
647 | getDiagnostics().Report(diag::err_unable_to_rename_temp) |
648 | << OF.TempFilename << OF.Filename << ec.message(); |
649 | |
650 | llvm::sys::fs::remove(OF.TempFilename); |
651 | } |
652 | } |
653 | } else if (!OF.Filename.empty() && EraseFiles) |
654 | llvm::sys::fs::remove(OF.Filename); |
655 | } |
656 | OutputFiles.clear(); |
657 | if (DeleteBuiltModules) { |
658 | for (auto &Module : BuiltModules) |
659 | llvm::sys::fs::remove(Module.second); |
660 | BuiltModules.clear(); |
661 | } |
662 | NonSeekStream.reset(); |
663 | } |
664 | |
665 | std::unique_ptr<raw_pwrite_stream> |
666 | CompilerInstance::createDefaultOutputFile(bool Binary, StringRef InFile, |
667 | StringRef Extension) { |
668 | return createOutputFile(getFrontendOpts().OutputFile, Binary, |
669 | , InFile, Extension, |
670 | ); |
671 | } |
672 | |
673 | std::unique_ptr<raw_pwrite_stream> CompilerInstance::createNullOutputFile() { |
674 | return llvm::make_unique<llvm::raw_null_ostream>(); |
675 | } |
676 | |
677 | std::unique_ptr<raw_pwrite_stream> |
678 | CompilerInstance::createOutputFile(StringRef OutputPath, bool Binary, |
679 | bool RemoveFileOnSignal, StringRef InFile, |
680 | StringRef Extension, bool UseTemporary, |
681 | bool CreateMissingDirectories) { |
682 | std::string OutputPathName, TempPathName; |
683 | std::error_code EC; |
684 | std::unique_ptr<raw_pwrite_stream> OS = createOutputFile( |
685 | OutputPath, EC, Binary, RemoveFileOnSignal, InFile, Extension, |
686 | UseTemporary, CreateMissingDirectories, &OutputPathName, &TempPathName); |
687 | if (!OS) { |
688 | getDiagnostics().Report(diag::err_fe_unable_to_open_output) << OutputPath |
689 | << EC.message(); |
690 | return nullptr; |
691 | } |
692 | |
693 | |
694 | |
695 | addOutputFile( |
696 | OutputFile((OutputPathName != "-") ? OutputPathName : "", TempPathName)); |
697 | |
698 | return OS; |
699 | } |
700 | |
701 | std::unique_ptr<llvm::raw_pwrite_stream> CompilerInstance::createOutputFile( |
702 | StringRef OutputPath, std::error_code &Error, bool Binary, |
703 | bool RemoveFileOnSignal, StringRef InFile, StringRef Extension, |
704 | bool UseTemporary, bool CreateMissingDirectories, |
705 | std::string *ResultPathName, std::string *TempPathName) { |
706 | (0) . __assert_fail ("(!CreateMissingDirectories || UseTemporary) && \"CreateMissingDirectories is only allowed when using temporary files\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/CompilerInstance.cpp", 707, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((!CreateMissingDirectories || UseTemporary) && |
707 | (0) . __assert_fail ("(!CreateMissingDirectories || UseTemporary) && \"CreateMissingDirectories is only allowed when using temporary files\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/CompilerInstance.cpp", 707, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "CreateMissingDirectories is only allowed when using temporary files"); |
708 | |
709 | std::string OutFile, TempFile; |
710 | if (!OutputPath.empty()) { |
711 | OutFile = OutputPath; |
712 | } else if (InFile == "-") { |
713 | OutFile = "-"; |
714 | } else if (!Extension.empty()) { |
715 | SmallString<128> Path(InFile); |
716 | llvm::sys::path::replace_extension(Path, Extension); |
717 | OutFile = Path.str(); |
718 | } else { |
719 | OutFile = "-"; |
720 | } |
721 | |
722 | std::unique_ptr<llvm::raw_fd_ostream> OS; |
723 | std::string OSFile; |
724 | |
725 | if (UseTemporary) { |
726 | if (OutFile == "-") |
727 | UseTemporary = false; |
728 | else { |
729 | llvm::sys::fs::file_status Status; |
730 | llvm::sys::fs::status(OutputPath, Status); |
731 | if (llvm::sys::fs::exists(Status)) { |
732 | |
733 | if (!llvm::sys::fs::can_write(OutputPath)) { |
734 | Error = make_error_code(llvm::errc::operation_not_permitted); |
735 | return nullptr; |
736 | } |
737 | |
738 | |
739 | |
740 | if (!llvm::sys::fs::is_regular_file(Status)) |
741 | UseTemporary = false; |
742 | } |
743 | } |
744 | } |
745 | |
746 | if (UseTemporary) { |
747 | |
748 | |
749 | |
750 | |
751 | StringRef OutputExtension = llvm::sys::path::extension(OutFile); |
752 | SmallString<128> TempPath = |
753 | StringRef(OutFile).drop_back(OutputExtension.size()); |
754 | TempPath += "-%%%%%%%%"; |
755 | TempPath += OutputExtension; |
756 | TempPath += ".tmp"; |
757 | int fd; |
758 | std::error_code EC = |
759 | llvm::sys::fs::createUniqueFile(TempPath, fd, TempPath); |
760 | |
761 | if (CreateMissingDirectories && |
762 | EC == llvm::errc::no_such_file_or_directory) { |
763 | StringRef Parent = llvm::sys::path::parent_path(OutputPath); |
764 | EC = llvm::sys::fs::create_directories(Parent); |
765 | if (!EC) { |
766 | EC = llvm::sys::fs::createUniqueFile(TempPath, fd, TempPath); |
767 | } |
768 | } |
769 | |
770 | if (!EC) { |
771 | OS.reset(new llvm::raw_fd_ostream(fd, )); |
772 | OSFile = TempFile = TempPath.str(); |
773 | } |
774 | |
775 | |
776 | |
777 | } |
778 | |
779 | if (!OS) { |
780 | OSFile = OutFile; |
781 | OS.reset(new llvm::raw_fd_ostream( |
782 | OSFile, Error, |
783 | (Binary ? llvm::sys::fs::F_None : llvm::sys::fs::F_Text))); |
784 | if (Error) |
785 | return nullptr; |
786 | } |
787 | |
788 | |
789 | if (RemoveFileOnSignal) |
790 | llvm::sys::RemoveFileOnSignal(OSFile); |
791 | |
792 | if (ResultPathName) |
793 | *ResultPathName = OutFile; |
794 | if (TempPathName) |
795 | *TempPathName = TempFile; |
796 | |
797 | if (!Binary || OS->supportsSeeking()) |
798 | return std::move(OS); |
799 | |
800 | auto B = llvm::make_unique<llvm::buffer_ostream>(*OS); |
801 | assert(!NonSeekStream); |
802 | NonSeekStream = std::move(OS); |
803 | return std::move(B); |
804 | } |
805 | |
806 | |
807 | |
808 | bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input){ |
809 | return InitializeSourceManager( |
810 | Input, getDiagnostics(), getFileManager(), getSourceManager(), |
811 | hasPreprocessor() ? &getPreprocessor().getHeaderSearchInfo() : nullptr, |
812 | getDependencyOutputOpts(), getFrontendOpts()); |
813 | } |
814 | |
815 | |
816 | bool CompilerInstance::( |
817 | const FrontendInputFile &Input, DiagnosticsEngine &Diags, |
818 | FileManager &FileMgr, SourceManager &SourceMgr, HeaderSearch *HS, |
819 | DependencyOutputOptions &DepOpts, const FrontendOptions &Opts) { |
820 | SrcMgr::CharacteristicKind Kind = |
821 | Input.getKind().getFormat() == InputKind::ModuleMap |
822 | ? Input.isSystem() ? SrcMgr::C_System_ModuleMap |
823 | : SrcMgr::C_User_ModuleMap |
824 | : Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User; |
825 | |
826 | if (Input.isBuffer()) { |
827 | SourceMgr.setMainFileID(SourceMgr.createFileID(SourceManager::Unowned, |
828 | Input.getBuffer(), Kind)); |
829 | (0) . __assert_fail ("SourceMgr.getMainFileID().isValid() && \"Couldn't establish MainFileID!\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/CompilerInstance.cpp", 830, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(SourceMgr.getMainFileID().isValid() && |
830 | (0) . __assert_fail ("SourceMgr.getMainFileID().isValid() && \"Couldn't establish MainFileID!\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/CompilerInstance.cpp", 830, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Couldn't establish MainFileID!"); |
831 | return true; |
832 | } |
833 | |
834 | StringRef InputFile = Input.getFile(); |
835 | |
836 | |
837 | if (InputFile != "-") { |
838 | const FileEntry *File = FileMgr.getFile(InputFile, ); |
839 | if (!File) { |
840 | Diags.Report(diag::err_fe_error_reading) << InputFile; |
841 | return false; |
842 | } |
843 | |
844 | |
845 | |
846 | |
847 | |
848 | |
849 | if (File->isNamedPipe()) { |
850 | auto MB = FileMgr.getBufferForFile(File, ); |
851 | if (MB) { |
852 | |
853 | File = FileMgr.getVirtualFile(InputFile, (*MB)->getBufferSize(), 0); |
854 | SourceMgr.overrideFileContents(File, std::move(*MB)); |
855 | } else { |
856 | Diags.Report(diag::err_cannot_open_file) << InputFile |
857 | << MB.getError().message(); |
858 | return false; |
859 | } |
860 | } |
861 | |
862 | SourceMgr.setMainFileID( |
863 | SourceMgr.createFileID(File, SourceLocation(), Kind)); |
864 | } else { |
865 | llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> SBOrErr = |
866 | llvm::MemoryBuffer::getSTDIN(); |
867 | if (std::error_code EC = SBOrErr.getError()) { |
868 | Diags.Report(diag::err_fe_error_reading_stdin) << EC.message(); |
869 | return false; |
870 | } |
871 | std::unique_ptr<llvm::MemoryBuffer> SB = std::move(SBOrErr.get()); |
872 | |
873 | const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(), |
874 | SB->getBufferSize(), 0); |
875 | SourceMgr.setMainFileID( |
876 | SourceMgr.createFileID(File, SourceLocation(), Kind)); |
877 | SourceMgr.overrideFileContents(File, std::move(SB)); |
878 | } |
879 | |
880 | (0) . __assert_fail ("SourceMgr.getMainFileID().isValid() && \"Couldn't establish MainFileID!\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/CompilerInstance.cpp", 881, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(SourceMgr.getMainFileID().isValid() && |
881 | (0) . __assert_fail ("SourceMgr.getMainFileID().isValid() && \"Couldn't establish MainFileID!\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/CompilerInstance.cpp", 881, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Couldn't establish MainFileID!"); |
882 | return true; |
883 | } |
884 | |
885 | |
886 | |
887 | bool CompilerInstance::ExecuteAction(FrontendAction &Act) { |
888 | (0) . __assert_fail ("hasDiagnostics() && \"Diagnostics engine is not initialized!\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/CompilerInstance.cpp", 888, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(hasDiagnostics() && "Diagnostics engine is not initialized!"); |
889 | (0) . __assert_fail ("!getFrontendOpts().ShowHelp && \"Client must handle '-help'!\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/CompilerInstance.cpp", 889, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!"); |
890 | (0) . __assert_fail ("!getFrontendOpts().ShowVersion && \"Client must handle '-version'!\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/CompilerInstance.cpp", 890, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!"); |
891 | |
892 | |
893 | |
894 | raw_ostream &OS = llvm::errs(); |
895 | |
896 | if (!Act.PrepareToExecute(*this)) |
897 | return false; |
898 | |
899 | |
900 | setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), |
901 | getInvocation().TargetOpts)); |
902 | if (!hasTarget()) |
903 | return false; |
904 | |
905 | |
906 | if ((getLangOpts().CUDA || getLangOpts().OpenMPIsDevice) && |
907 | !getFrontendOpts().AuxTriple.empty()) { |
908 | auto TO = std::make_shared<TargetOptions>(); |
909 | TO->Triple = llvm::Triple::normalize(getFrontendOpts().AuxTriple); |
910 | TO->HostTriple = getTarget().getTriple().str(); |
911 | setAuxTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), TO)); |
912 | } |
913 | |
914 | |
915 | |
916 | |
917 | |
918 | getTarget().adjust(getLangOpts()); |
919 | |
920 | |
921 | getTarget().adjustTargetOptions(getCodeGenOpts(), getTargetOpts()); |
922 | |
923 | if (auto *Aux = getAuxTarget()) |
924 | getTarget().setAuxTarget(Aux); |
925 | |
926 | |
927 | if (getFrontendOpts().ProgramAction == frontend::RewriteObjC) |
928 | getTarget().noSignedCharForObjCBool(); |
929 | |
930 | |
931 | if (getHeaderSearchOpts().Verbose) |
932 | OS << "clang -cc1 version " CLANG_VERSION_STRING |
933 | << " based upon " << BACKEND_PACKAGE_STRING |
934 | << " default target " << llvm::sys::getDefaultTargetTriple() << "\n"; |
935 | |
936 | if (getFrontendOpts().ShowTimers) |
937 | createFrontendTimer(); |
938 | |
939 | if (getFrontendOpts().ShowStats || !getFrontendOpts().StatsFile.empty()) |
940 | llvm::EnableStatistics(false); |
941 | |
942 | for (const FrontendInputFile &FIF : getFrontendOpts().Inputs) { |
943 | |
944 | |
945 | if (hasSourceManager() && !Act.isModelParsingAction()) |
946 | getSourceManager().clearIDTables(); |
947 | |
948 | if (Act.BeginSourceFile(*this, FIF)) { |
949 | Act.Execute(); |
950 | Act.EndSourceFile(); |
951 | } |
952 | } |
953 | |
954 | |
955 | getDiagnostics().getClient()->finish(); |
956 | |
957 | if (getDiagnosticOpts().ShowCarets) { |
958 | |
959 | |
960 | unsigned NumWarnings = getDiagnostics().getClient()->getNumWarnings(); |
961 | unsigned NumErrors = getDiagnostics().getClient()->getNumErrors(); |
962 | |
963 | if (NumWarnings) |
964 | OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s"); |
965 | if (NumWarnings && NumErrors) |
966 | OS << " and "; |
967 | if (NumErrors) |
968 | OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s"); |
969 | if (NumWarnings || NumErrors) { |
970 | OS << " generated"; |
971 | if (getLangOpts().CUDA) { |
972 | if (!getLangOpts().CUDAIsDevice) { |
973 | OS << " when compiling for host"; |
974 | } else { |
975 | OS << " when compiling for " << getTargetOpts().CPU; |
976 | } |
977 | } |
978 | OS << ".\n"; |
979 | } |
980 | } |
981 | |
982 | if (getFrontendOpts().ShowStats) { |
983 | if (hasFileManager()) { |
984 | getFileManager().PrintStats(); |
985 | OS << '\n'; |
986 | } |
987 | llvm::PrintStatistics(OS); |
988 | } |
989 | StringRef StatsFile = getFrontendOpts().StatsFile; |
990 | if (!StatsFile.empty()) { |
991 | std::error_code EC; |
992 | auto StatS = llvm::make_unique<llvm::raw_fd_ostream>(StatsFile, EC, |
993 | llvm::sys::fs::F_Text); |
994 | if (EC) { |
995 | getDiagnostics().Report(diag::warn_fe_unable_to_open_stats_file) |
996 | << StatsFile << EC.message(); |
997 | } else { |
998 | llvm::PrintStatisticsJSON(*StatS); |
999 | } |
1000 | } |
1001 | |
1002 | return !getDiagnostics().getClient()->getNumErrors(); |
1003 | } |
1004 | |
1005 | |
1006 | |
1007 | static InputKind::Language getLanguageFromOptions(const LangOptions &LangOpts) { |
1008 | if (LangOpts.OpenCL) |
1009 | return InputKind::OpenCL; |
1010 | if (LangOpts.CUDA) |
1011 | return InputKind::CUDA; |
1012 | if (LangOpts.ObjC) |
1013 | return LangOpts.CPlusPlus ? InputKind::ObjCXX : InputKind::ObjC; |
1014 | return LangOpts.CPlusPlus ? InputKind::CXX : InputKind::C; |
1015 | } |
1016 | |
1017 | |
1018 | |
1019 | |
1020 | static bool |
1021 | compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, |
1022 | StringRef ModuleName, FrontendInputFile Input, |
1023 | StringRef OriginalModuleMapFile, StringRef ModuleFileName, |
1024 | llvm::function_ref<void(CompilerInstance &)> PreBuildStep = |
1025 | [](CompilerInstance &) {}, |
1026 | llvm::function_ref<void(CompilerInstance &)> PostBuildStep = |
1027 | [](CompilerInstance &) {}) { |
1028 | |
1029 | auto Invocation = |
1030 | std::make_shared<CompilerInvocation>(ImportingInstance.getInvocation()); |
1031 | |
1032 | PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); |
1033 | |
1034 | |
1035 | |
1036 | Invocation->getLangOpts()->resetNonModularOptions(); |
1037 | PPOpts.resetNonModularOptions(); |
1038 | |
1039 | |
1040 | |
1041 | HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts(); |
1042 | PPOpts.Macros.erase( |
1043 | std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(), |
1044 | [&HSOpts](const std::pair<std::string, bool> &def) { |
1045 | StringRef MacroDef = def.first; |
1046 | return HSOpts.ModulesIgnoreMacros.count( |
1047 | llvm::CachedHashString(MacroDef.split('=').first)) > 0; |
1048 | }), |
1049 | PPOpts.Macros.end()); |
1050 | |
1051 | |
1052 | Invocation->getLangOpts()->ModuleName = |
1053 | ImportingInstance.getInvocation().getLangOpts()->ModuleName; |
1054 | |
1055 | |
1056 | Invocation->getLangOpts()->CurrentModule = ModuleName; |
1057 | |
1058 | |
1059 | |
1060 | |
1061 | PreprocessorOptions &ImportingPPOpts |
1062 | = ImportingInstance.getInvocation().getPreprocessorOpts(); |
1063 | if (!ImportingPPOpts.FailedModules) |
1064 | ImportingPPOpts.FailedModules = |
1065 | std::make_shared<PreprocessorOptions::FailedModulesSet>(); |
1066 | PPOpts.FailedModules = ImportingPPOpts.FailedModules; |
1067 | |
1068 | |
1069 | |
1070 | |
1071 | FrontendOptions &FrontendOpts = Invocation->getFrontendOpts(); |
1072 | FrontendOpts.OutputFile = ModuleFileName.str(); |
1073 | FrontendOpts.DisableFree = false; |
1074 | FrontendOpts.GenerateGlobalModuleIndex = false; |
1075 | FrontendOpts.BuildingImplicitModule = true; |
1076 | FrontendOpts.OriginalModuleMap = OriginalModuleMapFile; |
1077 | |
1078 | HSOpts.ModulesHashContent = true; |
1079 | FrontendOpts.Inputs = {Input}; |
1080 | |
1081 | |
1082 | PPOpts.RetainRemappedFileBuffers = true; |
1083 | |
1084 | Invocation->getDiagnosticOpts().VerifyDiagnostics = 0; |
1085 | (0) . __assert_fail ("ImportingInstance.getInvocation().getModuleHash() == Invocation->getModuleHash() && \"Module hash mismatch!\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/CompilerInstance.cpp", 1086, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ImportingInstance.getInvocation().getModuleHash() == |
1086 | (0) . __assert_fail ("ImportingInstance.getInvocation().getModuleHash() == Invocation->getModuleHash() && \"Module hash mismatch!\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/CompilerInstance.cpp", 1086, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> Invocation->getModuleHash() && "Module hash mismatch!"); |
1087 | |
1088 | |
1089 | |
1090 | |
1091 | |
1092 | CompilerInstance Instance(ImportingInstance.getPCHContainerOperations(), |
1093 | &ImportingInstance.getModuleCache()); |
1094 | auto &Inv = *Invocation; |
1095 | Instance.setInvocation(std::move(Invocation)); |
1096 | |
1097 | Instance.createDiagnostics(new ForwardingDiagnosticConsumer( |
1098 | ImportingInstance.getDiagnosticClient()), |
1099 | ); |
1100 | |
1101 | |
1102 | |
1103 | Instance.setFileManager(&ImportingInstance.getFileManager()); |
1104 | Instance.createSourceManager(Instance.getFileManager()); |
1105 | SourceManager &SourceMgr = Instance.getSourceManager(); |
1106 | SourceMgr.setModuleBuildStack( |
1107 | ImportingInstance.getSourceManager().getModuleBuildStack()); |
1108 | SourceMgr.pushModuleBuildStack(ModuleName, |
1109 | FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager())); |
1110 | |
1111 | |
1112 | |
1113 | |
1114 | Instance.setModuleDepCollector(ImportingInstance.getModuleDepCollector()); |
1115 | Inv.getDependencyOutputOpts() = DependencyOutputOptions(); |
1116 | |
1117 | ImportingInstance.getDiagnostics().Report(ImportLoc, |
1118 | diag::remark_module_build) |
1119 | << ModuleName << ModuleFileName; |
1120 | |
1121 | PreBuildStep(Instance); |
1122 | |
1123 | |
1124 | |
1125 | llvm::CrashRecoveryContext CRC; |
1126 | CRC.RunSafelyOnThread( |
1127 | [&]() { |
1128 | GenerateModuleFromModuleMapAction Action; |
1129 | Instance.ExecuteAction(Action); |
1130 | }, |
1131 | DesiredStackSize); |
1132 | |
1133 | PostBuildStep(Instance); |
1134 | |
1135 | ImportingInstance.getDiagnostics().Report(ImportLoc, |
1136 | diag::remark_module_build_done) |
1137 | << ModuleName; |
1138 | |
1139 | |
1140 | |
1141 | |
1142 | |
1143 | Instance.clearOutputFiles(); |
1144 | |
1145 | return !Instance.getDiagnostics().hasErrorOccurred(); |
1146 | } |
1147 | |
1148 | static const FileEntry *getPublicModuleMap(const FileEntry *File, |
1149 | FileManager &FileMgr) { |
1150 | StringRef Filename = llvm::sys::path::filename(File->getName()); |
1151 | SmallString<128> PublicFilename(File->getDir()->getName()); |
1152 | if (Filename == "module_private.map") |
1153 | llvm::sys::path::append(PublicFilename, "module.map"); |
1154 | else if (Filename == "module.private.modulemap") |
1155 | llvm::sys::path::append(PublicFilename, "module.modulemap"); |
1156 | else |
1157 | return nullptr; |
1158 | return FileMgr.getFile(PublicFilename); |
1159 | } |
1160 | |
1161 | |
1162 | |
1163 | |
1164 | static bool compileModuleImpl(CompilerInstance &ImportingInstance, |
1165 | SourceLocation ImportLoc, |
1166 | Module *Module, |
1167 | StringRef ModuleFileName) { |
1168 | InputKind IK(getLanguageFromOptions(ImportingInstance.getLangOpts()), |
1169 | InputKind::ModuleMap); |
1170 | |
1171 | |
1172 | ModuleMap &ModMap |
1173 | = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap(); |
1174 | bool Result; |
1175 | if (const FileEntry *ModuleMapFile = |
1176 | ModMap.getContainingModuleMapFile(Module)) { |
1177 | |
1178 | |
1179 | |
1180 | if (const FileEntry *PublicMMFile = getPublicModuleMap( |
1181 | ModuleMapFile, ImportingInstance.getFileManager())) |
1182 | ModuleMapFile = PublicMMFile; |
1183 | |
1184 | |
1185 | Result = compileModuleImpl( |
1186 | ImportingInstance, ImportLoc, Module->getTopLevelModuleName(), |
1187 | FrontendInputFile(ModuleMapFile->getName(), IK, +Module->IsSystem), |
1188 | ModMap.getModuleMapFileForUniquing(Module)->getName(), |
1189 | ModuleFileName); |
1190 | } else { |
1191 | |
1192 | |
1193 | |
1194 | |
1195 | SmallString<128> FakeModuleMapFile(Module->Directory->getName()); |
1196 | llvm::sys::path::append(FakeModuleMapFile, "__inferred_module.map"); |
1197 | |
1198 | std::string InferredModuleMapContent; |
1199 | llvm::raw_string_ostream OS(InferredModuleMapContent); |
1200 | Module->print(OS); |
1201 | OS.flush(); |
1202 | |
1203 | Result = compileModuleImpl( |
1204 | ImportingInstance, ImportLoc, Module->getTopLevelModuleName(), |
1205 | FrontendInputFile(FakeModuleMapFile, IK, +Module->IsSystem), |
1206 | ModMap.getModuleMapFileForUniquing(Module)->getName(), |
1207 | ModuleFileName, |
1208 | [&](CompilerInstance &Instance) { |
1209 | std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer = |
1210 | llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent); |
1211 | ModuleMapFile = Instance.getFileManager().getVirtualFile( |
1212 | FakeModuleMapFile, InferredModuleMapContent.size(), 0); |
1213 | Instance.getSourceManager().overrideFileContents( |
1214 | ModuleMapFile, std::move(ModuleMapBuffer)); |
1215 | }); |
1216 | } |
1217 | |
1218 | |
1219 | |
1220 | if (ImportingInstance.getFrontendOpts().GenerateGlobalModuleIndex) { |
1221 | ImportingInstance.setBuildGlobalModuleIndex(true); |
1222 | } |
1223 | |
1224 | return Result; |
1225 | } |
1226 | |
1227 | static bool compileAndLoadModule(CompilerInstance &ImportingInstance, |
1228 | SourceLocation ImportLoc, |
1229 | SourceLocation ModuleNameLoc, Module *Module, |
1230 | StringRef ModuleFileName) { |
1231 | DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics(); |
1232 | |
1233 | auto diagnoseBuildFailure = [&] { |
1234 | Diags.Report(ModuleNameLoc, diag::err_module_not_built) |
1235 | << Module->Name << SourceRange(ImportLoc, ModuleNameLoc); |
1236 | }; |
1237 | |
1238 | |
1239 | |
1240 | StringRef Dir = llvm::sys::path::parent_path(ModuleFileName); |
1241 | llvm::sys::fs::create_directories(Dir); |
1242 | |
1243 | while (1) { |
1244 | unsigned ModuleLoadCapabilities = ASTReader::ARR_Missing; |
1245 | llvm::LockFileManager Locked(ModuleFileName); |
1246 | switch (Locked) { |
1247 | case llvm::LockFileManager::LFS_Error: |
1248 | |
1249 | |
1250 | |
1251 | Diags.Report(ModuleNameLoc, diag::remark_module_lock_failure) |
1252 | << Module->Name << Locked.getErrorMessage(); |
1253 | |
1254 | Locked.unsafeRemoveLockFile(); |
1255 | LLVM_FALLTHROUGH; |
1256 | case llvm::LockFileManager::LFS_Owned: |
1257 | |
1258 | if (!compileModuleImpl(ImportingInstance, ModuleNameLoc, Module, |
1259 | ModuleFileName)) { |
1260 | diagnoseBuildFailure(); |
1261 | return false; |
1262 | } |
1263 | break; |
1264 | |
1265 | case llvm::LockFileManager::LFS_Shared: |
1266 | |
1267 | |
1268 | switch (Locked.waitForUnlock()) { |
1269 | case llvm::LockFileManager::Res_Success: |
1270 | ModuleLoadCapabilities |= ASTReader::ARR_OutOfDate; |
1271 | break; |
1272 | case llvm::LockFileManager::Res_OwnerDied: |
1273 | continue; |
1274 | case llvm::LockFileManager::Res_Timeout: |
1275 | |
1276 | |
1277 | |
1278 | Diags.Report(ModuleNameLoc, diag::remark_module_lock_timeout) |
1279 | << Module->Name; |
1280 | |
1281 | Locked.unsafeRemoveLockFile(); |
1282 | continue; |
1283 | } |
1284 | break; |
1285 | } |
1286 | |
1287 | |
1288 | ASTReader::ASTReadResult ReadResult = |
1289 | ImportingInstance.getModuleManager()->ReadAST( |
1290 | ModuleFileName, serialization::MK_ImplicitModule, ImportLoc, |
1291 | ModuleLoadCapabilities); |
1292 | |
1293 | if (ReadResult == ASTReader::OutOfDate && |
1294 | Locked == llvm::LockFileManager::LFS_Shared) { |
1295 | |
1296 | |
1297 | |
1298 | continue; |
1299 | } else if (ReadResult == ASTReader::Missing) { |
1300 | diagnoseBuildFailure(); |
1301 | } else if (ReadResult != ASTReader::Success && |
1302 | !Diags.hasErrorOccurred()) { |
1303 | |
1304 | diagnoseBuildFailure(); |
1305 | } |
1306 | return ReadResult == ASTReader::Success; |
1307 | } |
1308 | } |
1309 | |
1310 | |
1311 | |
1312 | static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro, |
1313 | Module *Mod, SourceLocation ImportLoc) { |
1314 | IdentifierInfo *Id = PP.getIdentifierInfo(ConfigMacro); |
1315 | SourceManager &SourceMgr = PP.getSourceManager(); |
1316 | |
1317 | |
1318 | |
1319 | if (!Id->hadMacroDefinition()) |
1320 | return; |
1321 | auto *LatestLocalMD = PP.getLocalMacroDirectiveHistory(Id); |
1322 | |
1323 | |
1324 | MacroInfo *CmdLineDefinition = nullptr; |
1325 | for (auto *MD = LatestLocalMD; MD; MD = MD->getPrevious()) { |
1326 | |
1327 | FileID FID = SourceMgr.getFileID(MD->getLocation()); |
1328 | if (FID.isInvalid() || FID != PP.getPredefinesFileID()) |
1329 | continue; |
1330 | if (auto *DMD = dyn_cast<DefMacroDirective>(MD)) |
1331 | CmdLineDefinition = DMD->getMacroInfo(); |
1332 | break; |
1333 | } |
1334 | |
1335 | auto *CurrentDefinition = PP.getMacroInfo(Id); |
1336 | if (CurrentDefinition == CmdLineDefinition) { |
1337 | |
1338 | } else if (!CurrentDefinition) { |
1339 | |
1340 | |
1341 | PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) |
1342 | << true << ConfigMacro << Mod->getFullModuleName(); |
1343 | auto LatestDef = LatestLocalMD->getDefinition(); |
1344 | (0) . __assert_fail ("LatestDef.isUndefined() && \"predefined macro went away with no #undef?\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/CompilerInstance.cpp", 1345, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(LatestDef.isUndefined() && |
1345 | (0) . __assert_fail ("LatestDef.isUndefined() && \"predefined macro went away with no #undef?\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/CompilerInstance.cpp", 1345, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "predefined macro went away with no #undef?"); |
1346 | PP.Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here) |
1347 | << true; |
1348 | return; |
1349 | } else if (!CmdLineDefinition) { |
1350 | |
1351 | |
1352 | PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) |
1353 | << false << ConfigMacro << Mod->getFullModuleName(); |
1354 | PP.Diag(CurrentDefinition->getDefinitionLoc(), |
1355 | diag::note_module_def_undef_here) |
1356 | << false; |
1357 | } else if (!CurrentDefinition->isIdenticalTo(*CmdLineDefinition, PP, |
1358 | )) { |
1359 | |
1360 | PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) |
1361 | << false << ConfigMacro << Mod->getFullModuleName(); |
1362 | PP.Diag(CurrentDefinition->getDefinitionLoc(), |
1363 | diag::note_module_def_undef_here) |
1364 | << false; |
1365 | } |
1366 | } |
1367 | |
1368 | |
1369 | static void writeTimestampFile(StringRef TimestampFile) { |
1370 | std::error_code EC; |
1371 | llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::F_None); |
1372 | } |
1373 | |
1374 | |
1375 | |
1376 | static void (const HeaderSearchOptions &HSOpts) { |
1377 | struct stat StatBuf; |
1378 | llvm::SmallString<128> TimestampFile; |
1379 | TimestampFile = HSOpts.ModuleCachePath; |
1380 | assert(!TimestampFile.empty()); |
1381 | llvm::sys::path::append(TimestampFile, "modules.timestamp"); |
1382 | |
1383 | |
1384 | if (::stat(TimestampFile.c_str(), &StatBuf)) { |
1385 | |
1386 | if (errno == ENOENT) { |
1387 | writeTimestampFile(TimestampFile); |
1388 | } |
1389 | return; |
1390 | } |
1391 | |
1392 | |
1393 | |
1394 | time_t TimeStampModTime = StatBuf.st_mtime; |
1395 | time_t CurrentTime = time(nullptr); |
1396 | if (CurrentTime - TimeStampModTime <= time_t(HSOpts.ModuleCachePruneInterval)) |
1397 | return; |
1398 | |
1399 | |
1400 | |
1401 | |
1402 | writeTimestampFile(TimestampFile); |
1403 | |
1404 | |
1405 | |
1406 | std::error_code EC; |
1407 | SmallString<128> ModuleCachePathNative; |
1408 | llvm::sys::path::native(HSOpts.ModuleCachePath, ModuleCachePathNative); |
1409 | for (llvm::sys::fs::directory_iterator Dir(ModuleCachePathNative, EC), DirEnd; |
1410 | Dir != DirEnd && !EC; Dir.increment(EC)) { |
1411 | |
1412 | if (!llvm::sys::fs::is_directory(Dir->path())) |
1413 | continue; |
1414 | |
1415 | |
1416 | for (llvm::sys::fs::directory_iterator File(Dir->path(), EC), FileEnd; |
1417 | File != FileEnd && !EC; File.increment(EC)) { |
1418 | |
1419 | StringRef Extension = llvm::sys::path::extension(File->path()); |
1420 | if (Extension != ".pcm" && Extension != ".timestamp" && |
1421 | llvm::sys::path::filename(File->path()) != "modules.idx") |
1422 | continue; |
1423 | |
1424 | |
1425 | |
1426 | if (::stat(File->path().c_str(), &StatBuf)) |
1427 | continue; |
1428 | |
1429 | |
1430 | time_t FileAccessTime = StatBuf.st_atime; |
1431 | if (CurrentTime - FileAccessTime <= |
1432 | time_t(HSOpts.ModuleCachePruneAfter)) { |
1433 | continue; |
1434 | } |
1435 | |
1436 | |
1437 | llvm::sys::fs::remove(File->path()); |
1438 | |
1439 | |
1440 | std::string TimpestampFilename = File->path() + ".timestamp"; |
1441 | llvm::sys::fs::remove(TimpestampFilename); |
1442 | } |
1443 | |
1444 | |
1445 | |
1446 | if (llvm::sys::fs::directory_iterator(Dir->path(), EC) == |
1447 | llvm::sys::fs::directory_iterator() && !EC) |
1448 | llvm::sys::fs::remove(Dir->path()); |
1449 | } |
1450 | } |
1451 | |
1452 | void CompilerInstance::createModuleManager() { |
1453 | if (!ModuleManager) { |
1454 | if (!hasASTContext()) |
1455 | createASTContext(); |
1456 | |
1457 | |
1458 | |
1459 | if (getSourceManager().getModuleBuildStack().empty() && |
1460 | !getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty() && |
1461 | getHeaderSearchOpts().ModuleCachePruneInterval > 0 && |
1462 | getHeaderSearchOpts().ModuleCachePruneAfter > 0) { |
1463 | pruneModuleCache(getHeaderSearchOpts()); |
1464 | } |
1465 | |
1466 | HeaderSearchOptions &HSOpts = getHeaderSearchOpts(); |
1467 | std::string Sysroot = HSOpts.Sysroot; |
1468 | const PreprocessorOptions &PPOpts = getPreprocessorOpts(); |
1469 | std::unique_ptr<llvm::Timer> ReadTimer; |
1470 | if (FrontendTimerGroup) |
1471 | ReadTimer = llvm::make_unique<llvm::Timer>("reading_modules", |
1472 | "Reading modules", |
1473 | *FrontendTimerGroup); |
1474 | ModuleManager = new ASTReader( |
1475 | getPreprocessor(), getModuleCache(), &getASTContext(), |
1476 | getPCHContainerReader(), getFrontendOpts().ModuleFileExtensions, |
1477 | Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation, |
1478 | , |
1479 | , |
1480 | HSOpts.ModulesValidateSystemHeaders, |
1481 | getFrontendOpts().UseGlobalModuleIndex, std::move(ReadTimer)); |
1482 | if (hasASTConsumer()) { |
1483 | ModuleManager->setDeserializationListener( |
1484 | getASTConsumer().GetASTDeserializationListener()); |
1485 | getASTContext().setASTMutationListener( |
1486 | getASTConsumer().GetASTMutationListener()); |
1487 | } |
1488 | getASTContext().setExternalSource(ModuleManager); |
1489 | if (hasSema()) |
1490 | ModuleManager->InitializeSema(getSema()); |
1491 | if (hasASTConsumer()) |
1492 | ModuleManager->StartTranslationUnit(&getASTConsumer()); |
1493 | |
1494 | if (TheDependencyFileGenerator) |
1495 | TheDependencyFileGenerator->AttachToASTReader(*ModuleManager); |
1496 | for (auto &Listener : DependencyCollectors) |
1497 | Listener->attachToASTReader(*ModuleManager); |
1498 | } |
1499 | } |
1500 | |
1501 | bool CompilerInstance::loadModuleFile(StringRef FileName) { |
1502 | llvm::Timer Timer; |
1503 | if (FrontendTimerGroup) |
1504 | Timer.init("preloading." + FileName.str(), "Preloading " + FileName.str(), |
1505 | *FrontendTimerGroup); |
1506 | llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr); |
1507 | |
1508 | |
1509 | |
1510 | |
1511 | struct ReadModuleNames : ASTReaderListener { |
1512 | CompilerInstance &CI; |
1513 | llvm::SmallVector<IdentifierInfo*, 8> LoadedModules; |
1514 | |
1515 | ReadModuleNames(CompilerInstance &CI) : CI(CI) {} |
1516 | |
1517 | void ReadModuleName(StringRef ModuleName) override { |
1518 | LoadedModules.push_back( |
1519 | CI.getPreprocessor().getIdentifierInfo(ModuleName)); |
1520 | } |
1521 | |
1522 | void registerAll() { |
1523 | for (auto *II : LoadedModules) { |
1524 | CI.KnownModules[II] = CI.getPreprocessor() |
1525 | .getHeaderSearchInfo() |
1526 | .getModuleMap() |
1527 | .findModule(II->getName()); |
1528 | } |
1529 | LoadedModules.clear(); |
1530 | } |
1531 | |
1532 | void markAllUnavailable() { |
1533 | for (auto *II : LoadedModules) { |
1534 | if (Module *M = CI.getPreprocessor() |
1535 | .getHeaderSearchInfo() |
1536 | .getModuleMap() |
1537 | .findModule(II->getName())) { |
1538 | M->HasIncompatibleModuleFile = true; |
1539 | |
1540 | |
1541 | |
1542 | SmallVector<Module *, 2> Stack; |
1543 | Stack.push_back(M); |
1544 | while (!Stack.empty()) { |
1545 | Module *Current = Stack.pop_back_val(); |
1546 | if (Current->IsMissingRequirement) continue; |
1547 | Current->IsAvailable = true; |
1548 | Stack.insert(Stack.end(), |
1549 | Current->submodule_begin(), Current->submodule_end()); |
1550 | } |
1551 | } |
1552 | } |
1553 | LoadedModules.clear(); |
1554 | } |
1555 | }; |
1556 | |
1557 | |
1558 | if (!ModuleManager) |
1559 | createModuleManager(); |
1560 | |
1561 | |
1562 | |
1563 | bool ConfigMismatchIsRecoverable = |
1564 | getDiagnostics().getDiagnosticLevel(diag::warn_module_config_mismatch, |
1565 | SourceLocation()) |
1566 | <= DiagnosticsEngine::Warning; |
1567 | |
1568 | auto Listener = llvm::make_unique<ReadModuleNames>(*this); |
1569 | auto &ListenerRef = *Listener; |
1570 | ASTReader::ListenerScope ReadModuleNamesListener(*ModuleManager, |
1571 | std::move(Listener)); |
1572 | |
1573 | |
1574 | switch (ModuleManager->ReadAST( |
1575 | FileName, serialization::MK_ExplicitModule, SourceLocation(), |
1576 | ConfigMismatchIsRecoverable ? ASTReader::ARR_ConfigurationMismatch : 0)) { |
1577 | case ASTReader::Success: |
1578 | |
1579 | |
1580 | ListenerRef.registerAll(); |
1581 | return true; |
1582 | |
1583 | case ASTReader::ConfigurationMismatch: |
1584 | |
1585 | getDiagnostics().Report(SourceLocation(), diag::warn_module_config_mismatch) |
1586 | << FileName; |
1587 | |
1588 | |
1589 | ListenerRef.markAllUnavailable(); |
1590 | return true; |
1591 | |
1592 | default: |
1593 | return false; |
1594 | } |
1595 | } |
1596 | |
1597 | ModuleLoadResult |
1598 | CompilerInstance::loadModule(SourceLocation ImportLoc, |
1599 | ModuleIdPath Path, |
1600 | Module::NameVisibilityKind Visibility, |
1601 | bool IsInclusionDirective) { |
1602 | |
1603 | StringRef ModuleName = Path[0].first->getName(); |
1604 | SourceLocation ModuleNameLoc = Path[0].second; |
1605 | |
1606 | |
1607 | |
1608 | |
1609 | if (ImportLoc.isValid() && LastModuleImportLoc == ImportLoc) { |
1610 | |
1611 | if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule) |
1612 | ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility, |
1613 | ImportLoc); |
1614 | return LastModuleImportResult; |
1615 | } |
1616 | |
1617 | clang::Module *Module = nullptr; |
1618 | |
1619 | |
1620 | llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known |
1621 | = KnownModules.find(Path[0].first); |
1622 | if (Known != KnownModules.end()) { |
1623 | |
1624 | Module = Known->second; |
1625 | } else if (ModuleName == getLangOpts().CurrentModule) { |
1626 | |
1627 | Module = PP->getHeaderSearchInfo().lookupModule( |
1628 | ModuleName, true, |
1629 | !IsInclusionDirective); |
1630 | |
1631 | |
1632 | |
1633 | |
1634 | |
1635 | |
1636 | |
1637 | |
1638 | Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; |
1639 | } else { |
1640 | |
1641 | Module = PP->getHeaderSearchInfo().lookupModule(ModuleName, true, |
1642 | !IsInclusionDirective); |
1643 | HeaderSearchOptions &HSOpts = |
1644 | PP->getHeaderSearchInfo().getHeaderSearchOpts(); |
1645 | |
1646 | std::string ModuleFileName; |
1647 | enum ModuleSource { |
1648 | ModuleNotFound, ModuleCache, PrebuiltModulePath, ModuleBuildPragma |
1649 | } Source = ModuleNotFound; |
1650 | |
1651 | |
1652 | |
1653 | auto BuiltModuleIt = BuiltModules.find(ModuleName); |
1654 | if (BuiltModuleIt != BuiltModules.end()) { |
1655 | ModuleFileName = BuiltModuleIt->second; |
1656 | Source = ModuleBuildPragma; |
1657 | } |
1658 | |
1659 | |
1660 | if (Source == ModuleNotFound && (!HSOpts.PrebuiltModuleFiles.empty() || |
1661 | !HSOpts.PrebuiltModulePaths.empty())) { |
1662 | ModuleFileName = |
1663 | PP->getHeaderSearchInfo().getPrebuiltModuleFileName(ModuleName); |
1664 | if (!ModuleFileName.empty()) |
1665 | Source = PrebuiltModulePath; |
1666 | } |
1667 | |
1668 | |
1669 | if (Source == ModuleNotFound && Module) { |
1670 | ModuleFileName = PP->getHeaderSearchInfo().getCachedModuleFileName(Module); |
1671 | Source = ModuleCache; |
1672 | } |
1673 | |
1674 | if (Source == ModuleNotFound) { |
1675 | |
1676 | getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found) |
1677 | << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); |
1678 | ModuleBuildFailed = true; |
1679 | return ModuleLoadResult(); |
1680 | } |
1681 | |
1682 | if (ModuleFileName.empty()) { |
1683 | if (Module && Module->HasIncompatibleModuleFile) { |
1684 | |
1685 | |
1686 | return ModuleLoadResult::ConfigMismatch; |
1687 | } |
1688 | |
1689 | getDiagnostics().Report(ModuleNameLoc, diag::err_module_build_disabled) |
1690 | << ModuleName; |
1691 | ModuleBuildFailed = true; |
1692 | return ModuleLoadResult(); |
1693 | } |
1694 | |
1695 | |
1696 | if (!ModuleManager) |
1697 | createModuleManager(); |
1698 | |
1699 | llvm::Timer Timer; |
1700 | if (FrontendTimerGroup) |
1701 | Timer.init("loading." + ModuleFileName, "Loading " + ModuleFileName, |
1702 | *FrontendTimerGroup); |
1703 | llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr); |
1704 | |
1705 | |
1706 | |
1707 | unsigned ARRFlags = Source == ModuleCache ? |
1708 | ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing : |
1709 | Source == PrebuiltModulePath ? |
1710 | 0 : |
1711 | ASTReader::ARR_ConfigurationMismatch; |
1712 | switch (ModuleManager->ReadAST(ModuleFileName, |
1713 | Source == PrebuiltModulePath |
1714 | ? serialization::MK_PrebuiltModule |
1715 | : Source == ModuleBuildPragma |
1716 | ? serialization::MK_ExplicitModule |
1717 | : serialization::MK_ImplicitModule, |
1718 | ImportLoc, ARRFlags)) { |
1719 | case ASTReader::Success: { |
1720 | if (Source != ModuleCache && !Module) { |
1721 | Module = PP->getHeaderSearchInfo().lookupModule(ModuleName, true, |
1722 | !IsInclusionDirective); |
1723 | if (!Module || !Module->getASTFile() || |
1724 | FileMgr->getFile(ModuleFileName) != Module->getASTFile()) { |
1725 | |
1726 | |
1727 | getDiagnostics().Report(ModuleNameLoc, diag::err_module_prebuilt) |
1728 | << ModuleName; |
1729 | ModuleBuildFailed = true; |
1730 | KnownModules[Path[0].first] = nullptr; |
1731 | return ModuleLoadResult(); |
1732 | } |
1733 | } |
1734 | break; |
1735 | } |
1736 | |
1737 | case ASTReader::OutOfDate: |
1738 | case ASTReader::Missing: { |
1739 | if (Source != ModuleCache) { |
1740 | |
1741 | |
1742 | |
1743 | ModuleBuildFailed = true; |
1744 | KnownModules[Path[0].first] = nullptr; |
1745 | return ModuleLoadResult(); |
1746 | } |
1747 | |
1748 | |
1749 | (0) . __assert_fail ("Module && \"missing module file\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/CompilerInstance.cpp", 1749, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Module && "missing module file"); |
1750 | |
1751 | ModuleBuildStack ModPath = getSourceManager().getModuleBuildStack(); |
1752 | ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end(); |
1753 | for (; Pos != PosEnd; ++Pos) { |
1754 | if (Pos->first == ModuleName) |
1755 | break; |
1756 | } |
1757 | |
1758 | if (Pos != PosEnd) { |
1759 | SmallString<256> CyclePath; |
1760 | for (; Pos != PosEnd; ++Pos) { |
1761 | CyclePath += Pos->first; |
1762 | CyclePath += " -> "; |
1763 | } |
1764 | CyclePath += ModuleName; |
1765 | |
1766 | getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle) |
1767 | << ModuleName << CyclePath; |
1768 | return ModuleLoadResult(); |
1769 | } |
1770 | |
1771 | |
1772 | |
1773 | if (getPreprocessorOpts().FailedModules && |
1774 | getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) { |
1775 | getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built) |
1776 | << ModuleName |
1777 | << SourceRange(ImportLoc, ModuleNameLoc); |
1778 | ModuleBuildFailed = true; |
1779 | return ModuleLoadResult(); |
1780 | } |
1781 | |
1782 | |
1783 | if (!compileAndLoadModule(*this, ImportLoc, ModuleNameLoc, Module, |
1784 | ModuleFileName)) { |
1785 | (0) . __assert_fail ("getDiagnostics().hasErrorOccurred() && \"undiagnosed error in compileAndLoadModule\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/CompilerInstance.cpp", 1786, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(getDiagnostics().hasErrorOccurred() && |
1786 | (0) . __assert_fail ("getDiagnostics().hasErrorOccurred() && \"undiagnosed error in compileAndLoadModule\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/CompilerInstance.cpp", 1786, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "undiagnosed error in compileAndLoadModule"); |
1787 | if (getPreprocessorOpts().FailedModules) |
1788 | getPreprocessorOpts().FailedModules->addFailed(ModuleName); |
1789 | KnownModules[Path[0].first] = nullptr; |
1790 | ModuleBuildFailed = true; |
1791 | return ModuleLoadResult(); |
1792 | } |
1793 | |
1794 | |
1795 | break; |
1796 | } |
1797 | |
1798 | case ASTReader::ConfigurationMismatch: |
1799 | if (Source == PrebuiltModulePath) |
1800 | |
1801 | |
1802 | getDiagnostics().Report(SourceLocation(), |
1803 | diag::warn_module_config_mismatch) |
1804 | << ModuleFileName; |
1805 | |
1806 | LLVM_FALLTHROUGH; |
1807 | case ASTReader::VersionMismatch: |
1808 | case ASTReader::HadErrors: |
1809 | ModuleLoader::HadFatalFailure = true; |
1810 | |
1811 | |
1812 | KnownModules[Path[0].first] = nullptr; |
1813 | return ModuleLoadResult(); |
1814 | |
1815 | case ASTReader::Failure: |
1816 | ModuleLoader::HadFatalFailure = true; |
1817 | |
1818 | KnownModules[Path[0].first] = nullptr; |
1819 | ModuleBuildFailed = true; |
1820 | return ModuleLoadResult(); |
1821 | } |
1822 | |
1823 | |
1824 | Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; |
1825 | } |
1826 | |
1827 | |
1828 | if (!Module) |
1829 | return ModuleLoadResult(); |
1830 | |
1831 | |
1832 | |
1833 | bool MapPrivateSubModToTopLevel = false; |
1834 | if (Path.size() > 1) { |
1835 | for (unsigned I = 1, N = Path.size(); I != N; ++I) { |
1836 | StringRef Name = Path[I].first->getName(); |
1837 | clang::Module *Sub = Module->findSubmodule(Name); |
1838 | |
1839 | |
1840 | |
1841 | |
1842 | |
1843 | if (!Sub && PP->getLangOpts().ImplicitModules && Name == "Private" && |
1844 | Module == Module->getTopLevelModule()) { |
1845 | SmallString<128> PrivateModule(Module->Name); |
1846 | PrivateModule.append("_Private"); |
1847 | |
1848 | SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> PrivPath; |
1849 | auto &II = PP->getIdentifierTable().get( |
1850 | PrivateModule, PP->getIdentifierInfo(Module->Name)->getTokenID()); |
1851 | PrivPath.push_back(std::make_pair(&II, Path[0].second)); |
1852 | |
1853 | if (PP->getHeaderSearchInfo().lookupModule(PrivateModule, true, |
1854 | !IsInclusionDirective)) |
1855 | Sub = |
1856 | loadModule(ImportLoc, PrivPath, Visibility, IsInclusionDirective); |
1857 | if (Sub) { |
1858 | MapPrivateSubModToTopLevel = true; |
1859 | if (!getDiagnostics().isIgnored( |
1860 | diag::warn_no_priv_submodule_use_toplevel, ImportLoc)) { |
1861 | getDiagnostics().Report(Path[I].second, |
1862 | diag::warn_no_priv_submodule_use_toplevel) |
1863 | << Path[I].first << Module->getFullModuleName() << PrivateModule |
1864 | << SourceRange(Path[0].second, Path[I].second) |
1865 | << FixItHint::CreateReplacement(SourceRange(Path[0].second), |
1866 | PrivateModule); |
1867 | getDiagnostics().Report(Sub->DefinitionLoc, |
1868 | diag::note_private_top_level_defined); |
1869 | } |
1870 | } |
1871 | } |
1872 | |
1873 | if (!Sub) { |
1874 | |
1875 | SmallVector<StringRef, 2> Best; |
1876 | unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)(); |
1877 | |
1878 | for (clang::Module::submodule_iterator J = Module->submodule_begin(), |
1879 | JEnd = Module->submodule_end(); |
1880 | J != JEnd; ++J) { |
1881 | unsigned ED = Name.edit_distance((*J)->Name, |
1882 | , |
1883 | BestEditDistance); |
1884 | if (ED <= BestEditDistance) { |
1885 | if (ED < BestEditDistance) { |
1886 | Best.clear(); |
1887 | BestEditDistance = ED; |
1888 | } |
1889 | |
1890 | Best.push_back((*J)->Name); |
1891 | } |
1892 | } |
1893 | |
1894 | |
1895 | if (Best.size() == 1) { |
1896 | getDiagnostics().Report(Path[I].second, |
1897 | diag::err_no_submodule_suggest) |
1898 | << Path[I].first << Module->getFullModuleName() << Best[0] |
1899 | << SourceRange(Path[0].second, Path[I-1].second) |
1900 | << FixItHint::CreateReplacement(SourceRange(Path[I].second), |
1901 | Best[0]); |
1902 | |
1903 | Sub = Module->findSubmodule(Best[0]); |
1904 | } |
1905 | } |
1906 | |
1907 | if (!Sub) { |
1908 | |
1909 | |
1910 | getDiagnostics().Report(Path[I].second, diag::err_no_submodule) |
1911 | << Path[I].first << Module->getFullModuleName() |
1912 | << SourceRange(Path[0].second, Path[I-1].second); |
1913 | break; |
1914 | } |
1915 | |
1916 | Module = Sub; |
1917 | } |
1918 | } |
1919 | |
1920 | |
1921 | |
1922 | if (ModuleName != getLangOpts().CurrentModule) { |
1923 | if (!Module->IsFromModuleFile && !MapPrivateSubModToTopLevel) { |
1924 | |
1925 | |
1926 | |
1927 | |
1928 | |
1929 | |
1930 | getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule) |
1931 | << Module->getFullModuleName() |
1932 | << SourceRange(Path.front().second, Path.back().second); |
1933 | |
1934 | return ModuleLoadResult::MissingExpected; |
1935 | } |
1936 | |
1937 | |
1938 | if (Preprocessor::checkModuleIsAvailable(getLangOpts(), getTarget(), |
1939 | getDiagnostics(), Module)) { |
1940 | getDiagnostics().Report(ImportLoc, diag::note_module_import_here) |
1941 | << SourceRange(Path.front().second, Path.back().second); |
1942 | LastModuleImportLoc = ImportLoc; |
1943 | LastModuleImportResult = ModuleLoadResult(); |
1944 | return ModuleLoadResult(); |
1945 | } |
1946 | |
1947 | ModuleManager->makeModuleVisible(Module, Visibility, ImportLoc); |
1948 | } |
1949 | |
1950 | |
1951 | clang::Module *TopModule = Module->getTopLevelModule(); |
1952 | for (unsigned I = 0, N = TopModule->ConfigMacros.size(); I != N; ++I) { |
1953 | checkConfigMacro(getPreprocessor(), TopModule->ConfigMacros[I], |
1954 | Module, ImportLoc); |
1955 | } |
1956 | |
1957 | |
1958 | getPreprocessor() |
1959 | .getHeaderSearchInfo() |
1960 | .getModuleMap() |
1961 | .resolveLinkAsDependencies(TopModule); |
1962 | |
1963 | LastModuleImportLoc = ImportLoc; |
1964 | LastModuleImportResult = ModuleLoadResult(Module); |
1965 | return LastModuleImportResult; |
1966 | } |
1967 | |
1968 | void CompilerInstance::loadModuleFromSource(SourceLocation ImportLoc, |
1969 | StringRef ModuleName, |
1970 | StringRef Source) { |
1971 | |
1972 | SmallString<128> CleanModuleName(ModuleName); |
1973 | for (auto &C : CleanModuleName) |
1974 | if (!isAlphanumeric(C)) |
1975 | C = '_'; |
1976 | |
1977 | |
1978 | |
1979 | |
1980 | SmallString<128> ModuleFileName; |
1981 | if (std::error_code EC = llvm::sys::fs::createTemporaryFile( |
1982 | CleanModuleName, "pcm", ModuleFileName)) { |
1983 | getDiagnostics().Report(ImportLoc, diag::err_fe_unable_to_open_output) |
1984 | << ModuleFileName << EC.message(); |
1985 | return; |
1986 | } |
1987 | std::string ModuleMapFileName = (CleanModuleName + ".map").str(); |
1988 | |
1989 | FrontendInputFile Input( |
1990 | ModuleMapFileName, |
1991 | InputKind(getLanguageFromOptions(*Invocation->getLangOpts()), |
1992 | InputKind::ModuleMap, )); |
1993 | |
1994 | std::string NullTerminatedSource(Source.str()); |
1995 | |
1996 | auto PreBuildStep = [&](CompilerInstance &Other) { |
1997 | |
1998 | |
1999 | const FileEntry *ModuleMapFile = Other.getFileManager().getVirtualFile( |
2000 | ModuleMapFileName, NullTerminatedSource.size(), 0); |
2001 | Other.getSourceManager().overrideFileContents( |
2002 | ModuleMapFile, |
2003 | llvm::MemoryBuffer::getMemBuffer(NullTerminatedSource.c_str())); |
2004 | |
2005 | Other.BuiltModules = std::move(BuiltModules); |
2006 | Other.DeleteBuiltModules = false; |
2007 | }; |
2008 | |
2009 | auto PostBuildStep = [this](CompilerInstance &Other) { |
2010 | BuiltModules = std::move(Other.BuiltModules); |
2011 | }; |
2012 | |
2013 | |
2014 | if (compileModuleImpl(*this, ImportLoc, ModuleName, Input, StringRef(), |
2015 | ModuleFileName, PreBuildStep, PostBuildStep)) { |
2016 | BuiltModules[ModuleName] = ModuleFileName.str(); |
2017 | llvm::sys::RemoveFileOnSignal(ModuleFileName); |
2018 | } |
2019 | } |
2020 | |
2021 | void CompilerInstance::makeModuleVisible(Module *Mod, |
2022 | Module::NameVisibilityKind Visibility, |
2023 | SourceLocation ImportLoc) { |
2024 | if (!ModuleManager) |
2025 | createModuleManager(); |
2026 | if (!ModuleManager) |
2027 | return; |
2028 | |
2029 | ModuleManager->makeModuleVisible(Mod, Visibility, ImportLoc); |
2030 | } |
2031 | |
2032 | GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex( |
2033 | SourceLocation TriggerLoc) { |
2034 | if (getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty()) |
2035 | return nullptr; |
2036 | if (!ModuleManager) |
2037 | createModuleManager(); |
2038 | |
2039 | if (!ModuleManager) |
2040 | return nullptr; |
2041 | |
2042 | |
2043 | ModuleManager->loadGlobalIndex(); |
2044 | GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex(); |
2045 | |
2046 | if (!GlobalIndex && shouldBuildGlobalModuleIndex() && hasFileManager() && |
2047 | hasPreprocessor()) { |
2048 | llvm::sys::fs::create_directories( |
2049 | getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); |
2050 | GlobalModuleIndex::writeIndex( |
2051 | getFileManager(), getPCHContainerReader(), |
2052 | getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); |
2053 | ModuleManager->resetForReload(); |
2054 | ModuleManager->loadGlobalIndex(); |
2055 | GlobalIndex = ModuleManager->getGlobalIndex(); |
2056 | } |
2057 | |
2058 | |
2059 | if (!HaveFullGlobalModuleIndex && GlobalIndex && !buildingModule()) { |
2060 | ModuleMap &MMap = getPreprocessor().getHeaderSearchInfo().getModuleMap(); |
2061 | bool RecreateIndex = false; |
2062 | for (ModuleMap::module_iterator I = MMap.module_begin(), |
2063 | E = MMap.module_end(); I != E; ++I) { |
2064 | Module *TheModule = I->second; |
2065 | const FileEntry *Entry = TheModule->getASTFile(); |
2066 | if (!Entry) { |
2067 | SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path; |
2068 | Path.push_back(std::make_pair( |
2069 | getPreprocessor().getIdentifierInfo(TheModule->Name), TriggerLoc)); |
2070 | std::reverse(Path.begin(), Path.end()); |
2071 | |
2072 | loadModule(TheModule->DefinitionLoc, Path, Module::Hidden, false); |
2073 | RecreateIndex = true; |
2074 | } |
2075 | } |
2076 | if (RecreateIndex) { |
2077 | GlobalModuleIndex::writeIndex( |
2078 | getFileManager(), getPCHContainerReader(), |
2079 | getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); |
2080 | ModuleManager->resetForReload(); |
2081 | ModuleManager->loadGlobalIndex(); |
2082 | GlobalIndex = ModuleManager->getGlobalIndex(); |
2083 | } |
2084 | HaveFullGlobalModuleIndex = true; |
2085 | } |
2086 | return GlobalIndex; |
2087 | } |
2088 | |
2089 | |
2090 | bool |
2091 | CompilerInstance::lookupMissingImports(StringRef Name, |
2092 | SourceLocation TriggerLoc) { |
2093 | |
2094 | |
2095 | if (!buildingModule()) { |
2096 | |
2097 | GlobalModuleIndex *GlobalIndex = loadGlobalModuleIndex( |
2098 | TriggerLoc); |
2099 | |
2100 | |
2101 | if (GlobalIndex) { |
2102 | GlobalModuleIndex::HitSet FoundModules; |
2103 | |
2104 | |
2105 | |
2106 | |
2107 | if (GlobalIndex->lookupIdentifier(Name, FoundModules)) |
2108 | return true; |
2109 | } |
2110 | } |
2111 | |
2112 | return false; |
2113 | } |
2114 | void CompilerInstance::resetAndLeakSema() { llvm::BuryPointer(takeSema()); } |
2115 | |
2116 | void CompilerInstance::setExternalSemaSource( |
2117 | IntrusiveRefCntPtr<ExternalSemaSource> ESS) { |
2118 | ExternalSemaSrc = std::move(ESS); |
2119 | } |
2120 | |