[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:20 PST 2024


https://github.com/macurtis-amd created https://github.com/llvm/llvm-project/pull/117563

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.

>From 9968ef5bf76b8e045ad24767188eaadab93dd747 Mon Sep 17 00:00:00 2001
From: Matthew Curtis <macurtis at amd.com>
Date: Sat, 23 Nov 2024 08:43:20 -0600
Subject: [PATCH] [flang] Preserve fixed form in fc1 -x value

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.
---
 clang/include/clang/Driver/Types.def      |  7 +++++--
 clang/lib/Driver/ToolChain.cpp            | 12 ++++++++----
 clang/lib/Driver/Types.cpp                | 14 ++++++++------
 flang/lib/Frontend/CompilerInvocation.cpp | 12 ++++++++++++
 flang/test/Driver/x-lang.f                |  8 ++++++++
 flang/test/Parser/x-f95-fixed.f           | 17 +++++++++++++++++
 6 files changed, 58 insertions(+), 12 deletions(-)
 create mode 100644 flang/test/Driver/x-lang.f
 create mode 100644 flang/test/Parser/x-f95-fixed.f

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})}}^



More information about the cfe-commits mailing list