# # Debugger STL Visualization Script # # Copyright (c) 2001-2002 Green Hills Software, Inc. # # This program is the property of Green Hills Software, Inc, # its contents are proprietary information and no part of it # is to be disclosed to anyone except employees of Green Hills # Software, Inc., or as agreed in writing signed by the President # of Green Hills Software, Inc. # list { signature = {"std::list<*>"} required_fields = {"__size_alloc_"} type = "container" predicate = "if ($_MULTI_MAJOR_VERSION >= 8) {" predicate += " if ($_IDE_SEQUENCE >= 452) {" predicate += " if (!$M_is_ptr(self.__end_.__next_)) {" predicate += " return 0;" predicate += " }" predicate += " }" predicate += "}" predicate += "return 1;" size = "return self.__size_alloc_.__value_" begin_iter = "return self.__end_.__next_;" next_iter = "return self->__next_;" value_from_iter = "return (($M_typeof(self)::__node_pointer)(self))->__value_;" functions { size { name = "size" body = "return self.__size_alloc_.__value_" } front { name = "front" body = "return (($M_typeof(self)::__node_pointer)(self->__end_.__next_))->__value_" } back { name = "back" body = "return (($M_typeof(self)::__node_pointer)(self->__end_.__prev_))->__value_" } empty { name = "empty" body = "return self.__size_alloc_.__value_ == 0" } } } list_iterator { signature = {"std::__list_iterator<*, void*>", "std::__list_const_iterator<*, void*>"} required_fields = {"__ptr_"} type = "structure" predicate = "if ($_MULTI_MAJOR_VERSION >= 8) {" predicate += " if ($_IDE_SEQUENCE >= 452) {" predicate += " if (!$M_is_ptr(self.__ptr_)) {" predicate += " return 0;" predicate += " }" predicate += " }" predicate += "}" predicate += "return self.__ptr_ != 0;" fields { next { name = "__next_" value = "return self.__ptr_->__next_ } prev { name = "__prev_" value = "return self.__ptr_->__prev_ } value { name = "__value_" value = "return (($M_typeof(self.__ptr_)::__node_pointer)(self.__ptr_))->__value_" } } functions { deref { name = "operator*" body = "return (($M_typeof(self.__ptr_)::__node_pointer)(self.__ptr_))->__value_" } } } list_node_base { signature = {"std::__list_node_base<*, void*>"} required_fields = {"__next_", "__prev_"} type = "structure" predicate = "if ($_MULTI_MAJOR_VERSION >= 8) {" predicate += " if ($_IDE_SEQUENCE >= 452) {" predicate += " if (!$M_is_ptr(self.__next_)) {" predicate += " return 0;" predicate += " }" predicate += " }" predicate += "}" predicate += "return 1;" fields { next { name = "__next_" value = "return self.__next_ } prev { name = "__prev_" value = "return self.__prev_ } value { name = "__value_" value = "return (($M_typeof(self)::__node_pointer)(&self))->__value_" } } } vector { signature = {"std::vector<*>"} required_fields = {"__end_cap_"} type = "container" predicate = "if ($_MULTI_MAJOR_VERSION >= 8) {" predicate += " if ($_IDE_SEQUENCE >= 452) {" predicate += " if (!$M_is_ptr(self.__begin_)) {" predicate += " return 0;" predicate += " }" predicate += " }" predicate += "}" predicate += "return 1;" size = "return self.__end_ - self.__begin_" begin_iter = "return self.__begin_;" next_iter = "return self + 1;" direct_iter = "return self + $GHSIndex;" value_from_iter = "return *(self);" functions { size { name = "size" body = "return self.__end_ - self.__begin_" } front { name = "front" body = "return *(self.__begin_);" } back { name = "back" body = "return *(self.__end_ - 1);" } empty { name = "empty" body = "return self.__begin_ == self.__end_" } data { name = "data" body = "return self.__begin_"; } } } vector_iterator { signature = {"std::__wrap_iter<*>"} required_fields = { "__i_" } type = "structure" predicate = "if ($_MULTI_MAJOR_VERSION >= 8) {" predicate += " if ($_IDE_SEQUENCE >= 452) {" predicate += " if (!$M_is_ptr(self.__i_)) {" predicate += " return 0;" predicate += " }" predicate += " }" predicate += "}" predicate += "return self.__i_ != 0;" fields { value { name = "value" value = "return *(self.__i_)" } } functions { deref { name = "operator*" body = "return *(self.__i_)" } } } boolvector { signature = {"std::vector"} required_fields = {"__cap_alloc_"} type = "container" predicate = "if ($_MULTI_MAJOR_VERSION >= 8) {" predicate += " if ($_IDE_SEQUENCE >= 452) {" predicate += " if (!$M_is_ptr(self.__begin_)) {" predicate += " return 0;" predicate += " }" predicate += " }" predicate += "}" predicate += "return 1;" size = "return self.__size_" begin_iter = "$GHSOffset = 0;" begin_iter += "$GHSBPW = ($M_typeof(self)::__bits_per_word);" begin_iter += "$GHSPtr = self.__begin_;" begin_iter += "return $GHSPtr;" next_iter = "if ($GHSOffset+1 < $GHSBPW) {" next_iter += " ++$GHSOffset;" next_iter += "} else {" next_iter += " ++$GHSPtr;" next_iter += " $GHSOffset = 0;" next_iter += "};" next_iter += "return $GHSPtr;" direct_iter = "$GHSOffset += $GHSIndex;" direct_iter += "$GHSPtr += $GHSOffset / $GHSBPW;" direct_iter += "$GHSOffset = $GHSOffset % $GHSBPW;" direct_iter += "return $GHSPtr;" value_from_iter = "$GHSResult = ( (*$GHSPtr >> $GHSOffset) & 1 ) != 0; return $GHSResult;" functions { size { name = "size" body = "return self.__size_" } empty { name = "empty" body = "return self.__size_ == 0" } } } boolvector_iterator { signature = {"std::__bit_iterator, *>"} required_fields = {"__seg_", "__ctz_"} type = "structure" predicate = "if ($_MULTI_MAJOR_VERSION >= 8) {" predicate += " if ($_IDE_SEQUENCE >= 452) {" predicate += " if (!$M_is_ptr(self.__seg_)) {" predicate += " return 0;" predicate += " }" predicate += " }" predicate += "}" predicate += "return self.__seg_ != 0 && self.__ctz_ < ($M_typeof(self)::__bits_per_word);" fields { value { name = "value" value = "return ((*self.__seg_) & (1ULL<"} required_fields = {"first", "second"} type = "structure" fields { first { name = "first" value = "return self.first;" mutable = false } second { name = "second" value = "return self.second;" } } } mapfind { # because PJP.mdv only covers the following signature. signature = { "std::map", "std::map"} required_fields {"__tree_"} type = "function_definer" predicate = "if ($_MULTI_MAJOR_VERSION >= 8) {" predicate += " if ($_IDE_SEQUENCE >= 452) {" predicate += " if (!$M_is_ptr(self.__tree_.__pair1_.__value_.__left_)) {" predicate += " return 0;" predicate += " }" predicate += " }" predicate += "}" predicate += "return 1;" functions { index { name = "find" arguments = {"keyval"} body = "$GHSpnode = (($M_typeof(self)::__base::__node_pointer)(self.__tree_.__pair1_.__value_.__left_));" body += "while ($GHSpnode) {" body += " if ($GHSpnode->__value_.__cc_.first == keyval) {" body += " return $GHSpnode->__value_.__cc_.second;" body += " } else if ($GHSpnode->__value_.__cc_.first > keyval) {" body += " $GHSpnode = ($M_typeof($GHSpnode))($GHSpnode->__left_);" body += " } else {" body += " $GHSpnode = ($M_typeof($GHSpnode))($GHSpnode->__right_);" body += " }" body += "}" body += "if (! $GHSpnode) { return \"Value not found\"; };" } } } map_value_type { signature = {"std::__value_type<*, *>"} required_fields = {"__cc_"} type = "alias" value = "return self.__cc_" } set { signature = {"std::set<*>", "std::multiset<*>"} required_fields = {"__tree_"} type = "container" predicate = "if ($_MULTI_MAJOR_VERSION >= 8) {" predicate += " if ($_IDE_SEQUENCE >= 452) {" predicate += " if (!$M_is_ptr(self.__tree_.__begin_node_)) {" predicate += " return 0;" predicate += " }" predicate += " }" predicate += "}" predicate += "return 1;" size = "return self.__tree_.__pair3_.__value_;" begin_iter = "return (($M_typeof(self)::__base::__node_pointer)(self.__tree_.__begin_node_));" next_iter = "if (self->__right_) {" next_iter += " $GHSptr = self->__right_;" next_iter += " while ($GHSptr->__left_) {" next_iter += " $GHSptr = $GHSptr->__left_;" next_iter += " };" next_iter += " return ($M_typeof(self))$GHSptr;" next_iter += "} else {" next_iter += " $GHSptr = self;" next_iter += " $GHSpnode = ($M_typeof(self))$GHSptr->__parent_;" next_iter += " while($GHSptr != $GHSpnode->__left_) {" next_iter += " $GHSptr = $GHSpnode;" next_iter += " $GHSpnode = ($M_typeof(self))$GHSptr->__parent_;" next_iter += " };" next_iter += " return ($M_typeof(self))$GHSpnode;" next_iter += "};" value_from_iter = "return self->__value_;" functions { size { name = "size" body = "return self.__tree_.__pair3_.__value_;" } empty { name = "empty" body = "return self.__tree_.__pair3_.__value_ == 0;" } } } map { signature = {"std::map<*>", "std::multimap<*>"} required_fields = {"__tree_"} type = "container" predicate = "if ($_MULTI_MAJOR_VERSION >= 8) {" predicate += " if ($_IDE_SEQUENCE >= 452) {" predicate += " if (!$M_is_ptr(self.__tree_.__begin_node_)) {" predicate += " return 0;" predicate += " }" predicate += " }" predicate += "}" predicate += "return 1;" size = "return self.__tree_.__pair3_.__value_;" begin_iter = "return (($M_typeof(self)::__base::__node_pointer)(self.__tree_.__begin_node_));" next_iter = "if (self->__right_) {" next_iter += " $GHSptr = self->__right_;" next_iter += " while ($GHSptr->__left_) {" next_iter += " $GHSptr = $GHSptr->__left_;" next_iter += " };" next_iter += " return ($M_typeof(self))$GHSptr;" next_iter += "} else {" next_iter += " $GHSptr = self;" next_iter += " $GHSpnode = ($M_typeof(self))$GHSptr->__parent_;" next_iter += " while($GHSptr != $GHSpnode->__left_) {" next_iter += " $GHSptr = $GHSpnode;" next_iter += " $GHSpnode = ($M_typeof(self))$GHSptr->__parent_;" next_iter += " };" next_iter += " return ($M_typeof(self))$GHSpnode;" next_iter += "};" value_from_iter = "return self->__value_.__cc_;" functions { size { name = "size" body = "return self.__tree_.__pair3_.__value_;" } empty { name = "empty" body = "return self.__tree_.__pair3_.__value_ == 0;" } } } map_iterator { signature = {"std::__map_iterator>", "std::__map_const_iterator>"} required_fields = {"__i_"} type = "structure" predicate = "if ($_MULTI_MAJOR_VERSION >= 8) {" predicate += " if ($_IDE_SEQUENCE >= 452) {" predicate += " if (!$M_is_ptr(self.__i_.__ptr_)) {" predicate += " return 0;" predicate += " }" predicate += " if ($_MULTI_MAJOR_VERSION > 8 && !$M_has_member(($M_typeof($M_typeof(self.__i_)::_NodePtr))(self.__i_.__ptr_), __parent_)) {" predicate += " return 0;" predicate += " }" predicate += " }" predicate += "}" predicate += "return self.__i_.__ptr_ != 0;" # libcxx uses super-root which only has "__left_" field that points to root. # Current there iss no way to detect dynamic type of a runtime object. # so we test if ptr->parent->child == ptr # it holds for all valid ptr and probably fails for map.end(), because # its parent is some garbage memory. fields { value { name = "__value_" value = "$GHSp = (($M_typeof($M_typeof(self.__i_)::_NodePtr))(self.__i_.__ptr_));" value += "if ((($M_typeof($M_typeof(self.__i_)::_NodePtr))($GHSp->__parent_))->__right_ == $GHSp || $GHSp->__parent_->__left_ == $GHSp) {" value += " return (($M_typeof($M_typeof(self.__i_)::_NodePtr))(self.__i_.__ptr_))->__value_;" value += "} else {" value += " return \"invalid\";" value += "}" } } functions { deref { name = "operator*" body = "$GHSp = (($M_typeof($M_typeof(self.__i_)::_NodePtr))(self.__i_.__ptr_));" body += "if ((($M_typeof($M_typeof(self.__i_)::_NodePtr))($GHSp->__parent_))->__right_ == $GHSp || $GHSp->__parent_->__left_ == $GHSp) {" body += " return (($M_typeof($M_typeof(self.__i_)::_NodePtr))(self.__i_.__ptr_))->__value_;" body += "} else {" body += " return \"invalid\";" body += "}" } } } tree_iterator { signature = {"std::__tree_const_iterator<*>", "std::__tree_iterator<*>"} required_fields = {"__ptr_"} type = "structure" predicate = "if ($_MULTI_MAJOR_VERSION >= 8) {" predicate += " if ($_IDE_SEQUENCE >= 452) {" predicate += " if (!$M_is_ptr(self.__ptr_)) {" predicate += " return 0;" predicate += " }" predicate += " $GHSp = (($M_typeof($M_typeof(self)::_NodePtr))(self.__ptr_));" predicate += " if (!$M_has_member($GHSp, __parent_)) {" predicate += " return 0;" predicate += " }" predicate += " }" predicate += "}" predicate += "return self.__ptr_ != 0;" # see comment above fields { value { name = "__value_" value = "$GHSp = ( ($M_typeof ($M_typeof(self)::_NodePtr) )(self.__ptr_) );" value += "if ((($M_typeof($M_typeof(self)::_NodePtr))($GHSp->__parent_))->__right_ == $GHSp || $GHSp->__parent_->__left_ == $GHSp) {" value += " return (($M_typeof($M_typeof(self)::_NodePtr))(self.__ptr_))->__value_;" value += "} else {" value += " return \"invalid\";" value += "}" } } functions { deref { name = "operator*" body = "$GHSp = ( ($M_typeof ($M_typeof(self)::_NodePtr) )(self.__ptr_) );" body += "if ((($M_typeof($M_typeof(self)::_NodePtr))($GHSp->__parent_))->__right_ == $GHSp || $GHSp->__parent_->__left_ == $GHSp) {" body += " return (($M_typeof($M_typeof(self)::_NodePtr))(self.__ptr_))->__value_;" body += "} else {" body += " return \"invalid\";" body += "}" } } } deque { signature = {"std::deque<*>"} required_fields = { "__start_", "__map_", "__size_" } type = "container" predicate = "if ($_MULTI_MAJOR_VERSION >= 8) {" predicate += " if ($_IDE_SEQUENCE >= 452) {" predicate += " if (!$M_is_ptr(self.__map_.__begin_)) {" predicate += " return 0;" predicate += " }" predicate += " }" predicate += "}" predicate += "return 1;" size = "return self.__size_.__value_;" begin_iter = "$GHSMyoff = self.__start_; return self;" next_iter = "$GHSMyoff++; return self; value_from_iter = "$GHSBlockSize = 4096 / sizeof($M_typeof(self)::value_type);" value_from_iter += "if ($GHSBlockSize < 16) { $GHSBlockSize = 16; }" value_from_iter += "$GHSBlockQ = $GHSMyoff / $GHSBlockSize;" value_from_iter += "$GHSBlockR = $GHSMyoff % $GHSBlockSize;" value_from_iter += "return self.__map_.__begin_[$GHSBlockQ][$GHSBlockR];" functions { size { name = "size" body = "return self.__size_.__value_;" } empty { name = "empty" body = "return self.__size_.__value_ == 0;" } } } # other container that use deque. copied from above. queue { signature = {"std::queue<*, std::deque<*>>", "std::stack<*, std::deque<*>>"} required_fields = { "c" } type = "container" predicate = "if ($_MULTI_MAJOR_VERSION >= 8) {" predicate += " if ($_IDE_SEQUENCE >= 452) {" predicate += " if (!$M_is_ptr(self.c.__map_.__begin_)) {" predicate += " return 0;" predicate += " }" predicate += " }" predicate += "}" predicate += "return 1;" size = "return self.c.__size_.__value_;" begin_iter = "$GHSMyoff = self.c.__start_; return self;" next_iter = "$GHSMyoff++; return self; value_from_iter = "$GHSBlockSize = 4096 / sizeof($M_typeof(self.c)::value_type);" value_from_iter += "if ($GHSBlockSize < 16) { $GHSBlockSize = 16; }" value_from_iter += "$GHSBlockQ = $GHSMyoff / $GHSBlockSize;" value_from_iter += "$GHSBlockR = $GHSMyoff % $GHSBlockSize;" value_from_iter += "return self.c.__map_.__begin_[$GHSBlockQ][$GHSBlockR];" functions { size { name = "size" body = "return self.c.__size_.__value_;" } empty { name = "empty" body = "return self.c.__size_.__value_ == 0;" } } } deque_iterator { signature = {"std::__deque_iterator<*>"} required_fields = {"__m_iter_", "__ptr_"} type = "structure" predicate = "if ($_MULTI_MAJOR_VERSION >= 8) {" predicate += " if ($_IDE_SEQUENCE >= 452) {" predicate += " if (!$M_is_ptr(self.__ptr_)) {" predicate += " return 0;" predicate += " }" predicate += " }" predicate += "}" predicate += "return 1;" fields { value { name = "value" value = "return self.__ptr_" } } functions { deref { name = "operator*" body = "return *self.__ptr_" } } } string { signature = {"std::basic_string<*>","std::string"} required_fields = {"__r_"} type = "alias" value = "if ((($M_typeof(self)::__rep*)(&self.__r_))->__s.__is_long_) {" value += " return (($M_typeof(self)::__rep*)(&self.__r_))->__l.__data_;" value += "} else {" value += " return (($M_typeof(self)::__rep*)(&self.__r_))->__s.__data_;" value += "}" mutable = false replace_self = true } array { signature = { "std::array<*>" } required_fields = {"__elems_"} type = "container" size = "return sizeof(self.__elems_)/sizeof(self.__elems_[0])" begin_iter = "return self.__elems_;" next_iter = "return self+1;" direct_iter= "return self + $GHSIndex;" value_from_iter = "return *(self);" functions { size { name = "size" body = "return sizeof(self.__elems_)/sizeof(self.__elems_[0])" } front { name = "front" body = "return self.__elems_[0]" } back { name = "back" body = "return self.__elems_[self._Size-1]" } data { name = "data" body = "return ($M_typeof(self.__elems_[0])*)(self.__elems_)" } empty { name = "empty" body = "return 1 == 0;" } } } array_of_size_0 { signature = { "std::array<*>" } required_fields = {"__dummy"} type = "container" size = "return 0" begin_iter = "return 0" next_iter = "return 0" value_from_iter = "return 0" functions { size { name = "size" body = "return 0" } empty { name = "empty" body = "return 0==0" } data { name = "data" body = "return (char*)0" } } } optional { signature = {"std::optional<*>"} required_fields = {"__engaged_", "__val_"} type = "structure" fields { engaged { name = "__engaged_" value = "return self.__engaged_" } value { name = "value" value = "if (!self.__engaged_) { value += " return (char*)0;" value += "}" value += "return self.__val_" } } } variant { signature = { "std::variant<*>" } required_fields = {"__impl_"} type = "structure" predicate = "return self.__impl_.__index < 255" fields { value { name = "value" value = "$GHSIndex = self.__impl_.__index;" value += "$GHSCur = &(self.__impl_.__data);" value += "while ($GHSCur->_Index != $GHSIndex) {" value += " if ($_MULTI_MAJOR_VERSION >= 8) {" value += " if ($_IDE_SEQUENCE >= 452) {" value += " if (!$M_has_member($GHSCur, __tail)) {" value += " return NULL" value += " }" value += " }" value += " }" value += " $GHSCur = &($GHSCur->__tail)" value += "}" value += " if ($_MULTI_MAJOR_VERSION >= 8) {" value += " if ($_IDE_SEQUENCE >= 452) {" value += " if (!$M_has_member($GHSCur, __head)) {" value += " return NULL" value += " }" value += " }" value += "}" value += "return $GHSCur->__head" } } } variant_valueless { signature = { "std::variant<*>" } required_fields = {"__impl_"} type = "structure" predicate = "return self.__impl_.__index == 255" fields { } }