llvm.org GIT mirror llvm / f1f27bb
ADT: Split out simple_ilist, a simple intrusive list Split out a new, low-level intrusive list type with clear semantics. Unlike iplist (and ilist), all operations on simple_ilist are intrusive, and simple_ilist never takes ownership of its nodes. This enables an intuitive API that has the right defaults for intrusive lists. - insert() takes references (not pointers!) to nodes (in iplist/ilist, passing a reference will cause the node to be copied). - erase() takes only iterators (like std::list), and does not destroy the nodes. - remove() takes only references and has the same behaviour as erase(). - clear() does not destroy the nodes. - The destructor does not destroy the nodes. - New API {erase,remove,clear}AndDispose() take an extra Disposer functor for callsites that want to call some disposal routine (e.g., std::default_delete). This list is not currently configurable, and has no callbacks. The initial motivation was to fix iplist<>::sort to work correctly (even with callbacks in ilist_traits<>). iplist<> uses simple_ilist<>::sort directly. The new test in unittests/IR/ModuleTest.cpp crashes without this commit. Fixing sort() via a low-level layer provided a good opportunity to: - Unit test the low-level functionality thoroughly. - Modernize the API, largely inspired by other intrusive list implementations. Here's a sketch of a longer-term plan: - Create BumpPtrList<>, a non-intrusive list implemented using simple_ilist<>, and use it for the Token list in lib/Support/YAMLParser.cpp. This will factor out the only real use of createNode(). - Evolve the iplist<> and ilist<> APIs in the direction of simple_ilist<>, making allocation/deallocation explicit at call sites (similar to simple_ilist<>::eraseAndDispose()). - Factor out remaining calls to createNode() and deleteNode() and remove the customization from ilist_traits<>. - Transition uses of iplist<>/ilist<> that don't need callbacks over to simple_ilist<>. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280107 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan P. N. Exon Smith 3 years ago
9 changed file(s) with 1019 addition(s) and 143 deletion(s). Raw diff Collapse all Expand all
2323 #ifndef LLVM_ADT_ILIST_H
2424 #define LLVM_ADT_ILIST_H
2525
26 #include "llvm/ADT/ilist_base.h"
27 #include "llvm/ADT/ilist_iterator.h"
28 #include "llvm/ADT/ilist_node.h"
26 #include "llvm/ADT/simple_ilist.h"
2927 #include "llvm/Support/Compiler.h"
30 #include
3128 #include
3229 #include
3330 #include
118115 /// ilist_sentinel, which holds pointers to the first and last nodes in the
119116 /// list.
120117 template >
121 class iplist : public Traits, ilist_base, ilist_node_access {
118 class iplist : public Traits, simple_ilist {
122119 // TODO: Drop this assertion and the transitive type traits anytime after
123120 // v4.0 is branched (i.e,. keep them for one release to help out-of-tree code
124121 // update).
125122 static_assert(!ilist_detail::HasObsoleteCustomization::value,
126123 "ilist customization points have changed!");
127124
128 ilist_sentinel Sentinel;
129
130 typedef ilist_node node_type;
131 typedef const ilist_node const_node_type;
125 typedef simple_ilist base_list_type;
132126
133127 static bool op_less(NodeTy &L, NodeTy &R) { return L < R; }
134128 static bool op_equal(NodeTy &L, NodeTy &R) { return L == R; }
138132 void operator=(const iplist &) = delete;
139133
140134 public:
141 typedef NodeTy *pointer;
142 typedef const NodeTy *const_pointer;
143 typedef NodeTy &reference;
144 typedef const NodeTy &const_reference;
145 typedef NodeTy value_type;
146 typedef ilist_iterator iterator;
147 typedef ilist_iterator const_iterator;
148 typedef size_t size_type;
149 typedef ptrdiff_t difference_type;
150 typedef ilist_iterator const_reverse_iterator;
151 typedef ilist_iterator reverse_iterator;
135 typedef typename base_list_type::pointer pointer;
136 typedef typename base_list_type::const_pointer const_pointer;
137 typedef typename base_list_type::reference reference;
138 typedef typename base_list_type::const_reference const_reference;
139 typedef typename base_list_type::value_type value_type;
140 typedef typename base_list_type::size_type size_type;
141 typedef typename base_list_type::difference_type difference_type;
142 typedef typename base_list_type::iterator iterator;
143 typedef typename base_list_type::const_iterator const_iterator;
144 typedef typename base_list_type::reverse_iterator reverse_iterator;
145 typedef
146 typename base_list_type::const_reverse_iterator const_reverse_iterator;
152147
153148 iplist() = default;
154149 ~iplist() { clear(); }
155150
156 // Iterator creation methods.
157 iterator begin() { return ++iterator(Sentinel); }
158 const_iterator begin() const { return ++const_iterator(Sentinel); }
159 iterator end() { return iterator(Sentinel); }
160 const_iterator end() const { return const_iterator(Sentinel); }
161
162 // reverse iterator creation methods.
163 reverse_iterator rbegin() { return ++reverse_iterator(Sentinel); }
164 const_reverse_iterator rbegin() const{ return ++const_reverse_iterator(Sentinel); }
165 reverse_iterator rend() { return reverse_iterator(Sentinel); }
166 const_reverse_iterator rend() const { return const_reverse_iterator(Sentinel); }
167
168151 // Miscellaneous inspection routines.
169152 size_type max_size() const { return size_type(-1); }
170 bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { return Sentinel.empty(); }
171
172 // Front and back accessor functions...
173 reference front() {
174 assert(!empty() && "Called front() on empty list!");
175 return *begin();
176 }
177 const_reference front() const {
178 assert(!empty() && "Called front() on empty list!");
179 return *begin();
180 }
181 reference back() {
182 assert(!empty() && "Called back() on empty list!");
183 return *--end();
184 }
185 const_reference back() const {
186 assert(!empty() && "Called back() on empty list!");
187 return *--end();
188 }
153
154 using base_list_type::begin;
155 using base_list_type::end;
156 using base_list_type::rbegin;
157 using base_list_type::rend;
158 using base_list_type::empty;
159 using base_list_type::front;
160 using base_list_type::back;
189161
190162 void swap(iplist &RHS) {
191163 assert(0 && "Swap does not use list traits callback correctly yet!");
192 std::swap(Sentinel, RHS.Sentinel);
164 base_list_type::swap(RHS);
193165 }
194166
195167 iterator insert(iterator where, NodeTy *New) {
196 ilist_base::insertBefore(*where.getNodePtr(), *this->getNodePtr(New));
197
168 auto I = base_list_type::insert(where, *New);
198169 this->addNodeToList(New); // Notify traits that we added a node...
199 return iterator(New);
170 return I;
200171 }
201172
202173 iterator insert(iterator where, const NodeTy &New) {
211182 }
212183
213184 NodeTy *remove(iterator &IT) {
214 assert(IT != end() && "Cannot remove end of list!");
215 NodeTy *Node = &*IT++;
216 ilist_base::remove(*this->getNodePtr(Node));
185 NodeTy *Node = &*IT;
186 base_list_type::erase(IT++);
217187 this->removeNodeFromList(Node); // Notify traits that we removed a node...
218188 return Node;
219189 }
240210 ///
241211 /// This should only be used immediately before freeing nodes in bulk to
242212 /// avoid traversing the list and bringing all the nodes into cache.
243 void clearAndLeakNodesUnsafely() { Sentinel.reset(); }
213 void clearAndLeakNodesUnsafely() { base_list_type::clear(); }
244214
245215 private:
246216 // transfer - The heart of the splice function. Move linked list nodes from
250220 if (position == last)
251221 return;
252222
253 ilist_base::transferBefore(*position.getNodePtr(), *first.getNodePtr(),
254 *last.getNodePtr());
223 base_list_type::splice(position, L2, first, last);
255224
256225 // Callback. Note that the nodes have moved from before-last to
257226 // before-position.
264233 // Functionality derived from other functions defined above...
265234 //
266235
267 size_type LLVM_ATTRIBUTE_UNUSED_RESULT size() const {
268 return std::distance(begin(), end());
269 }
236 using base_list_type::size;
270237
271238 iterator erase(iterator first, iterator last) {
272239 while (first != last)
317284 void merge(iplist &Right, Compare comp) {
318285 if (this == &Right)
319286 return;
320 iterator First1 = begin(), Last1 = end();
321 iterator First2 = Right.begin(), Last2 = Right.end();
322 while (First1 != Last1 && First2 != Last2) {
323 if (comp(*First2, *First1)) {
324 iterator Next = First2;
325 transfer(First1, Right, First2, ++Next);
326 First2 = Next;
327 } else {
328 ++First1;
329 }
330 }
331 if (First2 != Last2)
332 transfer(Last1, Right, First2, Last2);
287 this->transferNodesFromList(Right, Right.begin(), Right.end());
288 base_list_type::merge(Right, comp);
333289 }
334290 void merge(iplist &Right) { return merge(Right, op_less); }
335291
336 template
337 void sort(Compare comp) {
338 // The list is empty, vacuously sorted.
339 if (empty())
340 return;
341 // The list has a single element, vacuously sorted.
342 if (std::next(begin()) == end())
343 return;
344 // Find the split point for the list.
345 iterator Center = begin(), End = begin();
346 while (End != end() && std::next(End) != end()) {
347 Center = std::next(Center);
348 End = std::next(std::next(End));
349 }
350 // Split the list into two.
351 iplist RightHalf;
352 RightHalf.splice(RightHalf.begin(), *this, Center, end());
353
354 // Sort the two sublists.
355 sort(comp);
356 RightHalf.sort(comp);
357
358 // Merge the two sublists back together.
359 merge(RightHalf, comp);
360 }
361 void sort() { sort(op_less); }
292 using base_list_type::sort;
362293
363294 /// \brief Get the previous node, or \c nullptr for the list head.
364295 NodeTy *getPrevNode(NodeTy &N) const {
3838 N.setNext(nullptr);
3939 }
4040
41 static void removeRangeImpl(ilist_node_base &First, ilist_node_base &Last) {
42 ilist_node_base *Prev = First.getPrev();
43 ilist_node_base *Final = Last.getPrev();
44 Last.setPrev(Prev);
45 Prev->setNext(&Last);
46
47 // Not strictly necessary, but helps catch a class of bugs.
48 First.setPrev(nullptr);
49 Final->setNext(nullptr);
50 }
51
4152 static void transferBeforeImpl(ilist_node_base &Next, ilist_node_base &First,
4253 ilist_node_base &Last) {
43 assert(&Next != &Last && "Should be checked by callers");
44 assert(&First != &Last && "Should be checked by callers");
54 if (&Next == &Last || &First == &Last)
55 return;
56
4557 // Position cannot be contained in the range to be transferred.
4658 assert(&Next != &First &&
4759 // Check for the most common mistake.
6678 }
6779
6880 template static void remove(T &N) { removeImpl(N); }
81 template static void removeRange(T &First, T &Last) {
82 removeRangeImpl(First, Last);
83 }
6984
7085 template static void transferBefore(T &Next, T &First, T &Last) {
7186 transferBeforeImpl(Next, First, Last);
0 //===- llvm/ADT/simple_ilist.h - Simple Intrusive List ----------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_ADT_SIMPLE_ILIST_H
10 #define LLVM_ADT_SIMPLE_ILIST_H
11
12 #include "llvm/ADT/ilist_base.h"
13 #include "llvm/ADT/ilist_iterator.h"
14 #include "llvm/ADT/ilist_node.h"
15 #include
16 #include
17 #include
18
19 namespace llvm {
20
21 /// A simple intrusive list implementation.
22 ///
23 /// This is a simple intrusive list for a \c T that inherits from \c
24 /// ilist_node. The list never takes ownership of anything inserted in it.
25 ///
26 /// Unlike \a iplist and \a ilist, \a simple_ilist never allocates or
27 /// deletes values, and has no callback traits.
28 ///
29 /// The API for adding nodes include \a push_front(), \a push_back(), and \a
30 /// insert(). These all take values by reference (not by pointer), except for
31 /// the range version of \a insert().
32 ///
33 /// There are three sets of API for discarding nodes from the list: \a
34 /// remove(), which takes a reference to the node to remove, \a erase(), which
35 /// takes an iterator or iterator range and returns the next one, and \a
36 /// clear(), which empties out the container. All three are constant time
37 /// operations. None of these deletes any nodes; in particular, if there is a
38 /// single node in the list, then these have identical semantics:
39 /// \li \c L.remove(L.front());
40 /// \li \c L.erase(L.begin());
41 /// \li \c L.clear();
42 ///
43 /// As a convenience for callers, there are parallel APIs that take a \c
44 /// Disposer (such as \c std::default_delete): \a removeAndDispose(), \a
45 /// eraseAndDispose(), and \a clearAndDispose(). These have different names
46 /// because the extra semantic is otherwise non-obvious. They are equivalent
47 /// to calling \a std::for_each() on the range to be discarded.
48 template class simple_ilist : ilist_base, ilist_node_access {
49 ilist_sentinel Sentinel;
50
51 public:
52 typedef T value_type;
53 typedef T *pointer;
54 typedef T &reference;
55 typedef const T *const_pointer;
56 typedef const T &const_reference;
57 typedef ilist_iterator iterator;
58 typedef ilist_iterator const_iterator;
59 typedef size_t size_type;
60 typedef ptrdiff_t difference_type;
61 typedef ilist_iterator const_reverse_iterator;
62 typedef ilist_iterator reverse_iterator;
63
64 simple_ilist() = default;
65 ~simple_ilist() = default;
66
67 // No copy constructors.
68 simple_ilist(const simple_ilist &) = delete;
69 simple_ilist &operator=(const simple_ilist &) = delete;
70
71 // Move constructors.
72 simple_ilist(simple_ilist &&X) { splice(end(), X); }
73 simple_ilist &operator=(simple_ilist &&X) {
74 clear();
75 splice(end(), X);
76 return *this;
77 }
78
79 iterator begin() { return ++iterator(Sentinel); }
80 const_iterator begin() const { return ++const_iterator(Sentinel); }
81 iterator end() { return iterator(Sentinel); }
82 const_iterator end() const { return const_iterator(Sentinel); }
83 reverse_iterator rbegin() { return ++reverse_iterator(Sentinel); }
84 const_reverse_iterator rbegin() const {
85 return ++const_reverse_iterator(Sentinel);
86 }
87 reverse_iterator rend() { return reverse_iterator(Sentinel); }
88 const_reverse_iterator rend() const {
89 return const_reverse_iterator(Sentinel);
90 }
91
92 /// Check if the list is empty in constant time.
93 bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { return Sentinel.empty(); }
94
95 /// Calculate the size of the list in linear time.
96 size_type LLVM_ATTRIBUTE_UNUSED_RESULT size() const {
97 return std::distance(begin(), end());
98 }
99
100 reference front() { return *begin(); }
101 const_reference front() const { return *begin(); }
102 reference back() { return *rbegin(); }
103 const_reference back() const { return *rbegin(); }
104
105 /// Insert a node at the front; never copies.
106 void push_front(reference Node) { insert(begin(), Node); }
107
108 /// Insert a node at the back; never copies.
109 void push_back(reference Node) { insert(end(), Node); }
110
111 /// Remove the node at the front; never deletes.
112 void pop_front() { erase(begin()); }
113
114 /// Remove the node at the back; never deletes.
115 void pop_back() { erase(--end()); }
116
117 /// Swap with another list in place using std::swap.
118 void swap(simple_ilist &X) { std::swap(*this, X); }
119
120 /// Insert a node by reference; never copies.
121 iterator insert(iterator I, reference Node) {
122 ilist_base::insertBefore(*I.getNodePtr(), *this->getNodePtr(&Node));
123 return iterator(&Node);
124 }
125
126 /// Insert a range of nodes; never copies.
127 template
128 void insert(iterator I, Iterator First, Iterator Last) {
129 for (; First != Last; ++First)
130 insert(I, *First);
131 }
132
133 /// Remove a node by reference; never deletes.
134 ///
135 /// \see \a erase() for removing by iterator.
136 /// \see \a removeAndDispose() if the node should be deleted.
137 void remove(reference N) { ilist_base::remove(*this->getNodePtr(&N)); }
138
139 /// Remove a node by reference and dispose of it.
140 template
141 void removeAndDispose(reference N, Disposer dispose) {
142 remove(N);
143 dispose(&N);
144 }
145
146 /// Remove a node by iterator; never deletes.
147 ///
148 /// \see \a remove() for removing by reference.
149 /// \see \a eraseAndDispose() it the node should be deleted.
150 iterator erase(iterator I) {
151 assert(I != end() && "Cannot remove end of list!");
152 remove(*I++);
153 return I;
154 }
155
156 /// Remove a range of nodes; never deletes.
157 ///
158 /// \see \a eraseAndDispose() if the nodes should be deleted.
159 iterator erase(iterator First, iterator Last) {
160 ilist_base::removeRange(*First.getNodePtr(), *Last.getNodePtr());
161 return Last;
162 }
163
164 /// Remove a node by iterator and dispose of it.
165 template
166 iterator eraseAndDispose(iterator I, Disposer dispose) {
167 auto Next = std::next(I);
168 erase(I);
169 dispose(&*I);
170 return Next;
171 }
172
173 /// Remove a range of nodes and dispose of them.
174 template
175 iterator eraseAndDispose(iterator First, iterator Last, Disposer dispose) {
176 while (First != Last)
177 First = eraseAndDispose(First, dispose);
178 return Last;
179 }
180
181 /// Clear the list; never deletes.
182 ///
183 /// \see \a clearAndDispose() if the nodes should be deleted.
184 void clear() { Sentinel.reset(); }
185
186 /// Clear the list and dispose of the nodes.
187 template void clearAndDispose(Disposer dispose) {
188 eraseAndDispose(begin(), end(), dispose);
189 }
190
191 /// Splice in another list.
192 void splice(iterator I, simple_ilist &L2) {
193 splice(I, L2, L2.begin(), L2.end());
194 }
195
196 /// Splice in a node from another list.
197 void splice(iterator I, simple_ilist &L2, iterator Node) {
198 splice(I, L2, Node, std::next(Node));
199 }
200
201 /// Splice in a range of nodes from another list.
202 void splice(iterator I, simple_ilist &, iterator First, iterator Last) {
203 ilist_base::transferBefore(*I.getNodePtr(), *First.getNodePtr(),
204 *Last.getNodePtr());
205 }
206
207 /// Merge in another list.
208 ///
209 /// \pre \c this and \p RHS are sorted.
210 ///@{
211 void merge(simple_ilist &RHS) { merge(RHS, std::less()); }
212 template void merge(simple_ilist &RHS, Compare comp);
213 ///@}
214
215 /// Sort the list.
216 ///@{
217 void sort() { sort(std::less()); }
218 template void sort(Compare comp);
219 ///@}
220 };
221
222 template
223 template
224 void simple_ilist::merge(simple_ilist &RHS, Compare comp) {
225 if (this == &RHS || RHS.empty())
226 return;
227 iterator LI = begin(), LE = end();
228 iterator RI = RHS.begin(), RE = RHS.end();
229 while (LI != LE) {
230 if (comp(*RI, *LI)) {
231 // Transfer a run of at least size 1 from RHS to LHS.
232 iterator RunStart = RI++;
233 RI = std::find_if(RI, RE, [&](reference RV) { return !comp(RV, *LI); });
234 splice(LI, RHS, RunStart, RI);
235 if (RI == RE)
236 return;
237 }
238 ++LI;
239 }
240 // Transfer the remaining RHS nodes once LHS is finished.
241 splice(LE, RHS, RI, RE);
242 }
243
244 template
245 template
246 void simple_ilist::sort(Compare comp) {
247 // Vacuously sorted.
248 if (empty() || std::next(begin()) == end())
249 return;
250
251 // Split the list in the middle.
252 iterator Center = begin(), End = begin();
253 while (End != end() && ++End != end()) {
254 ++Center;
255 ++End;
256 }
257 simple_ilist RHS;
258 RHS.splice(RHS.end(), *this, Center, end());
259
260 // Sort the sublists and merge back together.
261 sort(comp);
262 RHS.sort(comp);
263 merge(RHS, comp);
264 }
265
266 } // end namespace llvm
267
268 #endif // LLVM_ADT_SIMPLE_ILIST_H
4343 ScopeExitTest.cpp
4444 SequenceTest.cpp
4545 SetVectorTest.cpp
46 SimpleIListTest.cpp
4647 SmallPtrSetTest.cpp
4748 SmallStringTest.cpp
4849 SmallVectorTest.cpp
6262 EXPECT_EQ(nullptr, B.getNext());
6363 }
6464
65 TEST(IListBaseTest, removeRangeImpl) {
66 ilist_node_base S, A, B, C, D;
67
68 // [S] <-> A <-> B <-> C <-> D <-> [S]
69 S.setPrev(&S);
70 S.setNext(&S);
71 ilist_base::insertBeforeImpl(S, A);
72 ilist_base::insertBeforeImpl(S, B);
73 ilist_base::insertBeforeImpl(S, C);
74 ilist_base::insertBeforeImpl(S, D);
75
76 // [S] <-> A <-> D <-> [S]
77 ilist_base::removeRangeImpl(B, D);
78 EXPECT_EQ(&D, S.getPrev());
79 EXPECT_EQ(&A, D.getPrev());
80 EXPECT_EQ(&S, A.getPrev());
81 EXPECT_EQ(&A, S.getNext());
82 EXPECT_EQ(&D, A.getNext());
83 EXPECT_EQ(&S, D.getNext());
84 EXPECT_EQ(nullptr, B.getPrev());
85 EXPECT_EQ(nullptr, C.getNext());
86 }
87
88 TEST(IListBaseTest, removeRangeImplAllButSentinel) {
89 ilist_node_base S, A, B;
90
91 // [S] <-> A <-> B <-> [S]
92 S.setPrev(&S);
93 S.setNext(&S);
94 ilist_base::insertBeforeImpl(S, A);
95 ilist_base::insertBeforeImpl(S, B);
96
97 // [S] <-> [S]
98 ilist_base::removeRangeImpl(A, S);
99 EXPECT_EQ(&S, S.getPrev());
100 EXPECT_EQ(&S, S.getNext());
101 EXPECT_EQ(nullptr, A.getPrev());
102 EXPECT_EQ(nullptr, B.getNext());
103 }
104
65105 TEST(IListBaseTest, transferBeforeImpl) {
66106 ilist_node_base S1, S2, A, B, C, D, E;
67107
66 //
77 //===----------------------------------------------------------------------===//
88
9 #include "llvm/ADT/ilist.h"
9 #include "llvm/ADT/simple_ilist.h"
1010 #include "gtest/gtest.h"
1111
1212 using namespace llvm;
1616 struct Node : ilist_node {};
1717
1818 TEST(IListIteratorTest, DefaultConstructor) {
19 iplist::iterator I;
20 iplist::reverse_iterator RI;
21 iplist::const_iterator CI;
22 iplist::const_reverse_iterator CRI;
19 simple_ilist::iterator I;
20 simple_ilist::reverse_iterator RI;
21 simple_ilist::const_iterator CI;
22 simple_ilist::const_reverse_iterator CRI;
2323 EXPECT_EQ(nullptr, I.getNodePtr());
2424 EXPECT_EQ(nullptr, CI.getNodePtr());
2525 EXPECT_EQ(nullptr, RI.getNodePtr());
3737 }
3838
3939 TEST(IListIteratorTest, Empty) {
40 iplist L;
40 simple_ilist L;
4141
4242 // Check iterators of L.
4343 EXPECT_EQ(L.begin(), L.end());
4848 EXPECT_EQ(L.rend(), L.end().getReverse());
4949
5050 // Iterators shouldn't match default constructors.
51 iplist::iterator I;
52 iplist::reverse_iterator RI;
51 simple_ilist::iterator I;
52 simple_ilist::reverse_iterator RI;
5353 EXPECT_NE(I, L.begin());
5454 EXPECT_NE(I, L.end());
5555 EXPECT_NE(RI, L.rbegin());
5656 EXPECT_NE(RI, L.rend());
57
58 // Don't delete nodes.
59 L.clearAndLeakNodesUnsafely();
6057 }
6158
6259 TEST(IListIteratorTest, OneNodeList) {
63 iplist L;
60 simple_ilist L;
6461 Node A;
65 L.insert(L.end(), &A);
62 L.insert(L.end(), A);
6663
6764 // Check address of reference.
6865 EXPECT_EQ(&A, &*L.begin());
8077 // Check conversions.
8178 EXPECT_EQ(L.rbegin(), L.begin().getReverse());
8279 EXPECT_EQ(L.begin(), L.rbegin().getReverse());
83
84 // Don't delete nodes.
85 L.clearAndLeakNodesUnsafely();
8680 }
8781
8882 TEST(IListIteratorTest, TwoNodeList) {
89 iplist L;
83 simple_ilist L;
9084 Node A, B;
91 L.insert(L.end(), &A);
92 L.insert(L.end(), &B);
85 L.insert(L.end(), A);
86 L.insert(L.end(), B);
9387
9488 // Check order.
9589 EXPECT_EQ(&A, &*L.begin());
10498 EXPECT_EQ(L.rbegin(), (++L.begin()).getReverse());
10599 EXPECT_EQ(++L.begin(), L.rbegin().getReverse());
106100 EXPECT_EQ(L.begin(), (++L.rbegin()).getReverse());
107
108 // Don't delete nodes.
109 L.clearAndLeakNodesUnsafely();
110101 }
111102
112103 TEST(IListIteratorTest, CheckEraseForward) {
113 iplist L;
104 simple_ilist L;
114105 Node A, B;
115 L.insert(L.end(), &A);
116 L.insert(L.end(), &B);
106 L.insert(L.end(), A);
107 L.insert(L.end(), B);
117108
118109 // Erase nodes.
119110 auto I = L.begin();
120111 EXPECT_EQ(&A, &*I);
121 EXPECT_EQ(&A, L.remove(I++));
112 L.remove(*I++);
122113 EXPECT_EQ(&B, &*I);
123 EXPECT_EQ(&B, L.remove(I++));
114 L.remove(*I++);
124115 EXPECT_EQ(L.end(), I);
125
126 // Don't delete nodes.
127 L.clearAndLeakNodesUnsafely();
128116 }
129117
130118 TEST(IListIteratorTest, CheckEraseReverse) {
131 iplist L;
119 simple_ilist L;
132120 Node A, B;
133 L.insert(L.end(), &A);
134 L.insert(L.end(), &B);
121 L.insert(L.end(), A);
122 L.insert(L.end(), B);
135123
136124 // Erase nodes.
137125 auto RI = L.rbegin();
138126 EXPECT_EQ(&B, &*RI);
139 EXPECT_EQ(&B, L.remove(&*RI++));
127 L.remove(*RI++);
140128 EXPECT_EQ(&A, &*RI);
141 EXPECT_EQ(&A, L.remove(&*RI++));
129 L.remove(*RI++);
142130 EXPECT_EQ(L.rend(), RI);
143
144 // Don't delete nodes.
145 L.clearAndLeakNodesUnsafely();
146131 }
147132
148133 } // end namespace
0 //===- unittests/ADT/SimpleIListTest.cpp - simple_ilist unit tests --------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/ADT/simple_ilist.h"
10 #include "gtest/gtest.h"
11
12 using namespace llvm;
13
14 namespace {
15
16 struct Node : ilist_node {};
17 bool operator<(const Node &L, const Node &R) { return &L < &R; }
18 bool makeFalse(const Node &, const Node &) { return false; }
19
20 struct deleteNode : std::default_delete {};
21 void doNothing(Node *) {}
22
23 TEST(SimpleIListTest, DefaultConstructor) {
24 simple_ilist L;
25 EXPECT_EQ(L.begin(), L.end());
26 EXPECT_TRUE(L.empty());
27 EXPECT_EQ(0u, L.size());
28 }
29
30 TEST(SimpleIListTest, pushPopFront) {
31 simple_ilist L;
32 Node A, B;
33 L.push_front(B);
34 L.push_front(A);
35 EXPECT_EQ(&A, &L.front());
36 EXPECT_EQ(&B, &L.back());
37 EXPECT_FALSE(L.empty());
38 EXPECT_EQ(2u, L.size());
39
40 // Pop front and check the new front.
41 L.pop_front();
42 EXPECT_EQ(&B, &L.front());
43
44 // Pop to empty.
45 L.pop_front();
46 EXPECT_TRUE(L.empty());
47 }
48
49 TEST(SimpleIListTest, pushPopBack) {
50 simple_ilist L;
51 Node A, B;
52 L.push_back(A);
53 L.push_back(B);
54 EXPECT_EQ(&A, &L.front());
55 EXPECT_EQ(&B, &L.back());
56 EXPECT_FALSE(L.empty());
57 EXPECT_EQ(2u, L.size());
58
59 // Pop back and check the new front.
60 L.pop_back();
61 EXPECT_EQ(&A, &L.back());
62
63 // Pop to empty.
64 L.pop_back();
65 EXPECT_TRUE(L.empty());
66 }
67
68 TEST(SimpleIListTest, swap) {
69 simple_ilist L1, L2;
70 Node A, B;
71 L1.push_back(A);
72 L1.push_back(B);
73 L1.swap(L2);
74 EXPECT_TRUE(L1.empty());
75 EXPECT_EQ(0u, L1.size());
76 EXPECT_EQ(&A, &L2.front());
77 EXPECT_EQ(&B, &L2.back());
78 EXPECT_FALSE(L2.empty());
79 EXPECT_EQ(2u, L2.size());
80 }
81
82 TEST(SimpleIListTest, insertEraseAtEnd) {
83 simple_ilist L;
84 Node A, B;
85 L.insert(L.end(), A);
86 L.insert(L.end(), B);
87 EXPECT_EQ(&A, &L.front());
88 EXPECT_EQ(&B, &L.back());
89 EXPECT_FALSE(L.empty());
90 EXPECT_EQ(2u, L.size());
91 }
92
93 TEST(SimpleIListTest, insertAtBegin) {
94 simple_ilist L;
95 Node A, B;
96 L.insert(L.begin(), B);
97 L.insert(L.begin(), A);
98 EXPECT_EQ(&A, &L.front());
99 EXPECT_EQ(&B, &L.back());
100 EXPECT_FALSE(L.empty());
101 EXPECT_EQ(2u, L.size());
102 }
103
104 TEST(SimpleIListTest, remove) {
105 simple_ilist L;
106 Node A, B, C;
107 L.push_back(A);
108 L.push_back(B);
109 L.push_back(C);
110 EXPECT_EQ(&A, &L.front());
111 EXPECT_EQ(&B, &*++L.begin());
112 EXPECT_EQ(&C, &L.back());
113 EXPECT_EQ(3u, L.size());
114
115 L.remove(B);
116 EXPECT_EQ(&A, &L.front());
117 EXPECT_EQ(&C, &L.back());
118 EXPECT_EQ(2u, L.size());
119
120 L.remove(A);
121 EXPECT_EQ(&C, &L.front());
122 EXPECT_EQ(1u, L.size());
123
124 L.remove(C);
125 EXPECT_TRUE(L.empty());
126 }
127
128 TEST(SimpleIListTest, removeAndDispose) {
129 simple_ilist L;
130 Node A, C;
131 Node *B = new Node;
132 L.push_back(A);
133 L.push_back(*B);
134 L.push_back(C);
135 EXPECT_EQ(&A, &L.front());
136 EXPECT_EQ(B, &*++L.begin());
137 EXPECT_EQ(&C, &L.back());
138 EXPECT_EQ(3u, L.size());
139
140 L.removeAndDispose(*B, deleteNode());
141 EXPECT_EQ(&A, &L.front());
142 EXPECT_EQ(&C, &L.back());
143 EXPECT_EQ(2u, L.size());
144 }
145
146 TEST(SimpleIListTest, removeAndDisposeNullDeleter) {
147 simple_ilist L;
148 Node A, B, C;
149 L.push_back(A);
150 L.push_back(B);
151 L.push_back(C);
152 EXPECT_EQ(&A, &L.front());
153 EXPECT_EQ(&B, &*++L.begin());
154 EXPECT_EQ(&C, &L.back());
155 EXPECT_EQ(3u, L.size());
156
157 L.removeAndDispose(B, doNothing);
158 EXPECT_EQ(&A, &L.front());
159 EXPECT_EQ(&C, &L.back());
160 EXPECT_EQ(2u, L.size());
161 }
162
163 TEST(SimpleIListTest, erase) {
164 simple_ilist L;
165 Node A, B, C;
166 L.push_back(A);
167 L.push_back(B);
168 L.push_back(C);
169 EXPECT_EQ(&A, &L.front());
170 EXPECT_EQ(&B, &*++L.begin());
171 EXPECT_EQ(&C, &L.back());
172 EXPECT_EQ(3u, L.size());
173
174 EXPECT_EQ(C.getIterator(), L.erase(B.getIterator()));
175 EXPECT_EQ(&A, &L.front());
176 EXPECT_EQ(&C, &L.back());
177 EXPECT_EQ(2u, L.size());
178 }
179
180 TEST(SimpleIListTest, eraseAndDispose) {
181 simple_ilist L;
182 Node A, C;
183 Node *B = new Node;
184 L.push_back(A);
185 L.push_back(*B);
186 L.push_back(C);
187 EXPECT_EQ(&A, &L.front());
188 EXPECT_EQ(B, &*++L.begin());
189 EXPECT_EQ(&C, &L.back());
190 EXPECT_EQ(3u, L.size());
191
192 L.eraseAndDispose(B->getIterator(), deleteNode());
193 EXPECT_EQ(&A, &L.front());
194 EXPECT_EQ(&C, &L.back());
195 EXPECT_EQ(2u, L.size());
196 }
197
198 TEST(SimpleIListTest, eraseAndDisposeNullDeleter) {
199 simple_ilist L;
200 Node A, B, C;
201 L.push_back(A);
202 L.push_back(B);
203 L.push_back(C);
204 EXPECT_EQ(&A, &L.front());
205 EXPECT_EQ(&B, &*++L.begin());
206 EXPECT_EQ(&C, &L.back());
207 EXPECT_EQ(3u, L.size());
208
209 L.eraseAndDispose(B.getIterator(), doNothing);
210 EXPECT_EQ(&A, &L.front());
211 EXPECT_EQ(&C, &L.back());
212 EXPECT_EQ(2u, L.size());
213 }
214
215 TEST(SimpleIListTest, eraseRange) {
216 simple_ilist L;
217 Node A, B, C, D, E;
218 L.push_back(A);
219 L.push_back(B);
220 L.push_back(C);
221 L.push_back(D);
222 L.push_back(E);
223 auto I = L.begin();
224 EXPECT_EQ(&A, &*I++);
225 EXPECT_EQ(&B, &*I++);
226 EXPECT_EQ(&C, &*I++);
227 EXPECT_EQ(&D, &*I++);
228 EXPECT_EQ(&E, &*I++);
229 EXPECT_EQ(L.end(), I);
230 EXPECT_EQ(5u, L.size());
231
232 // Erase a range.
233 EXPECT_EQ(E.getIterator(), L.erase(B.getIterator(), E.getIterator()));
234 EXPECT_EQ(&A, &L.front());
235 EXPECT_EQ(&E, &L.back());
236 EXPECT_EQ(2u, L.size());
237 }
238
239 TEST(SimpleIListTest, eraseAndDisposeRange) {
240 simple_ilist L;
241 Node A, *B = new Node, *C = new Node, *D = new Node, E;
242 L.push_back(A);
243 L.push_back(*B);
244 L.push_back(*C);
245 L.push_back(*D);
246 L.push_back(E);
247 auto I = L.begin();
248 EXPECT_EQ(&A, &*I++);
249 EXPECT_EQ(B, &*I++);
250 EXPECT_EQ(C, &*I++);
251 EXPECT_EQ(D, &*I++);
252 EXPECT_EQ(&E, &*I++);
253 EXPECT_EQ(L.end(), I);
254 EXPECT_EQ(5u, L.size());
255
256 // Erase a range.
257 EXPECT_EQ(E.getIterator(),
258 L.eraseAndDispose(B->getIterator(), E.getIterator(), deleteNode()));
259 EXPECT_EQ(&A, &L.front());
260 EXPECT_EQ(&E, &L.back());
261 EXPECT_EQ(2u, L.size());
262 }
263
264 TEST(SimpleIListTest, eraseAndDisposeRangeNullDeleter) {
265 simple_ilist L;
266 Node A, B, C, D, E;
267 L.push_back(A);
268 L.push_back(B);
269 L.push_back(C);
270 L.push_back(D);
271 L.push_back(E);
272 auto I = L.begin();
273 EXPECT_EQ(&A, &*I++);
274 EXPECT_EQ(&B, &*I++);
275 EXPECT_EQ(&C, &*I++);
276 EXPECT_EQ(&D, &*I++);
277 EXPECT_EQ(&E, &*I++);
278 EXPECT_EQ(L.end(), I);
279 EXPECT_EQ(5u, L.size());
280
281 // Erase a range.
282 EXPECT_EQ(E.getIterator(),
283 L.eraseAndDispose(B.getIterator(), E.getIterator(), doNothing));
284 EXPECT_EQ(&A, &L.front());
285 EXPECT_EQ(&E, &L.back());
286 EXPECT_EQ(2u, L.size());
287 }
288
289 TEST(SimpleIListTest, clear) {
290 simple_ilist L;
291 Node A, B;
292 L.push_back(A);
293 L.push_back(B);
294 L.clear();
295 EXPECT_TRUE(L.empty());
296 EXPECT_EQ(0u, L.size());
297 }
298
299 TEST(SimpleIListTest, clearAndDispose) {
300 simple_ilist L;
301 Node *A = new Node;
302 Node *B = new Node;
303 L.push_back(*A);
304 L.push_back(*B);
305 L.clearAndDispose(deleteNode());
306 EXPECT_TRUE(L.empty());
307 EXPECT_EQ(0u, L.size());
308 }
309
310 TEST(SimpleIListTest, clearAndDisposeNullDeleter) {
311 simple_ilist L;
312 Node A, B;
313 L.push_back(A);
314 L.push_back(B);
315 L.clearAndDispose(doNothing);
316 EXPECT_TRUE(L.empty());
317 EXPECT_EQ(0u, L.size());
318 }
319
320 TEST(SimpleIListTest, spliceList) {
321 simple_ilist L1, L2;
322 Node A, B, C, D;
323
324 // [A, D].
325 L1.push_back(A);
326 L1.push_back(D);
327
328 // [B, C].
329 L2.push_back(B);
330 L2.push_back(C);
331
332 // Splice in L2, giving [A, B, C, D].
333 L1.splice(--L1.end(), L2);
334 EXPECT_TRUE(L2.empty());
335 EXPECT_EQ(4u, L1.size());
336 auto I = L1.begin();
337 EXPECT_EQ(&A, &*I++);
338 EXPECT_EQ(&B, &*I++);
339 EXPECT_EQ(&C, &*I++);
340 EXPECT_EQ(&D, &*I++);
341 EXPECT_EQ(L1.end(), I);
342 }
343
344 TEST(SimpleIListTest, spliceSingle) {
345 simple_ilist L1, L2;
346 Node A, B, C, D, E;
347
348 // [A, C].
349 L1.push_back(A);
350 L1.push_back(C);
351
352 // [D, B, E].
353 L2.push_back(D);
354 L2.push_back(B);
355 L2.push_back(E);
356
357 // Splice B from L2 to L1, giving [A, B, C] and [D, E].
358 L1.splice(--L1.end(), L2, ++L2.begin());
359 auto I = L1.begin();
360 EXPECT_EQ(&A, &*I++);
361 EXPECT_EQ(&B, &*I++);
362 EXPECT_EQ(&C, &*I++);
363 EXPECT_EQ(L1.end(), I);
364
365 I = L2.begin();
366 EXPECT_EQ(&D, &*I++);
367 EXPECT_EQ(&E, &*I++);
368 EXPECT_EQ(L2.end(), I);
369 }
370
371 TEST(SimpleIListTest, spliceRange) {
372 simple_ilist L1, L2;
373 Node A, B, C, D, E, F;
374
375 // [A, D].
376 L1.push_back(A);
377 L1.push_back(D);
378
379 // [E, B, C, F].
380 L2.push_back(E);
381 L2.push_back(B);
382 L2.push_back(C);
383 L2.push_back(F);
384
385 // Splice B from L2 to L1, giving [A, B, C, D] and [E, F].
386 L1.splice(--L1.end(), L2, ++L2.begin(), --L2.end());
387 auto I = L1.begin();
388 EXPECT_EQ(&A, &*I++);
389 EXPECT_EQ(&B, &*I++);
390 EXPECT_EQ(&C, &*I++);
391 EXPECT_EQ(&D, &*I++);
392 EXPECT_EQ(L1.end(), I);
393
394 I = L2.begin();
395 EXPECT_EQ(&E, &*I++);
396 EXPECT_EQ(&F, &*I++);
397 EXPECT_EQ(L2.end(), I);
398 }
399
400 TEST(SimpleIListTest, merge) {
401 for (bool IsL1LHS : {false, true}) {
402 simple_ilist L1, L2;
403 Node Ns[10];
404
405 // Fill L1.
406 L1.push_back(Ns[0]);
407 L1.push_back(Ns[3]);
408 L1.push_back(Ns[4]);
409 L1.push_back(Ns[8]);
410
411 // Fill L2.
412 L2.push_back(Ns[1]);
413 L2.push_back(Ns[2]);
414 L2.push_back(Ns[5]);
415 L2.push_back(Ns[6]);
416 L2.push_back(Ns[7]);
417 L2.push_back(Ns[9]);
418
419 // Check setup.
420 EXPECT_EQ(4u, L1.size());
421 EXPECT_EQ(6u, L2.size());
422 EXPECT_TRUE(std::is_sorted(L1.begin(), L1.end()));
423 EXPECT_TRUE(std::is_sorted(L2.begin(), L2.end()));
424
425 // Merge.
426 auto &LHS = IsL1LHS ? L1 : L2;
427 auto &RHS = IsL1LHS ? L2 : L1;
428 LHS.merge(RHS);
429 EXPECT_TRUE(RHS.empty());
430 EXPECT_FALSE(LHS.empty());
431 EXPECT_TRUE(std::is_sorted(LHS.begin(), LHS.end()));
432 auto I = LHS.begin();
433 for (Node &N : Ns)
434 EXPECT_EQ(&N, &*I++);
435 EXPECT_EQ(LHS.end(), I);
436 }
437 }
438
439 TEST(SimpleIListTest, mergeIsStable) {
440 simple_ilist L1, L2;
441 Node Ns[5];
442
443 auto setup = [&]() {
444 EXPECT_TRUE(L1.empty());
445 EXPECT_TRUE(L2.empty());
446
447 // Fill L1.
448 L1.push_back(Ns[0]);
449 L1.push_back(Ns[3]);
450 L1.push_back(Ns[4]);
451
452 // Fill L2.
453 L2.push_back(Ns[1]);
454 L2.push_back(Ns[2]);
455
456 // Check setup.
457 EXPECT_EQ(3u, L1.size());
458 EXPECT_EQ(2u, L2.size());
459 EXPECT_TRUE(std::is_sorted(L1.begin(), L1.end(), makeFalse));
460 EXPECT_TRUE(std::is_sorted(L2.begin(), L2.end(), makeFalse));
461 };
462
463 // Merge. Should be stable.
464 setup();
465 L1.merge(L2, makeFalse);
466 EXPECT_TRUE(L2.empty());
467 EXPECT_FALSE(L1.empty());
468 EXPECT_TRUE(std::is_sorted(L1.begin(), L1.end(), makeFalse));
469 auto I = L1.begin();
470 EXPECT_EQ(&Ns[0], &*I++);
471 EXPECT_EQ(&Ns[3], &*I++);
472 EXPECT_EQ(&Ns[4], &*I++);
473 EXPECT_EQ(&Ns[1], &*I++);
474 EXPECT_EQ(&Ns[2], &*I++);
475 EXPECT_EQ(L1.end(), I);
476
477 // Merge the other way. Should be stable.
478 L1.clear();
479 setup();
480 L2.merge(L1, makeFalse);
481 EXPECT_TRUE(L1.empty());
482 EXPECT_FALSE(L2.empty());
483 EXPECT_TRUE(std::is_sorted(L2.begin(), L2.end(), makeFalse));
484 I = L2.begin();
485 EXPECT_EQ(&Ns[1], &*I++);
486 EXPECT_EQ(&Ns[2], &*I++);
487 EXPECT_EQ(&Ns[0], &*I++);
488 EXPECT_EQ(&Ns[3], &*I++);
489 EXPECT_EQ(&Ns[4], &*I++);
490 EXPECT_EQ(L2.end(), I);
491 }
492
493 TEST(SimpleIListTest, mergeEmpty) {
494 for (bool IsL1LHS : {false, true}) {
495 simple_ilist L1, L2;
496 Node Ns[4];
497
498 // Fill L1.
499 L1.push_back(Ns[0]);
500 L1.push_back(Ns[1]);
501 L1.push_back(Ns[2]);
502 L1.push_back(Ns[3]);
503
504 // Check setup.
505 EXPECT_EQ(4u, L1.size());
506 EXPECT_TRUE(L2.empty());
507 EXPECT_TRUE(std::is_sorted(L1.begin(), L1.end()));
508
509 // Merge.
510 auto &LHS = IsL1LHS ? L1 : L2;
511 auto &RHS = IsL1LHS ? L2 : L1;
512 LHS.merge(RHS);
513 EXPECT_TRUE(RHS.empty());
514 EXPECT_FALSE(LHS.empty());
515 EXPECT_TRUE(std::is_sorted(LHS.begin(), LHS.end()));
516 auto I = LHS.begin();
517 for (Node &N : Ns)
518 EXPECT_EQ(&N, &*I++);
519 EXPECT_EQ(LHS.end(), I);
520 }
521 }
522
523 TEST(SimpleIListTest, mergeBothEmpty) {
524 simple_ilist L1, L2;
525 L1.merge(L2);
526 EXPECT_TRUE(L1.empty());
527 EXPECT_TRUE(L2.empty());
528 }
529
530 TEST(SimpleIListTest, sort) {
531 simple_ilist L;
532 Node Ns[10];
533
534 // Fill L.
535 for (int I : {3, 4, 0, 8, 1, 2, 6, 7, 9, 5})
536 L.push_back(Ns[I]);
537
538 // Check setup.
539 EXPECT_EQ(10u, L.size());
540 EXPECT_FALSE(std::is_sorted(L.begin(), L.end()));
541
542 // Sort.
543 L.sort();
544 EXPECT_TRUE(std::is_sorted(L.begin(), L.end()));
545 auto I = L.begin();
546 for (Node &N : Ns)
547 EXPECT_EQ(&N, &*I++);
548 EXPECT_EQ(L.end(), I);
549 }
550
551 TEST(SimpleIListTest, sortIsStable) {
552 simple_ilist L;
553 Node Ns[10];
554
555 // Compare such that nodes are partitioned but not fully sorted.
556 auto partition = [&](const Node &N) { return &N >= &Ns[5]; };
557 auto compare = [&](const Node &L, const Node &R) {
558 return partition(L) < partition(R);
559 };
560
561 // Fill L.
562 for (int I : {3, 4, 7, 8, 1, 2, 6, 0, 9, 5})
563 L.push_back(Ns[I]);
564
565 // Check setup.
566 EXPECT_EQ(10u, L.size());
567 EXPECT_FALSE(std::is_sorted(L.begin(), L.end(), compare));
568
569 // Sort.
570 L.sort(compare);
571 EXPECT_TRUE(std::is_sorted(L.begin(), L.end(), compare));
572 auto I = L.begin();
573 for (int O : {3, 4, 1, 2, 0})
574 EXPECT_EQ(&Ns[O], &*I++);
575 for (int O : {7, 8, 6, 9, 5})
576 EXPECT_EQ(&Ns[O], &*I++);
577 EXPECT_EQ(L.end(), I);
578 }
579
580 TEST(SimpleIListTest, sortEmpty) {
581 simple_ilist L;
582 L.sort();
583 }
584
585 } // end namespace
1919 LegacyPassManagerTest.cpp
2020 MDBuilderTest.cpp
2121 MetadataTest.cpp
22 ModuleTest.cpp
2223 PassManagerTest.cpp
2324 PatternMatch.cpp
2425 TypeBuilderTest.cpp
0 //===- unittests/IR/ModuleTest.cpp - Module unit tests --------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/IR/GlobalVariable.h"
10 #include "llvm/IR/Module.h"
11 #include "gtest/gtest.h"
12
13 using namespace llvm;
14
15 namespace {
16
17 bool sortByName(const GlobalVariable &L, const GlobalVariable &R) {
18 return L.getName() < R.getName();
19 }
20
21 bool sortByNameReverse(const GlobalVariable &L, const GlobalVariable &R) {
22 return sortByName(R, L);
23 }
24
25 TEST(ModuleTest, sortGlobalsByName) {
26 LLVMContext Context;
27 for (auto compare : {sortByName, sortByNameReverse}) {
28 Module M("M", Context);
29 Type *T = Type::getInt8Ty(Context);
30 GlobalValue::LinkageTypes L = GlobalValue::ExternalLinkage;
31 (void)new GlobalVariable(M, T, false, L, nullptr, "A");
32 (void)new GlobalVariable(M, T, false, L, nullptr, "F");
33 (void)new GlobalVariable(M, T, false, L, nullptr, "G");
34 (void)new GlobalVariable(M, T, false, L, nullptr, "E");
35 (void)new GlobalVariable(M, T, false, L, nullptr, "B");
36 (void)new GlobalVariable(M, T, false, L, nullptr, "H");
37 (void)new GlobalVariable(M, T, false, L, nullptr, "C");
38 (void)new GlobalVariable(M, T, false, L, nullptr, "D");
39
40 // Sort the globals by name.
41 EXPECT_FALSE(std::is_sorted(M.global_begin(), M.global_end(), compare));
42 M.getGlobalList().sort(compare);
43 EXPECT_TRUE(std::is_sorted(M.global_begin(), M.global_end(), compare));
44 }
45 }
46
47 } // end namespace