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