1 //===- FormatUtil.h ------------------------------------------- *- C++ --*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_TOOLS_LLVMPDBUTIL_FORMAT_UTIL_H
10 #define LLVM_TOOLS_LLVMPDBUTIL_FORMAT_UTIL_H
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/DebugInfo/CodeView/CodeView.h"
15 #include "llvm/Support/Endian.h"
16 #include "llvm/Support/FormatAdapters.h"
17 #include "llvm/Support/FormatVariadic.h"
20 #include <type_traits>
25 std::string
truncateStringBack(StringRef S
, uint32_t MaxLen
);
26 std::string
truncateStringMiddle(StringRef S
, uint32_t MaxLen
);
27 std::string
truncateStringFront(StringRef S
, uint32_t MaxLen
);
28 std::string
truncateQuotedNameFront(StringRef Label
, StringRef Name
,
30 std::string
truncateQuotedNameBack(StringRef Label
, StringRef Name
,
33 #define PUSH_MASKED_FLAG(Enum, Mask, TheOpt, Value, Text) \
34 if (Enum::TheOpt == (Value & Mask)) \
37 #define PUSH_FLAG(Enum, TheOpt, Value, Text) \
38 PUSH_MASKED_FLAG(Enum, Enum::TheOpt, TheOpt, Value, Text)
40 #define RETURN_CASE(Enum, X, Ret) \
44 template <typename T
> std::string
formatUnknownEnum(T Value
) {
45 return formatv("unknown ({0})", static_cast<std::underlying_type_t
<T
>>(Value
))
49 std::string
formatSegmentOffset(uint16_t Segment
, uint32_t Offset
);
51 enum class CharacteristicStyle
{
52 HeaderDefinition
, // format as windows header definition
53 Descriptive
, // format as human readable words
55 std::string
formatSectionCharacteristics(
56 uint32_t IndentLevel
, uint32_t C
, uint32_t FlagsPerLine
,
58 CharacteristicStyle Style
= CharacteristicStyle::HeaderDefinition
);
60 std::string
typesetItemList(ArrayRef
<std::string
> Opts
, uint32_t IndentLevel
,
61 uint32_t GroupSize
, StringRef Sep
);
63 std::string
typesetStringList(uint32_t IndentLevel
,
64 ArrayRef
<StringRef
> Strings
);
66 std::string
formatChunkKind(codeview::DebugSubsectionKind Kind
,
67 bool Friendly
= true);
68 std::string
formatSymbolKind(codeview::SymbolKind K
);
69 std::string
formatTypeLeafKind(codeview::TypeLeafKind K
);
71 /// Returns the number of digits in the given integer.
72 inline int NumDigits(uint64_t N
) {
89 if (N
< 1000000000ULL)
91 if (N
< 10000000000ULL)
93 if (N
< 100000000000ULL)
95 if (N
< 1000000000000ULL)
97 if (N
< 10000000000000ULL)
99 if (N
< 100000000000000ULL)
101 if (N
< 1000000000000000ULL)
103 if (N
< 10000000000000000ULL)
105 if (N
< 100000000000000000ULL)
107 if (N
< 1000000000000000000ULL)
109 if (N
< 10000000000000000000ULL)
115 template <typename T
>
116 struct EndianAdapter final
117 : public FormatAdapter
<support::detail::packed_endian_specific_integral
<
118 T
, support::little
, support::unaligned
>> {
120 support::detail::packed_endian_specific_integral
<T
, support::little
,
123 explicit EndianAdapter(EndianType
&&Item
)
124 : FormatAdapter
<EndianType
>(std::move(Item
)) {}
126 void format(llvm::raw_ostream
&Stream
, StringRef Style
) override
{
127 format_provider
<T
>::format(static_cast<T
>(this->Item
), Stream
, Style
);
130 } // namespace detail
132 template <typename T
>
133 detail::EndianAdapter
<T
>
134 fmtle(support::detail::packed_endian_specific_integral
<T
, support::little
,
137 return detail::EndianAdapter
<T
>(std::move(Value
));