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/Frontend/TargetOptions.h" 14 #include "flang/Parser/parsing.h" 15 #include "flang/Semantics/semantics.h" 16 #include "clang/Basic/Diagnostic.h" 17 #include "clang/Basic/DiagnosticOptions.h" 18 #include "llvm/Option/ArgList.h" 19 #include <memory> 20 21 namespace Fortran::frontend { 22 23 /// Fill out Opts based on the options given in Args. 24 /// 25 /// When errors are encountered, return false and, if Diags is non-null, 26 /// report the error(s). 27 bool ParseDiagnosticArgs(clang::DiagnosticOptions &opts, 28 llvm::opt::ArgList &args, bool defaultDiagColor = true); 29 30 class CompilerInvocationBase { 31 public: 32 /// Options controlling the diagnostic engine. 33 llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> diagnosticOpts_; 34 /// Options for the preprocessor. 35 std::shared_ptr<Fortran::frontend::PreprocessorOptions> preprocessorOpts_; 36 37 CompilerInvocationBase(); 38 CompilerInvocationBase(const CompilerInvocationBase &x); 39 ~CompilerInvocationBase(); 40 41 clang::DiagnosticOptions &GetDiagnosticOpts() { 42 return *diagnosticOpts_.get(); 43 } 44 const clang::DiagnosticOptions &GetDiagnosticOpts() const { 45 return *diagnosticOpts_.get(); 46 } 47 48 PreprocessorOptions &preprocessorOpts() { return *preprocessorOpts_; } 49 const PreprocessorOptions &preprocessorOpts() const { 50 return *preprocessorOpts_; 51 } 52 }; 53 54 class CompilerInvocation : public CompilerInvocationBase { 55 /// Options for the frontend driver 56 // TODO: Merge with or translate to parserOpts_. We shouldn't need two sets of 57 // options. 58 FrontendOptions frontendOpts_; 59 60 /// Options for Flang parser 61 // TODO: Merge with or translate to frontendOpts_. We shouldn't need two sets 62 // of options. 63 Fortran::parser::Options parserOpts_; 64 65 /// Options controlling the target. 66 Fortran::frontend::TargetOptions targetOpts_; 67 68 // Semantics context 69 std::unique_ptr<Fortran::semantics::SemanticsContext> semanticsContext_; 70 71 /// Semantic options 72 // TODO: Merge with or translate to frontendOpts_. We shouldn't need two sets 73 // of options. 74 std::string moduleDir_ = "."; 75 76 std::string moduleFileSuffix_ = ".mod"; 77 78 bool debugModuleDir_ = false; 79 80 bool warnAsErr_ = false; 81 82 /// This flag controls the unparsing and is used to decide whether to print out 83 /// the semantically analyzed version of an object or expression or the plain 84 /// version that does not include any information from semantic analysis. 85 bool useAnalyzedObjectsForUnparse_ = true; 86 87 // Fortran Dialect options 88 Fortran::common::IntrinsicTypeDefaultKinds defaultKinds_; 89 90 bool EnableConformanceChecks_ = false; 91 92 /// Used in e.g. unparsing to dump the analyzed rather than the original 93 /// parse-tree objects. 94 Fortran::parser::AnalyzedObjectsAsFortran AsFortran_{ 95 [](llvm::raw_ostream &o, const Fortran::evaluate::GenericExprWrapper &x) { 96 if (x.v) { 97 x.v->AsFortran(o); 98 } else { 99 o << "(bad expression)"; 100 } 101 }, 102 [](llvm::raw_ostream &o, 103 const Fortran::evaluate::GenericAssignmentWrapper &x) { 104 if (x.v) { 105 x.v->AsFortran(o); 106 } else { 107 o << "(bad assignment)"; 108 } 109 }, 110 [](llvm::raw_ostream &o, const Fortran::evaluate::ProcedureRef &x) { 111 x.AsFortran(o << "CALL "); 112 }, 113 }; 114 115 public: 116 CompilerInvocation() = default; 117 118 FrontendOptions &frontendOpts() { return frontendOpts_; } 119 const FrontendOptions &frontendOpts() const { return frontendOpts_; } 120 121 Fortran::parser::Options &fortranOpts() { return parserOpts_; } 122 const Fortran::parser::Options &fortranOpts() const { return parserOpts_; } 123 124 TargetOptions &targetOpts() { return targetOpts_; } 125 const TargetOptions &TargetOpts() const { return targetOpts_; } 126 127 Fortran::semantics::SemanticsContext &semanticsContext() { 128 return *semanticsContext_; 129 } 130 const Fortran::semantics::SemanticsContext &semanticsContext() const { 131 return *semanticsContext_; 132 } 133 134 std::string &moduleDir() { return moduleDir_; } 135 const std::string &moduleDir() const { return moduleDir_; } 136 137 std::string &moduleFileSuffix() { return moduleFileSuffix_; } 138 const std::string &moduleFileSuffix() const { return moduleFileSuffix_; } 139 140 bool &debugModuleDir() { return debugModuleDir_; } 141 const bool &debugModuleDir() const { return debugModuleDir_; } 142 143 bool &warnAsErr() { return warnAsErr_; } 144 const bool &warnAsErr() const { return warnAsErr_; } 145 146 bool &useAnalyzedObjectsForUnparse() { return useAnalyzedObjectsForUnparse_; } 147 const bool &useAnalyzedObjectsForUnparse() const { 148 return useAnalyzedObjectsForUnparse_; 149 } 150 151 bool &enableConformanceChecks() { return EnableConformanceChecks_; } 152 const bool &enableConformanceChecks() const { 153 return EnableConformanceChecks_; 154 } 155 156 Fortran::parser::AnalyzedObjectsAsFortran &asFortran() { return AsFortran_; } 157 const Fortran::parser::AnalyzedObjectsAsFortran &asFortran() const { 158 return AsFortran_; 159 } 160 161 Fortran::common::IntrinsicTypeDefaultKinds &defaultKinds() { 162 return defaultKinds_; 163 } 164 const Fortran::common::IntrinsicTypeDefaultKinds &defaultKinds() const { 165 return defaultKinds_; 166 } 167 168 /// Create a compiler invocation from a list of input options. 169 /// \returns true on success. 170 /// \returns false if an error was encountered while parsing the arguments 171 /// \param [out] res - The resulting invocation. 172 static bool CreateFromArgs(CompilerInvocation &res, 173 llvm::ArrayRef<const char *> commandLineArgs, 174 clang::DiagnosticsEngine &diags); 175 176 // Enables the std=f2018 conformance check 177 void set_EnableConformanceChecks() { EnableConformanceChecks_ = true; } 178 179 /// Useful setters 180 void SetModuleDir(std::string &moduleDir) { moduleDir_ = moduleDir; } 181 182 void SetModuleFileSuffix(const char *moduleFileSuffix) { 183 moduleFileSuffix_ = std::string(moduleFileSuffix); 184 } 185 186 void SetDebugModuleDir(bool flag) { debugModuleDir_ = flag; } 187 188 void SetWarnAsErr(bool flag) { warnAsErr_ = flag; } 189 190 void SetUseAnalyzedObjectsForUnparse(bool flag) { 191 useAnalyzedObjectsForUnparse_ = flag; 192 } 193 194 /// Set the Fortran options to predefined defaults. 195 // TODO: We should map frontendOpts_ to parserOpts_ instead. For that, we 196 // need to extend frontendOpts_ first. Next, we need to add the corresponding 197 // compiler driver options in libclangDriver. 198 void SetDefaultFortranOpts(); 199 200 /// Set the default predefinitions. 201 void SetDefaultPredefinitions(); 202 203 /// Collect the macro definitions from preprocessorOpts_ and prepare them for 204 /// the parser (i.e. copy into parserOpts_) 205 void CollectMacroDefinitions(); 206 207 /// Set the Fortran options to user-specified values. 208 /// These values are found in the preprocessor options. 209 void SetFortranOpts(); 210 211 /// Set the Semantic Options 212 void SetSemanticsOpts(Fortran::parser::AllCookedSources &); 213 }; 214 215 } // end namespace Fortran::frontend 216 #endif // LLVM_FLANG_FRONTEND_COMPILERINVOCATION_H 217