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