52  explicit Traverse(Visitor &v) : visitor_{v} {}
 
   55  template <
typename A, 
bool C>
 
   57    return visitor_(x.value());
 
   61    return visitor_(p.get());
 
   63  template <
typename _> Result operator()(
const SymbolRef x)
 const {
 
   66  template <
typename A> Result operator()(
const std::unique_ptr<A> &x)
 const {
 
   67    return visitor_(x.get());
 
   69  template <
typename A> Result operator()(
const std::shared_ptr<A> &x)
 const {
 
   70    return visitor_(x.get());
 
   72  template <
typename A> Result operator()(
const A *x)
 const {
 
   76      return visitor_.Default();
 
   79  template <
typename A> Result operator()(
const std::optional<A> &x)
 const {
 
   83      return visitor_.Default();
 
   86  template <
typename... As>
 
   87  Result operator()(
const std::variant<As...> &u)
 const {
 
   88    return common::visit([=](
const auto &y) { 
return visitor_(y); }, u);
 
   90  template <
typename A> Result operator()(
const std::vector<A> &x)
 const {
 
   91    return CombineContents(x);
 
   93  template <
typename A, 
typename B>
 
   94  Result operator()(
const std::pair<A, B> &x)
 const {
 
   95    return Combine(x.first, x.second);
 
   99  Result operator()(
const BOZLiteralConstant &)
 const {
 
  100    return visitor_.Default();
 
  102  Result operator()(
const NullPointer &)
 const { 
return visitor_.Default(); }
 
  103  template <
typename T> Result operator()(
const Constant<T> &x)
 const {
 
  104    if constexpr (T::category == TypeCategory::Derived) {
 
  105      return visitor_.Combine(
 
  106          visitor_(x.result().derivedTypeSpec()), CombineContents(x.values()));
 
  108      return visitor_.Default();
 
  111  Result operator()(
const Symbol &symbol)
 const {
 
  112    const Symbol &ultimate{symbol.GetUltimate()};
 
  113    if constexpr (TraverseAssocEntityDetails) {
 
  114      if (
const auto *assoc{
 
  116        return visitor_(assoc->expr());
 
  119    return visitor_.Default();
 
  122    return visitor_.Default();
 
  124  Result operator()(
const ImpliedDoIndex &)
 const { 
return visitor_.Default(); }
 
  127  Result operator()(
const BaseObject &x)
 const { 
return visitor_(x.u); }
 
  128  Result operator()(
const Component &x)
 const {
 
  129    return Combine(x.base(), x.symbol());
 
  132    if (
const Component * component{x.UnwrapComponent()}) {
 
  133      return visitor_(*component);
 
  135      return visitor_(DEREF(x.UnwrapSymbolRef()));
 
  139    return visitor_(x.base());
 
  141  Result operator()(
const Triplet &x)
 const {
 
  142    return Combine(x.GetLower(), x.GetUpper(), x.GetStride());
 
  144  Result operator()(
const Subscript &x)
 const { 
return visitor_(x.u); }
 
  145  Result operator()(
const ArrayRef &x)
 const {
 
  146    return Combine(x.base(), x.subscript());
 
  148  Result operator()(
const CoarrayRef &x)
 const {
 
  149    return Combine(x.base(), x.cosubscript(), x.stat(), x.team());
 
  151  Result operator()(
const DataRef &x)
 const { 
return visitor_(x.u); }
 
  152  Result operator()(
const Substring &x)
 const {
 
  153    return Combine(x.parent(), x.GetLower(), x.GetUpper());
 
  156    return visitor_(x.complex());
 
  158  template <
typename T> Result operator()(
const Designator<T> &x)
 const {
 
  159    return visitor_(x.u);
 
  162    return visitor_(x.base());
 
  167    return visitor_.Default();
 
  170    if (
const Component * component{x.GetComponent()}) {
 
  171      return visitor_(*component);
 
  172    } 
else if (
const Symbol * symbol{x.GetSymbol()}) {
 
  173      return visitor_(*symbol);
 
  175      return visitor_(DEREF(x.GetSpecificIntrinsic()));
 
  179    if (
const auto *symbol{x.GetAssumedTypeDummy()}) {
 
  180      return visitor_(*symbol);
 
  182      return visitor_(x.UnwrapExpr());
 
  186    return Combine(x.proc(), x.arguments());
 
  188  template <
typename T> Result operator()(
const FunctionRef<T> &x)
 const {
 
  193  template <
typename T>
 
  195    return visitor_(x.u);
 
  197  template <
typename T>
 
  199    return CombineContents(x);
 
  201  template <
typename T> Result operator()(
const ImpliedDo<T> &x)
 const {
 
  202    return Combine(x.lower(), x.upper(), x.stride(), x.values());
 
  205    return visitor_(x.GetExplicit());
 
  208      const semantics::DerivedTypeSpec::ParameterMapType::value_type &x)
 const {
 
  209    return visitor_(x.second);
 
  212      const semantics::DerivedTypeSpec::ParameterMapType &x)
 const {
 
  213    return CombineContents(x);
 
  216    return Combine(x.originalTypeSymbol(), x.parameters());
 
  218  Result operator()(
const StructureConstructorValues::value_type &x)
 const {
 
  219    return visitor_(x.second);
 
  221  Result operator()(
const StructureConstructorValues &x)
 const {
 
  222    return CombineContents(x);
 
  225    return visitor_.Combine(visitor_(x.derivedTypeSpec()), CombineContents(x));
 
  230  template <
typename D, 
typename R, 
typename... Os>
 
  232    if constexpr (
sizeof...(Os) == 1) {
 
  233      return visitor_(op.left());
 
  235      return CombineOperands(op, std::index_sequence_for<Os...>{});
 
  239    return visitor_(x.u);
 
  241  template <
typename T> Result operator()(
const Expr<T> &x)
 const {
 
  242    return visitor_(x.u);
 
  244  Result operator()(
const Assignment &x)
 const {
 
  245    return Combine(x.lhs, x.rhs, x.u);
 
  248    return visitor_.Default();
 
  252    return visitor_(x.v);
 
  256  template <
typename ITER> Result CombineRange(ITER iter, ITER end)
 const {
 
  258      return visitor_.Default();
 
  260      Result result{visitor_(*iter)};
 
  261      for (++iter; iter != end; ++iter) {
 
  262        result = visitor_.Combine(std::move(result), visitor_(*iter));
 
  268  template <
typename A> Result CombineContents(
const A &x)
 const {
 
  269    return CombineRange(x.begin(), x.end());
 
  272  template <
typename D, 
typename R, 
typename... Os, 
size_t... Is>
 
  273  Result CombineOperands(
 
  275    static_assert(
sizeof...(Os) > 1 && 
"Expecting multiple operands");
 
  276    return Combine(op.template operand<Is>()...);
 
  279  template <
typename A, 
typename... Bs>
 
  280  Result Combine(
const A &x, 
const Bs &...ys)
 const {
 
  281    if constexpr (
sizeof...(Bs) == 0) {
 
  284      return visitor_.Combine(visitor_(x), Combine(ys...));