awarzynski updated this revision to Diff 354294.
awarzynski added a subscriber: PeteSteinfeld.
awarzynski added a comment.

Rename the new flag as `-fno-analyzed-objects-for-unparse`

Based on the discussion, I've renamed the flag to better reflect the intention. 
Does it make more sense now?

Note, the default behaviour of the drivers does not change with this patch 
(i.e. `{f18|flang-new} -fdebug-unparse` will generate identical results 
_before_ and _after_).

@klousler & @PeteSteinfeld, many thanks for all the feedback!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103612/new/

https://reviews.llvm.org/D103612

Files:
  clang/include/clang/Driver/Options.td
  flang/include/flang/Frontend/CompilerInvocation.h
  flang/lib/Frontend/CompilerInvocation.cpp
  flang/lib/Frontend/FrontendActions.cpp
  flang/lib/Frontend/FrontendOptions.cpp
  flang/test/Driver/driver-help.f90
  flang/test/Driver/unparse-use-analyzed.f95
  flang/tools/f18/f18.cpp
  flang/tools/f18/flang

Index: flang/tools/f18/flang
===================================================================
--- flang/tools/f18/flang
+++ flang/tools/f18/flang
@@ -8,7 +8,7 @@
 #===------------------------------------------------------------------------===#
 
 wd=$(cd $(dirname "$0")/.. && pwd)
-opts="-module-suffix .f18.mod "
+opts="-fno-analyzed-objects-for-unparse -module-suffix .f18.mod "
 if ! $wd/bin/f18 $opts "$@"
 then status=$?
      echo flang: in $PWD, f18 failed with exit status $status: $wd/bin/f18 $opts "$@" >&2
Index: flang/tools/f18/f18.cpp
===================================================================
--- flang/tools/f18/f18.cpp
+++ flang/tools/f18/f18.cpp
@@ -105,7 +105,7 @@
   bool debugModuleWriter{false};
   bool defaultReal8{false};
   bool measureTree{false};
-  bool unparseTypedExprsToF18_FC{false};
+  bool useAnalyzedObjectsForUnparse{true};
   std::vector<std::string> F18_FCArgs;
   const char *prefix{nullptr};
   bool getDefinition{false};
@@ -322,7 +322,8 @@
     Unparse(llvm::outs(), parseTree, driver.encoding, true /*capitalize*/,
         options.features.IsEnabled(
             Fortran::common::LanguageFeature::BackslashEscapes),
-        nullptr /* action before each statement */, &asFortran);
+        nullptr /* action before each statement */,
+        driver.useAnalyzedObjectsForUnparse ? &asFortran : nullptr);
     return {};
   }
   if (driver.dumpPreFirTree) {
@@ -353,7 +354,7 @@
         options.features.IsEnabled(
             Fortran::common::LanguageFeature::BackslashEscapes),
         nullptr /* action before each statement */,
-        driver.unparseTypedExprsToF18_FC ? &asFortran : nullptr);
+        driver.useAnalyzedObjectsForUnparse ? &asFortran : nullptr);
   }
 
   RunOtherCompiler(driver, tmpSourcePath.data(), relo.data());
@@ -578,8 +579,8 @@
     } else if (arg == "-funparse-with-symbols" ||
         arg == "-fdebug-unparse-with-symbols") {
       driver.dumpUnparseWithSymbols = true;
-    } else if (arg == "-funparse-typed-exprs-to-f18-fc") {
-      driver.unparseTypedExprsToF18_FC = true;
+    } else if (arg == "-fno-analyzed-objects-for-unparse") {
+      driver.useAnalyzedObjectsForUnparse = false;
     } else if (arg == "-fparse-only" || arg == "-fsyntax-only") {
       driver.syntaxOnly = true;
     } else if (arg == "-c") {
Index: flang/test/Driver/unparse-use-analyzed.f95
===================================================================
--- /dev/null
+++ flang/test/Driver/unparse-use-analyzed.f95
@@ -0,0 +1,31 @@
+! Tests `-fno-analyzed-exprs-as-fortran` frontend option
+
+!--------------------------
+! RUN lines
+!--------------------------
+! RUN: %flang_fc1 -fdebug-unparse  %s | FileCheck %s --check-prefix=DEFAULT
+! RUN: %flang_fc1 -fdebug-unparse -fno-analyzed-objects-for-unparse %s | FileCheck %s --check-prefix=DISABLED
+
+!------------------------------------------------
+! EXPECTED OUTPUT: default - use analyzed objects
+!------------------------------------------------
+! DEFAULT: PROGRAM test
+! DEFAULT-NEXT:  REAL, PARAMETER :: val = 3.43e2_4
+! DEFAULT-NEXT:  PRINT *, 3.47e2_4
+! DEFAULT-NEXT: END PROGRAM
+
+!-----------------------------------------------------------
+! EXPECTED OUTPUT: disabled - don't use the analyzed objects
+!-----------------------------------------------------------
+! DISABLED: PROGRAM test
+! DISABLED-NEXT:  REAL, PARAMETER :: val = 343.0
+! DISABLED-NEXT:  PRINT *, val+4
+! DISABLED-NEXT: END PROGRAM
+
+!--------------------------
+! INPUT
+!--------------------------
+program test
+  real, parameter :: val = 343.0
+  print *, val + 4
+end program
Index: flang/test/Driver/driver-help.f90
===================================================================
--- flang/test/Driver/driver-help.f90
+++ flang/test/Driver/driver-help.f90
@@ -101,6 +101,8 @@
 ! HELP-FC1-NEXT:                        Specify where to find the compiled intrinsic modules
 ! HELP-FC1-NEXT: -flarge-sizes          Use INTEGER(KIND=8) for the result type in size-related intrinsics
 ! HELP-FC1-NEXT: -flogical-abbreviations Enable logical abbreviations
+! HELP-FC1-NEXT: -fno-analyzed-objects-for-unparse
+! HELP-FC1-NEXT:                        Do not use the analyzed objects when unparsing
 ! HELP-FC1-NEXT: -fopenacc              Enable OpenACC
 ! HELP-FC1-NEXT: -fopenmp               Parse OpenMP pragmas and generate parallel code.
 ! HELP-FC1-NEXT: -fxor-operator         Enable .XOR. as a synonym of .NEQV.
Index: flang/lib/Frontend/FrontendOptions.cpp
===================================================================
--- flang/lib/Frontend/FrontendOptions.cpp
+++ flang/lib/Frontend/FrontendOptions.cpp
@@ -32,34 +32,6 @@
       suffix == "F03" || suffix == "F08" || suffix == "F18";
 }
 
-// TODO: This is a copy of `asFortran` from f18.cpp and is added here for
-// compatiblity. It doesn't really belong here, but I couldn't find a better
-// place. We should decide whether to add it to the Evaluate or Parse/Unparse
-// APIs or some dedicated utility library in the driver.
-Fortran::parser::AnalyzedObjectsAsFortran
-Fortran::frontend::getBasicAsFortran() {
-  return Fortran::parser::AnalyzedObjectsAsFortran{
-      [](llvm::raw_ostream &o, const Fortran::evaluate::GenericExprWrapper &x) {
-        if (x.v) {
-          x.v->AsFortran(o);
-        } else {
-          o << "(bad expression)";
-        }
-      },
-      [](llvm::raw_ostream &o,
-          const Fortran::evaluate::GenericAssignmentWrapper &x) {
-        if (x.v) {
-          x.v->AsFortran(o);
-        } else {
-          o << "(bad assignment)";
-        }
-      },
-      [](llvm::raw_ostream &o, const Fortran::evaluate::ProcedureRef &x) {
-        x.AsFortran(o << "CALL ");
-      },
-  };
-}
-
 InputKind FrontendOptions::GetInputKindForExtension(llvm::StringRef extension) {
   if (isFixedFormSuffix(extension) || isFreeFormSuffix(extension)) {
     return Language::Fortran;
Index: flang/lib/Frontend/FrontendActions.cpp
===================================================================
--- flang/lib/Frontend/FrontendActions.cpp
+++ flang/lib/Frontend/FrontendActions.cpp
@@ -242,28 +242,27 @@
 }
 
 void DebugUnparseNoSemaAction::ExecuteAction() {
+  auto &invoc = this->instance().invocation();
   auto &parseTree{instance().parsing().parseTree()};
 
-  Fortran::parser::AnalyzedObjectsAsFortran asFortran =
-      Fortran::frontend::getBasicAsFortran();
-
   // TODO: Options should come from CompilerInvocation
   Unparse(llvm::outs(), *parseTree,
       /*encoding=*/Fortran::parser::Encoding::UTF_8,
       /*capitalizeKeywords=*/true, /*backslashEscapes=*/false,
-      /*preStatement=*/nullptr, &asFortran);
+      /*preStatement=*/nullptr,
+      invoc.useAnalyzedObjectsForUnparse() ? &invoc.asFortran() : nullptr);
 }
 
 void DebugUnparseAction::ExecuteAction() {
+  auto &invoc = this->instance().invocation();
   auto &parseTree{instance().parsing().parseTree()};
-  Fortran::parser::AnalyzedObjectsAsFortran asFortran =
-      Fortran::frontend::getBasicAsFortran();
 
   // TODO: Options should come from CompilerInvocation
   Unparse(llvm::outs(), *parseTree,
       /*encoding=*/Fortran::parser::Encoding::UTF_8,
       /*capitalizeKeywords=*/true, /*backslashEscapes=*/false,
-      /*preStatement=*/nullptr, &asFortran);
+      /*preStatement=*/nullptr,
+      invoc.useAnalyzedObjectsForUnparse() ? &invoc.asFortran() : nullptr);
 
   // Report fatal semantic errors
   reportFatalSemanticErrors(semantics(), this->instance().diagnostics(),
@@ -310,12 +309,11 @@
 
   // Dump parse tree
   auto &parseTree{instance().parsing().parseTree()};
-  Fortran::parser::AnalyzedObjectsAsFortran asFortran =
-      Fortran::frontend::getBasicAsFortran();
   llvm::outs() << "========================";
   llvm::outs() << " Flang: parse tree dump ";
   llvm::outs() << "========================\n";
-  Fortran::parser::DumpTree(llvm::outs(), parseTree, &asFortran);
+  Fortran::parser::DumpTree(
+      llvm::outs(), parseTree, &ci.invocation().asFortran());
 
   auto &semantics = this->semantics();
   auto tables{Fortran::semantics::BuildRuntimeDerivedTypeTables(
@@ -343,20 +341,19 @@
 
 void DebugDumpParseTreeNoSemaAction::ExecuteAction() {
   auto &parseTree{instance().parsing().parseTree()};
-  Fortran::parser::AnalyzedObjectsAsFortran asFortran =
-      Fortran::frontend::getBasicAsFortran();
 
   // Dump parse tree
-  Fortran::parser::DumpTree(llvm::outs(), parseTree, &asFortran);
+  Fortran::parser::DumpTree(
+      llvm::outs(), parseTree, &this->instance().invocation().asFortran());
 }
 
 void DebugDumpParseTreeAction::ExecuteAction() {
   auto &parseTree{instance().parsing().parseTree()};
-  Fortran::parser::AnalyzedObjectsAsFortran asFortran =
-      Fortran::frontend::getBasicAsFortran();
 
   // Dump parse tree
-  Fortran::parser::DumpTree(llvm::outs(), parseTree, &asFortran);
+  Fortran::parser::DumpTree(
+      llvm::outs(), parseTree, &this->instance().invocation().asFortran());
+
   // Report fatal semantic errors
   reportFatalSemanticErrors(semantics(), this->instance().diagnostics(),
       GetCurrentFileOrBufferName());
Index: flang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- flang/lib/Frontend/CompilerInvocation.cpp
+++ flang/lib/Frontend/CompilerInvocation.cpp
@@ -404,6 +404,12 @@
     res.SetModuleFileSuffix(moduleSuffix->getValue());
   }
 
+  // -fno-analyzed-objects-for-unparse
+  if (args.hasArg(
+          clang::driver::options::OPT_fno_analyzed_objects_for_unparse)) {
+    res.SetUseAnalyzedObjectsForUnparse(false);
+  }
+
   return diags.getNumErrors() == numErrorsBefore;
 }
 
Index: flang/include/flang/Frontend/CompilerInvocation.h
===================================================================
--- flang/include/flang/Frontend/CompilerInvocation.h
+++ flang/include/flang/Frontend/CompilerInvocation.h
@@ -75,11 +75,34 @@
 
   bool warnAsErr_ = false;
 
+  bool useAnalyzedObjectsForUnparse_ = true;
+
   // Fortran Dialect options
   Fortran::common::IntrinsicTypeDefaultKinds defaultKinds_;
 
   bool EnableConformanceChecks_ = false;
 
+  Fortran::parser::AnalyzedObjectsAsFortran AsFortran_{
+      [](llvm::raw_ostream &o, const Fortran::evaluate::GenericExprWrapper &x) {
+        if (x.v) {
+          x.v->AsFortran(o);
+        } else {
+          o << "(bad expression)";
+        }
+      },
+      [](llvm::raw_ostream &o,
+          const Fortran::evaluate::GenericAssignmentWrapper &x) {
+        if (x.v) {
+          x.v->AsFortran(o);
+        } else {
+          o << "(bad assignment)";
+        }
+      },
+      [](llvm::raw_ostream &o, const Fortran::evaluate::ProcedureRef &x) {
+        x.AsFortran(o << "CALL ");
+      },
+  };
+
 public:
   CompilerInvocation() = default;
 
@@ -108,11 +131,21 @@
   bool &warnAsErr() { return warnAsErr_; }
   const bool &warnAsErr() const { return warnAsErr_; }
 
+  bool &useAnalyzedObjectsForUnparse() { return useAnalyzedObjectsForUnparse_; }
+  const bool &useAnalyzedObjectsForUnparse() const {
+    return useAnalyzedObjectsForUnparse_;
+  }
+
   bool &enableConformanceChecks() { return EnableConformanceChecks_; }
   const bool &enableConformanceChecks() const {
     return EnableConformanceChecks_;
   }
 
+  Fortran::parser::AnalyzedObjectsAsFortran &asFortran() { return AsFortran_; }
+  const Fortran::parser::AnalyzedObjectsAsFortran &asFortran() const {
+    return AsFortran_;
+  }
+
   Fortran::common::IntrinsicTypeDefaultKinds &defaultKinds() {
     return defaultKinds_;
   }
@@ -142,6 +175,10 @@
 
   void SetWarnAsErr(bool flag) { warnAsErr_ = flag; }
 
+  void SetUseAnalyzedObjectsForUnparse(bool flag) {
+    useAnalyzedObjectsForUnparse_ = flag;
+  }
+
   /// Set the Fortran options to predifined defaults. These defaults are
   /// consistend with f18/f18.cpp.
   // TODO: We should map frontendOpts_ to parserOpts_ instead. For that, we
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -4536,6 +4536,11 @@
 
 def module_suffix : Separate<["-"], "module-suffix">,  Group<f_Group>, MetaVarName<"<suffix>">,
   HelpText<"Use <suffix> as the suffix for module files (the default value is `.mod`)">;
+def fanalyzed_objects_for_unparse : Flag<["-"],
+  "fanalyzed-objects-for-unparse">,  Group<f_Group>;
+def fno_analyzed_objects_for_unparse : Flag<["-"],
+  "fno-analyzed-objects-for-unparse">,  Group<f_Group>,
+  HelpText<"Do not use the analyzed objects when unparsing">;
 
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to