[clang] [flang] [flang] Preserve fixed form in fc1 -x value (PR #117563)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 25 06:36:56 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-driver
@llvm/pr-subscribers-clang
Author: None (macurtis-amd)
<details>
<summary>Changes</summary>
Fixes an issue introduced by
9fb2db1e1f42 [flang] Retain spaces when preprocessing fixed-form source
Where flang -fc1 fails to parse preprocessor output because it now remains in fixed form.
---
Full diff: https://github.com/llvm/llvm-project/pull/117563.diff
6 Files Affected:
- (modified) clang/include/clang/Driver/Types.def (+5-2)
- (modified) clang/lib/Driver/ToolChain.cpp (+8-4)
- (modified) clang/lib/Driver/Types.cpp (+8-6)
- (modified) flang/lib/Frontend/CompilerInvocation.cpp (+12)
- (added) flang/test/Driver/x-lang.f (+8)
- (added) flang/test/Parser/x-f95-fixed.f (+17)
``````````diff
diff --git a/clang/include/clang/Driver/Types.def b/clang/include/clang/Driver/Types.def
index 214c5e7a789f97..5b64700c6a688b 100644
--- a/clang/include/clang/Driver/Types.def
+++ b/clang/include/clang/Driver/Types.def
@@ -88,8 +88,11 @@ TYPE("assembler-with-cpp", Asm, PP_Asm, "S", phases
// modules when Flang needs to emit pre-processed files. Therefore, the
// `PP_TYPE` is set to `PP_Fortran` so that the driver is fine with
// "pre-processing a pre-processed file".
-TYPE("f95", PP_Fortran, PP_Fortran, "i", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
-TYPE("f95-cpp-input", Fortran, PP_Fortran, nullptr, phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("f95", PP_Fortran, PP_Fortran, "i", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("f95-cpp-input", Fortran, PP_Fortran, nullptr, phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("f95-fixed", PP_Fortran_Fixed, PP_Fortran_Fixed, "i", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("f95-fixed-cpp-input", Fortran_Fixed, PP_Fortran_Fixed, nullptr, phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+
TYPE("java", Java, INVALID, nullptr, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
// LLVM IR/LTO types. We define separate types for IR and LTO because LTO
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 0d426a467e9a3b..768e2e7842650c 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -1037,10 +1037,14 @@ types::ID ToolChain::LookupTypeForExtension(StringRef Ext) const {
types::ID id = types::lookupTypeForExtension(Ext);
// Flang always runs the preprocessor and has no notion of "preprocessed
- // fortran". Here, TY_PP_Fortran is coerced to TY_Fortran to avoid treating
- // them differently.
- if (D.IsFlangMode() && id == types::TY_PP_Fortran)
- id = types::TY_Fortran;
+ // fortran". Here, TY_PP_Fortran[_Fixed] is coerced to TY_Fortran[_Fixed] to
+ // avoid treating them differently.
+ if (D.IsFlangMode()) {
+ if (id == types::TY_PP_Fortran)
+ id = types::TY_Fortran;
+ else if (id == types::TY_PP_Fortran_Fixed)
+ id = types::TY_Fortran_Fixed;
+ }
return id;
}
diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp
index eaca74a7b55292..19e2c55d4a663a 100644
--- a/clang/lib/Driver/Types.cpp
+++ b/clang/lib/Driver/Types.cpp
@@ -162,7 +162,9 @@ bool types::isAcceptedByFlang(ID Id) {
return false;
case TY_Fortran:
+ case TY_Fortran_Fixed:
case TY_PP_Fortran:
+ case TY_PP_Fortran_Fixed:
return true;
case TY_LLVM_IR:
case TY_LLVM_BC:
@@ -300,8 +302,8 @@ types::ID types::lookupTypeForExtension(llvm::StringRef Ext) {
return llvm::StringSwitch<types::ID>(Ext)
.Case("c", TY_C)
.Case("C", TY_CXX)
- .Case("F", TY_Fortran)
- .Case("f", TY_PP_Fortran)
+ .Case("F", TY_Fortran_Fixed)
+ .Case("f", TY_PP_Fortran_Fixed)
.Case("h", TY_CHeader)
.Case("H", TY_CXXHeader)
.Case("i", TY_PP_C)
@@ -344,10 +346,10 @@ types::ID types::lookupTypeForExtension(llvm::StringRef Ext) {
.Case("f90", TY_PP_Fortran)
.Case("F95", TY_Fortran)
.Case("f95", TY_PP_Fortran)
- .Case("for", TY_PP_Fortran)
- .Case("FOR", TY_PP_Fortran)
- .Case("fpp", TY_Fortran)
- .Case("FPP", TY_Fortran)
+ .Case("for", TY_PP_Fortran_Fixed)
+ .Case("FOR", TY_PP_Fortran_Fixed)
+ .Case("fpp", TY_Fortran_Fixed)
+ .Case("FPP", TY_Fortran_Fixed)
.Case("gch", TY_PCH)
.Case("hip", TY_HIP)
.Case("hipi", TY_PP_HIP)
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 0b79c95eade0d3..acd884fb10b3fe 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -639,6 +639,7 @@ static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
// Get the input kind (from the value passed via `-x`)
InputKind dashX(Language::Unknown);
+ FortranForm dashXForm = FortranForm::Unknown;
if (const llvm::opt::Arg *a =
args.getLastArg(clang::driver::options::OPT_x)) {
llvm::StringRef xValue = a->getValue();
@@ -648,6 +649,8 @@ static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
// pre-processed inputs.
.Case("f95", Language::Fortran)
.Case("f95-cpp-input", Language::Fortran)
+ .Case("f95-fixed", Language::Fortran)
+ .Case("f95-fixed-cpp-input", Language::Fortran)
// CUDA Fortran
.Case("cuda", Language::Fortran)
.Default(Language::Unknown);
@@ -663,6 +666,13 @@ static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
if (dashX.isUnknown())
diags.Report(clang::diag::err_drv_invalid_value)
<< a->getAsString(args) << a->getValue();
+
+ if (dashX.getLanguage() == Language::Fortran) {
+ if (xValue.starts_with("f95-fixed"))
+ dashXForm = FortranForm::FixedForm;
+ else
+ dashXForm = FortranForm::FreeForm;
+ }
}
// Collect the input files and save them in our instance of FrontendOptions.
@@ -694,6 +704,8 @@ static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
arg->getOption().matches(clang::driver::options::OPT_ffixed_form)
? FortranForm::FixedForm
: FortranForm::FreeForm;
+ } else if (dashXForm != FortranForm::Unknown) {
+ opts.fortranForm = dashXForm;
}
// Set fixedFormColumns based on -ffixed-line-length=<value>
diff --git a/flang/test/Driver/x-lang.f b/flang/test/Driver/x-lang.f
new file mode 100644
index 00000000000000..08282c9479f55a
--- /dev/null
+++ b/flang/test/Driver/x-lang.f
@@ -0,0 +1,8 @@
+!RUN: %flang -save-temps -### %S/Inputs/free-form-test.f90 2>&1 | FileCheck %s --check-prefix=FREE
+!RUN: %flang -save-temps -### %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=FIXED
+
+FREE: "-fc1" {{.*}} "-o" "free-form-test.i" {{.*}} "-x" "f95-cpp-input" "{{.*}}/free-form-test.f90"
+FREE-NEXT: "-fc1" {{.*}} "-o" "free-form-test.bc" {{.*}} "-x" "f95" "free-form-test.i"
+
+FIXED: "-fc1" {{.*}} "-o" "fixed-form-test.i" {{.*}} "-x" "f95-fixed-cpp-input" "{{.*}}/fixed-form-test.f"
+FIXED-NEXT: "-fc1" {{.*}} "-o" "fixed-form-test.bc" {{.*}} "-x" "f95-fixed" "fixed-form-test.i"
diff --git a/flang/test/Parser/x-f95-fixed.f b/flang/test/Parser/x-f95-fixed.f
new file mode 100644
index 00000000000000..2012bfc018ff12
--- /dev/null
+++ b/flang/test/Parser/x-f95-fixed.f
@@ -0,0 +1,17 @@
+ subroutine foo(a, b)
+ if ( (a .eq. 0) .and.(b. eq. 1)) then
+
+ print *, "foo"
+ end if
+ end subroutine
+
+! RUN: %flang_fc1 -fsyntax-only "-x" "f95-fixed" %s 2>&1 | FileCheck %s --allow-empty --check-prefix=F95-FIXED
+! F95-FIXED-NOT: Could not parse {{.*}}x-f95-fixed.f
+! F95-FIXED-NOT: error
+! F95-FIXED-NOT: warning
+
+! RUN: not %flang_fc1 -fsyntax-only "-x" "f95" %s 2>&1 | FileCheck %s --check-prefix=F95 --strict-whitespace
+! F95: error: Could not parse {{.*}}x-f95-fixed.f
+! F95: {{.*}}x-f95-fixed.f:2:31: error: expected ')'
+! F95: if ( (a .eq. 0) .and.(b. eq. 1)) then
+! F95: {{^([ ]{32})}}^
``````````
</details>
https://github.com/llvm/llvm-project/pull/117563
More information about the cfe-commits
mailing list