/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/include/clang/Analysis/Support/BumpVector.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- BumpVector.h - Vector-like ADT that uses bump 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 BumpVector, a vector-like ADT whose contents are |
10 | | // allocated from a BumpPtrAllocator. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | // FIXME: Most of this is copy-and-paste from SmallVector.h. We can |
15 | | // refactor this core logic into something common that is shared between |
16 | | // the two. The main thing that is different is the allocation strategy. |
17 | | |
18 | | #ifndef LLVM_CLANG_ANALYSIS_SUPPORT_BUMPVECTOR_H |
19 | | #define LLVM_CLANG_ANALYSIS_SUPPORT_BUMPVECTOR_H |
20 | | |
21 | | #include "llvm/ADT/PointerIntPair.h" |
22 | | #include "llvm/Support/Allocator.h" |
23 | | #include <cassert> |
24 | | #include <cstddef> |
25 | | #include <cstring> |
26 | | #include <iterator> |
27 | | #include <memory> |
28 | | #include <type_traits> |
29 | | |
30 | | namespace clang { |
31 | | |
32 | | class BumpVectorContext { |
33 | | llvm::PointerIntPair<llvm::BumpPtrAllocator*, 1> Alloc; |
34 | | |
35 | | public: |
36 | | /// Construct a new BumpVectorContext that creates a new BumpPtrAllocator |
37 | | /// and destroys it when the BumpVectorContext object is destroyed. |
38 | 445k | BumpVectorContext() : Alloc(new llvm::BumpPtrAllocator(), 1) {} |
39 | | |
40 | 14.3k | BumpVectorContext(BumpVectorContext &&Other) : Alloc(Other.Alloc) { |
41 | 14.3k | Other.Alloc.setInt(false); |
42 | 14.3k | Other.Alloc.setPointer(nullptr); |
43 | 14.3k | } |
44 | | |
45 | | /// Construct a new BumpVectorContext that reuses an existing |
46 | | /// BumpPtrAllocator. This BumpPtrAllocator is not destroyed when the |
47 | | /// BumpVectorContext object is destroyed. |
48 | 14.9k | BumpVectorContext(llvm::BumpPtrAllocator &A) : Alloc(&A, 0) {} |
49 | | |
50 | 460k | ~BumpVectorContext() { |
51 | 460k | if (Alloc.getInt()) |
52 | 445k | delete Alloc.getPointer(); |
53 | 460k | } |
54 | | |
55 | 15.7M | llvm::BumpPtrAllocator &getAllocator() { return *Alloc.getPointer(); } |
56 | | }; |
57 | | |
58 | | template<typename T> |
59 | | class BumpVector { |
60 | | T *Begin = nullptr; |
61 | | T *End = nullptr; |
62 | | T *Capacity = nullptr; |
63 | | |
64 | | public: |
65 | | // Default ctor - Initialize to empty. |
66 | 6.69M | explicit BumpVector(BumpVectorContext &C, unsigned N) { |
67 | 6.69M | reserve(C, N); |
68 | 6.69M | } clang::BumpVector<clang::ento::ExplodedNode*>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 37.8k | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 37.8k | reserve(C, N); | 68 | 37.8k | } |
clang::BumpVector<clang::ento::MemRegion const*>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 462 | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 462 | reserve(C, N); | 68 | 462 | } |
clang::BumpVector<clang::VarDecl const*>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 389 | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 389 | reserve(C, N); | 68 | 389 | } |
clang::BumpVector<clang::CFGElement>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 2.07M | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 2.07M | reserve(C, N); | 68 | 2.07M | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 4.15M | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 4.15M | reserve(C, N); | 68 | 4.15M | } |
clang::BumpVector<clang::CFGBlock*>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 414k | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 414k | reserve(C, N); | 68 | 414k | } |
clang::BumpVector<clang::VarDecl*>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 14.3k | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 14.3k | reserve(C, N); | 68 | 14.3k | } |
|
69 | | |
70 | 414k | ~BumpVector() { |
71 | 414k | if (std::is_class<T>::value) { |
72 | 0 | // Destroy the constructed elements in the vector. |
73 | 0 | destroy_range(Begin, End); |
74 | 0 | } |
75 | 414k | } |
76 | | |
77 | | using size_type = size_t; |
78 | | using difference_type = ptrdiff_t; |
79 | | using value_type = T; |
80 | | using iterator = T *; |
81 | | using const_iterator = const T *; |
82 | | |
83 | | using const_reverse_iterator = std::reverse_iterator<const_iterator>; |
84 | | using reverse_iterator = std::reverse_iterator<iterator>; |
85 | | |
86 | | using reference = T &; |
87 | | using const_reference = const T &; |
88 | | using pointer = T *; |
89 | | using const_pointer = const T *; |
90 | | |
91 | | // forward iterator creation methods. |
92 | 4.63M | iterator begin() { return Begin; } clang::BumpVector<clang::CFGElement>::begin() Line | Count | Source | 92 | 1.63M | iterator begin() { return Begin; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::begin() Line | Count | Source | 92 | 842k | iterator begin() { return Begin; } |
clang::BumpVector<clang::CFGBlock*>::begin() Line | Count | Source | 92 | 2.14M | iterator begin() { return Begin; } |
clang::BumpVector<clang::ento::ExplodedNode*>::begin() Line | Count | Source | 92 | 8.48k | iterator begin() { return Begin; } |
clang::BumpVector<clang::ento::MemRegion const*>::begin() Line | Count | Source | 92 | 4.52k | iterator begin() { return Begin; } |
|
93 | 5.69M | const_iterator begin() const { return Begin; } clang::BumpVector<clang::CFGElement>::begin() const Line | Count | Source | 93 | 1.21M | const_iterator begin() const { return Begin; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::begin() const Line | Count | Source | 93 | 4.38M | const_iterator begin() const { return Begin; } |
clang::BumpVector<clang::CFGBlock*>::begin() const Line | Count | Source | 93 | 91.3k | const_iterator begin() const { return Begin; } |
clang::BumpVector<clang::VarDecl const*>::begin() const Line | Count | Source | 93 | 770 | const_iterator begin() const { return Begin; } |
|
94 | 7.12M | iterator end() { return End; } clang::BumpVector<clang::CFGElement>::end() Line | Count | Source | 94 | 1.63M | iterator end() { return End; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::end() Line | Count | Source | 94 | 842k | iterator end() { return End; } |
clang::BumpVector<clang::CFGBlock*>::end() Line | Count | Source | 94 | 4.63M | iterator end() { return End; } |
clang::BumpVector<clang::ento::ExplodedNode*>::end() Line | Count | Source | 94 | 7.75k | iterator end() { return End; } |
clang::BumpVector<clang::ento::MemRegion const*>::end() Line | Count | Source | 94 | 4.50k | iterator end() { return End; } |
|
95 | 6.57M | const_iterator end() const { return End; } clang::BumpVector<clang::CFGElement>::end() const Line | Count | Source | 95 | 1.25M | const_iterator end() const { return End; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::end() const Line | Count | Source | 95 | 5.22M | const_iterator end() const { return End; } |
clang::BumpVector<clang::CFGBlock*>::end() const Line | Count | Source | 95 | 91.3k | const_iterator end() const { return End; } |
clang::BumpVector<clang::VarDecl const*>::end() const Line | Count | Source | 95 | 770 | const_iterator end() const { return End; } |
|
96 | | |
97 | | // reverse iterator creation methods. |
98 | 1.63M | reverse_iterator rbegin() { return reverse_iterator(end()); } clang::BumpVector<clang::CFGElement>::rbegin() Line | Count | Source | 98 | 1.63M | reverse_iterator rbegin() { return reverse_iterator(end()); } |
Unexecuted instantiation: clang::BumpVector<clang::CFGBlock::AdjacentBlock>::rbegin() clang::BumpVector<clang::CFGBlock*>::rbegin() Line | Count | Source | 98 | 67 | reverse_iterator rbegin() { return reverse_iterator(end()); } |
|
99 | 791k | const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } clang::BumpVector<clang::CFGElement>::rbegin() const Line | Count | Source | 99 | 790k | const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::rbegin() const Line | Count | Source | 99 | 386 | const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } |
Unexecuted instantiation: clang::BumpVector<clang::CFGBlock*>::rbegin() const |
100 | 1.63M | reverse_iterator rend() { return reverse_iterator(begin()); } clang::BumpVector<clang::CFGElement>::rend() Line | Count | Source | 100 | 1.63M | reverse_iterator rend() { return reverse_iterator(begin()); } |
Unexecuted instantiation: clang::BumpVector<clang::CFGBlock::AdjacentBlock>::rend() clang::BumpVector<clang::CFGBlock*>::rend() Line | Count | Source | 100 | 67 | reverse_iterator rend() { return reverse_iterator(begin()); } |
|
101 | 791k | const_reverse_iterator rend() const { |
102 | 791k | return const_reverse_iterator(begin()); |
103 | 791k | } clang::BumpVector<clang::CFGElement>::rend() const Line | Count | Source | 101 | 790k | const_reverse_iterator rend() const { | 102 | 790k | return const_reverse_iterator(begin()); | 103 | 790k | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::rend() const Line | Count | Source | 101 | 238 | const_reverse_iterator rend() const { | 102 | 238 | return const_reverse_iterator(begin()); | 103 | 238 | } |
Unexecuted instantiation: clang::BumpVector<clang::CFGBlock*>::rend() const |
104 | | |
105 | 496k | bool empty() const { return Begin == End; } clang::BumpVector<clang::CFGElement>::empty() const Line | Count | Source | 105 | 178k | bool empty() const { return Begin == End; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::empty() const Line | Count | Source | 105 | 317k | bool empty() const { return Begin == End; } |
|
106 | 12.3M | size_type size() const { return End-Begin; } clang::BumpVector<clang::CFGElement>::size() const Line | Count | Source | 106 | 6.69M | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::size() const Line | Count | Source | 106 | 5.02M | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::CFGBlock*>::size() const Line | Count | Source | 106 | 461k | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::ento::ExplodedNode*>::size() const Line | Count | Source | 106 | 125k | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::ento::MemRegion const*>::size() const Line | Count | Source | 106 | 462 | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::VarDecl const*>::size() const Line | Count | Source | 106 | 389 | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::VarDecl*>::size() const Line | Count | Source | 106 | 30.9k | size_type size() const { return End-Begin; } |
|
107 | | |
108 | | reference operator[](unsigned idx) { |
109 | | assert(Begin + idx < End); |
110 | | return Begin[idx]; |
111 | | } |
112 | 2.67M | const_reference operator[](unsigned idx) const { |
113 | 2.67M | assert(Begin + idx < End); |
114 | 2.67M | return Begin[idx]; |
115 | 2.67M | } clang::BumpVector<clang::CFGElement>::operator[](unsigned int) const Line | Count | Source | 112 | 2.56M | const_reference operator[](unsigned idx) const { | 113 | 2.56M | assert(Begin + idx < End); | 114 | 2.56M | return Begin[idx]; | 115 | 2.56M | } |
clang::BumpVector<clang::VarDecl*>::operator[](unsigned int) const Line | Count | Source | 112 | 105k | const_reference operator[](unsigned idx) const { | 113 | 105k | assert(Begin + idx < End); | 114 | 105k | return Begin[idx]; | 115 | 105k | } |
|
116 | | |
117 | 0 | reference front() { |
118 | 0 | return begin()[0]; |
119 | 0 | } |
120 | 57.9k | const_reference front() const { |
121 | 57.9k | return begin()[0]; |
122 | 57.9k | } |
123 | | |
124 | 2.49M | reference back() { |
125 | 2.49M | return end()[-1]; |
126 | 2.49M | } |
127 | 101k | const_reference back() const { |
128 | 101k | return end()[-1]; |
129 | 101k | } |
130 | | |
131 | | void pop_back() { |
132 | | --End; |
133 | | End->~T(); |
134 | | } |
135 | | |
136 | | T pop_back_val() { |
137 | | T Result = back(); |
138 | | pop_back(); |
139 | | return Result; |
140 | | } |
141 | | |
142 | | void clear() { |
143 | | if (std::is_class<T>::value) { |
144 | | destroy_range(Begin, End); |
145 | | } |
146 | | End = Begin; |
147 | | } |
148 | | |
149 | | /// data - Return a pointer to the vector's buffer, even if empty(). |
150 | | pointer data() { |
151 | | return pointer(Begin); |
152 | | } |
153 | | |
154 | | /// data - Return a pointer to the vector's buffer, even if empty(). |
155 | | const_pointer data() const { |
156 | | return const_pointer(Begin); |
157 | | } |
158 | | |
159 | 15.6M | void push_back(const_reference Elt, BumpVectorContext &C) { |
160 | 15.6M | if (End < Capacity) { |
161 | 15.6M | Retry: |
162 | 15.6M | new (End) T(Elt); |
163 | 15.6M | ++End; |
164 | 15.6M | return; |
165 | 2.05M | } |
166 | 2.05M | grow(C); |
167 | 2.05M | goto Retry; |
168 | 2.05M | } clang::BumpVector<clang::CFGElement>::push_back(clang::CFGElement const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 9.24M | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 9.24M | if (End < Capacity) { | 161 | 9.24M | Retry: | 162 | 9.24M | new (End) T(Elt); | 163 | 9.24M | ++End; | 164 | 9.24M | return; | 165 | 1.15M | } | 166 | 1.15M | grow(C); | 167 | 1.15M | goto Retry; | 168 | 1.15M | } |
clang::BumpVector<clang::ento::ExplodedNode*>::push_back(clang::ento::ExplodedNode* const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 79.2k | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 79.2k | if (End < Capacity) { | 161 | 79.2k | Retry: | 162 | 79.2k | new (End) T(Elt); | 163 | 79.2k | ++End; | 164 | 79.2k | return; | 165 | 221 | } | 166 | 221 | grow(C); | 167 | 221 | goto Retry; | 168 | 221 | } |
clang::BumpVector<clang::ento::MemRegion const*>::push_back(clang::ento::MemRegion const* const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 584 | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 584 | if (End < Capacity) { | 161 | 584 | Retry: | 162 | 584 | new (End) T(Elt); | 163 | 584 | ++End; | 164 | 584 | return; | 165 | 0 | } | 166 | 0 | grow(C); | 167 | 0 | goto Retry; | 168 | 0 | } |
clang::BumpVector<clang::VarDecl const*>::push_back(clang::VarDecl const* const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 321 | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 321 | if (End < Capacity) { | 161 | 321 | Retry: | 162 | 321 | new (End) T(Elt); | 163 | 321 | ++End; | 164 | 321 | return; | 165 | 0 | } | 166 | 0 | grow(C); | 167 | 0 | goto Retry; | 168 | 0 | } |
clang::BumpVector<clang::VarDecl*>::push_back(clang::VarDecl* const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 16.5k | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 16.5k | if (End < Capacity) { | 161 | 16.5k | Retry: | 162 | 16.5k | new (End) T(Elt); | 163 | 16.5k | ++End; | 164 | 16.5k | return; | 165 | 61 | } | 166 | 61 | grow(C); | 167 | 61 | goto Retry; | 168 | 61 | } |
clang::BumpVector<clang::CFGBlock*>::push_back(clang::CFGBlock* const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 2.07M | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 2.07M | if (End < Capacity) { | 161 | 2.07M | Retry: | 162 | 2.07M | new (End) T(Elt); | 163 | 2.07M | ++End; | 164 | 2.07M | return; | 165 | 46.5k | } | 166 | 46.5k | grow(C); | 167 | 46.5k | goto Retry; | 168 | 46.5k | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::push_back(clang::CFGBlock::AdjacentBlock const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 4.26M | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 4.26M | if (End < Capacity) { | 161 | 4.26M | Retry: | 162 | 4.26M | new (End) T(Elt); | 163 | 4.26M | ++End; | 164 | 4.26M | return; | 165 | 853k | } | 166 | 853k | grow(C); | 167 | 853k | goto Retry; | 168 | 853k | } |
|
169 | | |
170 | | /// insert - Insert some number of copies of element into a position. Return |
171 | | /// iterator to position after last inserted copy. |
172 | | iterator insert(iterator I, size_t Cnt, const_reference E, |
173 | 116 | BumpVectorContext &C) { |
174 | 116 | assert(I >= Begin && I <= End && "Iterator out of bounds."); |
175 | 116 | if (End + Cnt <= Capacity) { |
176 | 116 | Retry: |
177 | 116 | move_range_right(I, End, Cnt); |
178 | 116 | construct_range(I, I + Cnt, E); |
179 | 116 | End += Cnt; |
180 | 116 | return I + Cnt; |
181 | 0 | } |
182 | 0 | ptrdiff_t D = I - Begin; |
183 | 0 | grow(C, size() + Cnt); |
184 | 0 | I = Begin + D; |
185 | 0 | goto Retry; |
186 | 0 | } |
187 | | |
188 | 6.69M | void reserve(BumpVectorContext &C, unsigned N) { |
189 | 6.69M | if (unsigned(Capacity-Begin) < N) |
190 | 6.69M | grow(C, N); |
191 | 6.69M | } clang::BumpVector<clang::CFGElement>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 2.07M | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 2.07M | if (unsigned(Capacity-Begin) < N) | 190 | 2.07M | grow(C, N); | 191 | 2.07M | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 4.15M | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 4.15M | if (unsigned(Capacity-Begin) < N) | 190 | 4.15M | grow(C, N); | 191 | 4.15M | } |
clang::BumpVector<clang::CFGBlock*>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 414k | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 414k | if (unsigned(Capacity-Begin) < N) | 190 | 414k | grow(C, N); | 191 | 414k | } |
clang::BumpVector<clang::ento::ExplodedNode*>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 37.8k | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 37.8k | if (unsigned(Capacity-Begin) < N) | 190 | 37.8k | grow(C, N); | 191 | 37.8k | } |
clang::BumpVector<clang::ento::MemRegion const*>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 462 | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 462 | if (unsigned(Capacity-Begin) < N) | 190 | 462 | grow(C, N); | 191 | 462 | } |
clang::BumpVector<clang::VarDecl const*>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 389 | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 389 | if (unsigned(Capacity-Begin) < N) | 190 | 389 | grow(C, N); | 191 | 389 | } |
clang::BumpVector<clang::VarDecl*>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 14.3k | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 14.3k | if (unsigned(Capacity-Begin) < N) | 190 | 14.3k | grow(C, N); | 191 | 14.3k | } |
|
192 | | |
193 | | /// capacity - Return the total number of elements in the currently allocated |
194 | | /// buffer. |
195 | | size_t capacity() const { return Capacity - Begin; } |
196 | | |
197 | | private: |
198 | | /// grow - double the size of the allocated memory, guaranteeing space for at |
199 | | /// least one more element or MinSize if specified. |
200 | | void grow(BumpVectorContext &C, size_type MinSize = 1); |
201 | | |
202 | 116 | void construct_range(T *S, T *E, const T &Elt) { |
203 | 143 | for (; S != E; ++S27 ) |
204 | 27 | new (S) T(Elt); |
205 | 116 | } |
206 | | |
207 | 2.00M | void destroy_range(T *S, T *E) { |
208 | 11.8M | while (S != E) { |
209 | 9.86M | --E; |
210 | 9.86M | E->~T(); |
211 | 9.86M | } |
212 | 2.00M | } clang::BumpVector<clang::CFGElement>::destroy_range(clang::CFGElement*, clang::CFGElement*) Line | Count | Source | 207 | 1.15M | void destroy_range(T *S, T *E) { | 208 | 9.92M | while (S != E) { | 209 | 8.76M | --E; | 210 | 8.76M | E->~T(); | 211 | 8.76M | } | 212 | 1.15M | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::destroy_range(clang::CFGBlock::AdjacentBlock*, clang::CFGBlock::AdjacentBlock*) Line | Count | Source | 207 | 853k | void destroy_range(T *S, T *E) { | 208 | 1.94M | while (S != E) { | 209 | 1.09M | --E; | 210 | 1.09M | E->~T(); | 211 | 1.09M | } | 212 | 853k | } |
Unexecuted instantiation: clang::BumpVector<clang::CFGBlock*>::destroy_range(clang::CFGBlock**, clang::CFGBlock**) Unexecuted instantiation: clang::BumpVector<clang::ento::ExplodedNode*>::destroy_range(clang::ento::ExplodedNode**, clang::ento::ExplodedNode**) Unexecuted instantiation: clang::BumpVector<clang::ento::MemRegion const*>::destroy_range(clang::ento::MemRegion const**, clang::ento::MemRegion const**) Unexecuted instantiation: clang::BumpVector<clang::VarDecl const*>::destroy_range(clang::VarDecl const**, clang::VarDecl const**) Unexecuted instantiation: clang::BumpVector<clang::VarDecl*>::destroy_range(clang::VarDecl**, clang::VarDecl**) |
213 | | |
214 | 116 | void move_range_right(T *S, T *E, size_t D) { |
215 | 369 | for (T *I = E + D - 1, *IL = S + D - 1; I != IL; --I253 ) { |
216 | 253 | --E; |
217 | 253 | new (I) T(*E); |
218 | 253 | E->~T(); |
219 | 253 | } |
220 | 116 | } |
221 | | }; |
222 | | |
223 | | // Define this out-of-line to dissuade the C++ compiler from inlining it. |
224 | | template <typename T> |
225 | 8.75M | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { |
226 | 8.75M | size_t CurCapacity = Capacity-Begin; |
227 | 8.75M | size_t CurSize = size(); |
228 | 8.75M | size_t NewCapacity = 2*CurCapacity; |
229 | 8.75M | if (NewCapacity < MinSize) |
230 | 6.69M | NewCapacity = MinSize; |
231 | 8.75M | |
232 | 8.75M | // Allocate the memory from the BumpPtrAllocator. |
233 | 8.75M | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); |
234 | 8.75M | |
235 | 8.75M | // Copy the elements over. |
236 | 8.75M | if (Begin != End) { |
237 | 2.05M | if (std::is_class<T>::value) { |
238 | 2.00M | std::uninitialized_copy(Begin, End, NewElts); |
239 | 2.00M | // Destroy the original elements. |
240 | 2.00M | destroy_range(Begin, End); |
241 | 2.00M | } else { |
242 | 46.7k | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). |
243 | 46.7k | memcpy(NewElts, Begin, CurSize * sizeof(T)); |
244 | 46.7k | } |
245 | 2.05M | } |
246 | 8.75M | |
247 | 8.75M | // For now, leak 'Begin'. We can add it back to a freelist in |
248 | 8.75M | // BumpVectorContext. |
249 | 8.75M | Begin = NewElts; |
250 | 8.75M | End = NewElts+CurSize; |
251 | 8.75M | Capacity = Begin+NewCapacity; |
252 | 8.75M | } clang::BumpVector<clang::CFGElement>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 3.23M | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 3.23M | size_t CurCapacity = Capacity-Begin; | 227 | 3.23M | size_t CurSize = size(); | 228 | 3.23M | size_t NewCapacity = 2*CurCapacity; | 229 | 3.23M | if (NewCapacity < MinSize) | 230 | 2.07M | NewCapacity = MinSize; | 231 | 3.23M | | 232 | 3.23M | // Allocate the memory from the BumpPtrAllocator. | 233 | 3.23M | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | 3.23M | | 235 | 3.23M | // Copy the elements over. | 236 | 3.23M | if (Begin != End) { | 237 | 1.15M | if (std::is_class<T>::value) { | 238 | 1.15M | std::uninitialized_copy(Begin, End, NewElts); | 239 | 1.15M | // Destroy the original elements. | 240 | 1.15M | destroy_range(Begin, End); | 241 | 1.15M | } else { | 242 | 0 | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 0 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 0 | } | 245 | 1.15M | } | 246 | 3.23M | | 247 | 3.23M | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | 3.23M | // BumpVectorContext. | 249 | 3.23M | Begin = NewElts; | 250 | 3.23M | End = NewElts+CurSize; | 251 | 3.23M | Capacity = Begin+NewCapacity; | 252 | 3.23M | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 5.00M | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 5.00M | size_t CurCapacity = Capacity-Begin; | 227 | 5.00M | size_t CurSize = size(); | 228 | 5.00M | size_t NewCapacity = 2*CurCapacity; | 229 | 5.00M | if (NewCapacity < MinSize) | 230 | 4.15M | NewCapacity = MinSize; | 231 | 5.00M | | 232 | 5.00M | // Allocate the memory from the BumpPtrAllocator. | 233 | 5.00M | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | 5.00M | | 235 | 5.00M | // Copy the elements over. | 236 | 5.00M | if (Begin != End) { | 237 | 853k | if (std::is_class<T>::value) { | 238 | 853k | std::uninitialized_copy(Begin, End, NewElts); | 239 | 853k | // Destroy the original elements. | 240 | 853k | destroy_range(Begin, End); | 241 | 853k | } else { | 242 | 0 | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 0 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 0 | } | 245 | 853k | } | 246 | 5.00M | | 247 | 5.00M | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | 5.00M | // BumpVectorContext. | 249 | 5.00M | Begin = NewElts; | 250 | 5.00M | End = NewElts+CurSize; | 251 | 5.00M | Capacity = Begin+NewCapacity; | 252 | 5.00M | } |
clang::BumpVector<clang::CFGBlock*>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 461k | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 461k | size_t CurCapacity = Capacity-Begin; | 227 | 461k | size_t CurSize = size(); | 228 | 461k | size_t NewCapacity = 2*CurCapacity; | 229 | 461k | if (NewCapacity < MinSize) | 230 | 414k | NewCapacity = MinSize; | 231 | 461k | | 232 | 461k | // Allocate the memory from the BumpPtrAllocator. | 233 | 461k | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | 461k | | 235 | 461k | // Copy the elements over. | 236 | 461k | if (Begin != End) { | 237 | 46.5k | if (std::is_class<T>::value) { | 238 | 0 | std::uninitialized_copy(Begin, End, NewElts); | 239 | 0 | // Destroy the original elements. | 240 | 0 | destroy_range(Begin, End); | 241 | 46.5k | } else { | 242 | 46.5k | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 46.5k | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 46.5k | } | 245 | 46.5k | } | 246 | 461k | | 247 | 461k | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | 461k | // BumpVectorContext. | 249 | 461k | Begin = NewElts; | 250 | 461k | End = NewElts+CurSize; | 251 | 461k | Capacity = Begin+NewCapacity; | 252 | 461k | } |
clang::BumpVector<clang::ento::ExplodedNode*>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 38.0k | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 38.0k | size_t CurCapacity = Capacity-Begin; | 227 | 38.0k | size_t CurSize = size(); | 228 | 38.0k | size_t NewCapacity = 2*CurCapacity; | 229 | 38.0k | if (NewCapacity < MinSize) | 230 | 37.8k | NewCapacity = MinSize; | 231 | 38.0k | | 232 | 38.0k | // Allocate the memory from the BumpPtrAllocator. | 233 | 38.0k | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | 38.0k | | 235 | 38.0k | // Copy the elements over. | 236 | 38.0k | if (Begin != End) { | 237 | 221 | if (std::is_class<T>::value) { | 238 | 0 | std::uninitialized_copy(Begin, End, NewElts); | 239 | 0 | // Destroy the original elements. | 240 | 0 | destroy_range(Begin, End); | 241 | 221 | } else { | 242 | 221 | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 221 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 221 | } | 245 | 221 | } | 246 | 38.0k | | 247 | 38.0k | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | 38.0k | // BumpVectorContext. | 249 | 38.0k | Begin = NewElts; | 250 | 38.0k | End = NewElts+CurSize; | 251 | 38.0k | Capacity = Begin+NewCapacity; | 252 | 38.0k | } |
clang::BumpVector<clang::ento::MemRegion const*>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 462 | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 462 | size_t CurCapacity = Capacity-Begin; | 227 | 462 | size_t CurSize = size(); | 228 | 462 | size_t NewCapacity = 2*CurCapacity; | 229 | 462 | if (NewCapacity < MinSize) | 230 | 462 | NewCapacity = MinSize; | 231 | 462 | | 232 | 462 | // Allocate the memory from the BumpPtrAllocator. | 233 | 462 | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | 462 | | 235 | 462 | // Copy the elements over. | 236 | 462 | if (Begin != End) { | 237 | 0 | if (std::is_class<T>::value) { | 238 | 0 | std::uninitialized_copy(Begin, End, NewElts); | 239 | 0 | // Destroy the original elements. | 240 | 0 | destroy_range(Begin, End); | 241 | 0 | } else { | 242 | 0 | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 0 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 0 | } | 245 | 0 | } | 246 | 462 | | 247 | 462 | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | 462 | // BumpVectorContext. | 249 | 462 | Begin = NewElts; | 250 | 462 | End = NewElts+CurSize; | 251 | 462 | Capacity = Begin+NewCapacity; | 252 | 462 | } |
clang::BumpVector<clang::VarDecl const*>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 389 | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 389 | size_t CurCapacity = Capacity-Begin; | 227 | 389 | size_t CurSize = size(); | 228 | 389 | size_t NewCapacity = 2*CurCapacity; | 229 | 389 | if (NewCapacity < MinSize) | 230 | 389 | NewCapacity = MinSize; | 231 | 389 | | 232 | 389 | // Allocate the memory from the BumpPtrAllocator. | 233 | 389 | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | 389 | | 235 | 389 | // Copy the elements over. | 236 | 389 | if (Begin != End) { | 237 | 0 | if (std::is_class<T>::value) { | 238 | 0 | std::uninitialized_copy(Begin, End, NewElts); | 239 | 0 | // Destroy the original elements. | 240 | 0 | destroy_range(Begin, End); | 241 | 0 | } else { | 242 | 0 | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 0 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 0 | } | 245 | 0 | } | 246 | 389 | | 247 | 389 | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | 389 | // BumpVectorContext. | 249 | 389 | Begin = NewElts; | 250 | 389 | End = NewElts+CurSize; | 251 | 389 | Capacity = Begin+NewCapacity; | 252 | 389 | } |
clang::BumpVector<clang::VarDecl*>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 14.4k | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 14.4k | size_t CurCapacity = Capacity-Begin; | 227 | 14.4k | size_t CurSize = size(); | 228 | 14.4k | size_t NewCapacity = 2*CurCapacity; | 229 | 14.4k | if (NewCapacity < MinSize) | 230 | 14.3k | NewCapacity = MinSize; | 231 | 14.4k | | 232 | 14.4k | // Allocate the memory from the BumpPtrAllocator. | 233 | 14.4k | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | 14.4k | | 235 | 14.4k | // Copy the elements over. | 236 | 14.4k | if (Begin != End) { | 237 | 61 | if (std::is_class<T>::value) { | 238 | 0 | std::uninitialized_copy(Begin, End, NewElts); | 239 | 0 | // Destroy the original elements. | 240 | 0 | destroy_range(Begin, End); | 241 | 61 | } else { | 242 | 61 | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 61 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 61 | } | 245 | 61 | } | 246 | 14.4k | | 247 | 14.4k | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | 14.4k | // BumpVectorContext. | 249 | 14.4k | Begin = NewElts; | 250 | 14.4k | End = NewElts+CurSize; | 251 | 14.4k | Capacity = Begin+NewCapacity; | 252 | 14.4k | } |
|
253 | | |
254 | | } // namespace clang |
255 | | |
256 | | #endif // LLVM_CLANG_ANALYSIS_SUPPORT_BUMPVECTOR_H |