about summary refs log tree commit diff
path: root/src/rt/rust_crate_map.cpp
diff options
context:
space:
mode:
authorILyoan <ilyoan@gmail.com>2013-01-29 20:19:23 +0900
committerILyoan <ilyoan@gmail.com>2013-01-29 21:03:05 +0900
commit8ec36d779b760eed8625ec69a983461e2ffe3914 (patch)
tree5b1fef224982a8b6f14f21403e68681a252128e9 /src/rt/rust_crate_map.cpp
parentfc9650b1467a7388e60838ddbeb1755d5fe149b5 (diff)
downloadrust-8ec36d779b760eed8625ec69a983461e2ffe3914.tar.gz
rust-8ec36d779b760eed8625ec69a983461e2ffe3914.zip
fix #2673: avoid visiting the same crate twice
Diffstat (limited to 'src/rt/rust_crate_map.cpp')
-rw-r--r--src/rt/rust_crate_map.cpp28
1 files changed, 19 insertions, 9 deletions
diff --git a/src/rt/rust_crate_map.cpp b/src/rt/rust_crate_map.cpp
index 00f764a1406..7faae196000 100644
--- a/src/rt/rust_crate_map.cpp
+++ b/src/rt/rust_crate_map.cpp
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 #include "rust_crate_map.h"
+#include <set>
 
 void iter_module_map(const mod_entry* map,
                      void (*fn)(const mod_entry* entry, void *cookie),
@@ -20,18 +21,27 @@ void iter_module_map(const mod_entry* map,
 
 void iter_crate_map(const cratemap* map,
                     void (*fn)(const mod_entry* map, void *cookie),
-                    void *cookie) {
-    // First iterate this crate
-    iter_module_map(map->entries(), fn, cookie);
-    // Then recurse on linked crates
-    // FIXME (#2673) this does double work in diamond-shaped deps. could
-    //   keep a set of visited addresses, if it turns out to be actually
-    //   slow
-    for (cratemap::iterator i = map->begin(), e = map->end(); i != e; ++i) {
-        iter_crate_map(*i, fn, cookie);
+                    void *cookie,
+                    std::set<const cratemap*>& visited) {
+    if (visited.find(map) == visited.end()) {
+        // Mark this crate visited
+        visited.insert(map);
+        // First iterate this crate
+        iter_module_map(map->entries(), fn, cookie);
+        // Then recurse on linked crates
+        for (cratemap::iterator i = map->begin(),
+                e = map->end(); i != e; ++i) {
+            iter_crate_map(*i, fn, cookie, visited);
+        }
     }
 }
 
+void iter_crate_map(const cratemap* map,
+                    void (*fn)(const mod_entry* map, void *cookie),
+                    void *cookie) {
+    std::set<const cratemap*> visited;
+    iter_crate_map(map, fn, cookie, visited);
+}
 //
 // Local Variables:
 // mode: C++