Bug Summary

File:llvm/lib/ObjectYAML/DWARFEmitter.cpp
Warning:line 1041, column 22
Moved-from object 'Err' is moved

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name DWARFEmitter.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-12/lib/clang/12.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/build-llvm/lib/ObjectYAML -I /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/lib/ObjectYAML -I /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/build-llvm/include -I /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-12/lib/clang/12.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/build-llvm/lib/ObjectYAML -fdebug-prefix-map=/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b=. -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-09-17-195756-12974-1 -x c++ /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/lib/ObjectYAML/DWARFEmitter.cpp

/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/lib/ObjectYAML/DWARFEmitter.cpp

1//===- DWARFEmitter - Convert YAML to DWARF binary data -------------------===//
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/// \file
10/// The DWARF component of yaml2obj. Provided as library code for tests.
11///
12//===----------------------------------------------------------------------===//
13
14#include "llvm/ObjectYAML/DWARFEmitter.h"
15#include "llvm/ADT/ArrayRef.h"
16#include "llvm/ADT/StringMap.h"
17#include "llvm/ADT/StringRef.h"
18#include "llvm/ADT/StringSwitch.h"
19#include "llvm/BinaryFormat/Dwarf.h"
20#include "llvm/ObjectYAML/DWARFYAML.h"
21#include "llvm/Support/Errc.h"
22#include "llvm/Support/Error.h"
23#include "llvm/Support/Host.h"
24#include "llvm/Support/LEB128.h"
25#include "llvm/Support/MathExtras.h"
26#include "llvm/Support/MemoryBuffer.h"
27#include "llvm/Support/SourceMgr.h"
28#include "llvm/Support/SwapByteOrder.h"
29#include "llvm/Support/YAMLTraits.h"
30#include "llvm/Support/raw_ostream.h"
31#include <algorithm>
32#include <cassert>
33#include <cstddef>
34#include <cstdint>
35#include <memory>
36#include <string>
37#include <vector>
38
39using namespace llvm;
40
41template <typename T>
42static void writeInteger(T Integer, raw_ostream &OS, bool IsLittleEndian) {
43 if (IsLittleEndian != sys::IsLittleEndianHost)
44 sys::swapByteOrder(Integer);
45 OS.write(reinterpret_cast<char *>(&Integer), sizeof(T));
46}
47
48static Error writeVariableSizedInteger(uint64_t Integer, size_t Size,
49 raw_ostream &OS, bool IsLittleEndian) {
50 if (8 == Size)
51 writeInteger((uint64_t)Integer, OS, IsLittleEndian);
52 else if (4 == Size)
53 writeInteger((uint32_t)Integer, OS, IsLittleEndian);
54 else if (2 == Size)
55 writeInteger((uint16_t)Integer, OS, IsLittleEndian);
56 else if (1 == Size)
57 writeInteger((uint8_t)Integer, OS, IsLittleEndian);
58 else
59 return createStringError(errc::not_supported,
60 "invalid integer write size: %zu", Size);
61
62 return Error::success();
63}
64
65static void ZeroFillBytes(raw_ostream &OS, size_t Size) {
66 std::vector<uint8_t> FillData;
67 FillData.insert(FillData.begin(), Size, 0);
68 OS.write(reinterpret_cast<char *>(FillData.data()), Size);
69}
70
71static void writeInitialLength(const dwarf::DwarfFormat Format,
72 const uint64_t Length, raw_ostream &OS,
73 bool IsLittleEndian) {
74 bool IsDWARF64 = Format == dwarf::DWARF64;
75 if (IsDWARF64)
76 cantFail(writeVariableSizedInteger(dwarf::DW_LENGTH_DWARF64, 4, OS,
77 IsLittleEndian));
78 cantFail(
79 writeVariableSizedInteger(Length, IsDWARF64 ? 8 : 4, OS, IsLittleEndian));
80}
81
82static void writeDWARFOffset(uint64_t Offset, dwarf::DwarfFormat Format,
83 raw_ostream &OS, bool IsLittleEndian) {
84 cantFail(writeVariableSizedInteger(Offset, Format == dwarf::DWARF64 ? 8 : 4,
85 OS, IsLittleEndian));
86}
87
88Error DWARFYAML::emitDebugStr(raw_ostream &OS, const DWARFYAML::Data &DI) {
89 for (StringRef Str : *DI.DebugStrings) {
90 OS.write(Str.data(), Str.size());
91 OS.write('\0');
92 }
93
94 return Error::success();
95}
96
97StringRef DWARFYAML::Data::getAbbrevTableContentByIndex(uint64_t Index) const {
98 assert(Index < DebugAbbrev.size() &&((Index < DebugAbbrev.size() && "Index should be less than the size of DebugAbbrev array"
) ? static_cast<void> (0) : __assert_fail ("Index < DebugAbbrev.size() && \"Index should be less than the size of DebugAbbrev array\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/lib/ObjectYAML/DWARFEmitter.cpp"
, 99, __PRETTY_FUNCTION__))
99 "Index should be less than the size of DebugAbbrev array")((Index < DebugAbbrev.size() && "Index should be less than the size of DebugAbbrev array"
) ? static_cast<void> (0) : __assert_fail ("Index < DebugAbbrev.size() && \"Index should be less than the size of DebugAbbrev array\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/lib/ObjectYAML/DWARFEmitter.cpp"
, 99, __PRETTY_FUNCTION__))
;
100 auto It = AbbrevTableContents.find(Index);
101 if (It != AbbrevTableContents.cend())
102 return It->second;
103
104 std::string AbbrevTableBuffer;
105 raw_string_ostream OS(AbbrevTableBuffer);
106
107 uint64_t AbbrevCode = 0;
108 for (const DWARFYAML::Abbrev &AbbrevDecl : DebugAbbrev[Index].Table) {
109 AbbrevCode = AbbrevDecl.Code ? (uint64_t)*AbbrevDecl.Code : AbbrevCode + 1;
110 encodeULEB128(AbbrevCode, OS);
111 encodeULEB128(AbbrevDecl.Tag, OS);
112 OS.write(AbbrevDecl.Children);
113 for (auto Attr : AbbrevDecl.Attributes) {
114 encodeULEB128(Attr.Attribute, OS);
115 encodeULEB128(Attr.Form, OS);
116 if (Attr.Form == dwarf::DW_FORM_implicit_const)
117 encodeSLEB128(Attr.Value, OS);
118 }
119 encodeULEB128(0, OS);
120 encodeULEB128(0, OS);
121 }
122
123 // The abbreviations for a given compilation unit end with an entry
124 // consisting of a 0 byte for the abbreviation code.
125 OS.write_zeros(1);
126
127 AbbrevTableContents.insert({Index, AbbrevTableBuffer});
128
129 return AbbrevTableContents[Index];
130}
131
132Error DWARFYAML::emitDebugAbbrev(raw_ostream &OS, const DWARFYAML::Data &DI) {
133 for (uint64_t I = 0; I < DI.DebugAbbrev.size(); ++I) {
134 StringRef AbbrevTableContent = DI.getAbbrevTableContentByIndex(I);
135 OS.write(AbbrevTableContent.data(), AbbrevTableContent.size());
136 }
137
138 return Error::success();
139}
140
141Error DWARFYAML::emitDebugAranges(raw_ostream &OS, const DWARFYAML::Data &DI) {
142 assert(DI.DebugAranges && "unexpected emitDebugAranges() call")((DI.DebugAranges && "unexpected emitDebugAranges() call"
) ? static_cast<void> (0) : __assert_fail ("DI.DebugAranges && \"unexpected emitDebugAranges() call\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/lib/ObjectYAML/DWARFEmitter.cpp"
, 142, __PRETTY_FUNCTION__))
;
143 for (auto Range : *DI.DebugAranges) {
144 uint8_t AddrSize;
145 if (Range.AddrSize)
146 AddrSize = *Range.AddrSize;
147 else
148 AddrSize = DI.Is64BitAddrSize ? 8 : 4;
149
150 uint64_t Length = 4; // sizeof(version) 2 + sizeof(address_size) 1 +
151 // sizeof(segment_selector_size) 1
152 Length +=
153 Range.Format == dwarf::DWARF64 ? 8 : 4; // sizeof(debug_info_offset)
154
155 const uint64_t HeaderLength =
156 Length + (Range.Format == dwarf::DWARF64
157 ? 12
158 : 4); // sizeof(unit_header) = 12 (DWARF64) or 4 (DWARF32)
159 const uint64_t PaddedHeaderLength = alignTo(HeaderLength, AddrSize * 2);
160
161 if (Range.Length) {
162 Length = *Range.Length;
163 } else {
164 Length += PaddedHeaderLength - HeaderLength;
165 Length += AddrSize * 2 * (Range.Descriptors.size() + 1);
166 }
167
168 writeInitialLength(Range.Format, Length, OS, DI.IsLittleEndian);
169 writeInteger((uint16_t)Range.Version, OS, DI.IsLittleEndian);
170 writeDWARFOffset(Range.CuOffset, Range.Format, OS, DI.IsLittleEndian);
171 writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
172 writeInteger((uint8_t)Range.SegSize, OS, DI.IsLittleEndian);
173 ZeroFillBytes(OS, PaddedHeaderLength - HeaderLength);
174
175 for (auto Descriptor : Range.Descriptors) {
176 if (Error Err = writeVariableSizedInteger(Descriptor.Address, AddrSize,
177 OS, DI.IsLittleEndian))
178 return createStringError(errc::not_supported,
179 "unable to write debug_aranges address: %s",
180 toString(std::move(Err)).c_str());
181 cantFail(writeVariableSizedInteger(Descriptor.Length, AddrSize, OS,
182 DI.IsLittleEndian));
183 }
184 ZeroFillBytes(OS, AddrSize * 2);
185 }
186
187 return Error::success();
188}
189
190Error DWARFYAML::emitDebugRanges(raw_ostream &OS, const DWARFYAML::Data &DI) {
191 const size_t RangesOffset = OS.tell();
192 uint64_t EntryIndex = 0;
193 for (auto DebugRanges : *DI.DebugRanges) {
194 const size_t CurrOffset = OS.tell() - RangesOffset;
195 if (DebugRanges.Offset && (uint64_t)*DebugRanges.Offset < CurrOffset)
196 return createStringError(errc::invalid_argument,
197 "'Offset' for 'debug_ranges' with index " +
198 Twine(EntryIndex) +
199 " must be greater than or equal to the "
200 "number of bytes written already (0x" +
201 Twine::utohexstr(CurrOffset) + ")");
202 if (DebugRanges.Offset)
203 ZeroFillBytes(OS, *DebugRanges.Offset - CurrOffset);
204
205 uint8_t AddrSize;
206 if (DebugRanges.AddrSize)
207 AddrSize = *DebugRanges.AddrSize;
208 else
209 AddrSize = DI.Is64BitAddrSize ? 8 : 4;
210 for (auto Entry : DebugRanges.Entries) {
211 if (Error Err = writeVariableSizedInteger(Entry.LowOffset, AddrSize, OS,
212 DI.IsLittleEndian))
213 return createStringError(
214 errc::not_supported,
215 "unable to write debug_ranges address offset: %s",
216 toString(std::move(Err)).c_str());
217 cantFail(writeVariableSizedInteger(Entry.HighOffset, AddrSize, OS,
218 DI.IsLittleEndian));
219 }
220 ZeroFillBytes(OS, AddrSize * 2);
221 ++EntryIndex;
222 }
223
224 return Error::success();
225}
226
227static Error emitPubSection(raw_ostream &OS, const DWARFYAML::PubSection &Sect,
228 bool IsLittleEndian, bool IsGNUPubSec = false) {
229 writeInitialLength(Sect.Format, Sect.Length, OS, IsLittleEndian);
230 writeInteger((uint16_t)Sect.Version, OS, IsLittleEndian);
231 writeInteger((uint32_t)Sect.UnitOffset, OS, IsLittleEndian);
232 writeInteger((uint32_t)Sect.UnitSize, OS, IsLittleEndian);
233 for (auto Entry : Sect.Entries) {
234 writeInteger((uint32_t)Entry.DieOffset, OS, IsLittleEndian);
235 if (IsGNUPubSec)
236 writeInteger((uint8_t)Entry.Descriptor, OS, IsLittleEndian);
237 OS.write(Entry.Name.data(), Entry.Name.size());
238 OS.write('\0');
239 }
240
241 return Error::success();
242}
243
244Error DWARFYAML::emitDebugPubnames(raw_ostream &OS, const Data &DI) {
245 assert(DI.PubNames && "unexpected emitDebugPubnames() call")((DI.PubNames && "unexpected emitDebugPubnames() call"
) ? static_cast<void> (0) : __assert_fail ("DI.PubNames && \"unexpected emitDebugPubnames() call\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/lib/ObjectYAML/DWARFEmitter.cpp"
, 245, __PRETTY_FUNCTION__))
;
246 return emitPubSection(OS, *DI.PubNames, DI.IsLittleEndian);
247}
248
249Error DWARFYAML::emitDebugPubtypes(raw_ostream &OS, const Data &DI) {
250 assert(DI.PubTypes && "unexpected emitDebugPubtypes() call")((DI.PubTypes && "unexpected emitDebugPubtypes() call"
) ? static_cast<void> (0) : __assert_fail ("DI.PubTypes && \"unexpected emitDebugPubtypes() call\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/lib/ObjectYAML/DWARFEmitter.cpp"
, 250, __PRETTY_FUNCTION__))
;
251 return emitPubSection(OS, *DI.PubTypes, DI.IsLittleEndian);
252}
253
254Error DWARFYAML::emitDebugGNUPubnames(raw_ostream &OS, const Data &DI) {
255 assert(DI.GNUPubNames && "unexpected emitDebugGNUPubnames() call")((DI.GNUPubNames && "unexpected emitDebugGNUPubnames() call"
) ? static_cast<void> (0) : __assert_fail ("DI.GNUPubNames && \"unexpected emitDebugGNUPubnames() call\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/lib/ObjectYAML/DWARFEmitter.cpp"
, 255, __PRETTY_FUNCTION__))
;
256 return emitPubSection(OS, *DI.GNUPubNames, DI.IsLittleEndian,
257 /*IsGNUStyle=*/true);
258}
259
260Error DWARFYAML::emitDebugGNUPubtypes(raw_ostream &OS, const Data &DI) {
261 assert(DI.GNUPubTypes && "unexpected emitDebugGNUPubtypes() call")((DI.GNUPubTypes && "unexpected emitDebugGNUPubtypes() call"
) ? static_cast<void> (0) : __assert_fail ("DI.GNUPubTypes && \"unexpected emitDebugGNUPubtypes() call\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/lib/ObjectYAML/DWARFEmitter.cpp"
, 261, __PRETTY_FUNCTION__))
;
262 return emitPubSection(OS, *DI.GNUPubTypes, DI.IsLittleEndian,
263 /*IsGNUStyle=*/true);
264}
265
266static Expected<uint64_t> writeDIE(const DWARFYAML::Data &DI, uint64_t CUIndex,
267 uint64_t AbbrevTableID,
268 const dwarf::FormParams &Params,
269 const DWARFYAML::Entry &Entry,
270 raw_ostream &OS, bool IsLittleEndian) {
271 uint64_t EntryBegin = OS.tell();
272 encodeULEB128(Entry.AbbrCode, OS);
273 uint32_t AbbrCode = Entry.AbbrCode;
274 if (AbbrCode == 0 || Entry.Values.empty())
275 return OS.tell() - EntryBegin;
276
277 Expected<DWARFYAML::Data::AbbrevTableInfo> AbbrevTableInfoOrErr =
278 DI.getAbbrevTableInfoByID(AbbrevTableID);
279 if (!AbbrevTableInfoOrErr)
280 return createStringError(errc::invalid_argument,
281 toString(AbbrevTableInfoOrErr.takeError()) +
282 " for compilation unit with index " +
283 utostr(CUIndex));
284
285 ArrayRef<DWARFYAML::Abbrev> AbbrevDecls(
286 DI.DebugAbbrev[AbbrevTableInfoOrErr->Index].Table);
287
288 if (AbbrCode > AbbrevDecls.size())
289 return createStringError(
290 errc::invalid_argument,
291 "abbrev code must be less than or equal to the number of "
292 "entries in abbreviation table");
293 const DWARFYAML::Abbrev &Abbrev = AbbrevDecls[AbbrCode - 1];
294 auto FormVal = Entry.Values.begin();
295 auto AbbrForm = Abbrev.Attributes.begin();
296 for (; FormVal != Entry.Values.end() && AbbrForm != Abbrev.Attributes.end();
297 ++FormVal, ++AbbrForm) {
298 dwarf::Form Form = AbbrForm->Form;
299 bool Indirect;
300 do {
301 Indirect = false;
302 switch (Form) {
303 case dwarf::DW_FORM_addr:
304 // TODO: Test this error.
305 if (Error Err = writeVariableSizedInteger(
306 FormVal->Value, Params.AddrSize, OS, IsLittleEndian))
307 return std::move(Err);
308 break;
309 case dwarf::DW_FORM_ref_addr:
310 // TODO: Test this error.
311 if (Error Err = writeVariableSizedInteger(FormVal->Value,
312 Params.getRefAddrByteSize(),
313 OS, IsLittleEndian))
314 return std::move(Err);
315 break;
316 case dwarf::DW_FORM_exprloc:
317 case dwarf::DW_FORM_block:
318 encodeULEB128(FormVal->BlockData.size(), OS);
319 OS.write((const char *)FormVal->BlockData.data(),
320 FormVal->BlockData.size());
321 break;
322 case dwarf::DW_FORM_block1: {
323 writeInteger((uint8_t)FormVal->BlockData.size(), OS, IsLittleEndian);
324 OS.write((const char *)FormVal->BlockData.data(),
325 FormVal->BlockData.size());
326 break;
327 }
328 case dwarf::DW_FORM_block2: {
329 writeInteger((uint16_t)FormVal->BlockData.size(), OS, IsLittleEndian);
330 OS.write((const char *)FormVal->BlockData.data(),
331 FormVal->BlockData.size());
332 break;
333 }
334 case dwarf::DW_FORM_block4: {
335 writeInteger((uint32_t)FormVal->BlockData.size(), OS, IsLittleEndian);
336 OS.write((const char *)FormVal->BlockData.data(),
337 FormVal->BlockData.size());
338 break;
339 }
340 case dwarf::DW_FORM_strx:
341 case dwarf::DW_FORM_addrx:
342 case dwarf::DW_FORM_rnglistx:
343 case dwarf::DW_FORM_loclistx:
344 case dwarf::DW_FORM_udata:
345 case dwarf::DW_FORM_ref_udata:
346 case dwarf::DW_FORM_GNU_addr_index:
347 case dwarf::DW_FORM_GNU_str_index:
348 encodeULEB128(FormVal->Value, OS);
349 break;
350 case dwarf::DW_FORM_data1:
351 case dwarf::DW_FORM_ref1:
352 case dwarf::DW_FORM_flag:
353 case dwarf::DW_FORM_strx1:
354 case dwarf::DW_FORM_addrx1:
355 writeInteger((uint8_t)FormVal->Value, OS, IsLittleEndian);
356 break;
357 case dwarf::DW_FORM_data2:
358 case dwarf::DW_FORM_ref2:
359 case dwarf::DW_FORM_strx2:
360 case dwarf::DW_FORM_addrx2:
361 writeInteger((uint16_t)FormVal->Value, OS, IsLittleEndian);
362 break;
363 case dwarf::DW_FORM_data4:
364 case dwarf::DW_FORM_ref4:
365 case dwarf::DW_FORM_ref_sup4:
366 case dwarf::DW_FORM_strx4:
367 case dwarf::DW_FORM_addrx4:
368 writeInteger((uint32_t)FormVal->Value, OS, IsLittleEndian);
369 break;
370 case dwarf::DW_FORM_data8:
371 case dwarf::DW_FORM_ref8:
372 case dwarf::DW_FORM_ref_sup8:
373 case dwarf::DW_FORM_ref_sig8:
374 writeInteger((uint64_t)FormVal->Value, OS, IsLittleEndian);
375 break;
376 case dwarf::DW_FORM_sdata:
377 encodeSLEB128(FormVal->Value, OS);
378 break;
379 case dwarf::DW_FORM_string:
380 OS.write(FormVal->CStr.data(), FormVal->CStr.size());
381 OS.write('\0');
382 break;
383 case dwarf::DW_FORM_indirect:
384 encodeULEB128(FormVal->Value, OS);
385 Indirect = true;
386 Form = static_cast<dwarf::Form>((uint64_t)FormVal->Value);
387 ++FormVal;
388 break;
389 case dwarf::DW_FORM_strp:
390 case dwarf::DW_FORM_sec_offset:
391 case dwarf::DW_FORM_GNU_ref_alt:
392 case dwarf::DW_FORM_GNU_strp_alt:
393 case dwarf::DW_FORM_line_strp:
394 case dwarf::DW_FORM_strp_sup:
395 cantFail(writeVariableSizedInteger(FormVal->Value,
396 Params.getDwarfOffsetByteSize(), OS,
397 IsLittleEndian));
398 break;
399 default:
400 break;
401 }
402 } while (Indirect);
403 }
404
405 return OS.tell() - EntryBegin;
406}
407
408Error DWARFYAML::emitDebugInfo(raw_ostream &OS, const DWARFYAML::Data &DI) {
409 for (uint64_t I = 0; I < DI.CompileUnits.size(); ++I) {
410 const DWARFYAML::Unit &Unit = DI.CompileUnits[I];
411 uint8_t AddrSize;
412 if (Unit.AddrSize)
413 AddrSize = *Unit.AddrSize;
414 else
415 AddrSize = DI.Is64BitAddrSize ? 8 : 4;
416 dwarf::FormParams Params = {Unit.Version, AddrSize, Unit.Format};
417 uint64_t Length = 3; // sizeof(version) + sizeof(address_size)
418 Length += Unit.Version >= 5 ? 1 : 0; // sizeof(unit_type)
419 Length += Params.getDwarfOffsetByteSize(); // sizeof(debug_abbrev_offset)
420
421 // Since the length of the current compilation unit is undetermined yet, we
422 // firstly write the content of the compilation unit to a buffer to
423 // calculate it and then serialize the buffer content to the actual output
424 // stream.
425 std::string EntryBuffer;
426 raw_string_ostream EntryBufferOS(EntryBuffer);
427
428 uint64_t AbbrevTableID = Unit.AbbrevTableID.getValueOr(I);
429 for (const DWARFYAML::Entry &Entry : Unit.Entries) {
430 if (Expected<uint64_t> EntryLength =
431 writeDIE(DI, I, AbbrevTableID, Params, Entry, EntryBufferOS,
432 DI.IsLittleEndian))
433 Length += *EntryLength;
434 else
435 return EntryLength.takeError();
436 }
437
438 // If the length is specified in the YAML description, we use it instead of
439 // the actual length.
440 if (Unit.Length)
441 Length = *Unit.Length;
442
443 writeInitialLength(Unit.Format, Length, OS, DI.IsLittleEndian);
444 writeInteger((uint16_t)Unit.Version, OS, DI.IsLittleEndian);
445
446 uint64_t AbbrevTableOffset = 0;
447 if (Unit.AbbrOffset) {
448 AbbrevTableOffset = *Unit.AbbrOffset;
449 } else {
450 if (Expected<DWARFYAML::Data::AbbrevTableInfo> AbbrevTableInfoOrErr =
451 DI.getAbbrevTableInfoByID(AbbrevTableID)) {
452 AbbrevTableOffset = AbbrevTableInfoOrErr->Offset;
453 } else {
454 // The current compilation unit may not have DIEs and it will not be
455 // able to find the associated abbrev table. We consume the error and
456 // assign 0 to the debug_abbrev_offset in such circumstances.
457 consumeError(AbbrevTableInfoOrErr.takeError());
458 }
459 }
460
461 if (Unit.Version >= 5) {
462 writeInteger((uint8_t)Unit.Type, OS, DI.IsLittleEndian);
463 writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
464 writeDWARFOffset(AbbrevTableOffset, Unit.Format, OS, DI.IsLittleEndian);
465 } else {
466 writeDWARFOffset(AbbrevTableOffset, Unit.Format, OS, DI.IsLittleEndian);
467 writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
468 }
469
470 OS.write(EntryBuffer.data(), EntryBuffer.size());
471 }
472
473 return Error::success();
474}
475
476static void emitFileEntry(raw_ostream &OS, const DWARFYAML::File &File) {
477 OS.write(File.Name.data(), File.Name.size());
478 OS.write('\0');
479 encodeULEB128(File.DirIdx, OS);
480 encodeULEB128(File.ModTime, OS);
481 encodeULEB128(File.Length, OS);
482}
483
484static void writeLineTableOpcode(const DWARFYAML::LineTableOpcode &Op,
485 uint8_t OpcodeBase, uint8_t AddrSize,
486 raw_ostream &OS, bool IsLittleEndian) {
487 writeInteger((uint8_t)Op.Opcode, OS, IsLittleEndian);
488 if (Op.Opcode == 0) {
489 encodeULEB128(Op.ExtLen, OS);
490 writeInteger((uint8_t)Op.SubOpcode, OS, IsLittleEndian);
491 switch (Op.SubOpcode) {
492 case dwarf::DW_LNE_set_address:
493 cantFail(
494 writeVariableSizedInteger(Op.Data, AddrSize, OS, IsLittleEndian));
495 break;
496 case dwarf::DW_LNE_define_file:
497 emitFileEntry(OS, Op.FileEntry);
498 break;
499 case dwarf::DW_LNE_set_discriminator:
500 encodeULEB128(Op.Data, OS);
501 break;
502 case dwarf::DW_LNE_end_sequence:
503 break;
504 default:
505 for (auto OpByte : Op.UnknownOpcodeData)
506 writeInteger((uint8_t)OpByte, OS, IsLittleEndian);
507 }
508 } else if (Op.Opcode < OpcodeBase) {
509 switch (Op.Opcode) {
510 case dwarf::DW_LNS_copy:
511 case dwarf::DW_LNS_negate_stmt:
512 case dwarf::DW_LNS_set_basic_block:
513 case dwarf::DW_LNS_const_add_pc:
514 case dwarf::DW_LNS_set_prologue_end:
515 case dwarf::DW_LNS_set_epilogue_begin:
516 break;
517
518 case dwarf::DW_LNS_advance_pc:
519 case dwarf::DW_LNS_set_file:
520 case dwarf::DW_LNS_set_column:
521 case dwarf::DW_LNS_set_isa:
522 encodeULEB128(Op.Data, OS);
523 break;
524
525 case dwarf::DW_LNS_advance_line:
526 encodeSLEB128(Op.SData, OS);
527 break;
528
529 case dwarf::DW_LNS_fixed_advance_pc:
530 writeInteger((uint16_t)Op.Data, OS, IsLittleEndian);
531 break;
532
533 default:
534 for (auto OpData : Op.StandardOpcodeData) {
535 encodeULEB128(OpData, OS);
536 }
537 }
538 }
539}
540
541Error DWARFYAML::emitDebugLine(raw_ostream &OS, const DWARFYAML::Data &DI) {
542 for (const DWARFYAML::LineTable &LineTable : DI.DebugLines) {
543 // Buffer holds the bytes following the header_length (or prologue_length in
544 // DWARFv2) field to the end of the line number program itself.
545 std::string Buffer;
546 raw_string_ostream BufferOS(Buffer);
547
548 writeInteger(LineTable.MinInstLength, BufferOS, DI.IsLittleEndian);
549 // TODO: Add support for emitting DWARFv5 line table.
550 if (LineTable.Version >= 4)
551 writeInteger(LineTable.MaxOpsPerInst, BufferOS, DI.IsLittleEndian);
552 writeInteger(LineTable.DefaultIsStmt, BufferOS, DI.IsLittleEndian);
553 writeInteger(LineTable.LineBase, BufferOS, DI.IsLittleEndian);
554 writeInteger(LineTable.LineRange, BufferOS, DI.IsLittleEndian);
555 writeInteger(LineTable.OpcodeBase, BufferOS, DI.IsLittleEndian);
556
557 for (uint8_t OpcodeLength : LineTable.StandardOpcodeLengths)
558 writeInteger(OpcodeLength, BufferOS, DI.IsLittleEndian);
559
560 for (StringRef IncludeDir : LineTable.IncludeDirs) {
561 BufferOS.write(IncludeDir.data(), IncludeDir.size());
562 BufferOS.write('\0');
563 }
564 BufferOS.write('\0');
565
566 for (const DWARFYAML::File &File : LineTable.Files)
567 emitFileEntry(BufferOS, File);
568 BufferOS.write('\0');
569
570 uint64_t HeaderLength =
571 LineTable.PrologueLength ? *LineTable.PrologueLength : Buffer.size();
572
573 for (const DWARFYAML::LineTableOpcode &Op : LineTable.Opcodes)
574 writeLineTableOpcode(Op, LineTable.OpcodeBase, DI.Is64BitAddrSize ? 8 : 4,
575 BufferOS, DI.IsLittleEndian);
576
577 uint64_t Length;
578 if (LineTable.Length) {
579 Length = *LineTable.Length;
580 } else {
581 Length = 2; // sizeof(version)
582 Length +=
583 (LineTable.Format == dwarf::DWARF64 ? 8 : 4); // sizeof(header_length)
584 Length += Buffer.size();
585 }
586
587 writeInitialLength(LineTable.Format, Length, OS, DI.IsLittleEndian);
588 writeInteger(LineTable.Version, OS, DI.IsLittleEndian);
589 writeDWARFOffset(HeaderLength, LineTable.Format, OS, DI.IsLittleEndian);
590 OS.write(Buffer.data(), Buffer.size());
591 }
592
593 return Error::success();
594}
595
596Error DWARFYAML::emitDebugAddr(raw_ostream &OS, const Data &DI) {
597 for (const AddrTableEntry &TableEntry : *DI.DebugAddr) {
598 uint8_t AddrSize;
599 if (TableEntry.AddrSize)
600 AddrSize = *TableEntry.AddrSize;
601 else
602 AddrSize = DI.Is64BitAddrSize ? 8 : 4;
603
604 uint64_t Length;
605 if (TableEntry.Length)
606 Length = (uint64_t)*TableEntry.Length;
607 else
608 // 2 (version) + 1 (address_size) + 1 (segment_selector_size) = 4
609 Length = 4 + (AddrSize + TableEntry.SegSelectorSize) *
610 TableEntry.SegAddrPairs.size();
611
612 writeInitialLength(TableEntry.Format, Length, OS, DI.IsLittleEndian);
613 writeInteger((uint16_t)TableEntry.Version, OS, DI.IsLittleEndian);
614 writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
615 writeInteger((uint8_t)TableEntry.SegSelectorSize, OS, DI.IsLittleEndian);
616
617 for (const SegAddrPair &Pair : TableEntry.SegAddrPairs) {
618 if (TableEntry.SegSelectorSize != 0)
619 if (Error Err = writeVariableSizedInteger(Pair.Segment,
620 TableEntry.SegSelectorSize,
621 OS, DI.IsLittleEndian))
622 return createStringError(errc::not_supported,
623 "unable to write debug_addr segment: %s",
624 toString(std::move(Err)).c_str());
625 if (AddrSize != 0)
626 if (Error Err = writeVariableSizedInteger(Pair.Address, AddrSize, OS,
627 DI.IsLittleEndian))
628 return createStringError(errc::not_supported,
629 "unable to write debug_addr address: %s",
630 toString(std::move(Err)).c_str());
631 }
632 }
633
634 return Error::success();
635}
636
637Error DWARFYAML::emitDebugStrOffsets(raw_ostream &OS, const Data &DI) {
638 assert(DI.DebugStrOffsets && "unexpected emitDebugStrOffsets() call")((DI.DebugStrOffsets && "unexpected emitDebugStrOffsets() call"
) ? static_cast<void> (0) : __assert_fail ("DI.DebugStrOffsets && \"unexpected emitDebugStrOffsets() call\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/lib/ObjectYAML/DWARFEmitter.cpp"
, 638, __PRETTY_FUNCTION__))
;
639 for (const DWARFYAML::StringOffsetsTable &Table : *DI.DebugStrOffsets) {
640 uint64_t Length;
641 if (Table.Length)
642 Length = *Table.Length;
643 else
644 // sizeof(version) + sizeof(padding) = 4
645 Length =
646 4 + Table.Offsets.size() * (Table.Format == dwarf::DWARF64 ? 8 : 4);
647
648 writeInitialLength(Table.Format, Length, OS, DI.IsLittleEndian);
649 writeInteger((uint16_t)Table.Version, OS, DI.IsLittleEndian);
650 writeInteger((uint16_t)Table.Padding, OS, DI.IsLittleEndian);
651
652 for (uint64_t Offset : Table.Offsets)
653 writeDWARFOffset(Offset, Table.Format, OS, DI.IsLittleEndian);
654 }
655
656 return Error::success();
657}
658
659static Error checkOperandCount(StringRef EncodingString,
660 ArrayRef<yaml::Hex64> Values,
661 uint64_t ExpectedOperands) {
662 if (Values.size() != ExpectedOperands)
663 return createStringError(
664 errc::invalid_argument,
665 "invalid number (%zu) of operands for the operator: %s, %" PRIu64"l" "u"
666 " expected",
667 Values.size(), EncodingString.str().c_str(), ExpectedOperands);
668
669 return Error::success();
670}
671
672static Error writeListEntryAddress(StringRef EncodingName, raw_ostream &OS,
673 uint64_t Addr, uint8_t AddrSize,
674 bool IsLittleEndian) {
675 if (Error Err = writeVariableSizedInteger(Addr, AddrSize, OS, IsLittleEndian))
676 return createStringError(errc::invalid_argument,
677 "unable to write address for the operator %s: %s",
678 EncodingName.str().c_str(),
679 toString(std::move(Err)).c_str());
680
681 return Error::success();
682}
683
684static Expected<uint64_t>
685writeDWARFExpression(raw_ostream &OS,
686 const DWARFYAML::DWARFOperation &Operation,
687 uint8_t AddrSize, bool IsLittleEndian) {
688 auto CheckOperands = [&](uint64_t ExpectedOperands) -> Error {
689 return checkOperandCount(dwarf::OperationEncodingString(Operation.Operator),
690 Operation.Values, ExpectedOperands);
691 };
692
693 uint64_t ExpressionBegin = OS.tell();
694 writeInteger((uint8_t)Operation.Operator, OS, IsLittleEndian);
695 switch (Operation.Operator) {
696 case dwarf::DW_OP_consts:
697 if (Error Err = CheckOperands(1))
698 return std::move(Err);
699 encodeSLEB128(Operation.Values[0], OS);
700 break;
701 case dwarf::DW_OP_stack_value:
702 if (Error Err = CheckOperands(0))
703 return std::move(Err);
704 break;
705 default:
706 StringRef EncodingStr = dwarf::OperationEncodingString(Operation.Operator);
707 return createStringError(errc::not_supported,
708 "DWARF expression: " +
709 (EncodingStr.empty()
710 ? "0x" + utohexstr(Operation.Operator)
711 : EncodingStr) +
712 " is not supported");
713 }
714 return OS.tell() - ExpressionBegin;
715}
716
717static Expected<uint64_t> writeListEntry(raw_ostream &OS,
718 const DWARFYAML::RnglistEntry &Entry,
719 uint8_t AddrSize,
720 bool IsLittleEndian) {
721 uint64_t BeginOffset = OS.tell();
722 writeInteger((uint8_t)Entry.Operator, OS, IsLittleEndian);
723
724 StringRef EncodingName = dwarf::RangeListEncodingString(Entry.Operator);
725
726 auto CheckOperands = [&](uint64_t ExpectedOperands) -> Error {
727 return checkOperandCount(EncodingName, Entry.Values, ExpectedOperands);
728 };
729
730 auto WriteAddress = [&](uint64_t Addr) -> Error {
731 return writeListEntryAddress(EncodingName, OS, Addr, AddrSize,
732 IsLittleEndian);
733 };
734
735 switch (Entry.Operator) {
736 case dwarf::DW_RLE_end_of_list:
737 if (Error Err = CheckOperands(0))
738 return std::move(Err);
739 break;
740 case dwarf::DW_RLE_base_addressx:
741 if (Error Err = CheckOperands(1))
742 return std::move(Err);
743 encodeULEB128(Entry.Values[0], OS);
744 break;
745 case dwarf::DW_RLE_startx_endx:
746 case dwarf::DW_RLE_startx_length:
747 case dwarf::DW_RLE_offset_pair:
748 if (Error Err = CheckOperands(2))
749 return std::move(Err);
750 encodeULEB128(Entry.Values[0], OS);
751 encodeULEB128(Entry.Values[1], OS);
752 break;
753 case dwarf::DW_RLE_base_address:
754 if (Error Err = CheckOperands(1))
755 return std::move(Err);
756 if (Error Err = WriteAddress(Entry.Values[0]))
757 return std::move(Err);
758 break;
759 case dwarf::DW_RLE_start_end:
760 if (Error Err = CheckOperands(2))
761 return std::move(Err);
762 if (Error Err = WriteAddress(Entry.Values[0]))
763 return std::move(Err);
764 cantFail(WriteAddress(Entry.Values[1]));
765 break;
766 case dwarf::DW_RLE_start_length:
767 if (Error Err = CheckOperands(2))
768 return std::move(Err);
769 if (Error Err = WriteAddress(Entry.Values[0]))
770 return std::move(Err);
771 encodeULEB128(Entry.Values[1], OS);
772 break;
773 }
774
775 return OS.tell() - BeginOffset;
776}
777
778static Expected<uint64_t> writeListEntry(raw_ostream &OS,
779 const DWARFYAML::LoclistEntry &Entry,
780 uint8_t AddrSize,
781 bool IsLittleEndian) {
782 uint64_t BeginOffset = OS.tell();
783 writeInteger((uint8_t)Entry.Operator, OS, IsLittleEndian);
784
785 StringRef EncodingName = dwarf::LocListEncodingString(Entry.Operator);
786
787 auto CheckOperands = [&](uint64_t ExpectedOperands) -> Error {
788 return checkOperandCount(EncodingName, Entry.Values, ExpectedOperands);
789 };
790
791 auto WriteAddress = [&](uint64_t Addr) -> Error {
792 return writeListEntryAddress(EncodingName, OS, Addr, AddrSize,
793 IsLittleEndian);
794 };
795
796 auto WriteDWARFOperations = [&]() -> Error {
797 std::string OpBuffer;
798 raw_string_ostream OpBufferOS(OpBuffer);
799 uint64_t DescriptionsLength = 0;
800
801 for (const DWARFYAML::DWARFOperation &Op : Entry.Descriptions) {
802 if (Expected<uint64_t> OpSize =
803 writeDWARFExpression(OpBufferOS, Op, AddrSize, IsLittleEndian))
804 DescriptionsLength += *OpSize;
805 else
806 return OpSize.takeError();
807 }
808
809 if (Entry.DescriptionsLength)
810 DescriptionsLength = *Entry.DescriptionsLength;
811 else
812 DescriptionsLength = OpBuffer.size();
813
814 encodeULEB128(DescriptionsLength, OS);
815 OS.write(OpBuffer.data(), OpBuffer.size());
816
817 return Error::success();
818 };
819
820 switch (Entry.Operator) {
821 case dwarf::DW_LLE_end_of_list:
822 if (Error Err = CheckOperands(0))
823 return std::move(Err);
824 break;
825 case dwarf::DW_LLE_base_addressx:
826 if (Error Err = CheckOperands(1))
827 return std::move(Err);
828 encodeULEB128(Entry.Values[0], OS);
829 break;
830 case dwarf::DW_LLE_startx_endx:
831 case dwarf::DW_LLE_startx_length:
832 case dwarf::DW_LLE_offset_pair:
833 if (Error Err = CheckOperands(2))
834 return std::move(Err);
835 encodeULEB128(Entry.Values[0], OS);
836 encodeULEB128(Entry.Values[1], OS);
837 if (Error Err = WriteDWARFOperations())
838 return std::move(Err);
839 break;
840 case dwarf::DW_LLE_default_location:
841 if (Error Err = CheckOperands(0))
842 return std::move(Err);
843 if (Error Err = WriteDWARFOperations())
844 return std::move(Err);
845 break;
846 case dwarf::DW_LLE_base_address:
847 if (Error Err = CheckOperands(1))
848 return std::move(Err);
849 if (Error Err = WriteAddress(Entry.Values[0]))
850 return std::move(Err);
851 break;
852 case dwarf::DW_LLE_start_end:
853 if (Error Err = CheckOperands(2))
854 return std::move(Err);
855 if (Error Err = WriteAddress(Entry.Values[0]))
856 return std::move(Err);
857 cantFail(WriteAddress(Entry.Values[1]));
858 if (Error Err = WriteDWARFOperations())
859 return std::move(Err);
860 break;
861 case dwarf::DW_LLE_start_length:
862 if (Error Err = CheckOperands(2))
863 return std::move(Err);
864 if (Error Err = WriteAddress(Entry.Values[0]))
865 return std::move(Err);
866 encodeULEB128(Entry.Values[1], OS);
867 if (Error Err = WriteDWARFOperations())
868 return std::move(Err);
869 break;
870 }
871
872 return OS.tell() - BeginOffset;
873}
874
875template <typename EntryType>
876static Error writeDWARFLists(raw_ostream &OS,
877 ArrayRef<DWARFYAML::ListTable<EntryType>> Tables,
878 bool IsLittleEndian, bool Is64BitAddrSize) {
879 for (const DWARFYAML::ListTable<EntryType> &Table : Tables) {
880 // sizeof(version) + sizeof(address_size) + sizeof(segment_selector_size) +
881 // sizeof(offset_entry_count) = 8
882 uint64_t Length = 8;
883
884 uint8_t AddrSize;
885 if (Table.AddrSize)
886 AddrSize = *Table.AddrSize;
887 else
888 AddrSize = Is64BitAddrSize ? 8 : 4;
889
890 // Since the length of the current range/location lists entry is
891 // undetermined yet, we firstly write the content of the range/location
892 // lists to a buffer to calculate the length and then serialize the buffer
893 // content to the actual output stream.
894 std::string ListBuffer;
895 raw_string_ostream ListBufferOS(ListBuffer);
896
897 // Offsets holds offsets for each range/location list. The i-th element is
898 // the offset from the beginning of the first range/location list to the
899 // location of the i-th range list.
900 std::vector<uint64_t> Offsets;
901
902 for (const DWARFYAML::ListEntries<EntryType> &List : Table.Lists) {
903 Offsets.push_back(ListBufferOS.tell());
904 if (List.Content) {
905 List.Content->writeAsBinary(ListBufferOS, UINT64_MAX(18446744073709551615UL));
906 Length += List.Content->binary_size();
907 } else if (List.Entries) {
908 for (const EntryType &Entry : *List.Entries) {
909 Expected<uint64_t> EntrySize =
910 writeListEntry(ListBufferOS, Entry, AddrSize, IsLittleEndian);
911 if (!EntrySize)
912 return EntrySize.takeError();
913 Length += *EntrySize;
914 }
915 }
916 }
917
918 // If the offset_entry_count field isn't specified, yaml2obj will infer it
919 // from the 'Offsets' field in the YAML description. If the 'Offsets' field
920 // isn't specified either, yaml2obj will infer it from the auto-generated
921 // offsets.
922 uint32_t OffsetEntryCount;
923 if (Table.OffsetEntryCount)
924 OffsetEntryCount = *Table.OffsetEntryCount;
925 else
926 OffsetEntryCount = Table.Offsets ? Table.Offsets->size() : Offsets.size();
927 uint64_t OffsetsSize =
928 OffsetEntryCount * (Table.Format == dwarf::DWARF64 ? 8 : 4);
929 Length += OffsetsSize;
930
931 // If the length is specified in the YAML description, we use it instead of
932 // the actual length.
933 if (Table.Length)
934 Length = *Table.Length;
935
936 writeInitialLength(Table.Format, Length, OS, IsLittleEndian);
937 writeInteger((uint16_t)Table.Version, OS, IsLittleEndian);
938 writeInteger((uint8_t)AddrSize, OS, IsLittleEndian);
939 writeInteger((uint8_t)Table.SegSelectorSize, OS, IsLittleEndian);
940 writeInteger((uint32_t)OffsetEntryCount, OS, IsLittleEndian);
941
942 auto EmitOffsets = [&](ArrayRef<uint64_t> Offsets, uint64_t OffsetsSize) {
943 for (uint64_t Offset : Offsets)
944 writeDWARFOffset(OffsetsSize + Offset, Table.Format, OS,
945 IsLittleEndian);
946 };
947
948 if (Table.Offsets)
949 EmitOffsets(ArrayRef<uint64_t>((const uint64_t *)Table.Offsets->data(),
950 Table.Offsets->size()),
951 0);
952 else if (OffsetEntryCount != 0)
953 EmitOffsets(Offsets, OffsetsSize);
954
955 OS.write(ListBuffer.data(), ListBuffer.size());
956 }
957
958 return Error::success();
959}
960
961Error DWARFYAML::emitDebugRnglists(raw_ostream &OS, const Data &DI) {
962 assert(DI.DebugRnglists && "unexpected emitDebugRnglists() call")((DI.DebugRnglists && "unexpected emitDebugRnglists() call"
) ? static_cast<void> (0) : __assert_fail ("DI.DebugRnglists && \"unexpected emitDebugRnglists() call\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/lib/ObjectYAML/DWARFEmitter.cpp"
, 962, __PRETTY_FUNCTION__))
;
963 return writeDWARFLists<DWARFYAML::RnglistEntry>(
964 OS, *DI.DebugRnglists, DI.IsLittleEndian, DI.Is64BitAddrSize);
965}
966
967Error DWARFYAML::emitDebugLoclists(raw_ostream &OS, const Data &DI) {
968 assert(DI.DebugLoclists && "unexpected emitDebugRnglists() call")((DI.DebugLoclists && "unexpected emitDebugRnglists() call"
) ? static_cast<void> (0) : __assert_fail ("DI.DebugLoclists && \"unexpected emitDebugRnglists() call\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/lib/ObjectYAML/DWARFEmitter.cpp"
, 968, __PRETTY_FUNCTION__))
;
969 return writeDWARFLists<DWARFYAML::LoclistEntry>(
970 OS, *DI.DebugLoclists, DI.IsLittleEndian, DI.Is64BitAddrSize);
971}
972
973std::function<Error(raw_ostream &, const DWARFYAML::Data &)>
974DWARFYAML::getDWARFEmitterByName(StringRef SecName) {
975 auto EmitFunc =
976 StringSwitch<
977 std::function<Error(raw_ostream &, const DWARFYAML::Data &)>>(SecName)
978 .Case("debug_abbrev", DWARFYAML::emitDebugAbbrev)
979 .Case("debug_addr", DWARFYAML::emitDebugAddr)
980 .Case("debug_aranges", DWARFYAML::emitDebugAranges)
981 .Case("debug_gnu_pubnames", DWARFYAML::emitDebugGNUPubnames)
982 .Case("debug_gnu_pubtypes", DWARFYAML::emitDebugGNUPubtypes)
983 .Case("debug_info", DWARFYAML::emitDebugInfo)
984 .Case("debug_line", DWARFYAML::emitDebugLine)
985 .Case("debug_loclists", DWARFYAML::emitDebugLoclists)
986 .Case("debug_pubnames", DWARFYAML::emitDebugPubnames)
987 .Case("debug_pubtypes", DWARFYAML::emitDebugPubtypes)
988 .Case("debug_ranges", DWARFYAML::emitDebugRanges)
989 .Case("debug_rnglists", DWARFYAML::emitDebugRnglists)
990 .Case("debug_str", DWARFYAML::emitDebugStr)
991 .Case("debug_str_offsets", DWARFYAML::emitDebugStrOffsets)
992 .Default([&](raw_ostream &, const DWARFYAML::Data &) {
993 return createStringError(errc::not_supported,
994 SecName + " is not supported");
995 });
996
997 return EmitFunc;
998}
999
1000static Error
1001emitDebugSectionImpl(const DWARFYAML::Data &DI, StringRef Sec,
1002 StringMap<std::unique_ptr<MemoryBuffer>> &OutputBuffers) {
1003 std::string Data;
1004 raw_string_ostream DebugInfoStream(Data);
1005
1006 auto EmitFunc = DWARFYAML::getDWARFEmitterByName(Sec);
1007
1008 if (Error Err = EmitFunc(DebugInfoStream, DI))
1009 return Err;
1010 DebugInfoStream.flush();
1011 if (!Data.empty())
1012 OutputBuffers[Sec] = MemoryBuffer::getMemBufferCopy(Data);
1013
1014 return Error::success();
1015}
1016
1017Expected<StringMap<std::unique_ptr<MemoryBuffer>>>
1018DWARFYAML::emitDebugSections(StringRef YAMLString, bool IsLittleEndian,
1019 bool Is64BitAddrSize) {
1020 auto CollectDiagnostic = [](const SMDiagnostic &Diag, void *DiagContext) {
1021 *static_cast<SMDiagnostic *>(DiagContext) = Diag;
1022 };
1023
1024 SMDiagnostic GeneratedDiag;
1025 yaml::Input YIn(YAMLString, /*Ctxt=*/nullptr, CollectDiagnostic,
1026 &GeneratedDiag);
1027
1028 DWARFYAML::Data DI;
1029 DI.IsLittleEndian = IsLittleEndian;
1030 DI.Is64BitAddrSize = Is64BitAddrSize;
1031
1032 YIn >> DI;
1033 if (YIn.error())
1
Taking false branch
1034 return createStringError(YIn.error(), GeneratedDiag.getMessage());
1035
1036 StringMap<std::unique_ptr<MemoryBuffer>> DebugSections;
1037 Error Err = Error::success();
1038 cantFail(std::move(Err));
2
Calling move constructor for 'Error'
4
Returning from move constructor for 'Error'
1039
1040 for (StringRef SecName : DI.getNonEmptySectionNames())
1041 Err = joinErrors(std::move(Err),
5
Moved-from object 'Err' is moved
1042 emitDebugSectionImpl(DI, SecName, DebugSections));
1043
1044 if (Err)
1045 return std::move(Err);
1046 return std::move(DebugSections);
1047}

/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include/llvm/Support/Error.h

1//===- llvm/Support/Error.h - Recoverable error handling --------*- 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 defines an API used to report recoverable errors.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_SUPPORT_ERROR_H
14#define LLVM_SUPPORT_ERROR_H
15
16#include "llvm-c/Error.h"
17#include "llvm/ADT/STLExtras.h"
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/ADT/StringExtras.h"
20#include "llvm/ADT/Twine.h"
21#include "llvm/Config/abi-breaking.h"
22#include "llvm/Support/AlignOf.h"
23#include "llvm/Support/Compiler.h"
24#include "llvm/Support/Debug.h"
25#include "llvm/Support/ErrorHandling.h"
26#include "llvm/Support/ErrorOr.h"
27#include "llvm/Support/Format.h"
28#include "llvm/Support/raw_ostream.h"
29#include <algorithm>
30#include <cassert>
31#include <cstdint>
32#include <cstdlib>
33#include <functional>
34#include <memory>
35#include <new>
36#include <string>
37#include <system_error>
38#include <type_traits>
39#include <utility>
40#include <vector>
41
42namespace llvm {
43
44class ErrorSuccess;
45
46/// Base class for error info classes. Do not extend this directly: Extend
47/// the ErrorInfo template subclass instead.
48class ErrorInfoBase {
49public:
50 virtual ~ErrorInfoBase() = default;
51
52 /// Print an error message to an output stream.
53 virtual void log(raw_ostream &OS) const = 0;
54
55 /// Return the error message as a string.
56 virtual std::string message() const {
57 std::string Msg;
58 raw_string_ostream OS(Msg);
59 log(OS);
60 return OS.str();
61 }
62
63 /// Convert this error to a std::error_code.
64 ///
65 /// This is a temporary crutch to enable interaction with code still
66 /// using std::error_code. It will be removed in the future.
67 virtual std::error_code convertToErrorCode() const = 0;
68
69 // Returns the class ID for this type.
70 static const void *classID() { return &ID; }
71
72 // Returns the class ID for the dynamic type of this ErrorInfoBase instance.
73 virtual const void *dynamicClassID() const = 0;
74
75 // Check whether this instance is a subclass of the class identified by
76 // ClassID.
77 virtual bool isA(const void *const ClassID) const {
78 return ClassID == classID();
79 }
80
81 // Check whether this instance is a subclass of ErrorInfoT.
82 template <typename ErrorInfoT> bool isA() const {
83 return isA(ErrorInfoT::classID());
84 }
85
86private:
87 virtual void anchor();
88
89 static char ID;
90};
91
92/// Lightweight error class with error context and mandatory checking.
93///
94/// Instances of this class wrap a ErrorInfoBase pointer. Failure states
95/// are represented by setting the pointer to a ErrorInfoBase subclass
96/// instance containing information describing the failure. Success is
97/// represented by a null pointer value.
98///
99/// Instances of Error also contains a 'Checked' flag, which must be set
100/// before the destructor is called, otherwise the destructor will trigger a
101/// runtime error. This enforces at runtime the requirement that all Error
102/// instances be checked or returned to the caller.
103///
104/// There are two ways to set the checked flag, depending on what state the
105/// Error instance is in. For Error instances indicating success, it
106/// is sufficient to invoke the boolean conversion operator. E.g.:
107///
108/// @code{.cpp}
109/// Error foo(<...>);
110///
111/// if (auto E = foo(<...>))
112/// return E; // <- Return E if it is in the error state.
113/// // We have verified that E was in the success state. It can now be safely
114/// // destroyed.
115/// @endcode
116///
117/// A success value *can not* be dropped. For example, just calling 'foo(<...>)'
118/// without testing the return value will raise a runtime error, even if foo
119/// returns success.
120///
121/// For Error instances representing failure, you must use either the
122/// handleErrors or handleAllErrors function with a typed handler. E.g.:
123///
124/// @code{.cpp}
125/// class MyErrorInfo : public ErrorInfo<MyErrorInfo> {
126/// // Custom error info.
127/// };
128///
129/// Error foo(<...>) { return make_error<MyErrorInfo>(...); }
130///
131/// auto E = foo(<...>); // <- foo returns failure with MyErrorInfo.
132/// auto NewE =
133/// handleErrors(E,
134/// [](const MyErrorInfo &M) {
135/// // Deal with the error.
136/// },
137/// [](std::unique_ptr<OtherError> M) -> Error {
138/// if (canHandle(*M)) {
139/// // handle error.
140/// return Error::success();
141/// }
142/// // Couldn't handle this error instance. Pass it up the stack.
143/// return Error(std::move(M));
144/// );
145/// // Note - we must check or return NewE in case any of the handlers
146/// // returned a new error.
147/// @endcode
148///
149/// The handleAllErrors function is identical to handleErrors, except
150/// that it has a void return type, and requires all errors to be handled and
151/// no new errors be returned. It prevents errors (assuming they can all be
152/// handled) from having to be bubbled all the way to the top-level.
153///
154/// *All* Error instances must be checked before destruction, even if
155/// they're moved-assigned or constructed from Success values that have already
156/// been checked. This enforces checking through all levels of the call stack.
157class LLVM_NODISCARD[[clang::warn_unused_result]] Error {
158 // ErrorList needs to be able to yank ErrorInfoBase pointers out of Errors
159 // to add to the error list. It can't rely on handleErrors for this, since
160 // handleErrors does not support ErrorList handlers.
161 friend class ErrorList;
162
163 // handleErrors needs to be able to set the Checked flag.
164 template <typename... HandlerTs>
165 friend Error handleErrors(Error E, HandlerTs &&... Handlers);
166
167 // Expected<T> needs to be able to steal the payload when constructed from an
168 // error.
169 template <typename T> friend class Expected;
170
171 // wrap needs to be able to steal the payload.
172 friend LLVMErrorRef wrap(Error);
173
174protected:
175 /// Create a success value. Prefer using 'Error::success()' for readability
176 Error() {
177 setPtr(nullptr);
178 setChecked(false);
179 }
180
181public:
182 /// Create a success value.
183 static ErrorSuccess success();
184
185 // Errors are not copy-constructable.
186 Error(const Error &Other) = delete;
187
188 /// Move-construct an error value. The newly constructed error is considered
189 /// unchecked, even if the source error had been checked. The original error
190 /// becomes a checked Success value, regardless of its original state.
191 Error(Error &&Other) {
192 setChecked(true);
193 *this = std::move(Other);
3
Object 'Err' is moved
194 }
195
196 /// Create an error value. Prefer using the 'make_error' function, but
197 /// this constructor can be useful when "re-throwing" errors from handlers.
198 Error(std::unique_ptr<ErrorInfoBase> Payload) {
199 setPtr(Payload.release());
200 setChecked(false);
201 }
202
203 // Errors are not copy-assignable.
204 Error &operator=(const Error &Other) = delete;
205
206 /// Move-assign an error value. The current error must represent success, you
207 /// you cannot overwrite an unhandled error. The current error is then
208 /// considered unchecked. The source error becomes a checked success value,
209 /// regardless of its original state.
210 Error &operator=(Error &&Other) {
211 // Don't allow overwriting of unchecked values.
212 assertIsChecked();
213 setPtr(Other.getPtr());
214
215 // This Error is unchecked, even if the source error was checked.
216 setChecked(false);
217
218 // Null out Other's payload and set its checked bit.
219 Other.setPtr(nullptr);
220 Other.setChecked(true);
221
222 return *this;
223 }
224
225 /// Destroy a Error. Fails with a call to abort() if the error is
226 /// unchecked.
227 ~Error() {
228 assertIsChecked();
229 delete getPtr();
230 }
231
232 /// Bool conversion. Returns true if this Error is in a failure state,
233 /// and false if it is in an accept state. If the error is in a Success state
234 /// it will be considered checked.
235 explicit operator bool() {
236 setChecked(getPtr() == nullptr);
237 return getPtr() != nullptr;
238 }
239
240 /// Check whether one error is a subclass of another.
241 template <typename ErrT> bool isA() const {
242 return getPtr() && getPtr()->isA(ErrT::classID());
243 }
244
245 /// Returns the dynamic class id of this error, or null if this is a success
246 /// value.
247 const void* dynamicClassID() const {
248 if (!getPtr())
249 return nullptr;
250 return getPtr()->dynamicClassID();
251 }
252
253private:
254#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
255 // assertIsChecked() happens very frequently, but under normal circumstances
256 // is supposed to be a no-op. So we want it to be inlined, but having a bunch
257 // of debug prints can cause the function to be too large for inlining. So
258 // it's important that we define this function out of line so that it can't be
259 // inlined.
260 LLVM_ATTRIBUTE_NORETURN__attribute__((noreturn))
261 void fatalUncheckedError() const;
262#endif
263
264 void assertIsChecked() {
265#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
266 if (LLVM_UNLIKELY(!getChecked() || getPtr())__builtin_expect((bool)(!getChecked() || getPtr()), false))
267 fatalUncheckedError();
268#endif
269 }
270
271 ErrorInfoBase *getPtr() const {
272#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
273 return reinterpret_cast<ErrorInfoBase*>(
274 reinterpret_cast<uintptr_t>(Payload) &
275 ~static_cast<uintptr_t>(0x1));
276#else
277 return Payload;
278#endif
279 }
280
281 void setPtr(ErrorInfoBase *EI) {
282#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
283 Payload = reinterpret_cast<ErrorInfoBase*>(
284 (reinterpret_cast<uintptr_t>(EI) &
285 ~static_cast<uintptr_t>(0x1)) |
286 (reinterpret_cast<uintptr_t>(Payload) & 0x1));
287#else
288 Payload = EI;
289#endif
290 }
291
292 bool getChecked() const {
293#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
294 return (reinterpret_cast<uintptr_t>(Payload) & 0x1) == 0;
295#else
296 return true;
297#endif
298 }
299
300 void setChecked(bool V) {
301#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
302 Payload = reinterpret_cast<ErrorInfoBase*>(
303 (reinterpret_cast<uintptr_t>(Payload) &
304 ~static_cast<uintptr_t>(0x1)) |
305 (V ? 0 : 1));
306#endif
307 }
308
309 std::unique_ptr<ErrorInfoBase> takePayload() {
310 std::unique_ptr<ErrorInfoBase> Tmp(getPtr());
311 setPtr(nullptr);
312 setChecked(true);
313 return Tmp;
314 }
315
316 friend raw_ostream &operator<<(raw_ostream &OS, const Error &E) {
317 if (auto P = E.getPtr())
318 P->log(OS);
319 else
320 OS << "success";
321 return OS;
322 }
323
324 ErrorInfoBase *Payload = nullptr;
325};
326
327/// Subclass of Error for the sole purpose of identifying the success path in
328/// the type system. This allows to catch invalid conversion to Expected<T> at
329/// compile time.
330class ErrorSuccess final : public Error {};
331
332inline ErrorSuccess Error::success() { return ErrorSuccess(); }
333
334/// Make a Error instance representing failure using the given error info
335/// type.
336template <typename ErrT, typename... ArgTs> Error make_error(ArgTs &&... Args) {
337 return Error(std::make_unique<ErrT>(std::forward<ArgTs>(Args)...));
338}
339
340/// Base class for user error types. Users should declare their error types
341/// like:
342///
343/// class MyError : public ErrorInfo<MyError> {
344/// ....
345/// };
346///
347/// This class provides an implementation of the ErrorInfoBase::kind
348/// method, which is used by the Error RTTI system.
349template <typename ThisErrT, typename ParentErrT = ErrorInfoBase>
350class ErrorInfo : public ParentErrT {
351public:
352 using ParentErrT::ParentErrT; // inherit constructors
353
354 static const void *classID() { return &ThisErrT::ID; }
355
356 const void *dynamicClassID() const override { return &ThisErrT::ID; }
357
358 bool isA(const void *const ClassID) const override {
359 return ClassID == classID() || ParentErrT::isA(ClassID);
360 }
361};
362
363/// Special ErrorInfo subclass representing a list of ErrorInfos.
364/// Instances of this class are constructed by joinError.
365class ErrorList final : public ErrorInfo<ErrorList> {
366 // handleErrors needs to be able to iterate the payload list of an
367 // ErrorList.
368 template <typename... HandlerTs>
369 friend Error handleErrors(Error E, HandlerTs &&... Handlers);
370
371 // joinErrors is implemented in terms of join.
372 friend Error joinErrors(Error, Error);
373
374public:
375 void log(raw_ostream &OS) const override {
376 OS << "Multiple errors:\n";
377 for (auto &ErrPayload : Payloads) {
378 ErrPayload->log(OS);
379 OS << "\n";
380 }
381 }
382
383 std::error_code convertToErrorCode() const override;
384
385 // Used by ErrorInfo::classID.
386 static char ID;
387
388private:
389 ErrorList(std::unique_ptr<ErrorInfoBase> Payload1,
390 std::unique_ptr<ErrorInfoBase> Payload2) {
391 assert(!Payload1->isA<ErrorList>() && !Payload2->isA<ErrorList>() &&((!Payload1->isA<ErrorList>() && !Payload2->
isA<ErrorList>() && "ErrorList constructor payloads should be singleton errors"
) ? static_cast<void> (0) : __assert_fail ("!Payload1->isA<ErrorList>() && !Payload2->isA<ErrorList>() && \"ErrorList constructor payloads should be singleton errors\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include/llvm/Support/Error.h"
, 392, __PRETTY_FUNCTION__))
392 "ErrorList constructor payloads should be singleton errors")((!Payload1->isA<ErrorList>() && !Payload2->
isA<ErrorList>() && "ErrorList constructor payloads should be singleton errors"
) ? static_cast<void> (0) : __assert_fail ("!Payload1->isA<ErrorList>() && !Payload2->isA<ErrorList>() && \"ErrorList constructor payloads should be singleton errors\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include/llvm/Support/Error.h"
, 392, __PRETTY_FUNCTION__))
;
393 Payloads.push_back(std::move(Payload1));
394 Payloads.push_back(std::move(Payload2));
395 }
396
397 static Error join(Error E1, Error E2) {
398 if (!E1)
399 return E2;
400 if (!E2)
401 return E1;
402 if (E1.isA<ErrorList>()) {
403 auto &E1List = static_cast<ErrorList &>(*E1.getPtr());
404 if (E2.isA<ErrorList>()) {
405 auto E2Payload = E2.takePayload();
406 auto &E2List = static_cast<ErrorList &>(*E2Payload);
407 for (auto &Payload : E2List.Payloads)
408 E1List.Payloads.push_back(std::move(Payload));
409 } else
410 E1List.Payloads.push_back(E2.takePayload());
411
412 return E1;
413 }
414 if (E2.isA<ErrorList>()) {
415 auto &E2List = static_cast<ErrorList &>(*E2.getPtr());
416 E2List.Payloads.insert(E2List.Payloads.begin(), E1.takePayload());
417 return E2;
418 }
419 return Error(std::unique_ptr<ErrorList>(
420 new ErrorList(E1.takePayload(), E2.takePayload())));
421 }
422
423 std::vector<std::unique_ptr<ErrorInfoBase>> Payloads;
424};
425
426/// Concatenate errors. The resulting Error is unchecked, and contains the
427/// ErrorInfo(s), if any, contained in E1, followed by the
428/// ErrorInfo(s), if any, contained in E2.
429inline Error joinErrors(Error E1, Error E2) {
430 return ErrorList::join(std::move(E1), std::move(E2));
431}
432
433/// Tagged union holding either a T or a Error.
434///
435/// This class parallels ErrorOr, but replaces error_code with Error. Since
436/// Error cannot be copied, this class replaces getError() with
437/// takeError(). It also adds an bool errorIsA<ErrT>() method for testing the
438/// error class type.
439template <class T> class LLVM_NODISCARD[[clang::warn_unused_result]] Expected {
440 template <class T1> friend class ExpectedAsOutParameter;
441 template <class OtherT> friend class Expected;
442
443 static constexpr bool isRef = std::is_reference<T>::value;
444
445 using wrap = std::reference_wrapper<std::remove_reference_t<T>>;
446
447 using error_type = std::unique_ptr<ErrorInfoBase>;
448
449public:
450 using storage_type = std::conditional_t<isRef, wrap, T>;
451 using value_type = T;
452
453private:
454 using reference = std::remove_reference_t<T> &;
455 using const_reference = const std::remove_reference_t<T> &;
456 using pointer = std::remove_reference_t<T> *;
457 using const_pointer = const std::remove_reference_t<T> *;
458
459public:
460 /// Create an Expected<T> error value from the given Error.
461 Expected(Error Err)
462 : HasError(true)
463#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
464 // Expected is unchecked upon construction in Debug builds.
465 , Unchecked(true)
466#endif
467 {
468 assert(Err && "Cannot create Expected<T> from Error success value.")((Err && "Cannot create Expected<T> from Error success value."
) ? static_cast<void> (0) : __assert_fail ("Err && \"Cannot create Expected<T> from Error success value.\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include/llvm/Support/Error.h"
, 468, __PRETTY_FUNCTION__))
;
469 new (getErrorStorage()) error_type(Err.takePayload());
470 }
471
472 /// Forbid to convert from Error::success() implicitly, this avoids having
473 /// Expected<T> foo() { return Error::success(); } which compiles otherwise
474 /// but triggers the assertion above.
475 Expected(ErrorSuccess) = delete;
476
477 /// Create an Expected<T> success value from the given OtherT value, which
478 /// must be convertible to T.
479 template <typename OtherT>
480 Expected(OtherT &&Val,
481 std::enable_if_t<std::is_convertible<OtherT, T>::value> * = nullptr)
482 : HasError(false)
483#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
484 // Expected is unchecked upon construction in Debug builds.
485 ,
486 Unchecked(true)
487#endif
488 {
489 new (getStorage()) storage_type(std::forward<OtherT>(Val));
490 }
491
492 /// Move construct an Expected<T> value.
493 Expected(Expected &&Other) { moveConstruct(std::move(Other)); }
494
495 /// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT
496 /// must be convertible to T.
497 template <class OtherT>
498 Expected(
499 Expected<OtherT> &&Other,
500 std::enable_if_t<std::is_convertible<OtherT, T>::value> * = nullptr) {
501 moveConstruct(std::move(Other));
502 }
503
504 /// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT
505 /// isn't convertible to T.
506 template <class OtherT>
507 explicit Expected(
508 Expected<OtherT> &&Other,
509 std::enable_if_t<!std::is_convertible<OtherT, T>::value> * = nullptr) {
510 moveConstruct(std::move(Other));
511 }
512
513 /// Move-assign from another Expected<T>.
514 Expected &operator=(Expected &&Other) {
515 moveAssign(std::move(Other));
516 return *this;
517 }
518
519 /// Destroy an Expected<T>.
520 ~Expected() {
521 assertIsChecked();
522 if (!HasError)
523 getStorage()->~storage_type();
524 else
525 getErrorStorage()->~error_type();
526 }
527
528 /// Return false if there is an error.
529 explicit operator bool() {
530#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
531 Unchecked = HasError;
532#endif
533 return !HasError;
534 }
535
536 /// Returns a reference to the stored T value.
537 reference get() {
538 assertIsChecked();
539 return *getStorage();
540 }
541
542 /// Returns a const reference to the stored T value.
543 const_reference get() const {
544 assertIsChecked();
545 return const_cast<Expected<T> *>(this)->get();
546 }
547
548 /// Check that this Expected<T> is an error of type ErrT.
549 template <typename ErrT> bool errorIsA() const {
550 return HasError && (*getErrorStorage())->template isA<ErrT>();
551 }
552
553 /// Take ownership of the stored error.
554 /// After calling this the Expected<T> is in an indeterminate state that can
555 /// only be safely destructed. No further calls (beside the destructor) should
556 /// be made on the Expected<T> value.
557 Error takeError() {
558#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
559 Unchecked = false;
560#endif
561 return HasError ? Error(std::move(*getErrorStorage())) : Error::success();
562 }
563
564 /// Returns a pointer to the stored T value.
565 pointer operator->() {
566 assertIsChecked();
567 return toPointer(getStorage());
568 }
569
570 /// Returns a const pointer to the stored T value.
571 const_pointer operator->() const {
572 assertIsChecked();
573 return toPointer(getStorage());
574 }
575
576 /// Returns a reference to the stored T value.
577 reference operator*() {
578 assertIsChecked();
579 return *getStorage();
580 }
581
582 /// Returns a const reference to the stored T value.
583 const_reference operator*() const {
584 assertIsChecked();
585 return *getStorage();
586 }
587
588private:
589 template <class T1>
590 static bool compareThisIfSameType(const T1 &a, const T1 &b) {
591 return &a == &b;
592 }
593
594 template <class T1, class T2>
595 static bool compareThisIfSameType(const T1 &a, const T2 &b) {
596 return false;
597 }
598
599 template <class OtherT> void moveConstruct(Expected<OtherT> &&Other) {
600 HasError = Other.HasError;
601#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
602 Unchecked = true;
603 Other.Unchecked = false;
604#endif
605
606 if (!HasError)
607 new (getStorage()) storage_type(std::move(*Other.getStorage()));
608 else
609 new (getErrorStorage()) error_type(std::move(*Other.getErrorStorage()));
610 }
611
612 template <class OtherT> void moveAssign(Expected<OtherT> &&Other) {
613 assertIsChecked();
614
615 if (compareThisIfSameType(*this, Other))
616 return;
617
618 this->~Expected();
619 new (this) Expected(std::move(Other));
620 }
621
622 pointer toPointer(pointer Val) { return Val; }
623
624 const_pointer toPointer(const_pointer Val) const { return Val; }
625
626 pointer toPointer(wrap *Val) { return &Val->get(); }
627
628 const_pointer toPointer(const wrap *Val) const { return &Val->get(); }
629
630 storage_type *getStorage() {
631 assert(!HasError && "Cannot get value when an error exists!")((!HasError && "Cannot get value when an error exists!"
) ? static_cast<void> (0) : __assert_fail ("!HasError && \"Cannot get value when an error exists!\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include/llvm/Support/Error.h"
, 631, __PRETTY_FUNCTION__))
;
632 return reinterpret_cast<storage_type *>(TStorage.buffer);
633 }
634
635 const storage_type *getStorage() const {
636 assert(!HasError && "Cannot get value when an error exists!")((!HasError && "Cannot get value when an error exists!"
) ? static_cast<void> (0) : __assert_fail ("!HasError && \"Cannot get value when an error exists!\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include/llvm/Support/Error.h"
, 636, __PRETTY_FUNCTION__))
;
637 return reinterpret_cast<const storage_type *>(TStorage.buffer);
638 }
639
640 error_type *getErrorStorage() {
641 assert(HasError && "Cannot get error when a value exists!")((HasError && "Cannot get error when a value exists!"
) ? static_cast<void> (0) : __assert_fail ("HasError && \"Cannot get error when a value exists!\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include/llvm/Support/Error.h"
, 641, __PRETTY_FUNCTION__))
;
642 return reinterpret_cast<error_type *>(ErrorStorage.buffer);
643 }
644
645 const error_type *getErrorStorage() const {
646 assert(HasError && "Cannot get error when a value exists!")((HasError && "Cannot get error when a value exists!"
) ? static_cast<void> (0) : __assert_fail ("HasError && \"Cannot get error when a value exists!\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include/llvm/Support/Error.h"
, 646, __PRETTY_FUNCTION__))
;
647 return reinterpret_cast<const error_type *>(ErrorStorage.buffer);
648 }
649
650 // Used by ExpectedAsOutParameter to reset the checked flag.
651 void setUnchecked() {
652#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
653 Unchecked = true;
654#endif
655 }
656
657#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
658 LLVM_ATTRIBUTE_NORETURN__attribute__((noreturn))
659 LLVM_ATTRIBUTE_NOINLINE__attribute__((noinline))
660 void fatalUncheckedExpected() const {
661 dbgs() << "Expected<T> must be checked before access or destruction.\n";
662 if (HasError) {
663 dbgs() << "Unchecked Expected<T> contained error:\n";
664 (*getErrorStorage())->log(dbgs());
665 } else
666 dbgs() << "Expected<T> value was in success state. (Note: Expected<T> "
667 "values in success mode must still be checked prior to being "
668 "destroyed).\n";
669 abort();
670 }
671#endif
672
673 void assertIsChecked() {
674#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
675 if (LLVM_UNLIKELY(Unchecked)__builtin_expect((bool)(Unchecked), false))
676 fatalUncheckedExpected();
677#endif
678 }
679
680 union {
681 AlignedCharArrayUnion<storage_type> TStorage;
682 AlignedCharArrayUnion<error_type> ErrorStorage;
683 };
684 bool HasError : 1;
685#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
686 bool Unchecked : 1;
687#endif
688};
689
690/// Report a serious error, calling any installed error handler. See
691/// ErrorHandling.h.
692LLVM_ATTRIBUTE_NORETURN__attribute__((noreturn)) void report_fatal_error(Error Err,
693 bool gen_crash_diag = true);
694
695/// Report a fatal error if Err is a failure value.
696///
697/// This function can be used to wrap calls to fallible functions ONLY when it
698/// is known that the Error will always be a success value. E.g.
699///
700/// @code{.cpp}
701/// // foo only attempts the fallible operation if DoFallibleOperation is
702/// // true. If DoFallibleOperation is false then foo always returns
703/// // Error::success().
704/// Error foo(bool DoFallibleOperation);
705///
706/// cantFail(foo(false));
707/// @endcode
708inline void cantFail(Error Err, const char *Msg = nullptr) {
709 if (Err) {
710 if (!Msg)
711 Msg = "Failure value returned from cantFail wrapped call";
712#ifndef NDEBUG
713 std::string Str;
714 raw_string_ostream OS(Str);
715 OS << Msg << "\n" << Err;
716 Msg = OS.str().c_str();
717#endif
718 llvm_unreachable(Msg)::llvm::llvm_unreachable_internal(Msg, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include/llvm/Support/Error.h"
, 718)
;
719 }
720}
721
722/// Report a fatal error if ValOrErr is a failure value, otherwise unwraps and
723/// returns the contained value.
724///
725/// This function can be used to wrap calls to fallible functions ONLY when it
726/// is known that the Error will always be a success value. E.g.
727///
728/// @code{.cpp}
729/// // foo only attempts the fallible operation if DoFallibleOperation is
730/// // true. If DoFallibleOperation is false then foo always returns an int.
731/// Expected<int> foo(bool DoFallibleOperation);
732///
733/// int X = cantFail(foo(false));
734/// @endcode
735template <typename T>
736T cantFail(Expected<T> ValOrErr, const char *Msg = nullptr) {
737 if (ValOrErr)
738 return std::move(*ValOrErr);
739 else {
740 if (!Msg)
741 Msg = "Failure value returned from cantFail wrapped call";
742#ifndef NDEBUG
743 std::string Str;
744 raw_string_ostream OS(Str);
745 auto E = ValOrErr.takeError();
746 OS << Msg << "\n" << E;
747 Msg = OS.str().c_str();
748#endif
749 llvm_unreachable(Msg)::llvm::llvm_unreachable_internal(Msg, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include/llvm/Support/Error.h"
, 749)
;
750 }
751}
752
753/// Report a fatal error if ValOrErr is a failure value, otherwise unwraps and
754/// returns the contained reference.
755///
756/// This function can be used to wrap calls to fallible functions ONLY when it
757/// is known that the Error will always be a success value. E.g.
758///
759/// @code{.cpp}
760/// // foo only attempts the fallible operation if DoFallibleOperation is
761/// // true. If DoFallibleOperation is false then foo always returns a Bar&.
762/// Expected<Bar&> foo(bool DoFallibleOperation);
763///
764/// Bar &X = cantFail(foo(false));
765/// @endcode
766template <typename T>
767T& cantFail(Expected<T&> ValOrErr, const char *Msg = nullptr) {
768 if (ValOrErr)
769 return *ValOrErr;
770 else {
771 if (!Msg)
772 Msg = "Failure value returned from cantFail wrapped call";
773#ifndef NDEBUG
774 std::string Str;
775 raw_string_ostream OS(Str);
776 auto E = ValOrErr.takeError();
777 OS << Msg << "\n" << E;
778 Msg = OS.str().c_str();
779#endif
780 llvm_unreachable(Msg)::llvm::llvm_unreachable_internal(Msg, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include/llvm/Support/Error.h"
, 780)
;
781 }
782}
783
784/// Helper for testing applicability of, and applying, handlers for
785/// ErrorInfo types.
786template <typename HandlerT>
787class ErrorHandlerTraits
788 : public ErrorHandlerTraits<decltype(
789 &std::remove_reference<HandlerT>::type::operator())> {};
790
791// Specialization functions of the form 'Error (const ErrT&)'.
792template <typename ErrT> class ErrorHandlerTraits<Error (&)(ErrT &)> {
793public:
794 static bool appliesTo(const ErrorInfoBase &E) {
795 return E.template isA<ErrT>();
796 }
797
798 template <typename HandlerT>
799 static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
800 assert(appliesTo(*E) && "Applying incorrect handler")((appliesTo(*E) && "Applying incorrect handler") ? static_cast
<void> (0) : __assert_fail ("appliesTo(*E) && \"Applying incorrect handler\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include/llvm/Support/Error.h"
, 800, __PRETTY_FUNCTION__))
;
801 return H(static_cast<ErrT &>(*E));
802 }
803};
804
805// Specialization functions of the form 'void (const ErrT&)'.
806template <typename ErrT> class ErrorHandlerTraits<void (&)(ErrT &)> {
807public:
808 static bool appliesTo(const ErrorInfoBase &E) {
809 return E.template isA<ErrT>();
810 }
811
812 template <typename HandlerT>
813 static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
814 assert(appliesTo(*E) && "Applying incorrect handler")((appliesTo(*E) && "Applying incorrect handler") ? static_cast
<void> (0) : __assert_fail ("appliesTo(*E) && \"Applying incorrect handler\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include/llvm/Support/Error.h"
, 814, __PRETTY_FUNCTION__))
;
815 H(static_cast<ErrT &>(*E));
816 return Error::success();
817 }
818};
819
820/// Specialization for functions of the form 'Error (std::unique_ptr<ErrT>)'.
821template <typename ErrT>
822class ErrorHandlerTraits<Error (&)(std::unique_ptr<ErrT>)> {
823public:
824 static bool appliesTo(const ErrorInfoBase &E) {
825 return E.template isA<ErrT>();
826 }
827
828 template <typename HandlerT>
829 static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
830 assert(appliesTo(*E) && "Applying incorrect handler")((appliesTo(*E) && "Applying incorrect handler") ? static_cast
<void> (0) : __assert_fail ("appliesTo(*E) && \"Applying incorrect handler\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include/llvm/Support/Error.h"
, 830, __PRETTY_FUNCTION__))
;
831 std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release()));
832 return H(std::move(SubE));
833 }
834};
835
836/// Specialization for functions of the form 'void (std::unique_ptr<ErrT>)'.
837template <typename ErrT>
838class ErrorHandlerTraits<void (&)(std::unique_ptr<ErrT>)> {
839public:
840 static bool appliesTo(const ErrorInfoBase &E) {
841 return E.template isA<ErrT>();
842 }
843
844 template <typename HandlerT>
845 static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
846 assert(appliesTo(*E) && "Applying incorrect handler")((appliesTo(*E) && "Applying incorrect handler") ? static_cast
<void> (0) : __assert_fail ("appliesTo(*E) && \"Applying incorrect handler\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include/llvm/Support/Error.h"
, 846, __PRETTY_FUNCTION__))
;
847 std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release()));
848 H(std::move(SubE));
849 return Error::success();
850 }
851};
852
853// Specialization for member functions of the form 'RetT (const ErrT&)'.
854template <typename C, typename RetT, typename ErrT>
855class ErrorHandlerTraits<RetT (C::*)(ErrT &)>
856 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
857
858// Specialization for member functions of the form 'RetT (const ErrT&) const'.
859template <typename C, typename RetT, typename ErrT>
860class ErrorHandlerTraits<RetT (C::*)(ErrT &) const>
861 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
862
863// Specialization for member functions of the form 'RetT (const ErrT&)'.
864template <typename C, typename RetT, typename ErrT>
865class ErrorHandlerTraits<RetT (C::*)(const ErrT &)>
866 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
867
868// Specialization for member functions of the form 'RetT (const ErrT&) const'.
869template <typename C, typename RetT, typename ErrT>
870class ErrorHandlerTraits<RetT (C::*)(const ErrT &) const>
871 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
872
873/// Specialization for member functions of the form
874/// 'RetT (std::unique_ptr<ErrT>)'.
875template <typename C, typename RetT, typename ErrT>
876class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>)>
877 : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {};
878
879/// Specialization for member functions of the form
880/// 'RetT (std::unique_ptr<ErrT>) const'.
881template <typename C, typename RetT, typename ErrT>
882class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>) const>
883 : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {};
884
885inline Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload) {
886 return Error(std::move(Payload));
887}
888
889template <typename HandlerT, typename... HandlerTs>
890Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload,
891 HandlerT &&Handler, HandlerTs &&... Handlers) {
892 if (ErrorHandlerTraits<HandlerT>::appliesTo(*Payload))
893 return ErrorHandlerTraits<HandlerT>::apply(std::forward<HandlerT>(Handler),
894 std::move(Payload));
895 return handleErrorImpl(std::move(Payload),
896 std::forward<HandlerTs>(Handlers)...);
897}
898
899/// Pass the ErrorInfo(s) contained in E to their respective handlers. Any
900/// unhandled errors (or Errors returned by handlers) are re-concatenated and
901/// returned.
902/// Because this function returns an error, its result must also be checked
903/// or returned. If you intend to handle all errors use handleAllErrors
904/// (which returns void, and will abort() on unhandled errors) instead.
905template <typename... HandlerTs>
906Error handleErrors(Error E, HandlerTs &&... Hs) {
907 if (!E)
908 return Error::success();
909
910 std::unique_ptr<ErrorInfoBase> Payload = E.takePayload();
911
912 if (Payload->isA<ErrorList>()) {
913 ErrorList &List = static_cast<ErrorList &>(*Payload);
914 Error R;
915 for (auto &P : List.Payloads)
916 R = ErrorList::join(
917 std::move(R),
918 handleErrorImpl(std::move(P), std::forward<HandlerTs>(Hs)...));
919 return R;
920 }
921
922 return handleErrorImpl(std::move(Payload), std::forward<HandlerTs>(Hs)...);
923}
924
925/// Behaves the same as handleErrors, except that by contract all errors
926/// *must* be handled by the given handlers (i.e. there must be no remaining
927/// errors after running the handlers, or llvm_unreachable is called).
928template <typename... HandlerTs>
929void handleAllErrors(Error E, HandlerTs &&... Handlers) {
930 cantFail(handleErrors(std::move(E), std::forward<HandlerTs>(Handlers)...));
931}
932
933/// Check that E is a non-error, then drop it.
934/// If E is an error, llvm_unreachable will be called.
935inline void handleAllErrors(Error E) {
936 cantFail(std::move(E));
937}
938
939/// Handle any errors (if present) in an Expected<T>, then try a recovery path.
940///
941/// If the incoming value is a success value it is returned unmodified. If it
942/// is a failure value then it the contained error is passed to handleErrors.
943/// If handleErrors is able to handle the error then the RecoveryPath functor
944/// is called to supply the final result. If handleErrors is not able to
945/// handle all errors then the unhandled errors are returned.
946///
947/// This utility enables the follow pattern:
948///
949/// @code{.cpp}
950/// enum FooStrategy { Aggressive, Conservative };
951/// Expected<Foo> foo(FooStrategy S);
952///
953/// auto ResultOrErr =
954/// handleExpected(
955/// foo(Aggressive),
956/// []() { return foo(Conservative); },
957/// [](AggressiveStrategyError&) {
958/// // Implicitly conusme this - we'll recover by using a conservative
959/// // strategy.
960/// });
961///
962/// @endcode
963template <typename T, typename RecoveryFtor, typename... HandlerTs>
964Expected<T> handleExpected(Expected<T> ValOrErr, RecoveryFtor &&RecoveryPath,
965 HandlerTs &&... Handlers) {
966 if (ValOrErr)
967 return ValOrErr;
968
969 if (auto Err = handleErrors(ValOrErr.takeError(),
970 std::forward<HandlerTs>(Handlers)...))
971 return std::move(Err);
972
973 return RecoveryPath();
974}
975
976/// Log all errors (if any) in E to OS. If there are any errors, ErrorBanner
977/// will be printed before the first one is logged. A newline will be printed
978/// after each error.
979///
980/// This function is compatible with the helpers from Support/WithColor.h. You
981/// can pass any of them as the OS. Please consider using them instead of
982/// including 'error: ' in the ErrorBanner.
983///
984/// This is useful in the base level of your program to allow clean termination
985/// (allowing clean deallocation of resources, etc.), while reporting error
986/// information to the user.
987void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner = {});
988
989/// Write all error messages (if any) in E to a string. The newline character
990/// is used to separate error messages.
991inline std::string toString(Error E) {
992 SmallVector<std::string, 2> Errors;
993 handleAllErrors(std::move(E), [&Errors](const ErrorInfoBase &EI) {
994 Errors.push_back(EI.message());
995 });
996 return join(Errors.begin(), Errors.end(), "\n");
997}
998
999/// Consume a Error without doing anything. This method should be used
1000/// only where an error can be considered a reasonable and expected return
1001/// value.
1002///
1003/// Uses of this method are potentially indicative of design problems: If it's
1004/// legitimate to do nothing while processing an "error", the error-producer
1005/// might be more clearly refactored to return an Optional<T>.
1006inline void consumeError(Error Err) {
1007 handleAllErrors(std::move(Err), [](const ErrorInfoBase &) {});
1008}
1009
1010/// Convert an Expected to an Optional without doing anything. This method
1011/// should be used only where an error can be considered a reasonable and
1012/// expected return value.
1013///
1014/// Uses of this method are potentially indicative of problems: perhaps the
1015/// error should be propagated further, or the error-producer should just
1016/// return an Optional in the first place.
1017template <typename T> Optional<T> expectedToOptional(Expected<T> &&E) {
1018 if (E)
1019 return std::move(*E);
1020 consumeError(E.takeError());
1021 return None;
1022}
1023
1024/// Helper for converting an Error to a bool.
1025///
1026/// This method returns true if Err is in an error state, or false if it is
1027/// in a success state. Puts Err in a checked state in both cases (unlike
1028/// Error::operator bool(), which only does this for success states).
1029inline bool errorToBool(Error Err) {
1030 bool IsError = static_cast<bool>(Err);
1031 if (IsError)
1032 consumeError(std::move(Err));
1033 return IsError;
1034}
1035
1036/// Helper for Errors used as out-parameters.
1037///
1038/// This helper is for use with the Error-as-out-parameter idiom, where an error
1039/// is passed to a function or method by reference, rather than being returned.
1040/// In such cases it is helpful to set the checked bit on entry to the function
1041/// so that the error can be written to (unchecked Errors abort on assignment)
1042/// and clear the checked bit on exit so that clients cannot accidentally forget
1043/// to check the result. This helper performs these actions automatically using
1044/// RAII:
1045///
1046/// @code{.cpp}
1047/// Result foo(Error &Err) {
1048/// ErrorAsOutParameter ErrAsOutParam(&Err); // 'Checked' flag set
1049/// // <body of foo>
1050/// // <- 'Checked' flag auto-cleared when ErrAsOutParam is destructed.
1051/// }
1052/// @endcode
1053///
1054/// ErrorAsOutParameter takes an Error* rather than Error& so that it can be
1055/// used with optional Errors (Error pointers that are allowed to be null). If
1056/// ErrorAsOutParameter took an Error reference, an instance would have to be
1057/// created inside every condition that verified that Error was non-null. By
1058/// taking an Error pointer we can just create one instance at the top of the
1059/// function.
1060class ErrorAsOutParameter {
1061public:
1062 ErrorAsOutParameter(Error *Err) : Err(Err) {
1063 // Raise the checked bit if Err is success.
1064 if (Err)
1065 (void)!!*Err;
1066 }
1067
1068 ~ErrorAsOutParameter() {
1069 // Clear the checked bit.
1070 if (Err && !*Err)
1071 *Err = Error::success();
1072 }
1073
1074private:
1075 Error *Err;
1076};
1077
1078/// Helper for Expected<T>s used as out-parameters.
1079///
1080/// See ErrorAsOutParameter.
1081template <typename T>
1082class ExpectedAsOutParameter {
1083public:
1084 ExpectedAsOutParameter(Expected<T> *ValOrErr)
1085 : ValOrErr(ValOrErr) {
1086 if (ValOrErr)
1087 (void)!!*ValOrErr;
1088 }
1089
1090 ~ExpectedAsOutParameter() {
1091 if (ValOrErr)
1092 ValOrErr->setUnchecked();
1093 }
1094
1095private:
1096 Expected<T> *ValOrErr;
1097};
1098
1099/// This class wraps a std::error_code in a Error.
1100///
1101/// This is useful if you're writing an interface that returns a Error
1102/// (or Expected) and you want to call code that still returns
1103/// std::error_codes.
1104class ECError : public ErrorInfo<ECError> {
1105 friend Error errorCodeToError(std::error_code);
1106
1107 virtual void anchor() override;
1108
1109public:
1110 void setErrorCode(std::error_code EC) { this->EC = EC; }
1111 std::error_code convertToErrorCode() const override { return EC; }
1112 void log(raw_ostream &OS) const override { OS << EC.message(); }
1113
1114 // Used by ErrorInfo::classID.
1115 static char ID;
1116
1117protected:
1118 ECError() = default;
1119 ECError(std::error_code EC) : EC(EC) {}
1120
1121 std::error_code EC;
1122};
1123
1124/// The value returned by this function can be returned from convertToErrorCode
1125/// for Error values where no sensible translation to std::error_code exists.
1126/// It should only be used in this situation, and should never be used where a
1127/// sensible conversion to std::error_code is available, as attempts to convert
1128/// to/from this error will result in a fatal error. (i.e. it is a programmatic
1129///error to try to convert such a value).
1130std::error_code inconvertibleErrorCode();
1131
1132/// Helper for converting an std::error_code to a Error.
1133Error errorCodeToError(std::error_code EC);
1134
1135/// Helper for converting an ECError to a std::error_code.
1136///
1137/// This method requires that Err be Error() or an ECError, otherwise it
1138/// will trigger a call to abort().
1139std::error_code errorToErrorCode(Error Err);
1140
1141/// Convert an ErrorOr<T> to an Expected<T>.
1142template <typename T> Expected<T> errorOrToExpected(ErrorOr<T> &&EO) {
1143 if (auto EC = EO.getError())
1144 return errorCodeToError(EC);
1145 return std::move(*EO);
1146}
1147
1148/// Convert an Expected<T> to an ErrorOr<T>.
1149template <typename T> ErrorOr<T> expectedToErrorOr(Expected<T> &&E) {
1150 if (auto Err = E.takeError())
1151 return errorToErrorCode(std::move(Err));
1152 return std::move(*E);
1153}
1154
1155/// This class wraps a string in an Error.
1156///
1157/// StringError is useful in cases where the client is not expected to be able
1158/// to consume the specific error message programmatically (for example, if the
1159/// error message is to be presented to the user).
1160///
1161/// StringError can also be used when additional information is to be printed
1162/// along with a error_code message. Depending on the constructor called, this
1163/// class can either display:
1164/// 1. the error_code message (ECError behavior)
1165/// 2. a string
1166/// 3. the error_code message and a string
1167///
1168/// These behaviors are useful when subtyping is required; for example, when a
1169/// specific library needs an explicit error type. In the example below,
1170/// PDBError is derived from StringError:
1171///
1172/// @code{.cpp}
1173/// Expected<int> foo() {
1174/// return llvm::make_error<PDBError>(pdb_error_code::dia_failed_loading,
1175/// "Additional information");
1176/// }
1177/// @endcode
1178///
1179class StringError : public ErrorInfo<StringError> {
1180public:
1181 static char ID;
1182
1183 // Prints EC + S and converts to EC
1184 StringError(std::error_code EC, const Twine &S = Twine());
1185
1186 // Prints S and converts to EC
1187 StringError(const Twine &S, std::error_code EC);
1188
1189 void log(raw_ostream &OS) const override;
1190 std::error_code convertToErrorCode() const override;
1191
1192 const std::string &getMessage() const { return Msg; }
1193
1194private:
1195 std::string Msg;
1196 std::error_code EC;
1197 const bool PrintMsgOnly = false;
1198};
1199
1200/// Create formatted StringError object.
1201template <typename... Ts>
1202inline Error createStringError(std::error_code EC, char const *Fmt,
1203 const Ts &... Vals) {
1204 std::string Buffer;
1205 raw_string_ostream Stream(Buffer);
1206 Stream << format(Fmt, Vals...);
1207 return make_error<StringError>(Stream.str(), EC);
1208}
1209
1210Error createStringError(std::error_code EC, char const *Msg);
1211
1212inline Error createStringError(std::error_code EC, const Twine &S) {
1213 return createStringError(EC, S.str().c_str());
1214}
1215
1216template <typename... Ts>
1217inline Error createStringError(std::errc EC, char const *Fmt,
1218 const Ts &... Vals) {
1219 return createStringError(std::make_error_code(EC), Fmt, Vals...);
1220}
1221
1222/// This class wraps a filename and another Error.
1223///
1224/// In some cases, an error needs to live along a 'source' name, in order to
1225/// show more detailed information to the user.
1226class FileError final : public ErrorInfo<FileError> {
1227
1228 friend Error createFileError(const Twine &, Error);
1229 friend Error createFileError(const Twine &, size_t, Error);
1230
1231public:
1232 void log(raw_ostream &OS) const override {
1233 assert(Err && !FileName.empty() && "Trying to log after takeError().")((Err && !FileName.empty() && "Trying to log after takeError()."
) ? static_cast<void> (0) : __assert_fail ("Err && !FileName.empty() && \"Trying to log after takeError().\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include/llvm/Support/Error.h"
, 1233, __PRETTY_FUNCTION__))
;
1234 OS << "'" << FileName << "': ";
1235 if (Line.hasValue())
1236 OS << "line " << Line.getValue() << ": ";
1237 Err->log(OS);
1238 }
1239
1240 StringRef getFileName() { return FileName; }
1241
1242 Error takeError() { return Error(std::move(Err)); }
1243
1244 std::error_code convertToErrorCode() const override;
1245
1246 // Used by ErrorInfo::classID.
1247 static char ID;
1248
1249private:
1250 FileError(const Twine &F, Optional<size_t> LineNum,
1251 std::unique_ptr<ErrorInfoBase> E) {
1252 assert(E && "Cannot create FileError from Error success value.")((E && "Cannot create FileError from Error success value."
) ? static_cast<void> (0) : __assert_fail ("E && \"Cannot create FileError from Error success value.\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include/llvm/Support/Error.h"
, 1252, __PRETTY_FUNCTION__))
;
1253 assert(!F.isTriviallyEmpty() &&((!F.isTriviallyEmpty() && "The file name provided to FileError must not be empty."
) ? static_cast<void> (0) : __assert_fail ("!F.isTriviallyEmpty() && \"The file name provided to FileError must not be empty.\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include/llvm/Support/Error.h"
, 1254, __PRETTY_FUNCTION__))
1254 "The file name provided to FileError must not be empty.")((!F.isTriviallyEmpty() && "The file name provided to FileError must not be empty."
) ? static_cast<void> (0) : __assert_fail ("!F.isTriviallyEmpty() && \"The file name provided to FileError must not be empty.\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include/llvm/Support/Error.h"
, 1254, __PRETTY_FUNCTION__))
;
1255 FileName = F.str();
1256 Err = std::move(E);
1257 Line = std::move(LineNum);
1258 }
1259
1260 static Error build(const Twine &F, Optional<size_t> Line, Error E) {
1261 std::unique_ptr<ErrorInfoBase> Payload;
1262 handleAllErrors(std::move(E),
1263 [&](std::unique_ptr<ErrorInfoBase> EIB) -> Error {
1264 Payload = std::move(EIB);
1265 return Error::success();
1266 });
1267 return Error(
1268 std::unique_ptr<FileError>(new FileError(F, Line, std::move(Payload))));
1269 }
1270
1271 std::string FileName;
1272 Optional<size_t> Line;
1273 std::unique_ptr<ErrorInfoBase> Err;
1274};
1275
1276/// Concatenate a source file path and/or name with an Error. The resulting
1277/// Error is unchecked.
1278inline Error createFileError(const Twine &F, Error E) {
1279 return FileError::build(F, Optional<size_t>(), std::move(E));
1280}
1281
1282/// Concatenate a source file path and/or name with line number and an Error.
1283/// The resulting Error is unchecked.
1284inline Error createFileError(const Twine &F, size_t Line, Error E) {
1285 return FileError::build(F, Optional<size_t>(Line), std::move(E));
1286}
1287
1288/// Concatenate a source file path and/or name with a std::error_code
1289/// to form an Error object.
1290inline Error createFileError(const Twine &F, std::error_code EC) {
1291 return createFileError(F, errorCodeToError(EC));
1292}
1293
1294/// Concatenate a source file path and/or name with line number and
1295/// std::error_code to form an Error object.
1296inline Error createFileError(const Twine &F, size_t Line, std::error_code EC) {
1297 return createFileError(F, Line, errorCodeToError(EC));
1298}
1299
1300Error createFileError(const Twine &F, ErrorSuccess) = delete;
1301
1302/// Helper for check-and-exit error handling.
1303///
1304/// For tool use only. NOT FOR USE IN LIBRARY CODE.
1305///
1306class ExitOnError {
1307public:
1308 /// Create an error on exit helper.
1309 ExitOnError(std::string Banner = "", int DefaultErrorExitCode = 1)
1310 : Banner(std::move(Banner)),
1311 GetExitCode([=](const Error &) { return DefaultErrorExitCode; }) {}
1312
1313 /// Set the banner string for any errors caught by operator().
1314 void setBanner(std::string Banner) { this->Banner = std::move(Banner); }
1315
1316 /// Set the exit-code mapper function.
1317 void setExitCodeMapper(std::function<int(const Error &)> GetExitCode) {
1318 this->GetExitCode = std::move(GetExitCode);
1319 }
1320
1321 /// Check Err. If it's in a failure state log the error(s) and exit.
1322 void operator()(Error Err) const { checkError(std::move(Err)); }
1323
1324 /// Check E. If it's in a success state then return the contained value. If
1325 /// it's in a failure state log the error(s) and exit.
1326 template <typename T> T operator()(Expected<T> &&E) const {
1327 checkError(E.takeError());
1328 return std::move(*E);
1329 }
1330
1331 /// Check E. If it's in a success state then return the contained reference. If
1332 /// it's in a failure state log the error(s) and exit.
1333 template <typename T> T& operator()(Expected<T&> &&E) const {
1334 checkError(E.takeError());
1335 return *E;
1336 }
1337
1338private:
1339 void checkError(Error Err) const {
1340 if (Err) {
1341 int ExitCode = GetExitCode(Err);
1342 logAllUnhandledErrors(std::move(Err), errs(), Banner);
1343 exit(ExitCode);
1344 }
1345 }
1346
1347 std::string Banner;
1348 std::function<int(const Error &)> GetExitCode;
1349};
1350
1351/// Conversion from Error to LLVMErrorRef for C error bindings.
1352inline LLVMErrorRef wrap(Error Err) {
1353 return reinterpret_cast<LLVMErrorRef>(Err.takePayload().release());
1354}
1355
1356/// Conversion from LLVMErrorRef to Error for C error bindings.
1357inline Error unwrap(LLVMErrorRef ErrRef) {
1358 return Error(std::unique_ptr<ErrorInfoBase>(
1359 reinterpret_cast<ErrorInfoBase *>(ErrRef)));
1360}
1361
1362} // end namespace llvm
1363
1364#endif // LLVM_SUPPORT_ERROR_H