/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Support/NativeFormatting.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- NativeFormatting.cpp - Low level formatting helpers -------*- 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 | | #include "llvm/Support/NativeFormatting.h" |
11 | | |
12 | | #include "llvm/ADT/ArrayRef.h" |
13 | | #include "llvm/ADT/SmallString.h" |
14 | | #include "llvm/ADT/StringExtras.h" |
15 | | #include "llvm/Support/Format.h" |
16 | | |
17 | | using namespace llvm; |
18 | | |
19 | | template<typename T, std::size_t N> |
20 | 52.4M | static int format_to_buffer(T Value, char (&Buffer)[N]) { |
21 | 52.4M | char *EndPtr = std::end(Buffer); |
22 | 52.4M | char *CurPtr = EndPtr; |
23 | 52.4M | |
24 | 108M | do { |
25 | 108M | *--CurPtr = '0' + char(Value % 10); |
26 | 108M | Value /= 10; |
27 | 108M | } while (Value); |
28 | 52.4M | return EndPtr - CurPtr; |
29 | 52.4M | } NativeFormatting.cpp:int format_to_buffer<unsigned int, 128ul>(unsigned int, char (&) [128ul]) Line | Count | Source | 20 | 52.3M | static int format_to_buffer(T Value, char (&Buffer)[N]) { | 21 | 52.3M | char *EndPtr = std::end(Buffer); | 22 | 52.3M | char *CurPtr = EndPtr; | 23 | 52.3M | | 24 | 108M | do { | 25 | 108M | *--CurPtr = '0' + char(Value % 10); | 26 | 108M | Value /= 10; | 27 | 108M | } while (Value); | 28 | 52.3M | return EndPtr - CurPtr; | 29 | 52.3M | } |
Unexecuted instantiation: NativeFormatting.cpp:int format_to_buffer<unsigned long, 128ul>(unsigned long, char (&) [128ul]) NativeFormatting.cpp:int format_to_buffer<unsigned long long, 128ul>(unsigned long long, char (&) [128ul]) Line | Count | Source | 20 | 20.7k | static int format_to_buffer(T Value, char (&Buffer)[N]) { | 21 | 20.7k | char *EndPtr = std::end(Buffer); | 22 | 20.7k | char *CurPtr = EndPtr; | 23 | 20.7k | | 24 | 395k | do { | 25 | 395k | *--CurPtr = '0' + char(Value % 10); | 26 | 395k | Value /= 10; | 27 | 395k | } while (Value); | 28 | 20.7k | return EndPtr - CurPtr; | 29 | 20.7k | } |
|
30 | | |
31 | 82 | static void writeWithCommas(raw_ostream &S, ArrayRef<char> Buffer) { |
32 | 82 | assert(!Buffer.empty()); |
33 | 82 | |
34 | 82 | ArrayRef<char> ThisGroup; |
35 | 82 | int InitialDigits = ((Buffer.size() - 1) % 3) + 1; |
36 | 82 | ThisGroup = Buffer.take_front(InitialDigits); |
37 | 82 | S.write(ThisGroup.data(), ThisGroup.size()); |
38 | 82 | |
39 | 82 | Buffer = Buffer.drop_front(InitialDigits); |
40 | 82 | assert(Buffer.size() % 3 == 0); |
41 | 125 | while (!Buffer.empty()125 ) { |
42 | 43 | S << ','; |
43 | 43 | ThisGroup = Buffer.take_front(3); |
44 | 43 | S.write(ThisGroup.data(), 3); |
45 | 43 | Buffer = Buffer.drop_front(3); |
46 | 43 | } |
47 | 82 | } |
48 | | |
49 | | template <typename T> |
50 | | static void write_unsigned_impl(raw_ostream &S, T N, size_t MinDigits, |
51 | 52.4M | IntegerStyle Style, bool IsNegative) { |
52 | 52.4M | static_assert(std::is_unsigned<T>::value, "Value is not unsigned!"); |
53 | 52.4M | |
54 | 52.4M | char NumberBuffer[128]; |
55 | 52.4M | std::memset(NumberBuffer, '0', sizeof(NumberBuffer)); |
56 | 52.4M | |
57 | 52.4M | size_t Len = 0; |
58 | 52.4M | Len = format_to_buffer(N, NumberBuffer); |
59 | 52.4M | |
60 | 52.4M | if (IsNegative) |
61 | 416k | S << '-'; |
62 | 52.4M | |
63 | 52.4M | if (Len < MinDigits && 52.4M Style != IntegerStyle::Number439 ) { |
64 | 1.57k | for (size_t I = Len; I < MinDigits1.57k ; ++I1.13k ) |
65 | 1.13k | S << '0'; |
66 | 439 | } |
67 | 52.4M | |
68 | 52.4M | if (Style == IntegerStyle::Number52.4M ) { |
69 | 82 | writeWithCommas(S, ArrayRef<char>(std::end(NumberBuffer) - Len, Len)); |
70 | 52.4M | } else { |
71 | 52.4M | S.write(std::end(NumberBuffer) - Len, Len); |
72 | 52.4M | } |
73 | 52.4M | } NativeFormatting.cpp:void write_unsigned_impl<unsigned int>(llvm::raw_ostream&, unsigned int, unsigned long, llvm::IntegerStyle, bool) Line | Count | Source | 51 | 52.3M | IntegerStyle Style, bool IsNegative) { | 52 | 52.3M | static_assert(std::is_unsigned<T>::value, "Value is not unsigned!"); | 53 | 52.3M | | 54 | 52.3M | char NumberBuffer[128]; | 55 | 52.3M | std::memset(NumberBuffer, '0', sizeof(NumberBuffer)); | 56 | 52.3M | | 57 | 52.3M | size_t Len = 0; | 58 | 52.3M | Len = format_to_buffer(N, NumberBuffer); | 59 | 52.3M | | 60 | 52.3M | if (IsNegative) | 61 | 415k | S << '-'; | 62 | 52.3M | | 63 | 52.3M | if (Len < MinDigits && 52.3M Style != IntegerStyle::Number439 ) { | 64 | 1.57k | for (size_t I = Len; I < MinDigits1.57k ; ++I1.13k ) | 65 | 1.13k | S << '0'; | 66 | 439 | } | 67 | 52.3M | | 68 | 52.3M | if (Style == IntegerStyle::Number52.3M ) { | 69 | 78 | writeWithCommas(S, ArrayRef<char>(std::end(NumberBuffer) - Len, Len)); | 70 | 52.3M | } else { | 71 | 52.3M | S.write(std::end(NumberBuffer) - Len, Len); | 72 | 52.3M | } | 73 | 52.3M | } |
Unexecuted instantiation: NativeFormatting.cpp:void write_unsigned_impl<unsigned long>(llvm::raw_ostream&, unsigned long, unsigned long, llvm::IntegerStyle, bool) NativeFormatting.cpp:void write_unsigned_impl<unsigned long long>(llvm::raw_ostream&, unsigned long long, unsigned long, llvm::IntegerStyle, bool) Line | Count | Source | 51 | 20.7k | IntegerStyle Style, bool IsNegative) { | 52 | 20.7k | static_assert(std::is_unsigned<T>::value, "Value is not unsigned!"); | 53 | 20.7k | | 54 | 20.7k | char NumberBuffer[128]; | 55 | 20.7k | std::memset(NumberBuffer, '0', sizeof(NumberBuffer)); | 56 | 20.7k | | 57 | 20.7k | size_t Len = 0; | 58 | 20.7k | Len = format_to_buffer(N, NumberBuffer); | 59 | 20.7k | | 60 | 20.7k | if (IsNegative) | 61 | 936 | S << '-'; | 62 | 20.7k | | 63 | 20.7k | if (Len < MinDigits && 20.7k Style != IntegerStyle::Number0 ) { | 64 | 0 | for (size_t I = Len; I < MinDigits0 ; ++I0 ) | 65 | 0 | S << '0'; | 66 | 0 | } | 67 | 20.7k | | 68 | 20.7k | if (Style == IntegerStyle::Number20.7k ) { | 69 | 4 | writeWithCommas(S, ArrayRef<char>(std::end(NumberBuffer) - Len, Len)); | 70 | 20.7k | } else { | 71 | 20.7k | S.write(std::end(NumberBuffer) - Len, Len); | 72 | 20.7k | } | 73 | 20.7k | } |
|
74 | | |
75 | | template <typename T> |
76 | | static void write_unsigned(raw_ostream &S, T N, size_t MinDigits, |
77 | 52.4M | IntegerStyle Style, bool IsNegative = false) { |
78 | 52.4M | // Output using 32-bit div/mod if possible. |
79 | 52.4M | if (N == static_cast<uint32_t>(N)) |
80 | 52.3M | write_unsigned_impl(S, static_cast<uint32_t>(N), MinDigits, Style, |
81 | 52.3M | IsNegative); |
82 | 52.4M | else |
83 | 20.7k | write_unsigned_impl(S, N, MinDigits, Style, IsNegative); |
84 | 52.4M | } NativeFormatting.cpp:void write_unsigned<unsigned int>(llvm::raw_ostream&, unsigned int, unsigned long, llvm::IntegerStyle, bool) Line | Count | Source | 77 | 3.82k | IntegerStyle Style, bool IsNegative = false) { | 78 | 3.82k | // Output using 32-bit div/mod if possible. | 79 | 3.82k | if (N == static_cast<uint32_t>(N)) | 80 | 3.82k | write_unsigned_impl(S, static_cast<uint32_t>(N), MinDigits, Style, | 81 | 3.82k | IsNegative); | 82 | 3.82k | else | 83 | 0 | write_unsigned_impl(S, N, MinDigits, Style, IsNegative); | 84 | 3.82k | } |
NativeFormatting.cpp:void write_unsigned<unsigned long>(llvm::raw_ostream&, unsigned long, unsigned long, llvm::IntegerStyle, bool) Line | Count | Source | 77 | 129 | IntegerStyle Style, bool IsNegative = false) { | 78 | 129 | // Output using 32-bit div/mod if possible. | 79 | 129 | if (N == static_cast<uint32_t>(N)) | 80 | 129 | write_unsigned_impl(S, static_cast<uint32_t>(N), MinDigits, Style, | 81 | 129 | IsNegative); | 82 | 129 | else | 83 | 0 | write_unsigned_impl(S, N, MinDigits, Style, IsNegative); | 84 | 129 | } |
NativeFormatting.cpp:void write_unsigned<unsigned long long>(llvm::raw_ostream&, unsigned long long, unsigned long, llvm::IntegerStyle, bool) Line | Count | Source | 77 | 52.4M | IntegerStyle Style, bool IsNegative = false) { | 78 | 52.4M | // Output using 32-bit div/mod if possible. | 79 | 52.4M | if (N == static_cast<uint32_t>(N)) | 80 | 52.3M | write_unsigned_impl(S, static_cast<uint32_t>(N), MinDigits, Style, | 81 | 52.3M | IsNegative); | 82 | 52.4M | else | 83 | 20.7k | write_unsigned_impl(S, N, MinDigits, Style, IsNegative); | 84 | 52.4M | } |
|
85 | | |
86 | | template <typename T> |
87 | | static void write_signed(raw_ostream &S, T N, size_t MinDigits, |
88 | 18.4M | IntegerStyle Style) { |
89 | 18.4M | static_assert(std::is_signed<T>::value, "Value is not signed!"); |
90 | 18.4M | |
91 | 18.4M | using UnsignedT = typename std::make_unsigned<T>::type; |
92 | 18.4M | |
93 | 18.4M | if (N >= 018.4M ) { |
94 | 17.9M | write_unsigned(S, static_cast<UnsignedT>(N), MinDigits, Style); |
95 | 17.9M | return; |
96 | 17.9M | } |
97 | 416k | |
98 | 416k | UnsignedT UN = -(UnsignedT)N; |
99 | 416k | write_unsigned(S, UN, MinDigits, Style, true); |
100 | 416k | } NativeFormatting.cpp:void write_signed<int>(llvm::raw_ostream&, int, unsigned long, llvm::IntegerStyle) Line | Count | Source | 88 | 1.41k | IntegerStyle Style) { | 89 | 1.41k | static_assert(std::is_signed<T>::value, "Value is not signed!"); | 90 | 1.41k | | 91 | 1.41k | using UnsignedT = typename std::make_unsigned<T>::type; | 92 | 1.41k | | 93 | 1.41k | if (N >= 01.41k ) { | 94 | 1.31k | write_unsigned(S, static_cast<UnsignedT>(N), MinDigits, Style); | 95 | 1.31k | return; | 96 | 1.31k | } | 97 | 99 | | 98 | 99 | UnsignedT UN = -(UnsignedT)N; | 99 | 99 | write_unsigned(S, UN, MinDigits, Style, true); | 100 | 99 | } |
NativeFormatting.cpp:void write_signed<long>(llvm::raw_ostream&, long, unsigned long, llvm::IntegerStyle) Line | Count | Source | 88 | 14 | IntegerStyle Style) { | 89 | 14 | static_assert(std::is_signed<T>::value, "Value is not signed!"); | 90 | 14 | | 91 | 14 | using UnsignedT = typename std::make_unsigned<T>::type; | 92 | 14 | | 93 | 14 | if (N >= 014 ) { | 94 | 14 | write_unsigned(S, static_cast<UnsignedT>(N), MinDigits, Style); | 95 | 14 | return; | 96 | 14 | } | 97 | 0 |
| 98 | 0 | UnsignedT UN = -(UnsignedT)N; | 99 | 0 | write_unsigned(S, UN, MinDigits, Style, true); | 100 | 0 | } |
NativeFormatting.cpp:void write_signed<long long>(llvm::raw_ostream&, long long, unsigned long, llvm::IntegerStyle) Line | Count | Source | 88 | 18.4M | IntegerStyle Style) { | 89 | 18.4M | static_assert(std::is_signed<T>::value, "Value is not signed!"); | 90 | 18.4M | | 91 | 18.4M | using UnsignedT = typename std::make_unsigned<T>::type; | 92 | 18.4M | | 93 | 18.4M | if (N >= 018.4M ) { | 94 | 17.9M | write_unsigned(S, static_cast<UnsignedT>(N), MinDigits, Style); | 95 | 17.9M | return; | 96 | 17.9M | } | 97 | 416k | | 98 | 416k | UnsignedT UN = -(UnsignedT)N; | 99 | 416k | write_unsigned(S, UN, MinDigits, Style, true); | 100 | 416k | } |
|
101 | | |
102 | | void llvm::write_integer(raw_ostream &S, unsigned int N, size_t MinDigits, |
103 | 2.40k | IntegerStyle Style) { |
104 | 2.40k | write_unsigned(S, N, MinDigits, Style); |
105 | 2.40k | } |
106 | | |
107 | | void llvm::write_integer(raw_ostream &S, int N, size_t MinDigits, |
108 | 1.41k | IntegerStyle Style) { |
109 | 1.41k | write_signed(S, N, MinDigits, Style); |
110 | 1.41k | } |
111 | | |
112 | | void llvm::write_integer(raw_ostream &S, unsigned long N, size_t MinDigits, |
113 | 115 | IntegerStyle Style) { |
114 | 115 | write_unsigned(S, N, MinDigits, Style); |
115 | 115 | } |
116 | | |
117 | | void llvm::write_integer(raw_ostream &S, long N, size_t MinDigits, |
118 | 14 | IntegerStyle Style) { |
119 | 14 | write_signed(S, N, MinDigits, Style); |
120 | 14 | } |
121 | | |
122 | | void llvm::write_integer(raw_ostream &S, unsigned long long N, size_t MinDigits, |
123 | 34.0M | IntegerStyle Style) { |
124 | 34.0M | write_unsigned(S, N, MinDigits, Style); |
125 | 34.0M | } |
126 | | |
127 | | void llvm::write_integer(raw_ostream &S, long long N, size_t MinDigits, |
128 | 18.4M | IntegerStyle Style) { |
129 | 18.4M | write_signed(S, N, MinDigits, Style); |
130 | 18.4M | } |
131 | | |
132 | | void llvm::write_hex(raw_ostream &S, uint64_t N, HexPrintStyle Style, |
133 | 29.6M | Optional<size_t> Width) { |
134 | 29.6M | const size_t kMaxWidth = 128u; |
135 | 29.6M | |
136 | 29.6M | size_t W = std::min(kMaxWidth, Width.getValueOr(0u)); |
137 | 29.6M | |
138 | 29.6M | unsigned Nibbles = (64 - countLeadingZeros(N) + 3) / 4; |
139 | 29.6M | bool Prefix = (Style == HexPrintStyle::PrefixLower || |
140 | 29.6M | Style == HexPrintStyle::PrefixUpper); |
141 | 29.6M | bool Upper = |
142 | 330k | (Style == HexPrintStyle::Upper || Style == HexPrintStyle::PrefixUpper); |
143 | 29.6M | unsigned PrefixChars = Prefix ? 217.3k : 029.6M ; |
144 | 29.6M | unsigned NumChars = |
145 | 29.6M | std::max(static_cast<unsigned>(W), std::max(1u, Nibbles) + PrefixChars); |
146 | 29.6M | |
147 | 29.6M | char NumberBuffer[kMaxWidth]; |
148 | 29.6M | ::memset(NumberBuffer, '0', llvm::array_lengthof(NumberBuffer)); |
149 | 29.6M | if (Prefix) |
150 | 17.3k | NumberBuffer[1] = 'x'; |
151 | 29.6M | char *EndPtr = NumberBuffer + NumChars; |
152 | 29.6M | char *CurPtr = EndPtr; |
153 | 74.6M | while (N74.6M ) { |
154 | 45.0M | unsigned char x = static_cast<unsigned char>(N) % 16; |
155 | 45.0M | *--CurPtr = hexdigit(x, !Upper); |
156 | 45.0M | N /= 16; |
157 | 45.0M | } |
158 | 29.6M | |
159 | 29.6M | S.write(NumberBuffer, NumChars); |
160 | 29.6M | } |
161 | | |
162 | | void llvm::write_double(raw_ostream &S, double N, FloatStyle Style, |
163 | 28.8k | Optional<size_t> Precision) { |
164 | 28.8k | size_t Prec = Precision.getValueOr(getDefaultPrecision(Style)); |
165 | 28.8k | |
166 | 28.8k | if (std::isnan(N)28.8k ) { |
167 | 652 | S << "nan"; |
168 | 652 | return; |
169 | 28.2k | } else if (28.2k std::isinf(N)28.2k ) { |
170 | 28 | S << "INF"; |
171 | 28 | return; |
172 | 28 | } |
173 | 28.1k | |
174 | 28.1k | char Letter; |
175 | 28.1k | if (Style == FloatStyle::Exponent) |
176 | 27.8k | Letter = 'e'; |
177 | 319 | else if (319 Style == FloatStyle::ExponentUpper319 ) |
178 | 15 | Letter = 'E'; |
179 | 319 | else |
180 | 304 | Letter = 'f'; |
181 | 28.1k | |
182 | 28.1k | SmallString<8> Spec; |
183 | 28.1k | llvm::raw_svector_ostream Out(Spec); |
184 | 28.1k | Out << "%." << Prec << Letter; |
185 | 28.1k | |
186 | 28.1k | if (Style == FloatStyle::Exponent || 28.1k Style == FloatStyle::ExponentUpper319 ) { |
187 | | #ifdef _WIN32 |
188 | | // On MSVCRT and compatible, output of %e is incompatible to Posix |
189 | | // by default. Number of exponent digits should be at least 2. "%+03d" |
190 | | // FIXME: Implement our formatter to here or Support/Format.h! |
191 | | #if defined(__MINGW32__) |
192 | | // FIXME: It should be generic to C++11. |
193 | | if (N == 0.0 && std::signbit(N)) { |
194 | | char NegativeZero[] = "-0.000000e+00"; |
195 | | if (Style == FloatStyle::ExponentUpper) |
196 | | NegativeZero[strlen(NegativeZero) - 4] = 'E'; |
197 | | S << NegativeZero; |
198 | | return; |
199 | | } |
200 | | #else |
201 | | int fpcl = _fpclass(N); |
202 | | |
203 | | // negative zero |
204 | | if (fpcl == _FPCLASS_NZ) { |
205 | | char NegativeZero[] = "-0.000000e+00"; |
206 | | if (Style == FloatStyle::ExponentUpper) |
207 | | NegativeZero[strlen(NegativeZero) - 4] = 'E'; |
208 | | S << NegativeZero; |
209 | | return; |
210 | | } |
211 | | #endif |
212 | | |
213 | | char buf[32]; |
214 | | unsigned len; |
215 | | len = format(Spec.c_str(), N).snprint(buf, sizeof(buf)); |
216 | | if (len <= sizeof(buf) - 2) { |
217 | | if (len >= 5 && (buf[len - 5] == 'e' || buf[len - 5] == 'E') && |
218 | | buf[len - 3] == '0') { |
219 | | int cs = buf[len - 4]; |
220 | | if (cs == '+' || cs == '-') { |
221 | | int c1 = buf[len - 2]; |
222 | | int c0 = buf[len - 1]; |
223 | | if (isdigit(static_cast<unsigned char>(c1)) && |
224 | | isdigit(static_cast<unsigned char>(c0))) { |
225 | | // Trim leading '0': "...e+012" -> "...e+12\0" |
226 | | buf[len - 3] = c1; |
227 | | buf[len - 2] = c0; |
228 | | buf[--len] = 0; |
229 | | } |
230 | | } |
231 | | } |
232 | | S << buf; |
233 | | return; |
234 | | } |
235 | | #endif |
236 | | } |
237 | 28.1k | |
238 | 28.1k | if (Style == FloatStyle::Percent) |
239 | 56 | N *= 100.0; |
240 | 28.1k | |
241 | 28.1k | char Buf[32]; |
242 | 28.1k | format(Spec.c_str(), N).snprint(Buf, sizeof(Buf)); |
243 | 28.1k | S << Buf; |
244 | 28.1k | if (Style == FloatStyle::Percent) |
245 | 56 | S << '%'; |
246 | 28.8k | } |
247 | | |
248 | 2.38k | bool llvm::isPrefixedHexStyle(HexPrintStyle S) { |
249 | 2.32k | return (S == HexPrintStyle::PrefixLower || S == HexPrintStyle::PrefixUpper); |
250 | 2.38k | } |
251 | | |
252 | 29.0k | size_t llvm::getDefaultPrecision(FloatStyle Style) { |
253 | 29.0k | switch (Style) { |
254 | 28.5k | case FloatStyle::Exponent: |
255 | 28.5k | case FloatStyle::ExponentUpper: |
256 | 28.5k | return 6; // Number of decimal places. |
257 | 463 | case FloatStyle::Fixed: |
258 | 463 | case FloatStyle::Percent: |
259 | 463 | return 2; // Number of decimal places. |
260 | 0 | } |
261 | 0 | LLVM_BUILTIN_UNREACHABLE0 ; |
262 | 0 | } |