FormatProviders.h 15 KB

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