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 #ifndef LLVM_FLANG_FRONTEND_COMPILERINVOCATION_H
9 #define LLVM_FLANG_FRONTEND_COMPILERINVOCATION_H
10 
11 #include "flang/Frontend/FrontendOptions.h"
12 #include "flang/Frontend/PreprocessorOptions.h"
13 #include "flang/Parser/parsing.h"
14 #include "flang/Semantics/semantics.h"
15 #include "clang/Basic/Diagnostic.h"
16 #include "clang/Basic/DiagnosticOptions.h"
17 #include "llvm/Option/ArgList.h"
18 #include <memory>
19 
20 namespace Fortran::frontend {
21 
22 /// Fill out Opts based on the options given in Args.
23 ///
24 /// When errors are encountered, return false and, if Diags is non-null,
25 /// report the error(s).
26 bool ParseDiagnosticArgs(clang::DiagnosticOptions &opts,
27     llvm::opt::ArgList &args, bool defaultDiagColor = true);
28 
29 class CompilerInvocationBase {
30 public:
31   /// Options controlling the diagnostic engine.
32   llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> diagnosticOpts_;
33   /// Options for the preprocessor.
34   std::shared_ptr<Fortran::frontend::PreprocessorOptions> preprocessorOpts_;
35 
36   CompilerInvocationBase();
37   CompilerInvocationBase(const CompilerInvocationBase &x);
38   ~CompilerInvocationBase();
39 
40   clang::DiagnosticOptions &GetDiagnosticOpts() {
41     return *diagnosticOpts_.get();
42   }
43   const clang::DiagnosticOptions &GetDiagnosticOpts() const {
44     return *diagnosticOpts_.get();
45   }
46 
47   PreprocessorOptions &preprocessorOpts() { return *preprocessorOpts_; }
48   const PreprocessorOptions &preprocessorOpts() const {
49     return *preprocessorOpts_;
50   }
51 };
52 
53 class CompilerInvocation : public CompilerInvocationBase {
54   /// Options for the frontend driver
55   // TODO: Merge with or translate to parserOpts_. We shouldn't need two sets of
56   // options.
57   FrontendOptions frontendOpts_;
58 
59   /// Options for Flang parser
60   // TODO: Merge with or translate to frontendOpts_. We shouldn't need two sets
61   // of options.
62   Fortran::parser::Options parserOpts_;
63 
64   // Semantics context
65   std::unique_ptr<Fortran::semantics::SemanticsContext> semanticsContext_;
66 
67   /// Semantic options
68   // TODO: Merge with or translate to frontendOpts_. We shouldn't need two sets
69   // of options.
70   std::string moduleDir_ = ".";
71 
72   std::string moduleFileSuffix_ = ".mod";
73 
74   bool debugModuleDir_ = false;
75 
76   bool warnAsErr_ = false;
77 
78   // Fortran Dialect options
79   Fortran::common::IntrinsicTypeDefaultKinds defaultKinds_;
80 
81   bool EnableConformanceChecks_ = false;
82 
83 public:
84   CompilerInvocation() = default;
85 
86   FrontendOptions &frontendOpts() { return frontendOpts_; }
87   const FrontendOptions &frontendOpts() const { return frontendOpts_; }
88 
89   Fortran::parser::Options &fortranOpts() { return parserOpts_; }
90   const Fortran::parser::Options &fortranOpts() const { return parserOpts_; }
91 
92   Fortran::semantics::SemanticsContext &semanticsContext() {
93     return *semanticsContext_;
94   }
95   const Fortran::semantics::SemanticsContext &semanticsContext() const {
96     return *semanticsContext_;
97   }
98 
99   std::string &moduleDir() { return moduleDir_; }
100   const std::string &moduleDir() const { return moduleDir_; }
101 
102   std::string &moduleFileSuffix() { return moduleFileSuffix_; }
103   const std::string &moduleFileSuffix() const { return moduleFileSuffix_; }
104 
105   bool &debugModuleDir() { return debugModuleDir_; }
106   const bool &debugModuleDir() const { return debugModuleDir_; }
107 
108   bool &warnAsErr() { return warnAsErr_; }
109   const bool &warnAsErr() const { return warnAsErr_; }
110 
111   bool &enableConformanceChecks() { return EnableConformanceChecks_; }
112   const bool &enableConformanceChecks() const {
113     return EnableConformanceChecks_;
114   }
115 
116   Fortran::common::IntrinsicTypeDefaultKinds &defaultKinds() {
117     return defaultKinds_;
118   }
119   const Fortran::common::IntrinsicTypeDefaultKinds &defaultKinds() const {
120     return defaultKinds_;
121   }
122 
123   /// Create a compiler invocation from a list of input options.
124   /// \returns true on success.
125   /// \returns false if an error was encountered while parsing the arguments
126   /// \param [out] res - The resulting invocation.
127   static bool CreateFromArgs(CompilerInvocation &res,
128       llvm::ArrayRef<const char *> commandLineArgs,
129       clang::DiagnosticsEngine &diags);
130 
131   // Enables the std=f2018 conformance check
132   void set_EnableConformanceChecks() { EnableConformanceChecks_ = true; }
133 
134   /// Useful setters
135   void SetModuleDir(std::string &moduleDir) { moduleDir_ = moduleDir; }
136 
137   void SetModuleFileSuffix(const char *moduleFileSuffix) {
138     moduleFileSuffix_ = std::string(moduleFileSuffix);
139   }
140 
141   void SetDebugModuleDir(bool flag) { debugModuleDir_ = flag; }
142 
143   void SetWarnAsErr(bool flag) { warnAsErr_ = flag; }
144 
145   /// Set the Fortran options to predifined defaults. These defaults are
146   /// consistend with f18/f18.cpp.
147   // TODO: We should map frontendOpts_ to parserOpts_ instead. For that, we
148   // need to extend frontendOpts_ first. Next, we need to add the corresponding
149   // compiler driver options in libclangDriver.
150   void SetDefaultFortranOpts();
151 
152   /// Set the default predefinitions.
153   void setDefaultPredefinitions();
154 
155   /// Collect the macro definitions from preprocessorOpts_ and prepare them for
156   /// the parser (i.e. copy into parserOpts_)
157   void collectMacroDefinitions();
158 
159   /// Set the Fortran options to user-specified values.
160   /// These values are found in the preprocessor options.
161   void setFortranOpts();
162 
163   /// Set the Semantic Options
164   void setSemanticsOpts(Fortran::parser::AllCookedSources &);
165 };
166 
167 } // end namespace Fortran::frontend
168 #endif // LLVM_FLANG_FRONTEND_COMPILERINVOCATION_H
169