Author: Faris Rehman Date: 2021-02-18T11:33:24Z New Revision: 4bd08dab5ff99d094513f4adf4bf16bbce8f5a1f
URL: https://github.com/llvm/llvm-project/commit/4bd08dab5ff99d094513f4adf4bf16bbce8f5a1f DIFF: https://github.com/llvm/llvm-project/commit/4bd08dab5ff99d094513f4adf4bf16bbce8f5a1f.diff LOG: [flang][driver] Add debug dump options Add the following options: * -fdebug-dump-symbols * -fdebug-dump-parse-tree * -fdebug-dump-provenance Summary of changes: - Add 3 new frontend actions: DebugDumpSymbolsAction, DebugDumpParseTreeAction and DebugDumpProvenanceAction - Add a unique pointer to the Semantics instance created in PrescanAndSemaAction - Move fatal semantic error reporting to its own method, FrontendActions#reportFatalSemanticErrors - Port most tests using `-fdebug-dump-symbols` and `-fdebug-dump-parse-tree` to the new driver if built, otherwise default to f18 Differential Revision: https://reviews.llvm.org/D96716 Added: flang/test/Flang-Driver/debug-provenance.f90 Modified: clang/include/clang/Driver/Options.td flang/include/flang/Frontend/FrontendActions.h flang/include/flang/Frontend/FrontendOptions.h flang/lib/Frontend/CompilerInvocation.cpp flang/lib/Frontend/FrontendActions.cpp flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp flang/test/Flang-Driver/driver-help.f90 flang/test/Semantics/data05.f90 flang/test/Semantics/data08.f90 flang/test/Semantics/data09.f90 flang/test/Semantics/offsets01.f90 flang/test/Semantics/offsets02.f90 flang/test/Semantics/offsets03.f90 flang/test/Semantics/resolve100.f90 flang/test/Semantics/rewrite01.f90 Removed: ################################################################################ diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 7312c1988efe..635af48cc051 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4269,6 +4269,12 @@ def fdebug_unparse : Flag<["-"], "fdebug-unparse">, Group<Action_Group>, HelpText<"Unparse and stop.">; def fdebug_unparse_with_symbols : Flag<["-"], "fdebug-unparse-with-symbols">, Group<Action_Group>, HelpText<"Unparse and stop.">; +def fdebug_dump_symbols : Flag<["-"], "fdebug-dump-symbols">, Group<Action_Group>, + HelpText<"Dump symbols after the semantic analysis">; +def fdebug_dump_parse_tree : Flag<["-"], "fdebug-dump-parse-tree">, Group<Action_Group>, + HelpText<"Dump the parse tree">; +def fdebug_dump_provenance : Flag<["-"], "fdebug-dump-provenance">, Group<Action_Group>, + HelpText<"Dump provenance">; } diff --git a/flang/include/flang/Frontend/FrontendActions.h b/flang/include/flang/Frontend/FrontendActions.h index 4c29d0d5a641..ebcb695cca72 100644 --- a/flang/include/flang/Frontend/FrontendActions.h +++ b/flang/include/flang/Frontend/FrontendActions.h @@ -10,6 +10,8 @@ #define LLVM_FLANG_FRONTEND_FRONTENDACTIONS_H #include "flang/Frontend/FrontendAction.h" +#include "flang/Semantics/semantics.h" +#include <memory> namespace Fortran::frontend { @@ -37,12 +39,26 @@ class PrintPreprocessedAction : public PrescanAction { void ExecuteAction() override; }; +class DebugDumpProvenanceAction : public PrescanAction { + void ExecuteAction() override; +}; + //===----------------------------------------------------------------------===// // PrescanAndSema Actions //===----------------------------------------------------------------------===// class PrescanAndSemaAction : public FrontendAction { + std::unique_ptr<Fortran::semantics::Semantics> semantics_; + void ExecuteAction() override = 0; bool BeginSourceFileAction(CompilerInstance &ci) override; + +public: + Fortran::semantics::Semantics &semantics() { return *semantics_; } + const Fortran::semantics::Semantics &semantics() const { return *semantics_; } + + void setSemantics(std::unique_ptr<Fortran::semantics::Semantics> semantics) { + semantics_ = std::move(semantics); + } }; class DebugUnparseWithSymbolsAction : public PrescanAndSemaAction { @@ -53,6 +69,14 @@ class DebugUnparseAction : public PrescanAndSemaAction { void ExecuteAction() override; }; +class DebugDumpSymbolsAction : public PrescanAndSemaAction { + void ExecuteAction() override; +}; + +class DebugDumpParseTreeAction : public PrescanAndSemaAction { + void ExecuteAction() override; +}; + class ParseSyntaxOnlyAction : public PrescanAndSemaAction { void ExecuteAction() override; }; diff --git a/flang/include/flang/Frontend/FrontendOptions.h b/flang/include/flang/Frontend/FrontendOptions.h index bcf59289d01d..a26e1e3d84c7 100644 --- a/flang/include/flang/Frontend/FrontendOptions.h +++ b/flang/include/flang/Frontend/FrontendOptions.h @@ -41,6 +41,15 @@ enum ActionKind { /// Fortran source file DebugUnparseWithSymbols, + /// Parse, run semantics and then output symbols from semantics + DebugDumpSymbols, + + /// Parse, run semantics and then output the parse tree + DebugDumpParseTree, + + /// Dump provenance + DebugDumpProvenance + /// TODO: RunPreprocessor, EmitLLVM, EmitLLVMOnly, /// EmitCodeGenOnly, EmitAssembly, (...) }; diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index cd104d36fc22..ecc0fda4546b 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -116,6 +116,15 @@ static InputKind ParseFrontendArgs(FrontendOptions &opts, case clang::driver::options::OPT_fdebug_unparse_with_symbols: opts.programAction_ = DebugUnparseWithSymbols; break; + case clang::driver::options::OPT_fdebug_dump_symbols: + opts.programAction_ = DebugDumpSymbols; + break; + case clang::driver::options::OPT_fdebug_dump_parse_tree: + opts.programAction_ = DebugDumpParseTree; + break; + case clang::driver::options::OPT_fdebug_dump_provenance: + opts.programAction_ = DebugDumpProvenance; + break; // TODO: // case calng::driver::options::OPT_emit_llvm: diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index dc9da4eb7ba2..91e19a701db9 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -10,15 +10,28 @@ #include "flang/Common/default-kinds.h" #include "flang/Frontend/CompilerInstance.h" #include "flang/Frontend/FrontendOptions.h" +#include "flang/Parser/dump-parse-tree.h" #include "flang/Parser/parsing.h" #include "flang/Parser/provenance.h" #include "flang/Parser/source.h" #include "flang/Parser/unparse.h" #include "flang/Semantics/semantics.h" #include "flang/Semantics/unparse-with-symbols.h" +#include "llvm/ADT/StringRef.h" +#include <clang/Basic/Diagnostic.h> +#include <memory> using namespace Fortran::frontend; +void reportFatalSemanticErrors(const Fortran::semantics::Semantics &semantics, + clang::DiagnosticsEngine &diags, const llvm::StringRef &bufferName) { + if (semantics.AnyFatalError()) { + unsigned DiagID = diags.getCustomDiagID( + clang::DiagnosticsEngine::Error, "Semantic errors in %0"); + diags.Report(DiagID) << bufferName; + } +} + bool PrescanAction::BeginSourceFileAction(CompilerInstance &c1) { CompilerInstance &ci = this->instance(); @@ -101,23 +114,16 @@ bool PrescanAndSemaAction::BeginSourceFileAction(CompilerInstance &c1) { auto &parseTree{*ci.parsing().parseTree()}; // Prepare semantics - Fortran::semantics::Semantics semantics{ci.invocation().semanticsContext(), - parseTree, ci.parsing().cooked().AsCharBlock()}; + setSemantics(std::make_unique<Fortran::semantics::Semantics>( + ci.invocation().semanticsContext(), parseTree, + ci.parsing().cooked().AsCharBlock())); + auto &semantics = this->semantics(); // Run semantic checks semantics.Perform(); // Report the diagnostics from the semantic checks semantics.EmitMessages(ci.semaOutputStream()); - - if (semantics.AnyFatalError()) { - unsigned DiagID = ci.diagnostics().getCustomDiagID( - clang::DiagnosticsEngine::Error, "Semantic errors in %0"); - ci.diagnostics().Report(DiagID) << GetCurrentFileOrBufferName(); - - return false; - } - return true; } @@ -183,7 +189,14 @@ void PrintPreprocessedAction::ExecuteAction() { } } -void ParseSyntaxOnlyAction::ExecuteAction() {} +void DebugDumpProvenanceAction::ExecuteAction() { + this->instance().parsing().DumpProvenance(llvm::outs()); +} + +void ParseSyntaxOnlyAction::ExecuteAction() { + reportFatalSemanticErrors(semantics(), this->instance().diagnostics(), + GetCurrentFileOrBufferName()); +} void DebugUnparseAction::ExecuteAction() { auto &parseTree{instance().parsing().parseTree()}; @@ -195,6 +208,10 @@ void DebugUnparseAction::ExecuteAction() { /*encoding=*/Fortran::parser::Encoding::UTF_8, /*capitalizeKeywords=*/true, /*backslashEscapes=*/false, /*preStatement=*/nullptr, &asFortran); + + // Report fatal semantic errors + reportFatalSemanticErrors(semantics(), this->instance().diagnostics(), + GetCurrentFileOrBufferName()); } void DebugUnparseWithSymbolsAction::ExecuteAction() { @@ -202,6 +219,32 @@ void DebugUnparseWithSymbolsAction::ExecuteAction() { Fortran::semantics::UnparseWithSymbols( llvm::outs(), parseTree, /*encoding=*/Fortran::parser::Encoding::UTF_8); + + // Report fatal semantic errors + reportFatalSemanticErrors(semantics(), this->instance().diagnostics(), + GetCurrentFileOrBufferName()); +} + +void DebugDumpSymbolsAction::ExecuteAction() { + auto &semantics = this->semantics(); + + // Dump symbols + semantics.DumpSymbols(llvm::outs()); + // Report fatal semantic errors + reportFatalSemanticErrors( + semantics, this->instance().diagnostics(), GetCurrentFileOrBufferName()); +} + +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); + // Report fatal semantic errors + reportFatalSemanticErrors(semantics(), this->instance().diagnostics(), + GetCurrentFileOrBufferName()); } void EmitObjAction::ExecuteAction() { diff --git a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp index 12f538c929fd..aec968baf78d 100644 --- a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -43,6 +43,15 @@ static std::unique_ptr<FrontendAction> CreateFrontendBaseAction( case DebugUnparseWithSymbols: return std::make_unique<DebugUnparseWithSymbolsAction>(); break; + case DebugDumpSymbols: + return std::make_unique<DebugDumpSymbolsAction>(); + break; + case DebugDumpParseTree: + return std::make_unique<DebugDumpParseTreeAction>(); + break; + case DebugDumpProvenance: + return std::make_unique<DebugDumpProvenanceAction>(); + break; default: break; // TODO: diff --git a/flang/test/Flang-Driver/debug-provenance.f90 b/flang/test/Flang-Driver/debug-provenance.f90 new file mode 100644 index 000000000000..1d1d5cac3e70 --- /dev/null +++ b/flang/test/Flang-Driver/debug-provenance.f90 @@ -0,0 +1,26 @@ +! Ensure argument -fdebug-dump-provenance works as expected. + +! REQUIRES: new-flang-driver + +!-------------------------- +! FLANG DRIVER (flang-new) +!-------------------------- +! RUN: not %flang-new -fdebug-dump-provenance %s 2>&1 | FileCheck %s --check-prefix=FLANG + +!---------------------------------------- +! FRONTEND FLANG DRIVER (flang-new -fc1) +!---------------------------------------- +! RUN: %flang-new -fc1 -fdebug-dump-provenance %s 2>&1 | FileCheck %s --check-prefix=FRONTEND + +!---------------------------------- +! EXPECTED OUTPUT WITH `flang-new` +!---------------------------------- +! FLANG:warning: argument unused during compilation: '-fdebug-dump-provenance' + +!--------------------------------------- +! EXPECTED OUTPUT WITH `flang-new -fc1` +!--------------------------------------- +! FRONTEND:AllSources: +! FRONTEND:CookedSource::provenanceMap_: +program A +end diff --git a/flang/test/Flang-Driver/driver-help.f90 b/flang/test/Flang-Driver/driver-help.f90 index 881bd3770ee2..fd053313b8b7 100644 --- a/flang/test/Flang-Driver/driver-help.f90 +++ b/flang/test/Flang-Driver/driver-help.f90 @@ -56,6 +56,9 @@ ! 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-parse-tree Dump the 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-unparse-with-symbols ! HELP-FC1-NEXT: Unparse and stop. ! HELP-FC1-NEXT: -fdebug-unparse Unparse and stop. diff --git a/flang/test/Semantics/data05.f90 b/flang/test/Semantics/data05.f90 index 31d68b33a060..8e059c2c0652 100644 --- a/flang/test/Semantics/data05.f90 +++ b/flang/test/Semantics/data05.f90 @@ -1,4 +1,4 @@ -!RUN: %f18 -fdebug-dump-symbols %s | FileCheck %s +!RUN: %flang_fc1 -fdebug-dump-symbols %s | FileCheck %s module m interface integer function ifunc(n) diff --git a/flang/test/Semantics/data08.f90 b/flang/test/Semantics/data08.f90 index e9f53c147ae9..be56c7efa7ea 100644 --- a/flang/test/Semantics/data08.f90 +++ b/flang/test/Semantics/data08.f90 @@ -1,4 +1,4 @@ -! RUN: %f18 -fdebug-dump-symbols %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -fdebug-dump-symbols %s 2>&1 | FileCheck %s ! CHECK: DATA statement value initializes 'jx' of type 'INTEGER(4)' with CHARACTER ! CHECK: DATA statement value initializes 'jy' of type 'INTEGER(4)' with CHARACTER ! CHECK: DATA statement value initializes 'jz' of type 'INTEGER(4)' with CHARACTER diff --git a/flang/test/Semantics/data09.f90 b/flang/test/Semantics/data09.f90 index 4510b830ef7f..a6f5865399d5 100644 --- a/flang/test/Semantics/data09.f90 +++ b/flang/test/Semantics/data09.f90 @@ -1,4 +1,4 @@ -! RUN: %f18 -fsyntax-only -fdebug-dump-symbols %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -fsyntax-only -fdebug-dump-symbols %s 2>&1 | FileCheck %s ! CHECK: init:[INTEGER(4)::1065353216_4,1073741824_4,1077936128_4,1082130432_4] ! Verify that the closure of EQUIVALENCE'd symbols with any DATA ! initialization produces a combined initializer. diff --git a/flang/test/Semantics/offsets01.f90 b/flang/test/Semantics/offsets01.f90 index 394f6a7461f7..50974876e8d9 100644 --- a/flang/test/Semantics/offsets01.f90 +++ b/flang/test/Semantics/offsets01.f90 @@ -1,4 +1,4 @@ -!RUN: %f18 -fdebug-dump-symbols %s | FileCheck %s +!RUN: %flang_fc1 -fdebug-dump-symbols %s | FileCheck %s ! Size and alignment of intrinsic types subroutine s1 diff --git a/flang/test/Semantics/offsets02.f90 b/flang/test/Semantics/offsets02.f90 index 99a156e3c288..c7b21aede00a 100644 --- a/flang/test/Semantics/offsets02.f90 +++ b/flang/test/Semantics/offsets02.f90 @@ -1,4 +1,4 @@ -!RUN: %f18 -fdebug-dump-symbols %s | FileCheck %s +!RUN: %flang_fc1 -fdebug-dump-symbols %s | FileCheck %s ! Size and alignment of derived types diff --git a/flang/test/Semantics/offsets03.f90 b/flang/test/Semantics/offsets03.f90 index f578cb7e19c3..1a308217ee9c 100644 --- a/flang/test/Semantics/offsets03.f90 +++ b/flang/test/Semantics/offsets03.f90 @@ -1,4 +1,4 @@ -!RUN: %f18 -fdebug-dump-symbols %s | FileCheck %s +!RUN: %flang_fc1 -fdebug-dump-symbols %s | FileCheck %s ! Size and alignment with EQUIVALENCE and COMMON diff --git a/flang/test/Semantics/resolve100.f90 b/flang/test/Semantics/resolve100.f90 index 98d67d99e73f..d862d13a9feb 100644 --- a/flang/test/Semantics/resolve100.f90 +++ b/flang/test/Semantics/resolve100.f90 @@ -1,4 +1,4 @@ -!RUN: %f18 -fdebug-dump-symbols %s | FileCheck %s +!RUN: %flang_fc1 -fdebug-dump-symbols %s | FileCheck %s program p ! CHECK: a size=4 offset=0: ObjectEntity type: LOGICAL(4) diff --git a/flang/test/Semantics/rewrite01.f90 b/flang/test/Semantics/rewrite01.f90 index a189d4417f5d..3f9198fc449b 100644 --- a/flang/test/Semantics/rewrite01.f90 +++ b/flang/test/Semantics/rewrite01.f90 @@ -1,4 +1,4 @@ -! RUN: %f18 -fdebug-dump-parse-tree %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -fdebug-dump-parse-tree %s 2>&1 | FileCheck %s ! Ensure that READ(CVAR) [, item-list] is corrected when CVAR is a ! character variable so as to be a formatted read from the default ! unit, not an unformatted read from an internal unit (which is not _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits