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 @@ -4523,6 +4523,8 @@ HelpText<"Dump the parse tree (skips the semantic checks)">, DocBrief<[{Run the Parser and then output the parse tree. Semantic checks are disabled.}]>; +def fdebug_dump_all : Flag<["-"], "fdebug-dump-all">, Group, + HelpText<"Dump symbols and the parse tree after the semantic checks">; def fdebug_dump_provenance : Flag<["-"], "fdebug-dump-provenance">, Group, HelpText<"Dump provenance">; def fdebug_dump_parsing_log : Flag<["-"], "fdebug-dump-parsing-log">, 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 @@ -116,6 +116,10 @@ void ExecuteAction() override; }; +class DebugDumpAllAction : 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 @@ -51,6 +51,9 @@ /// Parse, run semantics and then output the parse tree DebugDumpParseTree, + /// Parse, run semantics and then output the parse tree and symbols + DebugDumpAll, + /// Parse and then output the parse tree, skip the semantic checks DebugDumpParseTreeNoSema, 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 @@ -141,6 +141,9 @@ case clang::driver::options::OPT_fdebug_dump_parse_tree: opts.programAction_ = DebugDumpParseTree; break; + case clang::driver::options::OPT_fdebug_dump_all: + opts.programAction_ = DebugDumpAll; + break; case clang::driver::options::OPT_fdebug_dump_parse_tree_no_sema: opts.programAction_ = DebugDumpParseTreeNoSema; 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 @@ -305,6 +305,42 @@ semantics.DumpSymbols(llvm::outs()); } +void DebugDumpAllAction::ExecuteAction() { + CompilerInstance &ci = this->instance(); + + // 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); + + auto &semantics = this->semantics(); + auto tables{Fortran::semantics::BuildRuntimeDerivedTypeTables( + instance().invocation().semanticsContext())}; + // The runtime derived type information table builder may find and report + // semantic errors. So it is important that we report them _after_ + // BuildRuntimeDerivedTypeTables is run. + reportFatalSemanticErrors( + semantics, this->instance().diagnostics(), GetCurrentFileOrBufferName()); + + if (!tables.schemata) { + unsigned DiagID = + ci.diagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error, + "could not find module file for __fortran_type_info"); + ci.diagnostics().Report(DiagID); + llvm::errs() << "\n"; + } + + // Dump symbols + llvm::outs() << "====================="; + llvm::outs() << " Flang: symbols dump "; + llvm::outs() << "=====================\n"; + semantics.DumpSymbols(llvm::outs()); +} + void DebugDumpParseTreeNoSemaAction::ExecuteAction() { auto &parseTree{instance().parsing().parseTree()}; Fortran::parser::AnalyzedObjectsAsFortran asFortran = 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 @@ -55,6 +55,9 @@ case DebugDumpParseTreeNoSema: return std::make_unique(); break; + case DebugDumpAll: + return std::make_unique(); + break; case DebugDumpProvenance: return std::make_unique(); break; 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 @@ -69,6 +69,7 @@ ! HELP-FC1-NEXT: -falternative-parameter-statement ! 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-all Dump symbols and the parse tree after the semantic checks ! HELP-FC1-NEXT: -fdebug-dump-parse-tree-no-sema ! HELP-FC1-NEXT: Dump the parse tree (skips the semantic checks) ! HELP-FC1-NEXT: -fdebug-dump-parse-tree Dump the parse tree diff --git a/flang/test/Driver/dump-all.f90 b/flang/test/Driver/dump-all.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Driver/dump-all.f90 @@ -0,0 +1,17 @@ +!---------- +! RUN lines +!---------- +! RUN: %flang_fc1 -fdebug-dump-all %s 2>&1 | FileCheck %s + +!---------------- +! EXPECTED OUTPUT +!---------------- +! CHECK: Flang: parse tree dump +! CHECK: Flang: symbols dump + +!------- +! INPUT +!------- +parameter(i=1) +integer :: j +end program