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 assert(Context && "Compiler instance has no AST context!");
563 return Context;
564 }
565
566 void resetAndLeakASTContext() {
567 llvm::BuryPointer(Ptr: Context.get());
568 Context.resetWithoutRelease();
569 }
570
571 /// setASTContext - Replace the current AST context.
572 void setASTContext(llvm::IntrusiveRefCntPtr<ASTContext> Value);
573
574 /// Replace the current Sema; the compiler instance takes ownership
575 /// of S.
576 void setSema(Sema *S);
577
578 /// @}
579 /// @name ASTConsumer
580 /// @{
581
582 bool hasASTConsumer() const { return (bool)Consumer; }
583
584 ASTConsumer &getASTConsumer() const {
585 assert(Consumer && "Compiler instance has no AST consumer!");
586 return *Consumer;
587 }
588
589 /// takeASTConsumer - Remove the current AST consumer and give ownership to
590 /// the caller.
591 std::unique_ptr<ASTConsumer> takeASTConsumer() { return std::move(Consumer); }
592
593 /// setASTConsumer - Replace the current AST consumer; the compiler instance
594 /// takes ownership of \p Value.
595 void setASTConsumer(std::unique_ptr<ASTConsumer> Value);
596
597 /// @}
598 /// @name Semantic analysis
599 /// @{
600 bool hasSema() const { return (bool)TheSema; }
601
602 Sema &getSema() const {
603 assert(TheSema && "Compiler instance has no Sema object!");
604 return *TheSema;
605 }
606
607 std::unique_ptr<Sema> takeSema();
608 void resetAndLeakSema();
609
610 /// @}
611 /// @name Module Management
612 /// @{
613
614 IntrusiveRefCntPtr<ASTReader> getASTReader() const;
615 void setASTReader(IntrusiveRefCntPtr<ASTReader> Reader);
616
617 std::shared_ptr<ModuleDependencyCollector> getModuleDepCollector() const;
618 void setModuleDepCollector(
619 std::shared_ptr<ModuleDependencyCollector> Collector);
620
621 std::shared_ptr<PCHContainerOperations> getPCHContainerOperations() const {
622 return ThePCHContainerOperations;
623 }
624
625 /// Return the appropriate PCHContainerWriter depending on the
626 /// current CodeGenOptions.
627 const PCHContainerWriter &getPCHContainerWriter() const {
628 assert(Invocation && "cannot determine module format without invocation");
629 StringRef Format = getHeaderSearchOpts().ModuleFormat;
630 auto *Writer = ThePCHContainerOperations->getWriterOrNull(Format);
631 if (!Writer) {
632 if (Diagnostics)
633 Diagnostics->Report(DiagID: diag::err_module_format_unhandled) << Format;
634 llvm::report_fatal_error(reason: "unknown module format");
635 }
636 return *Writer;
637 }
638
639 /// Return the appropriate PCHContainerReader depending on the
640 /// current CodeGenOptions.
641 const PCHContainerReader &getPCHContainerReader() const {
642 assert(Invocation && "cannot determine module format without invocation");
643 StringRef Format = getHeaderSearchOpts().ModuleFormat;
644 auto *Reader = ThePCHContainerOperations->getReaderOrNull(Format);
645 if (!Reader) {
646 if (Diagnostics)
647 Diagnostics->Report(DiagID: diag::err_module_format_unhandled) << Format;
648 llvm::report_fatal_error(reason: "unknown module format");
649 }
650 return *Reader;
651 }
652
653 /// @}
654 /// @name Code Completion
655 /// @{
656
657 bool hasCodeCompletionConsumer() const { return (bool)CompletionConsumer; }
658
659 CodeCompleteConsumer &getCodeCompletionConsumer() const {
660 assert(CompletionConsumer &&
661 "Compiler instance has no code completion consumer!");
662 return *CompletionConsumer;
663 }
664
665 /// setCodeCompletionConsumer - Replace the current code completion consumer;
666 /// the compiler instance takes ownership of \p Value.
667 void setCodeCompletionConsumer(CodeCompleteConsumer *Value);
668
669 /// }
670 /// @name Back-end Pass Plugins
671 /// @{
672
673 llvm::ArrayRef<std::unique_ptr<llvm::PassPlugin>> getPassPlugins() const {
674 return PassPlugins;
675 }
676
677 /// @}
678 /// @name Frontend timer
679 /// @{
680
681 llvm::TimerGroup &getTimerGroup() const { return *timerGroup; }
682
683 llvm::Timer &getFrontendTimer() const {
684 assert(FrontendTimer && "Compiler instance has no frontend timer!");
685 return *FrontendTimer;
686 }
687
688 /// }
689 /// @name Output Files
690 /// @{
691
692 /// clearOutputFiles - Clear the output file list. The underlying output
693 /// streams must have been closed beforehand.
694 ///
695 /// \param EraseFiles - If true, attempt to erase the files from disk.
696 void clearOutputFiles(bool EraseFiles);
697
698 /// @}
699 /// @name Construction Utility Methods
700 /// @{
701
702 /// Create the diagnostics engine using the invocation's diagnostic options
703 /// and replace any existing one with it.
704 ///
705 /// Note that this routine also replaces the diagnostic client,
706 /// allocating one if one is not provided.
707 ///
708 /// \param Client If non-NULL, a diagnostic client that will be
709 /// attached to (and, then, owned by) the DiagnosticsEngine inside this AST
710 /// unit.
711 ///
712 /// \param ShouldOwnClient If Client is non-NULL, specifies whether
713 /// the diagnostic object should take ownership of the client.
714 void createDiagnostics(DiagnosticConsumer *Client = nullptr,
715 bool ShouldOwnClient = true);
716
717 /// Create a DiagnosticsEngine object.
718 ///
719 /// If no diagnostic client is provided, this creates a
720 /// DiagnosticConsumer that is owned by the returned diagnostic
721 /// object, if using directly the caller is responsible for
722 /// releasing the returned DiagnosticsEngine's client eventually.
723 ///
724 /// \param VFS The file system used to load the suppression mappings file.
725 ///
726 /// \param Opts - The diagnostic options; note that the created text
727 /// diagnostic object contains a reference to these options.
728 ///
729 /// \param Client If non-NULL, a diagnostic client that will be
730 /// attached to (and, then, owned by) the returned DiagnosticsEngine
731 /// object. If NULL, the returned DiagnosticsEngine will own a newly-created
732 /// client.
733 ///
734 /// \param CodeGenOpts If non-NULL, the code gen options in use, which may be
735 /// used by some diagnostics printers (for logging purposes only).
736 ///
737 /// \return The new object on success, or null on failure.
738 static IntrusiveRefCntPtr<DiagnosticsEngine>
739 createDiagnostics(llvm::vfs::FileSystem &VFS, DiagnosticOptions &Opts,
740 DiagnosticConsumer *Client = nullptr,
741 bool ShouldOwnClient = true,
742 const CodeGenOptions *CodeGenOpts = nullptr);
743
744 /// Create the file manager and replace any existing one with it.
745 void createFileManager();
746
747 /// Create the source manager and replace any existing one with it.
748 void createSourceManager();
749
750 /// Create the preprocessor, using the invocation, file, and source managers,
751 /// and replace any existing one with it.
752 void createPreprocessor(TranslationUnitKind TUKind);
753
754 void setDependencyDirectivesGetter(
755 std::unique_ptr<DependencyDirectivesGetter> Getter) {
756 GetDependencyDirectives = std::move(Getter);
757 }
758
759 /// Create the AST context.
760 void createASTContext();
761
762 /// Create an external AST source to read a PCH file and attach it to the AST
763 /// context.
764 void createPCHExternalASTSource(
765 StringRef Path, DisableValidationForModuleKind DisableValidation,
766 bool AllowPCHWithCompilerErrors, void *DeserializationListener,
767 bool OwnDeserializationListener);
768
769 /// Create an external AST source to read a PCH file.
770 ///
771 /// \return - The new object on success, or null on failure.
772 static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource(
773 StringRef Path, StringRef Sysroot,
774 DisableValidationForModuleKind DisableValidation,
775 bool AllowPCHWithCompilerErrors, Preprocessor &PP, ModuleCache &ModCache,
776 ASTContext &Context, const PCHContainerReader &PCHContainerRdr,
777 const CodeGenOptions &CodeGenOpts,
778 ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
779 ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
780 void *DeserializationListener, bool OwnDeserializationListener,
781 bool Preamble, bool UseGlobalModuleIndex);
782
783 /// Create a code completion consumer using the invocation; note that this
784 /// will cause the source manager to truncate the input source file at the
785 /// completion point.
786 void createCodeCompletionConsumer();
787
788 /// Create a code completion consumer to print code completion results, at
789 /// \p Filename, \p Line, and \p Column, to the given output stream \p OS.
790 static CodeCompleteConsumer *createCodeCompletionConsumer(
791 Preprocessor &PP, StringRef Filename, unsigned Line, unsigned Column,
792 const CodeCompleteOptions &Opts, raw_ostream &OS);
793
794 /// Create the Sema object to be used for parsing.
795 void createSema(TranslationUnitKind TUKind,
796 CodeCompleteConsumer *CompletionConsumer);
797
798 /// Create the frontend timer and replace any existing one with it.
799 void createFrontendTimer();
800
801 /// Create the default output file (from the invocation's options) and add it
802 /// to the list of tracked output files.
803 ///
804 /// The files created by this are usually removed on signal, and, depending
805 /// on FrontendOptions, may also use a temporary file (that is, the data is
806 /// written to a temporary file which will atomically replace the target
807 /// output on success).
808 ///
809 /// \return - Null on error.
810 std::unique_ptr<raw_pwrite_stream> createDefaultOutputFile(
811 bool Binary = true, StringRef BaseInput = "", StringRef Extension = "",
812 bool RemoveFileOnSignal = true, bool CreateMissingDirectories = false,
813 bool ForceUseTemporary = false, bool SetOnlyIfDifferent = false);
814
815 /// Create a new output file, optionally deriving the output path name, and
816 /// add it to the list of tracked output files.
817 ///
818 /// \return - Null on error.
819 std::unique_ptr<raw_pwrite_stream>
820 createOutputFile(StringRef OutputPath, bool Binary, bool RemoveFileOnSignal,
821 bool UseTemporary, bool CreateMissingDirectories = false,
822 bool SetOnlyIfDifferent = false);
823
824private:
825 /// Prepare the CompilerInstance for executing a frontend action.
826 ///
827 /// Called by ExecuteAction. Consolidates instance-level setup that was
828 /// previously duplicated across tool entry points (cc1_main,
829 /// clang-repl/Interpreter, etc.).
830 void PrepareForExecution();
831
832 /// Create a new output file and add it to the list of tracked output files.
833 ///
834 /// If \p OutputPath is empty, then createOutputFile will derive an output
835 /// path location as \p BaseInput, with any suffix removed, and \p Extension
836 /// appended. If \p OutputPath is not stdout and \p UseTemporary
837 /// is true, createOutputFile will create a new temporary file that must be
838 /// renamed to \p OutputPath in the end.
839 ///
840 /// \param OutputPath - If given, the path to the output file.
841 /// \param Binary - The mode to open the file in.
842 /// \param RemoveFileOnSignal - Whether the file should be registered with
843 /// llvm::sys::RemoveFileOnSignal. Note that this is not safe for
844 /// multithreaded use, as the underlying signal mechanism is not reentrant
845 /// \param UseTemporary - Create a new temporary file that must be renamed to
846 /// OutputPath in the end.
847 /// \param CreateMissingDirectories - When \p UseTemporary is true, create
848 /// missing directories in the output path.
849 Expected<std::unique_ptr<raw_pwrite_stream>>
850 createOutputFileImpl(StringRef OutputPath, bool Binary,
851 bool RemoveFileOnSignal, bool UseTemporary,
852 bool CreateMissingDirectories, bool SetOnlyIfDifferent);
853
854public:
855 std::unique_ptr<raw_pwrite_stream> createNullOutputFile();
856
857 /// @}
858 /// @name Initialization Utility Methods
859 /// @{
860
861 /// InitializeSourceManager - Initialize the source manager to set InputFile
862 /// as the main file.
863 ///
864 /// \return True on success.
865 bool InitializeSourceManager(const FrontendInputFile &Input);
866
867 /// InitializeSourceManager - Initialize the source manager to set InputFile
868 /// as the main file.
869 ///
870 /// \return True on success.
871 static bool InitializeSourceManager(const FrontendInputFile &Input,
872 DiagnosticsEngine &Diags,
873 FileManager &FileMgr,
874 SourceManager &SourceMgr);
875
876 /// @}
877
878 void setOutputStream(std::unique_ptr<llvm::raw_pwrite_stream> OutStream) {
879 OutputStream = std::move(OutStream);
880 }
881
882 std::unique_ptr<llvm::raw_pwrite_stream> takeOutputStream() {
883 return std::move(OutputStream);
884 }
885
886 void createASTReader();
887
888 bool loadModuleFile(ModuleFileName FileName,
889 serialization::ModuleFile *&LoadedModuleFile);
890
891 /// Configuration object for making the result of \c cloneForModuleCompile()
892 /// thread-safe.
893 class ThreadSafeCloneConfig {
894 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS;
895 DiagnosticConsumer &DiagConsumer;
896 std::shared_ptr<ModuleCache> ModCache;
897 std::shared_ptr<ModuleDependencyCollector> ModuleDepCollector;
898
899 public:
900 ThreadSafeCloneConfig(
901 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
902 DiagnosticConsumer &DiagConsumer, std::shared_ptr<ModuleCache> ModCache,
903 std::shared_ptr<ModuleDependencyCollector> ModuleDepCollector = nullptr)
904 : VFS(std::move(VFS)), DiagConsumer(DiagConsumer),
905 ModCache(std::move(ModCache)),
906 ModuleDepCollector(std::move(ModuleDepCollector)) {
907 assert(this->VFS && "Clone config requires non-null VFS");
908 assert(this->ModCache && "Clone config requires non-null ModuleCache");
909 }
910
911 IntrusiveRefCntPtr<llvm::vfs::FileSystem> getVFS() const { return VFS; }
912 DiagnosticConsumer &getDiagConsumer() const { return DiagConsumer; }
913 std::shared_ptr<ModuleCache> getModuleCache() const { return ModCache; }
914 std::shared_ptr<ModuleDependencyCollector> getModuleDepCollector() const {
915 return ModuleDepCollector;
916 }
917 };
918
919private:
920 /// Find a module, potentially compiling it, before reading its AST. This is
921 /// the guts of loadModule.
922 ///
923 /// For prebuilt modules, the Module is not expected to exist in
924 /// HeaderSearch's ModuleMap. If a ModuleFile by that name is in the
925 /// ModuleManager, then it will be loaded and looked up.
926 ///
927 /// For implicit modules, the Module is expected to already be in the
928 /// ModuleMap. First attempt to load it from the given path on disk. If that
929 /// fails, defer to compileModuleAndReadAST, which will first build and then
930 /// load it.
931 ModuleLoadResult findOrCompileModuleAndReadAST(StringRef ModuleName,
932 SourceLocation ImportLoc,
933 SourceRange ModuleNameRange,
934 bool IsInclusionDirective);
935
936 /// Creates a \c CompilerInstance for compiling a module.
937 ///
938 /// This expects a properly initialized \c FrontendInputFile.
939 std::unique_ptr<CompilerInstance> cloneForModuleCompileImpl(
940 SourceLocation ImportLoc, StringRef ModuleName, FrontendInputFile Input,
941 StringRef OriginalModuleMapFile, StringRef ModuleFileName,
942 std::optional<ThreadSafeCloneConfig> ThreadSafeConfig = std::nullopt);
943
944public:
945 /// Creates a new \c CompilerInstance for compiling a module.
946 ///
947 /// This takes care of creating appropriate \c FrontendInputFile for
948 /// public/private frameworks, inferred modules and such.
949 ///
950 /// The \c ThreadSafeConfig takes precedence over the \c DiagnosticConsumer
951 /// and \c FileSystem of this instance (and disables \c FileManager sharing).
952 std::unique_ptr<CompilerInstance> cloneForModuleCompile(
953 SourceLocation ImportLoc, const Module *Module, StringRef ModuleFileName,
954 std::optional<ThreadSafeCloneConfig> ThreadSafeConfig = std::nullopt);
955
956 /// Compile a module file for the given module, using the options
957 /// provided by the importing compiler instance. Returns the PCM file in
958 /// a buffer.
959 // FIXME: This should be private, but it's called from static non-member
960 // functions in the implementation file.
961 std::unique_ptr<llvm::MemoryBuffer> compileModule(SourceLocation ImportLoc,
962 StringRef ModuleName,
963 StringRef ModuleFileName,
964 CompilerInstance &Instance);
965
966 ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
967 Module::NameVisibilityKind Visibility,
968 bool IsInclusionDirective) override;
969
970 void createModuleFromSource(SourceLocation ImportLoc, StringRef ModuleName,
971 StringRef Source) override;
972
973 void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility,
974 SourceLocation ImportLoc) override;
975
976 bool hadModuleLoaderFatalFailure() const {
977 return ModuleLoader::HadFatalFailure;
978 }
979
980 GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override;
981
982 bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override;
983
984 void setGenModuleActionWrapper(GenModuleActionWrapperFunc Wrapper) {
985 GenModuleActionWrapper = Wrapper;
986 }
987
988 GenModuleActionWrapperFunc getGenModuleActionWrapper() const {
989 return GenModuleActionWrapper;
990 }
991
992 void addDependencyCollector(std::shared_ptr<DependencyCollector> Listener) {
993 DependencyCollectors.push_back(x: std::move(Listener));
994 }
995
996 void clearDependencyCollectors() { DependencyCollectors.clear(); }
997
998 std::vector<std::shared_ptr<DependencyCollector>> &getDependencyCollectors() {
999 return DependencyCollectors;
1000 }
1001
1002 void setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS);
1003
1004 ModuleCache &getModuleCache() const { return *ModCache; }
1005 std::shared_ptr<ModuleCache> getModuleCachePtr() const { return ModCache; }
1006};
1007
1008} // end namespace clang
1009
1010#endif
1011