Skip to content

Commit 3a1513c

Browse files
author
Faris Rehman
committed
[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 6a75496, 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
1 parent fa2cdb8 commit 3a1513c

File tree

12 files changed

+195
-9
lines changed

12 files changed

+195
-9
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4129,7 +4129,6 @@ def fblas_matmul_limit_EQ : Joined<["-"], "fblas-matmul-limit=">, Group<gfortran
41294129
def fcheck_EQ : Joined<["-"], "fcheck=">, Group<gfortran_Group>;
41304130
def fcoarray_EQ : Joined<["-"], "fcoarray=">, Group<gfortran_Group>;
41314131
def fconvert_EQ : Joined<["-"], "fconvert=">, Group<gfortran_Group>;
4132-
def ffixed_line_length_VALUE : Joined<["-"], "ffixed-line-length-">, Group<gfortran_Group>;
41334132
def ffpe_trap_EQ : Joined<["-"], "ffpe-trap=">, Group<gfortran_Group>;
41344133
def ffree_line_length_VALUE : Joined<["-"], "ffree-line-length-">, Group<gfortran_Group>;
41354134
def finit_character_EQ : Joined<["-"], "finit-character=">, Group<gfortran_Group>;
@@ -4163,8 +4162,6 @@ defm dump_fortran_original : BooleanFFlag<"dump-fortran-original">, Group<gfortr
41634162
defm dump_parse_tree : BooleanFFlag<"dump-parse-tree">, Group<gfortran_Group>;
41644163
defm external_blas : BooleanFFlag<"external-blas">, Group<gfortran_Group>;
41654164
defm f2c : BooleanFFlag<"f2c">, Group<gfortran_Group>;
4166-
defm fixed_form : BooleanFFlag<"fixed-form">, Group<gfortran_Group>;
4167-
defm free_form : BooleanFFlag<"free-form">, Group<gfortran_Group>;
41684165
defm frontend_optimize : BooleanFFlag<"frontend-optimize">, Group<gfortran_Group>;
41694166
defm implicit_none : BooleanFFlag<"implicit-none">, Group<gfortran_Group>;
41704167
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
42074204
def test_io : Flag<["-"], "test-io">, Flags<[HelpHidden, FlangOption, FC1Option, FlangOnlyOption]>, Group<Action_Group>,
42084205
HelpText<"Run the InputOuputTest action. Use for development and testing only.">;
42094206

4207+
let Flags = [FC1Option, FlangOption, FlangOnlyOption] in {
4208+
4209+
def ffixed_form : Flag<["-"], "ffixed-form">, Group<f_Group>,
4210+
HelpText<"Process source files in fixed form">;
4211+
def ffree_form : Flag<["-"], "ffree-form">, Group<f_Group>,
4212+
HelpText<"Process source files in free form">;
4213+
def ffixed_line_length_EQ : Joined<["-"], "ffixed-line-length=">, Group<f_Group>,
4214+
HelpText<"Use <value> as character line width in fixed mode">,
4215+
DocBrief<[{Set column after which characters are ignored in typical fixed-form lines in the source
4216+
file}]>;
4217+
def ffixed_line_length_VALUE : Joined<["-"], "ffixed-line-length-">, Group<f_Group>, Alias<ffixed_line_length_EQ>;
4218+
4219+
}
4220+
42104221
//===----------------------------------------------------------------------===//
42114222
// CC1 Options
42124223
//===----------------------------------------------------------------------===//

clang/lib/Driver/ToolChains/Flang.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ using namespace clang::driver::tools;
1919
using namespace clang;
2020
using namespace llvm::opt;
2121

22+
void Flang::AddFortranDialectOptions(const ArgList &Args,
23+
ArgStringList &CmdArgs) const {
24+
Args.AddAllArgs(CmdArgs, {options::OPT_ffixed_form, options::OPT_ffree_form,
25+
options::OPT_ffixed_line_length_EQ});
26+
}
27+
2228
void Flang::AddPreprocessingOptions(const ArgList &Args,
2329
ArgStringList &CmdArgs) const {
2430
Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I});
@@ -79,6 +85,8 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
7985
if (types::getPreprocessedType(InputType) != types::TY_INVALID)
8086
AddPreprocessingOptions(Args, CmdArgs);
8187

88+
AddFortranDialectOptions(Args, CmdArgs);
89+
8290
if (Output.isFilename()) {
8391
CmdArgs.push_back("-o");
8492
CmdArgs.push_back(Output.getFilename());

clang/lib/Driver/ToolChains/Flang.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ namespace tools {
2424
/// Flang compiler tool.
2525
class LLVM_LIBRARY_VISIBILITY Flang : public Tool {
2626
private:
27+
/// Extract fortran dialect options from the driver arguments and add them to
28+
/// the list of arguments for the generated command/job.
29+
///
30+
/// \param [in] Args The list of input driver arguments
31+
/// \param [out] CmdArgs The list of output command arguments
32+
void AddFortranDialectOptions(const llvm::opt::ArgList &Args,
33+
llvm::opt::ArgStringList &CmdArgs) const;
34+
2735
/// Extract preprocessing options from the driver arguments and add them to
2836
/// the preprocessor command arguments.
2937
///

flang/include/flang/Frontend/FrontendOptions.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,18 @@ enum class Language : uint8_t {
7474
Fortran,
7575
};
7676

77+
// Source file layout
78+
enum class FortranForm {
79+
/// The user has not specified a form. Base the form off the file extension.
80+
Unknown,
81+
82+
/// -ffree-form
83+
FixedForm,
84+
85+
/// -ffixed-form
86+
FreeForm
87+
};
88+
7789
/// The kind of a file that we've been handed as an input.
7890
class InputKind {
7991
private:
@@ -159,6 +171,13 @@ class FrontendOptions {
159171
/// The frontend action to perform.
160172
frontend::ActionKind programAction_;
161173

174+
// The form to process files in, if specified.
175+
FortranForm fortranForm_ = FortranForm::Unknown;
176+
177+
// The column after which characters are ignored in fixed form lines in the
178+
// source file.
179+
int fixedFormColumns_ = 72;
180+
162181
public:
163182
FrontendOptions() : showHelp_(false), showVersion_(false) {}
164183

flang/lib/Frontend/CompilerInstance.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,14 @@ bool CompilerInstance::ExecuteAction(FrontendAction &act) {
148148
// Run the frontend action `act` for every input file.
149149
for (const FrontendInputFile &fif : frontendOpts().inputs_) {
150150
if (act.BeginSourceFile(*this, fif)) {
151-
// Switch between fixed and free form format based on the input file
152-
// extension. Ideally we should have all Fortran options set before
153-
// entering this loop (i.e. processing any input files). However, we
154-
// can't decide between fixed and free form based on the file extension
155-
// earlier than this.
156-
invoc.fortranOpts().isFixedForm = fif.IsFixedForm();
151+
if (invoc.frontendOpts().fortranForm_ == FortranForm::Unknown) {
152+
// Switch between fixed and free form format based on the input file
153+
// extension. Ideally we should have all Fortran options set before
154+
// entering this loop (i.e. processing any input files). However, we
155+
// can't decide between fixed and free form based on the file extension
156+
// earlier than this.
157+
invoc.fortranOpts().isFixedForm = fif.IsFixedForm();
158+
}
157159
if (llvm::Error err = act.Execute()) {
158160
consumeError(std::move(err));
159161
}

flang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,40 @@ static InputKind ParseFrontendArgs(FrontendOptions &opts,
162162

163163
opts.inputs_.emplace_back(std::move(inputs[i]), ik);
164164
}
165+
166+
// Set fortranForm_ based on options -ffree-form and -ffixed-form.
167+
if (const auto *arg = args.getLastArg(clang::driver::options::OPT_ffixed_form,
168+
clang::driver::options::OPT_ffree_form)) {
169+
opts.fortranForm_ =
170+
arg->getOption().matches(clang::driver::options::OPT_ffixed_form)
171+
? FortranForm::FixedForm
172+
: FortranForm::FreeForm;
173+
}
174+
175+
// Set fixedFormColumns_ based on -ffixed-line-length=<value>
176+
if (const auto *arg =
177+
args.getLastArg(clang::driver::options::OPT_ffixed_line_length_EQ)) {
178+
llvm::StringRef argValue = llvm::StringRef(arg->getValue());
179+
std::int64_t columns = -1;
180+
if (argValue == "none") {
181+
columns = 0;
182+
} else if (argValue.getAsInteger(/*Radix=*/10, columns)) {
183+
columns = -1;
184+
}
185+
if (columns < 0) {
186+
diags.Report(clang::diag::err_drv_invalid_value_with_suggestion)
187+
<< arg->getOption().getName() << arg->getValue()
188+
<< "value must be 'none' or a non-negative integer";
189+
} else if (columns == 0) {
190+
opts.fixedFormColumns_ = 1000000;
191+
} else if (columns < 7) {
192+
diags.Report(clang::diag::err_drv_invalid_value_with_suggestion)
193+
<< arg->getOption().getName() << arg->getValue()
194+
<< "value must be at least seven";
195+
} else {
196+
opts.fixedFormColumns_ = columns;
197+
}
198+
}
165199
return dashX;
166200
}
167201

@@ -278,8 +312,15 @@ void CompilerInvocation::SetDefaultFortranOpts() {
278312

279313
void CompilerInvocation::setFortranOpts() {
280314
auto &fortranOptions = fortranOpts();
315+
const auto &frontendOptions = frontendOpts();
281316
const auto &preprocessorOptions = preprocessorOpts();
282317

318+
if (frontendOptions.fortranForm_ != FortranForm::Unknown) {
319+
fortranOptions.isFixedForm =
320+
frontendOptions.fortranForm_ == FortranForm::FixedForm;
321+
}
322+
fortranOptions.fixedFormColumns = frontendOptions.fixedFormColumns_;
323+
283324
collectMacroDefinitions(preprocessorOptions, fortranOptions);
284325

285326
fortranOptions.searchDirectories.insert(
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
program FixedForm
2+
c end
23
end
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
! The length of the line below is exactly 73 characters
2+
program aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
3+
end

flang/test/Flang-Driver/driver-help-hidden.f90

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
! CHECK-NEXT: -D <macro>=<value> Define <macro> to <value> (or 1 if <value> omitted)
2424
! CHECK-NEXT: -E Only run the preprocessor
2525
! CHECK-NEXT: -fcolor-diagnostics Enable colors in diagnostics
26+
! CHECK-NEXT: -ffixed-form Process source files in fixed form
27+
! CHECK-NEXT: -ffixed-line-length=<value>
28+
! CHECK-NEXT: Use <value> as character line width in fixed mode
29+
! CHECK-NEXT: -ffree-form Process source files in free form
2630
! CHECK-NEXT: -fno-color-diagnostics Disable colors in diagnostics
2731
! CHECK-NEXT: -help Display available options
2832
! CHECK-NEXT: -I <dir> Add directory to the end of the list of include search paths

flang/test/Flang-Driver/driver-help.f90

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
! HELP-NEXT: -D <macro>=<value> Define <macro> to <value> (or 1 if <value> omitted)
2424
! HELP-NEXT: -E Only run the preprocessor
2525
! HELP-NEXT: -fcolor-diagnostics Enable colors in diagnostics
26+
! HELP-NEXT: -ffixed-form Process source files in fixed form
27+
! HELP-NEXT: -ffixed-line-length=<value>
28+
! HELP-NEXT: Use <value> as character line width in fixed mode
29+
! HELP-NEXT: -ffree-form Process source files in free form
2630
! HELP-NEXT: -fno-color-diagnostics Disable colors in diagnostics
2731
! HELP-NEXT: -help Display available options
2832
! HELP-NEXT: -I <dir> Add directory to the end of the list of include search paths
@@ -39,6 +43,10 @@
3943
! HELP-FC1-NEXT: -D <macro>=<value> Define <macro> to <value> (or 1 if <value> omitted)
4044
! HELP-FC1-NEXT: -emit-obj Emit native object files
4145
! HELP-FC1-NEXT: -E Only run the preprocessor
46+
! HELP-FC1-NEXT: -ffixed-form Process source files in fixed form
47+
! HELP-FC1-NEXT: -ffixed-line-length=<value>
48+
! HELP-FC1-NEXT: Use <value> as character line width in fixed mode
49+
! HELP-FC1-NEXT: -ffree-form Process source files in free form
4250
! HELP-FC1-NEXT: -help Display available options
4351
! HELP-FC1-NEXT: -I <dir> Add directory to the end of the list of include search paths
4452
! HELP-FC1-NEXT: -o <file> Write output to <file>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
! Ensure arguments -ffree-form and -ffixed-form work as expected.
2+
3+
! REQUIRES: new-flang-driver
4+
5+
!--------------------------
6+
! FLANG DRIVER (flang-new)
7+
!--------------------------
8+
! RUN: not %flang-new -fsyntax-only -ffree-form %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=FREEFORM
9+
! RUN: %flang-new -fsyntax-only -ffixed-form %S/Inputs/free-form-test.f90 2>&1 | FileCheck %s --check-prefix=FIXEDFORM
10+
11+
!----------------------------------------
12+
! FRONTEND FLANG DRIVER (flang-new -fc1)
13+
!----------------------------------------
14+
! RUN: not %flang-new -fc1 -fsyntax-only -ffree-form %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=FREEFORM
15+
! RUN: %flang-new -fc1 -fsyntax-only -ffixed-form %S/Inputs/free-form-test.f90 2>&1 | FileCheck %s --check-prefix=FIXEDFORM
16+
17+
!------------------------------------
18+
! EXPECTED OUTPUT FOR FREE FORM MODE
19+
!------------------------------------
20+
! FREEFORM:error: Could not parse
21+
22+
!-------------------------------------
23+
! EXPECTED OUTPUT FOR FIXED FORM MODE
24+
!-------------------------------------
25+
! FIXEDFORM:free-form-test.f90:1:1: Character in fixed-form label field must be a digit
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
! Ensure argument -ffixed-line-length=n works as expected.
2+
3+
! REQUIRES: new-flang-driver
4+
5+
!--------------------------
6+
! FLANG DRIVER (flang-new)
7+
!--------------------------
8+
! RUN: %flang-new -E %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=DEFAULTLENGTH
9+
! RUN: not %flang-new -E -ffixed-line-length=-2 %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=NEGATIVELENGTH
10+
! RUN: not %flang-new -E -ffixed-line-length=3 %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=INVALIDLENGTH
11+
! RUN: %flang-new -E -ffixed-line-length=none %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=UNLIMITEDLENGTH
12+
! RUN: %flang-new -E -ffixed-line-length=0 %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=UNLIMITEDLENGTH
13+
! RUN: %flang-new -E -ffixed-line-length=13 %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=LENGTH13
14+
15+
!----------------------------------------
16+
! FRONTEND FLANG DRIVER (flang-new -fc1)
17+
!----------------------------------------
18+
! RUN: %flang-new -fc1 -E %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=DEFAULTLENGTH
19+
! RUN: not %flang-new -fc1 -E -ffixed-line-length=-2 %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=NEGATIVELENGTH
20+
! RUN: not %flang-new -fc1 -E -ffixed-line-length=3 %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=INVALIDLENGTH
21+
! RUN: %flang-new -fc1 -E -ffixed-line-length=none %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=UNLIMITEDLENGTH
22+
! RUN: %flang-new -fc1 -E -ffixed-line-length=0 %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=UNLIMITEDLENGTH
23+
! RUN: %flang-new -fc1 -E -ffixed-line-length=13 %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=LENGTH13
24+
25+
!-------------------------------------
26+
! COMMAND ALIAS -ffixed-line-length-n
27+
!-------------------------------------
28+
! RUN: %flang-new -E -ffixed-line-length-13 %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=LENGTH13
29+
! RUN: %flang-new -fc1 -E -ffixed-line-length-13 %S/Inputs/fixed-line-length-test.f 2>&1 | FileCheck %s --check-prefix=LENGTH13
30+
31+
!-------------------------------------
32+
! EXPECTED OUTPUT WITH DEFAULT LENGTH
33+
!-------------------------------------
34+
! The line should be trimmed to 72 characters when reading based on the default value of fixed line length.
35+
! DEFAULTLENGTH: program{{(a{58})}}
36+
37+
!-----------------------------------------
38+
! EXPECTED OUTPUT WITH A NEGATIVE LENGTH
39+
!-----------------------------------------
40+
! NEGATIVELENGTH: invalid value '-2' in 'ffixed-line-length=','value must be 'none' or a non-negative integer'
41+
42+
!-----------------------------------------
43+
! EXPECTED OUTPUT WITH LENGTH LESS THAN 7
44+
!-----------------------------------------
45+
! INVALIDLENGTH: invalid value '3' in 'ffixed-line-length=','value must be at least seven'
46+
47+
!---------------------------------------
48+
! EXPECTED OUTPUT WITH UNLIMITED LENGTH
49+
!---------------------------------------
50+
! The line should not be trimmed and so 73 characters (including spaces) should be read.
51+
! UNLIMITEDLENGTH: program{{(a{59})}}
52+
53+
!--------------------------------
54+
! EXPECTED OUTPUT WITH LENGTH 13
55+
!--------------------------------
56+
! LENGTH13: program

0 commit comments

Comments
 (0)