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