LLVM  8.0.1
FormatProviders.h
Go to the documentation of this file.
1 //===- FormatProviders.h - Formatters for common LLVM types -----*- 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 implements format providers for many common LLVM types, for example
11 // allowing precision and width specifiers for scalar and string types.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_SUPPORT_FORMATPROVIDERS_H
16 #define LLVM_SUPPORT_FORMATPROVIDERS_H
17 
18 #include "llvm/ADT/Optional.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/ADT/StringSwitch.h"
21 #include "llvm/ADT/Twine.h"
24 
25 #include <type_traits>
26 #include <vector>
27 
28 namespace llvm {
29 namespace detail {
30 template <typename T>
32  : public std::integral_constant<
33  bool, is_one_of<T, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
34  int64_t, uint64_t, int, unsigned, long, unsigned long,
35  long long, unsigned long long>::value> {};
36 
37 template <typename T>
39  : public std::integral_constant<bool, std::is_same<T, char>::value> {};
40 
41 template <typename T>
42 struct is_cstring
43  : public std::integral_constant<bool,
44  is_one_of<T, char *, const char *>::value> {
45 };
46 
47 template <typename T>
49  : public std::integral_constant<bool,
50  std::is_convertible<T, llvm::StringRef>::value> {};
51 
52 template <typename T>
54  : public std::integral_constant<bool, std::is_pointer<T>::value &&
55  !is_cstring<T>::value> {};
56 
57 template <typename T>
59  : public std::integral_constant<bool, std::is_floating_point<T>::value> {};
60 
62 protected:
64  size_t Prec;
65  Optional<size_t> Result;
66  if (Str.empty())
67  Result = None;
68  else if (Str.getAsInteger(10, Prec)) {
69  assert(false && "Invalid precision specifier");
70  Result = None;
71  } else {
72  assert(Prec < 100 && "Precision out of range");
73  Result = std::min<size_t>(99u, Prec);
74  }
75  return Result;
76  }
77 
79  if (!Str.startswith_lower("x"))
80  return false;
81 
82  if (Str.consume_front("x-"))
83  Style = HexPrintStyle::Lower;
84  else if (Str.consume_front("X-"))
85  Style = HexPrintStyle::Upper;
86  else if (Str.consume_front("x+") || Str.consume_front("x"))
88  else if (Str.consume_front("X+") || Str.consume_front("X"))
90  return true;
91  }
92 
94  size_t Default) {
95  Str.consumeInteger(10, Default);
96  if (isPrefixedHexStyle(Style))
97  Default += 2;
98  return Default;
99  }
100 };
101 }
102 
103 /// Implementation of format_provider<T> for integral arithmetic types.
104 ///
105 /// The options string of an integral type has the grammar:
106 ///
107 /// integer_options :: [style][digits]
108 /// style :: <see table below>
109 /// digits :: <non-negative integer> 0-99
110 ///
111 /// ==========================================================================
112 /// | style | Meaning | Example | Digits Meaning |
113 /// --------------------------------------------------------------------------
114 /// | | | Input | Output | |
115 /// ==========================================================================
116 /// | x- | Hex no prefix, lower | 42 | 2a | Minimum # digits |
117 /// | X- | Hex no prefix, upper | 42 | 2A | Minimum # digits |
118 /// | x+ / x | Hex + prefix, lower | 42 | 0x2a | Minimum # digits |
119 /// | X+ / X | Hex + prefix, upper | 42 | 0x2A | Minimum # digits |
120 /// | N / n | Digit grouped number | 123456 | 123,456 | Ignored |
121 /// | D / d | Integer | 100000 | 100000 | Ignored |
122 /// | (empty) | Same as D / d | | | |
123 /// ==========================================================================
124 ///
125 
126 template <typename T>
128  T, typename std::enable_if<detail::use_integral_formatter<T>::value>::type>
129  : public detail::HelperFunctions {
130 private:
131 public:
132  static void format(const T &V, llvm::raw_ostream &Stream, StringRef Style) {
134  size_t Digits = 0;
135  if (consumeHexStyle(Style, HS)) {
136  Digits = consumeNumHexDigits(Style, HS, 0);
137  write_hex(Stream, V, HS, Digits);
138  return;
139  }
140 
142  if (Style.consume_front("N") || Style.consume_front("n"))
144  else if (Style.consume_front("D") || Style.consume_front("d"))
146 
147  Style.consumeInteger(10, Digits);
148  assert(Style.empty() && "Invalid integral format style!");
149  write_integer(Stream, V, Digits, IS);
150  }
151 };
152 
153 /// Implementation of format_provider<T> for integral pointer types.
154 ///
155 /// The options string of a pointer type has the grammar:
156 ///
157 /// pointer_options :: [style][precision]
158 /// style :: <see table below>
159 /// digits :: <non-negative integer> 0-sizeof(void*)
160 ///
161 /// ==========================================================================
162 /// | S | Meaning | Example |
163 /// --------------------------------------------------------------------------
164 /// | | | Input | Output |
165 /// ==========================================================================
166 /// | x- | Hex no prefix, lower | 0xDEADBEEF | deadbeef |
167 /// | X- | Hex no prefix, upper | 0xDEADBEEF | DEADBEEF |
168 /// | x+ / x | Hex + prefix, lower | 0xDEADBEEF | 0xdeadbeef |
169 /// | X+ / X | Hex + prefix, upper | 0xDEADBEEF | 0xDEADBEEF |
170 /// | (empty) | Same as X+ / X | | |
171 /// ==========================================================================
172 ///
173 /// The default precision is the number of nibbles in a machine word, and in all
174 /// cases indicates the minimum number of nibbles to print.
175 template <typename T>
177  T, typename std::enable_if<detail::use_pointer_formatter<T>::value>::type>
178  : public detail::HelperFunctions {
179 private:
180 public:
181  static void format(const T &V, llvm::raw_ostream &Stream, StringRef Style) {
183  consumeHexStyle(Style, HS);
184  size_t Digits = consumeNumHexDigits(Style, HS, sizeof(void *) * 2);
185  write_hex(Stream, reinterpret_cast<std::uintptr_t>(V), HS, Digits);
186  }
187 };
188 
189 /// Implementation of format_provider<T> for c-style strings and string
190 /// objects such as std::string and llvm::StringRef.
191 ///
192 /// The options string of a string type has the grammar:
193 ///
194 /// string_options :: [length]
195 ///
196 /// where `length` is an optional integer specifying the maximum number of
197 /// characters in the string to print. If `length` is omitted, the string is
198 /// printed up to the null terminator.
199 
200 template <typename T>
202  T, typename std::enable_if<detail::use_string_formatter<T>::value>::type> {
203  static void format(const T &V, llvm::raw_ostream &Stream, StringRef Style) {
204  size_t N = StringRef::npos;
205  if (!Style.empty() && Style.getAsInteger(10, N)) {
206  assert(false && "Style is not a valid integer");
207  }
208  llvm::StringRef S = V;
209  Stream << S.substr(0, N);
210  }
211 };
212 
213 /// Implementation of format_provider<T> for llvm::Twine.
214 ///
215 /// This follows the same rules as the string formatter.
216 
217 template <> struct format_provider<Twine> {
218  static void format(const Twine &V, llvm::raw_ostream &Stream,
219  StringRef Style) {
221  }
222 };
223 
224 /// Implementation of format_provider<T> for characters.
225 ///
226 /// The options string of a character type has the grammar:
227 ///
228 /// char_options :: (empty) | [integer_options]
229 ///
230 /// If `char_options` is empty, the character is displayed as an ASCII
231 /// character. Otherwise, it is treated as an integer options string.
232 ///
233 template <typename T>
235  T, typename std::enable_if<detail::use_char_formatter<T>::value>::type> {
236  static void format(const char &V, llvm::raw_ostream &Stream,
237  StringRef Style) {
238  if (Style.empty())
239  Stream << V;
240  else {
241  int X = static_cast<int>(V);
242  format_provider<int>::format(X, Stream, Style);
243  }
244  }
245 };
246 
247 /// Implementation of format_provider<T> for type `bool`
248 ///
249 /// The options string of a boolean type has the grammar:
250 ///
251 /// bool_options :: "" | "Y" | "y" | "D" | "d" | "T" | "t"
252 ///
253 /// ==================================
254 /// | C | Meaning |
255 /// ==================================
256 /// | Y | YES / NO |
257 /// | y | yes / no |
258 /// | D / d | Integer 0 or 1 |
259 /// | T | TRUE / FALSE |
260 /// | t | true / false |
261 /// | (empty) | Equivalent to 't' |
262 /// ==================================
263 template <> struct format_provider<bool> {
264  static void format(const bool &B, llvm::raw_ostream &Stream,
265  StringRef Style) {
266  Stream << StringSwitch<const char *>(Style)
267  .Case("Y", B ? "YES" : "NO")
268  .Case("y", B ? "yes" : "no")
269  .CaseLower("D", B ? "1" : "0")
270  .Case("T", B ? "TRUE" : "FALSE")
271  .Cases("t", "", B ? "true" : "false")
272  .Default(B ? "1" : "0");
273  }
274 };
275 
276 /// Implementation of format_provider<T> for floating point types.
277 ///
278 /// The options string of a floating point type has the format:
279 ///
280 /// float_options :: [style][precision]
281 /// style :: <see table below>
282 /// precision :: <non-negative integer> 0-99
283 ///
284 /// =====================================================
285 /// | style | Meaning | Example |
286 /// -----------------------------------------------------
287 /// | | | Input | Output |
288 /// =====================================================
289 /// | P / p | Percentage | 0.05 | 5.00% |
290 /// | F / f | Fixed point | 1.0 | 1.00 |
291 /// | E | Exponential with E | 100000 | 1.0E+05 |
292 /// | e | Exponential with e | 100000 | 1.0e+05 |
293 /// | (empty) | Same as F / f | | |
294 /// =====================================================
295 ///
296 /// The default precision is 6 for exponential (E / e) and 2 for everything
297 /// else.
298 
299 template <typename T>
301  T, typename std::enable_if<detail::use_double_formatter<T>::value>::type>
302  : public detail::HelperFunctions {
303  static void format(const T &V, llvm::raw_ostream &Stream, StringRef Style) {
304  FloatStyle S;
305  if (Style.consume_front("P") || Style.consume_front("p"))
307  else if (Style.consume_front("F") || Style.consume_front("f"))
308  S = FloatStyle::Fixed;
309  else if (Style.consume_front("E"))
311  else if (Style.consume_front("e"))
313  else
314  S = FloatStyle::Fixed;
315 
316  Optional<size_t> Precision = parseNumericPrecision(Style);
317  if (!Precision.hasValue())
318  Precision = getDefaultPrecision(S);
319 
320  write_double(Stream, static_cast<double>(V), S, Precision);
321  }
322 };
323 
324 namespace detail {
325 template <typename IterT>
326 using IterValue = typename std::iterator_traits<IterT>::value_type;
327 
328 template <typename IterT>
330  : public std::integral_constant<
331  bool, !uses_missing_provider<IterValue<IterT>>::value> {};
332 }
333 
334 /// Implementation of format_provider<T> for ranges.
335 ///
336 /// This will print an arbitrary range as a delimited sequence of items.
337 ///
338 /// The options string of a range type has the grammar:
339 ///
340 /// range_style ::= [separator] [element_style]
341 /// separator ::= "$" delimeted_expr
342 /// element_style ::= "@" delimeted_expr
343 /// delimeted_expr ::= "[" expr "]" | "(" expr ")" | "<" expr ">"
344 /// expr ::= <any string not containing delimeter>
345 ///
346 /// where the separator expression is the string to insert between consecutive
347 /// items in the range and the argument expression is the Style specification to
348 /// be used when formatting the underlying type. The default separator if
349 /// unspecified is ' ' (space). The syntax of the argument expression follows
350 /// whatever grammar is dictated by the format provider or format adapter used
351 /// to format the value type.
352 ///
353 /// Note that attempting to format an `iterator_range<T>` where no format
354 /// provider can be found for T will result in a compile error.
355 ///
356 
357 template <typename IterT> class format_provider<llvm::iterator_range<IterT>> {
358  using value = typename std::iterator_traits<IterT>::value_type;
359  using reference = typename std::iterator_traits<IterT>::reference;
360 
361  static StringRef consumeOneOption(StringRef &Style, char Indicator,
362  StringRef Default) {
363  if (Style.empty())
364  return Default;
365  if (Style.front() != Indicator)
366  return Default;
367  Style = Style.drop_front();
368  if (Style.empty()) {
369  assert(false && "Invalid range style");
370  return Default;
371  }
372 
373  for (const char *D : {"[]", "<>", "()"}) {
374  if (Style.front() != D[0])
375  continue;
376  size_t End = Style.find_first_of(D[1]);
377  if (End == StringRef::npos) {
378  assert(false && "Missing range option end delimeter!");
379  return Default;
380  }
381  StringRef Result = Style.slice(1, End);
382  Style = Style.drop_front(End + 1);
383  return Result;
384  }
385  assert(false && "Invalid range style!");
386  return Default;
387  }
388 
389  static std::pair<StringRef, StringRef> parseOptions(StringRef Style) {
390  StringRef Sep = consumeOneOption(Style, '$', ", ");
391  StringRef Args = consumeOneOption(Style, '@', "");
392  assert(Style.empty() && "Unexpected text in range option string!");
393  return std::make_pair(Sep, Args);
394  }
395 
396 public:
398  "Range value_type does not have a format provider!");
399  static void format(const llvm::iterator_range<IterT> &V,
400  llvm::raw_ostream &Stream, StringRef Style) {
401  StringRef Sep;
402  StringRef ArgStyle;
403  std::tie(Sep, ArgStyle) = parseOptions(Style);
404  auto Begin = V.begin();
405  auto End = V.end();
406  if (Begin != End) {
407  auto Adapter =
408  detail::build_format_adapter(std::forward<reference>(*Begin));
409  Adapter.format(Stream, ArgStyle);
410  ++Begin;
411  }
412  while (Begin != End) {
413  Stream << Sep;
414  auto Adapter =
415  detail::build_format_adapter(std::forward<reference>(*Begin));
416  Adapter.format(Stream, ArgStyle);
417  ++Begin;
418  }
419  }
420 };
421 }
422 
423 #endif
const NoneType None
Definition: None.h:24
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
LLVM_NODISCARD bool startswith_lower(StringRef Prefix) const
Check if this string starts with the given Prefix, ignoring case.
Definition: StringRef.cpp:47
This class represents lattice values for constants.
Definition: AllocatorList.h:24
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
static void format(const bool &B, llvm::raw_ostream &Stream, StringRef Style)
static bool consumeHexStyle(StringRef &Str, HexPrintStyle &Style)
void write_double(raw_ostream &S, double D, FloatStyle Style, Optional< size_t > Precision=None)
Definition: BitVector.h:938
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
size_t getDefaultPrecision(FloatStyle Style)
LLVM_ATTRIBUTE_ALWAYS_INLINE bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Definition: StringRef.h:678
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type consumeInteger(unsigned Radix, T &Result)
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:531
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:133
bool isPrefixedHexStyle(HexPrintStyle S)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:598
static void format(const char &V, llvm::raw_ostream &Stream, StringRef Style)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:497
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_front(size_t N=1) const
Return a StringRef equal to &#39;this&#39; but with the first N elements dropped.
Definition: StringRef.h:645
static void format(const llvm::iterator_range< IterT > &V, llvm::raw_ostream &Stream, StringRef Style)
static void format(const Twine &V, llvm::raw_ostream &Stream, StringRef Style)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition: StringRef.h:710
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
A range adaptor for a pair of iterators.
typename std::iterator_traits< IterT >::value_type IterValue
bool hasValue() const
Definition: Optional.h:165
void write_hex(raw_ostream &S, uint64_t N, HexPrintStyle Style, Optional< size_t > Width=None)
static const size_t npos
Definition: StringRef.h:51
LLVM_NODISCARD size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
Definition: StringRef.h:395
#define N
std::string str() const
Return the twine contents as a std::string.
Definition: Twine.cpp:18
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM_NODISCARD char front() const
front - Get the first character in the string.
Definition: StringRef.h:142
std::enable_if< uses_format_member< T >::value, T >::type build_format_adapter(T &&Item)
IteratorT begin() const
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
static Optional< size_t > parseNumericPrecision(StringRef Str)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
void write_integer(raw_ostream &S, unsigned int N, size_t MinDigits, IntegerStyle Style)
IteratorT end() const
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
static size_t consumeNumHexDigits(StringRef &Str, HexPrintStyle Style, size_t Default)