mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-10 06:26:08 +00:00

This patch adds support for the `-cpp` and `-nocpp` flags. The implemented semantics match f18 (i.e. the "throwaway" driver), but are different to gfortran. In Flang the preprocessor is always run. Instead, `-cpp/-nocpp` are used to control whether predefined and command-line preprocessor macro definitions are enabled or not. In practice this is sufficient to model gfortran`s `-cpp/-nocpp`. In the absence of `-cpp/-nocpp`, the driver will use the extension of the input file to decide whether to include the standard macro predefinitions. gfortran's documentation [1] was used to decide which file extension to use for this. The logic mentioned above was added in FrontendAction::BeginSourceFile. That's relatively late in the driver set-up, but this roughly where the name of the input file becomes available. The logic for deciding between fixed and free form works in a similar way and was also moved to FrontendAction::BeginSourceFile for consistency (and to reduce code-duplication). The `-cpp/-nocpp` flags are respected also when the input is read from stdin. This is different to: * gfortran (behaves as if `-cpp` was used) * f18 (behaves as if `-nocpp` was used) Starting with this patch, file extensions are significant and some test files had to be renamed to reflect that. Where possible, preprocessor tests were updated so that they can be shared between `f18` and `flang-new`. This was implemented on top of adding new test for `-cpp/-nocpp`. [1] https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html Reviewed By: kiranchandramohan Differential Revision: https://reviews.llvm.org/D99292
133 lines
5.0 KiB
C++
133 lines
5.0 KiB
C++
//===-- Flang.cpp - Flang+LLVM ToolChain Implementations --------*- 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
#include "Flang.h"
|
|
#include "CommonArgs.h"
|
|
|
|
#include "clang/Driver/Options.h"
|
|
|
|
#include <cassert>
|
|
|
|
using namespace clang::driver;
|
|
using namespace clang::driver::tools;
|
|
using namespace clang;
|
|
using namespace llvm::opt;
|
|
|
|
void Flang::AddFortranDialectOptions(const ArgList &Args,
|
|
ArgStringList &CmdArgs) const {
|
|
Args.AddAllArgs(
|
|
CmdArgs, {options::OPT_ffixed_form, options::OPT_ffree_form,
|
|
options::OPT_ffixed_line_length_EQ, options::OPT_fopenmp,
|
|
options::OPT_fopenacc, options::OPT_finput_charset_EQ,
|
|
options::OPT_fimplicit_none, options::OPT_fno_implicit_none,
|
|
options::OPT_fbackslash, options::OPT_fno_backslash,
|
|
options::OPT_flogical_abbreviations,
|
|
options::OPT_fno_logical_abbreviations,
|
|
options::OPT_fxor_operator, options::OPT_fno_xor_operator,
|
|
options::OPT_falternative_parameter_statement,
|
|
options::OPT_fdefault_real_8, options::OPT_fdefault_integer_8,
|
|
options::OPT_fdefault_double_8, options::OPT_flarge_sizes});
|
|
}
|
|
|
|
void Flang::AddPreprocessingOptions(const ArgList &Args,
|
|
ArgStringList &CmdArgs) const {
|
|
Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I,
|
|
options::OPT_cpp, options::OPT_nocpp});
|
|
}
|
|
|
|
void Flang::AddOtherOptions(const ArgList &Args, ArgStringList &CmdArgs) const {
|
|
Args.AddAllArgs(CmdArgs,
|
|
{options::OPT_module_dir, options::OPT_fdebug_module_writer,
|
|
options::OPT_fintrinsic_modules_path, options::OPT_pedantic,
|
|
options::OPT_std_EQ, options::OPT_W_Joined});
|
|
}
|
|
|
|
void Flang::ConstructJob(Compilation &C, const JobAction &JA,
|
|
const InputInfo &Output, const InputInfoList &Inputs,
|
|
const ArgList &Args, const char *LinkingOutput) const {
|
|
const auto &TC = getToolChain();
|
|
// TODO: Once code-generation is available, this will need to be commented
|
|
// out.
|
|
// const llvm::Triple &Triple = TC.getEffectiveTriple();
|
|
// const std::string &TripleStr = Triple.getTriple();
|
|
|
|
ArgStringList CmdArgs;
|
|
|
|
// Invoke ourselves in -fc1 mode.
|
|
CmdArgs.push_back("-fc1");
|
|
|
|
// TODO: Once code-generation is available, this will need to be commented
|
|
// out.
|
|
// Add the "effective" target triple.
|
|
// CmdArgs.push_back("-triple");
|
|
// CmdArgs.push_back(Args.MakeArgString(TripleStr));
|
|
|
|
if (isa<PreprocessJobAction>(JA)) {
|
|
CmdArgs.push_back("-E");
|
|
} else if (isa<CompileJobAction>(JA) || isa<BackendJobAction>(JA)) {
|
|
if (JA.getType() == types::TY_Nothing) {
|
|
CmdArgs.push_back("-fsyntax-only");
|
|
} else if (JA.getType() == types::TY_AST) {
|
|
CmdArgs.push_back("-emit-ast");
|
|
} else if (JA.getType() == types::TY_LLVM_IR ||
|
|
JA.getType() == types::TY_LTO_IR) {
|
|
CmdArgs.push_back("-emit-llvm");
|
|
} else if (JA.getType() == types::TY_LLVM_BC ||
|
|
JA.getType() == types::TY_LTO_BC) {
|
|
CmdArgs.push_back("-emit-llvm-bc");
|
|
} else if (JA.getType() == types::TY_PP_Asm) {
|
|
CmdArgs.push_back("-S");
|
|
} else {
|
|
assert(false && "Unexpected output type!");
|
|
}
|
|
} else if (isa<AssembleJobAction>(JA)) {
|
|
CmdArgs.push_back("-emit-obj");
|
|
} else {
|
|
assert(false && "Unexpected action class for Flang tool.");
|
|
}
|
|
|
|
const InputInfo &Input = Inputs[0];
|
|
types::ID InputType = Input.getType();
|
|
|
|
// Add preprocessing options like -I, -D, etc. if we are using the
|
|
// preprocessor (i.e. skip when dealing with e.g. binary files).
|
|
if (types::getPreprocessedType(InputType) != types::TY_INVALID)
|
|
AddPreprocessingOptions(Args, CmdArgs);
|
|
|
|
AddFortranDialectOptions(Args, CmdArgs);
|
|
|
|
// Add other compile options
|
|
AddOtherOptions(Args, CmdArgs);
|
|
|
|
// Forward -Xflang arguments to -fc1
|
|
Args.AddAllArgValues(CmdArgs, options::OPT_Xflang);
|
|
|
|
if (Output.isFilename()) {
|
|
CmdArgs.push_back("-o");
|
|
CmdArgs.push_back(Output.getFilename());
|
|
} else {
|
|
assert(Output.isNothing() && "Invalid output.");
|
|
}
|
|
|
|
assert(Input.isFilename() && "Invalid input.");
|
|
CmdArgs.push_back(Input.getFilename());
|
|
|
|
const auto& D = C.getDriver();
|
|
// TODO: Replace flang-new with flang once the new driver replaces the
|
|
// throwaway driver
|
|
const char *Exec = Args.MakeArgString(D.GetProgramPath("flang-new", TC));
|
|
C.addCommand(std::make_unique<Command>(JA, *this,
|
|
ResponseFileSupport::AtFileUTF8(),
|
|
Exec, CmdArgs, Inputs, Output));
|
|
}
|
|
|
|
Flang::Flang(const ToolChain &TC) : Tool("flang-new", "flang frontend", TC) {}
|
|
|
|
Flang::~Flang() {}
|