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

Yusuke MINATO via flang-commits flang-commits at lists.llvm.org
Wed Sep 9 01:06:44 PDT 2026


https://github.com/yus3710-fj updated https://github.com/llvm/llvm-project/pull/169814

>From ffe40c38ba81cf9229baf3c3af76827c9891ea26 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 7cab6e2122319..eae01fd72a111 100644
--- a/flang/include/flang/Semantics/scope.h
+++ b/flang/include/flang/Semantics/scope.h
@@ -297,6 +297,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 c000bb9038cf5..1a793c135a2f3 100644
--- a/flang/lib/Semantics/scope.cpp
+++ b/flang/lib/Semantics/scope.cpp
@@ -430,6 +430,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 3db88b6168581..ad54983db1b26 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.
@@ -865,7 +863,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) {
@@ -891,70 +889,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