Skip to content

Commit 265a996

Browse files
committed
[flang][nfc] Move Semantics from FrontendAction to CompilerInstance
`CompilerInstance` is a more appropriate place for a key component of the frontend like `Semantics`. This change opens a path for us to introduce new frontend actions that will also run semantics, but for which inheriting from `PrescanAndSemaAction` wouldn't make much sense. For example, for code-gen actions we plan to introduce a dedicate hierarchy of action classes. I've also added a doxyment for `CompilerInstance` to add a bit of context for this change (and also make future refactoring more informed). As `CompilerInstance` in Flang has been inspired by its counterpart in Clang, this comment is roughly a verbatim copy of the comment in Clang (with some adjustments from me). Credits to Daniel Dunbar for the great design and the original comment. Differential Revision: https://reviews.llvm.org/D108035
1 parent c35e4dc commit 265a996

File tree

3 files changed

+49
-27
lines changed

3 files changed

+49
-27
lines changed

flang/include/flang/Frontend/CompilerInstance.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,21 @@
1818

1919
namespace Fortran::frontend {
2020

21+
/// Helper class for managing a single instance of the Flang compiler.
22+
///
23+
/// This class serves two purposes:
24+
/// (1) It manages the various objects which are necessary to run the compiler
25+
/// (2) It provides utility routines for constructing and manipulating the
26+
/// common Flang objects.
27+
///
28+
/// The compiler instance generally owns the instance of all the objects that it
29+
/// manages. However, clients can still share objects by manually setting the
30+
/// object and retaking ownership prior to destroying the CompilerInstance.
31+
///
32+
/// The compiler instance is intended to simplify clients, but not to lock them
33+
/// in to the compiler instance for everything. When possible, utility functions
34+
/// come in two forms; a short form that reuses the CompilerInstance objects,
35+
/// and a long form that takes explicit instances of any required objects.
2136
class CompilerInstance {
2237

2338
/// The options used in this compiler instance.
@@ -30,6 +45,8 @@ class CompilerInstance {
3045

3146
std::shared_ptr<Fortran::parser::Parsing> parsing_;
3247

48+
std::unique_ptr<Fortran::semantics::Semantics> semantics_;
49+
3350
/// The stream for diagnostics from Semantics
3451
llvm::raw_ostream *semaOutputStream_ = &llvm::errs();
3552

@@ -110,6 +127,13 @@ class CompilerInstance {
110127
/// Get the current stream for verbose output.
111128
llvm::raw_ostream &semaOutputStream() { return *semaOutputStream_; }
112129

130+
Fortran::semantics::Semantics &semantics() { return *semantics_; }
131+
const Fortran::semantics::Semantics &semantics() const { return *semantics_; }
132+
133+
void setSemantics(std::unique_ptr<Fortran::semantics::Semantics> semantics) {
134+
semantics_ = std::move(semantics);
135+
}
136+
113137
/// }
114138
/// @name High-Level Operations
115139
/// {

flang/include/flang/Frontend/FrontendActions.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -90,18 +90,9 @@ class DebugDumpParseTreeNoSemaAction : public PrescanAndParseAction {
9090
// PrescanAndSema Actions
9191
//===----------------------------------------------------------------------===//
9292
class PrescanAndSemaAction : public FrontendAction {
93-
std::unique_ptr<Fortran::semantics::Semantics> semantics_;
9493

9594
void ExecuteAction() override = 0;
9695
bool BeginSourceFileAction(CompilerInstance &ci) override;
97-
98-
public:
99-
Fortran::semantics::Semantics &semantics() { return *semantics_; }
100-
const Fortran::semantics::Semantics &semantics() const { return *semantics_; }
101-
102-
void setSemantics(std::unique_ptr<Fortran::semantics::Semantics> semantics) {
103-
semantics_ = std::move(semantics);
104-
}
10596
};
10697

10798
class DebugUnparseWithSymbolsAction : public PrescanAndSemaAction {

flang/lib/Frontend/FrontendActions.cpp

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,10 @@ bool PrescanAndSemaAction::BeginSourceFileAction(CompilerInstance &c1) {
139139
auto &parseTree{*ci.parsing().parseTree()};
140140

141141
// Prepare semantics
142-
setSemantics(std::make_unique<Fortran::semantics::Semantics>(
142+
ci.setSemantics(std::make_unique<Fortran::semantics::Semantics>(
143143
ci.invocation().semanticsContext(), parseTree,
144144
ci.invocation().debugModuleDir()));
145-
auto &semantics = this->semantics();
145+
auto &semantics = ci.semantics();
146146

147147
// Run semantic checks
148148
semantics.Perform();
@@ -224,8 +224,10 @@ void DebugDumpProvenanceAction::ExecuteAction() {
224224
}
225225

226226
void ParseSyntaxOnlyAction::ExecuteAction() {
227-
reportFatalSemanticErrors(semantics(), this->instance().diagnostics(),
228-
GetCurrentFileOrBufferName());
227+
CompilerInstance &ci = this->instance();
228+
229+
reportFatalSemanticErrors(
230+
ci.semantics(), ci.diagnostics(), GetCurrentFileOrBufferName());
229231
}
230232

231233
void DebugUnparseNoSemaAction::ExecuteAction() {
@@ -256,24 +258,25 @@ void DebugUnparseAction::ExecuteAction() {
256258
invoc.useAnalyzedObjectsForUnparse() ? &invoc.asFortran() : nullptr);
257259

258260
// Report fatal semantic errors
259-
reportFatalSemanticErrors(semantics(), this->instance().diagnostics(),
261+
reportFatalSemanticErrors(ci.semantics(), this->instance().diagnostics(),
260262
GetCurrentFileOrBufferName());
261263
}
262264

263265
void DebugUnparseWithSymbolsAction::ExecuteAction() {
266+
CompilerInstance &ci = this->instance();
264267
auto &parseTree{*instance().parsing().parseTree()};
265268

266269
Fortran::semantics::UnparseWithSymbols(
267270
llvm::outs(), parseTree, /*encoding=*/Fortran::parser::Encoding::UTF_8);
268271

269272
// Report fatal semantic errors
270-
reportFatalSemanticErrors(semantics(), this->instance().diagnostics(),
271-
GetCurrentFileOrBufferName());
273+
reportFatalSemanticErrors(
274+
ci.semantics(), ci.diagnostics(), GetCurrentFileOrBufferName());
272275
}
273276

274277
void DebugDumpSymbolsAction::ExecuteAction() {
275278
CompilerInstance &ci = this->instance();
276-
auto &semantics = this->semantics();
279+
auto &semantics = ci.semantics();
277280

278281
auto tables{Fortran::semantics::BuildRuntimeDerivedTypeTables(
279282
instance().invocation().semanticsContext())};
@@ -306,7 +309,7 @@ void DebugDumpAllAction::ExecuteAction() {
306309
Fortran::parser::DumpTree(
307310
llvm::outs(), parseTree, &ci.invocation().asFortran());
308311

309-
auto &semantics = this->semantics();
312+
auto &semantics = ci.semantics();
310313
auto tables{Fortran::semantics::BuildRuntimeDerivedTypeTables(
311314
instance().invocation().semanticsContext())};
312315
// The runtime derived type information table builder may find and report
@@ -339,15 +342,16 @@ void DebugDumpParseTreeNoSemaAction::ExecuteAction() {
339342
}
340343

341344
void DebugDumpParseTreeAction::ExecuteAction() {
345+
CompilerInstance &ci = this->instance();
342346
auto &parseTree{instance().parsing().parseTree()};
343347

344348
// Dump parse tree
345349
Fortran::parser::DumpTree(
346350
llvm::outs(), parseTree, &this->instance().invocation().asFortran());
347351

348352
// Report fatal semantic errors
349-
reportFatalSemanticErrors(semantics(), this->instance().diagnostics(),
350-
GetCurrentFileOrBufferName());
353+
reportFatalSemanticErrors(
354+
ci.semantics(), ci.diagnostics(), GetCurrentFileOrBufferName());
351355
}
352356

353357
void DebugMeasureParseTreeAction::ExecuteAction() {
@@ -385,7 +389,7 @@ void DebugPreFIRTreeAction::ExecuteAction() {
385389
CompilerInstance &ci = this->instance();
386390
// Report and exit if fatal semantic errors are present
387391
if (reportFatalSemanticErrors(
388-
semantics(), ci.diagnostics(), GetCurrentFileOrBufferName())) {
392+
ci.semantics(), ci.diagnostics(), GetCurrentFileOrBufferName())) {
389393
return;
390394
}
391395

@@ -410,12 +414,13 @@ void DebugDumpParsingLogAction::ExecuteAction() {
410414
}
411415

412416
void GetDefinitionAction::ExecuteAction() {
417+
CompilerInstance &ci = this->instance();
418+
413419
// Report and exit if fatal semantic errors are present
414-
if (reportFatalSemanticErrors(semantics(), this->instance().diagnostics(),
415-
GetCurrentFileOrBufferName()))
420+
if (reportFatalSemanticErrors(
421+
ci.semantics(), ci.diagnostics(), GetCurrentFileOrBufferName()))
416422
return;
417423

418-
CompilerInstance &ci = this->instance();
419424
parser::AllCookedSources &cs = ci.allCookedSources();
420425
unsigned diagID = ci.diagnostics().getCustomDiagID(
421426
clang::DiagnosticsEngine::Error, "Symbol not found");
@@ -457,12 +462,14 @@ void GetDefinitionAction::ExecuteAction() {
457462
}
458463

459464
void GetSymbolsSourcesAction::ExecuteAction() {
465+
CompilerInstance &ci = this->instance();
466+
460467
// Report and exit if fatal semantic errors are present
461-
if (reportFatalSemanticErrors(semantics(), this->instance().diagnostics(),
462-
GetCurrentFileOrBufferName()))
468+
if (reportFatalSemanticErrors(
469+
ci.semantics(), ci.diagnostics(), GetCurrentFileOrBufferName()))
463470
return;
464471

465-
semantics().DumpSymbolsSources(llvm::outs());
472+
ci.semantics().DumpSymbolsSources(llvm::outs());
466473
}
467474

468475
void EmitObjAction::ExecuteAction() {

0 commit comments

Comments
 (0)