/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/AST/ASTVector.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- ASTVector.h - Vector that uses ASTContext for allocation ---*- C++ -*-=// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This file provides ASTVector, a vector ADT whose contents are |
10 | | // allocated using the allocator associated with an ASTContext.. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | // FIXME: Most of this is copy-and-paste from BumpVector.h and SmallVector.h. |
15 | | // We can refactor this core logic into something common. |
16 | | |
17 | | #ifndef LLVM_CLANG_AST_ASTVECTOR_H |
18 | | #define LLVM_CLANG_AST_ASTVECTOR_H |
19 | | |
20 | | #include "clang/AST/ASTContextAllocate.h" |
21 | | #include "llvm/ADT/PointerIntPair.h" |
22 | | #include <algorithm> |
23 | | #include <cassert> |
24 | | #include <cstddef> |
25 | | #include <cstring> |
26 | | #include <iterator> |
27 | | #include <memory> |
28 | | #include <type_traits> |
29 | | #include <utility> |
30 | | |
31 | | namespace clang { |
32 | | |
33 | | class ASTContext; |
34 | | |
35 | | template<typename T> |
36 | | class ASTVector { |
37 | | private: |
38 | | T *Begin = nullptr; |
39 | | T *End = nullptr; |
40 | | llvm::PointerIntPair<T *, 1, bool> Capacity; |
41 | | |
42 | 793k | void setEnd(T *P) { this->End = P; } clang::ASTVector<clang::DeclAccessPair>::setEnd(clang::DeclAccessPair*) Line | Count | Source | 42 | 127 | void setEnd(T *P) { this->End = P; } |
clang::ASTVector<clang::Stmt*>::setEnd(clang::Stmt**) Line | Count | Source | 42 | 531k | void setEnd(T *P) { this->End = P; } |
clang::ASTVector<unsigned long long>::setEnd(unsigned long long*) Line | Count | Source | 42 | 261k | void setEnd(T *P) { this->End = P; } |
|
43 | | |
44 | | protected: |
45 | | // Make a tag bit available to users of this class. |
46 | | // FIXME: This is a horrible hack. |
47 | 11.1M | bool getTag() const { return Capacity.getInt(); } |
48 | 37.2k | void setTag(bool B) { Capacity.setInt(B); } |
49 | | |
50 | | public: |
51 | | // Default ctor - Initialize to empty. |
52 | 7.45M | ASTVector() : Capacity(nullptr, false) {} clang::ASTVector<clang::DeclAccessPair>::ASTVector() Line | Count | Source | 52 | 7.05M | ASTVector() : Capacity(nullptr, false) {} |
clang::ASTVector<unsigned long long>::ASTVector() Line | Count | Source | 52 | 395k | ASTVector() : Capacity(nullptr, false) {} |
clang::ASTVector<clang::Stmt*>::ASTVector() Line | Count | Source | 52 | 5.39k | ASTVector() : Capacity(nullptr, false) {} |
|
53 | | |
54 | 14 | ASTVector(ASTVector &&O) : Begin(O.Begin), End(O.End), Capacity(O.Capacity) { |
55 | 14 | O.Begin = O.End = nullptr; |
56 | 14 | O.Capacity.setPointer(nullptr); |
57 | 14 | O.Capacity.setInt(false); |
58 | 14 | } |
59 | | |
60 | 235k | ASTVector(const ASTContext &C, unsigned N) : Capacity(nullptr, false) { |
61 | 235k | reserve(C, N); |
62 | 235k | } |
63 | | |
64 | 14 | ASTVector &operator=(ASTVector &&RHS) { |
65 | 14 | ASTVector O(std::move(RHS)); |
66 | | |
67 | 14 | using std::swap; |
68 | | |
69 | 14 | swap(Begin, O.Begin); |
70 | 14 | swap(End, O.End); |
71 | 14 | swap(Capacity, O.Capacity); |
72 | 14 | return *this; |
73 | 14 | } |
74 | | |
75 | 426k | ~ASTVector() { |
76 | 426k | if (std::is_class<T>::value) { |
77 | | // Destroy the constructed elements in the vector. |
78 | 14 | destroy_range(Begin, End); |
79 | 14 | } |
80 | 426k | } clang::ASTVector<unsigned long long>::~ASTVector() Line | Count | Source | 75 | 394k | ~ASTVector() { | 76 | 394k | if (std::is_class<T>::value) { | 77 | | // Destroy the constructed elements in the vector. | 78 | 0 | destroy_range(Begin, End); | 79 | 0 | } | 80 | 394k | } |
clang::ASTVector<clang::DeclAccessPair>::~ASTVector() Line | Count | Source | 75 | 14 | ~ASTVector() { | 76 | 14 | if (std::is_class<T>::value) { | 77 | | // Destroy the constructed elements in the vector. | 78 | 14 | destroy_range(Begin, End); | 79 | 14 | } | 80 | 14 | } |
clang::ASTVector<clang::Stmt*>::~ASTVector() Line | Count | Source | 75 | 31.7k | ~ASTVector() { | 76 | 31.7k | if (std::is_class<T>::value) { | 77 | | // Destroy the constructed elements in the vector. | 78 | 0 | destroy_range(Begin, End); | 79 | 0 | } | 80 | 31.7k | } |
|
81 | | |
82 | | using size_type = size_t; |
83 | | using difference_type = ptrdiff_t; |
84 | | using value_type = T; |
85 | | using iterator = T *; |
86 | | using const_iterator = const T *; |
87 | | |
88 | | using const_reverse_iterator = std::reverse_iterator<const_iterator>; |
89 | | using reverse_iterator = std::reverse_iterator<iterator>; |
90 | | |
91 | | using reference = T &; |
92 | | using const_reference = const T &; |
93 | | using pointer = T *; |
94 | | using const_pointer = const T *; |
95 | | |
96 | | // forward iterator creation methods. |
97 | 8.56M | iterator begin() { return Begin; } clang::ASTVector<clang::DeclAccessPair>::begin() Line | Count | Source | 97 | 7.21M | iterator begin() { return Begin; } |
clang::ASTVector<clang::Stmt*>::begin() Line | Count | Source | 97 | 1.34M | iterator begin() { return Begin; } |
|
98 | 212k | const_iterator begin() const { return Begin; } clang::ASTVector<clang::DeclAccessPair>::begin() const Line | Count | Source | 98 | 114k | const_iterator begin() const { return Begin; } |
clang::ASTVector<clang::Stmt*>::begin() const Line | Count | Source | 98 | 98.6k | const_iterator begin() const { return Begin; } |
|
99 | 10.9M | iterator end() { return End; } clang::ASTVector<clang::DeclAccessPair>::end() Line | Count | Source | 99 | 7.21M | iterator end() { return End; } |
clang::ASTVector<clang::Stmt*>::end() Line | Count | Source | 99 | 2.91M | iterator end() { return End; } |
clang::ASTVector<unsigned long long>::end() Line | Count | Source | 99 | 785k | iterator end() { return End; } |
|
100 | 212k | const_iterator end() const { return End; } clang::ASTVector<clang::DeclAccessPair>::end() const Line | Count | Source | 100 | 114k | const_iterator end() const { return End; } |
clang::ASTVector<clang::Stmt*>::end() const Line | Count | Source | 100 | 98.6k | const_iterator end() const { return End; } |
|
101 | | |
102 | | // reverse iterator creation methods. |
103 | 0 | reverse_iterator rbegin() { return reverse_iterator(end()); } |
104 | 1.10k | const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } |
105 | 0 | reverse_iterator rend() { return reverse_iterator(begin()); } |
106 | 1.10k | const_reverse_iterator rend() const { return const_reverse_iterator(begin());} |
107 | | |
108 | 250k | bool empty() const { return Begin == End; } clang::ASTVector<clang::DeclAccessPair>::empty() const Line | Count | Source | 108 | 37.0k | bool empty() const { return Begin == End; } |
clang::ASTVector<clang::Stmt*>::empty() const Line | Count | Source | 108 | 213k | bool empty() const { return Begin == End; } |
|
109 | 8.81M | size_type size() const { return End-Begin; } clang::ASTVector<clang::DeclAccessPair>::size() const Line | Count | Source | 109 | 184k | size_type size() const { return End-Begin; } |
clang::ASTVector<clang::Stmt*>::size() const Line | Count | Source | 109 | 7.89M | size_type size() const { return End-Begin; } |
clang::ASTVector<unsigned long long>::size() const Line | Count | Source | 109 | 727k | size_type size() const { return End-Begin; } |
|
110 | | |
111 | 3.22M | reference operator[](unsigned idx) { |
112 | 3.22M | assert(Begin + idx < End); |
113 | 0 | return Begin[idx]; |
114 | 3.22M | } Unexecuted instantiation: clang::ASTVector<clang::DeclAccessPair>::operator[](unsigned int) clang::ASTVector<clang::Stmt*>::operator[](unsigned int) Line | Count | Source | 111 | 3.22M | reference operator[](unsigned idx) { | 112 | 3.22M | assert(Begin + idx < End); | 113 | 0 | return Begin[idx]; | 114 | 3.22M | } |
|
115 | 2.00M | const_reference operator[](unsigned idx) const { |
116 | 2.00M | assert(Begin + idx < End); |
117 | 0 | return Begin[idx]; |
118 | 2.00M | } Unexecuted instantiation: clang::ASTVector<clang::DeclAccessPair>::operator[](unsigned int) const clang::ASTVector<clang::Stmt*>::operator[](unsigned int) const Line | Count | Source | 115 | 704k | const_reference operator[](unsigned idx) const { | 116 | 704k | assert(Begin + idx < End); | 117 | 0 | return Begin[idx]; | 118 | 704k | } |
clang::ASTVector<unsigned long long>::operator[](unsigned int) const Line | Count | Source | 115 | 1.30M | const_reference operator[](unsigned idx) const { | 116 | 1.30M | assert(Begin + idx < End); | 117 | 0 | return Begin[idx]; | 118 | 1.30M | } |
|
119 | | |
120 | | reference front() { |
121 | | return begin()[0]; |
122 | | } |
123 | | const_reference front() const { |
124 | | return begin()[0]; |
125 | | } |
126 | | |
127 | 0 | reference back() { |
128 | 0 | return end()[-1]; |
129 | 0 | } |
130 | | const_reference back() const { |
131 | | return end()[-1]; |
132 | | } |
133 | | |
134 | 0 | void pop_back() { |
135 | 0 | --End; |
136 | 0 | End->~T(); |
137 | 0 | } |
138 | | |
139 | 0 | T pop_back_val() { |
140 | 0 | T Result = back(); |
141 | 0 | pop_back(); |
142 | 0 | return Result; |
143 | 0 | } |
144 | | |
145 | 0 | void clear() { |
146 | 0 | if (std::is_class<T>::value) { |
147 | 0 | destroy_range(Begin, End); |
148 | 0 | } |
149 | 0 | End = Begin; |
150 | 0 | } |
151 | | |
152 | | /// data - Return a pointer to the vector's buffer, even if empty(). |
153 | 331k | pointer data() { |
154 | 331k | return pointer(Begin); |
155 | 331k | } |
156 | | |
157 | | /// data - Return a pointer to the vector's buffer, even if empty(). |
158 | 33 | const_pointer data() const { |
159 | 33 | return const_pointer(Begin); |
160 | 33 | } |
161 | | |
162 | 72.1k | void push_back(const_reference Elt, const ASTContext &C) { |
163 | 72.1k | if (End < this->capacity_ptr()) { |
164 | 72.1k | Retry: |
165 | 72.1k | new (End) T(Elt); |
166 | 72.1k | ++End; |
167 | 72.1k | return; |
168 | 37.0k | } |
169 | 35.0k | grow(C); |
170 | 35.0k | goto Retry; |
171 | 72.1k | } |
172 | | |
173 | 1.56M | void reserve(const ASTContext &C, unsigned N) { |
174 | 1.56M | if (unsigned(this->capacity_ptr()-Begin) < N) |
175 | 212k | grow(C, N); |
176 | 1.56M | } clang::ASTVector<clang::DeclAccessPair>::reserve(clang::ASTContext const&, unsigned int) Line | Count | Source | 173 | 1.25M | void reserve(const ASTContext &C, unsigned N) { | 174 | 1.25M | if (unsigned(this->capacity_ptr()-Begin) < N) | 175 | 35.4k | grow(C, N); | 176 | 1.25M | } |
clang::ASTVector<clang::Stmt*>::reserve(clang::ASTContext const&, unsigned int) Line | Count | Source | 173 | 317k | void reserve(const ASTContext &C, unsigned N) { | 174 | 317k | if (unsigned(this->capacity_ptr()-Begin) < N) | 175 | 176k | grow(C, N); | 176 | 317k | } |
|
177 | | |
178 | | /// capacity - Return the total number of elements in the currently allocated |
179 | | /// buffer. |
180 | 533k | size_t capacity() const { return this->capacity_ptr() - Begin; } clang::ASTVector<clang::DeclAccessPair>::capacity() const Line | Count | Source | 180 | 70.6k | size_t capacity() const { return this->capacity_ptr() - Begin; } |
clang::ASTVector<clang::Stmt*>::capacity() const Line | Count | Source | 180 | 201k | size_t capacity() const { return this->capacity_ptr() - Begin; } |
clang::ASTVector<unsigned long long>::capacity() const Line | Count | Source | 180 | 261k | size_t capacity() const { return this->capacity_ptr() - Begin; } |
|
181 | | |
182 | | /// append - Add the specified range to the end of the SmallVector. |
183 | | template<typename in_iter> |
184 | 637k | void append(const ASTContext &C, in_iter in_start, in_iter in_end) { |
185 | 637k | size_type NumInputs = std::distance(in_start, in_end); |
186 | | |
187 | 637k | if (NumInputs == 0) |
188 | 280k | return; |
189 | | |
190 | | // Grow allocated space if needed. |
191 | 357k | if (NumInputs > size_type(this->capacity_ptr()-this->end())) |
192 | 261k | this->grow(C, this->size()+NumInputs); |
193 | | |
194 | | // Copy the new elements over. |
195 | | // TODO: NEED To compile time dispatch on whether in_iter is a random access |
196 | | // iterator to use the fast uninitialized_copy. |
197 | 357k | std::uninitialized_copy(in_start, in_end, this->end()); |
198 | 357k | this->setEnd(this->end() + NumInputs); |
199 | 357k | } void clang::ASTVector<clang::DeclAccessPair>::append<clang::DeclAccessPair*>(clang::ASTContext const&, clang::DeclAccessPair*, clang::DeclAccessPair*) Line | Count | Source | 184 | 5.47k | void append(const ASTContext &C, in_iter in_start, in_iter in_end) { | 185 | 5.47k | size_type NumInputs = std::distance(in_start, in_end); | 186 | | | 187 | 5.47k | if (NumInputs == 0) | 188 | 5.35k | return; | 189 | | | 190 | | // Grow allocated space if needed. | 191 | 127 | if (NumInputs > size_type(this->capacity_ptr()-this->end())) | 192 | 127 | this->grow(C, this->size()+NumInputs); | 193 | | | 194 | | // Copy the new elements over. | 195 | | // TODO: NEED To compile time dispatch on whether in_iter is a random access | 196 | | // iterator to use the fast uninitialized_copy. | 197 | 127 | std::uninitialized_copy(in_start, in_end, this->end()); | 198 | 127 | this->setEnd(this->end() + NumInputs); | 199 | 127 | } |
void clang::ASTVector<clang::Stmt*>::append<clang::Expr* const*>(clang::ASTContext const&, clang::Expr* const*, clang::Expr* const*) Line | Count | Source | 184 | 235k | void append(const ASTContext &C, in_iter in_start, in_iter in_end) { | 185 | 235k | size_type NumInputs = std::distance(in_start, in_end); | 186 | | | 187 | 235k | if (NumInputs == 0) | 188 | 140k | return; | 189 | | | 190 | | // Grow allocated space if needed. | 191 | 95.2k | if (NumInputs > size_type(this->capacity_ptr()-this->end())) | 192 | 0 | this->grow(C, this->size()+NumInputs); | 193 | | | 194 | | // Copy the new elements over. | 195 | | // TODO: NEED To compile time dispatch on whether in_iter is a random access | 196 | | // iterator to use the fast uninitialized_copy. | 197 | 95.2k | std::uninitialized_copy(in_start, in_end, this->end()); | 198 | 95.2k | this->setEnd(this->end() + NumInputs); | 199 | 95.2k | } |
Unexecuted instantiation: void clang::ASTVector<clang::Stmt*>::append<clang::Stmt**>(clang::ASTContext const&, clang::Stmt**, clang::Stmt**) void clang::ASTVector<unsigned long long>::append<unsigned long long const*>(clang::ASTContext const&, unsigned long long const*, unsigned long long const*) Line | Count | Source | 184 | 395k | void append(const ASTContext &C, in_iter in_start, in_iter in_end) { | 185 | 395k | size_type NumInputs = std::distance(in_start, in_end); | 186 | | | 187 | 395k | if (NumInputs == 0) | 188 | 133k | return; | 189 | | | 190 | | // Grow allocated space if needed. | 191 | 261k | if (NumInputs > size_type(this->capacity_ptr()-this->end())) | 192 | 261k | this->grow(C, this->size()+NumInputs); | 193 | | | 194 | | // Copy the new elements over. | 195 | | // TODO: NEED To compile time dispatch on whether in_iter is a random access | 196 | | // iterator to use the fast uninitialized_copy. | 197 | 261k | std::uninitialized_copy(in_start, in_end, this->end()); | 198 | 261k | this->setEnd(this->end() + NumInputs); | 199 | 261k | } |
|
200 | | |
201 | | /// append - Add the specified range to the end of the SmallVector. |
202 | 430k | void append(const ASTContext &C, size_type NumInputs, const T &Elt) { |
203 | | // Grow allocated space if needed. |
204 | 430k | if (NumInputs > size_type(this->capacity_ptr()-this->end())) |
205 | 17.7k | this->grow(C, this->size()+NumInputs); |
206 | | |
207 | | // Copy the new elements over. |
208 | 430k | std::uninitialized_fill_n(this->end(), NumInputs, Elt); |
209 | 430k | this->setEnd(this->end() + NumInputs); |
210 | 430k | } |
211 | | |
212 | | /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory |
213 | | /// starting with "Dest", constructing elements into it as needed. |
214 | | template<typename It1, typename It2> |
215 | 0 | static void uninitialized_copy(It1 I, It1 E, It2 Dest) { |
216 | 0 | std::uninitialized_copy(I, E, Dest); |
217 | 0 | } Unexecuted instantiation: void clang::ASTVector<clang::Stmt*>::uninitialized_copy<clang::Stmt**, clang::Stmt**>(clang::Stmt**, clang::Stmt**, clang::Stmt**) Unexecuted instantiation: void clang::ASTVector<clang::Stmt*>::uninitialized_copy<clang::Expr* const*, clang::Stmt**>(clang::Expr* const*, clang::Expr* const*, clang::Stmt**) |
218 | | |
219 | | iterator insert(const ASTContext &C, iterator I, const T &Elt) { |
220 | | if (I == this->end()) { // Important special case for empty vector. |
221 | | push_back(Elt, C); |
222 | | return this->end()-1; |
223 | | } |
224 | | |
225 | | if (this->End < this->capacity_ptr()) { |
226 | | Retry: |
227 | | new (this->end()) T(this->back()); |
228 | | this->setEnd(this->end()+1); |
229 | | // Push everything else over. |
230 | | std::copy_backward(I, this->end()-1, this->end()); |
231 | | *I = Elt; |
232 | | return I; |
233 | | } |
234 | | size_t EltNo = I-this->begin(); |
235 | | this->grow(C); |
236 | | I = this->begin()+EltNo; |
237 | | goto Retry; |
238 | | } |
239 | | |
240 | | iterator insert(const ASTContext &C, iterator I, size_type NumToInsert, |
241 | 430k | const T &Elt) { |
242 | | // Convert iterator to elt# to avoid invalidating iterator when we reserve() |
243 | 430k | size_t InsertElt = I - this->begin(); |
244 | | |
245 | 430k | if (I == this->end()) { // Important special case for empty vector. |
246 | 430k | append(C, NumToInsert, Elt); |
247 | 430k | return this->begin() + InsertElt; |
248 | 430k | } |
249 | | |
250 | | // Ensure there is enough space. |
251 | 0 | reserve(C, static_cast<unsigned>(this->size() + NumToInsert)); |
252 | | |
253 | | // Uninvalidate the iterator. |
254 | 0 | I = this->begin()+InsertElt; |
255 | | |
256 | | // If there are more elements between the insertion point and the end of the |
257 | | // range than there are being inserted, we can use a simple approach to |
258 | | // insertion. Since we already reserved space, we know that this won't |
259 | | // reallocate the vector. |
260 | 0 | if (size_t(this->end()-I) >= NumToInsert) { |
261 | 0 | T *OldEnd = this->end(); |
262 | 0 | append(C, this->end()-NumToInsert, this->end()); |
263 | | |
264 | | // Copy the existing elements that get replaced. |
265 | 0 | std::copy_backward(I, OldEnd-NumToInsert, OldEnd); |
266 | |
|
267 | 0 | std::fill_n(I, NumToInsert, Elt); |
268 | 0 | return I; |
269 | 0 | } |
270 | | |
271 | | // Otherwise, we're inserting more elements than exist already, and we're |
272 | | // not inserting at the end. |
273 | | |
274 | | // Copy over the elements that we're about to overwrite. |
275 | 0 | T *OldEnd = this->end(); |
276 | 0 | this->setEnd(this->end() + NumToInsert); |
277 | 0 | size_t NumOverwritten = OldEnd-I; |
278 | 0 | this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten); |
279 | | |
280 | | // Replace the overwritten part. |
281 | 0 | std::fill_n(I, NumOverwritten, Elt); |
282 | | |
283 | | // Insert the non-overwritten middle part. |
284 | 0 | std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt); |
285 | 0 | return I; |
286 | 0 | } |
287 | | |
288 | | template<typename ItTy> |
289 | 235k | iterator insert(const ASTContext &C, iterator I, ItTy From, ItTy To) { |
290 | | // Convert iterator to elt# to avoid invalidating iterator when we reserve() |
291 | 235k | size_t InsertElt = I - this->begin(); |
292 | | |
293 | 235k | if (I == this->end()) { // Important special case for empty vector. |
294 | 235k | append(C, From, To); |
295 | 235k | return this->begin() + InsertElt; |
296 | 235k | } |
297 | | |
298 | 0 | size_t NumToInsert = std::distance(From, To); |
299 | | |
300 | | // Ensure there is enough space. |
301 | 0 | reserve(C, static_cast<unsigned>(this->size() + NumToInsert)); |
302 | | |
303 | | // Uninvalidate the iterator. |
304 | 0 | I = this->begin()+InsertElt; |
305 | | |
306 | | // If there are more elements between the insertion point and the end of the |
307 | | // range than there are being inserted, we can use a simple approach to |
308 | | // insertion. Since we already reserved space, we know that this won't |
309 | | // reallocate the vector. |
310 | 0 | if (size_t(this->end()-I) >= NumToInsert) { |
311 | 0 | T *OldEnd = this->end(); |
312 | 0 | append(C, this->end()-NumToInsert, this->end()); |
313 | | |
314 | | // Copy the existing elements that get replaced. |
315 | 0 | std::copy_backward(I, OldEnd-NumToInsert, OldEnd); |
316 | |
|
317 | 0 | std::copy(From, To, I); |
318 | 0 | return I; |
319 | 0 | } |
320 | | |
321 | | // Otherwise, we're inserting more elements than exist already, and we're |
322 | | // not inserting at the end. |
323 | | |
324 | | // Copy over the elements that we're about to overwrite. |
325 | 0 | T *OldEnd = this->end(); |
326 | 0 | this->setEnd(this->end() + NumToInsert); |
327 | 0 | size_t NumOverwritten = OldEnd-I; |
328 | 0 | this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten); |
329 | | |
330 | | // Replace the overwritten part. |
331 | 0 | for (; NumOverwritten > 0; --NumOverwritten) { |
332 | 0 | *I = *From; |
333 | 0 | ++I; ++From; |
334 | 0 | } |
335 | | |
336 | | // Insert the non-overwritten middle part. |
337 | 0 | this->uninitialized_copy(From, To, OldEnd); |
338 | 0 | return I; |
339 | 0 | } |
340 | | |
341 | 6.36k | void resize(const ASTContext &C, unsigned N, const T &NV) { |
342 | 6.36k | if (N < this->size()) { |
343 | 81 | this->destroy_range(this->begin()+N, this->end()); |
344 | 81 | this->setEnd(this->begin()+N); |
345 | 6.28k | } else if (N > this->size()) { |
346 | 6.25k | if (this->capacity() < N) |
347 | 556 | this->grow(C, N); |
348 | 6.25k | construct_range(this->end(), this->begin()+N, NV); |
349 | 6.25k | this->setEnd(this->begin()+N); |
350 | 6.25k | } |
351 | 6.36k | } |
352 | | |
353 | | private: |
354 | | /// grow - double the size of the allocated memory, guaranteeing space for at |
355 | | /// least one more element or MinSize if specified. |
356 | | void grow(const ASTContext &C, size_type MinSize = 1); |
357 | | |
358 | 6.25k | void construct_range(T *S, T *E, const T &Elt) { |
359 | 26.4k | for (; S != E; ++S20.1k ) |
360 | 20.1k | new (S) T(Elt); |
361 | 6.25k | } |
362 | | |
363 | 4.03k | void destroy_range(T *S, T *E) { |
364 | 8.20k | while (S != E) { |
365 | 4.16k | --E; |
366 | 4.16k | E->~T(); |
367 | 4.16k | } |
368 | 4.03k | } clang::ASTVector<clang::DeclAccessPair>::destroy_range(clang::DeclAccessPair*, clang::DeclAccessPair*) Line | Count | Source | 363 | 3.95k | void destroy_range(T *S, T *E) { | 364 | 8.04k | while (S != E) { | 365 | 4.08k | --E; | 366 | 4.08k | E->~T(); | 367 | 4.08k | } | 368 | 3.95k | } |
clang::ASTVector<clang::Stmt*>::destroy_range(clang::Stmt**, clang::Stmt**) Line | Count | Source | 363 | 81 | void destroy_range(T *S, T *E) { | 364 | 162 | while (S != E) { | 365 | 81 | --E; | 366 | 81 | E->~T(); | 367 | 81 | } | 368 | 81 | } |
Unexecuted instantiation: clang::ASTVector<unsigned long long>::destroy_range(unsigned long long*, unsigned long long*) |
369 | | |
370 | | protected: |
371 | 533k | const_iterator capacity_ptr() const { |
372 | 533k | return (iterator) Capacity.getPointer(); |
373 | 533k | } clang::ASTVector<clang::DeclAccessPair>::capacity_ptr() const Line | Count | Source | 371 | 70.6k | const_iterator capacity_ptr() const { | 372 | 70.6k | return (iterator) Capacity.getPointer(); | 373 | 70.6k | } |
clang::ASTVector<clang::Stmt*>::capacity_ptr() const Line | Count | Source | 371 | 201k | const_iterator capacity_ptr() const { | 372 | 201k | return (iterator) Capacity.getPointer(); | 373 | 201k | } |
clang::ASTVector<unsigned long long>::capacity_ptr() const Line | Count | Source | 371 | 261k | const_iterator capacity_ptr() const { | 372 | 261k | return (iterator) Capacity.getPointer(); | 373 | 261k | } |
|
374 | | |
375 | 2.42M | iterator capacity_ptr() { return (iterator)Capacity.getPointer(); } clang::ASTVector<clang::DeclAccessPair>::capacity_ptr() Line | Count | Source | 375 | 1.32M | iterator capacity_ptr() { return (iterator)Capacity.getPointer(); } |
clang::ASTVector<clang::Stmt*>::capacity_ptr() Line | Count | Source | 375 | 842k | iterator capacity_ptr() { return (iterator)Capacity.getPointer(); } |
clang::ASTVector<unsigned long long>::capacity_ptr() Line | Count | Source | 375 | 261k | iterator capacity_ptr() { return (iterator)Capacity.getPointer(); } |
|
376 | | }; |
377 | | |
378 | | // Define this out-of-line to dissuade the C++ compiler from inlining it. |
379 | | template <typename T> |
380 | 527k | void ASTVector<T>::grow(const ASTContext &C, size_t MinSize) { |
381 | 527k | size_t CurCapacity = this->capacity(); |
382 | 527k | size_t CurSize = size(); |
383 | 527k | size_t NewCapacity = 2*CurCapacity; |
384 | 527k | if (NewCapacity < MinSize) |
385 | 517k | NewCapacity = MinSize; |
386 | | |
387 | | // Allocate the memory from the ASTContext. |
388 | 527k | T *NewElts = new (C, alignof(T)) T[NewCapacity]; |
389 | | |
390 | | // Copy the elements over. |
391 | 527k | if (Begin != End) { |
392 | 10.3k | if (std::is_class<T>::value) { |
393 | 3.94k | std::uninitialized_copy(Begin, End, NewElts); |
394 | | // Destroy the original elements. |
395 | 3.94k | destroy_range(Begin, End); |
396 | 6.38k | } else { |
397 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). |
398 | 6.38k | memcpy(NewElts, Begin, CurSize * sizeof(T)); |
399 | 6.38k | } |
400 | 10.3k | } |
401 | | |
402 | | // ASTContext never frees any memory. |
403 | 527k | Begin = NewElts; |
404 | 527k | End = NewElts+CurSize; |
405 | 527k | Capacity.setPointer(Begin+NewCapacity); |
406 | 527k | } clang::ASTVector<clang::DeclAccessPair>::grow(clang::ASTContext const&, unsigned long) Line | Count | Source | 380 | 70.6k | void ASTVector<T>::grow(const ASTContext &C, size_t MinSize) { | 381 | 70.6k | size_t CurCapacity = this->capacity(); | 382 | 70.6k | size_t CurSize = size(); | 383 | 70.6k | size_t NewCapacity = 2*CurCapacity; | 384 | 70.6k | if (NewCapacity < MinSize) | 385 | 66.6k | NewCapacity = MinSize; | 386 | | | 387 | | // Allocate the memory from the ASTContext. | 388 | 70.6k | T *NewElts = new (C, alignof(T)) T[NewCapacity]; | 389 | | | 390 | | // Copy the elements over. | 391 | 70.6k | if (Begin != End) { | 392 | 3.94k | if (std::is_class<T>::value) { | 393 | 3.94k | std::uninitialized_copy(Begin, End, NewElts); | 394 | | // Destroy the original elements. | 395 | 3.94k | destroy_range(Begin, End); | 396 | 3.94k | } else { | 397 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 398 | 0 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 399 | 0 | } | 400 | 3.94k | } | 401 | | | 402 | | // ASTContext never frees any memory. | 403 | 70.6k | Begin = NewElts; | 404 | 70.6k | End = NewElts+CurSize; | 405 | 70.6k | Capacity.setPointer(Begin+NewCapacity); | 406 | 70.6k | } |
clang::ASTVector<clang::Stmt*>::grow(clang::ASTContext const&, unsigned long) Line | Count | Source | 380 | 194k | void ASTVector<T>::grow(const ASTContext &C, size_t MinSize) { | 381 | 194k | size_t CurCapacity = this->capacity(); | 382 | 194k | size_t CurSize = size(); | 383 | 194k | size_t NewCapacity = 2*CurCapacity; | 384 | 194k | if (NewCapacity < MinSize) | 385 | 188k | NewCapacity = MinSize; | 386 | | | 387 | | // Allocate the memory from the ASTContext. | 388 | 194k | T *NewElts = new (C, alignof(T)) T[NewCapacity]; | 389 | | | 390 | | // Copy the elements over. | 391 | 194k | if (Begin != End) { | 392 | 6.38k | if (std::is_class<T>::value) { | 393 | 0 | std::uninitialized_copy(Begin, End, NewElts); | 394 | | // Destroy the original elements. | 395 | 0 | destroy_range(Begin, End); | 396 | 6.38k | } else { | 397 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 398 | 6.38k | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 399 | 6.38k | } | 400 | 6.38k | } | 401 | | | 402 | | // ASTContext never frees any memory. | 403 | 194k | Begin = NewElts; | 404 | 194k | End = NewElts+CurSize; | 405 | 194k | Capacity.setPointer(Begin+NewCapacity); | 406 | 194k | } |
clang::ASTVector<unsigned long long>::grow(clang::ASTContext const&, unsigned long) Line | Count | Source | 380 | 261k | void ASTVector<T>::grow(const ASTContext &C, size_t MinSize) { | 381 | 261k | size_t CurCapacity = this->capacity(); | 382 | 261k | size_t CurSize = size(); | 383 | 261k | size_t NewCapacity = 2*CurCapacity; | 384 | 261k | if (NewCapacity < MinSize) | 385 | 261k | NewCapacity = MinSize; | 386 | | | 387 | | // Allocate the memory from the ASTContext. | 388 | 261k | T *NewElts = new (C, alignof(T)) T[NewCapacity]; | 389 | | | 390 | | // Copy the elements over. | 391 | 261k | if (Begin != End) { | 392 | 0 | if (std::is_class<T>::value) { | 393 | 0 | std::uninitialized_copy(Begin, End, NewElts); | 394 | | // Destroy the original elements. | 395 | 0 | destroy_range(Begin, End); | 396 | 0 | } else { | 397 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 398 | 0 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 399 | 0 | } | 400 | 0 | } | 401 | | | 402 | | // ASTContext never frees any memory. | 403 | 261k | Begin = NewElts; | 404 | 261k | End = NewElts+CurSize; | 405 | 261k | Capacity.setPointer(Begin+NewCapacity); | 406 | 261k | } |
|
407 | | |
408 | | } // namespace clang |
409 | | |
410 | | #endif // LLVM_CLANG_AST_ASTVECTOR_H |