diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4361,6 +4361,8 @@ HelpText<"Dump the parse tree">; def fdebug_dump_provenance : Flag<["-"], "fdebug-dump-provenance">, Group, HelpText<"Dump provenance">; +def fdebug_dump_parsing_log : Flag<["-"], "fdebug-dump-parsing-log">, Group, + HelpText<"Run instrumented parse and dump the parsing log">; def fdebug_measure_parse_tree : Flag<["-"], "fdebug-measure-parse-tree">, Group, HelpText<"Measure the parse tree">; def fdebug_pre_fir_tree : Flag<["-"], "fdebug-pre-fir-tree">, Group, diff --git a/flang/include/flang/Frontend/FrontendActions.h b/flang/include/flang/Frontend/FrontendActions.h --- a/flang/include/flang/Frontend/FrontendActions.h +++ b/flang/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/flang/include/flang/Frontend/FrontendOptions.h b/flang/include/flang/Frontend/FrontendOptions.h --- a/flang/include/flang/Frontend/FrontendOptions.h +++ b/flang/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 inputs_; diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/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/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/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/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp --- a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -52,6 +52,9 @@ case DebugDumpProvenance: return std::make_unique(); break; + case DebugDumpParsingLog: + return std::make_unique(); + break; case DebugMeasureParseTree: return std::make_unique(); break; diff --git a/flang/test/Driver/debug-parsing-log.f90 b/flang/test/Driver/debug-parsing-log.f90 new file mode 100644 --- /dev/null +++ b/flang/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/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90 --- a/flang/test/Driver/driver-help.f90 +++ b/flang/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/flang/tools/f18/f18.cpp b/flang/tools/f18/f18.cpp --- a/flang/tools/f18/f18.cpp +++ b/flang/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;