FormatUtil.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. //===- FormatUtil.h ------------------------------------------- *- 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. #ifndef LLVM_TOOLS_LLVMPDBUTIL_FORMAT_UTIL_H
  9. #define LLVM_TOOLS_LLVMPDBUTIL_FORMAT_UTIL_H
  10. #include "llvm/ADT/ArrayRef.h"
  11. #include "llvm/ADT/StringRef.h"
  12. #include "llvm/DebugInfo/CodeView/CodeView.h"
  13. #include "llvm/Support/Endian.h"
  14. #include "llvm/Support/FormatAdapters.h"
  15. #include "llvm/Support/FormatVariadic.h"
  16. #include <string>
  17. #include <type_traits>
  18. namespace llvm {
  19. namespace pdb {
  20. std::string truncateStringBack(StringRef S, uint32_t MaxLen);
  21. std::string truncateStringMiddle(StringRef S, uint32_t MaxLen);
  22. std::string truncateStringFront(StringRef S, uint32_t MaxLen);
  23. std::string truncateQuotedNameFront(StringRef Label, StringRef Name,
  24. uint32_t MaxLen);
  25. std::string truncateQuotedNameBack(StringRef Label, StringRef Name,
  26. uint32_t MaxLen);
  27. #define PUSH_MASKED_FLAG(Enum, Mask, TheOpt, Value, Text) \
  28. if (Enum::TheOpt == (Value & Mask)) \
  29. Opts.push_back(Text);
  30. #define PUSH_FLAG(Enum, TheOpt, Value, Text) \
  31. PUSH_MASKED_FLAG(Enum, Enum::TheOpt, TheOpt, Value, Text)
  32. #define RETURN_CASE(Enum, X, Ret) \
  33. case Enum::X: \
  34. return Ret;
  35. template <typename T> std::string formatUnknownEnum(T Value) {
  36. return formatv("unknown ({0})", static_cast<std::underlying_type_t<T>>(Value))
  37. .str();
  38. }
  39. std::string formatSegmentOffset(uint16_t Segment, uint32_t Offset);
  40. enum class CharacteristicStyle {
  41. HeaderDefinition, // format as windows header definition
  42. Descriptive, // format as human readable words
  43. };
  44. std::string formatSectionCharacteristics(
  45. uint32_t IndentLevel, uint32_t C, uint32_t FlagsPerLine,
  46. StringRef Separator,
  47. CharacteristicStyle Style = CharacteristicStyle::HeaderDefinition);
  48. std::string typesetItemList(ArrayRef<std::string> Opts, uint32_t IndentLevel,
  49. uint32_t GroupSize, StringRef Sep);
  50. std::string typesetStringList(uint32_t IndentLevel,
  51. ArrayRef<StringRef> Strings);
  52. std::string formatChunkKind(codeview::DebugSubsectionKind Kind,
  53. bool Friendly = true);
  54. std::string formatSymbolKind(codeview::SymbolKind K);
  55. std::string formatTypeLeafKind(codeview::TypeLeafKind K);
  56. /// Returns the number of digits in the given integer.
  57. inline int NumDigits(uint64_t N) {
  58. if (N < 10ULL)
  59. return 1;
  60. if (N < 100ULL)
  61. return 2;
  62. if (N < 1000ULL)
  63. return 3;
  64. if (N < 10000ULL)
  65. return 4;
  66. if (N < 100000ULL)
  67. return 5;
  68. if (N < 1000000ULL)
  69. return 6;
  70. if (N < 10000000ULL)
  71. return 7;
  72. if (N < 100000000ULL)
  73. return 8;
  74. if (N < 1000000000ULL)
  75. return 9;
  76. if (N < 10000000000ULL)
  77. return 10;
  78. if (N < 100000000000ULL)
  79. return 11;
  80. if (N < 1000000000000ULL)
  81. return 12;
  82. if (N < 10000000000000ULL)
  83. return 13;
  84. if (N < 100000000000000ULL)
  85. return 14;
  86. if (N < 1000000000000000ULL)
  87. return 15;
  88. if (N < 10000000000000000ULL)
  89. return 16;
  90. if (N < 100000000000000000ULL)
  91. return 17;
  92. if (N < 1000000000000000000ULL)
  93. return 18;
  94. if (N < 10000000000000000000ULL)
  95. return 19;
  96. return 20;
  97. }
  98. namespace detail {
  99. template <typename T>
  100. struct EndianAdapter final
  101. : public FormatAdapter<support::detail::packed_endian_specific_integral<
  102. T, support::little, support::unaligned>> {
  103. using EndianType =
  104. support::detail::packed_endian_specific_integral<T, support::little,
  105. support::unaligned>;
  106. explicit EndianAdapter(EndianType &&Item)
  107. : FormatAdapter<EndianType>(std::move(Item)) {}
  108. void format(llvm::raw_ostream &Stream, StringRef Style) override {
  109. format_provider<T>::format(static_cast<T>(this->Item), Stream, Style);
  110. }
  111. };
  112. } // namespace detail
  113. template <typename T>
  114. detail::EndianAdapter<T>
  115. fmtle(support::detail::packed_endian_specific_integral<T, support::little,
  116. support::unaligned>
  117. Value) {
  118. return detail::EndianAdapter<T>(std::move(Value));
  119. }
  120. }
  121. } // namespace llvm
  122. #endif