blob: 039b1b900f31be5bafb4db234db0fea8557e7761 [file] [log] [blame]
Zachary Turner63055452017-06-15 22:24:24 +00001//===- FormatUtil.cpp ----------------------------------------- *- 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#include "FormatUtil.h"
11#include "llvm/ADT/STLExtras.h"
12#include "llvm/ADT/StringExtras.h"
Zachary Turner28e31ee2017-08-11 20:46:28 +000013#include "llvm/BinaryFormat/COFF.h"
Zachary Turner63055452017-06-15 22:24:24 +000014#include "llvm/Support/FormatAdapters.h"
15#include "llvm/Support/FormatVariadic.h"
16
17using namespace llvm;
18using namespace llvm::pdb;
19
Zachary Turner8120ebf2017-07-05 21:54:58 +000020std::string llvm::pdb::truncateStringBack(StringRef S, uint32_t MaxLen) {
21 if (MaxLen == 0 || S.size() <= MaxLen || S.size() <= 3)
22 return S;
23
24 assert(MaxLen >= 3);
Zachary Turner91dcab42017-07-05 21:59:20 +000025 uint32_t FinalLen = std::min<size_t>(S.size(), MaxLen - 3);
Zachary Turner8120ebf2017-07-05 21:54:58 +000026 S = S.take_front(FinalLen);
27 return std::string(S) + std::string("...");
28}
29
Zachary Turnerf3b4b2d2017-07-07 18:45:37 +000030std::string llvm::pdb::truncateStringMiddle(StringRef S, uint32_t MaxLen) {
31 if (MaxLen == 0 || S.size() <= MaxLen || S.size() <= 3)
32 return S;
33
34 assert(MaxLen >= 3);
35 uint32_t FinalLen = std::min<size_t>(S.size(), MaxLen - 3);
36 StringRef Front = S.take_front(FinalLen / 2);
37 StringRef Back = S.take_back(Front.size());
38 return std::string(Front) + std::string("...") + std::string(Back);
39}
40
Zachary Turner8120ebf2017-07-05 21:54:58 +000041std::string llvm::pdb::truncateStringFront(StringRef S, uint32_t MaxLen) {
42 if (MaxLen == 0 || S.size() <= MaxLen || S.size() <= 3)
43 return S;
44
45 assert(MaxLen >= 3);
46 S = S.take_back(MaxLen - 3);
47 return std::string("...") + std::string(S);
48}
49
50std::string llvm::pdb::truncateQuotedNameFront(StringRef Label, StringRef Name,
51 uint32_t MaxLen) {
52 uint32_t RequiredExtraChars = Label.size() + 1 + 2;
53 if (MaxLen == 0 || RequiredExtraChars + Name.size() <= MaxLen)
54 return formatv("{0} \"{1}\"", Label, Name).str();
55
56 assert(MaxLen >= RequiredExtraChars);
57 std::string TN = truncateStringFront(Name, MaxLen - RequiredExtraChars);
58 return formatv("{0} \"{1}\"", Label, TN).str();
59}
60
61std::string llvm::pdb::truncateQuotedNameBack(StringRef Label, StringRef Name,
62 uint32_t MaxLen) {
63 uint32_t RequiredExtraChars = Label.size() + 1 + 2;
64 if (MaxLen == 0 || RequiredExtraChars + Name.size() <= MaxLen)
65 return formatv("{0} \"{1}\"", Label, Name).str();
66
67 assert(MaxLen >= RequiredExtraChars);
68 std::string TN = truncateStringBack(Name, MaxLen - RequiredExtraChars);
69 return formatv("{0} \"{1}\"", Label, TN).str();
70}
71
Zachary Turner63055452017-06-15 22:24:24 +000072std::string llvm::pdb::typesetItemList(ArrayRef<std::string> Opts,
Zachary Turner47d9a562017-06-16 00:04:24 +000073 uint32_t IndentLevel, uint32_t GroupSize,
Zachary Turner63055452017-06-15 22:24:24 +000074 StringRef Sep) {
75 std::string Result;
76 while (!Opts.empty()) {
77 ArrayRef<std::string> ThisGroup;
78 ThisGroup = Opts.take_front(GroupSize);
79 Opts = Opts.drop_front(ThisGroup.size());
80 Result += join(ThisGroup, Sep);
81 if (!Opts.empty()) {
82 Result += Sep;
83 Result += "\n";
84 Result += formatv("{0}", fmt_repeat(' ', IndentLevel));
85 }
86 }
87 return Result;
88}
89
90std::string llvm::pdb::typesetStringList(uint32_t IndentLevel,
91 ArrayRef<StringRef> Strings) {
92 std::string Result = "[";
93 for (const auto &S : Strings) {
94 Result += formatv("\n{0}{1}", fmt_repeat(' ', IndentLevel), S);
95 }
96 Result += "]";
97 return Result;
98}
99
100std::string llvm::pdb::formatSegmentOffset(uint16_t Segment, uint32_t Offset) {
101 return formatv("{0:4}:{1:4}", Segment, Offset);
102}
Zachary Turner28e31ee2017-08-11 20:46:28 +0000103
104#define PUSH_CHARACTERISTIC_FLAG(Enum, TheOpt, Value, Style, Descriptive) \
105 PUSH_FLAG(Enum, TheOpt, Value, \
106 ((Style == CharacteristicStyle::HeaderDefinition) ? #TheOpt \
107 : Descriptive))
108
109#define PUSH_MASKED_CHARACTERISTIC_FLAG(Enum, Mask, TheOpt, Value, Style, \
110 Descriptive) \
111 PUSH_MASKED_FLAG(Enum, Mask, TheOpt, Value, \
112 ((Style == CharacteristicStyle::HeaderDefinition) \
113 ? #TheOpt \
114 : Descriptive))
115
116std::string llvm::pdb::formatSectionCharacteristics(uint32_t IndentLevel,
117 uint32_t C,
118 uint32_t FlagsPerLine,
119 StringRef Separator,
120 CharacteristicStyle Style) {
121 using SC = COFF::SectionCharacteristics;
122 std::vector<std::string> Opts;
123 if (C == COFF::SC_Invalid)
124 return "invalid";
125 if (C == 0)
126 return "none";
127 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_TYPE_NOLOAD, C, Style, "noload");
128 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_TYPE_NO_PAD, C, Style, "no padding");
129 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_CNT_CODE, C, Style, "code");
130 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_CNT_INITIALIZED_DATA, C, Style,
131 "initialized data");
132 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_CNT_UNINITIALIZED_DATA, C, Style,
133 "uninitialized data");
134 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_LNK_OTHER, C, Style, "other");
135 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_LNK_INFO, C, Style, "info");
136 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_LNK_REMOVE, C, Style, "remove");
137 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_LNK_COMDAT, C, Style, "comdat");
138 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_GPREL, C, Style, "gp rel");
139 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_PURGEABLE, C, Style, "purgeable");
140 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_16BIT, C, Style, "16-bit");
141 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_LOCKED, C, Style, "locked");
142 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_PRELOAD, C, Style, "preload");
143 PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_1BYTES, C,
144 Style, "1 byte align");
145 PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_2BYTES, C,
146 Style, "2 byte align");
147 PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_4BYTES, C,
148 Style, "4 byte align");
149 PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_8BYTES, C,
150 Style, "8 byte align");
151 PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_16BYTES, C,
152 Style, "16 byte align");
153 PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_32BYTES, C,
154 Style, "32 byte align");
155 PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_64BYTES, C,
156 Style, "64 byte align");
157 PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_128BYTES, C,
158 Style, "128 byte align");
159 PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_256BYTES, C,
160 Style, "256 byte align");
161 PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_512BYTES, C,
162 Style, "512 byte align");
163 PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_1024BYTES, C,
164 Style, "1024 byte align");
165 PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_2048BYTES, C,
166 Style, "2048 byte align");
167 PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_4096BYTES, C,
168 Style, "4096 byte align");
169 PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_8192BYTES, C,
170 Style, "8192 byte align");
171 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_LNK_NRELOC_OVFL, C, Style,
172 "noreloc overflow");
173 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_DISCARDABLE, C, Style,
174 "discardable");
175 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_NOT_CACHED, C, Style,
176 "not cached");
177 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_NOT_PAGED, C, Style, "not paged");
178 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_SHARED, C, Style, "shared");
179 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_EXECUTE, C, Style,
180 "execute permissions");
181 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_READ, C, Style,
182 "read permissions");
183 PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_WRITE, C, Style,
184 "write permissions");
185 return typesetItemList(Opts, IndentLevel, FlagsPerLine, Separator);
186}