FormatProviders.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. //===- FormatProviders.h - Formatters for common LLVM types -----*- 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 format providers for many common LLVM types, for example
  10. // allowing precision and width specifiers for scalar and string types.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_SUPPORT_FORMATPROVIDERS_H
  14. #define LLVM_SUPPORT_FORMATPROVIDERS_H
  15. #include "llvm/ADT/Optional.h"
  16. #include "llvm/ADT/STLExtras.h"
  17. #include "llvm/ADT/StringSwitch.h"
  18. #include "llvm/ADT/Twine.h"
  19. #include "llvm/Support/FormatVariadicDetails.h"
  20. #include "llvm/Support/NativeFormatting.h"
  21. #include <type_traits>
  22. #include <vector>
  23. namespace llvm {
  24. namespace detail {
  25. template <typename T>
  26. struct use_integral_formatter
  27. : public std::integral_constant<
  28. bool, is_one_of<T, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
  29. int64_t, uint64_t, int, unsigned, long, unsigned long,
  30. long long, unsigned long long>::value> {};
  31. template <typename T>
  32. struct use_char_formatter
  33. : public std::integral_constant<bool, std::is_same<T, char>::value> {};
  34. template <typename T>
  35. struct is_cstring
  36. : public std::integral_constant<bool,
  37. is_one_of<T, char *, const char *>::value> {
  38. };
  39. template <typename T>
  40. struct use_string_formatter
  41. : public std::integral_constant<bool,
  42. std::is_convertible<T, llvm::StringRef>::value> {};
  43. template <typename T>
  44. struct use_pointer_formatter
  45. : public std::integral_constant<bool, std::is_pointer<T>::value &&
  46. !is_cstring<T>::value> {};
  47. template <typename T>
  48. struct use_double_formatter
  49. : public std::integral_constant<bool, std::is_floating_point<T>::value> {};
  50. class HelperFunctions {
  51. protected:
  52. static Optional<size_t> parseNumericPrecision(StringRef Str) {
  53. size_t Prec;
  54. Optional<size_t> Result;
  55. if (Str.empty())
  56. Result = None;
  57. else if (Str.getAsInteger(10, Prec)) {
  58. assert(false && "Invalid precision specifier");
  59. Result = None;
  60. } else {
  61. assert(Prec < 100 && "Precision out of range");
  62. Result = std::min<size_t>(99u, Prec);
  63. }
  64. return Result;
  65. }
  66. static bool consumeHexStyle(StringRef &Str, HexPrintStyle &Style) {
  67. if (!Str.startswith_lower("x"))
  68. return false;
  69. if (Str.consume_front("x-"))
  70. Style = HexPrintStyle::Lower;
  71. else if (Str.consume_front("X-"))
  72. Style = HexPrintStyle::Upper;
  73. else if (Str.consume_front("x+") || Str.consume_front("x"))
  74. Style = HexPrintStyle::PrefixLower;
  75. else if (Str.consume_front("X+") || Str.consume_front("X"))
  76. Style = HexPrintStyle::PrefixUpper;
  77. return true;
  78. }
  79. static size_t consumeNumHexDigits(StringRef &Str, HexPrintStyle Style,
  80. size_t Default) {
  81. Str.consumeInteger(10, Default);
  82. if (isPrefixedHexStyle(Style))
  83. Default += 2;
  84. return Default;
  85. }
  86. };
  87. }
  88. /// Implementation of format_provider<T> for integral arithmetic types.
  89. ///
  90. /// The options string of an integral type has the grammar:
  91. ///
  92. /// integer_options :: [style][digits]
  93. /// style :: <see table below>
  94. /// digits :: <non-negative integer> 0-99
  95. ///
  96. /// ==========================================================================
  97. /// | style | Meaning | Example | Digits Meaning |
  98. /// --------------------------------------------------------------------------
  99. /// | | | Input | Output | |
  100. /// ==========================================================================
  101. /// | x- | Hex no prefix, lower | 42 | 2a | Minimum # digits |
  102. /// | X- | Hex no prefix, upper | 42 | 2A | Minimum # digits |
  103. /// | x+ / x | Hex + prefix, lower | 42 | 0x2a | Minimum # digits |
  104. /// | X+ / X | Hex + prefix, upper | 42 | 0x2A | Minimum # digits |
  105. /// | N / n | Digit grouped number | 123456 | 123,456 | Ignored |
  106. /// | D / d | Integer | 100000 | 100000 | Ignored |
  107. /// | (empty) | Same as D / d | | | |
  108. /// ==========================================================================
  109. ///
  110. template <typename T>
  111. struct format_provider<
  112. T, std::enable_if_t<detail::use_integral_formatter<T>::value>>
  113. : public detail::HelperFunctions {
  114. private:
  115. public:
  116. static void format(const T &V, llvm::raw_ostream &Stream, StringRef Style) {
  117. HexPrintStyle HS;
  118. size_t Digits = 0;
  119. if (consumeHexStyle(Style, HS)) {
  120. Digits = consumeNumHexDigits(Style, HS, 0);
  121. write_hex(Stream, V, HS, Digits);
  122. return;
  123. }
  124. IntegerStyle IS = IntegerStyle::Integer;
  125. if (Style.consume_front("N") || Style.consume_front("n"))
  126. IS = IntegerStyle::Number;
  127. else if (Style.consume_front("D") || Style.consume_front("d"))
  128. IS = IntegerStyle::Integer;
  129. Style.consumeInteger(10, Digits);
  130. assert(Style.empty() && "Invalid integral format style!");
  131. write_integer(Stream, V, Digits, IS);
  132. }
  133. };
  134. /// Implementation of format_provider<T> for integral pointer types.
  135. ///
  136. /// The options string of a pointer type has the grammar:
  137. ///
  138. /// pointer_options :: [style][precision]
  139. /// style :: <see table below>
  140. /// digits :: <non-negative integer> 0-sizeof(void*)
  141. ///
  142. /// ==========================================================================
  143. /// | S | Meaning | Example |
  144. /// --------------------------------------------------------------------------
  145. /// | | | Input | Output |
  146. /// ==========================================================================
  147. /// | x- | Hex no prefix, lower | 0xDEADBEEF | deadbeef |
  148. /// | X- | Hex no prefix, upper | 0xDEADBEEF | DEADBEEF |
  149. /// | x+ / x | Hex + prefix, lower | 0xDEADBEEF | 0xdeadbeef |
  150. /// | X+ / X | Hex + prefix, upper | 0xDEADBEEF | 0xDEADBEEF |
  151. /// | (empty) | Same as X+ / X | | |
  152. /// ==========================================================================
  153. ///
  154. /// The default precision is the number of nibbles in a machine word, and in all
  155. /// cases indicates the minimum number of nibbles to print.
  156. template <typename T>
  157. struct format_provider<
  158. T, std::enable_if_t<detail::use_pointer_formatter<T>::value>>
  159. : public detail::HelperFunctions {
  160. private:
  161. public:
  162. static void format(const T &V, llvm::raw_ostream &Stream, StringRef Style) {
  163. HexPrintStyle HS = HexPrintStyle::PrefixUpper;
  164. consumeHexStyle(Style, HS);
  165. size_t Digits = consumeNumHexDigits(Style, HS, sizeof(void *) * 2);
  166. write_hex(Stream, reinterpret_cast<std::uintptr_t>(V), HS, Digits);
  167. }
  168. };
  169. /// Implementation of format_provider<T> for c-style strings and string
  170. /// objects such as std::string and llvm::StringRef.
  171. ///
  172. /// The options string of a string type has the grammar:
  173. ///
  174. /// string_options :: [length]
  175. ///
  176. /// where `length` is an optional integer specifying the maximum number of
  177. /// characters in the string to print. If `length` is omitted, the string is
  178. /// printed up to the null terminator.
  179. template <typename T>
  180. struct format_provider<
  181. T, std::enable_if_t<detail::use_string_formatter<T>::value>> {
  182. static void format(const T &V, llvm::raw_ostream &Stream, StringRef Style) {
  183. size_t N = StringRef::npos;
  184. if (!Style.empty() && Style.getAsInteger(10, N)) {
  185. assert(false && "Style is not a valid integer");
  186. }
  187. llvm::StringRef S = V;
  188. Stream << S.substr(0, N);
  189. }
  190. };
  191. /// Implementation of format_provider<T> for llvm::Twine.
  192. ///
  193. /// This follows the same rules as the string formatter.
  194. template <> struct format_provider<Twine> {
  195. static void format(const Twine &V, llvm::raw_ostream &Stream,
  196. StringRef Style) {
  197. format_provider<std::string>::format(V.str(), Stream, Style);
  198. }
  199. };
  200. /// Implementation of format_provider<T> for characters.
  201. ///
  202. /// The options string of a character type has the grammar:
  203. ///
  204. /// char_options :: (empty) | [integer_options]
  205. ///
  206. /// If `char_options` is empty, the character is displayed as an ASCII
  207. /// character. Otherwise, it is treated as an integer options string.
  208. ///
  209. template <typename T>
  210. struct format_provider<T,
  211. std::enable_if_t<detail::use_char_formatter<T>::value>> {
  212. static void format(const char &V, llvm::raw_ostream &Stream,
  213. StringRef Style) {
  214. if (Style.empty())
  215. Stream << V;
  216. else {
  217. int X = static_cast<int>(V);
  218. format_provider<int>::format(X, Stream, Style);
  219. }
  220. }
  221. };
  222. /// Implementation of format_provider<T> for type `bool`
  223. ///
  224. /// The options string of a boolean type has the grammar:
  225. ///
  226. /// bool_options :: "" | "Y" | "y" | "D" | "d" | "T" | "t"
  227. ///
  228. /// ==================================
  229. /// | C | Meaning |
  230. /// ==================================
  231. /// | Y | YES / NO |
  232. /// | y | yes / no |
  233. /// | D / d | Integer 0 or 1 |
  234. /// | T | TRUE / FALSE |
  235. /// | t | true / false |
  236. /// | (empty) | Equivalent to 't' |
  237. /// ==================================
  238. template <> struct format_provider<bool> {
  239. static void format(const bool &B, llvm::raw_ostream &Stream,
  240. StringRef Style) {
  241. Stream << StringSwitch<const char *>(Style)
  242. .Case("Y", B ? "YES" : "NO")
  243. .Case("y", B ? "yes" : "no")
  244. .CaseLower("D", B ? "1" : "0")
  245. .Case("T", B ? "TRUE" : "FALSE")
  246. .Cases("t", "", B ? "true" : "false")
  247. .Default(B ? "1" : "0");
  248. }
  249. };
  250. /// Implementation of format_provider<T> for floating point types.
  251. ///
  252. /// The options string of a floating point type has the format:
  253. ///
  254. /// float_options :: [style][precision]
  255. /// style :: <see table below>
  256. /// precision :: <non-negative integer> 0-99
  257. ///
  258. /// =====================================================
  259. /// | style | Meaning | Example |
  260. /// -----------------------------------------------------
  261. /// | | | Input | Output |
  262. /// =====================================================
  263. /// | P / p | Percentage | 0.05 | 5.00% |
  264. /// | F / f | Fixed point | 1.0 | 1.00 |
  265. /// | E | Exponential with E | 100000 | 1.0E+05 |
  266. /// | e | Exponential with e | 100000 | 1.0e+05 |
  267. /// | (empty) | Same as F / f | | |
  268. /// =====================================================
  269. ///
  270. /// The default precision is 6 for exponential (E / e) and 2 for everything
  271. /// else.
  272. template <typename T>
  273. struct format_provider<T,
  274. std::enable_if_t<detail::use_double_formatter<T>::value>>
  275. : public detail::HelperFunctions {
  276. static void format(const T &V, llvm::raw_ostream &Stream, StringRef Style) {
  277. FloatStyle S;
  278. if (Style.consume_front("P") || Style.consume_front("p"))
  279. S = FloatStyle::Percent;
  280. else if (Style.consume_front("F") || Style.consume_front("f"))
  281. S = FloatStyle::Fixed;
  282. else if (Style.consume_front("E"))
  283. S = FloatStyle::ExponentUpper;
  284. else if (Style.consume_front("e"))
  285. S = FloatStyle::Exponent;
  286. else
  287. S = FloatStyle::Fixed;
  288. Optional<size_t> Precision = parseNumericPrecision(Style);
  289. if (!Precision.hasValue())
  290. Precision = getDefaultPrecision(S);
  291. write_double(Stream, static_cast<double>(V), S, Precision);
  292. }
  293. };
  294. namespace detail {
  295. template <typename IterT>
  296. using IterValue = typename std::iterator_traits<IterT>::value_type;
  297. template <typename IterT>
  298. struct range_item_has_provider
  299. : public std::integral_constant<
  300. bool, !uses_missing_provider<IterValue<IterT>>::value> {};
  301. }
  302. /// Implementation of format_provider<T> for ranges.
  303. ///
  304. /// This will print an arbitrary range as a delimited sequence of items.
  305. ///
  306. /// The options string of a range type has the grammar:
  307. ///
  308. /// range_style ::= [separator] [element_style]
  309. /// separator ::= "$" delimeted_expr
  310. /// element_style ::= "@" delimeted_expr
  311. /// delimeted_expr ::= "[" expr "]" | "(" expr ")" | "<" expr ">"
  312. /// expr ::= <any string not containing delimeter>
  313. ///
  314. /// where the separator expression is the string to insert between consecutive
  315. /// items in the range and the argument expression is the Style specification to
  316. /// be used when formatting the underlying type. The default separator if
  317. /// unspecified is ' ' (space). The syntax of the argument expression follows
  318. /// whatever grammar is dictated by the format provider or format adapter used
  319. /// to format the value type.
  320. ///
  321. /// Note that attempting to format an `iterator_range<T>` where no format
  322. /// provider can be found for T will result in a compile error.
  323. ///
  324. template <typename IterT> class format_provider<llvm::iterator_range<IterT>> {
  325. using value = typename std::iterator_traits<IterT>::value_type;
  326. using reference = typename std::iterator_traits<IterT>::reference;
  327. static StringRef consumeOneOption(StringRef &Style, char Indicator,
  328. StringRef Default) {
  329. if (Style.empty())
  330. return Default;
  331. if (Style.front() != Indicator)
  332. return Default;
  333. Style = Style.drop_front();
  334. if (Style.empty()) {
  335. assert(false && "Invalid range style");
  336. return Default;
  337. }
  338. for (const char *D : {"[]", "<>", "()"}) {
  339. if (Style.front() != D[0])
  340. continue;
  341. size_t End = Style.find_first_of(D[1]);
  342. if (End == StringRef::npos) {
  343. assert(false && "Missing range option end delimeter!");
  344. return Default;
  345. }
  346. StringRef Result = Style.slice(1, End);
  347. Style = Style.drop_front(End + 1);
  348. return Result;
  349. }
  350. assert(false && "Invalid range style!");
  351. return Default;
  352. }
  353. static std::pair<StringRef, StringRef> parseOptions(StringRef Style) {
  354. StringRef Sep = consumeOneOption(Style, '$', ", ");
  355. StringRef Args = consumeOneOption(Style, '@', "");
  356. assert(Style.empty() && "Unexpected text in range option string!");
  357. return std::make_pair(Sep, Args);
  358. }
  359. public:
  360. static_assert(detail::range_item_has_provider<IterT>::value,
  361. "Range value_type does not have a format provider!");
  362. static void format(const llvm::iterator_range<IterT> &V,
  363. llvm::raw_ostream &Stream, StringRef Style) {
  364. StringRef Sep;
  365. StringRef ArgStyle;
  366. std::tie(Sep, ArgStyle) = parseOptions(Style);
  367. auto Begin = V.begin();
  368. auto End = V.end();
  369. if (Begin != End) {
  370. auto Adapter =
  371. detail::build_format_adapter(std::forward<reference>(*Begin));
  372. Adapter.format(Stream, ArgStyle);
  373. ++Begin;
  374. }
  375. while (Begin != End) {
  376. Stream << Sep;
  377. auto Adapter =
  378. detail::build_format_adapter(std::forward<reference>(*Begin));
  379. Adapter.format(Stream, ArgStyle);
  380. ++Begin;
  381. }
  382. }
  383. };
  384. }
  385. #endif