Bug Summary

File:tools/llvm-objdump/COFFDump.cpp
Warning:line 674, column 19
1st function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name COFFDump.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -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 -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn326551/build-llvm/tools/llvm-objdump -I /build/llvm-toolchain-snapshot-7~svn326551/tools/llvm-objdump -I /build/llvm-toolchain-snapshot-7~svn326551/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn326551/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.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++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn326551/build-llvm/tools/llvm-objdump -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-03-02-155150-1477-1 -x c++ /build/llvm-toolchain-snapshot-7~svn326551/tools/llvm-objdump/COFFDump.cpp

/build/llvm-toolchain-snapshot-7~svn326551/tools/llvm-objdump/COFFDump.cpp

1//===-- COFFDump.cpp - COFF-specific dumper ---------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief This file implements the COFF-specific dumper for llvm-objdump.
12/// It outputs the Win64 EH data structures as plain text.
13/// The encoding of the unwind codes is described in MSDN:
14/// http://msdn.microsoft.com/en-us/library/ck9asaa9.aspx
15///
16//===----------------------------------------------------------------------===//
17
18#include "llvm-objdump.h"
19#include "llvm/Object/COFF.h"
20#include "llvm/Object/COFFImportFile.h"
21#include "llvm/Object/ObjectFile.h"
22#include "llvm/Support/Format.h"
23#include "llvm/Support/Win64EH.h"
24#include "llvm/Support/raw_ostream.h"
25
26using namespace llvm;
27using namespace object;
28using namespace llvm::Win64EH;
29
30// Returns the name of the unwind code.
31static StringRef getUnwindCodeTypeName(uint8_t Code) {
32 switch(Code) {
33 default: llvm_unreachable("Invalid unwind code")::llvm::llvm_unreachable_internal("Invalid unwind code", "/build/llvm-toolchain-snapshot-7~svn326551/tools/llvm-objdump/COFFDump.cpp"
, 33)
;
34 case UOP_PushNonVol: return "UOP_PushNonVol";
35 case UOP_AllocLarge: return "UOP_AllocLarge";
36 case UOP_AllocSmall: return "UOP_AllocSmall";
37 case UOP_SetFPReg: return "UOP_SetFPReg";
38 case UOP_SaveNonVol: return "UOP_SaveNonVol";
39 case UOP_SaveNonVolBig: return "UOP_SaveNonVolBig";
40 case UOP_SaveXMM128: return "UOP_SaveXMM128";
41 case UOP_SaveXMM128Big: return "UOP_SaveXMM128Big";
42 case UOP_PushMachFrame: return "UOP_PushMachFrame";
43 }
44}
45
46// Returns the name of a referenced register.
47static StringRef getUnwindRegisterName(uint8_t Reg) {
48 switch(Reg) {
49 default: llvm_unreachable("Invalid register")::llvm::llvm_unreachable_internal("Invalid register", "/build/llvm-toolchain-snapshot-7~svn326551/tools/llvm-objdump/COFFDump.cpp"
, 49)
;
50 case 0: return "RAX";
51 case 1: return "RCX";
52 case 2: return "RDX";
53 case 3: return "RBX";
54 case 4: return "RSP";
55 case 5: return "RBP";
56 case 6: return "RSI";
57 case 7: return "RDI";
58 case 8: return "R8";
59 case 9: return "R9";
60 case 10: return "R10";
61 case 11: return "R11";
62 case 12: return "R12";
63 case 13: return "R13";
64 case 14: return "R14";
65 case 15: return "R15";
66 }
67}
68
69// Calculates the number of array slots required for the unwind code.
70static unsigned getNumUsedSlots(const UnwindCode &UnwindCode) {
71 switch (UnwindCode.getUnwindOp()) {
72 default: llvm_unreachable("Invalid unwind code")::llvm::llvm_unreachable_internal("Invalid unwind code", "/build/llvm-toolchain-snapshot-7~svn326551/tools/llvm-objdump/COFFDump.cpp"
, 72)
;
73 case UOP_PushNonVol:
74 case UOP_AllocSmall:
75 case UOP_SetFPReg:
76 case UOP_PushMachFrame:
77 return 1;
78 case UOP_SaveNonVol:
79 case UOP_SaveXMM128:
80 return 2;
81 case UOP_SaveNonVolBig:
82 case UOP_SaveXMM128Big:
83 return 3;
84 case UOP_AllocLarge:
85 return (UnwindCode.getOpInfo() == 0) ? 2 : 3;
86 }
87}
88
89// Prints one unwind code. Because an unwind code can occupy up to 3 slots in
90// the unwind codes array, this function requires that the correct number of
91// slots is provided.
92static void printUnwindCode(ArrayRef<UnwindCode> UCs) {
93 assert(UCs.size() >= getNumUsedSlots(UCs[0]))(static_cast <bool> (UCs.size() >= getNumUsedSlots(UCs
[0])) ? void (0) : __assert_fail ("UCs.size() >= getNumUsedSlots(UCs[0])"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/llvm-objdump/COFFDump.cpp"
, 93, __extension__ __PRETTY_FUNCTION__))
;
94 outs() << format(" 0x%02x: ", unsigned(UCs[0].u.CodeOffset))
95 << getUnwindCodeTypeName(UCs[0].getUnwindOp());
96 switch (UCs[0].getUnwindOp()) {
97 case UOP_PushNonVol:
98 outs() << " " << getUnwindRegisterName(UCs[0].getOpInfo());
99 break;
100 case UOP_AllocLarge:
101 if (UCs[0].getOpInfo() == 0) {
102 outs() << " " << UCs[1].FrameOffset;
103 } else {
104 outs() << " " << UCs[1].FrameOffset
105 + (static_cast<uint32_t>(UCs[2].FrameOffset) << 16);
106 }
107 break;
108 case UOP_AllocSmall:
109 outs() << " " << ((UCs[0].getOpInfo() + 1) * 8);
110 break;
111 case UOP_SetFPReg:
112 outs() << " ";
113 break;
114 case UOP_SaveNonVol:
115 outs() << " " << getUnwindRegisterName(UCs[0].getOpInfo())
116 << format(" [0x%04x]", 8 * UCs[1].FrameOffset);
117 break;
118 case UOP_SaveNonVolBig:
119 outs() << " " << getUnwindRegisterName(UCs[0].getOpInfo())
120 << format(" [0x%08x]", UCs[1].FrameOffset
121 + (static_cast<uint32_t>(UCs[2].FrameOffset) << 16));
122 break;
123 case UOP_SaveXMM128:
124 outs() << " XMM" << static_cast<uint32_t>(UCs[0].getOpInfo())
125 << format(" [0x%04x]", 16 * UCs[1].FrameOffset);
126 break;
127 case UOP_SaveXMM128Big:
128 outs() << " XMM" << UCs[0].getOpInfo()
129 << format(" [0x%08x]", UCs[1].FrameOffset
130 + (static_cast<uint32_t>(UCs[2].FrameOffset) << 16));
131 break;
132 case UOP_PushMachFrame:
133 outs() << " " << (UCs[0].getOpInfo() ? "w/o" : "w")
134 << " error code";
135 break;
136 }
137 outs() << "\n";
138}
139
140static void printAllUnwindCodes(ArrayRef<UnwindCode> UCs) {
141 for (const UnwindCode *I = UCs.begin(), *E = UCs.end(); I < E; ) {
142 unsigned UsedSlots = getNumUsedSlots(*I);
143 if (UsedSlots > UCs.size()) {
144 outs() << "Unwind data corrupted: Encountered unwind op "
145 << getUnwindCodeTypeName((*I).getUnwindOp())
146 << " which requires " << UsedSlots
147 << " slots, but only " << UCs.size()
148 << " remaining in buffer";
149 return ;
150 }
151 printUnwindCode(makeArrayRef(I, E));
152 I += UsedSlots;
153 }
154}
155
156// Given a symbol sym this functions returns the address and section of it.
157static std::error_code
158resolveSectionAndAddress(const COFFObjectFile *Obj, const SymbolRef &Sym,
159 const coff_section *&ResolvedSection,
160 uint64_t &ResolvedAddr) {
161 Expected<uint64_t> ResolvedAddrOrErr = Sym.getAddress();
162 if (!ResolvedAddrOrErr)
163 return errorToErrorCode(ResolvedAddrOrErr.takeError());
164 ResolvedAddr = *ResolvedAddrOrErr;
165 Expected<section_iterator> Iter = Sym.getSection();
166 if (!Iter)
167 return errorToErrorCode(Iter.takeError());
168 ResolvedSection = Obj->getCOFFSection(**Iter);
169 return std::error_code();
170}
171
172// Given a vector of relocations for a section and an offset into this section
173// the function returns the symbol used for the relocation at the offset.
174static std::error_code resolveSymbol(const std::vector<RelocationRef> &Rels,
175 uint64_t Offset, SymbolRef &Sym) {
176 for (auto &R : Rels) {
177 uint64_t Ofs = R.getOffset();
178 if (Ofs == Offset) {
179 Sym = *R.getSymbol();
180 return std::error_code();
181 }
182 }
183 return object_error::parse_failed;
184}
185
186// Given a vector of relocations for a section and an offset into this section
187// the function resolves the symbol used for the relocation at the offset and
188// returns the section content and the address inside the content pointed to
189// by the symbol.
190static std::error_code
191getSectionContents(const COFFObjectFile *Obj,
192 const std::vector<RelocationRef> &Rels, uint64_t Offset,
193 ArrayRef<uint8_t> &Contents, uint64_t &Addr) {
194 SymbolRef Sym;
195 if (std::error_code EC = resolveSymbol(Rels, Offset, Sym))
196 return EC;
197 const coff_section *Section;
198 if (std::error_code EC = resolveSectionAndAddress(Obj, Sym, Section, Addr))
199 return EC;
200 if (std::error_code EC = Obj->getSectionContents(Section, Contents))
201 return EC;
202 return std::error_code();
203}
204
205// Given a vector of relocations for a section and an offset into this section
206// the function returns the name of the symbol used for the relocation at the
207// offset.
208static std::error_code resolveSymbolName(const std::vector<RelocationRef> &Rels,
209 uint64_t Offset, StringRef &Name) {
210 SymbolRef Sym;
211 if (std::error_code EC = resolveSymbol(Rels, Offset, Sym))
212 return EC;
213 Expected<StringRef> NameOrErr = Sym.getName();
214 if (!NameOrErr)
215 return errorToErrorCode(NameOrErr.takeError());
216 Name = *NameOrErr;
217 return std::error_code();
218}
219
220static void printCOFFSymbolAddress(llvm::raw_ostream &Out,
221 const std::vector<RelocationRef> &Rels,
222 uint64_t Offset, uint32_t Disp) {
223 StringRef Sym;
224 if (!resolveSymbolName(Rels, Offset, Sym)) {
225 Out << Sym;
226 if (Disp > 0)
227 Out << format(" + 0x%04x", Disp);
228 } else {
229 Out << format("0x%04x", Disp);
230 }
231}
232
233static void
234printSEHTable(const COFFObjectFile *Obj, uint32_t TableVA, int Count) {
235 if (Count == 0)
236 return;
237
238 const pe32_header *PE32Header;
239 error(Obj->getPE32Header(PE32Header));
240 uint32_t ImageBase = PE32Header->ImageBase;
241 uintptr_t IntPtr = 0;
242 error(Obj->getVaPtr(TableVA, IntPtr));
243 const support::ulittle32_t *P = (const support::ulittle32_t *)IntPtr;
244 outs() << "SEH Table:";
245 for (int I = 0; I < Count; ++I)
246 outs() << format(" 0x%x", P[I] + ImageBase);
247 outs() << "\n\n";
248}
249
250template <typename T>
251static void printTLSDirectoryT(const coff_tls_directory<T> *TLSDir) {
252 size_t FormatWidth = sizeof(T) * 2;
253 outs() << "TLS directory:"
254 << "\n StartAddressOfRawData: "
255 << format_hex(TLSDir->StartAddressOfRawData, FormatWidth)
256 << "\n EndAddressOfRawData: "
257 << format_hex(TLSDir->EndAddressOfRawData, FormatWidth)
258 << "\n AddressOfIndex: "
259 << format_hex(TLSDir->AddressOfIndex, FormatWidth)
260 << "\n AddressOfCallBacks: "
261 << format_hex(TLSDir->AddressOfCallBacks, FormatWidth)
262 << "\n SizeOfZeroFill: "
263 << TLSDir->SizeOfZeroFill
264 << "\n Characteristics: "
265 << TLSDir->Characteristics
266 << "\n Alignment: "
267 << TLSDir->getAlignment()
268 << "\n\n";
269}
270
271static void printTLSDirectory(const COFFObjectFile *Obj) {
272 const pe32_header *PE32Header;
273 error(Obj->getPE32Header(PE32Header));
274
275 const pe32plus_header *PE32PlusHeader;
276 error(Obj->getPE32PlusHeader(PE32PlusHeader));
277
278 // Skip if it's not executable.
279 if (!PE32Header && !PE32PlusHeader)
280 return;
281
282 const data_directory *DataDir;
283 error(Obj->getDataDirectory(COFF::TLS_TABLE, DataDir));
284 uintptr_t IntPtr = 0;
285 if (DataDir->RelativeVirtualAddress == 0)
286 return;
287 error(Obj->getRvaPtr(DataDir->RelativeVirtualAddress, IntPtr));
288
289 if (PE32Header) {
290 auto *TLSDir = reinterpret_cast<const coff_tls_directory32 *>(IntPtr);
291 printTLSDirectoryT(TLSDir);
292 } else {
293 auto *TLSDir = reinterpret_cast<const coff_tls_directory64 *>(IntPtr);
294 printTLSDirectoryT(TLSDir);
295 }
296
297 outs() << "\n";
298}
299
300static void printLoadConfiguration(const COFFObjectFile *Obj) {
301 // Skip if it's not executable.
302 const pe32_header *PE32Header;
303 error(Obj->getPE32Header(PE32Header));
304 if (!PE32Header)
305 return;
306
307 // Currently only x86 is supported
308 if (Obj->getMachine() != COFF::IMAGE_FILE_MACHINE_I386)
309 return;
310
311 const data_directory *DataDir;
312 error(Obj->getDataDirectory(COFF::LOAD_CONFIG_TABLE, DataDir));
313 uintptr_t IntPtr = 0;
314 if (DataDir->RelativeVirtualAddress == 0)
315 return;
316 error(Obj->getRvaPtr(DataDir->RelativeVirtualAddress, IntPtr));
317
318 auto *LoadConf = reinterpret_cast<const coff_load_configuration32 *>(IntPtr);
319 outs() << "Load configuration:"
320 << "\n Timestamp: " << LoadConf->TimeDateStamp
321 << "\n Major Version: " << LoadConf->MajorVersion
322 << "\n Minor Version: " << LoadConf->MinorVersion
323 << "\n GlobalFlags Clear: " << LoadConf->GlobalFlagsClear
324 << "\n GlobalFlags Set: " << LoadConf->GlobalFlagsSet
325 << "\n Critical Section Default Timeout: " << LoadConf->CriticalSectionDefaultTimeout
326 << "\n Decommit Free Block Threshold: " << LoadConf->DeCommitFreeBlockThreshold
327 << "\n Decommit Total Free Threshold: " << LoadConf->DeCommitTotalFreeThreshold
328 << "\n Lock Prefix Table: " << LoadConf->LockPrefixTable
329 << "\n Maximum Allocation Size: " << LoadConf->MaximumAllocationSize
330 << "\n Virtual Memory Threshold: " << LoadConf->VirtualMemoryThreshold
331 << "\n Process Affinity Mask: " << LoadConf->ProcessAffinityMask
332 << "\n Process Heap Flags: " << LoadConf->ProcessHeapFlags
333 << "\n CSD Version: " << LoadConf->CSDVersion
334 << "\n Security Cookie: " << LoadConf->SecurityCookie
335 << "\n SEH Table: " << LoadConf->SEHandlerTable
336 << "\n SEH Count: " << LoadConf->SEHandlerCount
337 << "\n\n";
338 printSEHTable(Obj, LoadConf->SEHandlerTable, LoadConf->SEHandlerCount);
339 outs() << "\n";
340}
341
342// Prints import tables. The import table is a table containing the list of
343// DLL name and symbol names which will be linked by the loader.
344static void printImportTables(const COFFObjectFile *Obj) {
345 import_directory_iterator I = Obj->import_directory_begin();
346 import_directory_iterator E = Obj->import_directory_end();
347 if (I == E)
348 return;
349 outs() << "The Import Tables:\n";
350 for (const ImportDirectoryEntryRef &DirRef : Obj->import_directories()) {
351 const coff_import_directory_table_entry *Dir;
352 StringRef Name;
353 if (DirRef.getImportTableEntry(Dir)) return;
354 if (DirRef.getName(Name)) return;
355
356 outs() << format(" lookup %08x time %08x fwd %08x name %08x addr %08x\n\n",
357 static_cast<uint32_t>(Dir->ImportLookupTableRVA),
358 static_cast<uint32_t>(Dir->TimeDateStamp),
359 static_cast<uint32_t>(Dir->ForwarderChain),
360 static_cast<uint32_t>(Dir->NameRVA),
361 static_cast<uint32_t>(Dir->ImportAddressTableRVA));
362 outs() << " DLL Name: " << Name << "\n";
363 outs() << " Hint/Ord Name\n";
364 for (const ImportedSymbolRef &Entry : DirRef.imported_symbols()) {
365 bool IsOrdinal;
366 if (Entry.isOrdinal(IsOrdinal))
367 return;
368 if (IsOrdinal) {
369 uint16_t Ordinal;
370 if (Entry.getOrdinal(Ordinal))
371 return;
372 outs() << format(" % 6d\n", Ordinal);
373 continue;
374 }
375 uint32_t HintNameRVA;
376 if (Entry.getHintNameRVA(HintNameRVA))
377 return;
378 uint16_t Hint;
379 StringRef Name;
380 if (Obj->getHintName(HintNameRVA, Hint, Name))
381 return;
382 outs() << format(" % 6d ", Hint) << Name << "\n";
383 }
384 outs() << "\n";
385 }
386}
387
388// Prints export tables. The export table is a table containing the list of
389// exported symbol from the DLL.
390static void printExportTable(const COFFObjectFile *Obj) {
391 outs() << "Export Table:\n";
392 export_directory_iterator I = Obj->export_directory_begin();
393 export_directory_iterator E = Obj->export_directory_end();
394 if (I == E)
395 return;
396 StringRef DllName;
397 uint32_t OrdinalBase;
398 if (I->getDllName(DllName))
399 return;
400 if (I->getOrdinalBase(OrdinalBase))
401 return;
402 outs() << " DLL name: " << DllName << "\n";
403 outs() << " Ordinal base: " << OrdinalBase << "\n";
404 outs() << " Ordinal RVA Name\n";
405 for (; I != E; I = ++I) {
406 uint32_t Ordinal;
407 if (I->getOrdinal(Ordinal))
408 return;
409 uint32_t RVA;
410 if (I->getExportRVA(RVA))
411 return;
412 bool IsForwarder;
413 if (I->isForwarder(IsForwarder))
414 return;
415
416 if (IsForwarder) {
417 // Export table entries can be used to re-export symbols that
418 // this COFF file is imported from some DLLs. This is rare.
419 // In most cases IsForwarder is false.
420 outs() << format(" % 4d ", Ordinal);
421 } else {
422 outs() << format(" % 4d %# 8x", Ordinal, RVA);
423 }
424
425 StringRef Name;
426 if (I->getSymbolName(Name))
427 continue;
428 if (!Name.empty())
429 outs() << " " << Name;
430 if (IsForwarder) {
431 StringRef S;
432 if (I->getForwardTo(S))
433 return;
434 outs() << " (forwarded to " << S << ")";
435 }
436 outs() << "\n";
437 }
438}
439
440// Given the COFF object file, this function returns the relocations for .pdata
441// and the pointer to "runtime function" structs.
442static bool getPDataSection(const COFFObjectFile *Obj,
443 std::vector<RelocationRef> &Rels,
444 const RuntimeFunction *&RFStart, int &NumRFs) {
445 for (const SectionRef &Section : Obj->sections()) {
446 StringRef Name;
447 error(Section.getName(Name));
448 if (Name != ".pdata")
449 continue;
450
451 const coff_section *Pdata = Obj->getCOFFSection(Section);
452 for (const RelocationRef &Reloc : Section.relocations())
453 Rels.push_back(Reloc);
454
455 // Sort relocations by address.
456 std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
457
458 ArrayRef<uint8_t> Contents;
459 error(Obj->getSectionContents(Pdata, Contents));
460 if (Contents.empty())
461 continue;
462
463 RFStart = reinterpret_cast<const RuntimeFunction *>(Contents.data());
464 NumRFs = Contents.size() / sizeof(RuntimeFunction);
465 return true;
466 }
467 return false;
468}
469
470static void printWin64EHUnwindInfo(const Win64EH::UnwindInfo *UI) {
471 // The casts to int are required in order to output the value as number.
472 // Without the casts the value would be interpreted as char data (which
473 // results in garbage output).
474 outs() << " Version: " << static_cast<int>(UI->getVersion()) << "\n";
475 outs() << " Flags: " << static_cast<int>(UI->getFlags());
476 if (UI->getFlags()) {
477 if (UI->getFlags() & UNW_ExceptionHandler)
478 outs() << " UNW_ExceptionHandler";
479 if (UI->getFlags() & UNW_TerminateHandler)
480 outs() << " UNW_TerminateHandler";
481 if (UI->getFlags() & UNW_ChainInfo)
482 outs() << " UNW_ChainInfo";
483 }
484 outs() << "\n";
485 outs() << " Size of prolog: " << static_cast<int>(UI->PrologSize) << "\n";
486 outs() << " Number of Codes: " << static_cast<int>(UI->NumCodes) << "\n";
487 // Maybe this should move to output of UOP_SetFPReg?
488 if (UI->getFrameRegister()) {
489 outs() << " Frame register: "
490 << getUnwindRegisterName(UI->getFrameRegister()) << "\n";
491 outs() << " Frame offset: " << 16 * UI->getFrameOffset() << "\n";
492 } else {
493 outs() << " No frame pointer used\n";
494 }
495 if (UI->getFlags() & (UNW_ExceptionHandler | UNW_TerminateHandler)) {
496 // FIXME: Output exception handler data
497 } else if (UI->getFlags() & UNW_ChainInfo) {
498 // FIXME: Output chained unwind info
499 }
500
501 if (UI->NumCodes)
502 outs() << " Unwind Codes:\n";
503
504 printAllUnwindCodes(makeArrayRef(&UI->UnwindCodes[0], UI->NumCodes));
505
506 outs() << "\n";
507 outs().flush();
508}
509
510/// Prints out the given RuntimeFunction struct for x64, assuming that Obj is
511/// pointing to an executable file.
512static void printRuntimeFunction(const COFFObjectFile *Obj,
513 const RuntimeFunction &RF) {
514 if (!RF.StartAddress)
515 return;
516 outs() << "Function Table:\n"
517 << format(" Start Address: 0x%04x\n",
518 static_cast<uint32_t>(RF.StartAddress))
519 << format(" End Address: 0x%04x\n",
520 static_cast<uint32_t>(RF.EndAddress))
521 << format(" Unwind Info Address: 0x%04x\n",
522 static_cast<uint32_t>(RF.UnwindInfoOffset));
523 uintptr_t addr;
524 if (Obj->getRvaPtr(RF.UnwindInfoOffset, addr))
525 return;
526 printWin64EHUnwindInfo(reinterpret_cast<const Win64EH::UnwindInfo *>(addr));
527}
528
529/// Prints out the given RuntimeFunction struct for x64, assuming that Obj is
530/// pointing to an object file. Unlike executable, fields in RuntimeFunction
531/// struct are filled with zeros, but instead there are relocations pointing to
532/// them so that the linker will fill targets' RVAs to the fields at link
533/// time. This function interprets the relocations to find the data to be used
534/// in the resulting executable.
535static void printRuntimeFunctionRels(const COFFObjectFile *Obj,
536 const RuntimeFunction &RF,
537 uint64_t SectionOffset,
538 const std::vector<RelocationRef> &Rels) {
539 outs() << "Function Table:\n";
540 outs() << " Start Address: ";
541 printCOFFSymbolAddress(outs(), Rels,
542 SectionOffset +
543 /*offsetof(RuntimeFunction, StartAddress)*/ 0,
544 RF.StartAddress);
545 outs() << "\n";
546
547 outs() << " End Address: ";
548 printCOFFSymbolAddress(outs(), Rels,
549 SectionOffset +
550 /*offsetof(RuntimeFunction, EndAddress)*/ 4,
551 RF.EndAddress);
552 outs() << "\n";
553
554 outs() << " Unwind Info Address: ";
555 printCOFFSymbolAddress(outs(), Rels,
556 SectionOffset +
557 /*offsetof(RuntimeFunction, UnwindInfoOffset)*/ 8,
558 RF.UnwindInfoOffset);
559 outs() << "\n";
560
561 ArrayRef<uint8_t> XContents;
562 uint64_t UnwindInfoOffset = 0;
563 error(getSectionContents(
564 Obj, Rels, SectionOffset +
565 /*offsetof(RuntimeFunction, UnwindInfoOffset)*/ 8,
566 XContents, UnwindInfoOffset));
567 if (XContents.empty())
568 return;
569
570 UnwindInfoOffset += RF.UnwindInfoOffset;
571 if (UnwindInfoOffset > XContents.size())
572 return;
573
574 auto *UI = reinterpret_cast<const Win64EH::UnwindInfo *>(XContents.data() +
575 UnwindInfoOffset);
576 printWin64EHUnwindInfo(UI);
577}
578
579void llvm::printCOFFUnwindInfo(const COFFObjectFile *Obj) {
580 if (Obj->getMachine() != COFF::IMAGE_FILE_MACHINE_AMD64) {
581 errs() << "Unsupported image machine type "
582 "(currently only AMD64 is supported).\n";
583 return;
584 }
585
586 std::vector<RelocationRef> Rels;
587 const RuntimeFunction *RFStart;
588 int NumRFs;
589 if (!getPDataSection(Obj, Rels, RFStart, NumRFs))
590 return;
591 ArrayRef<RuntimeFunction> RFs(RFStart, NumRFs);
592
593 bool IsExecutable = Rels.empty();
594 if (IsExecutable) {
595 for (const RuntimeFunction &RF : RFs)
596 printRuntimeFunction(Obj, RF);
597 return;
598 }
599
600 for (const RuntimeFunction &RF : RFs) {
601 uint64_t SectionOffset =
602 std::distance(RFs.begin(), &RF) * sizeof(RuntimeFunction);
603 printRuntimeFunctionRels(Obj, RF, SectionOffset, Rels);
604 }
605}
606
607void llvm::printCOFFFileHeader(const object::ObjectFile *Obj) {
608 const COFFObjectFile *file = dyn_cast<const COFFObjectFile>(Obj);
609 printTLSDirectory(file);
610 printLoadConfiguration(file);
611 printImportTables(file);
612 printExportTable(file);
613}
614
615void llvm::printCOFFSymbolTable(const object::COFFImportFile *i) {
616 unsigned Index = 0;
617 bool IsCode = i->getCOFFImportHeader()->getType() == COFF::IMPORT_CODE;
618
619 for (const object::BasicSymbolRef &Sym : i->symbols()) {
620 std::string Name;
621 raw_string_ostream NS(Name);
622
623 Sym.printName(NS);
624 NS.flush();
625
626 outs() << "[" << format("%2d", Index) << "]"
627 << "(sec " << format("%2d", 0) << ")"
628 << "(fl 0x00)" // Flag bits, which COFF doesn't have.
629 << "(ty " << format("%3x", (IsCode && Index) ? 32 : 0) << ")"
630 << "(scl " << format("%3x", 0) << ") "
631 << "(nx " << 0 << ") "
632 << "0x" << format("%08x", 0) << " " << Name << '\n';
633
634 ++Index;
635 }
636}
637
638void llvm::printCOFFSymbolTable(const COFFObjectFile *coff) {
639 for (unsigned SI = 0, SE = coff->getNumberOfSymbols(); SI != SE; ++SI) {
1
Assuming 'SI' is not equal to 'SE'
2
Loop condition is true. Entering loop body
640 Expected<COFFSymbolRef> Symbol = coff->getSymbol(SI);
641 StringRef Name;
642 error(errorToErrorCode(Symbol.takeError()));
643 error(coff->getSymbolName(*Symbol, Name));
644
645 outs() << "[" << format("%2d", SI) << "]"
646 << "(sec " << format("%2d", int(Symbol->getSectionNumber())) << ")"
647 << "(fl 0x00)" // Flag bits, which COFF doesn't have.
648 << "(ty " << format("%3x", unsigned(Symbol->getType())) << ")"
649 << "(scl " << format("%3x", unsigned(Symbol->getStorageClass())) << ") "
650 << "(nx " << unsigned(Symbol->getNumberOfAuxSymbols()) << ") "
651 << "0x" << format("%08x", unsigned(Symbol->getValue())) << " "
652 << Name << "\n";
653
654 for (unsigned AI = 0, AE = Symbol->getNumberOfAuxSymbols(); AI < AE; ++AI, ++SI) {
3
Assuming 'AI' is < 'AE'
4
Loop condition is true. Entering loop body
655 if (Symbol->isSectionDefinition()) {
5
Taking false branch
656 const coff_aux_section_definition *asd;
657 error(coff->getAuxSymbol<coff_aux_section_definition>(SI + 1, asd));
658
659 int32_t AuxNumber = asd->getNumber(Symbol->isBigObj());
660
661 outs() << "AUX "
662 << format("scnlen 0x%x nreloc %d nlnno %d checksum 0x%x "
663 , unsigned(asd->Length)
664 , unsigned(asd->NumberOfRelocations)
665 , unsigned(asd->NumberOfLinenumbers)
666 , unsigned(asd->CheckSum))
667 << format("assoc %d comdat %d\n"
668 , unsigned(AuxNumber)
669 , unsigned(asd->Selection));
670 } else if (Symbol->isFileRecord()) {
6
Taking true branch
671 const char *FileName;
7
'FileName' declared without an initial value
672 error(coff->getAuxSymbol<char>(SI + 1, FileName));
8
Calling 'COFFObjectFile::getAuxSymbol'
468
Returning from 'COFFObjectFile::getAuxSymbol'
673
674 StringRef Name(FileName, Symbol->getNumberOfAuxSymbols() *
469
1st function call argument is an uninitialized value
675 coff->getSymbolTableEntrySize());
676 outs() << "AUX " << Name.rtrim(StringRef("\0", 1)) << '\n';
677
678 SI = SI + Symbol->getNumberOfAuxSymbols();
679 break;
680 } else if (Symbol->isWeakExternal()) {
681 const coff_aux_weak_external *awe;
682 error(coff->getAuxSymbol<coff_aux_weak_external>(SI + 1, awe));
683
684 outs() << "AUX " << format("indx %d srch %d\n",
685 static_cast<uint32_t>(awe->TagIndex),
686 static_cast<uint32_t>(awe->Characteristics));
687 } else {
688 outs() << "AUX Unknown\n";
689 }
690 }
691 }
692}

/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Object/COFF.h

1//===- COFF.h - COFF object file implementation -----------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file declares the COFFObjectFile class.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_OBJECT_COFF_H
15#define LLVM_OBJECT_COFF_H
16
17#include "llvm/ADT/iterator_range.h"
18#include "llvm/BinaryFormat/COFF.h"
19#include "llvm/DebugInfo/CodeView/CVDebugRecord.h"
20#include "llvm/MC/SubtargetFeature.h"
21#include "llvm/Object/Binary.h"
22#include "llvm/Object/Error.h"
23#include "llvm/Object/ObjectFile.h"
24#include "llvm/Support/BinaryByteStream.h"
25#include "llvm/Support/ConvertUTF.h"
26#include "llvm/Support/Endian.h"
27#include "llvm/Support/ErrorHandling.h"
28#include <cassert>
29#include <cstddef>
30#include <cstdint>
31#include <system_error>
32
33namespace llvm {
34
35template <typename T> class ArrayRef;
36
37namespace object {
38
39class BaseRelocRef;
40class DelayImportDirectoryEntryRef;
41class ExportDirectoryEntryRef;
42class ImportDirectoryEntryRef;
43class ImportedSymbolRef;
44class ResourceSectionRef;
45
46using import_directory_iterator = content_iterator<ImportDirectoryEntryRef>;
47using delay_import_directory_iterator =
48 content_iterator<DelayImportDirectoryEntryRef>;
49using export_directory_iterator = content_iterator<ExportDirectoryEntryRef>;
50using imported_symbol_iterator = content_iterator<ImportedSymbolRef>;
51using base_reloc_iterator = content_iterator<BaseRelocRef>;
52
53/// The DOS compatible header at the front of all PE/COFF executables.
54struct dos_header {
55 char Magic[2];
56 support::ulittle16_t UsedBytesInTheLastPage;
57 support::ulittle16_t FileSizeInPages;
58 support::ulittle16_t NumberOfRelocationItems;
59 support::ulittle16_t HeaderSizeInParagraphs;
60 support::ulittle16_t MinimumExtraParagraphs;
61 support::ulittle16_t MaximumExtraParagraphs;
62 support::ulittle16_t InitialRelativeSS;
63 support::ulittle16_t InitialSP;
64 support::ulittle16_t Checksum;
65 support::ulittle16_t InitialIP;
66 support::ulittle16_t InitialRelativeCS;
67 support::ulittle16_t AddressOfRelocationTable;
68 support::ulittle16_t OverlayNumber;
69 support::ulittle16_t Reserved[4];
70 support::ulittle16_t OEMid;
71 support::ulittle16_t OEMinfo;
72 support::ulittle16_t Reserved2[10];
73 support::ulittle32_t AddressOfNewExeHeader;
74};
75
76struct coff_file_header {
77 support::ulittle16_t Machine;
78 support::ulittle16_t NumberOfSections;
79 support::ulittle32_t TimeDateStamp;
80 support::ulittle32_t PointerToSymbolTable;
81 support::ulittle32_t NumberOfSymbols;
82 support::ulittle16_t SizeOfOptionalHeader;
83 support::ulittle16_t Characteristics;
84
85 bool isImportLibrary() const { return NumberOfSections == 0xffff; }
86};
87
88struct coff_bigobj_file_header {
89 support::ulittle16_t Sig1;
90 support::ulittle16_t Sig2;
91 support::ulittle16_t Version;
92 support::ulittle16_t Machine;
93 support::ulittle32_t TimeDateStamp;
94 uint8_t UUID[16];
95 support::ulittle32_t unused1;
96 support::ulittle32_t unused2;
97 support::ulittle32_t unused3;
98 support::ulittle32_t unused4;
99 support::ulittle32_t NumberOfSections;
100 support::ulittle32_t PointerToSymbolTable;
101 support::ulittle32_t NumberOfSymbols;
102};
103
104/// The 32-bit PE header that follows the COFF header.
105struct pe32_header {
106 support::ulittle16_t Magic;
107 uint8_t MajorLinkerVersion;
108 uint8_t MinorLinkerVersion;
109 support::ulittle32_t SizeOfCode;
110 support::ulittle32_t SizeOfInitializedData;
111 support::ulittle32_t SizeOfUninitializedData;
112 support::ulittle32_t AddressOfEntryPoint;
113 support::ulittle32_t BaseOfCode;
114 support::ulittle32_t BaseOfData;
115 support::ulittle32_t ImageBase;
116 support::ulittle32_t SectionAlignment;
117 support::ulittle32_t FileAlignment;
118 support::ulittle16_t MajorOperatingSystemVersion;
119 support::ulittle16_t MinorOperatingSystemVersion;
120 support::ulittle16_t MajorImageVersion;
121 support::ulittle16_t MinorImageVersion;
122 support::ulittle16_t MajorSubsystemVersion;
123 support::ulittle16_t MinorSubsystemVersion;
124 support::ulittle32_t Win32VersionValue;
125 support::ulittle32_t SizeOfImage;
126 support::ulittle32_t SizeOfHeaders;
127 support::ulittle32_t CheckSum;
128 support::ulittle16_t Subsystem;
129 // FIXME: This should be DllCharacteristics.
130 support::ulittle16_t DLLCharacteristics;
131 support::ulittle32_t SizeOfStackReserve;
132 support::ulittle32_t SizeOfStackCommit;
133 support::ulittle32_t SizeOfHeapReserve;
134 support::ulittle32_t SizeOfHeapCommit;
135 support::ulittle32_t LoaderFlags;
136 // FIXME: This should be NumberOfRvaAndSizes.
137 support::ulittle32_t NumberOfRvaAndSize;
138};
139
140/// The 64-bit PE header that follows the COFF header.
141struct pe32plus_header {
142 support::ulittle16_t Magic;
143 uint8_t MajorLinkerVersion;
144 uint8_t MinorLinkerVersion;
145 support::ulittle32_t SizeOfCode;
146 support::ulittle32_t SizeOfInitializedData;
147 support::ulittle32_t SizeOfUninitializedData;
148 support::ulittle32_t AddressOfEntryPoint;
149 support::ulittle32_t BaseOfCode;
150 support::ulittle64_t ImageBase;
151 support::ulittle32_t SectionAlignment;
152 support::ulittle32_t FileAlignment;
153 support::ulittle16_t MajorOperatingSystemVersion;
154 support::ulittle16_t MinorOperatingSystemVersion;
155 support::ulittle16_t MajorImageVersion;
156 support::ulittle16_t MinorImageVersion;
157 support::ulittle16_t MajorSubsystemVersion;
158 support::ulittle16_t MinorSubsystemVersion;
159 support::ulittle32_t Win32VersionValue;
160 support::ulittle32_t SizeOfImage;
161 support::ulittle32_t SizeOfHeaders;
162 support::ulittle32_t CheckSum;
163 support::ulittle16_t Subsystem;
164 support::ulittle16_t DLLCharacteristics;
165 support::ulittle64_t SizeOfStackReserve;
166 support::ulittle64_t SizeOfStackCommit;
167 support::ulittle64_t SizeOfHeapReserve;
168 support::ulittle64_t SizeOfHeapCommit;
169 support::ulittle32_t LoaderFlags;
170 support::ulittle32_t NumberOfRvaAndSize;
171};
172
173struct data_directory {
174 support::ulittle32_t RelativeVirtualAddress;
175 support::ulittle32_t Size;
176};
177
178struct debug_directory {
179 support::ulittle32_t Characteristics;
180 support::ulittle32_t TimeDateStamp;
181 support::ulittle16_t MajorVersion;
182 support::ulittle16_t MinorVersion;
183 support::ulittle32_t Type;
184 support::ulittle32_t SizeOfData;
185 support::ulittle32_t AddressOfRawData;
186 support::ulittle32_t PointerToRawData;
187};
188
189template <typename IntTy>
190struct import_lookup_table_entry {
191 IntTy Data;
192
193 bool isOrdinal() const { return Data < 0; }
194
195 uint16_t getOrdinal() const {
196 assert(isOrdinal() && "ILT entry is not an ordinal!")(static_cast <bool> (isOrdinal() && "ILT entry is not an ordinal!"
) ? void (0) : __assert_fail ("isOrdinal() && \"ILT entry is not an ordinal!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Object/COFF.h"
, 196, __extension__ __PRETTY_FUNCTION__))
;
197 return Data & 0xFFFF;
198 }
199
200 uint32_t getHintNameRVA() const {
201 assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!")(static_cast <bool> (!isOrdinal() && "ILT entry is not a Hint/Name RVA!"
) ? void (0) : __assert_fail ("!isOrdinal() && \"ILT entry is not a Hint/Name RVA!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Object/COFF.h"
, 201, __extension__ __PRETTY_FUNCTION__))
;
202 return Data & 0xFFFFFFFF;
203 }
204};
205
206using import_lookup_table_entry32 =
207 import_lookup_table_entry<support::little32_t>;
208using import_lookup_table_entry64 =
209 import_lookup_table_entry<support::little64_t>;
210
211struct delay_import_directory_table_entry {
212 // dumpbin reports this field as "Characteristics" instead of "Attributes".
213 support::ulittle32_t Attributes;
214 support::ulittle32_t Name;
215 support::ulittle32_t ModuleHandle;
216 support::ulittle32_t DelayImportAddressTable;
217 support::ulittle32_t DelayImportNameTable;
218 support::ulittle32_t BoundDelayImportTable;
219 support::ulittle32_t UnloadDelayImportTable;
220 support::ulittle32_t TimeStamp;
221};
222
223struct export_directory_table_entry {
224 support::ulittle32_t ExportFlags;
225 support::ulittle32_t TimeDateStamp;
226 support::ulittle16_t MajorVersion;
227 support::ulittle16_t MinorVersion;
228 support::ulittle32_t NameRVA;
229 support::ulittle32_t OrdinalBase;
230 support::ulittle32_t AddressTableEntries;
231 support::ulittle32_t NumberOfNamePointers;
232 support::ulittle32_t ExportAddressTableRVA;
233 support::ulittle32_t NamePointerRVA;
234 support::ulittle32_t OrdinalTableRVA;
235};
236
237union export_address_table_entry {
238 support::ulittle32_t ExportRVA;
239 support::ulittle32_t ForwarderRVA;
240};
241
242using export_name_pointer_table_entry = support::ulittle32_t;
243using export_ordinal_table_entry = support::ulittle16_t;
244
245struct StringTableOffset {
246 support::ulittle32_t Zeroes;
247 support::ulittle32_t Offset;
248};
249
250template <typename SectionNumberType>
251struct coff_symbol {
252 union {
253 char ShortName[COFF::NameSize];
254 StringTableOffset Offset;
255 } Name;
256
257 support::ulittle32_t Value;
258 SectionNumberType SectionNumber;
259
260 support::ulittle16_t Type;
261
262 uint8_t StorageClass;
263 uint8_t NumberOfAuxSymbols;
264};
265
266using coff_symbol16 = coff_symbol<support::ulittle16_t>;
267using coff_symbol32 = coff_symbol<support::ulittle32_t>;
268
269// Contains only common parts of coff_symbol16 and coff_symbol32.
270struct coff_symbol_generic {
271 union {
272 char ShortName[COFF::NameSize];
273 StringTableOffset Offset;
274 } Name;
275 support::ulittle32_t Value;
276};
277
278struct coff_aux_section_definition;
279
280class COFFSymbolRef {
281public:
282 COFFSymbolRef() = default;
283 COFFSymbolRef(const coff_symbol16 *CS) : CS16(CS) {}
284 COFFSymbolRef(const coff_symbol32 *CS) : CS32(CS) {}
285
286 const void *getRawPtr() const {
287 return CS16 ? static_cast<const void *>(CS16) : CS32;
288 }
289
290 const coff_symbol_generic *getGeneric() const {
291 if (CS16)
292 return reinterpret_cast<const coff_symbol_generic *>(CS16);
293 return reinterpret_cast<const coff_symbol_generic *>(CS32);
294 }
295
296 friend bool operator<(COFFSymbolRef A, COFFSymbolRef B) {
297 return A.getRawPtr() < B.getRawPtr();
298 }
299
300 bool isBigObj() const {
301 if (CS16)
302 return false;
303 if (CS32)
304 return true;
305 llvm_unreachable("COFFSymbolRef points to nothing!")::llvm::llvm_unreachable_internal("COFFSymbolRef points to nothing!"
, "/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Object/COFF.h"
, 305)
;
306 }
307
308 const char *getShortName() const {
309 return CS16 ? CS16->Name.ShortName : CS32->Name.ShortName;
310 }
311
312 const StringTableOffset &getStringTableOffset() const {
313 assert(isSet() && "COFFSymbolRef points to nothing!")(static_cast <bool> (isSet() && "COFFSymbolRef points to nothing!"
) ? void (0) : __assert_fail ("isSet() && \"COFFSymbolRef points to nothing!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Object/COFF.h"
, 313, __extension__ __PRETTY_FUNCTION__))
;
314 return CS16 ? CS16->Name.Offset : CS32->Name.Offset;
315 }
316
317 uint32_t getValue() const { return CS16 ? CS16->Value : CS32->Value; }
318
319 int32_t getSectionNumber() const {
320 assert(isSet() && "COFFSymbolRef points to nothing!")(static_cast <bool> (isSet() && "COFFSymbolRef points to nothing!"
) ? void (0) : __assert_fail ("isSet() && \"COFFSymbolRef points to nothing!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Object/COFF.h"
, 320, __extension__ __PRETTY_FUNCTION__))
;
321 if (CS16) {
322 // Reserved sections are returned as negative numbers.
323 if (CS16->SectionNumber <= COFF::MaxNumberOfSections16)
324 return CS16->SectionNumber;
325 return static_cast<int16_t>(CS16->SectionNumber);
326 }
327 return static_cast<int32_t>(CS32->SectionNumber);
328 }
329
330 uint16_t getType() const {
331 assert(isSet() && "COFFSymbolRef points to nothing!")(static_cast <bool> (isSet() && "COFFSymbolRef points to nothing!"
) ? void (0) : __assert_fail ("isSet() && \"COFFSymbolRef points to nothing!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Object/COFF.h"
, 331, __extension__ __PRETTY_FUNCTION__))
;
332 return CS16 ? CS16->Type : CS32->Type;
333 }
334
335 uint8_t getStorageClass() const {
336 assert(isSet() && "COFFSymbolRef points to nothing!")(static_cast <bool> (isSet() && "COFFSymbolRef points to nothing!"
) ? void (0) : __assert_fail ("isSet() && \"COFFSymbolRef points to nothing!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Object/COFF.h"
, 336, __extension__ __PRETTY_FUNCTION__))
;
337 return CS16 ? CS16->StorageClass : CS32->StorageClass;
338 }
339
340 uint8_t getNumberOfAuxSymbols() const {
341 assert(isSet() && "COFFSymbolRef points to nothing!")(static_cast <bool> (isSet() && "COFFSymbolRef points to nothing!"
) ? void (0) : __assert_fail ("isSet() && \"COFFSymbolRef points to nothing!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Object/COFF.h"
, 341, __extension__ __PRETTY_FUNCTION__))
;
342 return CS16 ? CS16->NumberOfAuxSymbols : CS32->NumberOfAuxSymbols;
343 }
344
345 uint8_t getBaseType() const { return getType() & 0x0F; }
346
347 uint8_t getComplexType() const {
348 return (getType() & 0xF0) >> COFF::SCT_COMPLEX_TYPE_SHIFT;
349 }
350
351 template <typename T> const T *getAux() const {
352 return CS16 ? reinterpret_cast<const T *>(CS16 + 1)
353 : reinterpret_cast<const T *>(CS32 + 1);
354 }
355
356 const coff_aux_section_definition *getSectionDefinition() const {
357 if (!getNumberOfAuxSymbols() ||
358 getStorageClass() != COFF::IMAGE_SYM_CLASS_STATIC)
359 return nullptr;
360 return getAux<coff_aux_section_definition>();
361 }
362
363 bool isAbsolute() const {
364 return getSectionNumber() == -1;
365 }
366
367 bool isExternal() const {
368 return getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL;
369 }
370
371 bool isCommon() const {
372 return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED &&
373 getValue() != 0;
374 }
375
376 bool isUndefined() const {
377 return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED &&
378 getValue() == 0;
379 }
380
381 bool isWeakExternal() const {
382 return getStorageClass() == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
383 }
384
385 bool isFunctionDefinition() const {
386 return isExternal() && getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
387 getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION &&
388 !COFF::isReservedSectionNumber(getSectionNumber());
389 }
390
391 bool isFunctionLineInfo() const {
392 return getStorageClass() == COFF::IMAGE_SYM_CLASS_FUNCTION;
393 }
394
395 bool isAnyUndefined() const {
396 return isUndefined() || isWeakExternal();
397 }
398
399 bool isFileRecord() const {
400 return getStorageClass() == COFF::IMAGE_SYM_CLASS_FILE;
401 }
402
403 bool isSection() const {
404 return getStorageClass() == COFF::IMAGE_SYM_CLASS_SECTION;
405 }
406
407 bool isSectionDefinition() const {
408 // C++/CLI creates external ABS symbols for non-const appdomain globals.
409 // These are also followed by an auxiliary section definition.
410 bool isAppdomainGlobal =
411 getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
412 getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE;
413 bool isOrdinarySection = getStorageClass() == COFF::IMAGE_SYM_CLASS_STATIC;
414 if (!getNumberOfAuxSymbols())
415 return false;
416 return isAppdomainGlobal || isOrdinarySection;
417 }
418
419 bool isCLRToken() const {
420 return getStorageClass() == COFF::IMAGE_SYM_CLASS_CLR_TOKEN;
421 }
422
423private:
424 bool isSet() const { return CS16 || CS32; }
425
426 const coff_symbol16 *CS16 = nullptr;
427 const coff_symbol32 *CS32 = nullptr;
428};
429
430struct coff_section {
431 char Name[COFF::NameSize];
432 support::ulittle32_t VirtualSize;
433 support::ulittle32_t VirtualAddress;
434 support::ulittle32_t SizeOfRawData;
435 support::ulittle32_t PointerToRawData;
436 support::ulittle32_t PointerToRelocations;
437 support::ulittle32_t PointerToLinenumbers;
438 support::ulittle16_t NumberOfRelocations;
439 support::ulittle16_t NumberOfLinenumbers;
440 support::ulittle32_t Characteristics;
441
442 // Returns true if the actual number of relocations is stored in
443 // VirtualAddress field of the first relocation table entry.
444 bool hasExtendedRelocations() const {
445 return (Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL) &&
446 NumberOfRelocations == UINT16_MAX(65535);
447 }
448
449 uint32_t getAlignment() const {
450 // The IMAGE_SCN_TYPE_NO_PAD bit is a legacy way of getting to
451 // IMAGE_SCN_ALIGN_1BYTES.
452 if (Characteristics & COFF::IMAGE_SCN_TYPE_NO_PAD)
453 return 1;
454
455 // Bit [20:24] contains section alignment. Both 0 and 1 mean alignment 1.
456 uint32_t Shift = (Characteristics >> 20) & 0xF;
457 if (Shift > 0)
458 return 1U << (Shift - 1);
459 return 1;
460 }
461};
462
463struct coff_relocation {
464 support::ulittle32_t VirtualAddress;
465 support::ulittle32_t SymbolTableIndex;
466 support::ulittle16_t Type;
467};
468
469struct coff_aux_function_definition {
470 support::ulittle32_t TagIndex;
471 support::ulittle32_t TotalSize;
472 support::ulittle32_t PointerToLinenumber;
473 support::ulittle32_t PointerToNextFunction;
474 char Unused1[2];
475};
476
477static_assert(sizeof(coff_aux_function_definition) == 18,
478 "auxiliary entry must be 18 bytes");
479
480struct coff_aux_bf_and_ef_symbol {
481 char Unused1[4];
482 support::ulittle16_t Linenumber;
483 char Unused2[6];
484 support::ulittle32_t PointerToNextFunction;
485 char Unused3[2];
486};
487
488static_assert(sizeof(coff_aux_bf_and_ef_symbol) == 18,
489 "auxiliary entry must be 18 bytes");
490
491struct coff_aux_weak_external {
492 support::ulittle32_t TagIndex;
493 support::ulittle32_t Characteristics;
494 char Unused1[10];
495};
496
497static_assert(sizeof(coff_aux_weak_external) == 18,
498 "auxiliary entry must be 18 bytes");
499
500struct coff_aux_section_definition {
501 support::ulittle32_t Length;
502 support::ulittle16_t NumberOfRelocations;
503 support::ulittle16_t NumberOfLinenumbers;
504 support::ulittle32_t CheckSum;
505 support::ulittle16_t NumberLowPart;
506 uint8_t Selection;
507 uint8_t Unused;
508 support::ulittle16_t NumberHighPart;
509 int32_t getNumber(bool IsBigObj) const {
510 uint32_t Number = static_cast<uint32_t>(NumberLowPart);
511 if (IsBigObj)
512 Number |= static_cast<uint32_t>(NumberHighPart) << 16;
513 return static_cast<int32_t>(Number);
514 }
515};
516
517static_assert(sizeof(coff_aux_section_definition) == 18,
518 "auxiliary entry must be 18 bytes");
519
520struct coff_aux_clr_token {
521 uint8_t AuxType;
522 uint8_t Reserved;
523 support::ulittle32_t SymbolTableIndex;
524 char MBZ[12];
525};
526
527static_assert(sizeof(coff_aux_clr_token) == 18,
528 "auxiliary entry must be 18 bytes");
529
530struct coff_import_header {
531 support::ulittle16_t Sig1;
532 support::ulittle16_t Sig2;
533 support::ulittle16_t Version;
534 support::ulittle16_t Machine;
535 support::ulittle32_t TimeDateStamp;
536 support::ulittle32_t SizeOfData;
537 support::ulittle16_t OrdinalHint;
538 support::ulittle16_t TypeInfo;
539
540 int getType() const { return TypeInfo & 0x3; }
541 int getNameType() const { return (TypeInfo >> 2) & 0x7; }
542};
543
544struct coff_import_directory_table_entry {
545 support::ulittle32_t ImportLookupTableRVA;
546 support::ulittle32_t TimeDateStamp;
547 support::ulittle32_t ForwarderChain;
548 support::ulittle32_t NameRVA;
549 support::ulittle32_t ImportAddressTableRVA;
550
551 bool isNull() const {
552 return ImportLookupTableRVA == 0 && TimeDateStamp == 0 &&
553 ForwarderChain == 0 && NameRVA == 0 && ImportAddressTableRVA == 0;
554 }
555};
556
557template <typename IntTy>
558struct coff_tls_directory {
559 IntTy StartAddressOfRawData;
560 IntTy EndAddressOfRawData;
561 IntTy AddressOfIndex;
562 IntTy AddressOfCallBacks;
563 support::ulittle32_t SizeOfZeroFill;
564 support::ulittle32_t Characteristics;
565
566 uint32_t getAlignment() const {
567 // Bit [20:24] contains section alignment.
568 uint32_t Shift = (Characteristics & 0x00F00000) >> 20;
569 if (Shift > 0)
570 return 1U << (Shift - 1);
571 return 0;
572 }
573};
574
575using coff_tls_directory32 = coff_tls_directory<support::little32_t>;
576using coff_tls_directory64 = coff_tls_directory<support::little64_t>;
577
578/// Bits in control flow guard flags as we understand them.
579enum class coff_guard_flags : uint32_t {
580 CFInstrumented = 0x00000100,
581 HasFidTable = 0x00000400,
582 ProtectDelayLoadIAT = 0x00001000,
583 DelayLoadIATSection = 0x00002000, // Delay load in separate section
584 HasLongJmpTable = 0x00010000,
585 FidTableHasFlags = 0x10000000, // Indicates that fid tables are 5 bytes
586};
587
588struct coff_load_config_code_integrity {
589 support::ulittle16_t Flags;
590 support::ulittle16_t Catalog;
591 support::ulittle32_t CatalogOffset;
592 support::ulittle32_t Reserved;
593};
594
595/// 32-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY32)
596struct coff_load_configuration32 {
597 support::ulittle32_t Size;
598 support::ulittle32_t TimeDateStamp;
599 support::ulittle16_t MajorVersion;
600 support::ulittle16_t MinorVersion;
601 support::ulittle32_t GlobalFlagsClear;
602 support::ulittle32_t GlobalFlagsSet;
603 support::ulittle32_t CriticalSectionDefaultTimeout;
604 support::ulittle32_t DeCommitFreeBlockThreshold;
605 support::ulittle32_t DeCommitTotalFreeThreshold;
606 support::ulittle32_t LockPrefixTable;
607 support::ulittle32_t MaximumAllocationSize;
608 support::ulittle32_t VirtualMemoryThreshold;
609 support::ulittle32_t ProcessAffinityMask;
610 support::ulittle32_t ProcessHeapFlags;
611 support::ulittle16_t CSDVersion;
612 support::ulittle16_t DependentLoadFlags;
613 support::ulittle32_t EditList;
614 support::ulittle32_t SecurityCookie;
615 support::ulittle32_t SEHandlerTable;
616 support::ulittle32_t SEHandlerCount;
617
618 // Added in MSVC 2015 for /guard:cf.
619 support::ulittle32_t GuardCFCheckFunction;
620 support::ulittle32_t GuardCFCheckDispatch;
621 support::ulittle32_t GuardCFFunctionTable;
622 support::ulittle32_t GuardCFFunctionCount;
623 support::ulittle32_t GuardFlags; // coff_guard_flags
624
625 // Added in MSVC 2017
626 coff_load_config_code_integrity CodeIntegrity;
627 support::ulittle32_t GuardAddressTakenIatEntryTable;
628 support::ulittle32_t GuardAddressTakenIatEntryCount;
629 support::ulittle32_t GuardLongJumpTargetTable;
630 support::ulittle32_t GuardLongJumpTargetCount;
631 support::ulittle32_t DynamicValueRelocTable;
632 support::ulittle32_t CHPEMetadataPointer;
633 support::ulittle32_t GuardRFFailureRoutine;
634 support::ulittle32_t GuardRFFailureRoutineFunctionPointer;
635 support::ulittle32_t DynamicValueRelocTableOffset;
636 support::ulittle16_t DynamicValueRelocTableSection;
637 support::ulittle16_t Reserved2;
638 support::ulittle32_t GuardRFVerifyStackPointerFunctionPointer;
639 support::ulittle32_t HotPatchTableOffset;
640};
641
642/// 64-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY64)
643struct coff_load_configuration64 {
644 support::ulittle32_t Size;
645 support::ulittle32_t TimeDateStamp;
646 support::ulittle16_t MajorVersion;
647 support::ulittle16_t MinorVersion;
648 support::ulittle32_t GlobalFlagsClear;
649 support::ulittle32_t GlobalFlagsSet;
650 support::ulittle32_t CriticalSectionDefaultTimeout;
651 support::ulittle64_t DeCommitFreeBlockThreshold;
652 support::ulittle64_t DeCommitTotalFreeThreshold;
653 support::ulittle64_t LockPrefixTable;
654 support::ulittle64_t MaximumAllocationSize;
655 support::ulittle64_t VirtualMemoryThreshold;
656 support::ulittle64_t ProcessAffinityMask;
657 support::ulittle32_t ProcessHeapFlags;
658 support::ulittle16_t CSDVersion;
659 support::ulittle16_t DependentLoadFlags;
660 support::ulittle64_t EditList;
661 support::ulittle64_t SecurityCookie;
662 support::ulittle64_t SEHandlerTable;
663 support::ulittle64_t SEHandlerCount;
664
665 // Added in MSVC 2015 for /guard:cf.
666 support::ulittle64_t GuardCFCheckFunction;
667 support::ulittle64_t GuardCFCheckDispatch;
668 support::ulittle64_t GuardCFFunctionTable;
669 support::ulittle64_t GuardCFFunctionCount;
670 support::ulittle32_t GuardFlags;
671
672 // Added in MSVC 2017
673 coff_load_config_code_integrity CodeIntegrity;
674 support::ulittle64_t GuardAddressTakenIatEntryTable;
675 support::ulittle64_t GuardAddressTakenIatEntryCount;
676 support::ulittle64_t GuardLongJumpTargetTable;
677 support::ulittle64_t GuardLongJumpTargetCount;
678 support::ulittle64_t DynamicValueRelocTable;
679 support::ulittle64_t CHPEMetadataPointer;
680 support::ulittle64_t GuardRFFailureRoutine;
681 support::ulittle64_t GuardRFFailureRoutineFunctionPointer;
682 support::ulittle32_t DynamicValueRelocTableOffset;
683 support::ulittle16_t DynamicValueRelocTableSection;
684 support::ulittle16_t Reserved2;
685 support::ulittle64_t GuardRFVerifyStackPointerFunctionPointer;
686 support::ulittle32_t HotPatchTableOffset;
687};
688
689struct coff_runtime_function_x64 {
690 support::ulittle32_t BeginAddress;
691 support::ulittle32_t EndAddress;
692 support::ulittle32_t UnwindInformation;
693};
694
695struct coff_base_reloc_block_header {
696 support::ulittle32_t PageRVA;
697 support::ulittle32_t BlockSize;
698};
699
700struct coff_base_reloc_block_entry {
701 support::ulittle16_t Data;
702
703 int getType() const { return Data >> 12; }
704 int getOffset() const { return Data & ((1 << 12) - 1); }
705};
706
707struct coff_resource_dir_entry {
708 union {
709 support::ulittle32_t NameOffset;
710 support::ulittle32_t ID;
711 uint32_t getNameOffset() const {
712 return maskTrailingOnes<uint32_t>(31) & NameOffset;
713 }
714 // Even though the PE/COFF spec doesn't mention this, the high bit of a name
715 // offset is set.
716 void setNameOffset(uint32_t Offset) { NameOffset = Offset | (1 << 31); }
717 } Identifier;
718 union {
719 support::ulittle32_t DataEntryOffset;
720 support::ulittle32_t SubdirOffset;
721
722 bool isSubDir() const { return SubdirOffset >> 31; }
723 uint32_t value() const {
724 return maskTrailingOnes<uint32_t>(31) & SubdirOffset;
725 }
726
727 } Offset;
728};
729
730struct coff_resource_data_entry {
731 support::ulittle32_t DataRVA;
732 support::ulittle32_t DataSize;
733 support::ulittle32_t Codepage;
734 support::ulittle32_t Reserved;
735};
736
737struct coff_resource_dir_table {
738 support::ulittle32_t Characteristics;
739 support::ulittle32_t TimeDateStamp;
740 support::ulittle16_t MajorVersion;
741 support::ulittle16_t MinorVersion;
742 support::ulittle16_t NumberOfNameEntries;
743 support::ulittle16_t NumberOfIDEntries;
744};
745
746struct debug_h_header {
747 support::ulittle32_t Magic;
748 support::ulittle16_t Version;
749 support::ulittle16_t HashAlgorithm;
750};
751
752class COFFObjectFile : public ObjectFile {
753private:
754 friend class ImportDirectoryEntryRef;
755 friend class ExportDirectoryEntryRef;
756 const coff_file_header *COFFHeader;
757 const coff_bigobj_file_header *COFFBigObjHeader;
758 const pe32_header *PE32Header;
759 const pe32plus_header *PE32PlusHeader;
760 const data_directory *DataDirectory;
761 const coff_section *SectionTable;
762 const coff_symbol16 *SymbolTable16;
763 const coff_symbol32 *SymbolTable32;
764 const char *StringTable;
765 uint32_t StringTableSize;
766 const coff_import_directory_table_entry *ImportDirectory;
767 const delay_import_directory_table_entry *DelayImportDirectory;
768 uint32_t NumberOfDelayImportDirectory;
769 const export_directory_table_entry *ExportDirectory;
770 const coff_base_reloc_block_header *BaseRelocHeader;
771 const coff_base_reloc_block_header *BaseRelocEnd;
772 const debug_directory *DebugDirectoryBegin;
773 const debug_directory *DebugDirectoryEnd;
774 // Either coff_load_configuration32 or coff_load_configuration64.
775 const void *LoadConfig = nullptr;
776
777 std::error_code getString(uint32_t offset, StringRef &Res) const;
778
779 template <typename coff_symbol_type>
780 const coff_symbol_type *toSymb(DataRefImpl Symb) const;
781 const coff_section *toSec(DataRefImpl Sec) const;
782 const coff_relocation *toRel(DataRefImpl Rel) const;
783
784 std::error_code initSymbolTablePtr();
785 std::error_code initImportTablePtr();
786 std::error_code initDelayImportTablePtr();
787 std::error_code initExportTablePtr();
788 std::error_code initBaseRelocPtr();
789 std::error_code initDebugDirectoryPtr();
790 std::error_code initLoadConfigPtr();
791
792public:
793 uintptr_t getSymbolTable() const {
794 if (SymbolTable16)
795 return reinterpret_cast<uintptr_t>(SymbolTable16);
796 if (SymbolTable32)
797 return reinterpret_cast<uintptr_t>(SymbolTable32);
798 return uintptr_t(0);
799 }
800
801 uint16_t getMachine() const {
802 if (COFFHeader)
803 return COFFHeader->Machine;
804 if (COFFBigObjHeader)
805 return COFFBigObjHeader->Machine;
806 llvm_unreachable("no COFF header!")::llvm::llvm_unreachable_internal("no COFF header!", "/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Object/COFF.h"
, 806)
;
807 }
808
809 uint16_t getSizeOfOptionalHeader() const {
810 if (COFFHeader)
811 return COFFHeader->isImportLibrary() ? 0
812 : COFFHeader->SizeOfOptionalHeader;
813 // bigobj doesn't have this field.
814 if (COFFBigObjHeader)
815 return 0;
816 llvm_unreachable("no COFF header!")::llvm::llvm_unreachable_internal("no COFF header!", "/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Object/COFF.h"
, 816)
;
817 }
818
819 uint16_t getCharacteristics() const {
820 if (COFFHeader)
821 return COFFHeader->isImportLibrary() ? 0 : COFFHeader->Characteristics;
822 // bigobj doesn't have characteristics to speak of,
823 // editbin will silently lie to you if you attempt to set any.
824 if (COFFBigObjHeader)
825 return 0;
826 llvm_unreachable("no COFF header!")::llvm::llvm_unreachable_internal("no COFF header!", "/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Object/COFF.h"
, 826)
;
827 }
828
829 uint32_t getTimeDateStamp() const {
830 if (COFFHeader)
831 return COFFHeader->TimeDateStamp;
832 if (COFFBigObjHeader)
833 return COFFBigObjHeader->TimeDateStamp;
834 llvm_unreachable("no COFF header!")::llvm::llvm_unreachable_internal("no COFF header!", "/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Object/COFF.h"
, 834)
;
835 }
836
837 uint32_t getNumberOfSections() const {
838 if (COFFHeader)
839 return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSections;
840 if (COFFBigObjHeader)
841 return COFFBigObjHeader->NumberOfSections;
842 llvm_unreachable("no COFF header!")::llvm::llvm_unreachable_internal("no COFF header!", "/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Object/COFF.h"
, 842)
;
843 }
844
845 uint32_t getPointerToSymbolTable() const {
846 if (COFFHeader)
847 return COFFHeader->isImportLibrary() ? 0
848 : COFFHeader->PointerToSymbolTable;
849 if (COFFBigObjHeader)
850 return COFFBigObjHeader->PointerToSymbolTable;
851 llvm_unreachable("no COFF header!")::llvm::llvm_unreachable_internal("no COFF header!", "/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Object/COFF.h"
, 851)
;
852 }
853
854 uint32_t getRawNumberOfSymbols() const {
855 if (COFFHeader)
856 return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSymbols;
857 if (COFFBigObjHeader)
858 return COFFBigObjHeader->NumberOfSymbols;
859 llvm_unreachable("no COFF header!")::llvm::llvm_unreachable_internal("no COFF header!", "/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Object/COFF.h"
, 859)
;
860 }
861
862 uint32_t getNumberOfSymbols() const {
863 if (!SymbolTable16 && !SymbolTable32)
864 return 0;
865 return getRawNumberOfSymbols();
866 }
867
868 const coff_load_configuration32 *getLoadConfig32() const {
869 assert(!is64())(static_cast <bool> (!is64()) ? void (0) : __assert_fail
("!is64()", "/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Object/COFF.h"
, 869, __extension__ __PRETTY_FUNCTION__))
;
870 return reinterpret_cast<const coff_load_configuration32 *>(LoadConfig);
871 }
872
873 const coff_load_configuration64 *getLoadConfig64() const {
874 assert(is64())(static_cast <bool> (is64()) ? void (0) : __assert_fail
("is64()", "/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Object/COFF.h"
, 874, __extension__ __PRETTY_FUNCTION__))
;
875 return reinterpret_cast<const coff_load_configuration64 *>(LoadConfig);
876 }
877
878protected:
879 void moveSymbolNext(DataRefImpl &Symb) const override;
880 Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
881 Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
882 uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
883 uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
884 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
885 uint32_t getSymbolFlags(DataRefImpl Symb) const override;
886 Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
887 Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
888 void moveSectionNext(DataRefImpl &Sec) const override;
889 std::error_code getSectionName(DataRefImpl Sec,
890 StringRef &Res) const override;
891 uint64_t getSectionAddress(DataRefImpl Sec) const override;
892 uint64_t getSectionIndex(DataRefImpl Sec) const override;
893 uint64_t getSectionSize(DataRefImpl Sec) const override;
894 std::error_code getSectionContents(DataRefImpl Sec,
895 StringRef &Res) const override;
896 uint64_t getSectionAlignment(DataRefImpl Sec) const override;
897 bool isSectionCompressed(DataRefImpl Sec) const override;
898 bool isSectionText(DataRefImpl Sec) const override;
899 bool isSectionData(DataRefImpl Sec) const override;
900 bool isSectionBSS(DataRefImpl Sec) const override;
901 bool isSectionVirtual(DataRefImpl Sec) const override;
902 relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
903 relocation_iterator section_rel_end(DataRefImpl Sec) const override;
904
905 void moveRelocationNext(DataRefImpl &Rel) const override;
906 uint64_t getRelocationOffset(DataRefImpl Rel) const override;
907 symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
908 uint64_t getRelocationType(DataRefImpl Rel) const override;
909 void getRelocationTypeName(DataRefImpl Rel,
910 SmallVectorImpl<char> &Result) const override;
911
912public:
913 COFFObjectFile(MemoryBufferRef Object, std::error_code &EC);
914
915 basic_symbol_iterator symbol_begin() const override;
916 basic_symbol_iterator symbol_end() const override;
917 section_iterator section_begin() const override;
918 section_iterator section_end() const override;
919
920 const coff_section *getCOFFSection(const SectionRef &Section) const;
921 COFFSymbolRef getCOFFSymbol(const DataRefImpl &Ref) const;
922 COFFSymbolRef getCOFFSymbol(const SymbolRef &Symbol) const;
923 const coff_relocation *getCOFFRelocation(const RelocationRef &Reloc) const;
924 unsigned getSectionID(SectionRef Sec) const;
925 unsigned getSymbolSectionID(SymbolRef Sym) const;
926
927 uint8_t getBytesInAddress() const override;
928 StringRef getFileFormatName() const override;
929 Triple::ArchType getArch() const override;
930 SubtargetFeatures getFeatures() const override { return SubtargetFeatures(); }
931
932 import_directory_iterator import_directory_begin() const;
933 import_directory_iterator import_directory_end() const;
934 delay_import_directory_iterator delay_import_directory_begin() const;
935 delay_import_directory_iterator delay_import_directory_end() const;
936 export_directory_iterator export_directory_begin() const;
937 export_directory_iterator export_directory_end() const;
938 base_reloc_iterator base_reloc_begin() const;
939 base_reloc_iterator base_reloc_end() const;
940 const debug_directory *debug_directory_begin() const {
941 return DebugDirectoryBegin;
942 }
943 const debug_directory *debug_directory_end() const {
944 return DebugDirectoryEnd;
945 }
946
947 iterator_range<import_directory_iterator> import_directories() const;
948 iterator_range<delay_import_directory_iterator>
949 delay_import_directories() const;
950 iterator_range<export_directory_iterator> export_directories() const;
951 iterator_range<base_reloc_iterator> base_relocs() const;
952 iterator_range<const debug_directory *> debug_directories() const {
953 return make_range(debug_directory_begin(), debug_directory_end());
954 }
955
956 const dos_header *getDOSHeader() const {
957 if (!PE32Header && !PE32PlusHeader)
958 return nullptr;
959 return reinterpret_cast<const dos_header *>(base());
960 }
961 std::error_code getPE32Header(const pe32_header *&Res) const;
962 std::error_code getPE32PlusHeader(const pe32plus_header *&Res) const;
963 std::error_code getDataDirectory(uint32_t index,
964 const data_directory *&Res) const;
965 std::error_code getSection(int32_t index, const coff_section *&Res) const;
966
967 template <typename coff_symbol_type>
968 std::error_code getSymbol(uint32_t Index,
969 const coff_symbol_type *&Res) const {
970 if (Index >= getNumberOfSymbols())
971 return object_error::parse_failed;
972
973 Res = reinterpret_cast<coff_symbol_type *>(getSymbolTable()) + Index;
974 return std::error_code();
975 }
976 Expected<COFFSymbolRef> getSymbol(uint32_t index) const {
977 if (SymbolTable16) {
10
Assuming the condition is false
11
Taking false branch
978 const coff_symbol16 *Symb = nullptr;
979 if (std::error_code EC = getSymbol(index, Symb))
980 return errorCodeToError(EC);
981 return COFFSymbolRef(Symb);
982 }
983 if (SymbolTable32) {
12
Assuming the condition is false
13
Taking false branch
984 const coff_symbol32 *Symb = nullptr;
985 if (std::error_code EC = getSymbol(index, Symb))
986 return errorCodeToError(EC);
987 return COFFSymbolRef(Symb);
988 }
989 return errorCodeToError(object_error::parse_failed);
14
Calling constructor for 'error_code'
19
Returning from constructor for 'error_code'
20
Calling move constructor for 'Error'
44
Returning from move constructor for 'Error'
45
Calling move constructor for 'Expected'
130
Returning from move constructor for 'Expected'
990 }
991
992 template <typename T>
993 std::error_code getAuxSymbol(uint32_t index, const T *&Res) const {
994 Expected<COFFSymbolRef> S = getSymbol(index);
9
Calling 'COFFObjectFile::getSymbol'
131
Returning from 'COFFObjectFile::getSymbol'
132
Calling move constructor for 'Expected'
216
Returning from move constructor for 'Expected'
995 if (Error E = S.takeError())
217
Calling 'Expected::takeError'
373
Returning from 'Expected::takeError'
374
Calling move constructor for 'Error'
398
Returning from move constructor for 'Error'
399
Calling 'Error::operator bool'
408
Returning from 'Error::operator bool'
409
Taking true branch
996 return errorToErrorCode(std::move(E));
410
Calling 'move'
411
Returning from 'move'
412
Calling move constructor for 'Error'
436
Returning from move constructor for 'Error'
437
Calling '~Error'
444
Returning from '~Error'
445
Calling '~Expected'
466
Returning from '~Expected'
997 Res = reinterpret_cast<const T *>(S->getRawPtr());
998 return std::error_code();
999 }
467
Returning without writing to 'Res'
1000
1001 std::error_code getSymbolName(COFFSymbolRef Symbol, StringRef &Res) const;
1002 std::error_code getSymbolName(const coff_symbol_generic *Symbol,
1003 StringRef &Res) const;
1004
1005 ArrayRef<uint8_t> getSymbolAuxData(COFFSymbolRef Symbol) const;
1006
1007 size_t getSymbolTableEntrySize() const {
1008 if (COFFHeader)
1009 return sizeof(coff_symbol16);
1010 if (COFFBigObjHeader)
1011 return sizeof(coff_symbol32);
1012 llvm_unreachable("null symbol table pointer!")::llvm::llvm_unreachable_internal("null symbol table pointer!"
, "/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Object/COFF.h"
, 1012)
;
1013 }
1014
1015 iterator_range<const coff_relocation *>
1016 getRelocations(const coff_section *Sec) const;
1017
1018 std::error_code getSectionName(const coff_section *Sec, StringRef &Res) const;
1019 uint64_t getSectionSize(const coff_section *Sec) const;
1020 std::error_code getSectionContents(const coff_section *Sec,
1021 ArrayRef<uint8_t> &Res) const;
1022
1023 uint64_t getImageBase() const;
1024 std::error_code getVaPtr(uint64_t VA, uintptr_t &Res) const;
1025 std::error_code getRvaPtr(uint32_t Rva, uintptr_t &Res) const;
1026
1027 /// Given an RVA base and size, returns a valid array of bytes or an error
1028 /// code if the RVA and size is not contained completely within a valid
1029 /// section.
1030 std::error_code getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
1031 ArrayRef<uint8_t> &Contents) const;
1032
1033 std::error_code getHintName(uint32_t Rva, uint16_t &Hint,
1034 StringRef &Name) const;
1035
1036 /// Get PDB information out of a codeview debug directory entry.
1037 std::error_code getDebugPDBInfo(const debug_directory *DebugDir,
1038 const codeview::DebugInfo *&Info,
1039 StringRef &PDBFileName) const;
1040
1041 /// Get PDB information from an executable. If the information is not present,
1042 /// Info will be set to nullptr and PDBFileName will be empty. An error is
1043 /// returned only on corrupt object files. Convenience accessor that can be
1044 /// used if the debug directory is not already handy.
1045 std::error_code getDebugPDBInfo(const codeview::DebugInfo *&Info,
1046 StringRef &PDBFileName) const;
1047
1048 bool isRelocatableObject() const override;
1049 bool is64() const { return PE32PlusHeader; }
1050
1051 static bool classof(const Binary *v) { return v->isCOFF(); }
1052};
1053
1054// The iterator for the import directory table.
1055class ImportDirectoryEntryRef {
1056public:
1057 ImportDirectoryEntryRef() = default;
1058 ImportDirectoryEntryRef(const coff_import_directory_table_entry *Table,
1059 uint32_t I, const COFFObjectFile *Owner)
1060 : ImportTable(Table), Index(I), OwningObject(Owner) {}
1061
1062 bool operator==(const ImportDirectoryEntryRef &Other) const;
1063 void moveNext();
1064
1065 imported_symbol_iterator imported_symbol_begin() const;
1066 imported_symbol_iterator imported_symbol_end() const;
1067 iterator_range<imported_symbol_iterator> imported_symbols() const;
1068
1069 imported_symbol_iterator lookup_table_begin() const;
1070 imported_symbol_iterator lookup_table_end() const;
1071 iterator_range<imported_symbol_iterator> lookup_table_symbols() const;
1072
1073 std::error_code getName(StringRef &Result) const;
1074 std::error_code getImportLookupTableRVA(uint32_t &Result) const;
1075 std::error_code getImportAddressTableRVA(uint32_t &Result) const;
1076
1077 std::error_code
1078 getImportTableEntry(const coff_import_directory_table_entry *&Result) const;
1079
1080private:
1081 const coff_import_directory_table_entry *ImportTable;
1082 uint32_t Index;
1083 const COFFObjectFile *OwningObject = nullptr;
1084};
1085
1086class DelayImportDirectoryEntryRef {
1087public:
1088 DelayImportDirectoryEntryRef() = default;
1089 DelayImportDirectoryEntryRef(const delay_import_directory_table_entry *T,
1090 uint32_t I, const COFFObjectFile *Owner)
1091 : Table(T), Index(I), OwningObject(Owner) {}
1092
1093 bool operator==(const DelayImportDirectoryEntryRef &Other) const;
1094 void moveNext();
1095
1096 imported_symbol_iterator imported_symbol_begin() const;
1097 imported_symbol_iterator imported_symbol_end() const;
1098 iterator_range<imported_symbol_iterator> imported_symbols() const;
1099
1100 std::error_code getName(StringRef &Result) const;
1101 std::error_code getDelayImportTable(
1102 const delay_import_directory_table_entry *&Result) const;
1103 std::error_code getImportAddress(int AddrIndex, uint64_t &Result) const;
1104
1105private:
1106 const delay_import_directory_table_entry *Table;
1107 uint32_t Index;
1108 const COFFObjectFile *OwningObject = nullptr;
1109};
1110
1111// The iterator for the export directory table entry.
1112class ExportDirectoryEntryRef {
1113public:
1114 ExportDirectoryEntryRef() = default;
1115 ExportDirectoryEntryRef(const export_directory_table_entry *Table, uint32_t I,
1116 const COFFObjectFile *Owner)
1117 : ExportTable(Table), Index(I), OwningObject(Owner) {}
1118
1119 bool operator==(const ExportDirectoryEntryRef &Other) const;
1120 void moveNext();
1121
1122 std::error_code getDllName(StringRef &Result) const;
1123 std::error_code getOrdinalBase(uint32_t &Result) const;
1124 std::error_code getOrdinal(uint32_t &Result) const;
1125 std::error_code getExportRVA(uint32_t &Result) const;
1126 std::error_code getSymbolName(StringRef &Result) const;
1127
1128 std::error_code isForwarder(bool &Result) const;
1129 std::error_code getForwardTo(StringRef &Result) const;
1130
1131private:
1132 const export_directory_table_entry *ExportTable;
1133 uint32_t Index;
1134 const COFFObjectFile *OwningObject = nullptr;
1135};
1136
1137class ImportedSymbolRef {
1138public:
1139 ImportedSymbolRef() = default;
1140 ImportedSymbolRef(const import_lookup_table_entry32 *Entry, uint32_t I,
1141 const COFFObjectFile *Owner)
1142 : Entry32(Entry), Entry64(nullptr), Index(I), OwningObject(Owner) {}
1143 ImportedSymbolRef(const import_lookup_table_entry64 *Entry, uint32_t I,
1144 const COFFObjectFile *Owner)
1145 : Entry32(nullptr), Entry64(Entry), Index(I), OwningObject(Owner) {}
1146
1147 bool operator==(const ImportedSymbolRef &Other) const;
1148 void moveNext();
1149
1150 std::error_code getSymbolName(StringRef &Result) const;
1151 std::error_code isOrdinal(bool &Result) const;
1152 std::error_code getOrdinal(uint16_t &Result) const;
1153 std::error_code getHintNameRVA(uint32_t &Result) const;
1154
1155private:
1156 const import_lookup_table_entry32 *Entry32;
1157 const import_lookup_table_entry64 *Entry64;
1158 uint32_t Index;
1159 const COFFObjectFile *OwningObject = nullptr;
1160};
1161
1162class BaseRelocRef {
1163public:
1164 BaseRelocRef() = default;
1165 BaseRelocRef(const coff_base_reloc_block_header *Header,
1166 const COFFObjectFile *Owner)
1167 : Header(Header), Index(0) {}
1168
1169 bool operator==(const BaseRelocRef &Other) const;
1170 void moveNext();
1171
1172 std::error_code getType(uint8_t &Type) const;
1173 std::error_code getRVA(uint32_t &Result) const;
1174
1175private:
1176 const coff_base_reloc_block_header *Header;
1177 uint32_t Index;
1178};
1179
1180class ResourceSectionRef {
1181public:
1182 ResourceSectionRef() = default;
1183 explicit ResourceSectionRef(StringRef Ref) : BBS(Ref, support::little) {}
1184
1185 Expected<ArrayRef<UTF16>>
1186 getEntryNameString(const coff_resource_dir_entry &Entry);
1187 Expected<const coff_resource_dir_table &>
1188 getEntrySubDir(const coff_resource_dir_entry &Entry);
1189 Expected<const coff_resource_dir_table &> getBaseTable();
1190
1191private:
1192 BinaryByteStream BBS;
1193
1194 Expected<const coff_resource_dir_table &> getTableAtOffset(uint32_t Offset);
1195 Expected<ArrayRef<UTF16>> getDirStringAtOffset(uint32_t Offset);
1196};
1197
1198// Corresponds to `_FPO_DATA` structure in the PE/COFF spec.
1199struct FpoData {
1200 support::ulittle32_t Offset; // ulOffStart: Offset 1st byte of function code
1201 support::ulittle32_t Size; // cbProcSize: # bytes in function
1202 support::ulittle32_t NumLocals; // cdwLocals: # bytes in locals/4
1203 support::ulittle16_t NumParams; // cdwParams: # bytes in params/4
1204 support::ulittle16_t Attributes;
1205
1206 // cbProlog: # bytes in prolog
1207 int getPrologSize() const { return Attributes & 0xF; }
1208
1209 // cbRegs: # regs saved
1210 int getNumSavedRegs() const { return (Attributes >> 8) & 0x7; }
1211
1212 // fHasSEH: true if seh is func
1213 bool hasSEH() const { return (Attributes >> 9) & 1; }
1214
1215 // fUseBP: true if EBP has been allocated
1216 bool useBP() const { return (Attributes >> 10) & 1; }
1217
1218 // cbFrame: frame pointer
1219 int getFP() const { return Attributes >> 14; }
1220};
1221
1222} // end namespace object
1223
1224} // end namespace llvm
1225
1226#endif // LLVM_OBJECT_COFF_H

/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/system_error

1// <system_error> -*- C++ -*-
2
3// Copyright (C) 2007-2017 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file include/system_error
26 * This is a Standard C++ Library header.
27 */
28
29#ifndef _GLIBCXX_SYSTEM_ERROR1
30#define _GLIBCXX_SYSTEM_ERROR1 1
31
32#pragma GCC system_header
33
34#if __cplusplus201103L < 201103L
35# include <bits/c++0x_warning.h>
36#else
37
38#include <bits/c++config.h>
39#include <bits/error_constants.h>
40#include <iosfwd>
41#include <stdexcept>
42
43namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
44{
45_GLIBCXX_BEGIN_NAMESPACE_VERSION
46
47 class error_code;
48 class error_condition;
49 class system_error;
50
51 /// is_error_code_enum
52 template<typename _Tp>
53 struct is_error_code_enum : public false_type { };
54
55 /// is_error_condition_enum
56 template<typename _Tp>
57 struct is_error_condition_enum : public false_type { };
58
59 template<>
60 struct is_error_condition_enum<errc>
61 : public true_type { };
62
63#if __cplusplus201103L > 201402L
64 template <typename _Tp>
65 inline constexpr bool is_error_code_enum_v =
66 is_error_code_enum<_Tp>::value;
67 template <typename _Tp>
68 inline constexpr bool is_error_condition_enum_v =
69 is_error_condition_enum<_Tp>::value;
70#endif // C++17
71 inline namespace _V2 {
72
73 /// error_category
74 class error_category
75 {
76 public:
77 constexpr error_category() noexcept = default;
78
79 virtual ~error_category();
80
81 error_category(const error_category&) = delete;
82 error_category& operator=(const error_category&) = delete;
83
84 virtual const char*
85 name() const noexcept = 0;
86
87 // We need two different virtual functions here, one returning a
88 // COW string and one returning an SSO string. Their positions in the
89 // vtable must be consistent for dynamic dispatch to work, but which one
90 // the name "message()" finds depends on which ABI the caller is using.
91#if _GLIBCXX_USE_CXX11_ABI1
92 private:
93 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11")))
94 virtual __cow_string
95 _M_message(int) const;
96
97 public:
98 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11")))
99 virtual string
100 message(int) const = 0;
101#else
102 virtual string
103 message(int) const = 0;
104
105 private:
106 virtual __sso_string
107 _M_message(int) const;
108#endif
109
110 public:
111 virtual error_condition
112 default_error_condition(int __i) const noexcept;
113
114 virtual bool
115 equivalent(int __i, const error_condition& __cond) const noexcept;
116
117 virtual bool
118 equivalent(const error_code& __code, int __i) const noexcept;
119
120 bool
121 operator<(const error_category& __other) const noexcept
122 { return less<const error_category*>()(this, &__other); }
123
124 bool
125 operator==(const error_category& __other) const noexcept
126 { return this == &__other; }
127
128 bool
129 operator!=(const error_category& __other) const noexcept
130 { return this != &__other; }
131 };
132
133 // DR 890.
134 _GLIBCXX_CONST__attribute__ ((__const__)) const error_category& system_category() noexcept;
135 _GLIBCXX_CONST__attribute__ ((__const__)) const error_category& generic_category() noexcept;
136
137 } // end inline namespace
138
139 error_code make_error_code(errc) noexcept;
140
141 template<typename _Tp>
142 struct hash;
143
144 /// error_code
145 // Implementation-specific error identification
146 struct error_code
147 {
148 error_code() noexcept
149 : _M_value(0), _M_cat(&system_category()) { }
150
151 error_code(int __v, const error_category& __cat) noexcept
152 : _M_value(__v), _M_cat(&__cat) { }
153
154 template<typename _ErrorCodeEnum, typename = typename
155 enable_if<is_error_code_enum<_ErrorCodeEnum>::value>::type>
156 error_code(_ErrorCodeEnum __e) noexcept
157 { *this = make_error_code(__e); }
15
Calling 'make_error_code'
18
Returning from 'make_error_code'
158
159 void
160 assign(int __v, const error_category& __cat) noexcept
161 {
162 _M_value = __v;
163 _M_cat = &__cat;
164 }
165
166 void
167 clear() noexcept
168 { assign(0, system_category()); }
169
170 // DR 804.
171 template<typename _ErrorCodeEnum>
172 typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value,
173 error_code&>::type
174 operator=(_ErrorCodeEnum __e) noexcept
175 { return *this = make_error_code(__e); }
176
177 int
178 value() const noexcept { return _M_value; }
179
180 const error_category&
181 category() const noexcept { return *_M_cat; }
182
183 error_condition
184 default_error_condition() const noexcept;
185
186 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11")))
187 string
188 message() const
189 { return category().message(value()); }
190
191 explicit operator bool() const noexcept
192 { return _M_value != 0; }
193
194 // DR 804.
195 private:
196 friend class hash<error_code>;
197
198 int _M_value;
199 const error_category* _M_cat;
200 };
201
202 // 19.4.2.6 non-member functions
203 inline error_code
204 make_error_code(errc __e) noexcept
205 { return error_code(static_cast<int>(__e), generic_category()); }
206
207 inline bool
208 operator<(const error_code& __lhs, const error_code& __rhs) noexcept
209 {
210 return (__lhs.category() < __rhs.category()
211 || (__lhs.category() == __rhs.category()
212 && __lhs.value() < __rhs.value()));
213 }
214
215 template<typename _CharT, typename _Traits>
216 basic_ostream<_CharT, _Traits>&
217 operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)
218 { return (__os << __e.category().name() << ':' << __e.value()); }
219
220 error_condition make_error_condition(errc) noexcept;
221
222 /// error_condition
223 // Portable error identification
224 struct error_condition
225 {
226 error_condition() noexcept
227 : _M_value(0), _M_cat(&generic_category()) { }
228
229 error_condition(int __v, const error_category& __cat) noexcept
230 : _M_value(__v), _M_cat(&__cat) { }
231
232 template<typename _ErrorConditionEnum, typename = typename
233 enable_if<is_error_condition_enum<_ErrorConditionEnum>::value>::type>
234 error_condition(_ErrorConditionEnum __e) noexcept
235 { *this = make_error_condition(__e); }
236
237 void
238 assign(int __v, const error_category& __cat) noexcept
239 {
240 _M_value = __v;
241 _M_cat = &__cat;
242 }
243
244 // DR 804.
245 template<typename _ErrorConditionEnum>
246 typename enable_if<is_error_condition_enum
247 <_ErrorConditionEnum>::value, error_condition&>::type
248 operator=(_ErrorConditionEnum __e) noexcept
249 { return *this = make_error_condition(__e); }
250
251 void
252 clear() noexcept
253 { assign(0, generic_category()); }
254
255 // 19.4.3.4 observers
256 int
257 value() const noexcept { return _M_value; }
258
259 const error_category&
260 category() const noexcept { return *_M_cat; }
261
262 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11")))
263 string
264 message() const
265 { return category().message(value()); }
266
267 explicit operator bool() const noexcept
268 { return _M_value != 0; }
269
270 // DR 804.
271 private:
272 int _M_value;
273 const error_category* _M_cat;
274 };
275
276 // 19.4.3.6 non-member functions
277 inline error_condition
278 make_error_condition(errc __e) noexcept
279 { return error_condition(static_cast<int>(__e), generic_category()); }
280
281 inline bool
282 operator<(const error_condition& __lhs,
283 const error_condition& __rhs) noexcept
284 {
285 return (__lhs.category() < __rhs.category()
286 || (__lhs.category() == __rhs.category()
287 && __lhs.value() < __rhs.value()));
288 }
289
290 // 19.4.4 Comparison operators
291 inline bool
292 operator==(const error_code& __lhs, const error_code& __rhs) noexcept
293 { return (__lhs.category() == __rhs.category()
294 && __lhs.value() == __rhs.value()); }
295
296 inline bool
297 operator==(const error_code& __lhs, const error_condition& __rhs) noexcept
298 {
299 return (__lhs.category().equivalent(__lhs.value(), __rhs)
300 || __rhs.category().equivalent(__lhs, __rhs.value()));
301 }
302
303 inline bool
304 operator==(const error_condition& __lhs, const error_code& __rhs) noexcept
305 {
306 return (__rhs.category().equivalent(__rhs.value(), __lhs)
307 || __lhs.category().equivalent(__rhs, __lhs.value()));
308 }
309
310 inline bool
311 operator==(const error_condition& __lhs,
312 const error_condition& __rhs) noexcept
313 {
314 return (__lhs.category() == __rhs.category()
315 && __lhs.value() == __rhs.value());
316 }
317
318 inline bool
319 operator!=(const error_code& __lhs, const error_code& __rhs) noexcept
320 { return !(__lhs == __rhs); }
321
322 inline bool
323 operator!=(const error_code& __lhs, const error_condition& __rhs) noexcept
324 { return !(__lhs == __rhs); }
325
326 inline bool
327 operator!=(const error_condition& __lhs, const error_code& __rhs) noexcept
328 { return !(__lhs == __rhs); }
329
330 inline bool
331 operator!=(const error_condition& __lhs,
332 const error_condition& __rhs) noexcept
333 { return !(__lhs == __rhs); }
334
335
336 /**
337 * @brief Thrown to indicate error code of underlying system.
338 *
339 * @ingroup exceptions
340 */
341 class system_error : public std::runtime_error
342 {
343 private:
344 error_code _M_code;
345
346 public:
347 system_error(error_code __ec = error_code())
348 : runtime_error(__ec.message()), _M_code(__ec) { }
349
350 system_error(error_code __ec, const string& __what)
351 : runtime_error(__what + ": " + __ec.message()), _M_code(__ec) { }
352
353 system_error(error_code __ec, const char* __what)
354 : runtime_error(__what + (": " + __ec.message())), _M_code(__ec) { }
355
356 system_error(int __v, const error_category& __ecat, const char* __what)
357 : system_error(error_code(__v, __ecat), __what) { }
358
359 system_error(int __v, const error_category& __ecat)
360 : runtime_error(error_code(__v, __ecat).message()),
361 _M_code(__v, __ecat) { }
362
363 system_error(int __v, const error_category& __ecat, const string& __what)
364 : runtime_error(__what + ": " + error_code(__v, __ecat).message()),
365 _M_code(__v, __ecat) { }
366
367 virtual ~system_error() noexcept;
368
369 const error_code&
370 code() const noexcept { return _M_code; }
371 };
372
373_GLIBCXX_END_NAMESPACE_VERSION
374} // namespace
375
376#include <bits/functional_hash.h>
377
378namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
379{
380_GLIBCXX_BEGIN_NAMESPACE_VERSION
381
382#ifndef _GLIBCXX_COMPATIBILITY_CXX0X
383 // DR 1182.
384 /// std::hash specialization for error_code.
385 template<>
386 struct hash<error_code>
387 : public __hash_base<size_t, error_code>
388 {
389 size_t
390 operator()(const error_code& __e) const noexcept
391 {
392 const size_t __tmp = std::_Hash_impl::hash(__e._M_value);
393 return std::_Hash_impl::__hash_combine(__e._M_cat, __tmp);
394 }
395 };
396#endif // _GLIBCXX_COMPATIBILITY_CXX0X
397
398#if __cplusplus201103L > 201402L
399 // DR 2686.
400 /// std::hash specialization for error_condition.
401 template<>
402 struct hash<error_condition>
403 : public __hash_base<size_t, error_condition>
404 {
405 size_t
406 operator()(const error_condition& __e) const noexcept
407 {
408 const size_t __tmp = std::_Hash_impl::hash(__e.value());
409 return std::_Hash_impl::__hash_combine(__e.category(), __tmp);
410 }
411 };
412#endif
413
414_GLIBCXX_END_NAMESPACE_VERSION
415} // namespace
416
417#endif // C++11
418
419#endif // _GLIBCXX_SYSTEM_ERROR

/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Object/Error.h

1//===- Error.h - system_error extensions for Object -------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This declares a new error_category for the Object library.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_OBJECT_ERROR_H
15#define LLVM_OBJECT_ERROR_H
16
17#include "llvm/ADT/Twine.h"
18#include "llvm/Support/Error.h"
19#include <system_error>
20
21namespace llvm {
22namespace object {
23
24class Binary;
25
26const std::error_category &object_category();
27
28enum class object_error {
29 // Error code 0 is absent. Use std::error_code() instead.
30 arch_not_found = 1,
31 invalid_file_type,
32 parse_failed,
33 unexpected_eof,
34 string_table_non_null_end,
35 invalid_section_index,
36 bitcode_section_not_found,
37 invalid_symbol_index,
38};
39
40inline std::error_code make_error_code(object_error e) {
41 return std::error_code(static_cast<int>(e), object_category());
16
Calling constructor for 'error_code'
17
Returning from constructor for 'error_code'
42}
43
44/// Base class for all errors indicating malformed binary files.
45///
46/// Having a subclass for all malformed binary files allows archive-walking
47/// code to skip malformed files without having to understand every possible
48/// way that a binary file might be malformed.
49///
50/// Currently inherits from ECError for easy interoperability with
51/// std::error_code, but this will be removed in the future.
52class BinaryError : public ErrorInfo<BinaryError, ECError> {
53public:
54 static char ID;
55 BinaryError() {
56 // Default to parse_failed, can be overridden with setErrorCode.
57 setErrorCode(make_error_code(object_error::parse_failed));
58 }
59};
60
61/// Generic binary error.
62///
63/// For errors that don't require their own specific sub-error (most errors)
64/// this class can be used to describe the error via a string message.
65class GenericBinaryError : public ErrorInfo<GenericBinaryError, BinaryError> {
66public:
67 static char ID;
68 GenericBinaryError(Twine Msg);
69 GenericBinaryError(Twine Msg, object_error ECOverride);
70 const std::string &getMessage() const { return Msg; }
71 void log(raw_ostream &OS) const override;
72private:
73 std::string Msg;
74};
75
76/// isNotObjectErrorInvalidFileType() is used when looping through the children
77/// of an archive after calling getAsBinary() on the child and it returns an
78/// llvm::Error. In the cases we want to loop through the children and ignore the
79/// non-objects in the archive this is used to test the error to see if an
80/// error() function needs to called on the llvm::Error.
81Error isNotObjectErrorInvalidFileType(llvm::Error Err);
82
83} // end namespace object.
84
85} // end namespace llvm.
86
87namespace std {
88template <>
89struct is_error_code_enum<llvm::object::object_error> : std::true_type {};
90}
91
92#endif

/build/llvm-toolchain-snapshot-7~svn326551/include/llvm/Support/Error.h

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

/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/bits/unique_ptr.h

1// unique_ptr implementation -*- C++ -*-
2
3// Copyright (C) 2008-2017 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file bits/unique_ptr.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{memory}
28 */
29
30#ifndef _UNIQUE_PTR_H1
31#define _UNIQUE_PTR_H1 1
32
33#include <bits/c++config.h>
34#include <debug/assertions.h>
35#include <type_traits>
36#include <utility>
37#include <tuple>
38#include <bits/stl_function.h>
39#include <bits/functional_hash.h>
40
41namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
42{
43_GLIBCXX_BEGIN_NAMESPACE_VERSION
44
45 /**
46 * @addtogroup pointer_abstractions
47 * @{
48 */
49
50#if _GLIBCXX_USE_DEPRECATED1
51 template<typename> class auto_ptr;
52#endif
53
54 /// Primary template of default_delete, used by unique_ptr
55 template<typename _Tp>
56 struct default_delete
57 {
58 /// Default constructor
59 constexpr default_delete() noexcept = default;
60
61 /** @brief Converting constructor.
62 *
63 * Allows conversion from a deleter for arrays of another type, @p _Up,
64 * only if @p _Up* is convertible to @p _Tp*.
65 */
66 template<typename _Up, typename = typename
67 enable_if<is_convertible<_Up*, _Tp*>::value>::type>
68 default_delete(const default_delete<_Up>&) noexcept { }
69
70 /// Calls @c delete @p __ptr
71 void
72 operator()(_Tp* __ptr) const
73 {
74 static_assert(!is_void<_Tp>::value,
75 "can't delete pointer to incomplete type");
76 static_assert(sizeof(_Tp)>0,
77 "can't delete pointer to incomplete type");
78 delete __ptr;
79 }
80 };
81
82 // _GLIBCXX_RESOLVE_LIB_DEFECTS
83 // DR 740 - omit specialization for array objects with a compile time length
84 /// Specialization for arrays, default_delete.
85 template<typename _Tp>
86 struct default_delete<_Tp[]>
87 {
88 public:
89 /// Default constructor
90 constexpr default_delete() noexcept = default;
91
92 /** @brief Converting constructor.
93 *
94 * Allows conversion from a deleter for arrays of another type, such as
95 * a const-qualified version of @p _Tp.
96 *
97 * Conversions from types derived from @c _Tp are not allowed because
98 * it is unsafe to @c delete[] an array of derived types through a
99 * pointer to the base type.
100 */
101 template<typename _Up, typename = typename
102 enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type>
103 default_delete(const default_delete<_Up[]>&) noexcept { }
104
105 /// Calls @c delete[] @p __ptr
106 template<typename _Up>
107 typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type
108 operator()(_Up* __ptr) const
109 {
110 static_assert(sizeof(_Tp)>0,
111 "can't delete pointer to incomplete type");
112 delete [] __ptr;
113 }
114 };
115
116 template <typename _Tp, typename _Dp>
117 class __uniq_ptr_impl
118 {
119 template <typename _Up, typename _Ep, typename = void>
120 struct _Ptr
121 {
122 using type = _Up*;
123 };
124
125 template <typename _Up, typename _Ep>
126 struct
127 _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
128 {
129 using type = typename remove_reference<_Ep>::type::pointer;
130 };
131
132 public:
133 using _DeleterConstraint = enable_if<
134 __and_<__not_<is_pointer<_Dp>>,
135 is_default_constructible<_Dp>>::value>;
136
137 using pointer = typename _Ptr<_Tp, _Dp>::type;
138
139 __uniq_ptr_impl() = default;
140 __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
141
142 template<typename _Del>
143 __uniq_ptr_impl(pointer __p, _Del&& __d)
144 : _M_t(__p, std::forward<_Del>(__d)) { }
101
Calling 'forward'
102
Returning from 'forward'
103
Calling constructor for 'tuple'
126
Returning from constructor for 'tuple'
187
Calling 'forward'
188
Returning from 'forward'
189
Calling constructor for 'tuple'
212
Returning from constructor for 'tuple'
264
Calling 'forward'
265
Returning from 'forward'
266
Calling constructor for 'tuple'
289
Returning from constructor for 'tuple'
145
146 pointer& _M_ptr() { return std::get<0>(_M_t); }
76
Calling 'get'
83
Returning from 'get'
162
Calling 'get'
169
Returning from 'get'
239
Calling 'get'
246
Returning from 'get'
307
Calling 'get'
314
Returning from 'get'
455
Calling 'get'
462
Returning from 'get'
147 pointer _M_ptr() const { return std::get<0>(_M_t); }
65
Calling 'get'
72
Returning from 'get'
151
Calling 'get'
158
Returning from 'get'
228
Calling 'get'
235
Returning from 'get'
296
Calling 'get'
303
Returning from 'get'
148 _Dp& _M_deleter() { return std::get<1>(_M_t); }
88
Calling 'get'
95
Returning from 'get'
174
Calling 'get'
181
Returning from 'get'
251
Calling 'get'
258
Returning from 'get'
149 const _Dp& _M_deleter() const { return std::get<1>(_M_t); }
150
151 private:
152 tuple<pointer, _Dp> _M_t;
153 };
154
155 /// 20.7.1.2 unique_ptr for single objects.
156 template <typename _Tp, typename _Dp = default_delete<_Tp>>
157 class unique_ptr
158 {
159 template <class _Up>
160 using _DeleterConstraint =
161 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
162
163 __uniq_ptr_impl<_Tp, _Dp> _M_t;
164
165 public:
166 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
167 using element_type = _Tp;
168 using deleter_type = _Dp;
169
170 // helper template for detecting a safe conversion from another
171 // unique_ptr
172 template<typename _Up, typename _Ep>
173 using __safe_conversion_up = __and_<
174 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
175 __not_<is_array<_Up>>,
176 __or_<__and_<is_reference<deleter_type>,
177 is_same<deleter_type, _Ep>>,
178 __and_<__not_<is_reference<deleter_type>>,
179 is_convertible<_Ep, deleter_type>>
180 >
181 >;
182
183 // Constructors.
184
185 /// Default constructor, creates a unique_ptr that owns nothing.
186 template <typename _Up = _Dp,
187 typename = _DeleterConstraint<_Up>>
188 constexpr unique_ptr() noexcept
189 : _M_t()
190 { }
191
192 /** Takes ownership of a pointer.
193 *
194 * @param __p A pointer to an object of @c element_type
195 *
196 * The deleter will be value-initialized.
197 */
198 template <typename _Up = _Dp,
199 typename = _DeleterConstraint<_Up>>
200 explicit
201 unique_ptr(pointer __p) noexcept
202 : _M_t(__p)
203 { }
204
205 /** Takes ownership of a pointer.
206 *
207 * @param __p A pointer to an object of @c element_type
208 * @param __d A reference to a deleter.
209 *
210 * The deleter will be initialized with @p __d
211 */
212 unique_ptr(pointer __p,
213 typename conditional<is_reference<deleter_type>::value,
214 deleter_type, const deleter_type&>::type __d) noexcept
215 : _M_t(__p, __d) { }
216
217 /** Takes ownership of a pointer.
218 *
219 * @param __p A pointer to an object of @c element_type
220 * @param __d An rvalue reference to a deleter.
221 *
222 * The deleter will be initialized with @p std::move(__d)
223 */
224 unique_ptr(pointer __p,
225 typename remove_reference<deleter_type>::type&& __d) noexcept
226 : _M_t(std::move(__p), std::move(__d))
227 { static_assert(!std::is_reference<deleter_type>::value,
228 "rvalue deleter bound to reference"); }
229
230 /// Creates a unique_ptr that owns nothing.
231 template <typename _Up = _Dp,
232 typename = _DeleterConstraint<_Up>>
233 constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
234
235 // Move constructors.
236
237 /// Move constructor.
238 unique_ptr(unique_ptr&& __u) noexcept
239 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
62
Calling 'unique_ptr::release'
85
Returning from 'unique_ptr::release'
86
Calling 'unique_ptr::get_deleter'
97
Returning from 'unique_ptr::get_deleter'
98
Calling 'forward'
99
Returning from 'forward'
100
Calling constructor for '__uniq_ptr_impl'
127
Returning from constructor for '__uniq_ptr_impl'
148
Calling 'unique_ptr::release'
171
Returning from 'unique_ptr::release'
172
Calling 'unique_ptr::get_deleter'
183
Returning from 'unique_ptr::get_deleter'
184
Calling 'forward'
185
Returning from 'forward'
186
Calling constructor for '__uniq_ptr_impl'
213
Returning from constructor for '__uniq_ptr_impl'
225
Calling 'unique_ptr::release'
248
Returning from 'unique_ptr::release'
249
Calling 'unique_ptr::get_deleter'
260
Returning from 'unique_ptr::get_deleter'
261
Calling 'forward'
262
Returning from 'forward'
263
Calling constructor for '__uniq_ptr_impl'
290
Returning from constructor for '__uniq_ptr_impl'
240
241 /** @brief Converting constructor from another type
242 *
243 * Requires that the pointer owned by @p __u is convertible to the
244 * type of pointer owned by this object, @p __u does not own an array,
245 * and @p __u has a compatible deleter type.
246 */
247 template<typename _Up, typename _Ep, typename = _Require<
248 __safe_conversion_up<_Up, _Ep>,
249 typename conditional<is_reference<_Dp>::value,
250 is_same<_Ep, _Dp>,
251 is_convertible<_Ep, _Dp>>::type>>
252 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
253 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
254 { }
255
256#if _GLIBCXX_USE_DEPRECATED1
257 /// Converting constructor from @c auto_ptr
258 template<typename _Up, typename = _Require<
259 is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
260 unique_ptr(auto_ptr<_Up>&& __u) noexcept;
261#endif
262
263 /// Destructor, invokes the deleter if the stored pointer is not null.
264 ~unique_ptr() noexcept
265 {
266 auto& __ptr = _M_t._M_ptr();
454
Calling '__uniq_ptr_impl::_M_ptr'
463
Returning from '__uniq_ptr_impl::_M_ptr'
267 if (__ptr != nullptr)
464
Taking false branch
268 get_deleter()(__ptr);
269 __ptr = pointer();
270 }
271
272 // Assignment.
273
274 /** @brief Move assignment operator.
275 *
276 * @param __u The object to transfer ownership from.
277 *
278 * Invokes the deleter first if this object owns a pointer.
279 */
280 unique_ptr&
281 operator=(unique_ptr&& __u) noexcept
282 {
283 reset(__u.release());
284 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
285 return *this;
286 }
287
288 /** @brief Assignment from another type.
289 *
290 * @param __u The object to transfer ownership from, which owns a
291 * convertible pointer to a non-array object.
292 *
293 * Invokes the deleter first if this object owns a pointer.
294 */
295 template<typename _Up, typename _Ep>
296 typename enable_if< __and_<
297 __safe_conversion_up<_Up, _Ep>,
298 is_assignable<deleter_type&, _Ep&&>
299 >::value,
300 unique_ptr&>::type
301 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
302 {
303 reset(__u.release());
304 get_deleter() = std::forward<_Ep>(__u.get_deleter());
305 return *this;
306 }
307
308 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
309 unique_ptr&
310 operator=(nullptr_t) noexcept
311 {
312 reset();
313 return *this;
314 }
315
316 // Observers.
317
318 /// Dereference the stored pointer.
319 typename add_lvalue_reference<element_type>::type
320 operator*() const
321 {
322 __glibcxx_assert(get() != pointer());
323 return *get();
324 }
325
326 /// Return the stored pointer.
327 pointer
328 operator->() const noexcept
329 {
330 _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
331 return get();
332 }
333
334 /// Return the stored pointer.
335 pointer
336 get() const noexcept
337 { return _M_t._M_ptr(); }
64
Calling '__uniq_ptr_impl::_M_ptr'
73
Returning from '__uniq_ptr_impl::_M_ptr'
150
Calling '__uniq_ptr_impl::_M_ptr'
159
Returning from '__uniq_ptr_impl::_M_ptr'
227
Calling '__uniq_ptr_impl::_M_ptr'
236
Returning from '__uniq_ptr_impl::_M_ptr'
295
Calling '__uniq_ptr_impl::_M_ptr'
304
Returning from '__uniq_ptr_impl::_M_ptr'
338
339 /// Return a reference to the stored deleter.
340 deleter_type&
341 get_deleter() noexcept
342 { return _M_t._M_deleter(); }
87
Calling '__uniq_ptr_impl::_M_deleter'
96
Returning from '__uniq_ptr_impl::_M_deleter'
173
Calling '__uniq_ptr_impl::_M_deleter'
182
Returning from '__uniq_ptr_impl::_M_deleter'
250
Calling '__uniq_ptr_impl::_M_deleter'
259
Returning from '__uniq_ptr_impl::_M_deleter'
343
344 /// Return a reference to the stored deleter.
345 const deleter_type&
346 get_deleter() const noexcept
347 { return _M_t._M_deleter(); }
348
349 /// Return @c true if the stored pointer is not null.
350 explicit operator bool() const noexcept
351 { return get() == pointer() ? false : true; }
352
353 // Modifiers.
354
355 /// Release ownership of any stored pointer.
356 pointer
357 release() noexcept
358 {
359 pointer __p = get();
63
Calling 'unique_ptr::get'
74
Returning from 'unique_ptr::get'
149
Calling 'unique_ptr::get'
160
Returning from 'unique_ptr::get'
226
Calling 'unique_ptr::get'
237
Returning from 'unique_ptr::get'
294
Calling 'unique_ptr::get'
305
Returning from 'unique_ptr::get'
360 _M_t._M_ptr() = pointer();
75
Calling '__uniq_ptr_impl::_M_ptr'
84
Returning from '__uniq_ptr_impl::_M_ptr'
161
Calling '__uniq_ptr_impl::_M_ptr'
170
Returning from '__uniq_ptr_impl::_M_ptr'
238
Calling '__uniq_ptr_impl::_M_ptr'
247
Returning from '__uniq_ptr_impl::_M_ptr'
306
Calling '__uniq_ptr_impl::_M_ptr'
315
Returning from '__uniq_ptr_impl::_M_ptr'
361 return __p;
362 }
363
364 /** @brief Replace the stored pointer.
365 *
366 * @param __p The new pointer to store.
367 *
368 * The deleter will be invoked if a pointer is already owned.
369 */
370 void
371 reset(pointer __p = pointer()) noexcept
372 {
373 using std::swap;
374 swap(_M_t._M_ptr(), __p);
375 if (__p != pointer())
376 get_deleter()(__p);
377 }
378
379 /// Exchange the pointer and deleter with another object.
380 void
381 swap(unique_ptr& __u) noexcept
382 {
383 using std::swap;
384 swap(_M_t, __u._M_t);
385 }
386
387 // Disable copy from lvalue.
388 unique_ptr(const unique_ptr&) = delete;
389 unique_ptr& operator=(const unique_ptr&) = delete;
390 };
391
392 /// 20.7.1.3 unique_ptr for array objects with a runtime length
393 // [unique.ptr.runtime]
394 // _GLIBCXX_RESOLVE_LIB_DEFECTS
395 // DR 740 - omit specialization for array objects with a compile time length
396 template<typename _Tp, typename _Dp>
397 class unique_ptr<_Tp[], _Dp>
398 {
399 template <typename _Up>
400 using _DeleterConstraint =
401 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
402
403 __uniq_ptr_impl<_Tp, _Dp> _M_t;
404
405 template<typename _Up>
406 using __remove_cv = typename remove_cv<_Up>::type;
407
408 // like is_base_of<_Tp, _Up> but false if unqualified types are the same
409 template<typename _Up>
410 using __is_derived_Tp
411 = __and_< is_base_of<_Tp, _Up>,
412 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
413
414 public:
415 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
416 using element_type = _Tp;
417 using deleter_type = _Dp;
418
419 // helper template for detecting a safe conversion from another
420 // unique_ptr
421 template<typename _Up, typename _Ep,
422 typename _Up_up = unique_ptr<_Up, _Ep>,
423 typename _Up_element_type = typename _Up_up::element_type>
424 using __safe_conversion_up = __and_<
425 is_array<_Up>,
426 is_same<pointer, element_type*>,
427 is_same<typename _Up_up::pointer, _Up_element_type*>,
428 is_convertible<_Up_element_type(*)[], element_type(*)[]>,
429 __or_<__and_<is_reference<deleter_type>, is_same<deleter_type, _Ep>>,
430 __and_<__not_<is_reference<deleter_type>>,
431 is_convertible<_Ep, deleter_type>>>
432 >;
433
434 // helper template for detecting a safe conversion from a raw pointer
435 template<typename _Up>
436 using __safe_conversion_raw = __and_<
437 __or_<__or_<is_same<_Up, pointer>,
438 is_same<_Up, nullptr_t>>,
439 __and_<is_pointer<_Up>,
440 is_same<pointer, element_type*>,
441 is_convertible<
442 typename remove_pointer<_Up>::type(*)[],
443 element_type(*)[]>
444 >
445 >
446 >;
447
448 // Constructors.
449
450 /// Default constructor, creates a unique_ptr that owns nothing.
451 template <typename _Up = _Dp,
452 typename = _DeleterConstraint<_Up>>
453 constexpr unique_ptr() noexcept
454 : _M_t()
455 { }
456
457 /** Takes ownership of a pointer.
458 *
459 * @param __p A pointer to an array of a type safely convertible
460 * to an array of @c element_type
461 *
462 * The deleter will be value-initialized.
463 */
464 template<typename _Up,
465 typename _Vp = _Dp,
466 typename = _DeleterConstraint<_Vp>,
467 typename = typename enable_if<
468 __safe_conversion_raw<_Up>::value, bool>::type>
469 explicit
470 unique_ptr(_Up __p) noexcept
471 : _M_t(__p)
472 { }
473
474 /** Takes ownership of a pointer.
475 *
476 * @param __p A pointer to an array of a type safely convertible
477 * to an array of @c element_type
478 * @param __d A reference to a deleter.
479 *
480 * The deleter will be initialized with @p __d
481 */
482 template<typename _Up,
483 typename = typename enable_if<
484 __safe_conversion_raw<_Up>::value, bool>::type>
485 unique_ptr(_Up __p,
486 typename conditional<is_reference<deleter_type>::value,
487 deleter_type, const deleter_type&>::type __d) noexcept
488 : _M_t(__p, __d) { }
489
490 /** Takes ownership of a pointer.
491 *
492 * @param __p A pointer to an array of a type safely convertible
493 * to an array of @c element_type
494 * @param __d A reference to a deleter.
495 *
496 * The deleter will be initialized with @p std::move(__d)
497 */
498 template<typename _Up,
499 typename = typename enable_if<
500 __safe_conversion_raw<_Up>::value, bool>::type>
501 unique_ptr(_Up __p, typename
502 remove_reference<deleter_type>::type&& __d) noexcept
503 : _M_t(std::move(__p), std::move(__d))
504 { static_assert(!is_reference<deleter_type>::value,
505 "rvalue deleter bound to reference"); }
506
507 /// Move constructor.
508 unique_ptr(unique_ptr&& __u) noexcept
509 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
510
511 /// Creates a unique_ptr that owns nothing.
512 template <typename _Up = _Dp,
513 typename = _DeleterConstraint<_Up>>
514 constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
515
516 template<typename _Up, typename _Ep,
517 typename = _Require<__safe_conversion_up<_Up, _Ep>>>
518 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
519 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
520 { }
521
522 /// Destructor, invokes the deleter if the stored pointer is not null.
523 ~unique_ptr()
524 {
525 auto& __ptr = _M_t._M_ptr();
526 if (__ptr != nullptr)
527 get_deleter()(__ptr);
528 __ptr = pointer();
529 }
530
531 // Assignment.
532
533 /** @brief Move assignment operator.
534 *
535 * @param __u The object to transfer ownership from.
536 *
537 * Invokes the deleter first if this object owns a pointer.
538 */
539 unique_ptr&
540 operator=(unique_ptr&& __u) noexcept
541 {
542 reset(__u.release());
543 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
544 return *this;
545 }
546
547 /** @brief Assignment from another type.
548 *
549 * @param __u The object to transfer ownership from, which owns a
550 * convertible pointer to an array object.
551 *
552 * Invokes the deleter first if this object owns a pointer.
553 */
554 template<typename _Up, typename _Ep>
555 typename
556 enable_if<__and_<__safe_conversion_up<_Up, _Ep>,
557 is_assignable<deleter_type&, _Ep&&>
558 >::value,
559 unique_ptr&>::type
560 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
561 {
562 reset(__u.release());
563 get_deleter() = std::forward<_Ep>(__u.get_deleter());
564 return *this;
565 }
566
567 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
568 unique_ptr&
569 operator=(nullptr_t) noexcept
570 {
571 reset();
572 return *this;
573 }
574
575 // Observers.
576
577 /// Access an element of owned array.
578 typename std::add_lvalue_reference<element_type>::type
579 operator[](size_t __i) const
580 {
581 __glibcxx_assert(get() != pointer());
582 return get()[__i];
583 }
584
585 /// Return the stored pointer.
586 pointer
587 get() const noexcept
588 { return _M_t._M_ptr(); }
589
590 /// Return a reference to the stored deleter.
591 deleter_type&
592 get_deleter() noexcept
593 { return _M_t._M_deleter(); }
594
595 /// Return a reference to the stored deleter.
596 const deleter_type&
597 get_deleter() const noexcept
598 { return _M_t._M_deleter(); }
599
600 /// Return @c true if the stored pointer is not null.
601 explicit operator bool() const noexcept
602 { return get() == pointer() ? false : true; }
603
604 // Modifiers.
605
606 /// Release ownership of any stored pointer.
607 pointer
608 release() noexcept
609 {
610 pointer __p = get();
611 _M_t._M_ptr() = pointer();
612 return __p;
613 }
614
615 /** @brief Replace the stored pointer.
616 *
617 * @param __p The new pointer to store.
618 *
619 * The deleter will be invoked if a pointer is already owned.
620 */
621 template <typename _Up,
622 typename = _Require<
623 __or_<is_same<_Up, pointer>,
624 __and_<is_same<pointer, element_type*>,
625 is_pointer<_Up>,
626 is_convertible<
627 typename remove_pointer<_Up>::type(*)[],
628 element_type(*)[]
629 >
630 >
631 >
632 >>
633 void
634 reset(_Up __p) noexcept
635 {
636 pointer __ptr = __p;
637 using std::swap;
638 swap(_M_t._M_ptr(), __ptr);
639 if (__ptr != nullptr)
640 get_deleter()(__ptr);
641 }
642
643 void reset(nullptr_t = nullptr) noexcept
644 {
645 reset(pointer());
646 }
647
648 /// Exchange the pointer and deleter with another object.
649 void
650 swap(unique_ptr& __u) noexcept
651 {
652 using std::swap;
653 swap(_M_t, __u._M_t);
654 }
655
656 // Disable copy from lvalue.
657 unique_ptr(const unique_ptr&) = delete;
658 unique_ptr& operator=(const unique_ptr&) = delete;
659 };
660
661 template<typename _Tp, typename _Dp>
662 inline
663#if __cplusplus201103L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
664 // Constrained free swap overload, see p0185r1
665 typename enable_if<__is_swappable<_Dp>::value>::type
666#else
667 void
668#endif
669 swap(unique_ptr<_Tp, _Dp>& __x,
670 unique_ptr<_Tp, _Dp>& __y) noexcept
671 { __x.swap(__y); }
672
673#if __cplusplus201103L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
674 template<typename _Tp, typename _Dp>
675 typename enable_if<!__is_swappable<_Dp>::value>::type
676 swap(unique_ptr<_Tp, _Dp>&,
677 unique_ptr<_Tp, _Dp>&) = delete;
678#endif
679
680 template<typename _Tp, typename _Dp,
681 typename _Up, typename _Ep>
682 inline bool
683 operator==(const unique_ptr<_Tp, _Dp>& __x,
684 const unique_ptr<_Up, _Ep>& __y)
685 { return __x.get() == __y.get(); }
686
687 template<typename _Tp, typename _Dp>
688 inline bool
689 operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
690 { return !__x; }
691
692 template<typename _Tp, typename _Dp>
693 inline bool
694 operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
695 { return !__x; }
696
697 template<typename _Tp, typename _Dp,
698 typename _Up, typename _Ep>
699 inline bool
700 operator!=(const unique_ptr<_Tp, _Dp>& __x,
701 const unique_ptr<_Up, _Ep>& __y)
702 { return __x.get() != __y.get(); }
703
704 template<typename _Tp, typename _Dp>
705 inline bool
706 operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
707 { return (bool)__x; }
708
709 template<typename _Tp, typename _Dp>
710 inline bool
711 operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
712 { return (bool)__x; }
713
714 template<typename _Tp, typename _Dp,
715 typename _Up, typename _Ep>
716 inline bool
717 operator<(const unique_ptr<_Tp, _Dp>& __x,
718 const unique_ptr<_Up, _Ep>& __y)
719 {
720 typedef typename
721 std::common_type<typename unique_ptr<_Tp, _Dp>::pointer,
722 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
723 return std::less<_CT>()(__x.get(), __y.get());
724 }
725
726 template<typename _Tp, typename _Dp>
727 inline bool
728 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
729 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
730 nullptr); }
731
732 template<typename _Tp, typename _Dp>
733 inline bool
734 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
735 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
736 __x.get()); }
737
738 template<typename _Tp, typename _Dp,
739 typename _Up, typename _Ep>
740 inline bool
741 operator<=(const unique_ptr<_Tp, _Dp>& __x,
742 const unique_ptr<_Up, _Ep>& __y)
743 { return !(__y < __x); }
744
745 template<typename _Tp, typename _Dp>
746 inline bool
747 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
748 { return !(nullptr < __x); }
749
750 template<typename _Tp, typename _Dp>
751 inline bool
752 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
753 { return !(__x < nullptr); }
754
755 template<typename _Tp, typename _Dp,
756 typename _Up, typename _Ep>
757 inline bool
758 operator>(const unique_ptr<_Tp, _Dp>& __x,
759 const unique_ptr<_Up, _Ep>& __y)
760 { return (__y < __x); }
761
762 template<typename _Tp, typename _Dp>
763 inline bool
764 operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
765 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
766 __x.get()); }
767
768 template<typename _Tp, typename _Dp>
769 inline bool
770 operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
771 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
772 nullptr); }
773
774 template<typename _Tp, typename _Dp,
775 typename _Up, typename _Ep>
776 inline bool
777 operator>=(const unique_ptr<_Tp, _Dp>& __x,
778 const unique_ptr<_Up, _Ep>& __y)
779 { return !(__x < __y); }
780
781 template<typename _Tp, typename _Dp>
782 inline bool
783 operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
784 { return !(__x < nullptr); }
785
786 template<typename _Tp, typename _Dp>
787 inline bool
788 operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
789 { return !(nullptr < __x); }
790
791 /// std::hash specialization for unique_ptr.
792 template<typename _Tp, typename _Dp>
793 struct hash<unique_ptr<_Tp, _Dp>>
794 : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
795 private __poison_hash<typename unique_ptr<_Tp, _Dp>::pointer>
796 {
797 size_t
798 operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept
799 {
800 typedef unique_ptr<_Tp, _Dp> _UP;
801 return std::hash<typename _UP::pointer>()(__u.get());
802 }
803 };
804
805#if __cplusplus201103L > 201103L
806
807#define __cpp_lib_make_unique 201304
808
809 template<typename _Tp>
810 struct _MakeUniq
811 { typedef unique_ptr<_Tp> __single_object; };
812
813 template<typename _Tp>
814 struct _MakeUniq<_Tp[]>
815 { typedef unique_ptr<_Tp[]> __array; };
816
817 template<typename _Tp, size_t _Bound>
818 struct _MakeUniq<_Tp[_Bound]>
819 { struct __invalid_type { }; };
820
821 /// std::make_unique for single objects
822 template<typename _Tp, typename... _Args>
823 inline typename _MakeUniq<_Tp>::__single_object
824 make_unique(_Args&&... __args)
825 { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
826
827 /// std::make_unique for arrays of unknown bound
828 template<typename _Tp>
829 inline typename _MakeUniq<_Tp>::__array
830 make_unique(size_t __num)
831 { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); }
832
833 /// Disable std::make_unique for arrays of known bound
834 template<typename _Tp, typename... _Args>
835 inline typename _MakeUniq<_Tp>::__invalid_type
836 make_unique(_Args&&...) = delete;
837#endif
838
839 // @} group pointer_abstractions
840
841_GLIBCXX_END_NAMESPACE_VERSION
842} // namespace
843
844#endif /* _UNIQUE_PTR_H */

/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/tuple

1// <tuple> -*- C++ -*-
2
3// Copyright (C) 2007-2017 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file include/tuple
26 * This is a Standard C++ Library header.
27 */
28
29#ifndef _GLIBCXX_TUPLE1
30#define _GLIBCXX_TUPLE1 1
31
32#pragma GCC system_header
33
34#if __cplusplus201103L < 201103L
35# include <bits/c++0x_warning.h>
36#else
37
38#include <utility>
39#include <array>
40#include <bits/uses_allocator.h>
41#include <bits/invoke.h>
42
43namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
44{
45_GLIBCXX_BEGIN_NAMESPACE_VERSION
46
47 /**
48 * @addtogroup utilities
49 * @{
50 */
51
52 template<typename... _Elements>
53 class tuple;
54
55 template<typename _Tp>
56 struct __is_empty_non_tuple : is_empty<_Tp> { };
57
58 // Using EBO for elements that are tuples causes ambiguous base errors.
59 template<typename _El0, typename... _El>
60 struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { };
61
62 // Use the Empty Base-class Optimization for empty, non-final types.
63 template<typename _Tp>
64 using __empty_not_final
65 = typename conditional<__is_final(_Tp), false_type,
66 __is_empty_non_tuple<_Tp>>::type;
67
68 template<std::size_t _Idx, typename _Head,
69 bool = __empty_not_final<_Head>::value>
70 struct _Head_base;
71
72 template<std::size_t _Idx, typename _Head>
73 struct _Head_base<_Idx, _Head, true>
74 : public _Head
75 {
76 constexpr _Head_base()
77 : _Head() { }
78
79 constexpr _Head_base(const _Head& __h)
80 : _Head(__h) { }
81
82 constexpr _Head_base(const _Head_base&) = default;
83 constexpr _Head_base(_Head_base&&) = default;
84
85 template<typename _UHead>
86 constexpr _Head_base(_UHead&& __h)
87 : _Head(std::forward<_UHead>(__h)) { }
115
Calling 'forward'
116
Returning from 'forward'
201
Calling 'forward'
202
Returning from 'forward'
278
Calling 'forward'
279
Returning from 'forward'
88
89 _Head_base(allocator_arg_t, __uses_alloc0)
90 : _Head() { }
91
92 template<typename _Alloc>
93 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
94 : _Head(allocator_arg, *__a._M_a) { }
95
96 template<typename _Alloc>
97 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
98 : _Head(*__a._M_a) { }
99
100 template<typename _UHead>
101 _Head_base(__uses_alloc0, _UHead&& __uhead)
102 : _Head(std::forward<_UHead>(__uhead)) { }
103
104 template<typename _Alloc, typename _UHead>
105 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
106 : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
107
108 template<typename _Alloc, typename _UHead>
109 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
110 : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
111
112 static constexpr _Head&
113 _M_head(_Head_base& __b) noexcept { return __b; }
114
115 static constexpr const _Head&
116 _M_head(const _Head_base& __b) noexcept { return __b; }
117 };
118
119 template<std::size_t _Idx, typename _Head>
120 struct _Head_base<_Idx, _Head, false>
121 {
122 constexpr _Head_base()
123 : _M_head_impl() { }
124
125 constexpr _Head_base(const _Head& __h)
126 : _M_head_impl(__h) { }
127
128 constexpr _Head_base(const _Head_base&) = default;
129 constexpr _Head_base(_Head_base&&) = default;
130
131 template<typename _UHead>
132 constexpr _Head_base(_UHead&& __h)
133 : _M_head_impl(std::forward<_UHead>(__h)) { }
122
Calling 'forward'
123
Returning from 'forward'
208
Calling 'forward'
209
Returning from 'forward'
285
Calling 'forward'
286
Returning from 'forward'
134
135 _Head_base(allocator_arg_t, __uses_alloc0)
136 : _M_head_impl() { }
137
138 template<typename _Alloc>
139 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
140 : _M_head_impl(allocator_arg, *__a._M_a) { }
141
142 template<typename _Alloc>
143 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
144 : _M_head_impl(*__a._M_a) { }
145
146 template<typename _UHead>
147 _Head_base(__uses_alloc0, _UHead&& __uhead)
148 : _M_head_impl(std::forward<_UHead>(__uhead)) { }
149
150 template<typename _Alloc, typename _UHead>
151 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
152 : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
153 { }
154
155 template<typename _Alloc, typename _UHead>
156 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
157 : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
158
159 static constexpr _Head&
160 _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
161
162 static constexpr const _Head&
163 _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
164
165 _Head _M_head_impl;
166 };
167
168 /**
169 * Contains the actual implementation of the @c tuple template, stored
170 * as a recursive inheritance hierarchy from the first element (most
171 * derived class) to the last (least derived class). The @c Idx
172 * parameter gives the 0-based index of the element stored at this
173 * point in the hierarchy; we use it to implement a constant-time
174 * get() operation.
175 */
176 template<std::size_t _Idx, typename... _Elements>
177 struct _Tuple_impl;
178
179 /**
180 * Recursive tuple implementation. Here we store the @c Head element
181 * and derive from a @c Tuple_impl containing the remaining elements
182 * (which contains the @c Tail).
183 */
184 template<std::size_t _Idx, typename _Head, typename... _Tail>
185 struct _Tuple_impl<_Idx, _Head, _Tail...>
186 : public _Tuple_impl<_Idx + 1, _Tail...>,
187 private _Head_base<_Idx, _Head>
188 {
189 template<std::size_t, typename...> friend class _Tuple_impl;
190
191 typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
192 typedef _Head_base<_Idx, _Head> _Base;
193
194 static constexpr _Head&
195 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
79
Calling '_Head_base::_M_head'
80
Returning from '_Head_base::_M_head'
165
Calling '_Head_base::_M_head'
166
Returning from '_Head_base::_M_head'
242
Calling '_Head_base::_M_head'
243
Returning from '_Head_base::_M_head'
310
Calling '_Head_base::_M_head'
311
Returning from '_Head_base::_M_head'
458
Calling '_Head_base::_M_head'
459
Returning from '_Head_base::_M_head'
196
197 static constexpr const _Head&
198 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
68
Calling '_Head_base::_M_head'
69
Returning from '_Head_base::_M_head'
154
Calling '_Head_base::_M_head'
155
Returning from '_Head_base::_M_head'
231
Calling '_Head_base::_M_head'
232
Returning from '_Head_base::_M_head'
299
Calling '_Head_base::_M_head'
300
Returning from '_Head_base::_M_head'
199
200 static constexpr _Inherited&
201 _M_tail(_Tuple_impl& __t) noexcept { return __t; }
202
203 static constexpr const _Inherited&
204 _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
205
206 constexpr _Tuple_impl()
207 : _Inherited(), _Base() { }
208
209 explicit
210 constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
211 : _Inherited(__tail...), _Base(__head) { }
212
213 template<typename _UHead, typename... _UTail, typename = typename
214 enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type>
215 explicit
216 constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
217 : _Inherited(std::forward<_UTail>(__tail)...),
109
Calling 'forward'
110
Returning from 'forward'
111
Calling constructor for '_Tuple_impl'
118
Returning from constructor for '_Tuple_impl'
195
Calling 'forward'
196
Returning from 'forward'
197
Calling constructor for '_Tuple_impl'
204
Returning from constructor for '_Tuple_impl'
272
Calling 'forward'
273
Returning from 'forward'
274
Calling constructor for '_Tuple_impl'
281
Returning from constructor for '_Tuple_impl'
218 _Base(std::forward<_UHead>(__head)) { }
119
Calling 'forward'
120
Returning from 'forward'
121
Calling constructor for '_Head_base'
124
Returning from constructor for '_Head_base'
205
Calling 'forward'
206
Returning from 'forward'
207
Calling constructor for '_Head_base'
210
Returning from constructor for '_Head_base'
282
Calling 'forward'
283
Returning from 'forward'
284
Calling constructor for '_Head_base'
287
Returning from constructor for '_Head_base'
219
220 constexpr _Tuple_impl(const _Tuple_impl&) = default;
221
222 constexpr
223 _Tuple_impl(_Tuple_impl&& __in)
224 noexcept(__and_<is_nothrow_move_constructible<_Head>,
225 is_nothrow_move_constructible<_Inherited>>::value)
226 : _Inherited(std::move(_M_tail(__in))),
227 _Base(std::forward<_Head>(_M_head(__in))) { }
228
229 template<typename... _UElements>
230 constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
231 : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
232 _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
233
234 template<typename _UHead, typename... _UTails>
235 constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
236 : _Inherited(std::move
237 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
238 _Base(std::forward<_UHead>
239 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
240
241 template<typename _Alloc>
242 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
243 : _Inherited(__tag, __a),
244 _Base(__tag, __use_alloc<_Head>(__a)) { }
245
246 template<typename _Alloc>
247 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
248 const _Head& __head, const _Tail&... __tail)
249 : _Inherited(__tag, __a, __tail...),
250 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
251
252 template<typename _Alloc, typename _UHead, typename... _UTail,
253 typename = typename enable_if<sizeof...(_Tail)
254 == sizeof...(_UTail)>::type>
255 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
256 _UHead&& __head, _UTail&&... __tail)
257 : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
258 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
259 std::forward<_UHead>(__head)) { }
260
261 template<typename _Alloc>
262 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
263 const _Tuple_impl& __in)
264 : _Inherited(__tag, __a, _M_tail(__in)),
265 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
266
267 template<typename _Alloc>
268 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
269 _Tuple_impl&& __in)
270 : _Inherited(__tag, __a, std::move(_M_tail(__in))),
271 _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
272 std::forward<_Head>(_M_head(__in))) { }
273
274 template<typename _Alloc, typename... _UElements>
275 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
276 const _Tuple_impl<_Idx, _UElements...>& __in)
277 : _Inherited(__tag, __a,
278 _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
279 _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
280 _Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
281
282 template<typename _Alloc, typename _UHead, typename... _UTails>
283 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
284 _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
285 : _Inherited(__tag, __a, std::move
286 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
287 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
288 std::forward<_UHead>
289 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
290
291 _Tuple_impl&
292 operator=(const _Tuple_impl& __in)
293 {
294 _M_head(*this) = _M_head(__in);
295 _M_tail(*this) = _M_tail(__in);
296 return *this;
297 }
298
299 _Tuple_impl&
300 operator=(_Tuple_impl&& __in)
301 noexcept(__and_<is_nothrow_move_assignable<_Head>,
302 is_nothrow_move_assignable<_Inherited>>::value)
303 {
304 _M_head(*this) = std::forward<_Head>(_M_head(__in));
305 _M_tail(*this) = std::move(_M_tail(__in));
306 return *this;
307 }
308
309 template<typename... _UElements>
310 _Tuple_impl&
311 operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
312 {
313 _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
314 _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in);
315 return *this;
316 }
317
318 template<typename _UHead, typename... _UTails>
319 _Tuple_impl&
320 operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
321 {
322 _M_head(*this) = std::forward<_UHead>
323 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
324 _M_tail(*this) = std::move
325 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in));
326 return *this;
327 }
328
329 protected:
330 void
331 _M_swap(_Tuple_impl& __in)
332 noexcept(__is_nothrow_swappable<_Head>::value
333 && noexcept(_M_tail(__in)._M_swap(_M_tail(__in))))
334 {
335 using std::swap;
336 swap(_M_head(*this), _M_head(__in));
337 _Inherited::_M_swap(_M_tail(__in));
338 }
339 };
340
341 // Basis case of inheritance recursion.
342 template<std::size_t _Idx, typename _Head>
343 struct _Tuple_impl<_Idx, _Head>
344 : private _Head_base<_Idx, _Head>
345 {
346 template<std::size_t, typename...> friend class _Tuple_impl;
347
348 typedef _Head_base<_Idx, _Head> _Base;
349
350 static constexpr _Head&
351 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
91
Calling '_Head_base::_M_head'
92
Returning from '_Head_base::_M_head'
177
Calling '_Head_base::_M_head'
178
Returning from '_Head_base::_M_head'
254
Calling '_Head_base::_M_head'
255
Returning from '_Head_base::_M_head'
352
353 static constexpr const _Head&
354 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
355
356 constexpr _Tuple_impl()
357 : _Base() { }
358
359 explicit
360 constexpr _Tuple_impl(const _Head& __head)
361 : _Base(__head) { }
362
363 template<typename _UHead>
364 explicit
365 constexpr _Tuple_impl(_UHead&& __head)
366 : _Base(std::forward<_UHead>(__head)) { }
112
Calling 'forward'
113
Returning from 'forward'
114
Calling constructor for '_Head_base'
117
Returning from constructor for '_Head_base'
198
Calling 'forward'
199
Returning from 'forward'
200
Calling constructor for '_Head_base'
203
Returning from constructor for '_Head_base'
275
Calling 'forward'
276
Returning from 'forward'
277
Calling constructor for '_Head_base'
280
Returning from constructor for '_Head_base'
367
368 constexpr _Tuple_impl(const _Tuple_impl&) = default;
369
370 constexpr
371 _Tuple_impl(_Tuple_impl&& __in)
372 noexcept(is_nothrow_move_constructible<_Head>::value)
373 : _Base(std::forward<_Head>(_M_head(__in))) { }
374
375 template<typename _UHead>
376 constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
377 : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
378
379 template<typename _UHead>
380 constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
381 : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
382 { }
383
384 template<typename _Alloc>
385 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
386 : _Base(__tag, __use_alloc<_Head>(__a)) { }
387
388 template<typename _Alloc>
389 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
390 const _Head& __head)
391 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
392
393 template<typename _Alloc, typename _UHead>
394 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
395 _UHead&& __head)
396 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
397 std::forward<_UHead>(__head)) { }
398
399 template<typename _Alloc>
400 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
401 const _Tuple_impl& __in)
402 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
403
404 template<typename _Alloc>
405 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
406 _Tuple_impl&& __in)
407 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
408 std::forward<_Head>(_M_head(__in))) { }
409
410 template<typename _Alloc, typename _UHead>
411 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
412 const _Tuple_impl<_Idx, _UHead>& __in)
413 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
414 _Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
415
416 template<typename _Alloc, typename _UHead>
417 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
418 _Tuple_impl<_Idx, _UHead>&& __in)
419 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
420 std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
421 { }
422
423 _Tuple_impl&
424 operator=(const _Tuple_impl& __in)
425 {
426 _M_head(*this) = _M_head(__in);
427 return *this;
428 }
429
430 _Tuple_impl&
431 operator=(_Tuple_impl&& __in)
432 noexcept(is_nothrow_move_assignable<_Head>::value)
433 {
434 _M_head(*this) = std::forward<_Head>(_M_head(__in));
435 return *this;
436 }
437
438 template<typename _UHead>
439 _Tuple_impl&
440 operator=(const _Tuple_impl<_Idx, _UHead>& __in)
441 {
442 _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
443 return *this;
444 }
445
446 template<typename _UHead>
447 _Tuple_impl&
448 operator=(_Tuple_impl<_Idx, _UHead>&& __in)
449 {
450 _M_head(*this)
451 = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
452 return *this;
453 }
454
455 protected:
456 void
457 _M_swap(_Tuple_impl& __in)
458 noexcept(__is_nothrow_swappable<_Head>::value)
459 {
460 using std::swap;
461 swap(_M_head(*this), _M_head(__in));
462 }
463 };
464
465 // Concept utility functions, reused in conditionally-explicit
466 // constructors.
467 template<bool, typename... _Elements>
468 struct _TC
469 {
470 template<typename... _UElements>
471 static constexpr bool _ConstructibleTuple()
472 {
473 return __and_<is_constructible<_Elements, const _UElements&>...>::value;
474 }
475
476 template<typename... _UElements>
477 static constexpr bool _ImplicitlyConvertibleTuple()
478 {
479 return __and_<is_convertible<const _UElements&, _Elements>...>::value;
480 }
481
482 template<typename... _UElements>
483 static constexpr bool _MoveConstructibleTuple()
484 {
485 return __and_<is_constructible<_Elements, _UElements&&>...>::value;
486 }
487
488 template<typename... _UElements>
489 static constexpr bool _ImplicitlyMoveConvertibleTuple()
490 {
491 return __and_<is_convertible<_UElements&&, _Elements>...>::value;
492 }
493
494 template<typename _SrcTuple>
495 static constexpr bool _NonNestedTuple()
496 {
497 return __and_<__not_<is_same<tuple<_Elements...>,
498 typename remove_cv<
499 typename remove_reference<_SrcTuple>::type
500 >::type>>,
501 __not_<is_convertible<_SrcTuple, _Elements...>>,
502 __not_<is_constructible<_Elements..., _SrcTuple>>
503 >::value;
504 }
505 template<typename... _UElements>
506 static constexpr bool _NotSameTuple()
507 {
508 return __not_<is_same<tuple<_Elements...>,
509 typename remove_const<
510 typename remove_reference<_UElements...>::type
511 >::type>>::value;
512 }
513 };
514
515 template<typename... _Elements>
516 struct _TC<false, _Elements...>
517 {
518 template<typename... _UElements>
519 static constexpr bool _ConstructibleTuple()
520 {
521 return false;
522 }
523
524 template<typename... _UElements>
525 static constexpr bool _ImplicitlyConvertibleTuple()
526 {
527 return false;
528 }
529
530 template<typename... _UElements>
531 static constexpr bool _MoveConstructibleTuple()
532 {
533 return false;
534 }
535
536 template<typename... _UElements>
537 static constexpr bool _ImplicitlyMoveConvertibleTuple()
538 {
539 return false;
540 }
541