[flang-commits] [flang] 4f21e6a - [flang][nfc] Tweak the FrontendAction class
Andrzej Warzynski via flang-commits
flang-commits at lists.llvm.org
Tue Aug 17 00:53:05 PDT 2021
Author: Andrzej Warzynski
Date: 2021-08-17T07:36:44Z
New Revision: 4f21e6aeddc2dbe4ae22aba5b97cae0c50c961f6
URL: https://github.com/llvm/llvm-project/commit/4f21e6aeddc2dbe4ae22aba5b97cae0c50c961f6
DIFF: https://github.com/llvm/llvm-project/commit/4f21e6aeddc2dbe4ae22aba5b97cae0c50c961f6.diff
LOG: [flang][nfc] Tweak the FrontendAction class
This patch refactors the `FrontendAction` class. It merely moves code
around so that re-using it is easier. No new functionality is
introduced.
1. Three new member methods are introduced: `RunPrescan`, `RunParse`,
`RunSemanticChecks`.
2. The following free functions are re-implemented as member methods:
* `reportFatalSemanticErrors`
* `reportFatalScanningErrors`
* `reportFatalParsingErrors`
* `reportFatalErrors`
`reportFatalSemanticErrors` is updated to resemble the other error
reporting functions and to make the API more consistent.
3. The `BeginSourceFileAction` methods are simplified and the unused
input argument is deleted.
Differential Revision: https://reviews.llvm.org/D108130
Added:
Modified:
flang/include/flang/Frontend/FrontendAction.h
flang/include/flang/Frontend/FrontendActions.h
flang/lib/Frontend/FrontendAction.cpp
flang/lib/Frontend/FrontendActions.cpp
Removed:
################################################################################
diff --git a/flang/include/flang/Frontend/FrontendAction.h b/flang/include/flang/Frontend/FrontendAction.h
index 87e82fe5274f5..aac1fcf268a08 100644
--- a/flang/include/flang/Frontend/FrontendAction.h
+++ b/flang/include/flang/Frontend/FrontendAction.h
@@ -43,7 +43,7 @@ class FrontendAction {
///
/// \return True on success; on failure ExecutionAction() and
/// EndSourceFileAction() will not be called.
- virtual bool BeginSourceFileAction(CompilerInstance &ci) { return true; }
+ virtual bool BeginSourceFileAction() { return true; }
/// @}
@@ -100,6 +100,34 @@ class FrontendAction {
/// Perform any per-file post processing, deallocate per-file
/// objects, and run statistics and output file cleanup code.
void EndSourceFile();
+
+ /// @}
+protected:
+ // Prescan the current input file. Return False if fatal errors are reported,
+ // True otherwise.
+ bool RunPrescan();
+ // Parse the current input file. Return False if fatal errors are reported,
+ // True otherwise.
+ bool RunParse();
+ // Run semantic checks for the current input file. Return False if fatal
+ // errors are reported, True otherwise.
+ bool RunSemanticChecks();
+
+ // Report fatal semantic errors. Return True if present, false otherwise.
+ bool reportFatalSemanticErrors();
+
+ // Report fatal scanning errors. Return True if present, false otherwise.
+ inline bool reportFatalScanningErrors() {
+ return reportFatalErrors("Could not scan %0");
+ }
+
+ // Report fatal parsing errors. Return True if present, false otherwise
+ inline bool reportFatalParsingErrors() {
+ return reportFatalErrors("Could not parse %0");
+ }
+
+private:
+ template <unsigned N> bool reportFatalErrors(const char (&message)[N]);
};
} // namespace Fortran::frontend
diff --git a/flang/include/flang/Frontend/FrontendActions.h b/flang/include/flang/Frontend/FrontendActions.h
index 9cfaabcf7677e..43fd1f0f65965 100644
--- a/flang/include/flang/Frontend/FrontendActions.h
+++ b/flang/include/flang/Frontend/FrontendActions.h
@@ -51,7 +51,7 @@ class InitOnlyAction : public FrontendAction {
//===----------------------------------------------------------------------===//
class PrescanAction : public FrontendAction {
void ExecuteAction() override = 0;
- bool BeginSourceFileAction(CompilerInstance &ci) override;
+ bool BeginSourceFileAction() override;
};
class PrintPreprocessedAction : public PrescanAction {
@@ -75,7 +75,7 @@ class DebugMeasureParseTreeAction : public PrescanAction {
//===----------------------------------------------------------------------===//
class PrescanAndParseAction : public FrontendAction {
void ExecuteAction() override = 0;
- bool BeginSourceFileAction(CompilerInstance &ci) override;
+ bool BeginSourceFileAction() override;
};
class DebugUnparseNoSemaAction : public PrescanAndParseAction {
@@ -92,7 +92,7 @@ class DebugDumpParseTreeNoSemaAction : public PrescanAndParseAction {
class PrescanAndSemaAction : public FrontendAction {
void ExecuteAction() override = 0;
- bool BeginSourceFileAction(CompilerInstance &ci) override;
+ bool BeginSourceFileAction() override;
};
class DebugUnparseWithSymbolsAction : public PrescanAndSemaAction {
diff --git a/flang/lib/Frontend/FrontendAction.cpp b/flang/lib/Frontend/FrontendAction.cpp
index 77700d2abec78..5285681e2904a 100644
--- a/flang/lib/Frontend/FrontendAction.cpp
+++ b/flang/lib/Frontend/FrontendAction.cpp
@@ -89,7 +89,7 @@ bool FrontendAction::BeginSourceFile(
invoc.fortranOpts().isFixedForm = currentInput().IsFixedForm();
}
- if (!BeginSourceFileAction(ci)) {
+ if (!BeginSourceFileAction()) {
BeginSourceFileCleanUp(*this, ci);
return false;
}
@@ -117,3 +117,96 @@ void FrontendAction::EndSourceFile() {
set_instance(nullptr);
set_currentInput(FrontendInputFile());
}
+
+bool FrontendAction::RunPrescan() {
+ CompilerInstance &ci = this->instance();
+ std::string currentInputPath{GetCurrentFileOrBufferName()};
+ Fortran::parser::Options parserOptions = ci.invocation().fortranOpts();
+
+ if (ci.invocation().frontendOpts().fortranForm == FortranForm::Unknown) {
+ // Switch between fixed and free form format based on the input file
+ // extension.
+ //
+ // Ideally we should have all Fortran options set before entering this
+ // method (i.e. before processing any specific input files). However, we
+ // can't decide between fixed and free form based on the file extension
+ // earlier than this.
+ parserOptions.isFixedForm = currentInput().IsFixedForm();
+ }
+
+ // Prescan. In case of failure, report and return.
+ ci.parsing().Prescan(currentInputPath, parserOptions);
+
+ return !reportFatalScanningErrors();
+}
+
+bool FrontendAction::RunParse() {
+ CompilerInstance &ci = this->instance();
+
+ // Parse. In case of failure, report and return.
+ ci.parsing().Parse(llvm::outs());
+
+ if (reportFatalParsingErrors()) {
+ return false;
+ }
+
+ // Report the diagnostics from parsing
+ ci.parsing().messages().Emit(llvm::errs(), ci.allCookedSources());
+
+ return true;
+}
+
+bool FrontendAction::RunSemanticChecks() {
+ CompilerInstance &ci = this->instance();
+ std::optional<parser::Program> &parseTree{ci.parsing().parseTree()};
+ assert(parseTree && "Cannot run semantic checks without a parse tree!");
+
+ // Prepare semantics
+ ci.setSemantics(std::make_unique<Fortran::semantics::Semantics>(
+ ci.invocation().semanticsContext(), *parseTree,
+ ci.invocation().debugModuleDir()));
+ auto &semantics = ci.semantics();
+
+ // Run semantic checks
+ semantics.Perform();
+
+ if (reportFatalSemanticErrors()) {
+ return false;
+ }
+
+ // Report the diagnostics from the semantic checks
+ semantics.EmitMessages(ci.semaOutputStream());
+
+ return true;
+}
+
+template <unsigned N>
+bool FrontendAction::reportFatalErrors(const char (&message)[N]) {
+ if (!instance_->parsing().messages().empty() &&
+ (instance_->invocation().warnAsErr() ||
+ instance_->parsing().messages().AnyFatalError())) {
+ const unsigned diagID = instance_->diagnostics().getCustomDiagID(
+ clang::DiagnosticsEngine::Error, message);
+ instance_->diagnostics().Report(diagID) << GetCurrentFileOrBufferName();
+ instance_->parsing().messages().Emit(
+ llvm::errs(), instance_->allCookedSources());
+ return true;
+ }
+ return false;
+}
+
+bool FrontendAction::reportFatalSemanticErrors() {
+ auto &diags = instance_->diagnostics();
+ auto &sema = instance_->semantics();
+
+ if (instance_->semantics().AnyFatalError()) {
+ unsigned DiagID = diags.getCustomDiagID(
+ clang::DiagnosticsEngine::Error, "Semantic errors in %0");
+ diags.Report(DiagID) << GetCurrentFileOrBufferName();
+ sema.EmitMessages(instance_->semaOutputStream());
+
+ return true;
+ }
+
+ return false;
+}
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index acd6b049dfe8d..f5ff2095281cd 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -27,132 +27,22 @@
using namespace Fortran::frontend;
-/// Report fatal semantic errors if present.
-///
-/// \param semantics The semantics instance
-/// \param diags The diagnostics engine instance
-/// \param bufferName The file or buffer name
-///
-/// \return True if fatal semantic errors are present, false if not
-bool 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;
- return true;
- }
- return false;
-}
-
-template <unsigned N>
-static bool reportFatalErrors(
- const FrontendAction *act, const char (&message)[N]) {
- CompilerInstance &ci = act->instance();
- if (!ci.parsing().messages().empty() &&
- (ci.invocation().warnAsErr() ||
- ci.parsing().messages().AnyFatalError())) {
- const unsigned diagID = ci.diagnostics().getCustomDiagID(
- clang::DiagnosticsEngine::Error, message);
- ci.diagnostics().Report(diagID) << act->GetCurrentFileOrBufferName();
- ci.parsing().messages().Emit(llvm::errs(), ci.allCookedSources());
- return true;
- }
- return false;
-}
-
-inline bool reportFatalScanningErrors(const FrontendAction *act) {
- return reportFatalErrors(act, "Could not scan %0");
-}
-
-inline bool reportFatalParsingErrors(const FrontendAction *act) {
- return reportFatalErrors(act, "Could not parse %0");
-}
-
-bool PrescanAction::BeginSourceFileAction(CompilerInstance &c1) {
- CompilerInstance &ci = this->instance();
- std::string currentInputPath{GetCurrentFileOrBufferName()};
- Fortran::parser::Options parserOptions = ci.invocation().fortranOpts();
-
- // Prescan. In case of failure, report and return.
- ci.parsing().Prescan(currentInputPath, parserOptions);
-
- return !reportFatalScanningErrors(this);
-}
-
-bool PrescanAndParseAction::BeginSourceFileAction(CompilerInstance &c1) {
- CompilerInstance &ci = this->instance();
-
- std::string currentInputPath{GetCurrentFileOrBufferName()};
-
- Fortran::parser::Options parserOptions = ci.invocation().fortranOpts();
-
- if (ci.invocation().frontendOpts().fortranForm == FortranForm::Unknown) {
- // Switch between fixed and free form format based on the input file
- // extension.
- //
- // Ideally we should have all Fortran options set before entering this
- // method (i.e. before processing any specific input files). However, we
- // can't decide between fixed and free form based on the file extension
- // earlier than this.
- parserOptions.isFixedForm = currentInput().IsFixedForm();
- }
-
- // Prescan. In case of failure, report and return.
- ci.parsing().Prescan(currentInputPath, parserOptions);
-
- if (reportFatalScanningErrors(this))
- return false;
-
- // Parse. In case of failure, report and return.
- ci.parsing().Parse(llvm::outs());
-
- if (reportFatalParsingErrors(this))
- return false;
-
- // Report the diagnostics from parsing
- ci.parsing().messages().Emit(llvm::errs(), ci.allCookedSources());
+//===----------------------------------------------------------------------===//
+// Custom BeginSourceFileAction
+//===----------------------------------------------------------------------===//
+bool PrescanAction::BeginSourceFileAction() { return RunPrescan(); }
- return true;
+bool PrescanAndParseAction::BeginSourceFileAction() {
+ return RunPrescan() && RunParse();
}
-bool PrescanAndSemaAction::BeginSourceFileAction(CompilerInstance &c1) {
- CompilerInstance &ci = this->instance();
- std::string currentInputPath{GetCurrentFileOrBufferName()};
- Fortran::parser::Options parserOptions = ci.invocation().fortranOpts();
-
- // Prescan. In case of failure, report and return.
- ci.parsing().Prescan(currentInputPath, parserOptions);
-
- if (reportFatalScanningErrors(this))
- return false;
-
- // Parse. In case of failure, report and return.
- ci.parsing().Parse(llvm::outs());
-
- if (reportFatalParsingErrors(this))
- return false;
-
- // Report the diagnostics from parsing
- ci.parsing().messages().Emit(llvm::errs(), ci.allCookedSources());
-
- auto &parseTree{*ci.parsing().parseTree()};
-
- // Prepare semantics
- ci.setSemantics(std::make_unique<Fortran::semantics::Semantics>(
- ci.invocation().semanticsContext(), parseTree,
- ci.invocation().debugModuleDir()));
- auto &semantics = ci.semantics();
-
- // Run semantic checks
- semantics.Perform();
-
- // Report the diagnostics from the semantic checks
- semantics.EmitMessages(ci.semaOutputStream());
-
- return true;
+bool PrescanAndSemaAction::BeginSourceFileAction() {
+ return RunPrescan() & RunParse() && RunSemanticChecks();
}
+//===----------------------------------------------------------------------===//
+// Custom ExecuteAction
+//===----------------------------------------------------------------------===//
void InputOutputTestAction::ExecuteAction() {
CompilerInstance &ci = instance();
@@ -224,10 +114,6 @@ void DebugDumpProvenanceAction::ExecuteAction() {
}
void ParseSyntaxOnlyAction::ExecuteAction() {
- CompilerInstance &ci = this->instance();
-
- reportFatalSemanticErrors(
- ci.semantics(), ci.diagnostics(), GetCurrentFileOrBufferName());
}
void DebugUnparseNoSemaAction::ExecuteAction() {
@@ -258,20 +144,17 @@ void DebugUnparseAction::ExecuteAction() {
invoc.useAnalyzedObjectsForUnparse() ? &invoc.asFortran() : nullptr);
// Report fatal semantic errors
- reportFatalSemanticErrors(ci.semantics(), this->instance().diagnostics(),
- GetCurrentFileOrBufferName());
+ reportFatalSemanticErrors();
}
void DebugUnparseWithSymbolsAction::ExecuteAction() {
- CompilerInstance &ci = this->instance();
auto &parseTree{*instance().parsing().parseTree()};
Fortran::semantics::UnparseWithSymbols(
llvm::outs(), parseTree, /*encoding=*/Fortran::parser::Encoding::UTF_8);
// Report fatal semantic errors
- reportFatalSemanticErrors(
- ci.semantics(), ci.diagnostics(), GetCurrentFileOrBufferName());
+ reportFatalSemanticErrors();
}
void DebugDumpSymbolsAction::ExecuteAction() {
@@ -283,8 +166,7 @@ void DebugDumpSymbolsAction::ExecuteAction() {
// 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());
+ reportFatalSemanticErrors();
if (!tables.schemata) {
unsigned DiagID =
@@ -315,8 +197,7 @@ void DebugDumpAllAction::ExecuteAction() {
// 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());
+ reportFatalSemanticErrors();
if (!tables.schemata) {
unsigned DiagID =
@@ -342,7 +223,6 @@ void DebugDumpParseTreeNoSemaAction::ExecuteAction() {
}
void DebugDumpParseTreeAction::ExecuteAction() {
- CompilerInstance &ci = this->instance();
auto &parseTree{instance().parsing().parseTree()};
// Dump parse tree
@@ -350,8 +230,7 @@ void DebugDumpParseTreeAction::ExecuteAction() {
llvm::outs(), parseTree, &this->instance().invocation().asFortran());
// Report fatal semantic errors
- reportFatalSemanticErrors(
- ci.semantics(), ci.diagnostics(), GetCurrentFileOrBufferName());
+ reportFatalSemanticErrors();
}
void DebugMeasureParseTreeAction::ExecuteAction() {
@@ -388,8 +267,7 @@ void DebugMeasureParseTreeAction::ExecuteAction() {
void DebugPreFIRTreeAction::ExecuteAction() {
CompilerInstance &ci = this->instance();
// Report and exit if fatal semantic errors are present
- if (reportFatalSemanticErrors(
- ci.semantics(), ci.diagnostics(), GetCurrentFileOrBufferName())) {
+ if (reportFatalSemanticErrors()) {
return;
}
@@ -417,9 +295,9 @@ void GetDefinitionAction::ExecuteAction() {
CompilerInstance &ci = this->instance();
// Report and exit if fatal semantic errors are present
- if (reportFatalSemanticErrors(
- ci.semantics(), ci.diagnostics(), GetCurrentFileOrBufferName()))
+ if (reportFatalSemanticErrors()) {
return;
+ }
parser::AllCookedSources &cs = ci.allCookedSources();
unsigned diagID = ci.diagnostics().getCustomDiagID(
@@ -465,9 +343,9 @@ void GetSymbolsSourcesAction::ExecuteAction() {
CompilerInstance &ci = this->instance();
// Report and exit if fatal semantic errors are present
- if (reportFatalSemanticErrors(
- ci.semantics(), ci.diagnostics(), GetCurrentFileOrBufferName()))
+ if (reportFatalSemanticErrors()) {
return;
+ }
ci.semantics().DumpSymbolsSources(llvm::outs());
}
More information about the flang-commits
mailing list