//===- CompilerInvocation.h - Compiler Invocation Helper Data ---*- C -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_FLANG_FRONTEND_COMPILERINVOCATION_H #define LLVM_FLANG_FRONTEND_COMPILERINVOCATION_H #include "flang/Frontend/FrontendOptions.h" #include "flang/Frontend/PreprocessorOptions.h" #include "flang/Parser/parsing.h" #include "flang/Semantics/semantics.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticOptions.h" #include "llvm/Option/ArgList.h" #include namespace Fortran::frontend { /// Fill out Opts based on the options given in Args. /// /// When errors are encountered, return false and, if Diags is non-null, /// report the error(s). bool ParseDiagnosticArgs(clang::DiagnosticOptions &opts, llvm::opt::ArgList &args, bool defaultDiagColor = true); class CompilerInvocationBase { public: /// Options controlling the diagnostic engine. llvm::IntrusiveRefCntPtr diagnosticOpts_; /// Options for the preprocessor. std::shared_ptr preprocessorOpts_; CompilerInvocationBase(); CompilerInvocationBase(const CompilerInvocationBase &x); ~CompilerInvocationBase(); clang::DiagnosticOptions &GetDiagnosticOpts() { return *diagnosticOpts_.get(); } const clang::DiagnosticOptions &GetDiagnosticOpts() const { return *diagnosticOpts_.get(); } PreprocessorOptions &preprocessorOpts() { return *preprocessorOpts_; } const PreprocessorOptions &preprocessorOpts() const { return *preprocessorOpts_; } }; class CompilerInvocation : public CompilerInvocationBase { /// Options for the frontend driver // TODO: Merge with or translate to parserOpts_. We shouldn't need two sets of // options. FrontendOptions frontendOpts_; /// Options for Flang parser // TODO: Merge with or translate to frontendOpts_. We shouldn't need two sets // of options. Fortran::parser::Options parserOpts_; // Semantics context std::unique_ptr semanticsContext_; /// Semantic options // TODO: Merge with or translate to frontendOpts_. We shouldn't need two sets // of options. std::string moduleDir_ = "."; std::string moduleFileSuffix_ = ".mod"; bool debugModuleDir_ = false; bool warnAsErr_ = false; /// This flag controls the unparsing and is used to decide whether to print out /// the semantically analyzed version of an object or expression or the plain /// version that does not include any information from semantic analysis. bool useAnalyzedObjectsForUnparse_ = true; // Fortran Dialect options Fortran::common::IntrinsicTypeDefaultKinds defaultKinds_; bool EnableConformanceChecks_ = false; /// Used in e.g. unparsing to dump the analyzed rather than the original /// parse-tree objects. Fortran::parser::AnalyzedObjectsAsFortran AsFortran_{ [](llvm::raw_ostream &o, const Fortran::evaluate::GenericExprWrapper &x) { if (x.v) { x.v->AsFortran(o); } else { o << "(bad expression)"; } }, [](llvm::raw_ostream &o, const Fortran::evaluate::GenericAssignmentWrapper &x) { if (x.v) { x.v->AsFortran(o); } else { o << "(bad assignment)"; } }, [](llvm::raw_ostream &o, const Fortran::evaluate::ProcedureRef &x) { x.AsFortran(o << "CALL "); }, }; public: CompilerInvocation() = default; FrontendOptions &frontendOpts() { return frontendOpts_; } const FrontendOptions &frontendOpts() const { return frontendOpts_; } Fortran::parser::Options &fortranOpts() { return parserOpts_; } const Fortran::parser::Options &fortranOpts() const { return parserOpts_; } Fortran::semantics::SemanticsContext &semanticsContext() { return *semanticsContext_; } const Fortran::semantics::SemanticsContext &semanticsContext() const { return *semanticsContext_; } std::string &moduleDir() { return moduleDir_; } const std::string &moduleDir() const { return moduleDir_; } std::string &moduleFileSuffix() { return moduleFileSuffix_; } const std::string &moduleFileSuffix() const { return moduleFileSuffix_; } bool &debugModuleDir() { return debugModuleDir_; } const bool &debugModuleDir() const { return debugModuleDir_; } bool &warnAsErr() { return warnAsErr_; } const bool &warnAsErr() const { return warnAsErr_; } bool &useAnalyzedObjectsForUnparse() { return useAnalyzedObjectsForUnparse_; } const bool &useAnalyzedObjectsForUnparse() const { return useAnalyzedObjectsForUnparse_; } bool &enableConformanceChecks() { return EnableConformanceChecks_; } const bool &enableConformanceChecks() const { return EnableConformanceChecks_; } Fortran::parser::AnalyzedObjectsAsFortran &asFortran() { return AsFortran_; } const Fortran::parser::AnalyzedObjectsAsFortran &asFortran() const { return AsFortran_; } Fortran::common::IntrinsicTypeDefaultKinds &defaultKinds() { return defaultKinds_; } const Fortran::common::IntrinsicTypeDefaultKinds &defaultKinds() const { return defaultKinds_; } /// Create a compiler invocation from a list of input options. /// \returns true on success. /// \returns false if an error was encountered while parsing the arguments /// \param [out] res - The resulting invocation. static bool CreateFromArgs(CompilerInvocation &res, llvm::ArrayRef commandLineArgs, clang::DiagnosticsEngine &diags); // Enables the std=f2018 conformance check void set_EnableConformanceChecks() { EnableConformanceChecks_ = true; } /// Useful setters void SetModuleDir(std::string &moduleDir) { moduleDir_ = moduleDir; } void SetModuleFileSuffix(const char *moduleFileSuffix) { moduleFileSuffix_ = std::string(moduleFileSuffix); } void SetDebugModuleDir(bool flag) { debugModuleDir_ = flag; } void SetWarnAsErr(bool flag) { warnAsErr_ = flag; } void SetUseAnalyzedObjectsForUnparse(bool flag) { useAnalyzedObjectsForUnparse_ = flag; } /// Set the Fortran options to predifined defaults. These defaults are /// consistend with f18/f18.cpp. // TODO: We should map frontendOpts_ to parserOpts_ instead. For that, we // need to extend frontendOpts_ first. Next, we need to add the corresponding // compiler driver options in libclangDriver. void SetDefaultFortranOpts(); /// Set the default predefinitions. void setDefaultPredefinitions(); /// Collect the macro definitions from preprocessorOpts_ and prepare them for /// the parser (i.e. copy into parserOpts_) void collectMacroDefinitions(); /// Set the Fortran options to user-specified values. /// These values are found in the preprocessor options. void setFortranOpts(); /// Set the Semantic Options void setSemanticsOpts(Fortran::parser::AllCookedSources &); }; } // end namespace Fortran::frontend #endif // LLVM_FLANG_FRONTEND_COMPILERINVOCATION_H