• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- CompilerInstance.h - Flang 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 #ifndef LLVM_FLANG_FRONTEND_COMPILERINSTANCE_H
9 #define LLVM_FLANG_FRONTEND_COMPILERINSTANCE_H
10 
11 #include "flang/Frontend/CompilerInvocation.h"
12 #include "flang/Frontend/FrontendAction.h"
13 #include "flang/Parser/parsing.h"
14 #include "flang/Parser/provenance.h"
15 #include "llvm/Support/raw_ostream.h"
16 
17 namespace Fortran::frontend {
18 
19 class CompilerInstance {
20 
21   /// The options used in this compiler instance.
22   std::shared_ptr<CompilerInvocation> invocation_;
23 
24   /// Flang file  manager.
25   std::shared_ptr<Fortran::parser::AllSources> allSources_;
26 
27   std::shared_ptr<Fortran::parser::AllCookedSources> allCookedSources_;
28 
29   std::shared_ptr<Fortran::parser::Parsing> parsing_;
30 
31   /// The diagnostics engine instance.
32   llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_;
33 
34   /// Holds information about the output file.
35   struct OutputFile {
36     std::string filename_;
OutputFileOutputFile37     OutputFile(std::string inputFilename)
38         : filename_(std::move(inputFilename)) {}
39   };
40 
41   /// Output stream that doesn't support seeking (e.g. terminal, pipe).
42   /// This stream is normally wrapped in buffer_ostream before being passed
43   /// to users (e.g. via CreateOutputFile).
44   std::unique_ptr<llvm::raw_fd_ostream> nonSeekStream_;
45 
46   /// The list of active output files.
47   std::list<OutputFile> outputFiles_;
48 
49   /// Holds the output stream provided by the user. Normally, users of
50   /// CompilerInstance will call CreateOutputFile to obtain/create an output
51   /// stream. If they want to provide their own output stream, this field will
52   /// facilitate this. It is optional and will normally be just a nullptr.
53   std::unique_ptr<llvm::raw_pwrite_stream> outputStream_;
54 
55 public:
56   explicit CompilerInstance();
57 
58   ~CompilerInstance();
59 
60   /// @name Compiler Invocation
61   /// {
62 
invocation()63   CompilerInvocation &invocation() {
64     assert(invocation_ && "Compiler instance has no invocation!");
65     return *invocation_;
66   };
67 
68   /// Replace the current invocation.
69   void set_invocation(std::shared_ptr<CompilerInvocation> value);
70 
71   /// }
72   /// @name File manager
73   /// {
74 
75   /// Return the current allSources.
allSources()76   Fortran::parser::AllSources &allSources() const { return *allSources_; }
77 
HasAllSources()78   bool HasAllSources() const { return allSources_ != nullptr; }
79 
80   /// }
81   /// @name Parser Operations
82   /// {
83 
84   /// Return parsing to be used by Actions.
parsing()85   Fortran::parser::Parsing &parsing() const { return *parsing_; }
86 
87   /// }
88   /// @name High-Level Operations
89   /// {
90 
91   /// Execute the provided action against the compiler's
92   /// CompilerInvocation object.
93   /// \param act - The action to execute.
94   /// \return - True on success.
95   bool ExecuteAction(FrontendAction &act);
96 
97   /// }
98   /// @name Forwarding Methods
99   /// {
100 
GetDiagnosticOpts()101   clang::DiagnosticOptions &GetDiagnosticOpts() {
102     return invocation_->GetDiagnosticOpts();
103   }
GetDiagnosticOpts()104   const clang::DiagnosticOptions &GetDiagnosticOpts() const {
105     return invocation_->GetDiagnosticOpts();
106   }
107 
frontendOpts()108   FrontendOptions &frontendOpts() { return invocation_->frontendOpts(); }
frontendOpts()109   const FrontendOptions &frontendOpts() const {
110     return invocation_->frontendOpts();
111   }
112 
113   /// }
114   /// @name Diagnostics Engine
115   /// {
116 
HasDiagnostics()117   bool HasDiagnostics() const { return diagnostics_ != nullptr; }
118 
119   /// Get the current diagnostics engine.
diagnostics()120   clang::DiagnosticsEngine &diagnostics() const {
121     assert(diagnostics_ && "Compiler instance has no diagnostics!");
122     return *diagnostics_;
123   }
124 
GetDiagnosticClient()125   clang::DiagnosticConsumer &GetDiagnosticClient() const {
126     assert(diagnostics_ && diagnostics_->getClient() &&
127         "Compiler instance has no diagnostic client!");
128     return *diagnostics_->getClient();
129   }
130 
131   /// {
132   /// @name Output Files
133   /// {
134 
135   /// Add an output file onto the list of tracked output files.
136   ///
137   /// \param outFile - The output file info.
138   void AddOutputFile(OutputFile &&outFile);
139 
140   /// Clear the output file list.
141   void ClearOutputFiles(bool eraseFiles);
142 
143   /// Create the default output file (based on the invocation's options) and
144   /// add it to the list of tracked output files. If the name of the output
145   /// file is not provided, it is derived from the input file.
146   ///
147   /// \param binary     The mode to open the file in.
148   /// \param baseInput  If the invocation contains no output file name (i.e.
149   ///                   outputFile_ in FrontendOptions is empty), the input path
150   ///                   name to use for deriving the output path.
151   /// \param extension  The extension to use for output names derived from
152   ///                   \p baseInput.
153   /// \return           ostream for the output file or nullptr on error.
154   std::unique_ptr<llvm::raw_pwrite_stream> CreateDefaultOutputFile(
155       bool binary = true, llvm::StringRef baseInput = "",
156       llvm::StringRef extension = "");
157 
158   /// Create a new output file
159   ///
160   /// \param outputPath   The path to the output file.
161   /// \param error [out]  On failure, the error.
162   /// \param binary       The mode to open the file in.
163   /// \return             ostream for the output file or nullptr on error.
164   std::unique_ptr<llvm::raw_pwrite_stream> CreateOutputFile(
165       llvm::StringRef outputPath, std::error_code &error, bool binary);
166 
167   /// }
168   /// @name Construction Utility Methods
169   /// {
170 
171   /// Create a DiagnosticsEngine object
172   ///
173   /// If no diagnostic client is provided, this method creates a
174   /// DiagnosticConsumer that is owned by the returned diagnostic object. If
175   /// using directly the caller is responsible for releasing the returned
176   /// DiagnosticsEngine's client eventually.
177   ///
178   /// \param opts - The diagnostic options; note that the created text
179   /// diagnostic object contains a reference to these options.
180   ///
181   /// \param client - If non-NULL, a diagnostic client that will be attached to
182   /// (and optionally, depending on /p shouldOwnClient, owned by) the returned
183   /// DiagnosticsEngine object.
184   ///
185   /// \return The new object on success, or null on failure.
186   static clang::IntrusiveRefCntPtr<clang::DiagnosticsEngine> CreateDiagnostics(
187       clang::DiagnosticOptions *opts,
188       clang::DiagnosticConsumer *client = nullptr, bool shouldOwnClient = true);
189   void CreateDiagnostics(
190       clang::DiagnosticConsumer *client = nullptr, bool shouldOwnClient = true);
191 
192   /// }
193   /// @name Output Stream Methods
194   /// {
set_outputStream(std::unique_ptr<llvm::raw_pwrite_stream> outStream)195   void set_outputStream(std::unique_ptr<llvm::raw_pwrite_stream> outStream) {
196     outputStream_ = std::move(outStream);
197   }
198 
IsOutputStreamNull()199   bool IsOutputStreamNull() { return (outputStream_ == nullptr); }
200 
201   // Allow the frontend compiler to write in the output stream.
WriteOutputStream(const std::string & message)202   void WriteOutputStream(const std::string &message) {
203     *outputStream_ << message;
204   }
205 };
206 
207 } // end namespace Fortran::frontend
208 #endif // LLVM_FLANG_FRONTEND_COMPILERINSTANCE_H
209