9
9
// except according to those terms.
10
10
11
11
#include " rust_crate_map.h"
12
+ #include < set>
12
13
13
14
void iter_module_map (const mod_entry* map,
14
15
void (*fn)(const mod_entry* entry, void *cookie),
@@ -20,18 +21,27 @@ void iter_module_map(const mod_entry* map,
20
21
21
22
void iter_crate_map (const cratemap* map,
22
23
void (*fn)(const mod_entry* map, void *cookie),
23
- void *cookie) {
24
- // First iterate this crate
25
- iter_module_map (map->entries (), fn, cookie);
26
- // Then recurse on linked crates
27
- // FIXME (#2673) this does double work in diamond-shaped deps. could
28
- // keep a set of visited addresses, if it turns out to be actually
29
- // slow
30
- for (cratemap::iterator i = map->begin (), e = map->end (); i != e; ++i) {
31
- iter_crate_map (*i, fn, cookie);
24
+ void *cookie,
25
+ std::set<const cratemap*>& visited) {
26
+ if (visited.find (map) == visited.end ()) {
27
+ // Mark this crate visited
28
+ visited.insert (map);
29
+ // First iterate this crate
30
+ iter_module_map (map->entries (), fn, cookie);
31
+ // Then recurse on linked crates
32
+ for (cratemap::iterator i = map->begin (),
33
+ e = map->end (); i != e; ++i) {
34
+ iter_crate_map (*i, fn, cookie, visited);
35
+ }
32
36
}
33
37
}
34
38
39
+ void iter_crate_map (const cratemap* map,
40
+ void (*fn)(const mod_entry* map, void *cookie),
41
+ void *cookie) {
42
+ std::set<const cratemap*> visited;
43
+ iter_crate_map (map, fn, cookie, visited);
44
+ }
35
45
//
36
46
// Local Variables:
37
47
// mode: C++
0 commit comments