1*9880d681SAndroid Build Coastguard Worker //===- llvm/unittest/ADT/ValueMapTest.cpp - ValueMap unit tests -*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/ValueMap.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/Config/llvm-config.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Constants.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Instructions.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h"
15*9880d681SAndroid Build Coastguard Worker #include "gtest/gtest.h"
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Worker using namespace llvm;
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Worker namespace {
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard Worker // Test fixture
22*9880d681SAndroid Build Coastguard Worker template<typename T>
23*9880d681SAndroid Build Coastguard Worker class ValueMapTest : public testing::Test {
24*9880d681SAndroid Build Coastguard Worker protected:
25*9880d681SAndroid Build Coastguard Worker LLVMContext Context;
26*9880d681SAndroid Build Coastguard Worker Constant *ConstantV;
27*9880d681SAndroid Build Coastguard Worker std::unique_ptr<BitCastInst> BitcastV;
28*9880d681SAndroid Build Coastguard Worker std::unique_ptr<BinaryOperator> AddV;
29*9880d681SAndroid Build Coastguard Worker
ValueMapTest()30*9880d681SAndroid Build Coastguard Worker ValueMapTest()
31*9880d681SAndroid Build Coastguard Worker : ConstantV(ConstantInt::get(Type::getInt32Ty(Context), 0)),
32*9880d681SAndroid Build Coastguard Worker BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(Context))),
33*9880d681SAndroid Build Coastguard Worker AddV(BinaryOperator::CreateAdd(ConstantV, ConstantV)) {}
34*9880d681SAndroid Build Coastguard Worker };
35*9880d681SAndroid Build Coastguard Worker
36*9880d681SAndroid Build Coastguard Worker // Run everything on Value*, a subtype to make sure that casting works as
37*9880d681SAndroid Build Coastguard Worker // expected, and a const subtype to make sure we cast const correctly.
38*9880d681SAndroid Build Coastguard Worker typedef ::testing::Types<Value, Instruction, const Instruction> KeyTypes;
39*9880d681SAndroid Build Coastguard Worker TYPED_TEST_CASE(ValueMapTest, KeyTypes);
40*9880d681SAndroid Build Coastguard Worker
TYPED_TEST(ValueMapTest,Null)41*9880d681SAndroid Build Coastguard Worker TYPED_TEST(ValueMapTest, Null) {
42*9880d681SAndroid Build Coastguard Worker ValueMap<TypeParam*, int> VM1;
43*9880d681SAndroid Build Coastguard Worker VM1[nullptr] = 7;
44*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(7, VM1.lookup(nullptr));
45*9880d681SAndroid Build Coastguard Worker }
46*9880d681SAndroid Build Coastguard Worker
TYPED_TEST(ValueMapTest,FollowsValue)47*9880d681SAndroid Build Coastguard Worker TYPED_TEST(ValueMapTest, FollowsValue) {
48*9880d681SAndroid Build Coastguard Worker ValueMap<TypeParam*, int> VM;
49*9880d681SAndroid Build Coastguard Worker VM[this->BitcastV.get()] = 7;
50*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
51*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0u, VM.count(this->AddV.get()));
52*9880d681SAndroid Build Coastguard Worker this->BitcastV->replaceAllUsesWith(this->AddV.get());
53*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(7, VM.lookup(this->AddV.get()));
54*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0u, VM.count(this->BitcastV.get()));
55*9880d681SAndroid Build Coastguard Worker this->AddV.reset();
56*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0u, VM.count(this->AddV.get()));
57*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0u, VM.count(this->BitcastV.get()));
58*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0U, VM.size());
59*9880d681SAndroid Build Coastguard Worker }
60*9880d681SAndroid Build Coastguard Worker
TYPED_TEST(ValueMapTest,OperationsWork)61*9880d681SAndroid Build Coastguard Worker TYPED_TEST(ValueMapTest, OperationsWork) {
62*9880d681SAndroid Build Coastguard Worker ValueMap<TypeParam*, int> VM;
63*9880d681SAndroid Build Coastguard Worker ValueMap<TypeParam*, int> VM2(16); (void)VM2;
64*9880d681SAndroid Build Coastguard Worker typename ValueMapConfig<TypeParam*>::ExtraData Data;
65*9880d681SAndroid Build Coastguard Worker ValueMap<TypeParam*, int> VM3(Data, 16); (void)VM3;
66*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(VM.empty());
67*9880d681SAndroid Build Coastguard Worker
68*9880d681SAndroid Build Coastguard Worker VM[this->BitcastV.get()] = 7;
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Worker // Find:
71*9880d681SAndroid Build Coastguard Worker typename ValueMap<TypeParam*, int>::iterator I =
72*9880d681SAndroid Build Coastguard Worker VM.find(this->BitcastV.get());
73*9880d681SAndroid Build Coastguard Worker ASSERT_TRUE(I != VM.end());
74*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(this->BitcastV.get(), I->first);
75*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(7, I->second);
76*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(VM.find(this->AddV.get()) == VM.end());
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker // Const find:
79*9880d681SAndroid Build Coastguard Worker const ValueMap<TypeParam*, int> &CVM = VM;
80*9880d681SAndroid Build Coastguard Worker typename ValueMap<TypeParam*, int>::const_iterator CI =
81*9880d681SAndroid Build Coastguard Worker CVM.find(this->BitcastV.get());
82*9880d681SAndroid Build Coastguard Worker ASSERT_TRUE(CI != CVM.end());
83*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(this->BitcastV.get(), CI->first);
84*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(7, CI->second);
85*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(CVM.find(this->AddV.get()) == CVM.end());
86*9880d681SAndroid Build Coastguard Worker
87*9880d681SAndroid Build Coastguard Worker // Insert:
88*9880d681SAndroid Build Coastguard Worker std::pair<typename ValueMap<TypeParam*, int>::iterator, bool> InsertResult1 =
89*9880d681SAndroid Build Coastguard Worker VM.insert(std::make_pair(this->AddV.get(), 3));
90*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(this->AddV.get(), InsertResult1.first->first);
91*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(3, InsertResult1.first->second);
92*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(InsertResult1.second);
93*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1u, VM.count(this->AddV.get()));
94*9880d681SAndroid Build Coastguard Worker std::pair<typename ValueMap<TypeParam*, int>::iterator, bool> InsertResult2 =
95*9880d681SAndroid Build Coastguard Worker VM.insert(std::make_pair(this->AddV.get(), 5));
96*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(this->AddV.get(), InsertResult2.first->first);
97*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(3, InsertResult2.first->second);
98*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(InsertResult2.second);
99*9880d681SAndroid Build Coastguard Worker
100*9880d681SAndroid Build Coastguard Worker // Erase:
101*9880d681SAndroid Build Coastguard Worker VM.erase(InsertResult2.first);
102*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0U, VM.count(this->AddV.get()));
103*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1U, VM.count(this->BitcastV.get()));
104*9880d681SAndroid Build Coastguard Worker VM.erase(this->BitcastV.get());
105*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0U, VM.count(this->BitcastV.get()));
106*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0U, VM.size());
107*9880d681SAndroid Build Coastguard Worker
108*9880d681SAndroid Build Coastguard Worker // Range insert:
109*9880d681SAndroid Build Coastguard Worker SmallVector<std::pair<Instruction*, int>, 2> Elems;
110*9880d681SAndroid Build Coastguard Worker Elems.push_back(std::make_pair(this->AddV.get(), 1));
111*9880d681SAndroid Build Coastguard Worker Elems.push_back(std::make_pair(this->BitcastV.get(), 2));
112*9880d681SAndroid Build Coastguard Worker VM.insert(Elems.begin(), Elems.end());
113*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1, VM.lookup(this->AddV.get()));
114*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(2, VM.lookup(this->BitcastV.get()));
115*9880d681SAndroid Build Coastguard Worker }
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker template<typename ExpectedType, typename VarType>
CompileAssertHasType(VarType)118*9880d681SAndroid Build Coastguard Worker void CompileAssertHasType(VarType) {
119*9880d681SAndroid Build Coastguard Worker static_assert(std::is_same<ExpectedType, VarType>::value,
120*9880d681SAndroid Build Coastguard Worker "Not the same type");
121*9880d681SAndroid Build Coastguard Worker }
122*9880d681SAndroid Build Coastguard Worker
TYPED_TEST(ValueMapTest,Iteration)123*9880d681SAndroid Build Coastguard Worker TYPED_TEST(ValueMapTest, Iteration) {
124*9880d681SAndroid Build Coastguard Worker ValueMap<TypeParam*, int> VM;
125*9880d681SAndroid Build Coastguard Worker VM[this->BitcastV.get()] = 2;
126*9880d681SAndroid Build Coastguard Worker VM[this->AddV.get()] = 3;
127*9880d681SAndroid Build Coastguard Worker size_t size = 0;
128*9880d681SAndroid Build Coastguard Worker for (typename ValueMap<TypeParam*, int>::iterator I = VM.begin(), E = VM.end();
129*9880d681SAndroid Build Coastguard Worker I != E; ++I) {
130*9880d681SAndroid Build Coastguard Worker ++size;
131*9880d681SAndroid Build Coastguard Worker std::pair<TypeParam*, int> value = *I; (void)value;
132*9880d681SAndroid Build Coastguard Worker CompileAssertHasType<TypeParam*>(I->first);
133*9880d681SAndroid Build Coastguard Worker if (I->second == 2) {
134*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(this->BitcastV.get(), I->first);
135*9880d681SAndroid Build Coastguard Worker I->second = 5;
136*9880d681SAndroid Build Coastguard Worker } else if (I->second == 3) {
137*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(this->AddV.get(), I->first);
138*9880d681SAndroid Build Coastguard Worker I->second = 6;
139*9880d681SAndroid Build Coastguard Worker } else {
140*9880d681SAndroid Build Coastguard Worker ADD_FAILURE() << "Iterated through an extra value.";
141*9880d681SAndroid Build Coastguard Worker }
142*9880d681SAndroid Build Coastguard Worker }
143*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(2U, size);
144*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(5, VM[this->BitcastV.get()]);
145*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(6, VM[this->AddV.get()]);
146*9880d681SAndroid Build Coastguard Worker
147*9880d681SAndroid Build Coastguard Worker size = 0;
148*9880d681SAndroid Build Coastguard Worker // Cast to const ValueMap to avoid a bug in DenseMap's iterators.
149*9880d681SAndroid Build Coastguard Worker const ValueMap<TypeParam*, int>& CVM = VM;
150*9880d681SAndroid Build Coastguard Worker for (typename ValueMap<TypeParam*, int>::const_iterator I = CVM.begin(),
151*9880d681SAndroid Build Coastguard Worker E = CVM.end(); I != E; ++I) {
152*9880d681SAndroid Build Coastguard Worker ++size;
153*9880d681SAndroid Build Coastguard Worker std::pair<TypeParam*, int> value = *I; (void)value;
154*9880d681SAndroid Build Coastguard Worker CompileAssertHasType<TypeParam*>(I->first);
155*9880d681SAndroid Build Coastguard Worker if (I->second == 5) {
156*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(this->BitcastV.get(), I->first);
157*9880d681SAndroid Build Coastguard Worker } else if (I->second == 6) {
158*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(this->AddV.get(), I->first);
159*9880d681SAndroid Build Coastguard Worker } else {
160*9880d681SAndroid Build Coastguard Worker ADD_FAILURE() << "Iterated through an extra value.";
161*9880d681SAndroid Build Coastguard Worker }
162*9880d681SAndroid Build Coastguard Worker }
163*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(2U, size);
164*9880d681SAndroid Build Coastguard Worker }
165*9880d681SAndroid Build Coastguard Worker
TYPED_TEST(ValueMapTest,DefaultCollisionBehavior)166*9880d681SAndroid Build Coastguard Worker TYPED_TEST(ValueMapTest, DefaultCollisionBehavior) {
167*9880d681SAndroid Build Coastguard Worker // By default, we overwrite the old value with the replaced value.
168*9880d681SAndroid Build Coastguard Worker ValueMap<TypeParam*, int> VM;
169*9880d681SAndroid Build Coastguard Worker VM[this->BitcastV.get()] = 7;
170*9880d681SAndroid Build Coastguard Worker VM[this->AddV.get()] = 9;
171*9880d681SAndroid Build Coastguard Worker this->BitcastV->replaceAllUsesWith(this->AddV.get());
172*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0u, VM.count(this->BitcastV.get()));
173*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(9, VM.lookup(this->AddV.get()));
174*9880d681SAndroid Build Coastguard Worker }
175*9880d681SAndroid Build Coastguard Worker
TYPED_TEST(ValueMapTest,ConfiguredCollisionBehavior)176*9880d681SAndroid Build Coastguard Worker TYPED_TEST(ValueMapTest, ConfiguredCollisionBehavior) {
177*9880d681SAndroid Build Coastguard Worker // TODO: Implement this when someone needs it.
178*9880d681SAndroid Build Coastguard Worker }
179*9880d681SAndroid Build Coastguard Worker
180*9880d681SAndroid Build Coastguard Worker template<typename KeyT, typename MutexT>
181*9880d681SAndroid Build Coastguard Worker struct LockMutex : ValueMapConfig<KeyT, MutexT> {
182*9880d681SAndroid Build Coastguard Worker struct ExtraData {
183*9880d681SAndroid Build Coastguard Worker MutexT *M;
184*9880d681SAndroid Build Coastguard Worker bool *CalledRAUW;
185*9880d681SAndroid Build Coastguard Worker bool *CalledDeleted;
186*9880d681SAndroid Build Coastguard Worker };
onRAUW__anone82456090111::LockMutex187*9880d681SAndroid Build Coastguard Worker static void onRAUW(const ExtraData &Data, KeyT Old, KeyT New) {
188*9880d681SAndroid Build Coastguard Worker *Data.CalledRAUW = true;
189*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(Data.M->try_lock()) << "Mutex should already be locked.";
190*9880d681SAndroid Build Coastguard Worker }
onDelete__anone82456090111::LockMutex191*9880d681SAndroid Build Coastguard Worker static void onDelete(const ExtraData &Data, KeyT Old) {
192*9880d681SAndroid Build Coastguard Worker *Data.CalledDeleted = true;
193*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(Data.M->try_lock()) << "Mutex should already be locked.";
194*9880d681SAndroid Build Coastguard Worker }
getMutex__anone82456090111::LockMutex195*9880d681SAndroid Build Coastguard Worker static MutexT *getMutex(const ExtraData &Data) { return Data.M; }
196*9880d681SAndroid Build Coastguard Worker };
197*9880d681SAndroid Build Coastguard Worker // FIXME: These tests started failing on Windows.
198*9880d681SAndroid Build Coastguard Worker #if LLVM_ENABLE_THREADS && !defined(LLVM_ON_WIN32)
TYPED_TEST(ValueMapTest,LocksMutex)199*9880d681SAndroid Build Coastguard Worker TYPED_TEST(ValueMapTest, LocksMutex) {
200*9880d681SAndroid Build Coastguard Worker sys::Mutex M(false); // Not recursive.
201*9880d681SAndroid Build Coastguard Worker bool CalledRAUW = false, CalledDeleted = false;
202*9880d681SAndroid Build Coastguard Worker typedef LockMutex<TypeParam*, sys::Mutex> ConfigType;
203*9880d681SAndroid Build Coastguard Worker typename ConfigType::ExtraData Data = {&M, &CalledRAUW, &CalledDeleted};
204*9880d681SAndroid Build Coastguard Worker ValueMap<TypeParam*, int, ConfigType> VM(Data);
205*9880d681SAndroid Build Coastguard Worker VM[this->BitcastV.get()] = 7;
206*9880d681SAndroid Build Coastguard Worker this->BitcastV->replaceAllUsesWith(this->AddV.get());
207*9880d681SAndroid Build Coastguard Worker this->AddV.reset();
208*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(CalledRAUW);
209*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(CalledDeleted);
210*9880d681SAndroid Build Coastguard Worker }
211*9880d681SAndroid Build Coastguard Worker #endif
212*9880d681SAndroid Build Coastguard Worker
213*9880d681SAndroid Build Coastguard Worker template<typename KeyT>
214*9880d681SAndroid Build Coastguard Worker struct NoFollow : ValueMapConfig<KeyT> {
215*9880d681SAndroid Build Coastguard Worker enum { FollowRAUW = false };
216*9880d681SAndroid Build Coastguard Worker };
217*9880d681SAndroid Build Coastguard Worker
TYPED_TEST(ValueMapTest,NoFollowRAUW)218*9880d681SAndroid Build Coastguard Worker TYPED_TEST(ValueMapTest, NoFollowRAUW) {
219*9880d681SAndroid Build Coastguard Worker ValueMap<TypeParam*, int, NoFollow<TypeParam*> > VM;
220*9880d681SAndroid Build Coastguard Worker VM[this->BitcastV.get()] = 7;
221*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
222*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0u, VM.count(this->AddV.get()));
223*9880d681SAndroid Build Coastguard Worker this->BitcastV->replaceAllUsesWith(this->AddV.get());
224*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
225*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0, VM.lookup(this->AddV.get()));
226*9880d681SAndroid Build Coastguard Worker this->AddV.reset();
227*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
228*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0, VM.lookup(this->AddV.get()));
229*9880d681SAndroid Build Coastguard Worker this->BitcastV.reset();
230*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0, VM.lookup(this->BitcastV.get()));
231*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0, VM.lookup(this->AddV.get()));
232*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0U, VM.size());
233*9880d681SAndroid Build Coastguard Worker }
234*9880d681SAndroid Build Coastguard Worker
235*9880d681SAndroid Build Coastguard Worker template<typename KeyT>
236*9880d681SAndroid Build Coastguard Worker struct CountOps : ValueMapConfig<KeyT> {
237*9880d681SAndroid Build Coastguard Worker struct ExtraData {
238*9880d681SAndroid Build Coastguard Worker int *Deletions;
239*9880d681SAndroid Build Coastguard Worker int *RAUWs;
240*9880d681SAndroid Build Coastguard Worker };
241*9880d681SAndroid Build Coastguard Worker
onRAUW__anone82456090111::CountOps242*9880d681SAndroid Build Coastguard Worker static void onRAUW(const ExtraData &Data, KeyT Old, KeyT New) {
243*9880d681SAndroid Build Coastguard Worker ++*Data.RAUWs;
244*9880d681SAndroid Build Coastguard Worker }
onDelete__anone82456090111::CountOps245*9880d681SAndroid Build Coastguard Worker static void onDelete(const ExtraData &Data, KeyT Old) {
246*9880d681SAndroid Build Coastguard Worker ++*Data.Deletions;
247*9880d681SAndroid Build Coastguard Worker }
248*9880d681SAndroid Build Coastguard Worker };
249*9880d681SAndroid Build Coastguard Worker
TYPED_TEST(ValueMapTest,CallsConfig)250*9880d681SAndroid Build Coastguard Worker TYPED_TEST(ValueMapTest, CallsConfig) {
251*9880d681SAndroid Build Coastguard Worker int Deletions = 0, RAUWs = 0;
252*9880d681SAndroid Build Coastguard Worker typename CountOps<TypeParam*>::ExtraData Data = {&Deletions, &RAUWs};
253*9880d681SAndroid Build Coastguard Worker ValueMap<TypeParam*, int, CountOps<TypeParam*> > VM(Data);
254*9880d681SAndroid Build Coastguard Worker VM[this->BitcastV.get()] = 7;
255*9880d681SAndroid Build Coastguard Worker this->BitcastV->replaceAllUsesWith(this->AddV.get());
256*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0, Deletions);
257*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1, RAUWs);
258*9880d681SAndroid Build Coastguard Worker this->AddV.reset();
259*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1, Deletions);
260*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1, RAUWs);
261*9880d681SAndroid Build Coastguard Worker this->BitcastV.reset();
262*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1, Deletions);
263*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1, RAUWs);
264*9880d681SAndroid Build Coastguard Worker }
265*9880d681SAndroid Build Coastguard Worker
266*9880d681SAndroid Build Coastguard Worker template<typename KeyT>
267*9880d681SAndroid Build Coastguard Worker struct ModifyingConfig : ValueMapConfig<KeyT> {
268*9880d681SAndroid Build Coastguard Worker // We'll put a pointer here back to the ValueMap this key is in, so
269*9880d681SAndroid Build Coastguard Worker // that we can modify it (and clobber *this) before the ValueMap
270*9880d681SAndroid Build Coastguard Worker // tries to do the same modification. In previous versions of
271*9880d681SAndroid Build Coastguard Worker // ValueMap, that exploded.
272*9880d681SAndroid Build Coastguard Worker typedef ValueMap<KeyT, int, ModifyingConfig<KeyT> > **ExtraData;
273*9880d681SAndroid Build Coastguard Worker
onRAUW__anone82456090111::ModifyingConfig274*9880d681SAndroid Build Coastguard Worker static void onRAUW(ExtraData Map, KeyT Old, KeyT New) {
275*9880d681SAndroid Build Coastguard Worker (*Map)->erase(Old);
276*9880d681SAndroid Build Coastguard Worker }
onDelete__anone82456090111::ModifyingConfig277*9880d681SAndroid Build Coastguard Worker static void onDelete(ExtraData Map, KeyT Old) {
278*9880d681SAndroid Build Coastguard Worker (*Map)->erase(Old);
279*9880d681SAndroid Build Coastguard Worker }
280*9880d681SAndroid Build Coastguard Worker };
TYPED_TEST(ValueMapTest,SurvivesModificationByConfig)281*9880d681SAndroid Build Coastguard Worker TYPED_TEST(ValueMapTest, SurvivesModificationByConfig) {
282*9880d681SAndroid Build Coastguard Worker ValueMap<TypeParam*, int, ModifyingConfig<TypeParam*> > *MapAddress;
283*9880d681SAndroid Build Coastguard Worker ValueMap<TypeParam*, int, ModifyingConfig<TypeParam*> > VM(&MapAddress);
284*9880d681SAndroid Build Coastguard Worker MapAddress = &VM;
285*9880d681SAndroid Build Coastguard Worker // Now the ModifyingConfig can modify the Map inside a callback.
286*9880d681SAndroid Build Coastguard Worker VM[this->BitcastV.get()] = 7;
287*9880d681SAndroid Build Coastguard Worker this->BitcastV->replaceAllUsesWith(this->AddV.get());
288*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0u, VM.count(this->BitcastV.get()));
289*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0u, VM.count(this->AddV.get()));
290*9880d681SAndroid Build Coastguard Worker VM[this->AddV.get()] = 7;
291*9880d681SAndroid Build Coastguard Worker this->AddV.reset();
292*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0u, VM.count(this->AddV.get()));
293*9880d681SAndroid Build Coastguard Worker }
294*9880d681SAndroid Build Coastguard Worker
295*9880d681SAndroid Build Coastguard Worker } // end namespace
296