[flang-commits] [flang] 265a996 - [flang][nfc] Move `Semantics` from `FrontendAction` to `CompilerInstance`

Andrzej Warzynski via flang-commits flang-commits at lists.llvm.org
Sun Aug 15 02:34:30 PDT 2021


Author: Andrzej Warzynski
Date: 2021-08-15T09:33:07Z
New Revision: 265a9961d13e78fc1a5f4b478ac9651fcccdf92b

URL: https://github.com/llvm/llvm-project/commit/265a9961d13e78fc1a5f4b478ac9651fcccdf92b
DIFF: https://github.com/llvm/llvm-project/commit/265a9961d13e78fc1a5f4b478ac9651fcccdf92b.diff

LOG: [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

Added: 
    

Modified: 
    flang/include/flang/Frontend/CompilerInstance.h
    flang/include/flang/Frontend/FrontendActions.h
    flang/lib/Frontend/FrontendActions.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Frontend/CompilerInstance.h b/flang/include/flang/Frontend/CompilerInstance.h
index 956fe144ac9ef..557c626ad9385 100644
--- a/flang/include/flang/Frontend/CompilerInstance.h
+++ b/flang/include/flang/Frontend/CompilerInstance.h
@@ -18,6 +18,21 @@
 
 namespace Fortran::frontend {
 
+/// Helper class for managing a single instance of the Flang compiler.
+///
+/// This class serves two purposes:
+///  (1) It manages the various objects which are necessary to run the compiler
+///  (2) It provides utility routines for constructing and manipulating the
+///      common Flang objects.
+///
+/// The compiler instance generally owns the instance of all the objects that it
+/// manages. However, clients can still share objects by manually setting the
+/// object and retaking ownership prior to destroying the CompilerInstance.
+///
+/// The compiler instance is intended to simplify clients, but not to lock them
+/// in to the compiler instance for everything. When possible, utility functions
+/// come in two forms; a short form that reuses the CompilerInstance objects,
+/// and a long form that takes explicit instances of any required objects.
 class CompilerInstance {
 
   /// The options used in this compiler instance.
@@ -30,6 +45,8 @@ class CompilerInstance {
 
   std::shared_ptr<Fortran::parser::Parsing> parsing_;
 
+  std::unique_ptr<Fortran::semantics::Semantics> semantics_;
+
   /// The stream for diagnostics from Semantics
   llvm::raw_ostream *semaOutputStream_ = &llvm::errs();
 
@@ -110,6 +127,13 @@ class CompilerInstance {
   /// Get the current stream for verbose output.
   llvm::raw_ostream &semaOutputStream() { return *semaOutputStream_; }
 
+  Fortran::semantics::Semantics &semantics() { return *semantics_; }
+  const Fortran::semantics::Semantics &semantics() const { return *semantics_; }
+
+  void setSemantics(std::unique_ptr<Fortran::semantics::Semantics> semantics) {
+    semantics_ = std::move(semantics);
+  }
+
   /// }
   /// @name High-Level Operations
   /// {

diff  --git a/flang/include/flang/Frontend/FrontendActions.h b/flang/include/flang/Frontend/FrontendActions.h
index d30ae1dbed0ff..9cfaabcf7677e 100644
--- a/flang/include/flang/Frontend/FrontendActions.h
+++ b/flang/include/flang/Frontend/FrontendActions.h
@@ -90,18 +90,9 @@ class DebugDumpParseTreeNoSemaAction : public PrescanAndParseAction {
 // PrescanAndSema Actions
 //===----------------------------------------------------------------------===//
 class PrescanAndSemaAction : public FrontendAction {
-  std::unique_ptr<Fortran::semantics::Semantics> semantics_;
 
   void ExecuteAction() override = 0;
   bool BeginSourceFileAction(CompilerInstance &ci) override;
-
-public:
-  Fortran::semantics::Semantics &semantics() { return *semantics_; }
-  const Fortran::semantics::Semantics &semantics() const { return *semantics_; }
-
-  void setSemantics(std::unique_ptr<Fortran::semantics::Semantics> semantics) {
-    semantics_ = std::move(semantics);
-  }
 };
 
 class DebugUnparseWithSymbolsAction : public PrescanAndSemaAction {

diff  --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index c12cafc02dbf3..acd6b049dfe8d 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -139,10 +139,10 @@ bool PrescanAndSemaAction::BeginSourceFileAction(CompilerInstance &c1) {
   auto &parseTree{*ci.parsing().parseTree()};
 
   // Prepare semantics
-  setSemantics(std::make_unique<Fortran::semantics::Semantics>(
+  ci.setSemantics(std::make_unique<Fortran::semantics::Semantics>(
       ci.invocation().semanticsContext(), parseTree,
       ci.invocation().debugModuleDir()));
-  auto &semantics = this->semantics();
+  auto &semantics = ci.semantics();
 
   // Run semantic checks
   semantics.Perform();
@@ -224,8 +224,10 @@ void DebugDumpProvenanceAction::ExecuteAction() {
 }
 
 void ParseSyntaxOnlyAction::ExecuteAction() {
-  reportFatalSemanticErrors(semantics(), this->instance().diagnostics(),
-      GetCurrentFileOrBufferName());
+  CompilerInstance &ci = this->instance();
+
+  reportFatalSemanticErrors(
+      ci.semantics(), ci.diagnostics(), GetCurrentFileOrBufferName());
 }
 
 void DebugUnparseNoSemaAction::ExecuteAction() {
@@ -256,24 +258,25 @@ void DebugUnparseAction::ExecuteAction() {
       invoc.useAnalyzedObjectsForUnparse() ? &invoc.asFortran() : nullptr);
 
   // Report fatal semantic errors
-  reportFatalSemanticErrors(semantics(), this->instance().diagnostics(),
+  reportFatalSemanticErrors(ci.semantics(), this->instance().diagnostics(),
       GetCurrentFileOrBufferName());
 }
 
 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(semantics(), this->instance().diagnostics(),
-      GetCurrentFileOrBufferName());
+  reportFatalSemanticErrors(
+      ci.semantics(), ci.diagnostics(), GetCurrentFileOrBufferName());
 }
 
 void DebugDumpSymbolsAction::ExecuteAction() {
   CompilerInstance &ci = this->instance();
-  auto &semantics = this->semantics();
+  auto &semantics = ci.semantics();
 
   auto tables{Fortran::semantics::BuildRuntimeDerivedTypeTables(
       instance().invocation().semanticsContext())};
@@ -306,7 +309,7 @@ void DebugDumpAllAction::ExecuteAction() {
   Fortran::parser::DumpTree(
       llvm::outs(), parseTree, &ci.invocation().asFortran());
 
-  auto &semantics = this->semantics();
+  auto &semantics = ci.semantics();
   auto tables{Fortran::semantics::BuildRuntimeDerivedTypeTables(
       instance().invocation().semanticsContext())};
   // The runtime derived type information table builder may find and report
@@ -339,6 +342,7 @@ void DebugDumpParseTreeNoSemaAction::ExecuteAction() {
 }
 
 void DebugDumpParseTreeAction::ExecuteAction() {
+  CompilerInstance &ci = this->instance();
   auto &parseTree{instance().parsing().parseTree()};
 
   // Dump parse tree
@@ -346,8 +350,8 @@ void DebugDumpParseTreeAction::ExecuteAction() {
       llvm::outs(), parseTree, &this->instance().invocation().asFortran());
 
   // Report fatal semantic errors
-  reportFatalSemanticErrors(semantics(), this->instance().diagnostics(),
-      GetCurrentFileOrBufferName());
+  reportFatalSemanticErrors(
+      ci.semantics(), ci.diagnostics(), GetCurrentFileOrBufferName());
 }
 
 void DebugMeasureParseTreeAction::ExecuteAction() {
@@ -385,7 +389,7 @@ void DebugPreFIRTreeAction::ExecuteAction() {
   CompilerInstance &ci = this->instance();
   // Report and exit if fatal semantic errors are present
   if (reportFatalSemanticErrors(
-          semantics(), ci.diagnostics(), GetCurrentFileOrBufferName())) {
+          ci.semantics(), ci.diagnostics(), GetCurrentFileOrBufferName())) {
     return;
   }
 
@@ -410,12 +414,13 @@ void DebugDumpParsingLogAction::ExecuteAction() {
 }
 
 void GetDefinitionAction::ExecuteAction() {
+  CompilerInstance &ci = this->instance();
+
   // Report and exit if fatal semantic errors are present
-  if (reportFatalSemanticErrors(semantics(), this->instance().diagnostics(),
-          GetCurrentFileOrBufferName()))
+  if (reportFatalSemanticErrors(
+          ci.semantics(), ci.diagnostics(), GetCurrentFileOrBufferName()))
     return;
 
-  CompilerInstance &ci = this->instance();
   parser::AllCookedSources &cs = ci.allCookedSources();
   unsigned diagID = ci.diagnostics().getCustomDiagID(
       clang::DiagnosticsEngine::Error, "Symbol not found");
@@ -457,12 +462,14 @@ void GetDefinitionAction::ExecuteAction() {
 }
 
 void GetSymbolsSourcesAction::ExecuteAction() {
+  CompilerInstance &ci = this->instance();
+
   // Report and exit if fatal semantic errors are present
-  if (reportFatalSemanticErrors(semantics(), this->instance().diagnostics(),
-          GetCurrentFileOrBufferName()))
+  if (reportFatalSemanticErrors(
+          ci.semantics(), ci.diagnostics(), GetCurrentFileOrBufferName()))
     return;
 
-  semantics().DumpSymbolsSources(llvm::outs());
+  ci.semantics().DumpSymbolsSources(llvm::outs());
 }
 
 void EmitObjAction::ExecuteAction() {


        


More information about the flang-commits mailing list