Bug Summary

File:tools/llvm-readobj/Win64EHDumper.cpp
Warning:line 293, column 9
1st function call argument is an uninitialized value

Annotated Source Code

/build/llvm-toolchain-snapshot-6.0~svn318882/tools/llvm-readobj/Win64EHDumper.cpp

1//===- Win64EHDumper.cpp - Win64 EH Printer ---------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Win64EHDumper.h"
11#include "llvm-readobj.h"
12#include "llvm/Object/COFF.h"
13#include "llvm/Support/ErrorHandling.h"
14#include "llvm/Support/Format.h"
15
16using namespace llvm;
17using namespace llvm::object;
18using namespace llvm::Win64EH;
19
20static const EnumEntry<unsigned> UnwindFlags[] = {
21 { "ExceptionHandler", UNW_ExceptionHandler },
22 { "TerminateHandler", UNW_TerminateHandler },
23 { "ChainInfo" , UNW_ChainInfo }
24};
25
26static const EnumEntry<unsigned> UnwindOpInfo[] = {
27 { "RAX", 0 },
28 { "RCX", 1 },
29 { "RDX", 2 },
30 { "RBX", 3 },
31 { "RSP", 4 },
32 { "RBP", 5 },
33 { "RSI", 6 },
34 { "RDI", 7 },
35 { "R8", 8 },
36 { "R9", 9 },
37 { "R10", 10 },
38 { "R11", 11 },
39 { "R12", 12 },
40 { "R13", 13 },
41 { "R14", 14 },
42 { "R15", 15 }
43};
44
45static uint64_t getOffsetOfLSDA(const UnwindInfo& UI) {
46 return static_cast<const char*>(UI.getLanguageSpecificData())
47 - reinterpret_cast<const char*>(&UI);
48}
49
50static uint32_t getLargeSlotValue(ArrayRef<UnwindCode> UC) {
51 if (UC.size() < 3)
52 return 0;
53 return UC[1].FrameOffset + (static_cast<uint32_t>(UC[2].FrameOffset) << 16);
54}
55
56// Returns the name of the unwind code.
57static StringRef getUnwindCodeTypeName(uint8_t Code) {
58 switch (Code) {
59 default: llvm_unreachable("Invalid unwind code")::llvm::llvm_unreachable_internal("Invalid unwind code", "/build/llvm-toolchain-snapshot-6.0~svn318882/tools/llvm-readobj/Win64EHDumper.cpp"
, 59)
;
60 case UOP_PushNonVol: return "PUSH_NONVOL";
61 case UOP_AllocLarge: return "ALLOC_LARGE";
62 case UOP_AllocSmall: return "ALLOC_SMALL";
63 case UOP_SetFPReg: return "SET_FPREG";
64 case UOP_SaveNonVol: return "SAVE_NONVOL";
65 case UOP_SaveNonVolBig: return "SAVE_NONVOL_FAR";
66 case UOP_SaveXMM128: return "SAVE_XMM128";
67 case UOP_SaveXMM128Big: return "SAVE_XMM128_FAR";
68 case UOP_PushMachFrame: return "PUSH_MACHFRAME";
69 }
70}
71
72// Returns the name of a referenced register.
73static StringRef getUnwindRegisterName(uint8_t Reg) {
74 switch (Reg) {
75 default: llvm_unreachable("Invalid register")::llvm::llvm_unreachable_internal("Invalid register", "/build/llvm-toolchain-snapshot-6.0~svn318882/tools/llvm-readobj/Win64EHDumper.cpp"
, 75)
;
76 case 0: return "RAX";
77 case 1: return "RCX";
78 case 2: return "RDX";
79 case 3: return "RBX";
80 case 4: return "RSP";
81 case 5: return "RBP";
82 case 6: return "RSI";
83 case 7: return "RDI";
84 case 8: return "R8";
85 case 9: return "R9";
86 case 10: return "R10";
87 case 11: return "R11";
88 case 12: return "R12";
89 case 13: return "R13";
90 case 14: return "R14";
91 case 15: return "R15";
92 }
93}
94
95// Calculates the number of array slots required for the unwind code.
96static unsigned getNumUsedSlots(const UnwindCode &UnwindCode) {
97 switch (UnwindCode.getUnwindOp()) {
98 default: llvm_unreachable("Invalid unwind code")::llvm::llvm_unreachable_internal("Invalid unwind code", "/build/llvm-toolchain-snapshot-6.0~svn318882/tools/llvm-readobj/Win64EHDumper.cpp"
, 98)
;
99 case UOP_PushNonVol:
100 case UOP_AllocSmall:
101 case UOP_SetFPReg:
102 case UOP_PushMachFrame:
103 return 1;
104 case UOP_SaveNonVol:
105 case UOP_SaveXMM128:
106 return 2;
107 case UOP_SaveNonVolBig:
108 case UOP_SaveXMM128Big:
109 return 3;
110 case UOP_AllocLarge:
111 return (UnwindCode.getOpInfo() == 0) ? 2 : 3;
112 }
113}
114
115static std::string formatSymbol(const Dumper::Context &Ctx,
116 const coff_section *Section, uint64_t Offset,
117 uint32_t Displacement) {
118 std::string Buffer;
119 raw_string_ostream OS(Buffer);
120
121 SymbolRef Symbol;
122 if (!Ctx.ResolveSymbol(Section, Offset, Symbol, Ctx.UserData)) {
123 Expected<StringRef> Name = Symbol.getName();
124 if (Name) {
125 OS << *Name;
126 if (Displacement > 0)
127 OS << format(" +0x%X (0x%" PRIX64"l" "X" ")", Displacement, Offset);
128 else
129 OS << format(" (0x%" PRIX64"l" "X" ")", Offset);
130 return OS.str();
131 } else {
132 // TODO: Actually report errors helpfully.
133 consumeError(Name.takeError());
134 }
135 }
136
137 OS << format(" (0x%" PRIX64"l" "X" ")", Offset);
138 return OS.str();
139}
140
141static std::error_code resolveRelocation(const Dumper::Context &Ctx,
142 const coff_section *Section,
143 uint64_t Offset,
144 const coff_section *&ResolvedSection,
145 uint64_t &ResolvedAddress) {
146 SymbolRef Symbol;
20
Calling defaulted default constructor for 'SymbolRef'
25
Returning from default constructor for 'SymbolRef'
147 if (std::error_code EC =
26
Calling 'error_code::operator bool'
28
Returning from 'error_code::operator bool'
29
Taking false branch
148 Ctx.ResolveSymbol(Section, Offset, Symbol, Ctx.UserData))
149 return EC;
150
151 Expected<uint64_t> ResolvedAddressOrErr = Symbol.getAddress();
30
Calling 'SymbolRef::getAddress'
57
Returning from 'SymbolRef::getAddress'
58
Calling move constructor for 'Expected'
73
Returning from move constructor for 'Expected'
152 if (!ResolvedAddressOrErr)
74
Calling 'Expected::operator bool'
76
Returning from 'Expected::operator bool'
77
Taking true branch
153 return errorToErrorCode(ResolvedAddressOrErr.takeError());
78
Calling 'Expected::takeError'
85
Returning from 'Expected::takeError'
86
Calling '~Expected'
96
Returning from '~Expected'
154 ResolvedAddress = *ResolvedAddressOrErr;
155
156 Expected<section_iterator> SI = Symbol.getSection();
157 if (!SI)
158 return errorToErrorCode(SI.takeError());
159 ResolvedSection = Ctx.COFF.getCOFFSection(**SI);
160 return std::error_code();
161}
162
163namespace llvm {
164namespace Win64EH {
165void Dumper::printRuntimeFunctionEntry(const Context &Ctx,
166 const coff_section *Section,
167 uint64_t Offset,
168 const RuntimeFunction &RF) {
169 SW.printString("StartAddress",
170 formatSymbol(Ctx, Section, Offset + 0, RF.StartAddress));
171 SW.printString("EndAddress",
172 formatSymbol(Ctx, Section, Offset + 4, RF.EndAddress));
173 SW.printString("UnwindInfoAddress",
174 formatSymbol(Ctx, Section, Offset + 8, RF.UnwindInfoOffset));
175}
176
177// Prints one unwind code. Because an unwind code can occupy up to 3 slots in
178// the unwind codes array, this function requires that the correct number of
179// slots is provided.
180void Dumper::printUnwindCode(const UnwindInfo& UI, ArrayRef<UnwindCode> UC) {
181 assert(UC.size() >= getNumUsedSlots(UC[0]))(static_cast <bool> (UC.size() >= getNumUsedSlots(UC
[0])) ? void (0) : __assert_fail ("UC.size() >= getNumUsedSlots(UC[0])"
, "/build/llvm-toolchain-snapshot-6.0~svn318882/tools/llvm-readobj/Win64EHDumper.cpp"
, 181, __extension__ __PRETTY_FUNCTION__))
;
182
183 SW.startLine() << format("0x%02X: ", unsigned(UC[0].u.CodeOffset))
184 << getUnwindCodeTypeName(UC[0].getUnwindOp());
185
186 switch (UC[0].getUnwindOp()) {
187 case UOP_PushNonVol:
188 OS << " reg=" << getUnwindRegisterName(UC[0].getOpInfo());
189 break;
190
191 case UOP_AllocLarge:
192 OS << " size="
193 << ((UC[0].getOpInfo() == 0) ? UC[1].FrameOffset * 8
194 : getLargeSlotValue(UC));
195 break;
196
197 case UOP_AllocSmall:
198 OS << " size=" << (UC[0].getOpInfo() + 1) * 8;
199 break;
200
201 case UOP_SetFPReg:
202 if (UI.getFrameRegister() == 0)
203 OS << " reg=<invalid>";
204 else
205 OS << " reg=" << getUnwindRegisterName(UI.getFrameRegister())
206 << format(", offset=0x%X", UI.getFrameOffset() * 16);
207 break;
208
209 case UOP_SaveNonVol:
210 OS << " reg=" << getUnwindRegisterName(UC[0].getOpInfo())
211 << format(", offset=0x%X", UC[1].FrameOffset * 8);
212 break;
213
214 case UOP_SaveNonVolBig:
215 OS << " reg=" << getUnwindRegisterName(UC[0].getOpInfo())
216 << format(", offset=0x%X", getLargeSlotValue(UC));
217 break;
218
219 case UOP_SaveXMM128:
220 OS << " reg=XMM" << static_cast<uint32_t>(UC[0].getOpInfo())
221 << format(", offset=0x%X", UC[1].FrameOffset * 16);
222 break;
223
224 case UOP_SaveXMM128Big:
225 OS << " reg=XMM" << static_cast<uint32_t>(UC[0].getOpInfo())
226 << format(", offset=0x%X", getLargeSlotValue(UC));
227 break;
228
229 case UOP_PushMachFrame:
230 OS << " errcode=" << (UC[0].getOpInfo() == 0 ? "no" : "yes");
231 break;
232 }
233
234 OS << "\n";
235}
236
237void Dumper::printUnwindInfo(const Context &Ctx, const coff_section *Section,
238 off_t Offset, const UnwindInfo &UI) {
239 DictScope UIS(SW, "UnwindInfo");
240 SW.printNumber("Version", UI.getVersion());
241 SW.printFlags("Flags", UI.getFlags(), makeArrayRef(UnwindFlags));
242 SW.printNumber("PrologSize", UI.PrologSize);
243 if (UI.getFrameRegister()) {
244 SW.printEnum("FrameRegister", UI.getFrameRegister(),
245 makeArrayRef(UnwindOpInfo));
246 SW.printHex("FrameOffset", UI.getFrameOffset());
247 } else {
248 SW.printString("FrameRegister", StringRef("-"));
249 SW.printString("FrameOffset", StringRef("-"));
250 }
251
252 SW.printNumber("UnwindCodeCount", UI.NumCodes);
253 {
254 ListScope UCS(SW, "UnwindCodes");
255 ArrayRef<UnwindCode> UC(&UI.UnwindCodes[0], UI.NumCodes);
256 for (const UnwindCode *UCI = UC.begin(), *UCE = UC.end(); UCI < UCE; ++UCI) {
257 unsigned UsedSlots = getNumUsedSlots(*UCI);
258 if (UsedSlots > UC.size()) {
259 errs() << "corrupt unwind data";
260 return;
261 }
262
263 printUnwindCode(UI, makeArrayRef(UCI, UCE));
264 UCI = UCI + UsedSlots - 1;
265 }
266 }
267
268 uint64_t LSDAOffset = Offset + getOffsetOfLSDA(UI);
269 if (UI.getFlags() & (UNW_ExceptionHandler | UNW_TerminateHandler)) {
270 SW.printString("Handler",
271 formatSymbol(Ctx, Section, LSDAOffset,
272 UI.getLanguageSpecificHandlerOffset()));
273 } else if (UI.getFlags() & UNW_ChainInfo) {
274 if (const RuntimeFunction *Chained = UI.getChainedFunctionEntry()) {
275 DictScope CS(SW, "Chained");
276 printRuntimeFunctionEntry(Ctx, Section, LSDAOffset, *Chained);
277 }
278 }
279}
280
281void Dumper::printRuntimeFunction(const Context &Ctx,
282 const coff_section *Section,
283 uint64_t SectionOffset,
284 const RuntimeFunction &RF) {
285 DictScope RFS(SW, "RuntimeFunction");
286 printRuntimeFunctionEntry(Ctx, Section, SectionOffset, RF);
287
288 const coff_section *XData;
18
'XData' declared without an initial value
289 uint64_t Offset;
290 resolveRelocation(Ctx, Section, SectionOffset + 8, XData, Offset);
19
Calling 'resolveRelocation'
97
Returning from 'resolveRelocation'
291
292 ArrayRef<uint8_t> Contents;
293 error(Ctx.COFF.getSectionContents(XData, Contents));
98
1st function call argument is an uninitialized value
294 if (Contents.empty())
295 return;
296
297 Offset = Offset + RF.UnwindInfoOffset;
298 if (Offset > Contents.size())
299 return;
300
301 const auto UI = reinterpret_cast<const UnwindInfo*>(Contents.data() + Offset);
302 printUnwindInfo(Ctx, XData, Offset, *UI);
303}
304
305void Dumper::printData(const Context &Ctx) {
306 for (const auto &Section : Ctx.COFF.sections()) {
307 StringRef Name;
308 Section.getName(Name);
309
310 if (Name != ".pdata" && !Name.startswith(".pdata$"))
1
Taking false branch
5
Taking false branch
9
Taking false branch
13
Taking false branch
311 continue;
312
313 const coff_section *PData = Ctx.COFF.getCOFFSection(Section);
314 ArrayRef<uint8_t> Contents;
315 error(Ctx.COFF.getSectionContents(PData, Contents));
316 if (Contents.empty())
2
Assuming the condition is false
3
Taking false branch
6
Assuming the condition is false
7
Taking false branch
10
Assuming the condition is false
11
Taking false branch
14
Assuming the condition is false
15
Taking false branch
317 continue;
318
319 const RuntimeFunction *Entries =
320 reinterpret_cast<const RuntimeFunction *>(Contents.data());
321 const size_t Count = Contents.size() / sizeof(RuntimeFunction);
322 ArrayRef<RuntimeFunction> RuntimeFunctions(Entries, Count);
323
324 size_t Index = 0;
325 for (const auto &RF : RuntimeFunctions) {
4
Assuming '__begin' is equal to '__end'
8
Assuming '__begin' is equal to '__end'
12
Assuming '__begin' is equal to '__end'
16
Assuming '__begin' is not equal to '__end'
326 printRuntimeFunction(Ctx, Ctx.COFF.getCOFFSection(Section),
17
Calling 'Dumper::printRuntimeFunction'
327 Index * sizeof(RuntimeFunction), RF);
328 ++Index;
329 }
330 }
331}
332}
333}
334

/build/llvm-toolchain-snapshot-6.0~svn318882/include/llvm/Object/ObjectFile.h

1//===- ObjectFile.h - File format independent object file -------*- 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 a file format independent ObjectFile class.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_OBJECT_OBJECTFILE_H
15#define LLVM_OBJECT_OBJECTFILE_H
16
17#include "llvm/ADT/StringRef.h"
18#include "llvm/ADT/iterator_range.h"
19#include "llvm/BinaryFormat/Magic.h"
20#include "llvm/MC/SubtargetFeature.h"
21#include "llvm/Object/Binary.h"
22#include "llvm/Object/Error.h"
23#include "llvm/Object/SymbolicFile.h"
24#include "llvm/Support/Casting.h"
25#include "llvm/Support/Error.h"
26#include "llvm/Support/FileSystem.h"
27#include "llvm/Support/MemoryBuffer.h"
28#include <cassert>
29#include <cstdint>
30#include <memory>
31#include <system_error>
32
33namespace llvm {
34
35class ARMAttributeParser;
36
37namespace object {
38
39class COFFObjectFile;
40class MachOObjectFile;
41class ObjectFile;
42class SectionRef;
43class SymbolRef;
44class symbol_iterator;
45class WasmObjectFile;
46
47using section_iterator = content_iterator<SectionRef>;
48
49/// This is a value type class that represents a single relocation in the list
50/// of relocations in the object file.
51class RelocationRef {
52 DataRefImpl RelocationPimpl;
53 const ObjectFile *OwningObject = nullptr;
54
55public:
56 RelocationRef() = default;
57 RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
58
59 bool operator==(const RelocationRef &Other) const;
60
61 void moveNext();
62
63 uint64_t getOffset() const;
64 symbol_iterator getSymbol() const;
65 uint64_t getType() const;
66
67 /// @brief Get a string that represents the type of this relocation.
68 ///
69 /// This is for display purposes only.
70 void getTypeName(SmallVectorImpl<char> &Result) const;
71
72 DataRefImpl getRawDataRefImpl() const;
73 const ObjectFile *getObject() const;
74};
75
76using relocation_iterator = content_iterator<RelocationRef>;
77
78/// This is a value type class that represents a single section in the list of
79/// sections in the object file.
80class SectionRef {
81 friend class SymbolRef;
82
83 DataRefImpl SectionPimpl;
84 const ObjectFile *OwningObject = nullptr;
85
86public:
87 SectionRef() = default;
88 SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
89
90 bool operator==(const SectionRef &Other) const;
91 bool operator!=(const SectionRef &Other) const;
92 bool operator<(const SectionRef &Other) const;
93
94 void moveNext();
95
96 std::error_code getName(StringRef &Result) const;
97 uint64_t getAddress() const;
98 uint64_t getIndex() const;
99 uint64_t getSize() const;
100 std::error_code getContents(StringRef &Result) const;
101
102 /// @brief Get the alignment of this section as the actual value (not log 2).
103 uint64_t getAlignment() const;
104
105 bool isCompressed() const;
106 bool isText() const;
107 bool isData() const;
108 bool isBSS() const;
109 bool isVirtual() const;
110 bool isBitcode() const;
111 bool isStripped() const;
112
113 bool containsSymbol(SymbolRef S) const;
114
115 relocation_iterator relocation_begin() const;
116 relocation_iterator relocation_end() const;
117 iterator_range<relocation_iterator> relocations() const {
118 return make_range(relocation_begin(), relocation_end());
119 }
120 section_iterator getRelocatedSection() const;
121
122 DataRefImpl getRawDataRefImpl() const;
123 const ObjectFile *getObject() const;
124};
125
126/// This is a value type class that represents a single symbol in the list of
127/// symbols in the object file.
128class SymbolRef : public BasicSymbolRef {
129 friend class SectionRef;
130
131public:
132 enum Type {
133 ST_Unknown, // Type not specified
134 ST_Data,
135 ST_Debug,
136 ST_File,
137 ST_Function,
138 ST_Other
139 };
140
141 SymbolRef() = default;
21
Calling defaulted default constructor for 'BasicSymbolRef'
24
Returning from default constructor for 'BasicSymbolRef'
142 SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
143 SymbolRef(const BasicSymbolRef &B) : BasicSymbolRef(B) {
144 assert(isa<ObjectFile>(BasicSymbolRef::getObject()))(static_cast <bool> (isa<ObjectFile>(BasicSymbolRef
::getObject())) ? void (0) : __assert_fail ("isa<ObjectFile>(BasicSymbolRef::getObject())"
, "/build/llvm-toolchain-snapshot-6.0~svn318882/include/llvm/Object/ObjectFile.h"
, 144, __extension__ __PRETTY_FUNCTION__))
;
145 }
146
147 Expected<StringRef> getName() const;
148 /// Returns the symbol virtual address (i.e. address at which it will be
149 /// mapped).
150 Expected<uint64_t> getAddress() const;
151
152 /// Return the value of the symbol depending on the object this can be an
153 /// offset or a virtual address.
154 uint64_t getValue() const;
155
156 /// @brief Get the alignment of this symbol as the actual value (not log 2).
157 uint32_t getAlignment() const;
158 uint64_t getCommonSize() const;
159 Expected<SymbolRef::Type> getType() const;
160
161 /// @brief Get section this symbol is defined in reference to. Result is
162 /// end_sections() if it is undefined or is an absolute symbol.
163 Expected<section_iterator> getSection() const;
164
165 const ObjectFile *getObject() const;
166};
167
168class symbol_iterator : public basic_symbol_iterator {
169public:
170 symbol_iterator(SymbolRef Sym) : basic_symbol_iterator(Sym) {}
171 symbol_iterator(const basic_symbol_iterator &B)
172 : basic_symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
173 cast<ObjectFile>(B->getObject()))) {}
174
175 const SymbolRef *operator->() const {
176 const BasicSymbolRef &P = basic_symbol_iterator::operator *();
177 return static_cast<const SymbolRef*>(&P);
178 }
179
180 const SymbolRef &operator*() const {
181 const BasicSymbolRef &P = basic_symbol_iterator::operator *();
182 return static_cast<const SymbolRef&>(P);
183 }
184};
185
186/// This class is the base class for all object file types. Concrete instances
187/// of this object are created by createObjectFile, which figures out which type
188/// to create.
189class ObjectFile : public SymbolicFile {
190 virtual void anchor();
191
192protected:
193 ObjectFile(unsigned int Type, MemoryBufferRef Source);
194
195 const uint8_t *base() const {
196 return reinterpret_cast<const uint8_t *>(Data.getBufferStart());
197 }
198
199 // These functions are for SymbolRef to call internally. The main goal of
200 // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
201 // entry in the memory mapped object file. SymbolPimpl cannot contain any
202 // virtual functions because then it could not point into the memory mapped
203 // file.
204 //
205 // Implementations assume that the DataRefImpl is valid and has not been
206 // modified externally. It's UB otherwise.
207 friend class SymbolRef;
208
209 virtual Expected<StringRef> getSymbolName(DataRefImpl Symb) const = 0;
210 std::error_code printSymbolName(raw_ostream &OS,
211 DataRefImpl Symb) const override;
212 virtual Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const = 0;
213 virtual uint64_t getSymbolValueImpl(DataRefImpl Symb) const = 0;
214 virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const;
215 virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0;
216 virtual Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const = 0;
217 virtual Expected<section_iterator>
218 getSymbolSection(DataRefImpl Symb) const = 0;
219
220 // Same as above for SectionRef.
221 friend class SectionRef;
222
223 virtual void moveSectionNext(DataRefImpl &Sec) const = 0;
224 virtual std::error_code getSectionName(DataRefImpl Sec,
225 StringRef &Res) const = 0;
226 virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0;
227 virtual uint64_t getSectionIndex(DataRefImpl Sec) const = 0;
228 virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0;
229 virtual std::error_code getSectionContents(DataRefImpl Sec,
230 StringRef &Res) const = 0;
231 virtual uint64_t getSectionAlignment(DataRefImpl Sec) const = 0;
232 virtual bool isSectionCompressed(DataRefImpl Sec) const = 0;
233 virtual bool isSectionText(DataRefImpl Sec) const = 0;
234 virtual bool isSectionData(DataRefImpl Sec) const = 0;
235 virtual bool isSectionBSS(DataRefImpl Sec) const = 0;
236 // A section is 'virtual' if its contents aren't present in the object image.
237 virtual bool isSectionVirtual(DataRefImpl Sec) const = 0;
238 virtual bool isSectionBitcode(DataRefImpl Sec) const;
239 virtual bool isSectionStripped(DataRefImpl Sec) const;
240 virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
241 virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
242 virtual section_iterator getRelocatedSection(DataRefImpl Sec) const;
243
244 // Same as above for RelocationRef.
245 friend class RelocationRef;
246 virtual void moveRelocationNext(DataRefImpl &Rel) const = 0;
247 virtual uint64_t getRelocationOffset(DataRefImpl Rel) const = 0;
248 virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0;
249 virtual uint64_t getRelocationType(DataRefImpl Rel) const = 0;
250 virtual void getRelocationTypeName(DataRefImpl Rel,
251 SmallVectorImpl<char> &Result) const = 0;
252
253 uint64_t getSymbolValue(DataRefImpl Symb) const;
254
255public:
256 ObjectFile() = delete;
257 ObjectFile(const ObjectFile &other) = delete;
258
259 uint64_t getCommonSymbolSize(DataRefImpl Symb) const {
260 assert(getSymbolFlags(Symb) & SymbolRef::SF_Common)(static_cast <bool> (getSymbolFlags(Symb) & SymbolRef
::SF_Common) ? void (0) : __assert_fail ("getSymbolFlags(Symb) & SymbolRef::SF_Common"
, "/build/llvm-toolchain-snapshot-6.0~svn318882/include/llvm/Object/ObjectFile.h"
, 260, __extension__ __PRETTY_FUNCTION__))
;
261 return getCommonSymbolSizeImpl(Symb);
262 }
263
264 using symbol_iterator_range = iterator_range<symbol_iterator>;
265 symbol_iterator_range symbols() const {
266 return symbol_iterator_range(symbol_begin(), symbol_end());
267 }
268
269 virtual section_iterator section_begin() const = 0;
270 virtual section_iterator section_end() const = 0;
271
272 using section_iterator_range = iterator_range<section_iterator>;
273 section_iterator_range sections() const {
274 return section_iterator_range(section_begin(), section_end());
275 }
276
277 /// @brief The number of bytes used to represent an address in this object
278 /// file format.
279 virtual uint8_t getBytesInAddress() const = 0;
280
281 virtual StringRef getFileFormatName() const = 0;
282 virtual /* Triple::ArchType */ unsigned getArch() const = 0;
283 virtual SubtargetFeatures getFeatures() const = 0;
284 virtual void setARMSubArch(Triple &TheTriple) const { }
285
286 /// @brief Create a triple from the data in this object file.
287 Triple makeTriple() const;
288
289 /// Returns platform-specific object flags, if any.
290 virtual std::error_code getPlatformFlags(unsigned &Result) const {
291 Result = 0;
292 return object_error::invalid_file_type;
293 }
294
295 virtual std::error_code
296 getBuildAttributes(ARMAttributeParser &Attributes) const {
297 return std::error_code();
298 }
299
300 /// Maps a debug section name to a standard DWARF section name.
301 virtual StringRef mapDebugSectionName(StringRef Name) const { return Name; }
302
303 /// True if this is a relocatable object (.o/.obj).
304 virtual bool isRelocatableObject() const = 0;
305
306 /// @returns Pointer to ObjectFile subclass to handle this type of object.
307 /// @param ObjectPath The path to the object file. ObjectPath.isObject must
308 /// return true.
309 /// @brief Create ObjectFile from path.
310 static Expected<OwningBinary<ObjectFile>>
311 createObjectFile(StringRef ObjectPath);
312
313 static Expected<std::unique_ptr<ObjectFile>>
314 createObjectFile(MemoryBufferRef Object, llvm::file_magic Type);
315 static Expected<std::unique_ptr<ObjectFile>>
316 createObjectFile(MemoryBufferRef Object) {
317 return createObjectFile(Object, llvm::file_magic::unknown);
318 }
319
320 static bool classof(const Binary *v) {
321 return v->isObject();
322 }
323
324 static Expected<std::unique_ptr<COFFObjectFile>>
325 createCOFFObjectFile(MemoryBufferRef Object);
326
327 static Expected<std::unique_ptr<ObjectFile>>
328 createELFObjectFile(MemoryBufferRef Object);
329
330 static Expected<std::unique_ptr<MachOObjectFile>>
331 createMachOObjectFile(MemoryBufferRef Object,
332 uint32_t UniversalCputype = 0,
333 uint32_t UniversalIndex = 0);
334
335 static Expected<std::unique_ptr<WasmObjectFile>>
336 createWasmObjectFile(MemoryBufferRef Object);
337};
338
339// Inline function definitions.
340inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
341 : BasicSymbolRef(SymbolP, Owner) {}
342
343inline Expected<StringRef> SymbolRef::getName() const {
344 return getObject()->getSymbolName(getRawDataRefImpl());
345}
346
347inline Expected<uint64_t> SymbolRef::getAddress() const {
348 return getObject()->getSymbolAddress(getRawDataRefImpl());
31
Calling 'SymbolRef::getObject'
54
Returning from 'SymbolRef::getObject'
55
Calling 'BasicSymbolRef::getRawDataRefImpl'
56
Returning from 'BasicSymbolRef::getRawDataRefImpl'
349}
350
351inline uint64_t SymbolRef::getValue() const {
352 return getObject()->getSymbolValue(getRawDataRefImpl());
353}
354
355inline uint32_t SymbolRef::getAlignment() const {
356 return getObject()->getSymbolAlignment(getRawDataRefImpl());
357}
358
359inline uint64_t SymbolRef::getCommonSize() const {
360 return getObject()->getCommonSymbolSize(getRawDataRefImpl());
361}
362
363inline Expected<section_iterator> SymbolRef::getSection() const {
364 return getObject()->getSymbolSection(getRawDataRefImpl());
365}
366
367inline Expected<SymbolRef::Type> SymbolRef::getType() const {
368 return getObject()->getSymbolType(getRawDataRefImpl());
369}
370
371inline const ObjectFile *SymbolRef::getObject() const {
372 const SymbolicFile *O = BasicSymbolRef::getObject();
32
Calling 'BasicSymbolRef::getObject'
33
Returning from 'BasicSymbolRef::getObject'
373 return cast<ObjectFile>(O);
34
Calling 'cast'
53
Returning from 'cast'
374}
375
376/// SectionRef
377inline SectionRef::SectionRef(DataRefImpl SectionP,
378 const ObjectFile *Owner)
379 : SectionPimpl(SectionP)
380 , OwningObject(Owner) {}
381
382inline bool SectionRef::operator==(const SectionRef &Other) const {
383 return SectionPimpl == Other.SectionPimpl;
384}
385
386inline bool SectionRef::operator!=(const SectionRef &Other) const {
387 return SectionPimpl != Other.SectionPimpl;
388}
389
390inline bool SectionRef::operator<(const SectionRef &Other) const {
391 return SectionPimpl < Other.SectionPimpl;
392}
393
394inline void SectionRef::moveNext() {
395 return OwningObject->moveSectionNext(SectionPimpl);
396}
397
398inline std::error_code SectionRef::getName(StringRef &Result) const {
399 return OwningObject->getSectionName(SectionPimpl, Result);
400}
401
402inline uint64_t SectionRef::getAddress() const {
403 return OwningObject->getSectionAddress(SectionPimpl);
404}
405
406inline uint64_t SectionRef::getIndex() const {
407 return OwningObject->getSectionIndex(SectionPimpl);
408}
409
410inline uint64_t SectionRef::getSize() const {
411 return OwningObject->getSectionSize(SectionPimpl);
412}
413
414inline std::error_code SectionRef::getContents(StringRef &Result) const {
415 return OwningObject->getSectionContents(SectionPimpl, Result);
416}
417
418inline uint64_t SectionRef::getAlignment() const {
419 return OwningObject->getSectionAlignment(SectionPimpl);
420}
421
422inline bool SectionRef::isCompressed() const {
423 return OwningObject->isSectionCompressed(SectionPimpl);
424}
425
426inline bool SectionRef::isText() const {
427 return OwningObject->isSectionText(SectionPimpl);
428}
429
430inline bool SectionRef::isData() const {
431 return OwningObject->isSectionData(SectionPimpl);
432}
433
434inline bool SectionRef::isBSS() const {
435 return OwningObject->isSectionBSS(SectionPimpl);
436}
437
438inline bool SectionRef::isVirtual() const {
439 return OwningObject->isSectionVirtual(SectionPimpl);
440}
441
442inline bool SectionRef::isBitcode() const {
443 return OwningObject->isSectionBitcode(SectionPimpl);
444}
445
446inline bool SectionRef::isStripped() const {
447 return OwningObject->isSectionStripped(SectionPimpl);
448}
449
450inline relocation_iterator SectionRef::relocation_begin() const {
451 return OwningObject->section_rel_begin(SectionPimpl);
452}
453
454inline relocation_iterator SectionRef::relocation_end() const {
455 return OwningObject->section_rel_end(SectionPimpl);
456}
457
458inline section_iterator SectionRef::getRelocatedSection() const {
459 return OwningObject->getRelocatedSection(SectionPimpl);
460}
461
462inline DataRefImpl SectionRef::getRawDataRefImpl() const {
463 return SectionPimpl;
464}
465
466inline const ObjectFile *SectionRef::getObject() const {
467 return OwningObject;
468}
469
470/// RelocationRef
471inline RelocationRef::RelocationRef(DataRefImpl RelocationP,
472 const ObjectFile *Owner)
473 : RelocationPimpl(RelocationP)
474 , OwningObject(Owner) {}
475
476inline bool RelocationRef::operator==(const RelocationRef &Other) const {
477 return RelocationPimpl == Other.RelocationPimpl;
478}
479
480inline void RelocationRef::moveNext() {
481 return OwningObject->moveRelocationNext(RelocationPimpl);
482}
483
484inline uint64_t RelocationRef::getOffset() const {
485 return OwningObject->getRelocationOffset(RelocationPimpl);
486}
487
488inline symbol_iterator RelocationRef::getSymbol() const {
489 return OwningObject->getRelocationSymbol(RelocationPimpl);
490}
491
492inline uint64_t RelocationRef::getType() const {
493 return OwningObject->getRelocationType(RelocationPimpl);
494}
495
496inline void RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const {
497 return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
498}
499
500inline DataRefImpl RelocationRef::getRawDataRefImpl() const {
501 return RelocationPimpl;
502}
503
504inline const ObjectFile *RelocationRef::getObject() const {
505 return OwningObject;
506}
507
508} // end namespace object
509
510} // end namespace llvm
511
512#endif // LLVM_OBJECT_OBJECTFILE_H

/build/llvm-toolchain-snapshot-6.0~svn318882/include/llvm/Object/SymbolicFile.h

1//===- SymbolicFile.h - Interface that only provides symbols ----*- 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 SymbolicFile interface.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_OBJECT_SYMBOLICFILE_H
15#define LLVM_OBJECT_SYMBOLICFILE_H
16
17#include "llvm/ADT/StringRef.h"
18#include "llvm/ADT/iterator_range.h"
19#include "llvm/BinaryFormat/Magic.h"
20#include "llvm/Object/Binary.h"
21#include "llvm/Support/Error.h"
22#include "llvm/Support/FileSystem.h"
23#include "llvm/Support/Format.h"
24#include "llvm/Support/MemoryBuffer.h"
25#include <cinttypes>
26#include <cstdint>
27#include <cstring>
28#include <iterator>
29#include <memory>
30#include <system_error>
31
32namespace llvm {
33namespace object {
34
35union DataRefImpl {
36 // This entire union should probably be a
37 // char[max(8, sizeof(uintptr_t))] and require the impl to cast.
38 struct {
39 uint32_t a, b;
40 } d;
41 uintptr_t p;
42
43 DataRefImpl() { std::memset(this, 0, sizeof(DataRefImpl)); }
44};
45
46template <typename OStream>
47OStream& operator<<(OStream &OS, const DataRefImpl &D) {
48 OS << "(" << format("0x%08" PRIxPTR"l" "x", D.p) << " (" << format("0x%08x", D.d.a)
49 << ", " << format("0x%08x", D.d.b) << "))";
50 return OS;
51}
52
53inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) {
54 // Check bitwise identical. This is the only legal way to compare a union w/o
55 // knowing which member is in use.
56 return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
57}
58
59inline bool operator!=(const DataRefImpl &a, const DataRefImpl &b) {
60 return !operator==(a, b);
61}
62
63inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
64 // Check bitwise identical. This is the only legal way to compare a union w/o
65 // knowing which member is in use.
66 return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0;
67}
68
69template <class content_type>
70class content_iterator
71 : public std::iterator<std::forward_iterator_tag, content_type> {
72 content_type Current;
73
74public:
75 content_iterator(content_type symb) : Current(std::move(symb)) {}
76
77 const content_type *operator->() const { return &Current; }
78
79 const content_type &operator*() const { return Current; }
80
81 bool operator==(const content_iterator &other) const {
82 return Current == other.Current;
83 }
84
85 bool operator!=(const content_iterator &other) const {
86 return !(*this == other);
87 }
88
89 content_iterator &operator++() { // preincrement
90 Current.moveNext();
91 return *this;
92 }
93};
94
95class SymbolicFile;
96
97/// This is a value type class that represents a single symbol in the list of
98/// symbols in the object file.
99class BasicSymbolRef {
100 DataRefImpl SymbolPimpl;
101 const SymbolicFile *OwningObject = nullptr;
102
103public:
104 enum Flags : unsigned {
105 SF_None = 0,
106 SF_Undefined = 1U << 0, // Symbol is defined in another object file
107 SF_Global = 1U << 1, // Global symbol
108 SF_Weak = 1U << 2, // Weak symbol
109 SF_Absolute = 1U << 3, // Absolute symbol
110 SF_Common = 1U << 4, // Symbol has common linkage
111 SF_Indirect = 1U << 5, // Symbol is an alias to another symbol
112 SF_Exported = 1U << 6, // Symbol is visible to other DSOs
113 SF_FormatSpecific = 1U << 7, // Specific to the object file format
114 // (e.g. section symbols)
115 SF_Thumb = 1U << 8, // Thumb symbol in a 32-bit ARM binary
116 SF_Hidden = 1U << 9, // Symbol has hidden visibility
117 SF_Const = 1U << 10, // Symbol value is constant
118 SF_Executable = 1U << 11, // Symbol points to an executable section
119 // (IR only)
120 };
121
122 BasicSymbolRef() = default;
22
Calling default constructor for 'DataRefImpl'
23
Returning from default constructor for 'DataRefImpl'
123 BasicSymbolRef(DataRefImpl SymbolP, const SymbolicFile *Owner);
124
125 bool operator==(const BasicSymbolRef &Other) const;
126 bool operator<(const BasicSymbolRef &Other) const;
127
128 void moveNext();
129
130 std::error_code printName(raw_ostream &OS) const;
131
132 /// Get symbol flags (bitwise OR of SymbolRef::Flags)
133 uint32_t getFlags() const;
134
135 DataRefImpl getRawDataRefImpl() const;
136 const SymbolicFile *getObject() const;
137};
138
139using basic_symbol_iterator = content_iterator<BasicSymbolRef>;
140
141class SymbolicFile : public Binary {
142public:
143 SymbolicFile(unsigned int Type, MemoryBufferRef Source);
144 ~SymbolicFile() override;
145
146 // virtual interface.
147 virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
148
149 virtual std::error_code printSymbolName(raw_ostream &OS,
150 DataRefImpl Symb) const = 0;
151
152 virtual uint32_t getSymbolFlags(DataRefImpl Symb) const = 0;
153
154 virtual basic_symbol_iterator symbol_begin() const = 0;
155
156 virtual basic_symbol_iterator symbol_end() const = 0;
157
158 // convenience wrappers.
159 using basic_symbol_iterator_range = iterator_range<basic_symbol_iterator>;
160 basic_symbol_iterator_range symbols() const {
161 return basic_symbol_iterator_range(symbol_begin(), symbol_end());
162 }
163
164 // construction aux.
165 static Expected<std::unique_ptr<SymbolicFile>>
166 createSymbolicFile(MemoryBufferRef Object, llvm::file_magic Type,
167 LLVMContext *Context);
168
169 static Expected<std::unique_ptr<SymbolicFile>>
170 createSymbolicFile(MemoryBufferRef Object) {
171 return createSymbolicFile(Object, llvm::file_magic::unknown, nullptr);
172 }
173 static Expected<OwningBinary<SymbolicFile>>
174 createSymbolicFile(StringRef ObjectPath);
175
176 static bool classof(const Binary *v) {
177 return v->isSymbolic();
178 }
179};
180
181inline BasicSymbolRef::BasicSymbolRef(DataRefImpl SymbolP,
182 const SymbolicFile *Owner)
183 : SymbolPimpl(SymbolP), OwningObject(Owner) {}
184
185inline bool BasicSymbolRef::operator==(const BasicSymbolRef &Other) const {
186 return SymbolPimpl == Other.SymbolPimpl;
187}
188
189inline bool BasicSymbolRef::operator<(const BasicSymbolRef &Other) const {
190 return SymbolPimpl < Other.SymbolPimpl;
191}
192
193inline void BasicSymbolRef::moveNext() {
194 return OwningObject->moveSymbolNext(SymbolPimpl);
195}
196
197inline std::error_code BasicSymbolRef::printName(raw_ostream &OS) const {
198 return OwningObject->printSymbolName(OS, SymbolPimpl);
199}
200
201inline uint32_t BasicSymbolRef::getFlags() const {
202 return OwningObject->getSymbolFlags(SymbolPimpl);
203}
204
205inline DataRefImpl BasicSymbolRef::getRawDataRefImpl() const {
206 return SymbolPimpl;
207}
208
209inline const SymbolicFile *BasicSymbolRef::getObject() const {
210 return OwningObject;
211}
212
213} // end namespace object
214} // end namespace llvm
215
216#endif // LLVM_OBJECT_SYMBOLICFILE_H

/usr/lib/gcc/x86_64-linux-gnu/7.2.0/../../../../include/c++/7.2.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); }
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; }
27
Assuming the condition is false
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-6.0~svn318882/include/llvm/Support/Casting.h

1//===- llvm/Support/Casting.h - Allow flexible, checked, casts --*- 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 the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(),
11// and dyn_cast_or_null<X>() templates.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_SUPPORT_CASTING_H
16#define LLVM_SUPPORT_CASTING_H
17
18#include "llvm/Support/Compiler.h"
19#include "llvm/Support/type_traits.h"
20#include <cassert>
21#include <memory>
22#include <type_traits>
23
24namespace llvm {
25
26//===----------------------------------------------------------------------===//
27// isa<x> Support Templates
28//===----------------------------------------------------------------------===//
29
30// Define a template that can be specialized by smart pointers to reflect the
31// fact that they are automatically dereferenced, and are not involved with the
32// template selection process... the default implementation is a noop.
33//
34template<typename From> struct simplify_type {
35 using SimpleType = From; // The real type this represents...
36
37 // An accessor to get the real value...
38 static SimpleType &getSimplifiedValue(From &Val) { return Val; }
39};
40
41template<typename From> struct simplify_type<const From> {
42 using NonConstSimpleType = typename simplify_type<From>::SimpleType;
43 using SimpleType =
44 typename add_const_past_pointer<NonConstSimpleType>::type;
45 using RetType =
46 typename add_lvalue_reference_if_not_pointer<SimpleType>::type;
47
48 static RetType getSimplifiedValue(const From& Val) {
49 return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val));
38
Calling 'simplify_type::getSimplifiedValue'
39
Returning from 'simplify_type::getSimplifiedValue'
50 }
51};
52
53// The core of the implementation of isa<X> is here; To and From should be
54// the names of classes. This template can be specialized to customize the
55// implementation of isa<> without rewriting it from scratch.
56template <typename To, typename From, typename Enabler = void>
57struct isa_impl {
58 static inline bool doit(const From &Val) {
59 return To::classof(&Val);
45
Calling 'ObjectFile::classof'
46
Returning from 'ObjectFile::classof'
60 }
61};
62
63/// \brief Always allow upcasts, and perform no dynamic check for them.
64template <typename To, typename From>
65struct isa_impl<
66 To, From, typename std::enable_if<std::is_base_of<To, From>::value>::type> {
67 static inline bool doit(const From &) { return true; }
68};
69
70template <typename To, typename From> struct isa_impl_cl {
71 static inline bool doit(const From &Val) {
72 return isa_impl<To, From>::doit(Val);
73 }
74};
75
76template <typename To, typename From> struct isa_impl_cl<To, const From> {
77 static inline bool doit(const From &Val) {
78 return isa_impl<To, From>::doit(Val);
79 }
80};
81
82template <typename To, typename From>
83struct isa_impl_cl<To, const std::unique_ptr<From>> {
84 static inline bool doit(const std::unique_ptr<From> &Val) {
85 assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer"
) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\""
, "/build/llvm-toolchain-snapshot-6.0~svn318882/include/llvm/Support/Casting.h"
, 85, __extension__ __PRETTY_FUNCTION__))
;
86 return isa_impl_cl<To, From>::doit(*Val);
87 }
88};
89
90template <typename To, typename From> struct isa_impl_cl<To, From*> {
91 static inline bool doit(const From *Val) {
92 assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer"
) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\""
, "/build/llvm-toolchain-snapshot-6.0~svn318882/include/llvm/Support/Casting.h"
, 92, __extension__ __PRETTY_FUNCTION__))
;
93 return isa_impl<To, From>::doit(*Val);
94 }
95};
96
97template <typename To, typename From> struct isa_impl_cl<To, From*const> {
98 static inline bool doit(const From *Val) {
99 assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer"
) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\""
, "/build/llvm-toolchain-snapshot-6.0~svn318882/include/llvm/Support/Casting.h"
, 99, __extension__ __PRETTY_FUNCTION__))
;
100 return isa_impl<To, From>::doit(*Val);
101 }
102};
103
104template <typename To, typename From> struct isa_impl_cl<To, const From*> {
105 static inline bool doit(const From *Val) {
106 assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer"
) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\""
, "/build/llvm-toolchain-snapshot-6.0~svn318882/include/llvm/Support/Casting.h"
, 106, __extension__ __PRETTY_FUNCTION__))
;
43
Within the expansion of the macro 'assert':
a
Assuming 'Val' is non-null
107 return isa_impl<To, From>::doit(*Val);
44
Calling 'isa_impl::doit'
47
Returning from 'isa_impl::doit'
108 }
109};
110
111template <typename To, typename From> struct isa_impl_cl<To, const From*const> {
112 static inline bool doit(const From *Val) {
113 assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer"
) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\""
, "/build/llvm-toolchain-snapshot-6.0~svn318882/include/llvm/Support/Casting.h"
, 113, __extension__ __PRETTY_FUNCTION__))
;
114 return isa_impl<To, From>::doit(*Val);
115 }
116};
117
118template<typename To, typename From, typename SimpleFrom>
119struct isa_impl_wrap {
120 // When From != SimplifiedType, we can simplify the type some more by using
121 // the simplify_type template.
122 static bool doit(const From &Val) {
123 return isa_impl_wrap<To, SimpleFrom,
41
Calling 'isa_impl_wrap::doit'
49
Returning from 'isa_impl_wrap::doit'
124 typename simplify_type<SimpleFrom>::SimpleType>::doit(
125 simplify_type<const From>::getSimplifiedValue(Val));
37
Calling 'simplify_type::getSimplifiedValue'
40
Returning from 'simplify_type::getSimplifiedValue'
126 }
127};
128
129template<typename To, typename FromTy>
130struct isa_impl_wrap<To, FromTy, FromTy> {
131 // When From == SimpleType, we are as simple as we are going to get.
132 static bool doit(const FromTy &Val) {
133 return isa_impl_cl<To,FromTy>::doit(Val);
42
Calling 'isa_impl_cl::doit'
48
Returning from 'isa_impl_cl::doit'
134 }
135};
136
137// isa<X> - Return true if the parameter to the template is an instance of the
138// template type argument. Used like this:
139//
140// if (isa<Type>(myVal)) { ... }
141//
142template <class X, class Y> LLVM_NODISCARD[[clang::warn_unused_result]] inline bool isa(const Y &Val) {
143 return isa_impl_wrap<X, const Y,
36
Calling 'isa_impl_wrap::doit'
50
Returning from 'isa_impl_wrap::doit'
144 typename simplify_type<const Y>::SimpleType>::doit(Val);
145}
146
147//===----------------------------------------------------------------------===//
148// cast<x> Support Templates
149//===----------------------------------------------------------------------===//
150
151template<class To, class From> struct cast_retty;
152
153// Calculate what type the 'cast' function should return, based on a requested
154// type of To and a source type of From.
155template<class To, class From> struct cast_retty_impl {
156 using ret_type = To &; // Normal case, return Ty&
157};
158template<class To, class From> struct cast_retty_impl<To, const From> {
159 using ret_type = const To &; // Normal case, return Ty&
160};
161
162template<class To, class From> struct cast_retty_impl<To, From*> {
163 using ret_type = To *; // Pointer arg case, return Ty*
164};
165
166template<class To, class From> struct cast_retty_impl<To, const From*> {
167 using ret_type = const To *; // Constant pointer arg case, return const Ty*
168};
169
170template<class To, class From> struct cast_retty_impl<To, const From*const> {
171 using ret_type = const To *; // Constant pointer arg case, return const Ty*
172};
173
174template <class To, class From>
175struct cast_retty_impl<To, std::unique_ptr<From>> {
176private:
177 using PointerType = typename cast_retty_impl<To, From *>::ret_type;
178 using ResultType = typename std::remove_pointer<PointerType>::type;
179
180public:
181 using ret_type = std::unique_ptr<ResultType>;
182};
183
184template<class To, class From, class SimpleFrom>
185struct cast_retty_wrap {
186 // When the simplified type and the from type are not the same, use the type
187 // simplifier to reduce the type, then reuse cast_retty_impl to get the
188 // resultant type.
189 using ret_type = typename cast_retty<To, SimpleFrom>::ret_type;
190};
191
192template<class To, class FromTy>
193struct cast_retty_wrap<To, FromTy, FromTy> {
194 // When the simplified type is equal to the from type, use it directly.
195 using ret_type = typename cast_retty_impl<To,FromTy>::ret_type;
196};
197
198template<class To, class From>
199struct cast_retty {
200 using ret_type = typename cast_retty_wrap<
201 To, From, typename simplify_type<From>::SimpleType>::ret_type;
202};
203
204// Ensure the non-simple values are converted using the simplify_type template
205// that may be specialized by smart pointers...
206//
207template<class To, class From, class SimpleFrom> struct cast_convert_val {
208 // This is not a simple type, use the template to simplify it...
209 static typename cast_retty<To, From>::ret_type doit(From &Val) {
210 return cast_convert_val<To, SimpleFrom,
211 typename simplify_type<SimpleFrom>::SimpleType>::doit(
212 simplify_type<From>::getSimplifiedValue(Val));
213 }
214};
215
216template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
217 // This _is_ a simple type, just cast it.
218 static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
219 typename cast_retty<To, FromTy>::ret_type Res2
220 = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val);
221 return Res2;
222 }
223};
224
225template <class X> struct is_simple_type {
226 static const bool value =
227 std::is_same<X, typename simplify_type<X>::SimpleType>::value;
228};
229
230// cast<X> - Return the argument parameter cast to the specified type. This
231// casting operator asserts that the type is correct, so it does not return null
232// on failure. It does not allow a null argument (use cast_or_null for that).
233// It is typically used like this:
234//
235// cast<Instruction>(myVal)->getParent()
236//
237template <class X, class Y>
238inline typename std::enable_if<!is_simple_type<Y>::value,
239 typename cast_retty<X, const Y>::ret_type>::type
240cast(const Y &Val) {
241 assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast<Ty>() argument of incompatible type!"
) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318882/include/llvm/Support/Casting.h"
, 241, __extension__ __PRETTY_FUNCTION__))
;
242 return cast_convert_val<
243 X, const Y, typename simplify_type<const Y>::SimpleType>::doit(Val);
244}
245
246template <class X, class Y>
247inline typename cast_retty<X, Y>::ret_type cast(Y &Val) {
248 assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast<Ty>() argument of incompatible type!"
) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318882/include/llvm/Support/Casting.h"
, 248, __extension__ __PRETTY_FUNCTION__))
;
249 return cast_convert_val<X, Y,
250 typename simplify_type<Y>::SimpleType>::doit(Val);
251}
252
253template <class X, class Y>
254inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) {
255 assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast<Ty>() argument of incompatible type!"
) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318882/include/llvm/Support/Casting.h"
, 255, __extension__ __PRETTY_FUNCTION__))
;
35
Within the expansion of the macro 'assert':
a
Calling 'isa'
b
Returning from 'isa'
c
Assuming the condition is true
256 return cast_convert_val<X, Y*,
51
Calling 'cast_convert_val::doit'
52
Returning from 'cast_convert_val::doit'
257 typename simplify_type<Y*>::SimpleType>::doit(Val);
258}
259
260template <class X, class Y>
261inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type
262cast(std::unique_ptr<Y> &&Val) {
263 assert(isa<X>(Val.get()) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val.get()) &&
"cast<Ty>() argument of incompatible type!") ? void (0
) : __assert_fail ("isa<X>(Val.get()) && \"cast<Ty>() argument of incompatible type!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318882/include/llvm/Support/Casting.h"
, 263, __extension__ __PRETTY_FUNCTION__))
;
264 using ret_type = typename cast_retty<X, std::unique_ptr<Y>>::ret_type;
265 return ret_type(
266 cast_convert_val<X, Y *, typename simplify_type<Y *>::SimpleType>::doit(
267 Val.release()));
268}
269
270// cast_or_null<X> - Functionally identical to cast, except that a null value is
271// accepted.
272//
273template <class X, class Y>
274LLVM_NODISCARD[[clang::warn_unused_result]] inline
275 typename std::enable_if<!is_simple_type<Y>::value,
276 typename cast_retty<X, const Y>::ret_type>::type
277 cast_or_null(const Y &Val) {
278 if (!Val)
279 return nullptr;
280 assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!"
) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318882/include/llvm/Support/Casting.h"
, 280, __extension__ __PRETTY_FUNCTION__))
;
281 return cast<X>(Val);
282}
283
284template <class X, class Y>
285LLVM_NODISCARD[[clang::warn_unused_result]] inline
286 typename std::enable_if<!is_simple_type<Y>::value,
287 typename cast_retty<X, Y>::ret_type>::type
288 cast_or_null(Y &Val) {
289 if (!Val)
290 return nullptr;
291 assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!"
) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318882/include/llvm/Support/Casting.h"
, 291, __extension__ __PRETTY_FUNCTION__))
;
292 return cast<X>(Val);
293}
294
295template <class X, class Y>
296LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type
297cast_or_null(Y *Val) {
298 if (!Val) return nullptr;
299 assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!"
) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318882/include/llvm/Support/Casting.h"
, 299, __extension__ __PRETTY_FUNCTION__))
;
300 return cast<X>(Val);
301}
302
303template <class X, class Y>
304inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type
305cast_or_null(std::unique_ptr<Y> &&Val) {
306 if (!Val)
307 return nullptr;
308 return cast<X>(std::move(Val));
309}
310
311// dyn_cast<X> - Return the argument parameter cast to the specified type. This
312// casting operator returns null if the argument is of the wrong type, so it can
313// be used to test for a type as well as cast if successful. This should be
314// used in the context of an if statement like this:
315//
316// if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
317//
318
319template <class X, class Y>
320LLVM_NODISCARD[[clang::warn_unused_result]] inline
321 typename std::enable_if<!is_simple_type<Y>::value,
322 typename cast_retty<X, const Y>::ret_type>::type
323 dyn_cast(const Y &Val) {
324 return isa<X>(Val) ? cast<X>(Val) : nullptr;
325}
326
327template <class X, class Y>
328LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) {
329 return isa<X>(Val) ? cast<X>(Val) : nullptr;
330}
331
332template <class X, class Y>
333LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) {
334 return isa<X>(Val) ? cast<X>(Val) : nullptr;
335}
336
337// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
338// value is accepted.
339//
340template <class X, class Y>
341LLVM_NODISCARD[[clang::warn_unused_result]] inline
342 typename std::enable_if<!is_simple_type<Y>::value,
343 typename cast_retty<X, const Y>::ret_type>::type
344 dyn_cast_or_null(const Y &Val) {
345 return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr;
346}
347
348template <class X, class Y>
349LLVM_NODISCARD[[clang::warn_unused_result]] inline
350 typename std::enable_if<!is_simple_type<Y>::value,
351 typename cast_retty<X, Y>::ret_type>::type
352 dyn_cast_or_null(Y &Val) {
353 return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr;
354}
355
356template <class X, class Y>
357LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type
358dyn_cast_or_null(Y *Val) {
359 return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr;
360}
361
362// unique_dyn_cast<X> - Given a unique_ptr<Y>, try to return a unique_ptr<X>,
363// taking ownership of the input pointer iff isa<X>(Val) is true. If the
364// cast is successful, From refers to nullptr on exit and the casted value
365// is returned. If the cast is unsuccessful, the function returns nullptr
366// and From is unchanged.
367template <class X, class Y>
368LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast(std::unique_ptr<Y> &Val)
369 -> decltype(cast<X>(Val)) {
370 if (!isa<X>(Val))
371 return nullptr;
372 return cast<X>(std::move(Val));
373}
374
375template <class X, class Y>
376LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast(std::unique_ptr<Y> &&Val)
377 -> decltype(cast<X>(Val)) {
378 return unique_dyn_cast<X, Y>(Val);
379}
380
381// dyn_cast_or_null<X> - Functionally identical to unique_dyn_cast, except that
382// a null value is accepted.
383template <class X, class Y>
384LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &Val)
385 -> decltype(cast<X>(Val)) {
386 if (!Val)
387 return nullptr;
388 return unique_dyn_cast<X, Y>(Val);
389}
390
391template <class X, class Y>
392LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &&Val)
393 -> decltype(cast<X>(Val)) {
394 return unique_dyn_cast_or_null<X, Y>(Val);
395}
396
397} // end namespace llvm
398
399#endif // LLVM_SUPPORT_CASTING_H

/build/llvm-toolchain-snapshot-6.0~svn318882/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);
188 *this = std::move(Other);
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());
195 setChecked(false);
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();
208 setPtr(Other.getPtr());
209
210 // This Error is unchecked, even if the source error was checked.
211 setChecked(false);
212
213 // Null out Other's payload and set its checked bit.
214 Other.setPtr(nullptr);
215 Other.setChecked(true);
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();
224 delete 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);
232 return getPtr() != nullptr;
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))
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));
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-6.0~svn318882/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-6.0~svn318882/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-6.0~svn318882/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)); }
59
Calling 'move'
60
Returning from 'move'
61
Calling 'Expected::moveConstruct'
72
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();
87
Calling 'Expected::assertIsChecked'
90
Returning from 'Expected::assertIsChecked'
502 if (!HasError)
91
Assuming the condition is true
92
Taking true branch
503 getStorage()->~storage_type();
93
Calling 'Expected::getStorage'
95
Returning from 'Expected::getStorage'
504 else
505 getErrorStorage()->~error_type();
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;
75
Assuming the condition is false
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();
79
'?' condition is true
80
Calling 'Expected::getErrorStorage'
82
Returning from 'Expected::getErrorStorage'
83
Calling 'move'
84
Returning from 'move'
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)
62
Assuming the condition is false
63
Taking false branch
587 new (getStorage()) storage_type(std::move(*Other.getStorage()));
588 else
589 new (getErrorStorage()) error_type(std::move(*Other.getErrorStorage()));
64
Calling 'Expected::getErrorStorage'
66
Returning from 'Expected::getErrorStorage'
67
Calling 'Expected::getErrorStorage'
69
Returning from 'Expected::getErrorStorage'
70
Calling 'move'
71
Returning from 'move'
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-6.0~svn318882/include/llvm/Support/Error.h"
, 611, __extension__ __PRETTY_FUNCTION__))
;
94
Within the expansion of the macro 'assert':
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-6.0~svn318882/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-6.0~svn318882/include/llvm/Support/Error.h"
, 621, __extension__ __PRETTY_FUNCTION__))
;
65
Within the expansion of the macro 'assert':
68
Within the expansion of the macro 'assert':
81
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-6.0~svn318882/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))
88
Within the expansion of the macro 'LLVM_UNLIKELY':
a
Assuming the condition is false
89
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-6.0~svn318882/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-6.0~svn318882/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-6.0~svn318882/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-6.0~svn318882/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-6.0~svn318882/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-6.0~svn318882/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-6.0~svn318882/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 it requires that all
886/// errors be handled by the given handlers. If any unhandled error remains
887/// after the handlers have run, report_fatal_error() will be 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 report_fatal_error 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 Errors used as out-parameters.
967///
968/// This helper is for use with the Error-as-out-parameter idiom, where an error
969/// is passed to a function or method by reference, rather than being returned.
970/// In such cases it is helpful to set the checked bit on entry to the function
971/// so that the error can be written to (unchecked Errors abort on assignment)
972/// and clear the checked bit on exit so that clients cannot accidentally forget
973/// to check the result. This helper performs these actions automatically using
974/// RAII:
975///
976/// @code{.cpp}
977/// Result foo(Error &Err) {
978/// ErrorAsOutParameter ErrAsOutParam(&Err); // 'Checked' flag set
979/// // <body of foo>
980/// // <- 'Checked' flag auto-cleared when ErrAsOutParam is destructed.
981/// }
982/// @endcode
983///
984/// ErrorAsOutParameter takes an Error* rather than Error& so that it can be
985/// used with optional Errors (Error pointers that are allowed to be null). If
986/// ErrorAsOutParameter took an Error reference, an instance would have to be
987/// created inside every condition that verified that Error was non-null. By
988/// taking an Error pointer we can just create one instance at the top of the
989/// function.
990class ErrorAsOutParameter {
991public:
992 ErrorAsOutParameter(Error *Err) : Err(Err) {
993 // Raise the checked bit if Err is success.
994 if (Err)
995 (void)!!*Err;
996 }
997
998 ~ErrorAsOutParameter() {
999 // Clear the checked bit.
1000 if (Err && !*Err)
1001 *Err = Error::success();
1002 }
1003
1004private:
1005 Error *Err;
1006};
1007
1008/// Helper for Expected<T>s used as out-parameters.
1009///
1010/// See ErrorAsOutParameter.
1011template <typename T>
1012class ExpectedAsOutParameter {
1013public:
1014 ExpectedAsOutParameter(Expected<T> *ValOrErr)
1015 : ValOrErr(ValOrErr) {
1016 if (ValOrErr)
1017 (void)!!*ValOrErr;
1018 }
1019
1020 ~ExpectedAsOutParameter() {
1021 if (ValOrErr)
1022 ValOrErr->setUnchecked();
1023 }
1024
1025private:
1026 Expected<T> *ValOrErr;
1027};
1028
1029/// This class wraps a std::error_code in a Error.
1030///
1031/// This is useful if you're writing an interface that returns a Error
1032/// (or Expected) and you want to call code that still returns
1033/// std::error_codes.
1034class ECError : public ErrorInfo<ECError> {
1035 friend Error errorCodeToError(std::error_code);
1036
1037public:
1038 void setErrorCode(std::error_code EC) { this->EC = EC; }
1039 std::error_code convertToErrorCode() const override { return EC; }
1040 void log(raw_ostream &OS) const override { OS << EC.message(); }
1041
1042 // Used by ErrorInfo::classID.
1043 static char ID;
1044
1045protected:
1046 ECError() = default;
1047 ECError(std::error_code EC) : EC(EC) {}
1048
1049 std::error_code EC;
1050};
1051
1052/// The value returned by this function can be returned from convertToErrorCode
1053/// for Error values where no sensible translation to std::error_code exists.
1054/// It should only be used in this situation, and should never be used where a
1055/// sensible conversion to std::error_code is available, as attempts to convert
1056/// to/from this error will result in a fatal error. (i.e. it is a programmatic
1057///error to try to convert such a value).
1058std::error_code inconvertibleErrorCode();
1059
1060/// Helper for converting an std::error_code to a Error.
1061Error errorCodeToError(std::error_code EC);
1062
1063/// Helper for converting an ECError to a std::error_code.
1064///
1065/// This method requires that Err be Error() or an ECError, otherwise it
1066/// will trigger a call to abort().
1067std::error_code errorToErrorCode(Error Err);
1068
1069/// Convert an ErrorOr<T> to an Expected<T>.
1070template <typename T> Expected<T> errorOrToExpected(ErrorOr<T> &&EO) {
1071 if (auto EC = EO.getError())
1072 return errorCodeToError(EC);
1073 return std::move(*EO);
1074}
1075
1076/// Convert an Expected<T> to an ErrorOr<T>.
1077template <typename T> ErrorOr<T> expectedToErrorOr(Expected<T> &&E) {
1078 if (auto Err = E.takeError())
1079 return errorToErrorCode(std::move(Err));
1080 return std::move(*E);
1081}
1082
1083/// This class wraps a string in an Error.
1084///
1085/// StringError is useful in cases where the client is not expected to be able
1086/// to consume the specific error message programmatically (for example, if the
1087/// error message is to be presented to the user).
1088class StringError : public ErrorInfo<StringError> {
1089public:
1090 static char ID;
1091
1092 StringError(const Twine &S, std::error_code EC);
1093
1094 void log(raw_ostream &OS) const override;
1095 std::error_code convertToErrorCode() const override;
1096
1097 const std::string &getMessage() const { return Msg; }
1098
1099private:
1100 std::string Msg;
1101 std::error_code EC;
1102};
1103
1104/// Helper for check-and-exit error handling.
1105///
1106/// For tool use only. NOT FOR USE IN LIBRARY CODE.
1107///
1108class ExitOnError {
1109public:
1110 /// Create an error on exit helper.
1111 ExitOnError(std::string Banner = "", int DefaultErrorExitCode = 1)
1112 : Banner(std::move(Banner)),
1113 GetExitCode([=](const Error &) { return DefaultErrorExitCode; }) {}
1114
1115 /// Set the banner string for any errors caught by operator().
1116 void setBanner(std::string Banner) { this->Banner = std::move(Banner); }
1117
1118 /// Set the exit-code mapper function.
1119 void setExitCodeMapper(std::function<int(const Error &)> GetExitCode) {
1120 this->GetExitCode = std::move(GetExitCode);
1121 }
1122
1123 /// Check Err. If it's in a failure state log the error(s) and exit.
1124 void operator()(Error Err) const { checkError(std::move(Err)); }
1125
1126 /// Check E. If it's in a success state then return the contained value. If
1127 /// it's in a failure state log the error(s) and exit.
1128 template <typename T> T operator()(Expected<T> &&E) const {
1129 checkError(E.takeError());
1130 return std::move(*E);
1131 }
1132
1133 /// Check E. If it's in a success state then return the contained reference. If
1134 /// it's in a failure state log the error(s) and exit.
1135 template <typename T> T& operator()(Expected<T&> &&E) const {
1136 checkError(E.takeError());
1137 return *E;
1138 }
1139
1140private:
1141 void checkError(Error Err) const {
1142 if (Err) {
1143 int ExitCode = GetExitCode(Err);
1144 logAllUnhandledErrors(std::move(Err), errs(), Banner);
1145 exit(ExitCode);
1146 }
1147 }
1148
1149 std::string Banner;
1150 std::function<int(const Error &)> GetExitCode;
1151};
1152
1153} // end namespace llvm
1154
1155#endif // LLVM_SUPPORT_ERROR_H