@@ -75,10 +75,28 @@ void AddChildren::visit(Class& c) {
75
75
dynamic_cast <Class*>(&childType); // TODO don't use dynamic_cast
76
76
if (!childClass) // TODO dodgy error handling
77
77
abort ();
78
- c.children .push_back (*childClass);
79
78
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);
82
100
}
83
101
84
102
// Recurse to find children-of-children
@@ -87,35 +105,6 @@ void AddChildren::visit(Class& c) {
87
105
}
88
106
}
89
107
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
-
119
108
void AddChildren::recordChildren (drgn_type* type) {
120
109
drgn_type_template_parameter* parents = drgn_type_parents (type);
121
110
@@ -141,20 +130,20 @@ void AddChildren::recordChildren(drgn_type* type) {
141
130
}
142
131
143
132
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) {
147
134
continue ;
148
135
}
149
136
150
137
/*
151
138
* drgn pointers are not stable, so use string representation for reverse
152
139
* mapping for now. We need to find a better way of creating this
153
140
* 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.
154
145
*/
155
146
childClasses_[parentName].push_back (type);
156
- // VLOG(1) << drgn_type_tag(type) << "(" << type << ") is a child of "
157
- // << drgn_type_tag(parent) << "(" << parent << ")";
158
147
}
159
148
}
160
149
0 commit comments