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