xref: /llvm-project/flang/include/flang/Frontend/CompilerInvocation.h (revision 310c281b020b169e760ca75f878f5873ffbb2a9f)
1 //===- CompilerInvocation.h - Compiler Invocation Helper Data ---*- 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 // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef FORTRAN_FRONTEND_COMPILERINVOCATION_H
14 #define FORTRAN_FRONTEND_COMPILERINVOCATION_H
15 
16 #include "flang/Common/LangOptions.h"
17 #include "flang/Frontend/CodeGenOptions.h"
18 #include "flang/Frontend/FrontendOptions.h"
19 #include "flang/Frontend/PreprocessorOptions.h"
20 #include "flang/Frontend/TargetOptions.h"
21 #include "flang/Lower/LoweringOptions.h"
22 #include "flang/Parser/parsing.h"
23 #include "flang/Semantics/semantics.h"
24 #include "mlir/Support/Timing.h"
25 #include "clang/Basic/Diagnostic.h"
26 #include "clang/Basic/DiagnosticOptions.h"
27 #include "llvm/Option/ArgList.h"
28 #include <memory>
29 
30 namespace llvm {
31 class TargetMachine;
32 }
33 
34 namespace Fortran::frontend {
35 
36 /// Fill out Opts based on the options given in Args.
37 ///
38 /// When errors are encountered, return false and, if Diags is non-null,
39 /// report the error(s).
40 bool parseDiagnosticArgs(clang::DiagnosticOptions &opts,
41                          llvm::opt::ArgList &args);
42 
43 class CompilerInvocationBase {
44 public:
45   /// Options controlling the diagnostic engine.
46   llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> diagnosticOpts;
47   /// Options for the preprocessor.
48   std::shared_ptr<Fortran::frontend::PreprocessorOptions> preprocessorOpts;
49 
50   CompilerInvocationBase();
51   CompilerInvocationBase(const CompilerInvocationBase &x);
52   ~CompilerInvocationBase();
53 
54   clang::DiagnosticOptions &getDiagnosticOpts() {
55     return *diagnosticOpts.get();
56   }
57   const clang::DiagnosticOptions &getDiagnosticOpts() const {
58     return *diagnosticOpts.get();
59   }
60 
61   PreprocessorOptions &getPreprocessorOpts() { return *preprocessorOpts; }
62   const PreprocessorOptions &getPreprocessorOpts() const {
63     return *preprocessorOpts;
64   }
65 };
66 
67 class CompilerInvocation : public CompilerInvocationBase {
68   /// Options for the frontend driver
69   // TODO: Merge with or translate to parserOpts_. We shouldn't need two sets of
70   // options.
71   FrontendOptions frontendOpts;
72 
73   /// Options for Flang parser
74   // TODO: Merge with or translate to frontendOpts. We shouldn't need two sets
75   // of options.
76   Fortran::parser::Options parserOpts;
77 
78   /// Options controlling lowering.
79   Fortran::lower::LoweringOptions loweringOpts;
80 
81   /// Options controlling the target.
82   Fortran::frontend::TargetOptions targetOpts;
83 
84   /// Options controlling IRgen and the backend.
85   Fortran::frontend::CodeGenOptions codeGenOpts;
86 
87   /// Options controlling language dialect.
88   Fortran::common::LangOptions langOpts;
89 
90   // The original invocation of the compiler driver.
91   // This string will be set as the return value from the COMPILER_OPTIONS
92   // intrinsic of iso_fortran_env.
93   std::string allCompilerInvocOpts;
94 
95   /// Semantic options
96   // TODO: Merge with or translate to frontendOpts. We shouldn't need two sets
97   // of options.
98   std::string moduleDir = ".";
99 
100   std::string moduleFileSuffix = ".mod";
101 
102   bool debugModuleDir = false;
103   bool hermeticModuleFileOutput = false;
104 
105   bool warnAsErr = false;
106 
107   // Executable name
108   const char *argv0;
109 
110   /// This flag controls the unparsing and is used to decide whether to print
111   /// out the semantically analyzed version of an object or expression or the
112   /// plain version that does not include any information from semantic
113   /// analysis.
114   bool useAnalyzedObjectsForUnparse = true;
115 
116   // Fortran Dialect options
117   Fortran::common::IntrinsicTypeDefaultKinds defaultKinds;
118 
119   // Fortran Warning options
120   bool enableConformanceChecks = false;
121   bool enableUsageChecks = false;
122   bool disableWarnings = false;
123 
124   /// Used in e.g. unparsing to dump the analyzed rather than the original
125   /// parse-tree objects.
126   Fortran::parser::AnalyzedObjectsAsFortran asFortran{
127       [](llvm::raw_ostream &o, const Fortran::evaluate::GenericExprWrapper &x) {
128         if (x.v) {
129           x.v->AsFortran(o);
130         } else {
131           o << "(bad expression)";
132         }
133       },
134       [](llvm::raw_ostream &o,
135          const Fortran::evaluate::GenericAssignmentWrapper &x) {
136         if (x.v) {
137           x.v->AsFortran(o);
138         } else {
139           o << "(bad assignment)";
140         }
141       },
142       [](llvm::raw_ostream &o, const Fortran::evaluate::ProcedureRef &x) {
143         x.AsFortran(o << "CALL ");
144       },
145   };
146 
147   /// Whether to time the invocation. Set when -ftime-report or -ftime-report=
148   /// is enabled.
149   bool enableTimers;
150 
151 public:
152   CompilerInvocation() = default;
153 
154   FrontendOptions &getFrontendOpts() { return frontendOpts; }
155   const FrontendOptions &getFrontendOpts() const { return frontendOpts; }
156 
157   Fortran::parser::Options &getFortranOpts() { return parserOpts; }
158   const Fortran::parser::Options &getFortranOpts() const { return parserOpts; }
159 
160   TargetOptions &getTargetOpts() { return targetOpts; }
161   const TargetOptions &getTargetOpts() const { return targetOpts; }
162 
163   CodeGenOptions &getCodeGenOpts() { return codeGenOpts; }
164   const CodeGenOptions &getCodeGenOpts() const { return codeGenOpts; }
165 
166   Fortran::common::LangOptions &getLangOpts() { return langOpts; }
167   const Fortran::common::LangOptions &getLangOpts() const { return langOpts; }
168 
169   Fortran::lower::LoweringOptions &getLoweringOpts() { return loweringOpts; }
170   const Fortran::lower::LoweringOptions &getLoweringOpts() const {
171     return loweringOpts;
172   }
173 
174   /// Creates and configures semantics context based on the compilation flags.
175   std::unique_ptr<Fortran::semantics::SemanticsContext>
176   getSemanticsCtx(Fortran::parser::AllCookedSources &allCookedSources,
177                   const llvm::TargetMachine &);
178 
179   std::string &getModuleDir() { return moduleDir; }
180   const std::string &getModuleDir() const { return moduleDir; }
181 
182   std::string &getModuleFileSuffix() { return moduleFileSuffix; }
183   const std::string &getModuleFileSuffix() const { return moduleFileSuffix; }
184 
185   bool &getDebugModuleDir() { return debugModuleDir; }
186   const bool &getDebugModuleDir() const { return debugModuleDir; }
187 
188   bool &getHermeticModuleFileOutput() { return hermeticModuleFileOutput; }
189   const bool &getHermeticModuleFileOutput() const {
190     return hermeticModuleFileOutput;
191   }
192 
193   bool &getWarnAsErr() { return warnAsErr; }
194   const bool &getWarnAsErr() const { return warnAsErr; }
195 
196   bool &getUseAnalyzedObjectsForUnparse() {
197     return useAnalyzedObjectsForUnparse;
198   }
199   const bool &getUseAnalyzedObjectsForUnparse() const {
200     return useAnalyzedObjectsForUnparse;
201   }
202 
203   bool &getEnableConformanceChecks() { return enableConformanceChecks; }
204   const bool &getEnableConformanceChecks() const {
205     return enableConformanceChecks;
206   }
207 
208   const char *getArgv0() { return argv0; }
209 
210   bool &getEnableUsageChecks() { return enableUsageChecks; }
211   const bool &getEnableUsageChecks() const { return enableUsageChecks; }
212 
213   bool &getDisableWarnings() { return disableWarnings; }
214   const bool &getDisableWarnings() const { return disableWarnings; }
215 
216   Fortran::parser::AnalyzedObjectsAsFortran &getAsFortran() {
217     return asFortran;
218   }
219   const Fortran::parser::AnalyzedObjectsAsFortran &getAsFortran() const {
220     return asFortran;
221   }
222 
223   Fortran::common::IntrinsicTypeDefaultKinds &getDefaultKinds() {
224     return defaultKinds;
225   }
226   const Fortran::common::IntrinsicTypeDefaultKinds &getDefaultKinds() const {
227     return defaultKinds;
228   }
229 
230   bool getEnableTimers() const { return enableTimers; }
231 
232   /// Create a compiler invocation from a list of input options.
233   /// \returns true on success.
234   /// \returns false if an error was encountered while parsing the arguments
235   /// \param [out] res - The resulting invocation.
236   static bool createFromArgs(CompilerInvocation &res,
237                              llvm::ArrayRef<const char *> commandLineArgs,
238                              clang::DiagnosticsEngine &diags,
239                              const char *argv0 = nullptr);
240 
241   // Enables the std=f2018 conformance check
242   void setEnableConformanceChecks() { enableConformanceChecks = true; }
243 
244   // Enables the usage checks
245   void setEnableUsageChecks() { enableUsageChecks = true; }
246 
247   // Disables all Warnings
248   void setDisableWarnings() { disableWarnings = true; }
249 
250   /// Useful setters
251   void setArgv0(const char *dir) { argv0 = dir; }
252 
253   void setModuleDir(std::string &dir) { moduleDir = dir; }
254 
255   void setModuleFileSuffix(const char *suffix) {
256     moduleFileSuffix = std::string(suffix);
257   }
258 
259   void setDebugModuleDir(bool flag) { debugModuleDir = flag; }
260   void setHermeticModuleFileOutput(bool flag) {
261     hermeticModuleFileOutput = flag;
262   }
263 
264   void setWarnAsErr(bool flag) { warnAsErr = flag; }
265 
266   void setUseAnalyzedObjectsForUnparse(bool flag) {
267     useAnalyzedObjectsForUnparse = flag;
268   }
269 
270   /// Set the Fortran options to predefined defaults.
271   // TODO: We should map frontendOpts_ to parserOpts_ instead. For that, we
272   // need to extend frontendOpts_ first. Next, we need to add the corresponding
273   // compiler driver options in libclangDriver.
274   void setDefaultFortranOpts();
275 
276   /// Set the default predefinitions.
277   void setDefaultPredefinitions();
278 
279   /// Collect the macro definitions from preprocessorOpts_ and prepare them for
280   /// the parser (i.e. copy into parserOpts_)
281   void collectMacroDefinitions();
282 
283   /// Set the Fortran options to user-specified values.
284   /// These values are found in the preprocessor options.
285   void setFortranOpts();
286 
287   /// Set the Semantic Options
288   void setSemanticsOpts(Fortran::parser::AllCookedSources &);
289 
290   /// Set \p loweringOptions controlling lowering behavior based
291   /// on the \p optimizationLevel.
292   void setLoweringOptions();
293 };
294 
295 } // end namespace Fortran::frontend
296 #endif // FORTRAN_FRONTEND_COMPILERINVOCATION_H
297