[flang][driver] Add `-fdebug-dump-parsing-log`

This patch adds `-fdebug-dump-parsing-log` in the new driver. This option is
semantically identical to `-fdebug-instrumented-parse` in `f18` (the
former is added as an alias in `f18`).

As dumping the parsing log makes only sense for instrumented parses, we
set Fortran::parser::Options::instrumentedParse to `True` when
`-fdebug-dump-parsing-log` is used. This is consistent with `f18`.

To facilitate tweaking the configuration of the frontend based on the
action being requested, `setUpFrontendBasedOnAction` is introduced in
CompilerInvocation.cpp.

Differential Revision: https://reviews.llvm.org/D97457

GitOrigin-RevId: 523d7bc6f427f9ae32e54dbf1764826cfb269d21
diff --git a/include/flang/Frontend/FrontendActions.h b/include/flang/Frontend/FrontendActions.h
index f6dfdd2..35d1e6f 100644
--- a/include/flang/Frontend/FrontendActions.h
+++ b/include/flang/Frontend/FrontendActions.h
@@ -54,6 +54,10 @@
   void ExecuteAction() override;
 };
 
+class DebugDumpParsingLogAction : public PrescanAction {
+  void ExecuteAction() override;
+};
+
 class DebugMeasureParseTreeAction : public PrescanAction {
   void ExecuteAction() override;
 };
diff --git a/include/flang/Frontend/FrontendOptions.h b/include/flang/Frontend/FrontendOptions.h
index 98a717d..48182f4 100644
--- a/include/flang/Frontend/FrontendOptions.h
+++ b/include/flang/Frontend/FrontendOptions.h
@@ -50,6 +50,9 @@
   /// Dump provenance
   DebugDumpProvenance,
 
+  /// Parse then output the parsing log
+  DebugDumpParsingLog,
+
   /// Parse then output the number of objects in the parse tree and the overall
   /// size
   DebugMeasureParseTree,
@@ -172,6 +175,9 @@
   /// Show the -version text.
   unsigned showVersion_ : 1;
 
+  /// Instrument the parse to get a more verbose log
+  unsigned instrumentedParse_ : 1;
+
   /// The input files and their types.
   std::vector<FrontendInputFile> inputs_;
 
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 0dc7e7c..1764970 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -85,6 +85,15 @@
   return true;
 }
 
+// Tweak the frontend configuration based on the frontend action
+static void setUpFrontendBasedOnAction(FrontendOptions &opts) {
+  assert(opts.programAction_ != Fortran::frontend::InvalidAction &&
+      "Fortran frontend action not set!");
+
+  if (opts.programAction_ == DebugDumpParsingLog)
+    opts.instrumentedParse_ = true;
+}
+
 static InputKind ParseFrontendArgs(FrontendOptions &opts,
     llvm::opt::ArgList &args, clang::DiagnosticsEngine &diags) {
 
@@ -125,6 +134,9 @@
     case clang::driver::options::OPT_fdebug_dump_provenance:
       opts.programAction_ = DebugDumpProvenance;
       break;
+    case clang::driver::options::OPT_fdebug_dump_parsing_log:
+      opts.programAction_ = DebugDumpParsingLog;
+      break;
     case clang::driver::options::OPT_fdebug_measure_parse_tree:
       opts.programAction_ = DebugMeasureParseTree;
       break;
@@ -264,6 +276,9 @@
           << arg->getAsString(args) << argValue;
     }
   }
+
+  setUpFrontendBasedOnAction(opts);
+
   return dashX;
 }
 
@@ -484,6 +499,9 @@
   // directories
   if (moduleDirJ.compare(".") != 0)
     fortranOptions.searchDirectories.emplace_back(moduleDirJ);
+
+  if (frontendOptions.instrumentedParse_)
+    fortranOptions.instrumentedParse = true;
 }
 
 void CompilerInvocation::setSemanticsOpts(
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index b7e4f91..f956015 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -307,6 +307,13 @@
   }
 }
 
+void DebugDumpParsingLogAction::ExecuteAction() {
+  CompilerInstance &ci = this->instance();
+
+  ci.parsing().Parse(llvm::errs());
+  ci.parsing().DumpParsingLog(llvm::outs());
+}
+
 void EmitObjAction::ExecuteAction() {
   CompilerInstance &ci = this->instance();
   unsigned DiagID = ci.diagnostics().getCustomDiagID(
diff --git a/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index c5f7bb2..041e79b 100644
--- a/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -52,6 +52,9 @@
   case DebugDumpProvenance:
     return std::make_unique<DebugDumpProvenanceAction>();
     break;
+  case DebugDumpParsingLog:
+    return std::make_unique<DebugDumpParsingLogAction>();
+    break;
   case DebugMeasureParseTree:
     return std::make_unique<DebugMeasureParseTreeAction>();
     break;
diff --git a/test/Driver/debug-parsing-log.f90 b/test/Driver/debug-parsing-log.f90
new file mode 100644
index 0000000..f658fa6
--- /dev/null
+++ b/test/Driver/debug-parsing-log.f90
@@ -0,0 +1,31 @@
+! RUN: %flang_fc1 -fdebug-dump-parsing-log %s  2>&1 | FileCheck %s
+
+!-----------------
+! EXPECTED OUTPUT
+!-----------------
+! Below are just few lines extracted from the dump. The actual output is much _much_ bigger.
+
+! CHECK: {{.*}}/debug-parsing-log.f90:31:1: IMPLICIT statement
+! CHECK-NEXT:  END PROGRAM
+! CHECK-NEXT:  ^
+! CHECK-NEXT:  fail 3
+! CHECK-NEXT: {{.*}}/debug-parsing-log.f90:31:1: error: expected 'IMPLICIT NONE'
+! CHECK-NEXT:   END PROGRAM
+! CHECK-NEXT:   ^
+! CHECK-NEXT: {{.*}}/debug-parsing-log.f90:31:1: in the context: IMPLICIT statement
+! CHECK-NEXT:   END PROGRAM
+! CHECK-NEXT:   ^
+! CHECK-NEXT: {{.*}}/debug-parsing-log.f90:31:1: in the context: implicit part
+! CHECK-NEXT:   END PROGRAM
+! CHECK-NEXT:   ^
+! CHECK-NEXT: {{.*}}/debug-parsing-log.f90:31:1: in the context: specification part
+! CHECK-NEXT:   END PROGRAM
+! CHECK-NEXT:   ^
+! CHECK-NEXT: {{.*}}/debug-parsing-log.f90:31:1: in the context: main program
+! CHECK-NEXT:   END PROGRAM
+! CHECK-NEXT:   ^
+
+!-----------------
+! TEST INPUT
+!-----------------
+END PROGRAM
diff --git a/test/Driver/driver-help.f90 b/test/Driver/driver-help.f90
index d1d5078..37daeea 100644
--- a/test/Driver/driver-help.f90
+++ b/test/Driver/driver-help.f90
@@ -62,6 +62,8 @@
 ! HELP-FC1-NEXT: Enable the old style PARAMETER statement
 ! HELP-FC1-NEXT: -fbackslash            Specify that backslash in string introduces an escape character
 ! HELP-FC1-NEXT: -fdebug-dump-parse-tree Dump the parse tree
+! HELP-FC1-NEXT: -fdebug-dump-parsing-log
+! HELP-FC1-NEXT:                   Run instrumented parse and dump the parsing log
 ! HELP-FC1-NEXT: -fdebug-dump-provenance Dump provenance
 ! HELP-FC1-NEXT: -fdebug-dump-symbols    Dump symbols after the semantic analysis
 ! HELP-FC1-NEXT: -fdebug-measure-parse-tree
diff --git a/tools/f18/f18.cpp b/tools/f18/f18.cpp
index f43813e..5bc069c 100644
--- a/tools/f18/f18.cpp
+++ b/tools/f18/f18.cpp
@@ -537,7 +537,8 @@
       driver.debugModuleWriter = true;
     } else if (arg == "-fdebug-measure-parse-tree") {
       driver.measureTree = true;
-    } else if (arg == "-fdebug-instrumented-parse") {
+    } else if (arg == "-fdebug-instrumented-parse" ||
+        arg == "-fdebug-dump-parsing-log") {
       options.instrumentedParse = true;
     } else if (arg == "-fdebug-no-semantics") {
       driver.debugNoSemantics = true;