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