OSDN Git Service

Fix PR1329.
authorJeff Cohen <jeffc@jolt-lang.org>
Sat, 14 Apr 2007 21:50:21 +0000 (21:50 +0000)
committerJeff Cohen <jeffc@jolt-lang.org>
Sat, 14 Apr 2007 21:50:21 +0000 (21:50 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36016 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/SmallPtrSet.h
lib/Support/SmallPtrSet.cpp

index 6bd4d09..40e9bb4 100644 (file)
@@ -53,6 +53,9 @@ protected:
   unsigned NumElements;
   unsigned NumTombstones;
   void *SmallArray[1];  // Must be last ivar.
+
+  // Helper to copy construct a SmallPtrSet.
+  SmallPtrSetImpl(const SmallPtrSetImpl& that);
 public:
   SmallPtrSetImpl(unsigned SmallSize) {
     assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 &&
@@ -214,6 +217,7 @@ class SmallPtrSet : public SmallPtrSetImpl {
   void *SmallArray[SmallSizePowTwo];
 public:
   SmallPtrSet() : SmallPtrSetImpl(NextPowerOfTwo<SmallSizePowTwo>::Val) {}
+  SmallPtrSet(const SmallPtrSet &that) : SmallPtrSetImpl(that) {}
   
   template<typename It>
   SmallPtrSet(It I, It E)
index 98d5bc9..61fad5e 100644 (file)
@@ -141,5 +141,33 @@ void SmallPtrSetImpl::Grow() {
     }
     
     delete [] OldBuckets;
+    NumTombstones = 0;
+  }
+}
+
+SmallPtrSetImpl::SmallPtrSetImpl(const SmallPtrSetImpl& that) {
+  NumElements = that.NumElements;
+  NumTombstones = 0;
+  if (that.isSmall()) {
+    CurArraySize = that.CurArraySize;
+    CurArray = &SmallArray[0];
+    memcpy(CurArray, that.CurArray, sizeof(void*)*CurArraySize);
+  } else {
+    CurArraySize = that.NumElements < 64 ? 128 : that.NumElements*2;
+    CurArray = new void*[CurArraySize+1];
+    memset(CurArray, -1, CurArraySize*sizeof(void*));
+    
+    // The end pointer, always valid, is set to a valid element to help the
+    // iterator.
+    CurArray[CurArraySize] = 0;
+
+    // Copy over all valid entries.
+    for (void **BucketPtr = that.CurArray, **E = that.CurArray+CurArraySize;
+         BucketPtr != E; ++BucketPtr) {
+      // Copy over the element if it is valid.
+      void *Elt = *BucketPtr;
+      if (Elt != getTombstoneMarker() && Elt != getEmptyMarker())
+        *const_cast<void**>(FindBucketFor(Elt)) = Elt;
+    }
   }
 }