Coverage Report

Created: 2020-06-26 05:44

/home/arjun/llvm-project/llvm/include/llvm/Support/Format.h
Line
Count
Source (jump to first uncovered line)
1
//===- Format.h - Efficient printf-style formatting for streams -*- 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 implements the format() function, which can be used with other
10
// LLVM subsystems to provide printf-style formatting.  This gives all the power
11
// and risk of printf.  This can be used like this (with raw_ostreams as an
12
// example):
13
//
14
//    OS << "mynumber: " << format("%4.5f", 1234.412) << '\n';
15
//
16
// Or if you prefer:
17
//
18
//  OS << format("mynumber: %4.5f\n", 1234.412);
19
//
20
//===----------------------------------------------------------------------===//
21
22
#ifndef LLVM_SUPPORT_FORMAT_H
23
#define LLVM_SUPPORT_FORMAT_H
24
25
#include "llvm/ADT/ArrayRef.h"
26
#include "llvm/ADT/STLExtras.h"
27
#include "llvm/ADT/StringRef.h"
28
#include "llvm/Support/DataTypes.h"
29
#include <cassert>
30
#include <cstdio>
31
#include <tuple>
32
#include <utility>
33
34
namespace llvm {
35
36
/// This is a helper class used for handling formatted output.  It is the
37
/// abstract base class of a templated derived class.
38
class format_object_base {
39
protected:
40
  const char *Fmt;
41
  ~format_object_base() = default; // Disallow polymorphic deletion.
42
  format_object_base(const format_object_base &) = default;
43
  virtual void home(); // Out of line virtual method.
44
45
  /// Call snprintf() for this object, on the given buffer and size.
46
  virtual int snprint(char *Buffer, unsigned BufferSize) const = 0;
47
48
public:
49
0
  format_object_base(const char *fmt) : Fmt(fmt) {}
50
51
  /// Format the object into the specified buffer.  On success, this returns
52
  /// the length of the formatted string.  If the buffer is too small, this
53
  /// returns a length to retry with, which will be larger than BufferSize.
54
0
  unsigned print(char *Buffer, unsigned BufferSize) const {
55
0
    assert(BufferSize && "Invalid buffer size!");
56
0
57
0
    // Print the string, leaving room for the terminating null.
58
0
    int N = snprint(Buffer, BufferSize);
59
0
60
0
    // VC++ and old GlibC return negative on overflow, just double the size.
61
0
    if (N < 0)
62
0
      return BufferSize * 2;
63
0
64
0
    // Other implementations yield number of bytes needed, not including the
65
0
    // final '\0'.
66
0
    if (unsigned(N) >= BufferSize)
67
0
      return N + 1;
68
0
69
0
    // Otherwise N is the length of output (not including the final '\0').
70
0
    return N;
71
0
  }
72
};
73
74
/// These are templated helper classes used by the format function that
75
/// capture the object to be formatted and the format string. When actually
76
/// printed, this synthesizes the string into a temporary buffer provided and
77
/// returns whether or not it is big enough.
78
79
// Helper to validate that format() parameters are scalars or pointers.
80
template <typename... Args> struct validate_format_parameters;
81
template <typename Arg, typename... Args>
82
struct validate_format_parameters<Arg, Args...> {
83
  static_assert(std::is_scalar<Arg>::value,
84
                "format can't be used with non fundamental / non pointer type");
85
0
  validate_format_parameters() { validate_format_parameters<Args...>(); }
Unexecuted instantiation: _ZN4llvm26validate_format_parametersIJhEEC2Ev
Unexecuted instantiation: _ZN4llvm26validate_format_parametersIJdEEC2Ev
86
};
87
template <> struct validate_format_parameters<> {};
88
89
template <typename... Ts>
90
class format_object final : public format_object_base {
91
  std::tuple<Ts...> Vals;
92
93
  template <std::size_t... Is>
94
  int snprint_tuple(char *Buffer, unsigned BufferSize,
95
0
                    std::index_sequence<Is...>) const {
96
#ifdef _MSC_VER
97
    return _snprintf(Buffer, BufferSize, Fmt, std::get<Is>(Vals)...);
98
#else
99
    return snprintf(Buffer, BufferSize, Fmt, std::get<Is>(Vals)...);
100
0
#endif
101
0
  }
Unexecuted instantiation: _ZNK4llvm13format_objectIJhEE13snprint_tupleIJLm0EEEEiPcjSt16integer_sequenceImJXspT_EEE
Unexecuted instantiation: _ZNK4llvm13format_objectIJdEE13snprint_tupleIJLm0EEEEiPcjSt16integer_sequenceImJXspT_EEE
102
103
public:
104
  format_object(const char *fmt, const Ts &... vals)
105
0
      : format_object_base(fmt), Vals(vals...) {
106
0
    validate_format_parameters<Ts...>();
107
0
  }
Unexecuted instantiation: _ZN4llvm13format_objectIJhEEC2EPKcRKh
Unexecuted instantiation: _ZN4llvm13format_objectIJdEEC2EPKcRKd
108
109
0
  int snprint(char *Buffer, unsigned BufferSize) const override {
110
0
    return snprint_tuple(Buffer, BufferSize, std::index_sequence_for<Ts...>());
111
0
  }
Unexecuted instantiation: _ZNK4llvm13format_objectIJhEE7snprintEPcj
Unexecuted instantiation: _ZNK4llvm13format_objectIJdEE7snprintEPcj
112
};
113
114
/// These are helper functions used to produce formatted output.  They use
115
/// template type deduction to construct the appropriate instance of the
116
/// format_object class to simplify their construction.
117
///
118
/// This is typically used like:
119
/// \code
120
///   OS << format("%0.4f", myfloat) << '\n';
121
/// \endcode
122
123
template <typename... Ts>
124
0
inline format_object<Ts...> format(const char *Fmt, const Ts &... Vals) {
125
0
  return format_object<Ts...>(Fmt, Vals...);
126
0
}
Unexecuted instantiation: _ZN4llvm6formatIJhEEENS_13format_objectIJDpT_EEEPKcDpRKS2_
Unexecuted instantiation: _ZN4llvm6formatIJdEEENS_13format_objectIJDpT_EEEPKcDpRKS2_
127
128
/// This is a helper class for left_justify, right_justify, and center_justify.
129
class FormattedString {
130
public:
131
  enum Justification { JustifyNone, JustifyLeft, JustifyRight, JustifyCenter };
132
  FormattedString(StringRef S, unsigned W, Justification J)
133
0
      : Str(S), Width(W), Justify(J) {}
134
135
private:
136
  StringRef Str;
137
  unsigned Width;
138
  Justification Justify;
139
  friend class raw_ostream;
140
};
141
142
/// left_justify - append spaces after string so total output is
143
/// \p Width characters.  If \p Str is larger that \p Width, full string
144
/// is written with no padding.
145
0
inline FormattedString left_justify(StringRef Str, unsigned Width) {
146
0
  return FormattedString(Str, Width, FormattedString::JustifyLeft);
147
0
}
148
149
/// right_justify - add spaces before string so total output is
150
/// \p Width characters.  If \p Str is larger that \p Width, full string
151
/// is written with no padding.
152
0
inline FormattedString right_justify(StringRef Str, unsigned Width) {
153
0
  return FormattedString(Str, Width, FormattedString::JustifyRight);
154
0
}
155
156
/// center_justify - add spaces before and after string so total output is
157
/// \p Width characters.  If \p Str is larger that \p Width, full string
158
/// is written with no padding.
159
0
inline FormattedString center_justify(StringRef Str, unsigned Width) {
160
0
  return FormattedString(Str, Width, FormattedString::JustifyCenter);
161
0
}
162
163
/// This is a helper class used for format_hex() and format_decimal().
164
class FormattedNumber {
165
  uint64_t HexValue;
166
  int64_t DecValue;
167
  unsigned Width;
168
  bool Hex;
169
  bool Upper;
170
  bool HexPrefix;
171
  friend class raw_ostream;
172
173
public:
174
  FormattedNumber(uint64_t HV, int64_t DV, unsigned W, bool H, bool U,
175
                  bool Prefix)
176
      : HexValue(HV), DecValue(DV), Width(W), Hex(H), Upper(U),
177
0
        HexPrefix(Prefix) {}
178
};
179
180
/// format_hex - Output \p N as a fixed width hexadecimal. If number will not
181
/// fit in width, full number is still printed.  Examples:
182
///   OS << format_hex(255, 4)              => 0xff
183
///   OS << format_hex(255, 4, true)        => 0xFF
184
///   OS << format_hex(255, 6)              => 0x00ff
185
///   OS << format_hex(255, 2)              => 0xff
186
inline FormattedNumber format_hex(uint64_t N, unsigned Width,
187
0
                                  bool Upper = false) {
188
0
  assert(Width <= 18 && "hex width must be <= 18");
189
0
  return FormattedNumber(N, 0, Width, true, Upper, true);
190
0
}
191
192
/// format_hex_no_prefix - Output \p N as a fixed width hexadecimal. Does not
193
/// prepend '0x' to the outputted string.  If number will not fit in width,
194
/// full number is still printed.  Examples:
195
///   OS << format_hex_no_prefix(255, 2)              => ff
196
///   OS << format_hex_no_prefix(255, 2, true)        => FF
197
///   OS << format_hex_no_prefix(255, 4)              => 00ff
198
///   OS << format_hex_no_prefix(255, 1)              => ff
199
inline FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width,
200
0
                                            bool Upper = false) {
201
0
  assert(Width <= 16 && "hex width must be <= 16");
202
0
  return FormattedNumber(N, 0, Width, true, Upper, false);
203
0
}
204
205
/// format_decimal - Output \p N as a right justified, fixed-width decimal. If
206
/// number will not fit in width, full number is still printed.  Examples:
207
///   OS << format_decimal(0, 5)     => "    0"
208
///   OS << format_decimal(255, 5)   => "  255"
209
///   OS << format_decimal(-1, 3)    => " -1"
210
///   OS << format_decimal(12345, 3) => "12345"
211
0
inline FormattedNumber format_decimal(int64_t N, unsigned Width) {
212
0
  return FormattedNumber(0, N, Width, false, false, false);
213
0
}
214
215
class FormattedBytes {
216
  ArrayRef<uint8_t> Bytes;
217
218
  // If not None, display offsets for each line relative to starting value.
219
  Optional<uint64_t> FirstByteOffset;
220
  uint32_t IndentLevel;  // Number of characters to indent each line.
221
  uint32_t NumPerLine;   // Number of bytes to show per line.
222
  uint8_t ByteGroupSize; // How many hex bytes are grouped without spaces
223
  bool Upper;            // Show offset and hex bytes as upper case.
224
  bool ASCII;            // Show the ASCII bytes for the hex bytes to the right.
225
  friend class raw_ostream;
226
227
public:
228
  FormattedBytes(ArrayRef<uint8_t> B, uint32_t IL, Optional<uint64_t> O,
229
                 uint32_t NPL, uint8_t BGS, bool U, bool A)
230
      : Bytes(B), FirstByteOffset(O), IndentLevel(IL), NumPerLine(NPL),
231
0
        ByteGroupSize(BGS), Upper(U), ASCII(A) {
232
0
233
0
    if (ByteGroupSize > NumPerLine)
234
0
      ByteGroupSize = NumPerLine;
235
0
  }
236
};
237
238
inline FormattedBytes
239
format_bytes(ArrayRef<uint8_t> Bytes, Optional<uint64_t> FirstByteOffset = None,
240
             uint32_t NumPerLine = 16, uint8_t ByteGroupSize = 4,
241
0
             uint32_t IndentLevel = 0, bool Upper = false) {
242
0
  return FormattedBytes(Bytes, IndentLevel, FirstByteOffset, NumPerLine,
243
0
                        ByteGroupSize, Upper, false);
244
0
}
245
246
inline FormattedBytes
247
format_bytes_with_ascii(ArrayRef<uint8_t> Bytes,
248
                        Optional<uint64_t> FirstByteOffset = None,
249
                        uint32_t NumPerLine = 16, uint8_t ByteGroupSize = 4,
250
0
                        uint32_t IndentLevel = 0, bool Upper = false) {
251
0
  return FormattedBytes(Bytes, IndentLevel, FirstByteOffset, NumPerLine,
252
0
                        ByteGroupSize, Upper, true);
253
0
}
254
255
} // end namespace llvm
256
257
#endif