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