[flang-commits] [flang] deb057a - [flang] Enclose Walk overloads into class for lookup purposes (#115926)

via flang-commits flang-commits at lists.llvm.org
Wed Nov 13 05:15:23 PST 2024


Author: Krzysztof Parzyszek
Date: 2024-11-13T07:15:18-06:00
New Revision: deb057adb7334734482452daf20ccdd8cece1aa8

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

LOG: [flang] Enclose Walk overloads into class for lookup purposes (#115926)

The parse-tree-visitor consists of a range of `Walk` functions where
each overload is specialized for a particular case. These overloads do
call one another, and due to the usual name lookup rules, an earlier
overload can't call an overload defined later unless the latter was
declared ahead of time.
To avoid listing a number of declarations at the beginning of the header
enclose them in a class as static members, with a couple of simple
forwarding calls. This takes advantage of the class member name lookup,
which uses the entire class definition for lookup.

Added: 
    

Modified: 
    flang/include/flang/Parser/parse-tree-visitor.h

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Parser/parse-tree-visitor.h b/flang/include/flang/Parser/parse-tree-visitor.h
index 81d01dbdd65cc9..e1ea4d459f4a60 100644
--- a/flang/include/flang/Parser/parse-tree-visitor.h
+++ b/flang/include/flang/Parser/parse-tree-visitor.h
@@ -29,881 +29,918 @@
 
 namespace Fortran::parser {
 
-// Default case for visitation of non-class data members, strings, and
-// any other non-decomposable values.
-template <typename A, typename V>
-std::enable_if_t<!std::is_class_v<A> || std::is_same_v<std::string, A> ||
-    std::is_same_v<CharBlock, A>>
-Walk(const A &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    visitor.Post(x);
-  }
-}
-template <typename A, typename M>
-std::enable_if_t<!std::is_class_v<A> || std::is_same_v<std::string, A> ||
-    std::is_same_v<CharBlock, A>>
-Walk(A &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    mutator.Post(x);
-  }
-}
+template <typename A, typename V> void Walk(const A &x, V &visitor);
+template <typename A, typename M> void Walk(A &x, M &mutator);
 
-template <typename V> void Walk(const format::ControlEditDesc &, V &);
-template <typename M> void Walk(format::ControlEditDesc &, M &);
-template <typename V> void Walk(const format::DerivedTypeDataEditDesc &, V &);
-template <typename M> void Walk(format::DerivedTypeDataEditDesc &, M &);
-template <typename V> void Walk(const format::FormatItem &, V &);
-template <typename M> void Walk(format::FormatItem &, M &);
-template <typename V> void Walk(const format::FormatSpecification &, V &);
-template <typename M> void Walk(format::FormatSpecification &, M &);
-template <typename V> void Walk(const format::IntrinsicTypeDataEditDesc &, V &);
-template <typename M> void Walk(format::IntrinsicTypeDataEditDesc &, M &);
-
-// Traversal of needed STL template classes (optional, list, tuple, variant)
-// For most lists, just traverse the elements; but when a list constitutes
-// a Block (i.e., std::list<ExecutionPartConstruct>), also invoke the
-// visitor/mutator on the list itself.
-template <typename T, typename V> void Walk(const std::list<T> &x, V &visitor) {
-  for (const auto &elem : x) {
-    Walk(elem, visitor);
+namespace detail {
+// A number of the Walk functions below call other Walk functions. Define
+// a dummy class, and put all of them in it to ensure that name lookup for
+// Walk considers all overloads (not just those defined prior to the call
+// to Walk).
+struct ParseTreeVisitorLookupScope {
+  // Default case for visitation of non-class data members, strings, and
+  // any other non-decomposable values.
+  template <typename A, typename V>
+  static std::enable_if_t<!std::is_class_v<A> ||
+      std::is_same_v<std::string, A> || std::is_same_v<CharBlock, A>>
+  Walk(const A &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      visitor.Post(x);
+    }
   }
-}
-template <typename T, typename M> void Walk(std::list<T> &x, M &mutator) {
-  for (auto &elem : x) {
-    Walk(elem, mutator);
+  template <typename A, typename M>
+  static std::enable_if_t<!std::is_class_v<A> ||
+      std::is_same_v<std::string, A> || std::is_same_v<CharBlock, A>>
+  Walk(A &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      mutator.Post(x);
+    }
   }
-}
-template <typename V> void Walk(const Block &x, V &visitor) {
-  if (visitor.Pre(x)) {
+
+  // Traversal of needed STL template classes (optional, list, tuple, variant)
+  // For most lists, just traverse the elements; but when a list constitutes
+  // a Block (i.e., std::list<ExecutionPartConstruct>), also invoke the
+  // visitor/mutator on the list itself.
+  template <typename T, typename V>
+  static void Walk(const std::list<T> &x, V &visitor) {
     for (const auto &elem : x) {
       Walk(elem, visitor);
     }
-    visitor.Post(x);
   }
-}
-template <typename M> void Walk(Block &x, M &mutator) {
-  if (mutator.Pre(x)) {
+  template <typename T, typename M>
+  static void Walk(std::list<T> &x, M &mutator) {
     for (auto &elem : x) {
       Walk(elem, mutator);
     }
-    mutator.Post(x);
   }
-}
-template <typename T, typename V>
-void Walk(const std::optional<T> &x, V &visitor) {
-  if (x) {
-    Walk(*x, visitor);
+  template <typename V> static void Walk(const Block &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      for (const auto &elem : x) {
+        Walk(elem, visitor);
+      }
+      visitor.Post(x);
+    }
   }
-}
-template <typename T, typename M> void Walk(std::optional<T> &x, M &mutator) {
-  if (x) {
-    Walk(*x, mutator);
+  template <typename M> static void Walk(Block &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      for (auto &elem : x) {
+        Walk(elem, mutator);
+      }
+      mutator.Post(x);
+    }
   }
-}
-template <std::size_t I = 0, typename Func, typename T>
-void ForEachInTuple(const T &tuple, Func func) {
-  func(std::get<I>(tuple));
-  if constexpr (I + 1 < std::tuple_size_v<T>) {
-    ForEachInTuple<I + 1>(tuple, func);
+  template <typename T, typename V>
+  static void Walk(const std::optional<T> &x, V &visitor) {
+    if (x) {
+      Walk(*x, visitor);
+    }
   }
-}
-template <typename V, typename... A>
-void Walk(const std::tuple<A...> &x, V &visitor) {
-  if (sizeof...(A) > 0) {
+  template <typename T, typename M>
+  static void Walk(std::optional<T> &x, M &mutator) {
+    if (x) {
+      Walk(*x, mutator);
+    }
+  }
+  template <std::size_t I = 0, typename Func, typename T>
+  static void ForEachInTuple(const T &tuple, Func func) {
+    func(std::get<I>(tuple));
+    if constexpr (I + 1 < std::tuple_size_v<T>) {
+      ForEachInTuple<I + 1>(tuple, func);
+    }
+  }
+  template <typename V, typename... A>
+  static void Walk(const std::tuple<A...> &x, V &visitor) {
+    if (sizeof...(A) > 0) {
+      if (visitor.Pre(x)) {
+        ForEachInTuple(x, [&](const auto &y) { Walk(y, visitor); });
+        visitor.Post(x);
+      }
+    }
+  }
+  template <std::size_t I = 0, typename Func, typename T>
+  static void ForEachInTuple(T &tuple, Func func) {
+    func(std::get<I>(tuple));
+    if constexpr (I + 1 < std::tuple_size_v<T>) {
+      ForEachInTuple<I + 1>(tuple, func);
+    }
+  }
+  template <typename M, typename... A>
+  static void Walk(std::tuple<A...> &x, M &mutator) {
+    if (sizeof...(A) > 0) {
+      if (mutator.Pre(x)) {
+        ForEachInTuple(x, [&](auto &y) { Walk(y, mutator); });
+        mutator.Post(x);
+      }
+    }
+  }
+  template <typename V, typename... A>
+  static void Walk(const std::variant<A...> &x, V &visitor) {
     if (visitor.Pre(x)) {
-      ForEachInTuple(x, [&](const auto &y) { Walk(y, visitor); });
+      common::visit([&](const auto &y) { Walk(y, visitor); }, x);
       visitor.Post(x);
     }
   }
-}
-template <std::size_t I = 0, typename Func, typename T>
-void ForEachInTuple(T &tuple, Func func) {
-  func(std::get<I>(tuple));
-  if constexpr (I + 1 < std::tuple_size_v<T>) {
-    ForEachInTuple<I + 1>(tuple, func);
-  }
-}
-template <typename M, typename... A>
-void Walk(std::tuple<A...> &x, M &mutator) {
-  if (sizeof...(A) > 0) {
+  template <typename M, typename... A>
+  static void Walk(std::variant<A...> &x, M &mutator) {
     if (mutator.Pre(x)) {
-      ForEachInTuple(x, [&](auto &y) { Walk(y, mutator); });
+      common::visit([&](auto &y) { Walk(y, mutator); }, x);
       mutator.Post(x);
     }
   }
-}
-template <typename V, typename... A>
-void Walk(const std::variant<A...> &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    common::visit([&](const auto &y) { Walk(y, visitor); }, x);
-    visitor.Post(x);
+  template <typename A, typename B, typename V>
+  static void Walk(const std::pair<A, B> &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.first, visitor);
+      Walk(x.second, visitor);
+    }
   }
-}
-template <typename M, typename... A>
-void Walk(std::variant<A...> &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    common::visit([&](auto &y) { Walk(y, mutator); }, x);
-    mutator.Post(x);
+  template <typename A, typename B, typename M>
+  static void Walk(std::pair<A, B> &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.first, mutator);
+      Walk(x.second, mutator);
+    }
   }
-}
-template <typename A, typename B, typename V>
-void Walk(const std::pair<A, B> &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.first, visitor);
-    Walk(x.second, visitor);
+
+  // Trait-determined traversal of empty, tuple, union, wrapper,
+  // and constraint-checking classes.
+  template <typename A, typename V>
+  static std::enable_if_t<EmptyTrait<A>> Walk(const A &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      visitor.Post(x);
+    }
   }
-}
-template <typename A, typename B, typename M>
-void Walk(std::pair<A, B> &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.first, mutator);
-    Walk(x.second, mutator);
+  template <typename A, typename M>
+  static std::enable_if_t<EmptyTrait<A>> Walk(A &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      mutator.Post(x);
+    }
   }
-}
 
-// Trait-determined traversal of empty, tuple, union, wrapper,
-// and constraint-checking classes.
-template <typename A, typename V>
-std::enable_if_t<EmptyTrait<A>> Walk(const A &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    visitor.Post(x);
+  template <typename A, typename V>
+  static std::enable_if_t<TupleTrait<A>> Walk(const A &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.t, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename A, typename M>
-std::enable_if_t<EmptyTrait<A>> Walk(A &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    mutator.Post(x);
+  template <typename A, typename M>
+  static std::enable_if_t<TupleTrait<A>> Walk(A &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.t, mutator);
+      mutator.Post(x);
+    }
   }
-}
 
-template <typename A, typename V>
-std::enable_if_t<TupleTrait<A>> Walk(const A &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.t, visitor);
-    visitor.Post(x);
+  template <typename A, typename V>
+  static std::enable_if_t<UnionTrait<A>> Walk(const A &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.u, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename A, typename M>
-std::enable_if_t<TupleTrait<A>> Walk(A &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.t, mutator);
-    mutator.Post(x);
+  template <typename A, typename M>
+  static std::enable_if_t<UnionTrait<A>> Walk(A &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.u, mutator);
+      mutator.Post(x);
+    }
   }
-}
 
-template <typename A, typename V>
-std::enable_if_t<UnionTrait<A>> Walk(const A &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.u, visitor);
-    visitor.Post(x);
+  template <typename A, typename V>
+  static std::enable_if_t<WrapperTrait<A>> Walk(const A &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.v, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename A, typename M>
-std::enable_if_t<UnionTrait<A>> Walk(A &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.u, mutator);
-    mutator.Post(x);
+  template <typename A, typename M>
+  static std::enable_if_t<WrapperTrait<A>> Walk(A &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.v, mutator);
+      mutator.Post(x);
+    }
   }
-}
 
-template <typename A, typename V>
-std::enable_if_t<WrapperTrait<A>> Walk(const A &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.v, visitor);
-    visitor.Post(x);
+  template <typename A, typename V>
+  static std::enable_if_t<ConstraintTrait<A>> Walk(const A &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.thing, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename A, typename M>
-std::enable_if_t<WrapperTrait<A>> Walk(A &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.v, mutator);
-    mutator.Post(x);
+  template <typename A, typename M>
+  static std::enable_if_t<ConstraintTrait<A>> Walk(A &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.thing, mutator);
+      mutator.Post(x);
+    }
   }
-}
 
-template <typename A, typename V>
-std::enable_if_t<ConstraintTrait<A>> Walk(const A &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.thing, visitor);
-    visitor.Post(x);
+  template <typename T, typename V>
+  static void Walk(const common::Indirection<T> &x, V &visitor) {
+    Walk(x.value(), visitor);
   }
-}
-template <typename A, typename M>
-std::enable_if_t<ConstraintTrait<A>> Walk(A &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.thing, mutator);
-    mutator.Post(x);
+  template <typename T, typename M>
+  static void Walk(common::Indirection<T> &x, M &mutator) {
+    Walk(x.value(), mutator);
   }
-}
-
-template <typename T, typename V>
-void Walk(const common::Indirection<T> &x, V &visitor) {
-  Walk(x.value(), visitor);
-}
-template <typename T, typename M>
-void Walk(common::Indirection<T> &x, M &mutator) {
-  Walk(x.value(), mutator);
-}
 
-template <typename T, typename V> void Walk(const Statement<T> &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    // N.B. The label, if any, is not visited.
-    Walk(x.source, visitor);
-    Walk(x.statement, visitor);
-    visitor.Post(x);
+  template <typename T, typename V>
+  static void Walk(const Statement<T> &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      // N.B. The label, if any, is not visited.
+      Walk(x.source, visitor);
+      Walk(x.statement, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename T, typename M> void Walk(Statement<T> &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    // N.B. The label, if any, is not visited.
-    Walk(x.source, mutator);
-    Walk(x.statement, mutator);
-    mutator.Post(x);
+  template <typename T, typename M>
+  static void Walk(Statement<T> &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      // N.B. The label, if any, is not visited.
+      Walk(x.source, mutator);
+      Walk(x.statement, mutator);
+      mutator.Post(x);
+    }
   }
-}
 
-template <typename T, typename V>
-void Walk(const UnlabeledStatement<T> &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.source, visitor);
-    Walk(x.statement, visitor);
-    visitor.Post(x);
+  template <typename T, typename V>
+  static void Walk(const UnlabeledStatement<T> &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.source, visitor);
+      Walk(x.statement, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename T, typename M>
-void Walk(UnlabeledStatement<T> &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.source, mutator);
-    Walk(x.statement, mutator);
-    mutator.Post(x);
+  template <typename T, typename M>
+  static void Walk(UnlabeledStatement<T> &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.source, mutator);
+      Walk(x.statement, mutator);
+      mutator.Post(x);
+    }
   }
-}
 
-template <typename V> void Walk(const Name &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.source, visitor);
-    visitor.Post(x);
+  template <typename V> static void Walk(const Name &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.source, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(Name &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.source, mutator);
-    mutator.Post(x);
+  template <typename M> static void Walk(Name &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.source, mutator);
+      mutator.Post(x);
+    }
   }
-}
 
-template <typename V> void Walk(const AcSpec &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.type, visitor);
-    Walk(x.values, visitor);
-    visitor.Post(x);
+  template <typename V> static void Walk(const AcSpec &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.type, visitor);
+      Walk(x.values, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(AcSpec &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.type, mutator);
-    Walk(x.values, mutator);
-    mutator.Post(x);
+  template <typename M> static void Walk(AcSpec &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.type, mutator);
+      Walk(x.values, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V> void Walk(const ArrayElement &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.base, visitor);
-    Walk(x.subscripts, visitor);
-    visitor.Post(x);
+  template <typename V> static void Walk(const ArrayElement &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.base, visitor);
+      Walk(x.subscripts, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(ArrayElement &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.base, mutator);
-    Walk(x.subscripts, mutator);
-    mutator.Post(x);
+  template <typename M> static void Walk(ArrayElement &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.base, mutator);
+      Walk(x.subscripts, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V>
-void Walk(const CharSelector::LengthAndKind &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.length, visitor);
-    Walk(x.kind, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const CharSelector::LengthAndKind &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.length, visitor);
+      Walk(x.kind, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(CharSelector::LengthAndKind &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.length, mutator);
-    Walk(x.kind, mutator);
-    mutator.Post(x);
+  template <typename M>
+  static void Walk(CharSelector::LengthAndKind &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.length, mutator);
+      Walk(x.kind, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V> void Walk(const CaseValueRange::Range &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.lower, visitor);
-    Walk(x.upper, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const CaseValueRange::Range &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.lower, visitor);
+      Walk(x.upper, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(CaseValueRange::Range &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.lower, mutator);
-    Walk(x.upper, mutator);
-    mutator.Post(x);
+  template <typename M> static void Walk(CaseValueRange::Range &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.lower, mutator);
+      Walk(x.upper, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V> void Walk(const CoindexedNamedObject &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.base, visitor);
-    Walk(x.imageSelector, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const CoindexedNamedObject &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.base, visitor);
+      Walk(x.imageSelector, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(CoindexedNamedObject &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.base, mutator);
-    Walk(x.imageSelector, mutator);
-    mutator.Post(x);
+  template <typename M> static void Walk(CoindexedNamedObject &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.base, mutator);
+      Walk(x.imageSelector, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V>
-void Walk(const DeclarationTypeSpec::Class &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.derived, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const DeclarationTypeSpec::Class &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.derived, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(DeclarationTypeSpec::Class &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.derived, mutator);
-    mutator.Post(x);
+  template <typename M>
+  static void Walk(DeclarationTypeSpec::Class &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.derived, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V>
-void Walk(const DeclarationTypeSpec::Type &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.derived, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const DeclarationTypeSpec::Type &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.derived, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(DeclarationTypeSpec::Type &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.derived, mutator);
-    mutator.Post(x);
+  template <typename M>
+  static void Walk(DeclarationTypeSpec::Type &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.derived, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V> void Walk(const ImportStmt &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.names, visitor);
-    visitor.Post(x);
+  template <typename V> static void Walk(const ImportStmt &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.names, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(ImportStmt &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.names, mutator);
-    mutator.Post(x);
+  template <typename M> static void Walk(ImportStmt &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.names, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V>
-void Walk(const IntrinsicTypeSpec::Character &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.selector, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const IntrinsicTypeSpec::Character &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.selector, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(IntrinsicTypeSpec::Character &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.selector, mutator);
-    mutator.Post(x);
+  template <typename M>
+  static void Walk(IntrinsicTypeSpec::Character &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.selector, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V>
-void Walk(const IntrinsicTypeSpec::Complex &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.kind, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const IntrinsicTypeSpec::Complex &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.kind, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(IntrinsicTypeSpec::Complex &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.kind, mutator);
-    mutator.Post(x);
+  template <typename M>
+  static void Walk(IntrinsicTypeSpec::Complex &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.kind, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V>
-void Walk(const IntrinsicTypeSpec::Logical &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.kind, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const IntrinsicTypeSpec::Logical &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.kind, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(IntrinsicTypeSpec::Logical &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.kind, mutator);
-    mutator.Post(x);
+  template <typename M>
+  static void Walk(IntrinsicTypeSpec::Logical &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.kind, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V> void Walk(const IntrinsicTypeSpec::Real &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.kind, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const IntrinsicTypeSpec::Real &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.kind, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(IntrinsicTypeSpec::Real &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.kind, mutator);
-    mutator.Post(x);
+  template <typename M>
+  static void Walk(IntrinsicTypeSpec::Real &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.kind, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename A, typename B, typename V>
-void Walk(const LoopBounds<A, B> &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.name, visitor);
-    Walk(x.lower, visitor);
-    Walk(x.upper, visitor);
-    Walk(x.step, visitor);
-    visitor.Post(x);
+  template <typename A, typename B, typename V>
+  static void Walk(const LoopBounds<A, B> &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.name, visitor);
+      Walk(x.lower, visitor);
+      Walk(x.upper, visitor);
+      Walk(x.step, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename A, typename B, typename M>
-void Walk(LoopBounds<A, B> &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.name, mutator);
-    Walk(x.lower, mutator);
-    Walk(x.upper, mutator);
-    Walk(x.step, mutator);
-    mutator.Post(x);
+  template <typename A, typename B, typename M>
+  static void Walk(LoopBounds<A, B> &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.name, mutator);
+      Walk(x.lower, mutator);
+      Walk(x.upper, mutator);
+      Walk(x.step, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V> void Walk(const CommonStmt &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.blocks, visitor);
-    visitor.Post(x);
+  template <typename V> static void Walk(const CommonStmt &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.blocks, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(CommonStmt &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.blocks, mutator);
-    mutator.Post(x);
+  template <typename M> static void Walk(CommonStmt &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.blocks, mutator);
+      mutator.Post(x);
+    }
   }
-}
 
-// Expr traversal uses iteration rather than recursion to avoid
-// blowing out the stack on very deep expression parse trees.
-// It replaces implementations that looked like:
-//   template <typename V> void Walk(const Expr &x, V visitor) {
-//     if (visitor.Pre(x)) {      // Pre on the Expr
-//       Walk(x.source, visitor);
-//       // Pre on the operator, walk the operands, Post on operator
-//       Walk(x.u, visitor);
-//       visitor.Post(x);         // Post on the Expr
-//     }
-//   }
-template <typename A, typename V, typename UNARY, typename BINARY>
-static void IterativeWalk(A &start, V &visitor) {
-  struct ExprWorkList {
-    ExprWorkList(A &x) : expr(&x) {}
-    bool doPostExpr{false}, doPostOpr{false};
-    A *expr;
-  };
-  std::vector<ExprWorkList> stack;
-  stack.emplace_back(start);
-  do {
-    A &expr{*stack.back().expr};
-    if (stack.back().doPostOpr) {
-      stack.back().doPostOpr = false;
-      common::visit([&visitor](auto &y) { visitor.Post(y); }, expr.u);
-    } else if (stack.back().doPostExpr) {
-      visitor.Post(expr);
-      stack.pop_back();
-    } else if (!visitor.Pre(expr)) {
-      stack.pop_back();
-    } else {
-      stack.back().doPostExpr = true;
-      Walk(expr.source, visitor);
-      UNARY *unary{nullptr};
-      BINARY *binary{nullptr};
-      common::visit(
-          [&unary, &binary](auto &y) {
-            if constexpr (std::is_convertible_v<decltype(&y), UNARY *>) {
-              unary = &y;
-            } else if constexpr (std::is_convertible_v<decltype(&y),
-                                     BINARY *>) {
-              binary = &y;
-            }
-          },
-          expr.u);
-      if (!unary && !binary) {
-        Walk(expr.u, visitor);
-      } else if (common::visit(
-                     [&visitor](auto &y) { return visitor.Pre(y); }, expr.u)) {
-        stack.back().doPostOpr = true;
-        if (unary) {
-          stack.emplace_back(unary->v.value());
-        } else {
-          stack.emplace_back(std::get<1>(binary->t).value());
-          stack.emplace_back(std::get<0>(binary->t).value());
+  // Expr traversal uses iteration rather than recursion to avoid
+  // blowing out the stack on very deep expression parse trees.
+  // It replaces implementations that looked like:
+  //   template <typename V> static void Walk(const Expr &x, V visitor) {
+  //     if (visitor.Pre(x)) {      // Pre on the Expr
+  //       Walk(x.source, visitor);
+  //       // Pre on the operator, walk the operands, Post on operator
+  //       Walk(x.u, visitor);
+  //       visitor.Post(x);         // Post on the Expr
+  //     }
+  //   }
+  template <typename A, typename V, typename UNARY, typename BINARY>
+  static void IterativeWalk(A &start, V &visitor) {
+    struct ExprWorkList {
+      ExprWorkList(A &x) : expr(&x) {}
+      bool doPostExpr{false}, doPostOpr{false};
+      A *expr;
+    };
+    std::vector<ExprWorkList> stack;
+    stack.emplace_back(start);
+    do {
+      A &expr{*stack.back().expr};
+      if (stack.back().doPostOpr) {
+        stack.back().doPostOpr = false;
+        common::visit([&visitor](auto &y) { visitor.Post(y); }, expr.u);
+      } else if (stack.back().doPostExpr) {
+        visitor.Post(expr);
+        stack.pop_back();
+      } else if (!visitor.Pre(expr)) {
+        stack.pop_back();
+      } else {
+        stack.back().doPostExpr = true;
+        Walk(expr.source, visitor);
+        UNARY *unary{nullptr};
+        BINARY *binary{nullptr};
+        common::visit(
+            [&unary, &binary](auto &y) {
+              if constexpr (std::is_convertible_v<decltype(&y), UNARY *>) {
+                unary = &y;
+              } else if constexpr (std::is_convertible_v<decltype(&y),
+                                       BINARY *>) {
+                binary = &y;
+              }
+            },
+            expr.u);
+        if (!unary && !binary) {
+          Walk(expr.u, visitor);
+        } else if (common::visit([&visitor](auto &y) { return visitor.Pre(y); },
+                       expr.u)) {
+          stack.back().doPostOpr = true;
+          if (unary) {
+            stack.emplace_back(unary->v.value());
+          } else {
+            stack.emplace_back(std::get<1>(binary->t).value());
+            stack.emplace_back(std::get<0>(binary->t).value());
+          }
         }
       }
-    }
-  } while (!stack.empty());
-}
-template <typename V> void Walk(const Expr &x, V &visitor) {
-  IterativeWalk<const Expr, V, const Expr::IntrinsicUnary,
-      const Expr::IntrinsicBinary>(x, visitor);
-}
-template <typename M> void Walk(Expr &x, M &mutator) {
-  IterativeWalk<Expr, M, Expr::IntrinsicUnary, Expr::IntrinsicBinary>(
-      x, mutator);
-}
+    } while (!stack.empty());
+  }
+  template <typename V> static void Walk(const Expr &x, V &visitor) {
+    IterativeWalk<const Expr, V, const Expr::IntrinsicUnary,
+        const Expr::IntrinsicBinary>(x, visitor);
+  }
+  template <typename M> static void Walk(Expr &x, M &mutator) {
+    IterativeWalk<Expr, M, Expr::IntrinsicUnary, Expr::IntrinsicBinary>(
+        x, mutator);
+  }
 
-template <typename V> void Walk(const Designator &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.source, visitor);
-    Walk(x.u, visitor);
-    visitor.Post(x);
+  template <typename V> static void Walk(const Designator &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.source, visitor);
+      Walk(x.u, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(Designator &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.source, mutator);
-    Walk(x.u, mutator);
-    mutator.Post(x);
+  template <typename M> static void Walk(Designator &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.source, mutator);
+      Walk(x.u, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V> void Walk(const FunctionReference &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.source, visitor);
-    Walk(x.v, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const FunctionReference &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.source, visitor);
+      Walk(x.v, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(FunctionReference &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.source, mutator);
-    Walk(x.v, mutator);
-    mutator.Post(x);
+  template <typename M> static void Walk(FunctionReference &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.source, mutator);
+      Walk(x.v, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V> void Walk(const CallStmt &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.source, visitor);
-    Walk(x.call, visitor);
-    Walk(x.chevrons, visitor);
-    visitor.Post(x);
+  template <typename V> static void Walk(const CallStmt &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.source, visitor);
+      Walk(x.call, visitor);
+      Walk(x.chevrons, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(CallStmt &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.source, mutator);
-    Walk(x.call, mutator);
-    Walk(x.chevrons, mutator);
-    mutator.Post(x);
+  template <typename M> static void Walk(CallStmt &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.source, mutator);
+      Walk(x.call, mutator);
+      Walk(x.chevrons, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V> void Walk(const PartRef &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.name, visitor);
-    Walk(x.subscripts, visitor);
-    Walk(x.imageSelector, visitor);
-    visitor.Post(x);
+  template <typename V> static void Walk(const PartRef &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.name, visitor);
+      Walk(x.subscripts, visitor);
+      Walk(x.imageSelector, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(PartRef &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.name, mutator);
-    Walk(x.subscripts, mutator);
-    Walk(x.imageSelector, mutator);
-    mutator.Post(x);
+  template <typename M> static void Walk(PartRef &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.name, mutator);
+      Walk(x.subscripts, mutator);
+      Walk(x.imageSelector, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V> void Walk(const ReadStmt &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.iounit, visitor);
-    Walk(x.format, visitor);
-    Walk(x.controls, visitor);
-    Walk(x.items, visitor);
-    visitor.Post(x);
+  template <typename V> static void Walk(const ReadStmt &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.iounit, visitor);
+      Walk(x.format, visitor);
+      Walk(x.controls, visitor);
+      Walk(x.items, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(ReadStmt &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.iounit, mutator);
-    Walk(x.format, mutator);
-    Walk(x.controls, mutator);
-    Walk(x.items, mutator);
-    mutator.Post(x);
+  template <typename M> static void Walk(ReadStmt &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.iounit, mutator);
+      Walk(x.format, mutator);
+      Walk(x.controls, mutator);
+      Walk(x.items, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V> void Walk(const SignedIntLiteralConstant &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.source, visitor);
-    Walk(x.t, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const SignedIntLiteralConstant &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.source, visitor);
+      Walk(x.t, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(SignedIntLiteralConstant &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.source, mutator);
-    Walk(x.t, mutator);
-    mutator.Post(x);
+  template <typename M>
+  static void Walk(SignedIntLiteralConstant &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.source, mutator);
+      Walk(x.t, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V> void Walk(const RealLiteralConstant &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.real, visitor);
-    Walk(x.kind, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const RealLiteralConstant &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.real, visitor);
+      Walk(x.kind, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(RealLiteralConstant &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.real, mutator);
-    Walk(x.kind, mutator);
-    mutator.Post(x);
+  template <typename M> static void Walk(RealLiteralConstant &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.real, mutator);
+      Walk(x.kind, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V>
-void Walk(const RealLiteralConstant::Real &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.source, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const RealLiteralConstant::Real &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.source, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(RealLiteralConstant::Real &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.source, mutator);
-    mutator.Post(x);
+  template <typename M>
+  static void Walk(RealLiteralConstant::Real &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.source, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V> void Walk(const StructureComponent &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.base, visitor);
-    Walk(x.component, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const StructureComponent &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.base, visitor);
+      Walk(x.component, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(StructureComponent &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.base, mutator);
-    Walk(x.component, mutator);
-    mutator.Post(x);
+  template <typename M> static void Walk(StructureComponent &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.base, mutator);
+      Walk(x.component, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V> void Walk(const Suffix &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.binding, visitor);
-    Walk(x.resultName, visitor);
-    visitor.Post(x);
+  template <typename V> static void Walk(const Suffix &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.binding, visitor);
+      Walk(x.resultName, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(Suffix &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.binding, mutator);
-    Walk(x.resultName, mutator);
-    mutator.Post(x);
+  template <typename M> static void Walk(Suffix &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.binding, mutator);
+      Walk(x.resultName, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V>
-void Walk(const TypeBoundProcedureStmt::WithInterface &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.interfaceName, visitor);
-    Walk(x.attributes, visitor);
-    Walk(x.bindingNames, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const TypeBoundProcedureStmt::WithInterface &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.interfaceName, visitor);
+      Walk(x.attributes, visitor);
+      Walk(x.bindingNames, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M>
-void Walk(TypeBoundProcedureStmt::WithInterface &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.interfaceName, mutator);
-    Walk(x.attributes, mutator);
-    Walk(x.bindingNames, mutator);
-    mutator.Post(x);
+  template <typename M>
+  static void Walk(TypeBoundProcedureStmt::WithInterface &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.interfaceName, mutator);
+      Walk(x.attributes, mutator);
+      Walk(x.bindingNames, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V>
-void Walk(const TypeBoundProcedureStmt::WithoutInterface &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.attributes, visitor);
-    Walk(x.declarations, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(
+      const TypeBoundProcedureStmt::WithoutInterface &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.attributes, visitor);
+      Walk(x.declarations, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M>
-void Walk(TypeBoundProcedureStmt::WithoutInterface &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.attributes, mutator);
-    Walk(x.declarations, mutator);
-    mutator.Post(x);
+  template <typename M>
+  static void Walk(TypeBoundProcedureStmt::WithoutInterface &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.attributes, mutator);
+      Walk(x.declarations, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V> void Walk(const UseStmt &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.nature, visitor);
-    Walk(x.moduleName, visitor);
-    Walk(x.u, visitor);
-    visitor.Post(x);
+  template <typename V> static void Walk(const UseStmt &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.nature, visitor);
+      Walk(x.moduleName, visitor);
+      Walk(x.u, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(UseStmt &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.nature, mutator);
-    Walk(x.moduleName, mutator);
-    Walk(x.u, mutator);
-    mutator.Post(x);
+  template <typename M> static void Walk(UseStmt &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.nature, mutator);
+      Walk(x.moduleName, mutator);
+      Walk(x.u, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V> void Walk(const WriteStmt &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.iounit, visitor);
-    Walk(x.format, visitor);
-    Walk(x.controls, visitor);
-    Walk(x.items, visitor);
-    visitor.Post(x);
+  template <typename V> static void Walk(const WriteStmt &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.iounit, visitor);
+      Walk(x.format, visitor);
+      Walk(x.controls, visitor);
+      Walk(x.items, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(WriteStmt &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.iounit, mutator);
-    Walk(x.format, mutator);
-    Walk(x.controls, mutator);
-    Walk(x.items, mutator);
-    mutator.Post(x);
+  template <typename M> static void Walk(WriteStmt &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.iounit, mutator);
+      Walk(x.format, mutator);
+      Walk(x.controls, mutator);
+      Walk(x.items, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V> void Walk(const format::ControlEditDesc &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.kind, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const format::ControlEditDesc &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.kind, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(format::ControlEditDesc &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.kind, mutator);
-    mutator.Post(x);
+  template <typename M>
+  static void Walk(format::ControlEditDesc &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.kind, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V>
-void Walk(const format::DerivedTypeDataEditDesc &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.type, visitor);
-    Walk(x.parameters, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const format::DerivedTypeDataEditDesc &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.type, visitor);
+      Walk(x.parameters, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M>
-void Walk(format::DerivedTypeDataEditDesc &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.type, mutator);
-    Walk(x.parameters, mutator);
-    mutator.Post(x);
+  template <typename M>
+  static void Walk(format::DerivedTypeDataEditDesc &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.type, mutator);
+      Walk(x.parameters, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V> void Walk(const format::FormatItem &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.repeatCount, visitor);
-    Walk(x.u, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const format::FormatItem &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.repeatCount, visitor);
+      Walk(x.u, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(format::FormatItem &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.repeatCount, mutator);
-    Walk(x.u, mutator);
-    mutator.Post(x);
+  template <typename M> static void Walk(format::FormatItem &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.repeatCount, mutator);
+      Walk(x.u, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V>
-void Walk(const format::FormatSpecification &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.items, visitor);
-    Walk(x.unlimitedItems, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const format::FormatSpecification &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.items, visitor);
+      Walk(x.unlimitedItems, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(format::FormatSpecification &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.items, mutator);
-    Walk(x.unlimitedItems, mutator);
-    mutator.Post(x);
+  template <typename M>
+  static void Walk(format::FormatSpecification &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.items, mutator);
+      Walk(x.unlimitedItems, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V>
-void Walk(const format::IntrinsicTypeDataEditDesc &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.kind, visitor);
-    Walk(x.width, visitor);
-    Walk(x.digits, visitor);
-    Walk(x.exponentWidth, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const format::IntrinsicTypeDataEditDesc &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.kind, visitor);
+      Walk(x.width, visitor);
+      Walk(x.digits, visitor);
+      Walk(x.exponentWidth, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M>
-void Walk(format::IntrinsicTypeDataEditDesc &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.kind, mutator);
-    Walk(x.width, mutator);
-    Walk(x.digits, mutator);
-    Walk(x.exponentWidth, mutator);
-    mutator.Post(x);
+  template <typename M>
+  static void Walk(format::IntrinsicTypeDataEditDesc &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.kind, mutator);
+      Walk(x.width, mutator);
+      Walk(x.digits, mutator);
+      Walk(x.exponentWidth, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V> void Walk(const CompilerDirective &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.source, visitor);
-    Walk(x.u, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const CompilerDirective &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.source, visitor);
+      Walk(x.u, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(CompilerDirective &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.source, mutator);
-    Walk(x.u, mutator);
-    mutator.Post(x);
+  template <typename M> static void Walk(CompilerDirective &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.source, mutator);
+      Walk(x.u, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V>
-void Walk(const CompilerDirective::Unrecognized &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const CompilerDirective::Unrecognized &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      visitor.Post(x);
+    }
   }
-}
-template <typename M>
-void Walk(CompilerDirective::Unrecognized &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    mutator.Post(x);
+  template <typename M>
+  static void Walk(CompilerDirective::Unrecognized &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      mutator.Post(x);
+    }
   }
-}
-template <typename V>
-void Walk(const OmpLinearClause::WithModifier &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.modifier, visitor);
-    Walk(x.names, visitor);
-    Walk(x.step, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const OmpLinearClause::WithModifier &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.modifier, visitor);
+      Walk(x.names, visitor);
+      Walk(x.step, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M> void Walk(OmpLinearClause::WithModifier &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.modifier, mutator);
-    Walk(x.names, mutator);
-    Walk(x.step, mutator);
-    mutator.Post(x);
+  template <typename M>
+  static void Walk(OmpLinearClause::WithModifier &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.modifier, mutator);
+      Walk(x.names, mutator);
+      Walk(x.step, mutator);
+      mutator.Post(x);
+    }
   }
-}
-template <typename V>
-void Walk(const OmpLinearClause::WithoutModifier &x, V &visitor) {
-  if (visitor.Pre(x)) {
-    Walk(x.names, visitor);
-    Walk(x.step, visitor);
-    visitor.Post(x);
+  template <typename V>
+  static void Walk(const OmpLinearClause::WithoutModifier &x, V &visitor) {
+    if (visitor.Pre(x)) {
+      Walk(x.names, visitor);
+      Walk(x.step, visitor);
+      visitor.Post(x);
+    }
   }
-}
-template <typename M>
-void Walk(OmpLinearClause::WithoutModifier &x, M &mutator) {
-  if (mutator.Pre(x)) {
-    Walk(x.names, mutator);
-    Walk(x.step, mutator);
-    mutator.Post(x);
+  template <typename M>
+  static void Walk(OmpLinearClause::WithoutModifier &x, M &mutator) {
+    if (mutator.Pre(x)) {
+      Walk(x.names, mutator);
+      Walk(x.step, mutator);
+      mutator.Post(x);
+    }
   }
+};
+} // namespace detail
+
+template <typename A, typename V> void Walk(const A &x, V &visitor) {
+  detail::ParseTreeVisitorLookupScope::Walk(x, visitor);
 }
+
+template <typename A, typename M> void Walk(A &x, M &mutator) {
+  detail::ParseTreeVisitorLookupScope::Walk(x, mutator);
+}
+
 } // namespace Fortran::parser
 #endif // FORTRAN_PARSER_PARSE_TREE_VISITOR_H_


        


More information about the flang-commits mailing list