llvm.org GIT mirror llvm / 41673c6
Add a new WeakVH value handle; NFC This relands r301425. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301813 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjoy Das 3 years ago
3 changed file(s) with 61 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
3333 ///
3434 /// This is to avoid having a vtable for the light-weight handle pointers. The
3535 /// fully general Callback version does have a vtable.
36 enum HandleBaseKind { Assert, Callback, WeakTracking };
36 enum HandleBaseKind { Assert, Callback, Weak, WeakTracking };
3737
3838 ValueHandleBase(const ValueHandleBase &RHS)
3939 : ValueHandleBase(RHS.PrevPair.getInt(), RHS) {}
4545 }
4646
4747 private:
48 PointerIntPair2, HandleBaseKind> PrevPair;
48 PointerIntPair3, HandleBaseKind> PrevPair;
4949 ValueHandleBase *Next;
5050
5151 Value *Val;
131131
132132 /// \brief Add this ValueHandle to the use list for V.
133133 void AddToUseList();
134 };
135
136 /// \brief A nullable Value handle that is nullable.
137 ///
138 /// This is a value handle that points to a value, and nulls itself
139 /// out if that value is deleted.
140 class WeakVH : public ValueHandleBase {
141 public:
142 WeakVH() : ValueHandleBase(Weak) {}
143 WeakVH(Value *P) : ValueHandleBase(Weak, P) {}
144 WeakVH(const WeakVH &RHS)
145 : ValueHandleBase(Weak, RHS) {}
146
147 WeakVH &operator=(const WeakVH &RHS) = default;
148
149 Value *operator=(Value *RHS) {
150 return ValueHandleBase::operator=(RHS);
151 }
152 Value *operator=(const ValueHandleBase &RHS) {
153 return ValueHandleBase::operator=(RHS);
154 }
155
156 operator Value*() const {
157 return getValPtr();
158 }
159 };
160
161 // Specialize simplify_type to allow WeakVH to participate in
162 // dyn_cast, isa, etc.
163 template <> struct simplify_type {
164 typedef Value *SimpleType;
165 static SimpleType getSimplifiedValue(WeakVH &WVH) { return WVH; }
166 };
167 template <> struct simplify_type {
168 typedef Value *SimpleType;
169 static SimpleType getSimplifiedValue(const WeakVH &WVH) { return WVH; }
134170 };
135171
136172 /// \brief Value handle that is nullable, but tries to track the Value.
819819 switch (Entry->getKind()) {
820820 case Assert:
821821 break;
822 case Weak:
822823 case WeakTracking:
823 // WeakTracking just goes to null, which will unlink it from the list.
824 // WeakTracking and Weak just go to null, which unlinks them
825 // from the list.
824826 Entry->operator=(nullptr);
825827 break;
826828 case Callback:
868870
869871 switch (Entry->getKind()) {
870872 case Assert:
871 // Asserting handle does not follow RAUW implicitly.
873 case Weak:
874 // Asserting and Weak handles do not follow RAUW implicitly.
872875 break;
873876 case WeakTracking:
874877 // Weak goes to the new value, which will unlink it from Old's list.
3232 public:
3333 ConcreteCallbackVH(Value *V) : CallbackVH(V) {}
3434 };
35
36 TEST_F(ValueHandle, WeakVH_BasicOperation) {
37 WeakVH WVH(BitcastV.get());
38 EXPECT_EQ(BitcastV.get(), WVH);
39 WVH = ConstantV;
40 EXPECT_EQ(ConstantV, WVH);
41
42 // Make sure I can call a method on the underlying Value. It
43 // doesn't matter which method.
44 EXPECT_EQ(Type::getInt32Ty(Context), WVH->getType());
45 EXPECT_EQ(Type::getInt32Ty(Context), (*WVH).getType());
46
47 WVH = BitcastV.get();
48 BitcastV->replaceAllUsesWith(ConstantV);
49 EXPECT_EQ(WVH, BitcastV.get());
50 BitcastV.reset();
51 EXPECT_EQ(WVH, nullptr);
52 }
3553
3654 TEST_F(ValueHandle, WeakTrackingVH_BasicOperation) {
3755 WeakTrackingVH WVH(BitcastV.get());