forked from OSchip/llvm-project
[flang][driver] Add forced form flags and -ffixed-line-length
Add support for the following layout options:
* -ffree-form
* -ffixed-form
- -ffixed-line-length=n (alias -ffixed-line-length-n)
Additionally remove options `-fno-free-form` and `-fno-fixed-form` as they were initially added to forward to gfortran but gfortran does not support these flags.
This patch adds the flag FlangOnlyOption to the existing options `-ffixed-form`, `-ffree-form` and `-ffree-line-length-` in Options.td. As of commit 6a75496836
, these flags are not currently forwarded to gfortran anyway.
The default fixed line length in FrontendOptions is 72, based off the current default in Fortran::parser::Options. The line length cannot be set to a negative integer, or a positive integer less than 7 excluding 0, consistent with the behaviour of gfortran.
This patch does not add `-ffree-line-length-n` as Fortran::parser::Options does not have a variable for free form columns.
Whilst the `fixedFormColumns` variable is used in f18 for `-ffree-line-length-n`, f18 only allows `-ffree-line-length-none`/`-ffree-line-length-0` and not a user-specified value. `fixedFormcolumns` cannot be used in the new driver as it is ignored in the frontend when dealing with free form files.
Summary of changes:
- Remove -fno-fixed-form and -fno-free-form from Options.td
- Make -ffixed-form, -ffree-form and -ffree-line-length-n FlangOnlyOption in Options.td
- Create AddFortranDialectOptions method in Flang.cpp
- Create FortranForm enum in FrontendOptions.h
- Add fortranForm_ and fixedFormColumns_ to Fortran::frontend::FrontendOptions
- Update fixed-form-test.f so that it guarantees that it fails when forced as a free form file to better facilitate testing.
Differential Revision: https://reviews.llvm.org/D95460
This commit is contained in:
parent
fa2cdb8140
commit
3a1513c142
|
@ -4129,7 +4129,6 @@ def fblas_matmul_limit_EQ : Joined<["-"], "fblas-matmul-limit=">, Group<gfortran
|
|||
def fcheck_EQ : Joined<["-"], "fcheck=">, Group<gfortran_Group>;
|
||||
def fcoarray_EQ : Joined<["-"], "fcoarray=">, Group<gfortran_Group>;
|
||||
def fconvert_EQ : Joined<["-"], "fconvert=">, Group<gfortran_Group>;
|
||||
def ffixed_line_length_VALUE : Joined<["-"], "ffixed-line-length-">, Group<gfortran_Group>;
|
||||
def ffpe_trap_EQ : Joined<["-"], "ffpe-trap=">, Group<gfortran_Group>;
|
||||
def ffree_line_length_VALUE : Joined<["-"], "ffree-line-length-">, Group<gfortran_Group>;
|
||||
def finit_character_EQ : Joined<["-"], "finit-character=">, Group<gfortran_Group>;
|
||||
|
@ -4163,8 +4162,6 @@ defm dump_fortran_original : BooleanFFlag<"dump-fortran-original">, Group<gfortr
|
|||
defm dump_parse_tree : BooleanFFlag<"dump-parse-tree">, Group<gfortran_Group>;
|
||||
defm external_blas : BooleanFFlag<"external-blas">, Group<gfortran_Group>;
|
||||
defm f2c : BooleanFFlag<"f2c">, Group<gfortran_Group>;
|
||||
defm fixed_form : BooleanFFlag<"fixed-form">, Group<gfortran_Group>;
|
||||
defm free_form : BooleanFFlag<"free-form">, Group<gfortran_Group>;
|
||||
defm frontend_optimize : BooleanFFlag<"frontend-optimize">, Group<gfortran_Group>;
|
||||
defm implicit_none : BooleanFFlag<"implicit-none">, Group<gfortran_Group>;
|
||||
defm init_local_zero : BooleanFFlag<"init-local-zero">, Group<gfortran_Group>;
|
||||
|
@ -4207,6 +4204,20 @@ def sycl_std_EQ : Joined<["-"], "sycl-std=">, Group<sycl_Group>, Flags<[CC1Optio
|
|||
def test_io : Flag<["-"], "test-io">, Flags<[HelpHidden, FlangOption, FC1Option, FlangOnlyOption]>, Group<Action_Group>,
|
||||
HelpText<"Run the InputOuputTest action. Use for development and testing only.">;
|
||||
|
||||
let Flags = [FC1Option, FlangOption, FlangOnlyOption] in {
|
||||
|
||||
def ffixed_form : Flag<["-"], "ffixed-form">, Group<f_Group>,
|
||||
HelpText<"Process source files in fixed form">;
|
||||
def ffree_form : Flag<["-"], "ffree-form">, Group<f_Group>,
|
||||
HelpText<"Process source files in free form">;
|
||||
def ffixed_line_length_EQ : Joined<["-"], "ffixed-line-length=">, Group<f_Group>,
|
||||
HelpText<"Use <value> as character line width in fixed mode">,
|
||||
DocBrief<[{Set column after which characters are ignored in typical fixed-form lines in the source
|
||||
file}]>;
|
||||
def ffixed_line_length_VALUE : Joined<["-"], "ffixed-line-length-">, Group<f_Group>, Alias<ffixed_line_length_EQ>;
|
||||
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// CC1 Options
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -19,6 +19,12 @@ 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});
|
||||
}
|
||||
|
||||
void Flang::AddPreprocessingOptions(const ArgList &Args,
|
||||
ArgStringList &CmdArgs) const {
|
||||
Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I});
|
||||
|
@ -79,6 +85,8 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
if (types::getPreprocessedType(InputType) != types::TY_INVALID)
|
||||
AddPreprocessingOptions(Args, CmdArgs);
|
||||
|
||||
AddFortranDialectOptions(Args, CmdArgs);
|
||||
|
||||
if (Output.isFilename()) {
|
||||
CmdArgs.push_back("-o");
|
||||
CmdArgs.push_back(Output.getFilename());
|
||||
|
|
|
@ -24,6 +24,14 @@ namespace tools {
|
|||
/// Flang compiler tool.
|
||||
class LLVM_LIBRARY_VISIBILITY Flang : public Tool {
|
||||
private:
|
||||
/// Extract fortran dialect options from the driver arguments and add them to
|
||||
/// the list of arguments for the generated command/job.
|
||||
///
|
||||
/// \param [in] Args The list of input driver arguments
|
||||
/// \param [out] CmdArgs The list of output command arguments
|
||||
void AddFortranDialectOptions(const llvm::opt::ArgList &Args,
|
||||
llvm::opt::ArgStringList &CmdArgs) const;
|
||||
|
||||
/// Extract preprocessing options from the driver arguments and add them to
|
||||
/// the preprocessor command arguments.
|
||||
///
|
||||
|
|
|
@ -74,6 +74,18 @@ enum class Language : uint8_t {
|
|||
Fortran,
|
||||
};
|
||||
|
||||
// Source file layout
|
||||
enum class FortranForm {
|
||||
/// The user has not specified a form. Base the form off the file extension.
|
||||
Unknown,
|
||||
|
||||
/// -ffree-form
|
||||
FixedForm,
|
||||
|
||||
/// -ffixed-form
|
||||
FreeForm
|
||||
};
|
||||
|
||||
/// The kind of a file that we've been handed as an input.
|
||||
class InputKind {
|
||||
private:
|
||||
|
@ -159,6 +171,13 @@ public:
|
|||
/// The frontend action to perform.
|
||||
frontend::ActionKind programAction_;
|
||||
|
||||
// The form to process files in, if specified.
|
||||
FortranForm fortranForm_ = FortranForm::Unknown;
|
||||
|
||||
// The column after which characters are ignored in fixed form lines in the
|
||||
// source file.
|
||||
int fixedFormColumns_ = 72;
|
||||
|
||||
public:
|
||||
FrontendOptions() : showHelp_(false), showVersion_(false) {}
|
||||
|
||||
|
|
|
@ -148,12 +148,14 @@ bool CompilerInstance::ExecuteAction(FrontendAction &act) {
|
|||
// Run the frontend action `act` for every input file.
|
||||
for (const FrontendInputFile &fif : frontendOpts().inputs_) {
|
||||
if (act.BeginSourceFile(*this, fif)) {
|
||||
// Switch between fixed and free form format based on the input file
|
||||
// extension. Ideally we should have all Fortran options set before
|
||||
// entering this loop (i.e. processing any input files). However, we
|
||||
// can't decide between fixed and free form based on the file extension
|
||||
// earlier than this.
|
||||
invoc.fortranOpts().isFixedForm = fif.IsFixedForm();
|
||||
if (invoc.frontendOpts().fortranForm_ == FortranForm::Unknown) {
|
||||
// Switch between fixed and free form format based on the input file
|
||||
// extension. Ideally we should have all Fortran options set before
|
||||
// entering this loop (i.e. processing any input files). However, we
|
||||
// can't decide between fixed and free form based on the file extension
|
||||
// earlier than this.
|
||||
invoc.fortranOpts().isFixedForm = fif.IsFixedForm();
|
||||
}
|
||||
if (llvm::Error err = act.Execute()) {
|
||||
consumeError(std::move(err));
|
||||
}
|
||||
|
|
|
@ -162,6 +162,40 @@ static InputKind ParseFrontendArgs(FrontendOptions &opts,
|
|||
|
||||
opts.inputs_.emplace_back(std::move(inputs[i]), ik);
|
||||
}
|
||||
|
||||
// Set fortranForm_ based on options -ffree-form and -ffixed-form.
|
||||
if (const auto *arg = args.getLastArg(clang::driver::options::OPT_ffixed_form,
|
||||
clang::driver::options::OPT_ffree_form)) {
|
||||
opts.fortranForm_ =
|
||||
arg->getOption().matches(clang::driver::options::OPT_ffixed_form)
|
||||
? FortranForm::FixedForm
|
||||
: FortranForm::FreeForm;
|
||||
}
|
||||
|
||||
// Set fixedFormColumns_ based on -ffixed-line-length=<value>
|
||||
if (const auto *arg =
|
||||
args.getLastArg(clang::driver::options::OPT_ffixed_line_length_EQ)) {
|
||||
llvm::StringRef argValue = llvm::StringRef(arg->getValue());
|
||||
std::int64_t columns = -1;
|
||||
if (argValue == "none") {
|
||||
columns = 0;
|
||||
} else if (argValue.getAsInteger(/*Radix=*/10, columns)) {
|
||||
columns = -1;
|
||||
}
|
||||
if (columns < 0) {
|
||||
diags.Report(clang::diag::err_drv_invalid_value_with_suggestion)
|
||||
<< arg->getOption().getName() << arg->getValue()
|
||||
<< "value must be 'none' or a non-negative integer";
|
||||
} else if (columns == 0) {
|
||||
opts.fixedFormColumns_ = 1000000;
|
||||
} else if (columns < 7) {
|
||||
diags.Report(clang::diag::err_drv_invalid_value_with_suggestion)
|
||||
<< arg->getOption().getName() << arg->getValue()
|
||||
<< "value must be at least seven";
|
||||
} else {
|
||||
opts.fixedFormColumns_ = columns;
|
||||
}
|
||||
}
|
||||
return dashX;
|
||||
}
|
||||
|
||||
|
@ -278,8 +312,15 @@ void CompilerInvocation::SetDefaultFortranOpts() {
|
|||
|
||||
void CompilerInvocation::setFortranOpts() {
|
||||
auto &fortranOptions = fortranOpts();
|
||||
const auto &frontendOptions = frontendOpts();
|
||||
const auto &preprocessorOptions = preprocessorOpts();
|
||||
|
||||
if (frontendOptions.fortranForm_ != FortranForm::Unknown) {
|
||||
fortranOptions.isFixedForm =
|
||||
frontendOptions.fortranForm_ == FortranForm::FixedForm;
|
||||
}
|
||||
fortranOptions.fixedFormColumns = frontendOptions.fixedFormColumns_;
|
||||
|
||||
collectMacroDefinitions(preprocessorOptions, fortranOptions);
|
||||
|
||||
fortranOptions.searchDirectories.insert(
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
program FixedForm
|
||||
c end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
! The length of the line below is exactly 73 characters
|
||||
program aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
end
|
|
@ -23,6 +23,10 @@
|
|||
! CHECK-NEXT: -D <macro>=<value> Define <macro> to <value> (or 1 if <value> omitted)
|
||||
! CHECK-NEXT: -E Only run the preprocessor
|
||||
! CHECK-NEXT: -fcolor-diagnostics Enable colors in diagnostics
|
||||
! CHECK-NEXT: -ffixed-form Process source files in fixed form
|
||||
! CHECK-NEXT: -ffixed-line-length=<value>
|
||||
! CHECK-NEXT: Use <value> as character line width in fixed mode
|
||||
! CHECK-NEXT: -ffree-form Process source files in free form
|
||||
! CHECK-NEXT: -fno-color-diagnostics Disable colors in diagnostics
|
||||
! CHECK-NEXT: -help Display available options
|
||||
! CHECK-NEXT: -I <dir> Add directory to the end of the list of include search paths
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
! HELP-NEXT: -D <macro>=<value> Define <macro> to <value> (or 1 if <value> omitted)
|
||||
! HELP-NEXT: -E Only run the preprocessor
|
||||
! HELP-NEXT: -fcolor-diagnostics Enable colors in diagnostics
|
||||
! HELP-NEXT: -ffixed-form Process source files in fixed form
|
||||
! HELP-NEXT: -ffixed-line-length=<value>
|
||||
! HELP-NEXT: Use <value> as character line width in fixed mode
|
||||
! HELP-NEXT: -ffree-form Process source files in free form
|
||||
! HELP-NEXT: -fno-color-diagnostics Disable colors in diagnostics
|
||||
! HELP-NEXT: -help Display available options
|
||||
! HELP-NEXT: -I <dir> Add directory to the end of the list of include search paths
|
||||
|
@ -39,6 +43,10 @@
|
|||
! HELP-FC1-NEXT: -D <macro>=<value> Define <macro> to <value> (or 1 if <value> omitted)
|
||||
! HELP-FC1-NEXT: -emit-obj Emit native object files
|
||||
! HELP-FC1-NEXT: -E Only run the preprocessor
|
||||
! HELP-FC1-NEXT: -ffixed-form Process source files in fixed form
|
||||
! HELP-FC1-NEXT: -ffixed-line-length=<value>
|
||||
! HELP-FC1-NEXT: Use <value> as character line width in fixed mode
|
||||
! HELP-FC1-NEXT: -ffree-form Process source files in free form
|
||||
! HELP-FC1-NEXT: -help Display available options
|
||||
! HELP-FC1-NEXT: -I <dir> Add directory to the end of the list of include search paths
|
||||
! HELP-FC1-NEXT: -o <file> Write output to <file>
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
! Ensure arguments -ffree-form and -ffixed-form work as expected.
|
||||
|
||||
! REQUIRES: new-flang-driver
|
||||
|
||||
!--------------------------
|
||||
! FLANG DRIVER (flang-new)
|
||||
!--------------------------
|
||||
! RUN: not %flang-new -fsyntax-only -ffree-form %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=FREEFORM
|
||||
! RUN: %flang-new -fsyntax-only -ffixed-form %S/Inputs/free-form-test.f90 2>&1 | FileCheck %s --check-prefix=FIXEDFORM
|
||||
|
||||
!----------------------------------------
|
||||
! FRONTEND FLANG DRIVER (flang-new -fc1)
|
||||
!----------------------------------------
|
||||
! RUN: not %flang-new -fc1 -fsyntax-only -ffree-form %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=FREEFORM
|
||||
! RUN: %flang-new -fc1 -fsyntax-only -ffixed-form %S/Inputs/free-form-test.f90 2>&1 | FileCheck %s --check-prefix=FIXEDFORM
|
||||
|
||||
!------------------------------------
|
||||
! EXPECTED OUTPUT FOR FREE FORM MODE
|
||||
!------------------------------------
|
||||
! FREEFORM:error: Could not parse
|
||||
|
||||
!-------------------------------------
|
||||
! EXPECTED OUTPUT FOR FIXED FORM MODE
|
||||
!-------------------------------------
|
||||
! FIXEDFORM:free-form-test.f90:1:1: Character in fixed-form label field must be a digit
|
|
@ -0,0 +1,56 @@
|
|||
! Ensure argument -ffixed-line-length=n works as expected.
|
||||
|
||||
! REQUIRES: new-flang-driver
|
||||
|
||||
!--------------------------
|
||||
! FLANG DRIVER (flang-new)
|
||||
!--------------------------
|
||||
! RUN: %flang-new -E %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=DEFAULTLENGTH
|
||||
! RUN: not %flang-new -E -ffixed-line-length=-2 %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=NEGATIVELENGTH
|
||||
! RUN: not %flang-new -E -ffixed-line-length=3 %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=INVALIDLENGTH
|
||||
! RUN: %flang-new -E -ffixed-line-length=none %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=UNLIMITEDLENGTH
|
||||
! RUN: %flang-new -E -ffixed-line-length=0 %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=UNLIMITEDLENGTH
|
||||
! RUN: %flang-new -E -ffixed-line-length=13 %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=LENGTH13
|
||||
|
||||
!----------------------------------------
|
||||
! FRONTEND FLANG DRIVER (flang-new -fc1)
|
||||
!----------------------------------------
|
||||
! RUN: %flang-new -fc1 -E %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=DEFAULTLENGTH
|
||||
! RUN: not %flang-new -fc1 -E -ffixed-line-length=-2 %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=NEGATIVELENGTH
|
||||
! RUN: not %flang-new -fc1 -E -ffixed-line-length=3 %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=INVALIDLENGTH
|
||||
! RUN: %flang-new -fc1 -E -ffixed-line-length=none %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=UNLIMITEDLENGTH
|
||||
! RUN: %flang-new -fc1 -E -ffixed-line-length=0 %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=UNLIMITEDLENGTH
|
||||
! RUN: %flang-new -fc1 -E -ffixed-line-length=13 %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=LENGTH13
|
||||
|
||||
!-------------------------------------
|
||||
! COMMAND ALIAS -ffixed-line-length-n
|
||||
!-------------------------------------
|
||||
! RUN: %flang-new -E -ffixed-line-length-13 %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=LENGTH13
|
||||
! RUN: %flang-new -fc1 -E -ffixed-line-length-13 %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=LENGTH13
|
||||
|
||||
!-------------------------------------
|
||||
! EXPECTED OUTPUT WITH DEFAULT LENGTH
|
||||
!-------------------------------------
|
||||
! The line should be trimmed to 72 characters when reading based on the default value of fixed line length.
|
||||
! DEFAULTLENGTH: program{{(a{58})}}
|
||||
|
||||
!-----------------------------------------
|
||||
! EXPECTED OUTPUT WITH A NEGATIVE LENGTH
|
||||
!-----------------------------------------
|
||||
! NEGATIVELENGTH: invalid value '-2' in 'ffixed-line-length=','value must be 'none' or a non-negative integer'
|
||||
|
||||
!-----------------------------------------
|
||||
! EXPECTED OUTPUT WITH LENGTH LESS THAN 7
|
||||
!-----------------------------------------
|
||||
! INVALIDLENGTH: invalid value '3' in 'ffixed-line-length=','value must be at least seven'
|
||||
|
||||
!---------------------------------------
|
||||
! EXPECTED OUTPUT WITH UNLIMITED LENGTH
|
||||
!---------------------------------------
|
||||
! The line should not be trimmed and so 73 characters (including spaces) should be read.
|
||||
! UNLIMITEDLENGTH: program{{(a{59})}}
|
||||
|
||||
!--------------------------------
|
||||
! EXPECTED OUTPUT WITH LENGTH 13
|
||||
!--------------------------------
|
||||
! LENGTH13: program
|
Loading…
Reference in New Issue