forked from OSchip/llvm-project
[flang][driver] Make `flang-new` always generate run-time type info
Currently, the driver generates the tables with "run-time type information for derived types" only when specific actions are run. However, the corresponding data might be required by the subsequent compilation stages (e.g. lowering, code-gen) and should be generated unconditionally. Note that this is only possible once the semantic checks have been run. Note that when generating these tables, extra semantic errors might be generated. The driver will always report these and in most cases such semantic errors will cause the driver to exit immediately. The only exception are actions inheriting from `PrescanAndSemaDebugAction`. Currently, there's only one such action: `DebugDumpAllAction` (corresponds to `-fdebug-dump-all` command-line flag). I've updated the comments for this action to clarify this. This change will mostly affect lowering, which currently is only available for most basic examples (e.g. empty programs). I wasn't able to find a working case that would demonstrate the new behaviour. I hope that this change is straightforward enough and am submitting it without a test. Differential Revision: https://reviews.llvm.org/D120051
This commit is contained in:
parent
25d7b4fb44
commit
16a91a1cbe
|
@ -13,6 +13,7 @@
|
|||
#include "flang/Frontend/PreprocessorOptions.h"
|
||||
#include "flang/Parser/parsing.h"
|
||||
#include "flang/Parser/provenance.h"
|
||||
#include "flang/Semantics/runtime-type-info.h"
|
||||
#include "flang/Semantics/semantics.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
|
@ -47,6 +48,8 @@ class CompilerInstance {
|
|||
|
||||
std::unique_ptr<Fortran::semantics::Semantics> semantics_;
|
||||
|
||||
std::unique_ptr<Fortran::semantics::RuntimeDerivedTypeTables> rtTyTables_;
|
||||
|
||||
/// The stream for diagnostics from Semantics
|
||||
llvm::raw_ostream *semaOutputStream_ = &llvm::errs();
|
||||
|
||||
|
@ -129,6 +132,16 @@ public:
|
|||
semantics_ = std::move(semantics);
|
||||
}
|
||||
|
||||
void setRtTyTables(
|
||||
std::unique_ptr<Fortran::semantics::RuntimeDerivedTypeTables> tables) {
|
||||
rtTyTables_ = std::move(tables);
|
||||
}
|
||||
|
||||
Fortran::semantics::RuntimeDerivedTypeTables &getRtTyTables() {
|
||||
assert(rtTyTables_ && "Missing runtime derived type tables!");
|
||||
return *rtTyTables_;
|
||||
}
|
||||
|
||||
/// }
|
||||
/// @name High-Level Operations
|
||||
/// {
|
||||
|
|
|
@ -112,6 +112,10 @@ protected:
|
|||
// Run semantic checks for the current input file. Return False if fatal
|
||||
// errors are reported, True otherwise.
|
||||
bool RunSemanticChecks();
|
||||
// Generate run-time type information for derived types. This may lead to new
|
||||
// semantic errors. Return False if fatal errors are reported, True
|
||||
// otherwise.
|
||||
bool GenerateRtTypeTables();
|
||||
|
||||
// Report fatal semantic errors. Return True if present, false otherwise.
|
||||
bool reportFatalSemanticErrors();
|
||||
|
|
|
@ -133,7 +133,12 @@ class PluginParseTreeAction : public PrescanAndSemaAction {
|
|||
// PrescanAndSemaDebug Actions
|
||||
//
|
||||
// These actions will parse the input, run the semantic checks and execute
|
||||
// their actions regardless of whether any semantic errors are found.
|
||||
// their actions _regardless of_ whether any semantic errors have been found.
|
||||
// This can be useful when adding new languge feature and when you wish to
|
||||
// investigate compiler output (e.g. the parse tree) despite any semantic
|
||||
// errors.
|
||||
//
|
||||
// NOTE: Use with care and for development only!
|
||||
//===----------------------------------------------------------------------===//
|
||||
class PrescanAndSemaDebugAction : public FrontendAction {
|
||||
|
||||
|
|
|
@ -180,6 +180,21 @@ bool FrontendAction::RunSemanticChecks() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FrontendAction::GenerateRtTypeTables() {
|
||||
instance().setRtTyTables(
|
||||
std::make_unique<Fortran::semantics::RuntimeDerivedTypeTables>(
|
||||
BuildRuntimeDerivedTypeTables(
|
||||
instance().invocation().semanticsContext())));
|
||||
|
||||
// The runtime derived type information table builder may find additional
|
||||
// semantic errors. Report them.
|
||||
if (reportFatalSemanticErrors()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <unsigned N>
|
||||
bool FrontendAction::reportFatalErrors(const char (&message)[N]) {
|
||||
if (!instance_->parsing().messages().empty() &&
|
||||
|
|
|
@ -47,12 +47,18 @@ bool PrescanAndParseAction::BeginSourceFileAction() {
|
|||
}
|
||||
|
||||
bool PrescanAndSemaAction::BeginSourceFileAction() {
|
||||
return RunPrescan() && RunParse() && RunSemanticChecks();
|
||||
return RunPrescan() && RunParse() && RunSemanticChecks() &&
|
||||
GenerateRtTypeTables();
|
||||
}
|
||||
|
||||
bool PrescanAndSemaDebugAction::BeginSourceFileAction() {
|
||||
// Semantic checks are made to succeed unconditionally.
|
||||
return RunPrescan() && RunParse() && (RunSemanticChecks() || true);
|
||||
// This is a "debug" action for development purposes. To facilitate this, the
|
||||
// semantic checks are made to succeed unconditionally to prevent this action
|
||||
// from exiting early (i.e. in the presence of semantic errors). We should
|
||||
// never do this in actions intended for end-users or otherwise regular
|
||||
// compiler workflows!
|
||||
return RunPrescan() && RunParse() && (RunSemanticChecks() || true) &&
|
||||
(GenerateRtTypeTables() || true);
|
||||
}
|
||||
|
||||
bool CodeGenAction::BeginSourceFileAction() {
|
||||
|
@ -218,25 +224,18 @@ void DebugUnparseWithSymbolsAction::ExecuteAction() {
|
|||
|
||||
void DebugDumpSymbolsAction::ExecuteAction() {
|
||||
CompilerInstance &ci = this->instance();
|
||||
auto &semantics = ci.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();
|
||||
|
||||
if (!tables.schemata) {
|
||||
if (!ci.getRtTyTables().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";
|
||||
return;
|
||||
}
|
||||
|
||||
// Dump symbols
|
||||
semantics.DumpSymbols(llvm::outs());
|
||||
ci.semantics().DumpSymbols(llvm::outs());
|
||||
}
|
||||
|
||||
void DebugDumpAllAction::ExecuteAction() {
|
||||
|
@ -250,27 +249,20 @@ void DebugDumpAllAction::ExecuteAction() {
|
|||
Fortran::parser::DumpTree(
|
||||
llvm::outs(), parseTree, &ci.invocation().asFortran());
|
||||
|
||||
auto &semantics = ci.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();
|
||||
|
||||
if (!tables.schemata) {
|
||||
if (!ci.getRtTyTables().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";
|
||||
return;
|
||||
}
|
||||
|
||||
// Dump symbols
|
||||
llvm::outs() << "=====================";
|
||||
llvm::outs() << " Flang: symbols dump ";
|
||||
llvm::outs() << "=====================\n";
|
||||
semantics.DumpSymbols(llvm::outs());
|
||||
ci.semantics().DumpSymbols(llvm::outs());
|
||||
}
|
||||
|
||||
void DebugDumpParseTreeNoSemaAction::ExecuteAction() {
|
||||
|
|
Loading…
Reference in New Issue