mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-06 07:16:07 +00:00

This new action encapsulates all actions that require the prescanner to be run before proceeding with other processing. By adding this new action, we are better equipped to control which actions _do_ run the prescanner and which _do not_. The following actions that require the prescanner are refactored to inherit from `PrescanAction`: * `PrintPreprocessedAction` * `ParseSyntaxOnlyAction` . New virtual method is introduced to facilitate all this: * `BeginSourceFileAction` Like in Clang, this method is run inside `BeginSourceFile`. In other words, it is invoked before `ExecuteAction` for the corresponding frontend action is run. This method allows us to: * carry out any processing that is always required by the action (e.g. run the prescanner) * fine tune the settings/options on a file-by-file basis (e.g. to decide between fixed-form and free-form based on file extension) This patch implements non-functional-changes. Reviewed By: FarisRehman Differential Revision: https://reviews.llvm.org/D95464
98 lines
3.0 KiB
C++
98 lines
3.0 KiB
C++
//===--- FrontendAction.cpp -----------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "flang/Frontend/FrontendAction.h"
|
|
#include "flang/Frontend/CompilerInstance.h"
|
|
#include "flang/Frontend/FrontendActions.h"
|
|
#include "flang/Frontend/FrontendOptions.h"
|
|
#include "flang/FrontendTool/Utils.h"
|
|
#include "clang/Basic/DiagnosticFrontend.h"
|
|
#include "llvm/Support/Errc.h"
|
|
#include "llvm/Support/VirtualFileSystem.h"
|
|
|
|
using namespace Fortran::frontend;
|
|
|
|
void FrontendAction::set_currentInput(const FrontendInputFile ¤tInput) {
|
|
this->currentInput_ = currentInput;
|
|
}
|
|
|
|
// Call this method if BeginSourceFile fails.
|
|
// Deallocate compiler instance, input and output descriptors
|
|
static void BeginSourceFileCleanUp(FrontendAction &fa, CompilerInstance &ci) {
|
|
ci.ClearOutputFiles(/*EraseFiles=*/true);
|
|
fa.set_currentInput(FrontendInputFile());
|
|
fa.set_instance(nullptr);
|
|
}
|
|
|
|
bool FrontendAction::BeginSourceFile(
|
|
CompilerInstance &ci, const FrontendInputFile &realInput) {
|
|
|
|
FrontendInputFile input(realInput);
|
|
|
|
// Return immediately if the input file does not exist or is not a file. Note
|
|
// that we cannot check this for input from stdin.
|
|
if (input.file() != "-") {
|
|
if (!llvm::sys::fs::is_regular_file(input.file())) {
|
|
// Create an diagnostic ID to report
|
|
unsigned diagID;
|
|
if (llvm::vfs::getRealFileSystem()->exists(input.file())) {
|
|
ci.diagnostics().Report(clang::diag::err_fe_error_reading)
|
|
<< input.file();
|
|
diagID = ci.diagnostics().getCustomDiagID(
|
|
clang::DiagnosticsEngine::Error, "%0 is not a regular file");
|
|
} else {
|
|
diagID = ci.diagnostics().getCustomDiagID(
|
|
clang::DiagnosticsEngine::Error, "%0 does not exist");
|
|
}
|
|
|
|
// Report the diagnostic and return
|
|
ci.diagnostics().Report(diagID) << input.file();
|
|
BeginSourceFileCleanUp(*this, ci);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
assert(!instance_ && "Already processing a source file!");
|
|
assert(!realInput.IsEmpty() && "Unexpected empty filename!");
|
|
set_currentInput(realInput);
|
|
set_instance(&ci);
|
|
|
|
if (!ci.HasAllSources()) {
|
|
BeginSourceFileCleanUp(*this, ci);
|
|
return false;
|
|
}
|
|
|
|
if (!BeginSourceFileAction(ci)) {
|
|
BeginSourceFileCleanUp(*this, ci);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool FrontendAction::ShouldEraseOutputFiles() {
|
|
return instance().diagnostics().hasErrorOccurred();
|
|
}
|
|
|
|
llvm::Error FrontendAction::Execute() {
|
|
ExecuteAction();
|
|
|
|
return llvm::Error::success();
|
|
}
|
|
|
|
void FrontendAction::EndSourceFile() {
|
|
CompilerInstance &ci = instance();
|
|
|
|
// Cleanup the output streams, and erase the output files if instructed by the
|
|
// FrontendAction.
|
|
ci.ClearOutputFiles(/*EraseFiles=*/ShouldEraseOutputFiles());
|
|
|
|
set_instance(nullptr);
|
|
set_currentInput(FrontendInputFile());
|
|
}
|