blob: 16b069e9a328596124eda8f7a17dd8a0d6bca282 [file] [log] [blame]
//===- 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 <memory>
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<clang::DiagnosticOptions> diagnosticOpts_;
/// Options for the preprocessor.
std::shared_ptr<Fortran::frontend::PreprocessorOptions> 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<Fortran::semantics::SemanticsContext> 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<const char *> 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 predefined defaults.
// 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