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 symbolBaseObject56 // 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; CLASS_BOILERPLATE(Component)75 76 bool warnAsErr_ = false; Component(DataRef && b,const Symbol & c)77 78 /// This flag controls the unparsing and is used to decide whether to print out 79 /// the semantically analyzed version of an object or expression or the plain 80 /// version that does not include any information from semantic analysis. 81 bool useAnalyzedObjectsForUnparse_ = true; base()82 83 // Fortran Dialect options 84 Fortran::common::IntrinsicTypeDefaultKinds defaultKinds_; GetLastSymbol()85 86 bool EnableConformanceChecks_ = false; 87 88 /// Used in e.g. unparsing to dump the analyzed rather than the original 89 /// parse-tree objects. 90 Fortran::parser::AnalyzedObjectsAsFortran AsFortran_{ 91 [](llvm::raw_ostream &o, const Fortran::evaluate::GenericExprWrapper &x) { 92 if (x.v) { 93 x.v->AsFortran(o); 94 } else { 95 o << "(bad expression)"; 96 } 97 }, 98 [](llvm::raw_ostream &o, 99 const Fortran::evaluate::GenericAssignmentWrapper &x) { 100 if (x.v) { CLASS_BOILERPLATE(NamedEntity)101 x.v->AsFortran(o); 102 } else { NamedEntity(Component && c)103 o << "(bad assignment)"; 104 } IsSymbol()105 }, 106 [](llvm::raw_ostream &o, const Fortran::evaluate::ProcedureRef &x) { 107 x.AsFortran(o << "CALL "); 108 }, GetComponent()109 }; 110 111 public: 112 CompilerInvocation() = default; 113 114 FrontendOptions &frontendOpts() { return frontendOpts_; } 115 const FrontendOptions &frontendOpts() const { return frontendOpts_; } 116 117 Fortran::parser::Options &fortranOpts() { return parserOpts_; } 118 const Fortran::parser::Options &fortranOpts() const { return parserOpts_; } 119 120 Fortran::semantics::SemanticsContext &semanticsContext() { 121 return *semanticsContext_; 122 } 123 const Fortran::semantics::SemanticsContext &semanticsContext() const { 124 return *semanticsContext_; 125 } 126 127 std::string &moduleDir() { return moduleDir_; } 128 const std::string &moduleDir() const { return moduleDir_; } 129 130 std::string &moduleFileSuffix() { return moduleFileSuffix_; } 131 const std::string &moduleFileSuffix() const { return moduleFileSuffix_; } 132 133 bool &debugModuleDir() { return debugModuleDir_; } 134 const bool &debugModuleDir() const { return debugModuleDir_; } TypeParamInquiry(NamedEntity && x,const Symbol & param)135 136 bool &warnAsErr() { return warnAsErr_; } TypeParamInquiry(std::optional<NamedEntity> && x,const Symbol & param)137 const bool &warnAsErr() const { return warnAsErr_; } 138 139 bool &useAnalyzedObjectsForUnparse() { return useAnalyzedObjectsForUnparse_; } base()140 const bool &useAnalyzedObjectsForUnparse() const { 141 return useAnalyzedObjectsForUnparse_; 142 } 143 Rank()144 bool &enableConformanceChecks() { return EnableConformanceChecks_; } 145 const bool &enableConformanceChecks() const { 146 return EnableConformanceChecks_; 147 } 148 149 Fortran::parser::AnalyzedObjectsAsFortran &asFortran() { return AsFortran_; } 150 const Fortran::parser::AnalyzedObjectsAsFortran &asFortran() const { 151 return AsFortran_; 152 } 153 154 Fortran::common::IntrinsicTypeDefaultKinds &defaultKinds() { 155 return defaultKinds_; 156 } 157 const Fortran::common::IntrinsicTypeDefaultKinds &defaultKinds() const { 158 return defaultKinds_; 159 } 160 161 /// Create a compiler invocation from a list of input options. 162 /// \returns true on success. 163 /// \returns false if an error was encountered while parsing the arguments 164 /// \param [out] res - The resulting invocation. 165 static bool CreateFromArgs(CompilerInvocation &res, 166 llvm::ArrayRef<const char *> commandLineArgs, 167 clang::DiagnosticsEngine &diags); 168 169 // Enables the std=f2018 conformance check 170 void set_EnableConformanceChecks() { EnableConformanceChecks_ = true; } 171 172 /// Useful setters 173 void SetModuleDir(std::string &moduleDir) { moduleDir_ = moduleDir; } 174 175 void SetModuleFileSuffix(const char *moduleFileSuffix) { 176 moduleFileSuffix_ = std::string(moduleFileSuffix); 177 } 178 179 void SetDebugModuleDir(bool flag) { debugModuleDir_ = flag; } EVALUATE_UNION_CLASS_BOILERPLATESubscript180 181 void SetWarnAsErr(bool flag) { warnAsErr_ = flag; } 182 183 void SetUseAnalyzedObjectsForUnparse(bool flag) { 184 useAnalyzedObjectsForUnparse_ = flag; 185 } 186 187 /// Set the Fortran options to predifined defaults. These defaults are 188 /// consistend with f18/f18.cpp. 189 // TODO: We should map frontendOpts_ to parserOpts_ instead. For that, we 190 // need to extend frontendOpts_ first. Next, we need to add the corresponding 191 // compiler driver options in libclangDriver. 192 void SetDefaultFortranOpts(); 193 194 /// Set the default predefinitions. CLASS_BOILERPLATE(ArrayRef)195 void setDefaultPredefinitions(); 196 197 /// Collect the macro definitions from preprocessorOpts_ and prepare them for ArrayRef(Component && c,std::vector<Subscript> && ss)198 /// the parser (i.e. copy into parserOpts_) 199 void collectMacroDefinitions(); ArrayRef(NamedEntity && base,std::vector<Subscript> && ss)200 201 /// Set the Fortran options to user-specified values. 202 /// These values are found in the preprocessor options. 203 void setFortranOpts(); base()204 205 /// Set the Semantic Options 206 void setSemanticsOpts(Fortran::parser::AllCookedSources &); 207 }; size()208 209 } // end namespace Fortran::frontend 210 #endif // LLVM_FLANG_FRONTEND_COMPILERINVOCATION_H 211