Coverage Report

Created: 2019-07-24 05:18

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