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 @@ -45,6 +45,30 @@ return false; } +template +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()}; @@ -53,18 +77,7 @@ // Prescan. In case of failure, report and return. ci.parsing().Prescan(currentInputPath, parserOptions); - if (!ci.parsing().messages().empty() && - (ci.invocation().warnAsErr() || - ci.parsing().messages().AnyFatalError())) { - const unsigned diagID = ci.diagnostics().getCustomDiagID( - clang::DiagnosticsEngine::Error, "Could not scan %0"); - ci.diagnostics().Report(diagID) << GetCurrentFileOrBufferName(); - ci.parsing().messages().Emit(llvm::errs(), ci.allCookedSources()); - - return false; - } - - return true; + return !reportFatalScanningErrors(this); } bool PrescanAndParseAction::BeginSourceFileAction(CompilerInstance &c1) { @@ -88,27 +101,14 @@ // Prescan. In case of failure, report and return. ci.parsing().Prescan(currentInputPath, parserOptions); - if (ci.parsing().messages().AnyFatalError()) { - const unsigned diagID = ci.diagnostics().getCustomDiagID( - clang::DiagnosticsEngine::Error, "Could not scan %0"); - ci.diagnostics().Report(diagID) << GetCurrentFileOrBufferName(); - ci.parsing().messages().Emit(llvm::errs(), ci.allCookedSources()); - + if (reportFatalScanningErrors(this)) return false; - } // Parse. In case of failure, report and return. ci.parsing().Parse(llvm::outs()); - if (ci.parsing().messages().AnyFatalError()) { - unsigned diagID = ci.diagnostics().getCustomDiagID( - clang::DiagnosticsEngine::Error, "Could not parse %0"); - ci.diagnostics().Report(diagID) << GetCurrentFileOrBufferName(); - - ci.parsing().messages().Emit( - llvm::errs(), this->instance().allCookedSources()); + if (reportFatalParsingErrors(this)) return false; - } // Report the diagnostics from parsing ci.parsing().messages().Emit(llvm::errs(), ci.allCookedSources()); @@ -124,31 +124,14 @@ // Prescan. In case of failure, report and return. ci.parsing().Prescan(currentInputPath, parserOptions); - if (!ci.parsing().messages().empty() && - (ci.invocation().warnAsErr() || - ci.parsing().messages().AnyFatalError())) { - const unsigned diagID = ci.diagnostics().getCustomDiagID( - clang::DiagnosticsEngine::Error, "Could not scan %0"); - ci.diagnostics().Report(diagID) << GetCurrentFileOrBufferName(); - ci.parsing().messages().Emit(llvm::errs(), ci.allCookedSources()); - + if (reportFatalScanningErrors(this)) return false; - } // Parse. In case of failure, report and return. ci.parsing().Parse(llvm::outs()); - if (!ci.parsing().messages().empty() && - (ci.invocation().warnAsErr() || - ci.parsing().messages().AnyFatalError())) { - unsigned diagID = ci.diagnostics().getCustomDiagID( - clang::DiagnosticsEngine::Error, "Could not parse %0"); - ci.diagnostics().Report(diagID) << GetCurrentFileOrBufferName(); - - ci.parsing().messages().Emit( - llvm::errs(), this->instance().allCookedSources()); + if (reportFatalParsingErrors(this)) return false; - } // Report the diagnostics from parsing ci.parsing().messages().Emit(llvm::errs(), ci.allCookedSources()); diff --git a/flang/test/Driver/parse-error.f95 b/flang/test/Driver/parse-error.f95 --- a/flang/test/Driver/parse-error.f95 +++ b/flang/test/Driver/parse-error.f95 @@ -1,5 +1,9 @@ ! Verify that parsing errors are correctly reported by the driver +! Focuses on actions inheriting from the following: +! * PrescanAndSemaAction (-fsyntax-only) +! * PrescanAndParseAction (-fdebug-unparse-no-sema) +! RUN: not %flang_fc1 -fdebug-unparse-no-sema %s 2>&1 | FileCheck %s --check-prefix=ERROR ! RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix=ERROR ! ERROR: Could not parse {{.*}}parse-error.f95