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