diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h --- a/flang/include/flang/Semantics/symbol.h +++ b/flang/include/flang/Semantics/symbol.h @@ -15,7 +15,6 @@ #include "flang/Common/reference.h" #include "flang/Common/visit.h" #include "llvm/ADT/DenseMapInfo.h" -#include "llvm/ADT/SmallSet.h" #include #include @@ -639,10 +638,7 @@ bool operator==(const Symbol &that) const { return this == &that; } bool operator!=(const Symbol &that) const { return !(*this == that); } - int Rank() const { - VisitedSymbols visited; - return RankImpl(visited); - } + int Rank() const { return RankImpl(); } int Corank() const { return common::visit( @@ -692,33 +688,32 @@ friend llvm::raw_ostream &DumpForUnparse( llvm::raw_ostream &, const Symbol &, bool); - using VisitedSymbols = llvm::SmallSet; + static constexpr int startRecursionDepth = 100; - inline const DeclTypeSpec *GetTypeImpl(VisitedSymbols &visited) const; - inline int RankImpl(VisitedSymbols &visited) const { - if (visited.contains(this)) { + inline const DeclTypeSpec *GetTypeImpl(int depth = startRecursionDepth) const; + inline int RankImpl(int depth = startRecursionDepth) const { + if (depth-- == 0) { return 0; } - visited.insert(this); return common::visit( common::visitors{ [&](const SubprogramDetails &sd) { - return sd.isFunction() ? sd.result().RankImpl(visited) : 0; + return sd.isFunction() ? sd.result().RankImpl(depth) : 0; }, [](const GenericDetails &) { return 0; /*TODO*/ }, [&](const ProcBindingDetails &x) { - return x.symbol().RankImpl(visited); + return x.symbol().RankImpl(depth); }, - [&](const UseDetails &x) { return x.symbol().RankImpl(visited); }, + [&](const UseDetails &x) { return x.symbol().RankImpl(depth); }, [&](const HostAssocDetails &x) { - return x.symbol().RankImpl(visited); + return x.symbol().RankImpl(depth); }, [](const ObjectEntityDetails &oed) { return oed.shape().Rank(); }, [&](const ProcEntityDetails &ped) { const Symbol *iface{ped.interface().symbol()}; - return iface ? iface->RankImpl(visited) : 0; + return iface ? iface->RankImpl(depth) : 0; }, [](const AssocEntityDetails &aed) { if (const auto &expr{aed.expr()}) { @@ -804,40 +799,36 @@ const_cast(this)->GetType()); } -inline const DeclTypeSpec *Symbol::GetTypeImpl(VisitedSymbols &visited) const { - if (visited.contains(this)) { - return nullptr; +inline const DeclTypeSpec *Symbol::GetTypeImpl(int depth) const { + if (depth-- == 0) { + return 0; } - visited.insert(this); return common::visit( common::visitors{ [](const EntityDetails &x) { return x.type(); }, [](const ObjectEntityDetails &x) { return x.type(); }, [](const AssocEntityDetails &x) { return x.type(); }, [&](const SubprogramDetails &x) { - return x.isFunction() ? x.result().GetTypeImpl(visited) : nullptr; + return x.isFunction() ? x.result().GetTypeImpl(depth) : nullptr; }, [&](const ProcEntityDetails &x) { const Symbol *symbol{x.interface().symbol()}; - return symbol ? symbol->GetTypeImpl(visited) : x.interface().type(); + return symbol ? symbol->GetTypeImpl(depth) : x.interface().type(); }, [&](const ProcBindingDetails &x) { - return x.symbol().GetTypeImpl(visited); + return x.symbol().GetTypeImpl(depth); }, [](const TypeParamDetails &x) { return x.type(); }, - [&](const UseDetails &x) { return x.symbol().GetTypeImpl(visited); }, + [&](const UseDetails &x) { return x.symbol().GetTypeImpl(depth); }, [&](const HostAssocDetails &x) { - return x.symbol().GetTypeImpl(visited); + return x.symbol().GetTypeImpl(depth); }, [](const auto &) -> const DeclTypeSpec * { return nullptr; }, }, details_); } -inline const DeclTypeSpec *Symbol::GetType() const { - VisitedSymbols visited; - return GetTypeImpl(visited); -} +inline const DeclTypeSpec *Symbol::GetType() const { return GetTypeImpl(); } // Sets and maps keyed by Symbols