@@ -75,10 +75,28 @@ void AddChildren::visit(Class& c) {
7575 dynamic_cast <Class*>(&childType); // TODO don't use dynamic_cast
7676 if (!childClass) // TODO dodgy error handling
7777 abort ();
78- c.children .push_back (*childClass);
7978
80- // // Add recursive children to this class as well
81- // enumerateClassChildren(drgnChild, children);
79+ /*
80+ * Confirm that this child is actually our child.
81+ *
82+ * We previously used unqualified names for speed, so types with the same
83+ * name in different namespaces would have been grouped together.
84+ */
85+ bool isActuallyChild = false ;
86+ for (const auto & parent : childClass->parents ) {
87+ // TODO support parent containers?
88+ auto * parentClass = dynamic_cast <Class*>(&stripTypedefs (parent.type ()));
89+ if (!parentClass)
90+ continue ;
91+
92+ if (parentClass->fqName () == c.fqName ()) {
93+ isActuallyChild = true ;
94+ break ;
95+ }
96+ }
97+
98+ if (isActuallyChild)
99+ c.children .push_back (*childClass);
82100 }
83101
84102 // Recurse to find children-of-children
@@ -87,35 +105,6 @@ void AddChildren::visit(Class& c) {
87105 }
88106}
89107
90- // TODO how to flatten children of children?
91- // void AddChildren::enumerateClassChildren(struct drgn_type *type,
92- // std::vector<std::reference_wrapper<Class>> &children) {
93- // // This function is called recursively to find children-of-children, so the
94- // // "children" vector argument will not necessarily be empty.
95- //
96- // const char* tag = drgn_type_tag(type);
97- // if (tag == nullptr) {
98- // return;
99- // }
100- // auto it = childClasses_.find(tag);
101- // if (it == childClasses_.end()) {
102- // return;
103- // }
104- //
105- // const auto& drgnChildren = it->second;
106- // for (drgn_type* drgnChild : drgnChildren) {
107- // // TODO there shouldn't be any need for a dynamic cast here...
108- // Type *ttt = enumerateClass(drgnChild);
109- // auto *child = dynamic_cast<Class*>(ttt);
110- // if (!child)
111- // abort();
112- // children.push_back(*child);
113- //
114- // // Add recursive children to this class as well
115- // enumerateClassChildren(drgnChild, children);
116- // }
117- // }
118-
119108void AddChildren::recordChildren (drgn_type* type) {
120109 drgn_type_template_parameter* parents = drgn_type_parents (type);
121110
@@ -141,20 +130,20 @@ void AddChildren::recordChildren(drgn_type* type) {
141130 }
142131
143132 const char * parentName = drgn_type_tag (parent);
144- if (parentName == nullptr ) {
145- // VLOG(1) << "No name for parent class (" << parent << ") of "
146- // << drgn_type_tag(type);
133+ if (!parentName) {
147134 continue ;
148135 }
149136
150137 /*
151138 * drgn pointers are not stable, so use string representation for reverse
152139 * mapping for now. We need to find a better way of creating this
153140 * childClasses map - ideally drgn would do this for us.
141+ *
142+ * Use unqualified names because fully-qualified names are too slow. We'll
143+ * check against fully-qualified names once we've narrowed down the number
144+ * of types to compare.
154145 */
155146 childClasses_[parentName].push_back (type);
156- // VLOG(1) << drgn_type_tag(type) << "(" << type << ") is a child of "
157- // << drgn_type_tag(parent) << "(" << parent << ")";
158147 }
159148}
160149
0 commit comments