[flang-commits] [flang] [flang][Semantics] Add dump method to Scope (NFC) (PR #169814)

via flang-commits flang-commits at lists.llvm.org
Thu Nov 27 06:34:21 PST 2025


https://github.com/parabola94 created https://github.com/llvm/llvm-project/pull/169814

We call `SemanticsContext::DumpSymbols` to dump the symbol table. This method prints all symbols and scopes in the global scopes. On the other hand, however, there is no method to only print inner scopes. This is because the dump method is bound to `SemanticsContext`, not `Scope`.

This patch refactors the dump method for the symbol table. This will help debugging.

>From 03a04f372ab148d89a5d1be8520c12e9f6d03b1e Mon Sep 17 00:00:00 2001
From: parabola94 <heavybaby5000 at toki.waseda.jp>
Date: Wed, 26 Nov 2025 23:33:55 +0900
Subject: [PATCH] [flang][Semantics] Add dump method to Scope (NFC)

We call `SemanticsContext::DumpSymbols` to dump the symbol table.
This method prints all symbols and scopes in the global scopes.
On the other hand, however, there is no method to only print inner scopes.
This is because the dump method is bound to `SemanticsContext`, not `Scope`.

This patch refactors the dump method for the symbol table.
This will help debugging.
---
 flang/include/flang/Semantics/scope.h |  5 ++
 flang/lib/Semantics/scope.cpp         | 72 +++++++++++++++++++++++++++
 flang/lib/Semantics/semantics.cpp     | 68 +------------------------
 3 files changed, 78 insertions(+), 67 deletions(-)

diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h
index ecffdb468bf6c..f268652058864 100644
--- a/flang/include/flang/Semantics/scope.h
+++ b/flang/include/flang/Semantics/scope.h
@@ -287,6 +287,11 @@ class Scope {
     runtimeDerivedTypeDescription_ = &symbol;
   }
 
+  void print(llvm::raw_ostream &os, int indent = 0) const;
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+  LLVM_DUMP_METHOD void dump() const;
+#endif
+
 private:
   Scope *parent_{
       nullptr}; // this is enclosing scope, not extended derived type base
diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp
index ab75d4c608387..3f1ba4d261769 100644
--- a/flang/lib/Semantics/scope.cpp
+++ b/flang/lib/Semantics/scope.cpp
@@ -432,6 +432,78 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Scope &scope) {
   return os;
 }
 
+void Scope::print(llvm::raw_ostream &os, int indent) const {
+  auto PutIndent{[&]() {
+    for (int i = 0; i < indent; ++i) {
+      os << "  ";
+    }
+  }};
+
+  PutIndent();
+  os << EnumToString(kind()) << " scope:";
+  if (symbol_) {
+    os << ' ' << symbol_->name();
+  }
+  if (alignment().has_value()) {
+    os << " size=" << size() << " alignment=" << *alignment();
+  }
+  if (derivedTypeSpec()) {
+    os << " instantiation of " << *derivedTypeSpec();
+  }
+  os << " sourceRange=" << sourceRange().size() << " bytes\n";
+
+  ++indent;
+
+  for (const auto &pair : *this) {
+    const auto &symbol{*pair.second};
+    PutIndent();
+    os << symbol << '\n';
+    if (const auto *details{symbol.detailsIf<GenericDetails>()}) {
+      if (const auto &type{details->derivedType()}) {
+        PutIndent();
+        os << *type << '\n';
+      }
+    }
+  }
+  if (!equivalenceSets().empty()) {
+    PutIndent();
+    os << "Equivalence Sets:";
+    for (const auto &set : equivalenceSets()) {
+      os << ' ';
+      char sep = '(';
+      for (const auto &object : set) {
+        os << sep << object.AsFortran();
+        sep = ',';
+      }
+      os << ')';
+    }
+    os << '\n';
+  }
+  if (!crayPointers().empty()) {
+    PutIndent();
+    os << "Cray Pointers:";
+    for (const auto &[pointee, pointer] : crayPointers()) {
+      os << " (" << pointer->name() << ',' << pointee << ')';
+    }
+    os << '\n';
+  }
+  for (const auto &pair : commonBlocks()) {
+    const auto &symbol{*pair.second};
+    PutIndent();
+    os << symbol << '\n';
+  }
+
+  for (const auto &child : children()) {
+    child.print(os, indent);
+  }
+
+  --indent;
+}
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+void Scope::dump() const { print(llvm::errs()); }
+#endif
+
 bool Scope::IsStmtFunction() const {
   return symbol_ && symbol_->test(Symbol::Flag::StmtFunction);
 }
diff --git a/flang/lib/Semantics/semantics.cpp b/flang/lib/Semantics/semantics.cpp
index 2606d997b1cd7..b73743f455dff 100644
--- a/flang/lib/Semantics/semantics.cpp
+++ b/flang/lib/Semantics/semantics.cpp
@@ -50,8 +50,6 @@
 namespace Fortran::semantics {
 
 using NameToSymbolMap = std::multimap<parser::CharBlock, SymbolRef>;
-static void DoDumpSymbols(llvm::raw_ostream &, const Scope &, int indent = 0);
-static void PutIndent(llvm::raw_ostream &, int indent);
 
 static void GetSymbolNames(const Scope &scope, NameToSymbolMap &symbols) {
   // Finds all symbol names in the scope without collecting duplicates.
@@ -667,7 +665,7 @@ void Semantics::EmitMessages(llvm::raw_ostream &os) {
 }
 
 void SemanticsContext::DumpSymbols(llvm::raw_ostream &os) {
-  DoDumpSymbols(os, globalScope());
+  globalScope().print(os);
 }
 
 ProgramTree &SemanticsContext::SaveProgramTree(ProgramTree &&tree) {
@@ -693,70 +691,6 @@ void Semantics::DumpSymbolsSources(llvm::raw_ostream &os) const {
   }
 }
 
-void DoDumpSymbols(llvm::raw_ostream &os, const Scope &scope, int indent) {
-  PutIndent(os, indent);
-  os << Scope::EnumToString(scope.kind()) << " scope:";
-  if (const auto *symbol{scope.symbol()}) {
-    os << ' ' << symbol->name();
-  }
-  if (scope.alignment().has_value()) {
-    os << " size=" << scope.size() << " alignment=" << *scope.alignment();
-  }
-  if (scope.derivedTypeSpec()) {
-    os << " instantiation of " << *scope.derivedTypeSpec();
-  }
-  os << " sourceRange=" << scope.sourceRange().size() << " bytes\n";
-  ++indent;
-  for (const auto &pair : scope) {
-    const auto &symbol{*pair.second};
-    PutIndent(os, indent);
-    os << symbol << '\n';
-    if (const auto *details{symbol.detailsIf<GenericDetails>()}) {
-      if (const auto &type{details->derivedType()}) {
-        PutIndent(os, indent);
-        os << *type << '\n';
-      }
-    }
-  }
-  if (!scope.equivalenceSets().empty()) {
-    PutIndent(os, indent);
-    os << "Equivalence Sets:";
-    for (const auto &set : scope.equivalenceSets()) {
-      os << ' ';
-      char sep = '(';
-      for (const auto &object : set) {
-        os << sep << object.AsFortran();
-        sep = ',';
-      }
-      os << ')';
-    }
-    os << '\n';
-  }
-  if (!scope.crayPointers().empty()) {
-    PutIndent(os, indent);
-    os << "Cray Pointers:";
-    for (const auto &[pointee, pointer] : scope.crayPointers()) {
-      os << " (" << pointer->name() << ',' << pointee << ')';
-    }
-    os << '\n';
-  }
-  for (const auto &pair : scope.commonBlocks()) {
-    const auto &symbol{*pair.second};
-    PutIndent(os, indent);
-    os << symbol << '\n';
-  }
-  for (const auto &child : scope.children()) {
-    DoDumpSymbols(os, child, indent);
-  }
-  --indent;
-}
-
-static void PutIndent(llvm::raw_ostream &os, int indent) {
-  for (int i = 0; i < indent; ++i) {
-    os << "  ";
-  }
-}
-
 void SemanticsContext::MapCommonBlockAndCheckConflicts(const Symbol &common) {
   if (!commonBlockMap_) {
     commonBlockMap_ = std::make_unique<CommonBlockMap>();



More information about the flang-commits mailing list