1//===-- CompilerInstance.h - Clang Compiler Instance ------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
10#define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
11
12#include "clang/AST/ASTConsumer.h"
13#include "clang/Basic/Diagnostic.h"
14#include "clang/Basic/SourceManager.h"
15#include "clang/Basic/TargetInfo.h"
16#include "clang/Frontend/CompilerInvocation.h"
17#include "clang/Frontend/PCHContainerOperations.h"
18#include "clang/Frontend/Utils.h"
19#include "clang/Lex/DependencyDirectivesScanner.h"
20#include "clang/Lex/HeaderSearchOptions.h"
21#include "clang/Lex/ModuleLoader.h"
22#include "llvm/ADT/ArrayRef.h"
23#include "llvm/ADT/DenseMap.h"
24#include "llvm/ADT/IntrusiveRefCntPtr.h"
25#include "llvm/ADT/StringRef.h"
26#include "llvm/Support/BuryPointer.h"
27#include "llvm/Support/FileSystem.h"
28#include "llvm/Support/VirtualFileSystem.h"
29#include "llvm/Support/VirtualOutputBackend.h"
30#include <cassert>
31#include <list>
32#include <memory>
33#include <optional>
34#include <string>
35#include <utility>
36
37namespace llvm {
38class raw_fd_ostream;
39class PassPlugin;
40class Timer;
41class TimerGroup;
42}
43
44namespace clang {
45class ASTContext;
46class ASTReader;
47
48namespace serialization {
49class ModuleFile;
50}
51
52class CodeCompleteConsumer;
53class DiagnosticsEngine;
54class DiagnosticConsumer;
55class FileManager;
56class FrontendAction;
57class Module;
58class ModuleCache;
59class Preprocessor;
60class Sema;
61class SourceManager;
62class TargetInfo;
63enum class DisableValidationForModuleKind;
64
65/// CompilerInstance - Helper class for managing a single instance of the Clang
66/// compiler.
67///
68/// The CompilerInstance serves two purposes:
69/// (1) It manages the various objects which are necessary to run the compiler,
70/// for example the preprocessor, the target information, and the AST
71/// context.
72/// (2) It provides utility routines for constructing and manipulating the
73/// common Clang objects.
74///
75/// The compiler instance generally owns the instance of all the objects that it
76/// manages. However, clients can still share objects by manually setting the
77/// object and retaking ownership prior to destroying the CompilerInstance.
78///
79/// The compiler instance is intended to simplify clients, but not to lock them
80/// in to the compiler instance for everything. When possible, utility functions
81/// come in two forms; a short form that reuses the CompilerInstance objects,
82/// and a long form that takes explicit instances of any required objects.
83class CompilerInstance : public ModuleLoader {
84 /// The options used in this compiler instance.
85 std::shared_ptr<CompilerInvocation> Invocation;
86
87 /// The virtual file system instance.
88 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS;
89
90 /// The diagnostics engine instance.
91 IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
92
93 /// The target being compiled for.
94 IntrusiveRefCntPtr<TargetInfo> Target;
95
96 /// Options for the auxiliary target.
97 std::unique_ptr<TargetOptions> AuxTargetOpts;
98
99 /// Auxiliary Target info.
100 IntrusiveRefCntPtr<TargetInfo> AuxTarget;
101
102 /// The file manager.
103 IntrusiveRefCntPtr<FileManager> FileMgr;
104
105 /// The output manager.
106 IntrusiveRefCntPtr<llvm::vfs::OutputBackend> OutputMgr;
107
108 /// The source manager.
109 IntrusiveRefCntPtr<SourceManager> SourceMgr;
110
111 /// The cache of PCM files.
112 std::shared_ptr<ModuleCache> ModCache;
113
114 /// Functor for getting the dependency preprocessor directives of a file.
115 std::unique_ptr<DependencyDirectivesGetter> GetDependencyDirectives;
116
117 /// The preprocessor.
118 std::shared_ptr<Preprocessor> PP;
119
120 /// The AST context.
121 IntrusiveRefCntPtr<ASTContext> Context;
122
123 /// An optional sema source that will be attached to sema.
124 IntrusiveRefCntPtr<ExternalSemaSource> ExternalSemaSrc;
125
126 /// The AST consumer.
127 std::unique_ptr<ASTConsumer> Consumer;
128
129 /// The code completion consumer.
130 std::unique_ptr<CodeCompleteConsumer> CompletionConsumer;
131
132 /// The semantic analysis object.
133 std::unique_ptr<Sema> TheSema;
134
135 /// Back-end pass plugins.
136 std::vector<std::unique_ptr<llvm::PassPlugin>> PassPlugins;
137
138 /// The frontend timer group.
139 std::unique_ptr<llvm::TimerGroup> timerGroup;
140
141 /// The frontend timer.
142 std::unique_ptr<llvm::Timer> FrontendTimer;
143
144 /// The ASTReader, if one exists.
145 IntrusiveRefCntPtr<ASTReader> TheASTReader;
146
147 /// The module dependency collector for crashdumps
148 std::shared_ptr<ModuleDependencyCollector> ModuleDepCollector;
149
150 /// The module provider.
151 std::shared_ptr<PCHContainerOperations> ThePCHContainerOperations;
152
153 std::vector<std::shared_ptr<DependencyCollector>> DependencyCollectors;
154
155 /// The set of modules that failed to build.
156 ///
157 /// This value will be passed among all of the compiler instances created
158 /// to (re)build modules, so that once a module fails to build anywhere,
159 /// other instances will see that the module has failed and won't try to
160 /// build it again.
161 llvm::StringSet<> FailedModules;
162
163 /// The set of top-level modules that has already been built on the
164 /// fly as part of this overall compilation action.
165 std::map<std::string, std::string, std::less<>> BuiltModules;
166
167 /// Should we delete the BuiltModules when we're done?
168 bool DeleteBuiltModules = true;
169
170 /// The location of the module-import keyword for the last module
171 /// import.
172 SourceLocation LastModuleImportLoc;
173
174 /// The result of the last module import.
175 ///
176 ModuleLoadResult LastModuleImportResult;
177
178 /// Whether we should (re)build the global module index once we
179 /// have finished with this translation unit.
180 bool BuildGlobalModuleIndex = false;
181
182 /// We have a full global module index, with all modules.
183 bool HaveFullGlobalModuleIndex = false;
184
185 /// One or more modules failed to build.
186 bool DisableGeneratingGlobalModuleIndex = false;
187
188 /// The stream for verbose output if owned, otherwise nullptr.
189 std::unique_ptr<raw_ostream> OwnedVerboseOutputStream;
190
191 /// The stream for verbose output.
192 raw_ostream *VerboseOutputStream = &llvm::errs();
193
194 /// The list of active output files.
195 std::list<llvm::vfs::OutputFile> OutputFiles;
196
197 /// Force an output buffer.
198 std::unique_ptr<llvm::raw_pwrite_stream> OutputStream;
199
200 CompilerInstance(const CompilerInstance &) = delete;
201 void operator=(const CompilerInstance &) = delete;
202public:
203 explicit CompilerInstance(
204 std::shared_ptr<CompilerInvocation> Invocation =
205 std::make_shared<CompilerInvocation>(),
206 std::shared_ptr<PCHContainerOperations> PCHContainerOps =
207 std::make_shared<PCHContainerOperations>(),
208 std::shared_ptr<ModuleCache> ModCache = nullptr);
209 ~CompilerInstance() override;
210
211 /// @name High-Level Operations
212 /// @{
213
214 /// ExecuteAction - Execute the provided action against the compiler's
215 /// CompilerInvocation object.
216 ///
217 /// This function makes the following assumptions:
218 ///
219 /// - The invocation options should be initialized. This function does not
220 /// handle the '-help' or '-version' options, clients should handle those
221 /// directly.
222 ///
223 /// - The diagnostics engine should have already been created by the client.
224 ///
225 /// - No other CompilerInstance state should have been initialized (this is
226 /// an unchecked error).
227 ///
228 /// - Clients should have initialized any LLVM target features that may be
229 /// required.
230 ///
231 /// - Clients should eventually call llvm_shutdown() upon the completion of
232 /// this routine to ensure that any managed objects are properly destroyed.
233 ///
234 /// Note that this routine may write output to 'stderr'.
235 ///
236 /// \param Act - The action to execute.
237 /// \return - True on success.
238 //
239 // FIXME: Eliminate the llvm_shutdown requirement, that should either be part
240 // of the context or else not CompilerInstance specific.
241 bool ExecuteAction(FrontendAction &Act);
242
243 /// At the end of a compilation, print the number of warnings/errors.
244 void printDiagnosticStats();
245
246 /// Load the list of plugins requested in the \c FrontendOptions.
247 void LoadRequestedPlugins();
248
249 /// @}
250 /// @name Compiler Invocation and Options
251 /// @{
252
253 CompilerInvocation &getInvocation() { return *Invocation; }
254
255 std::shared_ptr<CompilerInvocation> getInvocationPtr() { return Invocation; }
256
257 /// Indicates whether we should (re)build the global module index.
258 bool shouldBuildGlobalModuleIndex() const;
259
260 /// Set the flag indicating whether we should (re)build the global
261 /// module index.
262 void setBuildGlobalModuleIndex(bool Build) {
263 BuildGlobalModuleIndex = Build;
264 }
265
266 /// @}
267 /// @name Forwarding Methods
268 /// @{
269
270 AnalyzerOptions &getAnalyzerOpts() { return Invocation->getAnalyzerOpts(); }
271
272 CodeGenOptions &getCodeGenOpts() {
273 return Invocation->getCodeGenOpts();
274 }
275 const CodeGenOptions &getCodeGenOpts() const {
276 return Invocation->getCodeGenOpts();
277 }
278
279 DependencyOutputOptions &getDependencyOutputOpts() {
280 return Invocation->getDependencyOutputOpts();
281 }
282 const DependencyOutputOptions &getDependencyOutputOpts() const {
283 return Invocation->getDependencyOutputOpts();
284 }
285
286 DiagnosticOptions &getDiagnosticOpts() {
287 return Invocation->getDiagnosticOpts();
288 }
289 const DiagnosticOptions &getDiagnosticOpts() const {
290 return Invocation->getDiagnosticOpts();
291 }
292
293 FileSystemOptions &getFileSystemOpts() {
294 return Invocation->getFileSystemOpts();
295 }
296 const FileSystemOptions &getFileSystemOpts() const {
297 return Invocation->getFileSystemOpts();
298 }
299
300 FrontendOptions &getFrontendOpts() {
301 return Invocation->getFrontendOpts();
302 }
303 const FrontendOptions &getFrontendOpts() const {
304 return Invocation->getFrontendOpts();
305 }
306
307 HeaderSearchOptions &getHeaderSearchOpts() {
308 return Invocation->getHeaderSearchOpts();
309 }
310 const HeaderSearchOptions &getHeaderSearchOpts() const {
311 return Invocation->getHeaderSearchOpts();
312 }
313
314 APINotesOptions &getAPINotesOpts() { return Invocation->getAPINotesOpts(); }
315 const APINotesOptions &getAPINotesOpts() const {
316 return Invocation->getAPINotesOpts();
317 }
318
319 LangOptions &getLangOpts() { return Invocation->getLangOpts(); }
320 const LangOptions &getLangOpts() const { return Invocation->getLangOpts(); }
321
322 PreprocessorOptions &getPreprocessorOpts() {
323 return Invocation->getPreprocessorOpts();
324 }
325 const PreprocessorOptions &getPreprocessorOpts() const {
326 return Invocation->getPreprocessorOpts();
327 }
328
329 PreprocessorOutputOptions &getPreprocessorOutputOpts() {
330 return Invocation->getPreprocessorOutputOpts();
331 }
332 const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
333 return Invocation->getPreprocessorOutputOpts();
334 }
335
336 TargetOptions &getTargetOpts() {
337 return Invocation->getTargetOpts();
338 }
339 const TargetOptions &getTargetOpts() const {
340 return Invocation->getTargetOpts();
341 }
342
343 /// @}
344 /// @name Diagnostics Engine
345 /// @{
346
347 bool hasDiagnostics() const { return Diagnostics != nullptr; }
348
349 /// Get the current diagnostics engine.
350 DiagnosticsEngine &getDiagnostics() const {
351 assert(Diagnostics && "Compiler instance has no diagnostics!");
352 return *Diagnostics;
353 }
354
355 IntrusiveRefCntPtr<DiagnosticsEngine> getDiagnosticsPtr() const {
356 assert(Diagnostics && "Compiler instance has no diagnostics!");
357 return Diagnostics;
358 }
359
360 /// setDiagnostics - Replace the current diagnostics engine.
361 void setDiagnostics(llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Value);
362
363 DiagnosticConsumer &getDiagnosticClient() const {
364 assert(Diagnostics && Diagnostics->getClient() &&
365 "Compiler instance has no diagnostic client!");
366 return *Diagnostics->getClient();
367 }
368
369 /// @}
370 /// @name VerboseOutputStream
371 /// @{
372
373 /// Replace the current stream for verbose output.
374 void setVerboseOutputStream(raw_ostream &Value);
375
376 /// Replace the current stream for verbose output.
377 void setVerboseOutputStream(std::unique_ptr<raw_ostream> Value);
378
379 /// Get the current stream for verbose output.
380 raw_ostream &getVerboseOutputStream() {
381 return *VerboseOutputStream;
382 }
383
384 /// @}
385 /// @name Target Info
386 /// @{
387
388 bool hasTarget() const { return Target != nullptr; }
389
390 TargetInfo &getTarget() const {
391 assert(Target && "Compiler instance has no target!");
392 return *Target;
393 }
394
395 IntrusiveRefCntPtr<TargetInfo> getTargetPtr() const {
396 assert(Target && "Compiler instance has no target!");
397 return Target;
398 }
399
400 /// Replace the current Target.
401 void setTarget(TargetInfo *Value);
402
403 /// @}
404 /// @name AuxTarget Info
405 /// @{
406
407 TargetInfo *getAuxTarget() const { return AuxTarget.get(); }
408
409 /// Replace the current AuxTarget.
410 void setAuxTarget(TargetInfo *Value);
411
412 // Create Target and AuxTarget based on current options
413 bool createTarget();
414
415 /// @}
416 /// @name Virtual File System
417 /// @{
418
419 bool hasVirtualFileSystem() const { return VFS != nullptr; }
420
421 /// Create a virtual file system instance based on the invocation.
422 ///
423 /// @param BaseFS The file system that may be used when configuring the final
424 /// file system, and act as the underlying file system. Must not
425 /// be NULL.
426 /// @param DC If non-NULL, the diagnostic consumer to be used in case
427 /// configuring the file system emits diagnostics. Note that the
428 /// DiagnosticsEngine using the consumer won't obey the
429 /// --warning-suppression-mappings= flag.
430 void createVirtualFileSystem(IntrusiveRefCntPtr<llvm::vfs::FileSystem>
431 BaseFS = llvm::vfs::getRealFileSystem(),
432 DiagnosticConsumer *DC = nullptr);
433
434 /// Use the given file system.
435 void setVirtualFileSystem(IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS) {
436 VFS = std::move(FS);
437 }
438
439 llvm::vfs::FileSystem &getVirtualFileSystem() const { return *VFS; }
440
441 IntrusiveRefCntPtr<llvm::vfs::FileSystem> getVirtualFileSystemPtr() const {
442 return VFS;
443 }
444
445 /// @}
446 /// @name File Manager
447 /// @{
448
449 bool hasFileManager() const { return FileMgr != nullptr; }
450
451 /// Return the current file manager to the caller.
452 FileManager &getFileManager() const {
453 assert(FileMgr && "Compiler instance has no file manager!");
454 return *FileMgr;
455 }
456
457 IntrusiveRefCntPtr<FileManager> getFileManagerPtr() const {
458 assert(FileMgr && "Compiler instance has no file manager!");
459 return FileMgr;
460 }
461
462 void resetAndLeakFileManager() {
463 llvm::BuryPointer(Ptr: FileMgr.get());
464 FileMgr.resetWithoutRelease();
465 }
466
467 /// Replace the current file manager.
468 void setFileManager(IntrusiveRefCntPtr<FileManager> Value);
469
470 /// @}
471 /// @name Output Manager
472 /// @{
473
474 /// Set the output manager.
475 void
476 setOutputManager(IntrusiveRefCntPtr<llvm::vfs::OutputBackend> NewOutputs);
477
478 /// Create an output manager.
479 void createOutputManager();
480
481 bool hasOutputManager() const { return bool(OutputMgr); }
482
483 llvm::vfs::OutputBackend &getOutputManager();
484 llvm::vfs::OutputBackend &getOrCreateOutputManager();
485
486 /// @}
487 /// @name Source Manager
488 /// @{
489
490 bool hasSourceManager() const { return SourceMgr != nullptr; }
491
492 /// Return the current source manager.
493 SourceManager &getSourceManager() const {
494 assert(SourceMgr && "Compiler instance has no source manager!");
495 return *SourceMgr;
496 }
497
498 IntrusiveRefCntPtr<SourceManager> getSourceManagerPtr() const {
499 assert(SourceMgr && "Compiler instance has no source manager!");
500 return SourceMgr;
501 }
502
503 void resetAndLeakSourceManager() {
504 llvm::BuryPointer(Ptr: SourceMgr.get());
505 SourceMgr.resetWithoutRelease();
506 }
507
508 /// setSourceManager - Replace the current source manager.
509 void setSourceManager(llvm::IntrusiveRefCntPtr<SourceManager> Value);
510
511 /// @}
512 /// @name Preprocessor
513 /// @{
514
515 bool hasPreprocessor() const { return PP != nullptr; }
516
517 /// Return the current preprocessor.
518 Preprocessor &getPreprocessor() const {
519 assert(PP && "Compiler instance has no preprocessor!");
520 return *PP;
521 }
522
523 std::shared_ptr<Preprocessor> getPreprocessorPtr() { return PP; }
524
525 void resetAndLeakPreprocessor() {
526 llvm::BuryPointer(Ptr: new std::shared_ptr<Preprocessor>(PP));
527 }
528
529 /// Replace the current preprocessor.
530 void setPreprocessor(std::shared_ptr<Preprocessor> Value);
531
532 /// @}
533 /// @name ASTContext
534 /// @{
535
536 bool hasASTContext() const { return Context != nullptr; }
537
538 ASTContext &getASTContext() const {
539 assert(Context && "Compiler instance has no AST context!");
540 return *Context;
541 }
542
543 IntrusiveRefCntPtr<ASTContext> getASTContextPtr() const {
544 assert(Context && "Compiler instance has no AST context!");
545 return Context;
546 }
547
548 void resetAndLeakASTContext() {
549 llvm::BuryPointer(Ptr: Context.get());
550 Context.resetWithoutRelease();
551 }
552
553 /// setASTContext - Replace the current AST context.
554 void setASTContext(llvm::IntrusiveRefCntPtr<ASTContext> Value);
555
556 /// Replace the current Sema; the compiler instance takes ownership
557 /// of S.
558 void setSema(Sema *S);
559
560 /// @}
561 /// @name ASTConsumer
562 /// @{
563
564 bool hasASTConsumer() const { return (bool)Consumer; }
565
566 ASTConsumer &getASTConsumer() const {
567 assert(Consumer && "Compiler instance has no AST consumer!");
568 return *Consumer;
569 }
570
571 /// takeASTConsumer - Remove the current AST consumer and give ownership to
572 /// the caller.
573 std::unique_ptr<ASTConsumer> takeASTConsumer() { return std::move(Consumer); }
574
575 /// setASTConsumer - Replace the current AST consumer; the compiler instance
576 /// takes ownership of \p Value.
577 void setASTConsumer(std::unique_ptr<ASTConsumer> Value);
578
579 /// @}
580 /// @name Semantic analysis
581 /// @{
582 bool hasSema() const { return (bool)TheSema; }
583
584 Sema &getSema() const {
585 assert(TheSema && "Compiler instance has no Sema object!");
586 return *TheSema;
587 }
588
589 std::unique_ptr<Sema> takeSema();
590 void resetAndLeakSema();
591
592 /// @}
593 /// @name Module Management
594 /// @{
595
596 IntrusiveRefCntPtr<ASTReader> getASTReader() const;
597 void setASTReader(IntrusiveRefCntPtr<ASTReader> Reader);
598
599 std::shared_ptr<ModuleDependencyCollector> getModuleDepCollector() const;
600 void setModuleDepCollector(
601 std::shared_ptr<ModuleDependencyCollector> Collector);
602
603 std::shared_ptr<PCHContainerOperations> getPCHContainerOperations() const {
604 return ThePCHContainerOperations;
605 }
606
607 /// Return the appropriate PCHContainerWriter depending on the
608 /// current CodeGenOptions.
609 const PCHContainerWriter &getPCHContainerWriter() const {
610 assert(Invocation && "cannot determine module format without invocation");
611 StringRef Format = getHeaderSearchOpts().ModuleFormat;
612 auto *Writer = ThePCHContainerOperations->getWriterOrNull(Format);
613 if (!Writer) {
614 if (Diagnostics)
615 Diagnostics->Report(DiagID: diag::err_module_format_unhandled) << Format;
616 llvm::report_fatal_error(reason: "unknown module format");
617 }
618 return *Writer;
619 }
620
621 /// Return the appropriate PCHContainerReader depending on the
622 /// current CodeGenOptions.
623 const PCHContainerReader &getPCHContainerReader() const {
624 assert(Invocation && "cannot determine module format without invocation");
625 StringRef Format = getHeaderSearchOpts().ModuleFormat;
626 auto *Reader = ThePCHContainerOperations->getReaderOrNull(Format);
627 if (!Reader) {
628 if (Diagnostics)
629 Diagnostics->Report(DiagID: diag::err_module_format_unhandled) << Format;
630 llvm::report_fatal_error(reason: "unknown module format");
631 }
632 return *Reader;
633 }
634
635 /// @}
636 /// @name Code Completion
637 /// @{
638
639 bool hasCodeCompletionConsumer() const { return (bool)CompletionConsumer; }
640
641 CodeCompleteConsumer &getCodeCompletionConsumer() const {
642 assert(CompletionConsumer &&
643 "Compiler instance has no code completion consumer!");
644 return *CompletionConsumer;
645 }
646
647 /// setCodeCompletionConsumer - Replace the current code completion consumer;
648 /// the compiler instance takes ownership of \p Value.
649 void setCodeCompletionConsumer(CodeCompleteConsumer *Value);
650
651 /// }
652 /// @name Back-end Pass Plugins
653 /// @{
654
655 llvm::ArrayRef<std::unique_ptr<llvm::PassPlugin>> getPassPlugins() const {
656 return PassPlugins;
657 }
658
659 /// @}
660 /// @name Frontend timer
661 /// @{
662
663 llvm::TimerGroup &getTimerGroup() const { return *timerGroup; }
664
665 llvm::Timer &getFrontendTimer() const {
666 assert(FrontendTimer && "Compiler instance has no frontend timer!");
667 return *FrontendTimer;
668 }
669
670 /// }
671 /// @name Output Files
672 /// @{
673
674 /// clearOutputFiles - Clear the output file list. The underlying output
675 /// streams must have been closed beforehand.
676 ///
677 /// \param EraseFiles - If true, attempt to erase the files from disk.
678 void clearOutputFiles(bool EraseFiles);
679
680 /// @}
681 /// @name Construction Utility Methods
682 /// @{
683
684 /// Create the diagnostics engine using the invocation's diagnostic options
685 /// and replace any existing one with it.
686 ///
687 /// Note that this routine also replaces the diagnostic client,
688 /// allocating one if one is not provided.
689 ///
690 /// \param Client If non-NULL, a diagnostic client that will be
691 /// attached to (and, then, owned by) the DiagnosticsEngine inside this AST
692 /// unit.
693 ///
694 /// \param ShouldOwnClient If Client is non-NULL, specifies whether
695 /// the diagnostic object should take ownership of the client.
696 void createDiagnostics(DiagnosticConsumer *Client = nullptr,
697 bool ShouldOwnClient = true);
698
699 /// Create a DiagnosticsEngine object.
700 ///
701 /// If no diagnostic client is provided, this creates a
702 /// DiagnosticConsumer that is owned by the returned diagnostic
703 /// object, if using directly the caller is responsible for
704 /// releasing the returned DiagnosticsEngine's client eventually.
705 ///
706 /// \param VFS The file system used to load the suppression mappings file.
707 ///
708 /// \param Opts - The diagnostic options; note that the created text
709 /// diagnostic object contains a reference to these options.
710 ///
711 /// \param Client If non-NULL, a diagnostic client that will be
712 /// attached to (and, then, owned by) the returned DiagnosticsEngine
713 /// object. If NULL, the returned DiagnosticsEngine will own a newly-created
714 /// client.
715 ///
716 /// \param CodeGenOpts If non-NULL, the code gen options in use, which may be
717 /// used by some diagnostics printers (for logging purposes only).
718 ///
719 /// \return The new object on success, or null on failure.
720 static IntrusiveRefCntPtr<DiagnosticsEngine>
721 createDiagnostics(llvm::vfs::FileSystem &VFS, DiagnosticOptions &Opts,
722 DiagnosticConsumer *Client = nullptr,
723 bool ShouldOwnClient = true,
724 const CodeGenOptions *CodeGenOpts = nullptr);
725
726 /// Create the file manager and replace any existing one with it.
727 void createFileManager();
728
729 /// Create the source manager and replace any existing one with it.
730 void createSourceManager();
731
732 /// Create the preprocessor, using the invocation, file, and source managers,
733 /// and replace any existing one with it.
734 void createPreprocessor(TranslationUnitKind TUKind);
735
736 void setDependencyDirectivesGetter(
737 std::unique_ptr<DependencyDirectivesGetter> Getter) {
738 GetDependencyDirectives = std::move(Getter);
739 }
740
741 std::string getSpecificModuleCachePath(StringRef ContextHash);
742 std::string getSpecificModuleCachePath() {
743 return getSpecificModuleCachePath(ContextHash: getInvocation().computeContextHash());
744 }
745
746 /// Create the AST context.
747 void createASTContext();
748
749 /// Create an external AST source to read a PCH file and attach it to the AST
750 /// context.
751 void createPCHExternalASTSource(
752 StringRef Path, DisableValidationForModuleKind DisableValidation,
753 bool AllowPCHWithCompilerErrors, void *DeserializationListener,
754 bool OwnDeserializationListener);
755
756 /// Create an external AST source to read a PCH file.
757 ///
758 /// \return - The new object on success, or null on failure.
759 static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource(
760 StringRef Path, StringRef Sysroot,
761 DisableValidationForModuleKind DisableValidation,
762 bool AllowPCHWithCompilerErrors, Preprocessor &PP, ModuleCache &ModCache,
763 ASTContext &Context, const PCHContainerReader &PCHContainerRdr,
764 const CodeGenOptions &CodeGenOpts,
765 ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
766 ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
767 void *DeserializationListener, bool OwnDeserializationListener,
768 bool Preamble, bool UseGlobalModuleIndex);
769
770 /// Create a code completion consumer using the invocation; note that this
771 /// will cause the source manager to truncate the input source file at the
772 /// completion point.
773 void createCodeCompletionConsumer();
774
775 /// Create a code completion consumer to print code completion results, at
776 /// \p Filename, \p Line, and \p Column, to the given output stream \p OS.
777 static CodeCompleteConsumer *createCodeCompletionConsumer(
778 Preprocessor &PP, StringRef Filename, unsigned Line, unsigned Column,
779 const CodeCompleteOptions &Opts, raw_ostream &OS);
780
781 /// Create the Sema object to be used for parsing.
782 void createSema(TranslationUnitKind TUKind,
783 CodeCompleteConsumer *CompletionConsumer);
784
785 /// Create the frontend timer and replace any existing one with it.
786 void createFrontendTimer();
787
788 /// Create the default output file (from the invocation's options) and add it
789 /// to the list of tracked output files.
790 ///
791 /// The files created by this are usually removed on signal, and, depending
792 /// on FrontendOptions, may also use a temporary file (that is, the data is
793 /// written to a temporary file which will atomically replace the target
794 /// output on success).
795 ///
796 /// \return - Null on error.
797 std::unique_ptr<raw_pwrite_stream> createDefaultOutputFile(
798 bool Binary = true, StringRef BaseInput = "", StringRef Extension = "",
799 bool RemoveFileOnSignal = true, bool CreateMissingDirectories = false,
800 bool ForceUseTemporary = false);
801
802 /// Create a new output file, optionally deriving the output path name, and
803 /// add it to the list of tracked output files.
804 ///
805 /// \return - Null on error.
806 std::unique_ptr<raw_pwrite_stream>
807 createOutputFile(StringRef OutputPath, bool Binary, bool RemoveFileOnSignal,
808 bool UseTemporary, bool CreateMissingDirectories = false);
809
810private:
811 /// Create a new output file and add it to the list of tracked output files.
812 ///
813 /// If \p OutputPath is empty, then createOutputFile will derive an output
814 /// path location as \p BaseInput, with any suffix removed, and \p Extension
815 /// appended. If \p OutputPath is not stdout and \p UseTemporary
816 /// is true, createOutputFile will create a new temporary file that must be
817 /// renamed to \p OutputPath in the end.
818 ///
819 /// \param OutputPath - If given, the path to the output file.
820 /// \param Binary - The mode to open the file in.
821 /// \param RemoveFileOnSignal - Whether the file should be registered with
822 /// llvm::sys::RemoveFileOnSignal. Note that this is not safe for
823 /// multithreaded use, as the underlying signal mechanism is not reentrant
824 /// \param UseTemporary - Create a new temporary file that must be renamed to
825 /// OutputPath in the end.
826 /// \param CreateMissingDirectories - When \p UseTemporary is true, create
827 /// missing directories in the output path.
828 Expected<std::unique_ptr<raw_pwrite_stream>>
829 createOutputFileImpl(StringRef OutputPath, bool Binary,
830 bool RemoveFileOnSignal, bool UseTemporary,
831 bool CreateMissingDirectories);
832
833public:
834 std::unique_ptr<raw_pwrite_stream> createNullOutputFile();
835
836 /// @}
837 /// @name Initialization Utility Methods
838 /// @{
839
840 /// InitializeSourceManager - Initialize the source manager to set InputFile
841 /// as the main file.
842 ///
843 /// \return True on success.
844 bool InitializeSourceManager(const FrontendInputFile &Input);
845
846 /// InitializeSourceManager - Initialize the source manager to set InputFile
847 /// as the main file.
848 ///
849 /// \return True on success.
850 static bool InitializeSourceManager(const FrontendInputFile &Input,
851 DiagnosticsEngine &Diags,
852 FileManager &FileMgr,
853 SourceManager &SourceMgr);
854
855 /// @}
856
857 void setOutputStream(std::unique_ptr<llvm::raw_pwrite_stream> OutStream) {
858 OutputStream = std::move(OutStream);
859 }
860
861 std::unique_ptr<llvm::raw_pwrite_stream> takeOutputStream() {
862 return std::move(OutputStream);
863 }
864
865 void createASTReader();
866
867 bool loadModuleFile(StringRef FileName,
868 serialization::ModuleFile *&LoadedModuleFile);
869
870 /// Configuration object for making the result of \c cloneForModuleCompile()
871 /// thread-safe.
872 class ThreadSafeCloneConfig {
873 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS;
874 DiagnosticConsumer &DiagConsumer;
875 std::shared_ptr<ModuleCache> ModCache;
876 std::shared_ptr<ModuleDependencyCollector> ModuleDepCollector;
877
878 public:
879 ThreadSafeCloneConfig(
880 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
881 DiagnosticConsumer &DiagConsumer, std::shared_ptr<ModuleCache> ModCache,
882 std::shared_ptr<ModuleDependencyCollector> ModuleDepCollector = nullptr)
883 : VFS(std::move(VFS)), DiagConsumer(DiagConsumer),
884 ModCache(std::move(ModCache)),
885 ModuleDepCollector(std::move(ModuleDepCollector)) {
886 assert(this->VFS && "Clone config requires non-null VFS");
887 assert(this->ModCache && "Clone config requires non-null ModuleCache");
888 }
889
890 IntrusiveRefCntPtr<llvm::vfs::FileSystem> getVFS() const { return VFS; }
891 DiagnosticConsumer &getDiagConsumer() const { return DiagConsumer; }
892 std::shared_ptr<ModuleCache> getModuleCache() const { return ModCache; }
893 std::shared_ptr<ModuleDependencyCollector> getModuleDepCollector() const {
894 return ModuleDepCollector;
895 }
896 };
897
898private:
899 /// Find a module, potentially compiling it, before reading its AST. This is
900 /// the guts of loadModule.
901 ///
902 /// For prebuilt modules, the Module is not expected to exist in
903 /// HeaderSearch's ModuleMap. If a ModuleFile by that name is in the
904 /// ModuleManager, then it will be loaded and looked up.
905 ///
906 /// For implicit modules, the Module is expected to already be in the
907 /// ModuleMap. First attempt to load it from the given path on disk. If that
908 /// fails, defer to compileModuleAndReadAST, which will first build and then
909 /// load it.
910 ModuleLoadResult findOrCompileModuleAndReadAST(StringRef ModuleName,
911 SourceLocation ImportLoc,
912 SourceRange ModuleNameRange,
913 bool IsInclusionDirective);
914
915 /// Creates a \c CompilerInstance for compiling a module.
916 ///
917 /// This expects a properly initialized \c FrontendInputFile.
918 std::unique_ptr<CompilerInstance> cloneForModuleCompileImpl(
919 SourceLocation ImportLoc, StringRef ModuleName, FrontendInputFile Input,
920 StringRef OriginalModuleMapFile, StringRef ModuleFileName,
921 std::optional<ThreadSafeCloneConfig> ThreadSafeConfig = std::nullopt);
922
923public:
924 /// Creates a new \c CompilerInstance for compiling a module.
925 ///
926 /// This takes care of creating appropriate \c FrontendInputFile for
927 /// public/private frameworks, inferred modules and such.
928 ///
929 /// The \c ThreadSafeConfig takes precedence over the \c DiagnosticConsumer
930 /// and \c FileSystem of this instance (and disables \c FileManager sharing).
931 std::unique_ptr<CompilerInstance> cloneForModuleCompile(
932 SourceLocation ImportLoc, const Module *Module, StringRef ModuleFileName,
933 std::optional<ThreadSafeCloneConfig> ThreadSafeConfig = std::nullopt);
934
935 /// Compile a module file for the given module, using the options
936 /// provided by the importing compiler instance. Returns true if the module
937 /// was built without errors.
938 // FIXME: This should be private, but it's called from static non-member
939 // functions in the implementation file.
940 bool compileModule(SourceLocation ImportLoc, StringRef ModuleName,
941 StringRef ModuleFileName, CompilerInstance &Instance);
942
943 ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
944 Module::NameVisibilityKind Visibility,
945 bool IsInclusionDirective) override;
946
947 void createModuleFromSource(SourceLocation ImportLoc, StringRef ModuleName,
948 StringRef Source) override;
949
950 void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility,
951 SourceLocation ImportLoc) override;
952
953 bool hadModuleLoaderFatalFailure() const {
954 return ModuleLoader::HadFatalFailure;
955 }
956
957 GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override;
958
959 bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override;
960
961 void addDependencyCollector(std::shared_ptr<DependencyCollector> Listener) {
962 DependencyCollectors.push_back(x: std::move(Listener));
963 }
964
965 void clearDependencyCollectors() { DependencyCollectors.clear(); }
966
967 std::vector<std::shared_ptr<DependencyCollector>> &getDependencyCollectors() {
968 return DependencyCollectors;
969 }
970
971 void setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS);
972
973 ModuleCache &getModuleCache() const { return *ModCache; }
974 std::shared_ptr<ModuleCache> getModuleCachePtr() const { return ModCache; }
975};
976
977} // end namespace clang
978
979#endif
980