Bug Summary

File:llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
Warning:line 182, column 11
Called function pointer is null (null dereference)

Annotated Source Code

Press '?' to see keyboard shortcuts

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

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp

1//===-------- OrcMCJITReplacement.cpp - Orc-based MCJIT replacement -------===//
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#include "OrcMCJITReplacement.h"
10#include "llvm/ExecutionEngine/GenericValue.h"
11
12namespace {
13
14static struct RegisterJIT {
15 RegisterJIT() { llvm::orc::OrcMCJITReplacement::Register(); }
16} JITRegistrator;
17
18}
19
20extern "C" void LLVMLinkInOrcMCJITReplacement() {}
21
22namespace llvm {
23namespace orc {
24
25GenericValue
26OrcMCJITReplacement::runFunction(Function *F,
27 ArrayRef<GenericValue> ArgValues) {
28 assert(F && "Function *F was null at entry to run()")((F && "Function *F was null at entry to run()") ? static_cast
<void> (0) : __assert_fail ("F && \"Function *F was null at entry to run()\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 28, __PRETTY_FUNCTION__))
;
29
30 void *FPtr = getPointerToFunction(F);
31 assert(FPtr && "Pointer to fn's code was null after getPointerToFunction")((FPtr && "Pointer to fn's code was null after getPointerToFunction"
) ? static_cast<void> (0) : __assert_fail ("FPtr && \"Pointer to fn's code was null after getPointerToFunction\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 31, __PRETTY_FUNCTION__))
;
32 FunctionType *FTy = F->getFunctionType();
33 Type *RetTy = FTy->getReturnType();
34
35 assert((FTy->getNumParams() == ArgValues.size() ||(((FTy->getNumParams() == ArgValues.size() || (FTy->isVarArg
() && FTy->getNumParams() <= ArgValues.size()))
&& "Wrong number of arguments passed into function!"
) ? static_cast<void> (0) : __assert_fail ("(FTy->getNumParams() == ArgValues.size() || (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) && \"Wrong number of arguments passed into function!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 37, __PRETTY_FUNCTION__))
36 (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) &&(((FTy->getNumParams() == ArgValues.size() || (FTy->isVarArg
() && FTy->getNumParams() <= ArgValues.size()))
&& "Wrong number of arguments passed into function!"
) ? static_cast<void> (0) : __assert_fail ("(FTy->getNumParams() == ArgValues.size() || (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) && \"Wrong number of arguments passed into function!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 37, __PRETTY_FUNCTION__))
37 "Wrong number of arguments passed into function!")(((FTy->getNumParams() == ArgValues.size() || (FTy->isVarArg
() && FTy->getNumParams() <= ArgValues.size()))
&& "Wrong number of arguments passed into function!"
) ? static_cast<void> (0) : __assert_fail ("(FTy->getNumParams() == ArgValues.size() || (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) && \"Wrong number of arguments passed into function!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 37, __PRETTY_FUNCTION__))
;
38 assert(FTy->getNumParams() == ArgValues.size() &&((FTy->getNumParams() == ArgValues.size() && "This doesn't support passing arguments through varargs (yet)!"
) ? static_cast<void> (0) : __assert_fail ("FTy->getNumParams() == ArgValues.size() && \"This doesn't support passing arguments through varargs (yet)!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 39, __PRETTY_FUNCTION__))
39 "This doesn't support passing arguments through varargs (yet)!")((FTy->getNumParams() == ArgValues.size() && "This doesn't support passing arguments through varargs (yet)!"
) ? static_cast<void> (0) : __assert_fail ("FTy->getNumParams() == ArgValues.size() && \"This doesn't support passing arguments through varargs (yet)!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 39, __PRETTY_FUNCTION__))
;
40
41 // Handle some common cases first. These cases correspond to common `main'
42 // prototypes.
43 if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
44 switch (ArgValues.size()) {
45 case 3:
46 if (FTy->getParamType(0)->isIntegerTy(32) &&
47 FTy->getParamType(1)->isPointerTy() &&
48 FTy->getParamType(2)->isPointerTy()) {
49 int (*PF)(int, char **, const char **) =
50 (int (*)(int, char **, const char **))(intptr_t)FPtr;
51
52 // Call the function.
53 GenericValue rv;
54 rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
55 (char **)GVTOP(ArgValues[1]),
56 (const char **)GVTOP(ArgValues[2])));
57 return rv;
58 }
59 break;
60 case 2:
61 if (FTy->getParamType(0)->isIntegerTy(32) &&
62 FTy->getParamType(1)->isPointerTy()) {
63 int (*PF)(int, char **) = (int (*)(int, char **))(intptr_t)FPtr;
64
65 // Call the function.
66 GenericValue rv;
67 rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
68 (char **)GVTOP(ArgValues[1])));
69 return rv;
70 }
71 break;
72 case 1:
73 if (FTy->getNumParams() == 1 && FTy->getParamType(0)->isIntegerTy(32)) {
74 GenericValue rv;
75 int (*PF)(int) = (int (*)(int))(intptr_t)FPtr;
76 rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
77 return rv;
78 }
79 break;
80 }
81 }
82
83 // Handle cases where no arguments are passed first.
84 if (ArgValues.empty()) {
85 GenericValue rv;
86 switch (RetTy->getTypeID()) {
87 default:
88 llvm_unreachable("Unknown return type for function call!")::llvm::llvm_unreachable_internal("Unknown return type for function call!"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 88)
;
89 case Type::IntegerTyID: {
90 unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
91 if (BitWidth == 1)
92 rv.IntVal = APInt(BitWidth, ((bool (*)())(intptr_t)FPtr)());
93 else if (BitWidth <= 8)
94 rv.IntVal = APInt(BitWidth, ((char (*)())(intptr_t)FPtr)());
95 else if (BitWidth <= 16)
96 rv.IntVal = APInt(BitWidth, ((short (*)())(intptr_t)FPtr)());
97 else if (BitWidth <= 32)
98 rv.IntVal = APInt(BitWidth, ((int (*)())(intptr_t)FPtr)());
99 else if (BitWidth <= 64)
100 rv.IntVal = APInt(BitWidth, ((int64_t (*)())(intptr_t)FPtr)());
101 else
102 llvm_unreachable("Integer types > 64 bits not supported")::llvm::llvm_unreachable_internal("Integer types > 64 bits not supported"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 102)
;
103 return rv;
104 }
105 case Type::VoidTyID:
106 rv.IntVal = APInt(32, ((int (*)())(intptr_t)FPtr)());
107 return rv;
108 case Type::FloatTyID:
109 rv.FloatVal = ((float (*)())(intptr_t)FPtr)();
110 return rv;
111 case Type::DoubleTyID:
112 rv.DoubleVal = ((double (*)())(intptr_t)FPtr)();
113 return rv;
114 case Type::X86_FP80TyID:
115 case Type::FP128TyID:
116 case Type::PPC_FP128TyID:
117 llvm_unreachable("long double not supported yet")::llvm::llvm_unreachable_internal("long double not supported yet"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 117)
;
118 case Type::PointerTyID:
119 return PTOGV(((void *(*)())(intptr_t)FPtr)());
120 }
121 }
122
123 llvm_unreachable("Full-featured argument passing not supported yet!")::llvm::llvm_unreachable_internal("Full-featured argument passing not supported yet!"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp"
, 123)
;
124}
125
126void OrcMCJITReplacement::runStaticConstructorsDestructors(bool isDtors) {
127 auto &CtorDtorsMap = isDtors ? UnexecutedDestructors : UnexecutedConstructors;
1
Assuming 'isDtors' is false
2
'?' condition is false
128
129 for (auto &KV : CtorDtorsMap)
130 cantFail(LegacyCtorDtorRunner<LazyEmitLayerT>(
3
Calling 'LegacyCtorDtorRunner::runViaLayer'
131 AcknowledgeORCv1Deprecation, std::move(KV.second), KV.first)
132 .runViaLayer(LazyEmitLayer));
133
134 CtorDtorsMap.clear();
135}
136
137} // End namespace orc.
138} // End namespace llvm.

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h

1//===- ExecutionUtils.h - Utilities for executing code in Orc ---*- 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// Contains utilities for executing code in Orc.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H
14#define LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H
15
16#include "llvm/ADT/StringMap.h"
17#include "llvm/ADT/iterator_range.h"
18#include "llvm/ExecutionEngine/JITSymbol.h"
19#include "llvm/ExecutionEngine/Orc/Core.h"
20#include "llvm/ExecutionEngine/Orc/Mangling.h"
21#include "llvm/ExecutionEngine/Orc/OrcError.h"
22#include "llvm/ExecutionEngine/RuntimeDyld.h"
23#include "llvm/Object/Archive.h"
24#include "llvm/Support/DynamicLibrary.h"
25#include <algorithm>
26#include <cstdint>
27#include <string>
28#include <utility>
29#include <vector>
30
31namespace llvm {
32
33class ConstantArray;
34class GlobalVariable;
35class Function;
36class Module;
37class TargetMachine;
38class Value;
39
40namespace orc {
41
42class ObjectLayer;
43
44/// Run a main function, returning the result.
45///
46/// If the optional ProgramName argument is given then it will be inserted
47/// before the strings in Args as the first argument to the called function.
48///
49/// It is legal to have an empty argument list and no program name, however
50/// many main functions will expect a name argument at least, and will fail
51/// if none is provided.
52int runAsMain(int (*Main)(int, char *[]), ArrayRef<std::string> Args,
53 Optional<StringRef> ProgramName = None);
54
55/// This iterator provides a convenient way to iterate over the elements
56/// of an llvm.global_ctors/llvm.global_dtors instance.
57///
58/// The easiest way to get hold of instances of this class is to use the
59/// getConstructors/getDestructors functions.
60class CtorDtorIterator {
61public:
62 /// Accessor for an element of the global_ctors/global_dtors array.
63 ///
64 /// This class provides a read-only view of the element with any casts on
65 /// the function stripped away.
66 struct Element {
67 Element(unsigned Priority, Function *Func, Value *Data)
68 : Priority(Priority), Func(Func), Data(Data) {}
69
70 unsigned Priority;
71 Function *Func;
72 Value *Data;
73 };
74
75 /// Construct an iterator instance. If End is true then this iterator
76 /// acts as the end of the range, otherwise it is the beginning.
77 CtorDtorIterator(const GlobalVariable *GV, bool End);
78
79 /// Test iterators for equality.
80 bool operator==(const CtorDtorIterator &Other) const;
81
82 /// Test iterators for inequality.
83 bool operator!=(const CtorDtorIterator &Other) const;
84
85 /// Pre-increment iterator.
86 CtorDtorIterator& operator++();
87
88 /// Post-increment iterator.
89 CtorDtorIterator operator++(int);
90
91 /// Dereference iterator. The resulting value provides a read-only view
92 /// of this element of the global_ctors/global_dtors list.
93 Element operator*() const;
94
95private:
96 const ConstantArray *InitList;
97 unsigned I;
98};
99
100/// Create an iterator range over the entries of the llvm.global_ctors
101/// array.
102iterator_range<CtorDtorIterator> getConstructors(const Module &M);
103
104/// Create an iterator range over the entries of the llvm.global_ctors
105/// array.
106iterator_range<CtorDtorIterator> getDestructors(const Module &M);
107
108/// This iterator provides a convenient way to iterate over GlobalValues that
109/// have initialization effects.
110class StaticInitGVIterator {
111public:
112 StaticInitGVIterator() = default;
113
114 StaticInitGVIterator(Module &M)
115 : I(M.global_values().begin()), E(M.global_values().end()),
116 ObjFmt(Triple(M.getTargetTriple()).getObjectFormat()) {
117 if (I != E) {
118 if (!isStaticInitGlobal(*I))
119 moveToNextStaticInitGlobal();
120 } else
121 I = E = Module::global_value_iterator();
122 }
123
124 bool operator==(const StaticInitGVIterator &O) const { return I == O.I; }
125 bool operator!=(const StaticInitGVIterator &O) const { return I != O.I; }
126
127 StaticInitGVIterator &operator++() {
128 assert(I != E && "Increment past end of range")((I != E && "Increment past end of range") ? static_cast
<void> (0) : __assert_fail ("I != E && \"Increment past end of range\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h"
, 128, __PRETTY_FUNCTION__))
;
129 moveToNextStaticInitGlobal();
130 return *this;
131 }
132
133 GlobalValue &operator*() { return *I; }
134
135private:
136 bool isStaticInitGlobal(GlobalValue &GV);
137 void moveToNextStaticInitGlobal() {
138 ++I;
139 while (I != E && !isStaticInitGlobal(*I))
140 ++I;
141 if (I == E)
142 I = E = Module::global_value_iterator();
143 }
144
145 Module::global_value_iterator I, E;
146 Triple::ObjectFormatType ObjFmt;
147};
148
149/// Create an iterator range over the GlobalValues that contribute to static
150/// initialization.
151inline iterator_range<StaticInitGVIterator> getStaticInitGVs(Module &M) {
152 return make_range(StaticInitGVIterator(M), StaticInitGVIterator());
153}
154
155/// Convenience class for recording constructor/destructor names for
156/// later execution.
157template <typename JITLayerT>
158class LegacyCtorDtorRunner {
159public:
160 /// Construct a CtorDtorRunner for the given range using the given
161 /// name mangling function.
162 LLVM_ATTRIBUTE_DEPRECATED(LegacyCtorDtorRunner(std::vector<std::string> CtorDtorNames
, VModuleKey K) __attribute__((deprecated("ORCv1 utilities (utilities with the 'Legacy' prefix) are deprecated. "
"Please use the ORCv2 CtorDtorRunner utility instead")))
163 LegacyCtorDtorRunner(std::vector<std::string> CtorDtorNames,LegacyCtorDtorRunner(std::vector<std::string> CtorDtorNames
, VModuleKey K) __attribute__((deprecated("ORCv1 utilities (utilities with the 'Legacy' prefix) are deprecated. "
"Please use the ORCv2 CtorDtorRunner utility instead")))
164 VModuleKey K),LegacyCtorDtorRunner(std::vector<std::string> CtorDtorNames
, VModuleKey K) __attribute__((deprecated("ORCv1 utilities (utilities with the 'Legacy' prefix) are deprecated. "
"Please use the ORCv2 CtorDtorRunner utility instead")))
165 "ORCv1 utilities (utilities with the 'Legacy' prefix) are deprecated. "LegacyCtorDtorRunner(std::vector<std::string> CtorDtorNames
, VModuleKey K) __attribute__((deprecated("ORCv1 utilities (utilities with the 'Legacy' prefix) are deprecated. "
"Please use the ORCv2 CtorDtorRunner utility instead")))
166 "Please use the ORCv2 CtorDtorRunner utility instead")LegacyCtorDtorRunner(std::vector<std::string> CtorDtorNames
, VModuleKey K) __attribute__((deprecated("ORCv1 utilities (utilities with the 'Legacy' prefix) are deprecated. "
"Please use the ORCv2 CtorDtorRunner utility instead")))
;
167
168 LegacyCtorDtorRunner(ORCv1DeprecationAcknowledgement,
169 std::vector<std::string> CtorDtorNames, VModuleKey K)
170 : CtorDtorNames(std::move(CtorDtorNames)), K(K) {}
171
172 /// Run the recorded constructors/destructors through the given JIT
173 /// layer.
174 Error runViaLayer(JITLayerT &JITLayer) const {
175 using CtorDtorTy = void (*)();
176
177 for (const auto &CtorDtorName : CtorDtorNames) {
178 if (auto CtorDtorSym = JITLayer.findSymbolIn(K, CtorDtorName, false)) {
4
Calling 'JITSymbol::operator bool'
7
Returning from 'JITSymbol::operator bool'
8
Taking true branch
179 if (auto AddrOrErr = CtorDtorSym.getAddress()) {
9
Calling 'JITSymbol::getAddress'
17
Returning from 'JITSymbol::getAddress'
18
Calling 'Expected::operator bool'
20
Returning from 'Expected::operator bool'
21
Taking true branch
180 CtorDtorTy CtorDtor =
25
'CtorDtor' initialized to a null pointer value
181 reinterpret_cast<CtorDtorTy>(static_cast<uintptr_t>(*AddrOrErr));
22
Calling 'Expected::operator*'
24
Returning from 'Expected::operator*'
182 CtorDtor();
26
Called function pointer is null (null dereference)
183 } else
184 return AddrOrErr.takeError();
185 } else {
186 if (auto Err = CtorDtorSym.takeError())
187 return Err;
188 else
189 return make_error<JITSymbolNotFound>(CtorDtorName);
190 }
191 }
192 return Error::success();
193 }
194
195private:
196 std::vector<std::string> CtorDtorNames;
197 orc::VModuleKey K;
198};
199
200template <typename JITLayerT>
201LegacyCtorDtorRunner<JITLayerT>::LegacyCtorDtorRunner(
202 std::vector<std::string> CtorDtorNames, VModuleKey K)
203 : CtorDtorNames(std::move(CtorDtorNames)), K(K) {}
204
205class CtorDtorRunner {
206public:
207 CtorDtorRunner(JITDylib &JD) : JD(JD) {}
208 void add(iterator_range<CtorDtorIterator> CtorDtors);
209 Error run();
210
211private:
212 using CtorDtorList = std::vector<SymbolStringPtr>;
213 using CtorDtorPriorityMap = std::map<unsigned, CtorDtorList>;
214
215 JITDylib &JD;
216 CtorDtorPriorityMap CtorDtorsByPriority;
217};
218
219/// Support class for static dtor execution. For hosted (in-process) JITs
220/// only!
221///
222/// If a __cxa_atexit function isn't found C++ programs that use static
223/// destructors will fail to link. However, we don't want to use the host
224/// process's __cxa_atexit, because it will schedule JIT'd destructors to run
225/// after the JIT has been torn down, which is no good. This class makes it easy
226/// to override __cxa_atexit (and the related __dso_handle).
227///
228/// To use, clients should manually call searchOverrides from their symbol
229/// resolver. This should generally be done after attempting symbol resolution
230/// inside the JIT, but before searching the host process's symbol table. When
231/// the client determines that destructors should be run (generally at JIT
232/// teardown or after a return from main), the runDestructors method should be
233/// called.
234class LocalCXXRuntimeOverridesBase {
235public:
236 /// Run any destructors recorded by the overriden __cxa_atexit function
237 /// (CXAAtExitOverride).
238 void runDestructors();
239
240protected:
241 template <typename PtrTy> JITTargetAddress toTargetAddress(PtrTy *P) {
242 return static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(P));
243 }
244
245 using DestructorPtr = void (*)(void *);
246 using CXXDestructorDataPair = std::pair<DestructorPtr, void *>;
247 using CXXDestructorDataPairList = std::vector<CXXDestructorDataPair>;
248 CXXDestructorDataPairList DSOHandleOverride;
249 static int CXAAtExitOverride(DestructorPtr Destructor, void *Arg,
250 void *DSOHandle);
251};
252
253class LegacyLocalCXXRuntimeOverrides : public LocalCXXRuntimeOverridesBase {
254public:
255 /// Create a runtime-overrides class.
256 template <typename MangleFtorT>
257 LLVM_ATTRIBUTE_DEPRECATED(LegacyLocalCXXRuntimeOverrides(const MangleFtorT &Mangle)
__attribute__((deprecated("ORCv1 utilities (utilities with the 'Legacy' prefix) are deprecated. "
"Please use the ORCv2 LocalCXXRuntimeOverrides utility instead"
)))
258 LegacyLocalCXXRuntimeOverrides(const MangleFtorT &Mangle),LegacyLocalCXXRuntimeOverrides(const MangleFtorT &Mangle)
__attribute__((deprecated("ORCv1 utilities (utilities with the 'Legacy' prefix) are deprecated. "
"Please use the ORCv2 LocalCXXRuntimeOverrides utility instead"
)))
259 "ORCv1 utilities (utilities with the 'Legacy' prefix) are deprecated. "LegacyLocalCXXRuntimeOverrides(const MangleFtorT &Mangle)
__attribute__((deprecated("ORCv1 utilities (utilities with the 'Legacy' prefix) are deprecated. "
"Please use the ORCv2 LocalCXXRuntimeOverrides utility instead"
)))
260 "Please use the ORCv2 LocalCXXRuntimeOverrides utility instead")LegacyLocalCXXRuntimeOverrides(const MangleFtorT &Mangle)
__attribute__((deprecated("ORCv1 utilities (utilities with the 'Legacy' prefix) are deprecated. "
"Please use the ORCv2 LocalCXXRuntimeOverrides utility instead"
)))
;
261
262 template <typename MangleFtorT>
263 LegacyLocalCXXRuntimeOverrides(ORCv1DeprecationAcknowledgement,
264 const MangleFtorT &Mangle) {
265 addOverride(Mangle("__dso_handle"), toTargetAddress(&DSOHandleOverride));
266 addOverride(Mangle("__cxa_atexit"), toTargetAddress(&CXAAtExitOverride));
267 }
268
269 /// Search overrided symbols.
270 JITEvaluatedSymbol searchOverrides(const std::string &Name) {
271 auto I = CXXRuntimeOverrides.find(Name);
272 if (I != CXXRuntimeOverrides.end())
273 return JITEvaluatedSymbol(I->second, JITSymbolFlags::Exported);
274 return nullptr;
275 }
276
277private:
278 void addOverride(const std::string &Name, JITTargetAddress Addr) {
279 CXXRuntimeOverrides.insert(std::make_pair(Name, Addr));
280 }
281
282 StringMap<JITTargetAddress> CXXRuntimeOverrides;
283};
284
285template <typename MangleFtorT>
286LegacyLocalCXXRuntimeOverrides::LegacyLocalCXXRuntimeOverrides(
287 const MangleFtorT &Mangle) {
288 addOverride(Mangle("__dso_handle"), toTargetAddress(&DSOHandleOverride));
289 addOverride(Mangle("__cxa_atexit"), toTargetAddress(&CXAAtExitOverride));
290}
291
292class LocalCXXRuntimeOverrides : public LocalCXXRuntimeOverridesBase {
293public:
294 Error enable(JITDylib &JD, MangleAndInterner &Mangler);
295};
296
297/// An interface for Itanium __cxa_atexit interposer implementations.
298class ItaniumCXAAtExitSupport {
299public:
300 struct AtExitRecord {
301 void (*F)(void *);
302 void *Ctx;
303 };
304
305 void registerAtExit(void (*F)(void *), void *Ctx, void *DSOHandle);
306 void runAtExits(void *DSOHandle);
307
308private:
309 std::mutex AtExitsMutex;
310 DenseMap<void *, std::vector<AtExitRecord>> AtExitRecords;
311};
312
313/// A utility class to expose symbols found via dlsym to the JIT.
314///
315/// If an instance of this class is attached to a JITDylib as a fallback
316/// definition generator, then any symbol found in the given DynamicLibrary that
317/// passes the 'Allow' predicate will be added to the JITDylib.
318class DynamicLibrarySearchGenerator : public JITDylib::DefinitionGenerator {
319public:
320 using SymbolPredicate = std::function<bool(const SymbolStringPtr &)>;
321
322 /// Create a DynamicLibrarySearchGenerator that searches for symbols in the
323 /// given sys::DynamicLibrary.
324 ///
325 /// If the Allow predicate is given then only symbols matching the predicate
326 /// will be searched for. If the predicate is not given then all symbols will
327 /// be searched for.
328 DynamicLibrarySearchGenerator(sys::DynamicLibrary Dylib, char GlobalPrefix,
329 SymbolPredicate Allow = SymbolPredicate());
330
331 /// Permanently loads the library at the given path and, on success, returns
332 /// a DynamicLibrarySearchGenerator that will search it for symbol definitions
333 /// in the library. On failure returns the reason the library failed to load.
334 static Expected<std::unique_ptr<DynamicLibrarySearchGenerator>>
335 Load(const char *FileName, char GlobalPrefix,
336 SymbolPredicate Allow = SymbolPredicate());
337
338 /// Creates a DynamicLibrarySearchGenerator that searches for symbols in
339 /// the current process.
340 static Expected<std::unique_ptr<DynamicLibrarySearchGenerator>>
341 GetForCurrentProcess(char GlobalPrefix,
342 SymbolPredicate Allow = SymbolPredicate()) {
343 return Load(nullptr, GlobalPrefix, std::move(Allow));
344 }
345
346 Error tryToGenerate(LookupKind K, JITDylib &JD,
347 JITDylibLookupFlags JDLookupFlags,
348 const SymbolLookupSet &Symbols) override;
349
350private:
351 sys::DynamicLibrary Dylib;
352 SymbolPredicate Allow;
353 char GlobalPrefix;
354};
355
356/// A utility class to expose symbols from a static library.
357///
358/// If an instance of this class is attached to a JITDylib as a fallback
359/// definition generator, then any symbol found in the archive will result in
360/// the containing object being added to the JITDylib.
361class StaticLibraryDefinitionGenerator : public JITDylib::DefinitionGenerator {
362public:
363 /// Try to create a StaticLibraryDefinitionGenerator from the given path.
364 ///
365 /// This call will succeed if the file at the given path is a static library
366 /// is a valid archive, otherwise it will return an error.
367 static Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
368 Load(ObjectLayer &L, const char *FileName);
369
370 /// Try to create a StaticLibrarySearchGenerator from the given memory buffer.
371 /// This call will succeed if the buffer contains a valid archive, otherwise
372 /// it will return an error.
373 static Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
374 Create(ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer);
375
376 Error tryToGenerate(LookupKind K, JITDylib &JD,
377 JITDylibLookupFlags JDLookupFlags,
378 const SymbolLookupSet &Symbols) override;
379
380private:
381 StaticLibraryDefinitionGenerator(ObjectLayer &L,
382 std::unique_ptr<MemoryBuffer> ArchiveBuffer,
383 Error &Err);
384
385 ObjectLayer &L;
386 std::unique_ptr<MemoryBuffer> ArchiveBuffer;
387 std::unique_ptr<object::Archive> Archive;
388};
389
390} // end namespace orc
391} // end namespace llvm
392
393#endif // LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ExecutionEngine/JITSymbol.h

1//===- JITSymbol.h - JIT symbol abstraction ---------------------*- 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// Abstraction for target process addresses.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_EXECUTIONENGINE_JITSYMBOL_H
14#define LLVM_EXECUTIONENGINE_JITSYMBOL_H
15
16#include <algorithm>
17#include <cassert>
18#include <cstddef>
19#include <cstdint>
20#include <functional>
21#include <map>
22#include <set>
23#include <string>
24
25#include "llvm/ADT/BitmaskEnum.h"
26#include "llvm/ADT/FunctionExtras.h"
27#include "llvm/ADT/StringRef.h"
28#include "llvm/Support/Error.h"
29
30namespace llvm {
31
32class GlobalValue;
33class GlobalValueSummary;
34
35namespace object {
36
37class SymbolRef;
38
39} // end namespace object
40
41/// Represents an address in the target process's address space.
42using JITTargetAddress = uint64_t;
43
44/// Convert a JITTargetAddress to a pointer.
45///
46/// Note: This is a raw cast of the address bit pattern to the given pointer
47/// type. When casting to a function pointer in order to execute JIT'd code
48/// jitTargetAddressToFunction should be preferred, as it will also perform
49/// pointer signing on targets that require it.
50template <typename T> T jitTargetAddressToPointer(JITTargetAddress Addr) {
51 static_assert(std::is_pointer<T>::value, "T must be a pointer type");
52 uintptr_t IntPtr = static_cast<uintptr_t>(Addr);
53 assert(IntPtr == Addr && "JITTargetAddress value out of range for uintptr_t")((IntPtr == Addr && "JITTargetAddress value out of range for uintptr_t"
) ? static_cast<void> (0) : __assert_fail ("IntPtr == Addr && \"JITTargetAddress value out of range for uintptr_t\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ExecutionEngine/JITSymbol.h"
, 53, __PRETTY_FUNCTION__))
;
54 return reinterpret_cast<T>(IntPtr);
55}
56
57/// Convert a JITTargetAddress to a callable function pointer.
58///
59/// Casts the given address to a callable function pointer. This operation
60/// will perform pointer signing for platforms that require it (e.g. arm64e).
61template <typename T> T jitTargetAddressToFunction(JITTargetAddress Addr) {
62 static_assert(std::is_pointer<T>::value &&
63 std::is_function<std::remove_pointer_t<T>>::value,
64 "T must be a function pointer type");
65 return jitTargetAddressToPointer<T>(Addr);
66}
67
68/// Convert a pointer to a JITTargetAddress.
69template <typename T> JITTargetAddress pointerToJITTargetAddress(T *Ptr) {
70 return static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(Ptr));
71}
72
73/// Flags for symbols in the JIT.
74class JITSymbolFlags {
75public:
76 using UnderlyingType = uint8_t;
77 using TargetFlagsType = uint8_t;
78
79 enum FlagNames : UnderlyingType {
80 None = 0,
81 HasError = 1U << 0,
82 Weak = 1U << 1,
83 Common = 1U << 2,
84 Absolute = 1U << 3,
85 Exported = 1U << 4,
86 Callable = 1U << 5,
87 LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ Callable)LLVM_BITMASK_LARGEST_ENUMERATOR = Callable
88 };
89
90 /// Default-construct a JITSymbolFlags instance.
91 JITSymbolFlags() = default;
92
93 /// Construct a JITSymbolFlags instance from the given flags.
94 JITSymbolFlags(FlagNames Flags) : Flags(Flags) {}
95
96 /// Construct a JITSymbolFlags instance from the given flags and target
97 /// flags.
98 JITSymbolFlags(FlagNames Flags, TargetFlagsType TargetFlags)
99 : TargetFlags(TargetFlags), Flags(Flags) {}
100
101 /// Implicitly convert to bool. Returs true if any flag is set.
102 explicit operator bool() const { return Flags != None || TargetFlags != 0; }
103
104 /// Compare for equality.
105 bool operator==(const JITSymbolFlags &RHS) const {
106 return Flags == RHS.Flags && TargetFlags == RHS.TargetFlags;
107 }
108
109 /// Bitwise AND-assignment for FlagNames.
110 JITSymbolFlags &operator&=(const FlagNames &RHS) {
111 Flags &= RHS;
112 return *this;
113 }
114
115 /// Bitwise OR-assignment for FlagNames.
116 JITSymbolFlags &operator|=(const FlagNames &RHS) {
117 Flags |= RHS;
118 return *this;
119 }
120
121 /// Return true if there was an error retrieving this symbol.
122 bool hasError() const {
123 return (Flags & HasError) == HasError;
124 }
125
126 /// Returns true if the Weak flag is set.
127 bool isWeak() const {
128 return (Flags & Weak) == Weak;
129 }
130
131 /// Returns true if the Common flag is set.
132 bool isCommon() const {
133 return (Flags & Common) == Common;
134 }
135
136 /// Returns true if the symbol isn't weak or common.
137 bool isStrong() const {
138 return !isWeak() && !isCommon();
139 }
140
141 /// Returns true if the Exported flag is set.
142 bool isExported() const {
143 return (Flags & Exported) == Exported;
144 }
145
146 /// Returns true if the given symbol is known to be callable.
147 bool isCallable() const { return (Flags & Callable) == Callable; }
148
149 /// Get the underlying flags value as an integer.
150 UnderlyingType getRawFlagsValue() const {
151 return static_cast<UnderlyingType>(Flags);
152 }
153
154 /// Return a reference to the target-specific flags.
155 TargetFlagsType& getTargetFlags() { return TargetFlags; }
156
157 /// Return a reference to the target-specific flags.
158 const TargetFlagsType& getTargetFlags() const { return TargetFlags; }
159
160 /// Construct a JITSymbolFlags value based on the flags of the given global
161 /// value.
162 static JITSymbolFlags fromGlobalValue(const GlobalValue &GV);
163
164 /// Construct a JITSymbolFlags value based on the flags of the given global
165 /// value summary.
166 static JITSymbolFlags fromSummary(GlobalValueSummary *S);
167
168 /// Construct a JITSymbolFlags value based on the flags of the given libobject
169 /// symbol.
170 static Expected<JITSymbolFlags>
171 fromObjectSymbol(const object::SymbolRef &Symbol);
172
173private:
174 TargetFlagsType TargetFlags = 0;
175 FlagNames Flags = None;
176};
177
178inline JITSymbolFlags operator&(const JITSymbolFlags &LHS,
179 const JITSymbolFlags::FlagNames &RHS) {
180 JITSymbolFlags Tmp = LHS;
181 Tmp &= RHS;
182 return Tmp;
183}
184
185inline JITSymbolFlags operator|(const JITSymbolFlags &LHS,
186 const JITSymbolFlags::FlagNames &RHS) {
187 JITSymbolFlags Tmp = LHS;
188 Tmp |= RHS;
189 return Tmp;
190}
191
192/// ARM-specific JIT symbol flags.
193/// FIXME: This should be moved into a target-specific header.
194class ARMJITSymbolFlags {
195public:
196 ARMJITSymbolFlags() = default;
197
198 enum FlagNames {
199 None = 0,
200 Thumb = 1 << 0
201 };
202
203 operator JITSymbolFlags::TargetFlagsType&() { return Flags; }
204
205 static ARMJITSymbolFlags fromObjectSymbol(const object::SymbolRef &Symbol);
206
207private:
208 JITSymbolFlags::TargetFlagsType Flags = 0;
209};
210
211/// Represents a symbol that has been evaluated to an address already.
212class JITEvaluatedSymbol {
213public:
214 JITEvaluatedSymbol() = default;
215
216 /// Create a 'null' symbol.
217 JITEvaluatedSymbol(std::nullptr_t) {}
218
219 /// Create a symbol for the given address and flags.
220 JITEvaluatedSymbol(JITTargetAddress Address, JITSymbolFlags Flags)
221 : Address(Address), Flags(Flags) {}
222
223 /// An evaluated symbol converts to 'true' if its address is non-zero.
224 explicit operator bool() const { return Address != 0; }
225
226 /// Return the address of this symbol.
227 JITTargetAddress getAddress() const { return Address; }
228
229 /// Return the flags for this symbol.
230 JITSymbolFlags getFlags() const { return Flags; }
231
232 /// Set the flags for this symbol.
233 void setFlags(JITSymbolFlags Flags) { this->Flags = std::move(Flags); }
234
235private:
236 JITTargetAddress Address = 0;
237 JITSymbolFlags Flags;
238};
239
240/// Represents a symbol in the JIT.
241class JITSymbol {
242public:
243 using GetAddressFtor = unique_function<Expected<JITTargetAddress>()>;
244
245 /// Create a 'null' symbol, used to represent a "symbol not found"
246 /// result from a successful (non-erroneous) lookup.
247 JITSymbol(std::nullptr_t)
248 : CachedAddr(0) {}
249
250 /// Create a JITSymbol representing an error in the symbol lookup
251 /// process (e.g. a network failure during a remote lookup).
252 JITSymbol(Error Err)
253 : Err(std::move(Err)), Flags(JITSymbolFlags::HasError) {}
254
255 /// Create a symbol for a definition with a known address.
256 JITSymbol(JITTargetAddress Addr, JITSymbolFlags Flags)
257 : CachedAddr(Addr), Flags(Flags) {}
258
259 /// Construct a JITSymbol from a JITEvaluatedSymbol.
260 JITSymbol(JITEvaluatedSymbol Sym)
261 : CachedAddr(Sym.getAddress()), Flags(Sym.getFlags()) {}
262
263 /// Create a symbol for a definition that doesn't have a known address
264 /// yet.
265 /// @param GetAddress A functor to materialize a definition (fixing the
266 /// address) on demand.
267 ///
268 /// This constructor allows a JIT layer to provide a reference to a symbol
269 /// definition without actually materializing the definition up front. The
270 /// user can materialize the definition at any time by calling the getAddress
271 /// method.
272 JITSymbol(GetAddressFtor GetAddress, JITSymbolFlags Flags)
273 : GetAddress(std::move(GetAddress)), CachedAddr(0), Flags(Flags) {}
274
275 JITSymbol(const JITSymbol&) = delete;
276 JITSymbol& operator=(const JITSymbol&) = delete;
277
278 JITSymbol(JITSymbol &&Other)
279 : GetAddress(std::move(Other.GetAddress)), Flags(std::move(Other.Flags)) {
280 if (Flags.hasError())
281 Err = std::move(Other.Err);
282 else
283 CachedAddr = std::move(Other.CachedAddr);
284 }
285
286 JITSymbol& operator=(JITSymbol &&Other) {
287 GetAddress = std::move(Other.GetAddress);
288 Flags = std::move(Other.Flags);
289 if (Flags.hasError())
290 Err = std::move(Other.Err);
291 else
292 CachedAddr = std::move(Other.CachedAddr);
293 return *this;
294 }
295
296 ~JITSymbol() {
297 if (Flags.hasError())
298 Err.~Error();
299 else
300 CachedAddr.~JITTargetAddress();
301 }
302
303 /// Returns true if the symbol exists, false otherwise.
304 explicit operator bool() const {
305 return !Flags.hasError() && (CachedAddr || GetAddress);
5
Assuming field 'CachedAddr' is 0
6
Returning the value 1, which participates in a condition later
306 }
307
308 /// Move the error field value out of this JITSymbol.
309 Error takeError() {
310 if (Flags.hasError())
311 return std::move(Err);
312 return Error::success();
313 }
314
315 /// Get the address of the symbol in the target address space. Returns
316 /// '0' if the symbol does not exist.
317 Expected<JITTargetAddress> getAddress() {
318 assert(!Flags.hasError() && "getAddress called on error value")((!Flags.hasError() && "getAddress called on error value"
) ? static_cast<void> (0) : __assert_fail ("!Flags.hasError() && \"getAddress called on error value\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ExecutionEngine/JITSymbol.h"
, 318, __PRETTY_FUNCTION__))
;
10
'?' condition is true
319 if (GetAddress) {
11
Taking false branch
320 if (auto CachedAddrOrErr = GetAddress()) {
321 GetAddress = nullptr;
322 CachedAddr = *CachedAddrOrErr;
323 assert(CachedAddr && "Symbol could not be materialized.")((CachedAddr && "Symbol could not be materialized.") ?
static_cast<void> (0) : __assert_fail ("CachedAddr && \"Symbol could not be materialized.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ExecutionEngine/JITSymbol.h"
, 323, __PRETTY_FUNCTION__))
;
324 } else
325 return CachedAddrOrErr.takeError();
326 }
327 return CachedAddr;
12
Calling constructor for 'Expected<unsigned long>'
16
Returning from constructor for 'Expected<unsigned long>'
328 }
329
330 JITSymbolFlags getFlags() const { return Flags; }
331
332private:
333 GetAddressFtor GetAddress;
334 union {
335 JITTargetAddress CachedAddr;
336 Error Err;
337 };
338 JITSymbolFlags Flags;
339};
340
341/// Symbol resolution interface.
342///
343/// Allows symbol flags and addresses to be looked up by name.
344/// Symbol queries are done in bulk (i.e. you request resolution of a set of
345/// symbols, rather than a single one) to reduce IPC overhead in the case of
346/// remote JITing, and expose opportunities for parallel compilation.
347class JITSymbolResolver {
348public:
349 using LookupSet = std::set<StringRef>;
350 using LookupResult = std::map<StringRef, JITEvaluatedSymbol>;
351 using OnResolvedFunction = unique_function<void(Expected<LookupResult>)>;
352
353 virtual ~JITSymbolResolver() = default;
354
355 /// Returns the fully resolved address and flags for each of the given
356 /// symbols.
357 ///
358 /// This method will return an error if any of the given symbols can not be
359 /// resolved, or if the resolution process itself triggers an error.
360 virtual void lookup(const LookupSet &Symbols,
361 OnResolvedFunction OnResolved) = 0;
362
363 /// Returns the subset of the given symbols that should be materialized by
364 /// the caller. Only weak/common symbols should be looked up, as strong
365 /// definitions are implicitly always part of the caller's responsibility.
366 virtual Expected<LookupSet>
367 getResponsibilitySet(const LookupSet &Symbols) = 0;
368
369private:
370 virtual void anchor();
371};
372
373/// Legacy symbol resolution interface.
374class LegacyJITSymbolResolver : public JITSymbolResolver {
375public:
376 /// Performs lookup by, for each symbol, first calling
377 /// findSymbolInLogicalDylib and if that fails calling
378 /// findSymbol.
379 void lookup(const LookupSet &Symbols, OnResolvedFunction OnResolved) final;
380
381 /// Performs flags lookup by calling findSymbolInLogicalDylib and
382 /// returning the flags value for that symbol.
383 Expected<LookupSet> getResponsibilitySet(const LookupSet &Symbols) final;
384
385 /// This method returns the address of the specified symbol if it exists
386 /// within the logical dynamic library represented by this JITSymbolResolver.
387 /// Unlike findSymbol, queries through this interface should return addresses
388 /// for hidden symbols.
389 ///
390 /// This is of particular importance for the Orc JIT APIs, which support lazy
391 /// compilation by breaking up modules: Each of those broken out modules
392 /// must be able to resolve hidden symbols provided by the others. Clients
393 /// writing memory managers for MCJIT can usually ignore this method.
394 ///
395 /// This method will be queried by RuntimeDyld when checking for previous
396 /// definitions of common symbols.
397 virtual JITSymbol findSymbolInLogicalDylib(const std::string &Name) = 0;
398
399 /// This method returns the address of the specified function or variable.
400 /// It is used to resolve symbols during module linking.
401 ///
402 /// If the returned symbol's address is equal to ~0ULL then RuntimeDyld will
403 /// skip all relocations for that symbol, and the client will be responsible
404 /// for handling them manually.
405 virtual JITSymbol findSymbol(const std::string &Name) = 0;
406
407private:
408 virtual void anchor();
409};
410
411} // end namespace llvm
412
413#endif // LLVM_EXECUTIONENGINE_JITSYMBOL_H

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/Support/Error.h

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