@@ -751,6 +751,65 @@ bool DescriptorInquiry::operator==(const DescriptorInquiry &that) const {
751751 return field_ == that.field_ && base_ == that.base_ &&
752752 dimension_ == that.dimension_ ;
753753}
754+ #include < type_traits>
755+ #include < utility>
756+ template <typename T, typename = void > struct has_union : std::false_type {};
757+ template <typename T>
758+ struct has_union <T, std::void_t <decltype (T::u)>> : std::true_type {};
759+ template <typename T, typename = void > struct has_base : std::false_type {};
760+ template <typename T>
761+ struct has_base <T, std::void_t <decltype (std::declval<T>().base())>>
762+ : std::true_type {};
763+ template <typename T, typename = void >
764+ struct has_GetFirstSymbol : std::false_type {};
765+ template <typename T>
766+ struct has_GetFirstSymbol <T,
767+ std::void_t <decltype (std::declval<T>().GetFirstSymbol())>>
768+ : std::true_type {};
769+
770+ template <typename P, typename R>
771+ bool TestVariableIsPathFromRoot (const P &path, const R &root) {
772+ const SymbolRef *pathSym, *rootSym;
773+ if constexpr (has_union<P>::value) {
774+ pathSym = std::get_if<SymbolRef>(&path.u );
775+ }
776+ if constexpr (has_union<R>::value) {
777+ rootSym = std::get_if<SymbolRef>(&root.u );
778+ }
779+ if (pathSym) {
780+ return rootSym && AreSameSymbol (*rootSym, *pathSym);
781+ }
782+ if constexpr (has_GetFirstSymbol<P>::value) {
783+ if (rootSym) {
784+ return AreSameSymbol (path.GetFirstSymbol (), *rootSym);
785+ }
786+ }
787+ if constexpr (std::is_same_v<P, R>) {
788+ if (path == root) {
789+ return true ;
790+ }
791+ }
792+ if constexpr (has_base<P>::value) {
793+ return TestVariableIsPathFromRoot (path.base (), root);
794+ }
795+ if constexpr (has_union<P>::value) {
796+ return common::visit (
797+ common::visitors{
798+ [&](const auto &x) { return TestVariableIsPathFromRoot (x, root); },
799+ },
800+ path.u );
801+ }
802+ return false ;
803+ }
804+
805+ bool DataRef::IsPathFrom (const DataRef &that) const {
806+ return TestVariableIsPathFromRoot (*this , that);
807+ }
808+
809+ template <typename T>
810+ bool Designator<T>::IsPathFrom(const Designator<T> &that) const {
811+ return TestVariableIsPathFromRoot (*this , that);
812+ }
754813
755814#ifdef _MSC_VER // disable bogus warning about missing definitions
756815#pragma warning(disable : 4661)
0 commit comments