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 @@ -4773,6 +4773,8 @@ HelpText<"Dump the parse tree">, DocBrief<[{Run the Parser and the semantic checks, and then output the parse tree.}]>; +def fdebug_dump_pft : Flag<["-"], "fdebug-dump-pft">, Group, + HelpText<"Dump the pre-fir parse tree">; def fdebug_dump_parse_tree_no_sema : Flag<["-"], "fdebug-dump-parse-tree-no-sema">, Group, HelpText<"Dump the parse tree (skips the semantic checks)">, DocBrief<[{Run the Parser and then output the parse tree. Semantic 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 @@ -109,6 +109,10 @@ void ExecuteAction() override; }; +class DebugDumpPFTAction : public PrescanAndSemaAction { + void ExecuteAction() override; +}; + class DebugPreFIRTreeAction : public PrescanAndSemaAction { 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 @@ -57,6 +57,9 @@ /// Parse, run semantics and then output the parse tree DebugDumpParseTree, + /// Parse, run semantics and then output the pre-fir parse tree + DebugDumpPFT, + /// Parse, run semantics and then output the parse tree and symbols DebugDumpAll, 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 @@ -168,6 +168,9 @@ case clang::driver::options::OPT_fdebug_dump_parse_tree: opts.programAction = DebugDumpParseTree; break; + case clang::driver::options::OPT_fdebug_dump_pft: + opts.programAction = DebugDumpPFT; + break; case clang::driver::options::OPT_fdebug_dump_all: opts.programAction = DebugDumpAll; break; 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 @@ -506,3 +506,17 @@ } void PluginParseTreeAction::ExecuteAction() {} + +void DebugDumpPFTAction::ExecuteAction() { + CompilerInstance &ci = this->instance(); + + if (auto ast = Fortran::lower::createPFT( + *ci.parsing().parseTree(), ci.semantics().context())) { + Fortran::lower::dumpPFT(llvm::outs(), *ast); + return; + } + + unsigned DiagID = ci.diagnostics().getCustomDiagID( + clang::DiagnosticsEngine::Error, "Pre FIR Tree is NULL."); + ci.diagnostics().Report(DiagID); +} 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 @@ -49,6 +49,8 @@ return std::make_unique(); case DebugDumpParseTree: return std::make_unique(); + case DebugDumpPFT: + return std::make_unique(); case DebugDumpParseTreeNoSema: return std::make_unique(); case DebugDumpAll: 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 @@ -82,6 +82,7 @@ ! 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-pft Dump the pre-fir parse tree ! 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/test/Driver/dump-pft.f90 b/flang/test/Driver/dump-pft.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Driver/dump-pft.f90 @@ -0,0 +1,32 @@ +!------------- +! RUN COMMANDS +!------------- +! RUN: %flang_fc1 -fdebug-dump-parse-tree %s 2>&1 | FileCheck %s --check-prefix=PARSE_TREE +! RUN: %flang_fc1 -fdebug-dump-pft %s 2>&1 | FileCheck %s --check-prefix=PFT +! RUN: bbc -pft-test %s 2>&1 | FileCheck %s --check-prefix=PFT + +!----------------- +! EXPECTEED OUTPUT +!----------------- +! PFT: 1 Subroutine test_routine: subroutine test_routine(a, b, n) +! PFT-NEXT: 1 EndSubroutineStmt: end subroutine +! PRF-NEXT: End Subroutine test_routine +! PFT-NO: Program -> ProgramUnit -> SubroutineSubprogram + +! PARSE_TREE: Program -> ProgramUnit -> SubroutineSubprogram +! PARSE_TREE-NEXT: | SubroutineStmt +! PARSE_TREE-NEXT: | | Name = 'test_routine' +! PARSE_TREE-NEXT: | | DummyArg -> Name = 'a' +! PARSE_TREE-NEXT: | | DummyArg -> Name = 'b' +! PARSE_TREE-NEXT: | | DummyArg -> Name = 'n' +! PARSE_TREE-NEXT: | SpecificationPart +! PARSE_TREE-NEXT: | | ImplicitPart -> +! PARSE_TREE-NEXT: | ExecutionPart -> Block +! PARSE_TREE-NEXT: | EndSubroutineStmt -> +! PARSE_TREE-NO: Subroutine test_routine: subroutine test_routine(a, b, n) + +!------- +! INPUT +!------- +subroutine test_routine(a, b, n) +end subroutine