[flang-commits] [clang] [flang] [Flang] Adding -ffree-line-length-<value> flag (PR #192941)
via flang-commits
flang-commits at lists.llvm.org
Mon Apr 20 04:18:28 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-parser
Author: Jean-Didier PAILLEUX (JDPailleux)
<details>
<summary>Changes</summary>
Added support for the `-ffree-line-length-<value>` flag in Flang, which is equivalent to `-ffixed-line-length-<value>` but in free form.
This flag is supported by gfortran and can be used in some applications.
---
Full diff: https://github.com/llvm/llvm-project/pull/192941.diff
10 Files Affected:
- (modified) clang/include/clang/Options/Options.td (+5-1)
- (modified) clang/lib/Driver/ToolChains/Flang.cpp (+1)
- (modified) flang/include/flang/Frontend/FrontendOptions.h (+6-2)
- (modified) flang/include/flang/Parser/options.h (+1)
- (modified) flang/lib/Frontend/CompilerInvocation.cpp (+8-4)
- (modified) flang/lib/Parser/parsing.cpp (+1)
- (modified) flang/lib/Parser/prescan.cpp (+3)
- (modified) flang/lib/Parser/prescan.h (+5)
- (added) flang/test/Driver/Inputs/free-line-length-test.f90 (+4)
- (added) flang/test/Driver/ffree-line-length.f90 (+38)
``````````diff
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 5673fb0c47d5b..da54596ede209 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -7454,7 +7454,6 @@ def static_libgfortran : Flag<["-"], "static-libgfortran">, Group<gfortran_Group
def fblas_matmul_limit_EQ : Joined<["-"], "fblas-matmul-limit=">, Group<gfortran_Group>;
def fcheck_EQ : Joined<["-"], "fcheck=">, 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>;
def finit_integer_EQ : Joined<["-"], "finit-integer=">, Group<gfortran_Group>;
def finit_logical_EQ : Joined<["-"], "finit-logical=">, Group<gfortran_Group>;
@@ -7613,6 +7612,11 @@ def ffixed_line_length_EQ : Joined<["-"], "ffixed-line-length=">, Group<f_Group>
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>;
+def ffree_line_length_EQ : Joined<["-"], "ffree-line-length=">, Group<f_Group>,
+ HelpText<"Use <value> as character line width in free mode">,
+ DocBrief<[{Set column after which characters are ignored in typical free-form lines in the source
+file}]>;
+def ffree_line_length_VALUE : Joined<["-"], "ffree-line-length-">, Group<f_Group>, Alias<ffree_line_length_EQ>;
def fconvert_EQ : Joined<["-"], "fconvert=">, Group<f_Group>,
HelpText<"Set endian conversion of data for unformatted files">;
def fdefault_double_8 : Flag<["-"],"fdefault-double-8">, Group<f_Group>,
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index ce503b74295e4..41ad4288ccc6f 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -40,6 +40,7 @@ void Flang::addFortranDialectOptions(const ArgList &Args,
Args.addAllArgs(CmdArgs, {options::OPT_ffixed_form,
options::OPT_ffree_form,
options::OPT_ffixed_line_length_EQ,
+ options::OPT_ffree_line_length_EQ,
options::OPT_fopenacc,
options::OPT_finput_charset_EQ,
options::OPT_fimplicit_none,
diff --git a/flang/include/flang/Frontend/FrontendOptions.h b/flang/include/flang/Frontend/FrontendOptions.h
index 0bd2e621813ca..25683fc25f4b2 100644
--- a/flang/include/flang/Frontend/FrontendOptions.h
+++ b/flang/include/flang/Frontend/FrontendOptions.h
@@ -145,10 +145,10 @@ enum class FortranForm {
/// The user has not specified a form. Base the form off the file extension.
Unknown,
- /// -ffree-form
+ /// -ffixed-form
FixedForm,
- /// -ffixed-form
+ /// -ffree-form
FreeForm
};
@@ -286,6 +286,10 @@ struct FrontendOptions {
// source file.
int fixedFormColumns = 72;
+ // The column after which characters are ignored in free form lines in the
+ // source file.
+ int freeFormColumns = 1000000;
+
/// The input kind, either specified via -x argument or deduced from the input
/// file name.
InputKind dashX;
diff --git a/flang/include/flang/Parser/options.h b/flang/include/flang/Parser/options.h
index e65f253748d26..6db23dcb6bf07 100644
--- a/flang/include/flang/Parser/options.h
+++ b/flang/include/flang/Parser/options.h
@@ -25,6 +25,7 @@ struct Options {
bool isFixedForm{false};
int fixedFormColumns{72};
+ int freeFormColumns{1000000};
common::LanguageFeatureControl features;
std::vector<std::string> searchDirectories;
std::vector<std::string> intrinsicModuleDirectories;
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index fab1b792180c3..c3eccae8d2939 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -810,7 +810,8 @@ static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
// Set fixedFormColumns based on -ffixed-line-length=<value>
if (const auto *arg =
- args.getLastArg(clang::options::OPT_ffixed_line_length_EQ)) {
+ args.getLastArg(clang::options::OPT_ffixed_line_length_EQ,
+ clang::options::OPT_ffree_line_length_EQ)) {
llvm::StringRef argValue = llvm::StringRef(arg->getValue());
std::int64_t columns = -1;
if (argValue == "none") {
@@ -822,13 +823,15 @@ static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
diags.Report(clang::diag::err_drv_negative_columns)
<< arg->getOption().getName() << arg->getValue();
} else if (columns == 0) {
- opts.fixedFormColumns = 1000000;
+ columns = 1000000;
} else if (columns < 7) {
diags.Report(clang::diag::err_drv_small_columns)
<< arg->getOption().getName() << arg->getValue() << "7";
- } else {
- opts.fixedFormColumns = columns;
}
+ if (arg->getOption().matches(clang::options::OPT_ffixed_line_length_EQ))
+ opts.fixedFormColumns = columns;
+ else
+ opts.freeFormColumns = columns;
}
// Set conversion based on -fconvert=<value>
@@ -1871,6 +1874,7 @@ void CompilerInvocation::setFortranOpts() {
frontendOptions.fortranForm == FortranForm::FixedForm;
}
fortranOptions.fixedFormColumns = frontendOptions.fixedFormColumns;
+ fortranOptions.freeFormColumns = frontendOptions.freeFormColumns;
// -E
fortranOptions.prescanAndReformat =
diff --git a/flang/lib/Parser/parsing.cpp b/flang/lib/Parser/parsing.cpp
index 667d8d9297ecb..3bdbcb3fd1281 100644
--- a/flang/lib/Parser/parsing.cpp
+++ b/flang/lib/Parser/parsing.cpp
@@ -75,6 +75,7 @@ const SourceFile *Parsing::Prescan(const std::string &path, Options options) {
messages_, *currentCooked_, preprocessor_, options.features};
prescanner.set_fixedForm(options.isFixedForm)
.set_fixedFormColumnLimit(options.fixedFormColumns)
+ .set_freeFormColumnLimit(options.freeFormColumns)
.set_preprocessingOnly(options.prescanAndReformat)
.set_expandIncludeLines(!options.prescanAndReformat ||
options.expandIncludeLinesInPreprocessedOutput)
diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp
index 78537aef1fdfe..0c558b2241310 100644
--- a/flang/lib/Parser/prescan.cpp
+++ b/flang/lib/Parser/prescan.cpp
@@ -42,6 +42,7 @@ Prescanner::Prescanner(const Prescanner &that, Preprocessor &prepro,
backslashFreeFormContinuation_{that.backslashFreeFormContinuation_},
inFixedForm_{that.inFixedForm_},
fixedFormColumnLimit_{that.fixedFormColumnLimit_},
+ freeFormColumnLimit_{that.freeFormColumnLimit_},
encoding_{that.encoding_},
prescannerNesting_{that.prescannerNesting_ + 1},
skipLeadingAmpersand_{that.skipLeadingAmpersand_},
@@ -568,6 +569,8 @@ void Prescanner::SkipToEndOfLine() {
bool Prescanner::MustSkipToEndOfLine() const {
if (inFixedForm_ && column_ > fixedFormColumnLimit_ && !tabInCurrentLine_) {
return true; // skip over ignored columns in right margin (73:80)
+ } else if (!inFixedForm_ && column_ > freeFormColumnLimit_) {
+ return true; // inline comment goes to end of source line
} else if (*at_ == '!' && !inCharLiteral_ &&
(!inFixedForm_ || tabInCurrentLine_ || column_ != 6)) {
return InCompilerDirective() ||
diff --git a/flang/lib/Parser/prescan.h b/flang/lib/Parser/prescan.h
index 8f4f390d4ea37..2e511e4edf71e 100644
--- a/flang/lib/Parser/prescan.h
+++ b/flang/lib/Parser/prescan.h
@@ -68,6 +68,10 @@ class Prescanner {
fixedFormColumnLimit_ = limit;
return *this;
}
+ Prescanner &set_freeFormColumnLimit(int limit) {
+ freeFormColumnLimit_ = limit;
+ return *this;
+ }
Prescanner &AddCompilerDirectiveSentinel(const std::string &);
@@ -269,6 +273,7 @@ class Prescanner {
bool backslashFreeFormContinuation_{false};
bool inFixedForm_{false};
int fixedFormColumnLimit_{72};
+ int freeFormColumnLimit_{1000000};
Encoding encoding_{Encoding::UTF_8};
int parenthesisNesting_{0};
int prescannerNesting_{0};
diff --git a/flang/test/Driver/Inputs/free-line-length-test.f90 b/flang/test/Driver/Inputs/free-line-length-test.f90
new file mode 100644
index 0000000000000..dda2245ed34ce
--- /dev/null
+++ b/flang/test/Driver/Inputs/free-line-length-test.f90
@@ -0,0 +1,4 @@
+! The length of the line below is exactly 133 characters
+ program aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ end
+
diff --git a/flang/test/Driver/ffree-line-length.f90 b/flang/test/Driver/ffree-line-length.f90
new file mode 100644
index 0000000000000..9e54191181092
--- /dev/null
+++ b/flang/test/Driver/ffree-line-length.f90
@@ -0,0 +1,38 @@
+! Ensure argument -ffree-line-length=n works as expected.
+
+!--------------------------
+! FLANG DRIVER (flang)
+!--------------------------
+! RUN: %flang -E -Xflang -fno-reformat %S/Inputs/free-line-length-test.f90 2>&1 | FileCheck %s --check-prefix=UNLIMITEDLENGTH
+! RUN: not %flang -E -Xflang -fno-reformat -ffree-line-length=-2 %S/Inputs/free-line-length-test.f90 2>&1 | FileCheck %s --check-prefix=NEGATIVELENGTH
+! RUN: not %flang -E -Xflang -fno-reformat -ffree-line-length=3 %S/Inputs/free-line-length-test.f90 2>&1 | FileCheck %s --check-prefix=INVALIDLENGTH
+! RUN: %flang -E -Xflang -fno-reformat -ffree-line-length=none %S/Inputs/free-line-length-test.f90 2>&1 | FileCheck %s --check-prefix=UNLIMITEDLENGTH
+! RUN: %flang -E -Xflang -fno-reformat -ffree-line-length=0 %S/Inputs/free-line-length-test.f90 2>&1 | FileCheck %s --check-prefix=UNLIMITEDLENGTH
+! RUN: %flang -E -Xflang -fno-reformat -ffree-line-length=13 %S/Inputs/free-line-length-test.f90 2>&1 | FileCheck %s --check-prefix=LENGTH13
+
+!----------------------------------------
+! FRONTEND FLANG DRIVER (flang -fc1)
+!----------------------------------------
+! RUN: %flang_fc1 -E -fno-reformat %S/Inputs/free-line-length-test.f90 2>&1 | FileCheck %s --check-prefix=UNLIMITEDLENGTH
+! RUN: not %flang_fc1 -E -fno-reformat -ffree-line-length=-2 %S/Inputs/free-line-length-test.f90 2>&1 | FileCheck %s --check-prefix=NEGATIVELENGTH
+! RUN: not %flang_fc1 -E -fno-reformat -ffree-line-length=3 %S/Inputs/free-line-length-test.f90 2>&1 | FileCheck %s --check-prefix=INVALIDLENGTH
+! RUN: %flang_fc1 -E -fno-reformat -ffree-line-length=none %S/Inputs/free-line-length-test.f90 2>&1 | FileCheck %s --check-prefix=UNLIMITEDLENGTH
+! RUN: %flang_fc1 -E -fno-reformat -ffree-line-length=0 %S/Inputs/free-line-length-test.f90 2>&1 | FileCheck %s --check-prefix=UNLIMITEDLENGTH
+! RUN: %flang_fc1 -E -fno-reformat -ffree-line-length=13 %S/Inputs/free-line-length-test.f90 2>&1 | FileCheck %s --check-prefix=LENGTH13
+
+!-------------------------------------
+! COMMAND ALIAS -ffree-line-length-n
+!-------------------------------------
+! RUN: %flang -E -Xflang -fno-reformat -ffree-line-length-13 %S/Inputs/free-line-length-test.f90 2>&1 | FileCheck %s --check-prefix=LENGTH13
+! RUN: %flang_fc1 -E -fno-reformat -ffree-line-length-13 %S/Inputs/free-line-length-test.f90 2>&1 | FileCheck %s --check-prefix=LENGTH13
+
+
+! NEGATIVELENGTH: invalid value '-2' in 'ffree-line-length=', value must be 'none' or a positive integer
+
+! INVALIDLENGTH: invalid value '3' in 'ffree-line-length=', value must be '7' or greater
+
+! The line should not be trimmed and should be read.
+! UNLIMITEDLENGTH: program {{(a{118})}}
+
+! LENGTH13: program
+
``````````
</details>
https://github.com/llvm/llvm-project/pull/192941
More information about the flang-commits
mailing list