LLVM: include/llvm/Support/ErrorOr.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15#ifndef LLVM_SUPPORT_ERROROR_H

16#define LLVM_SUPPORT_ERROROR_H

17

19#include

20#include <system_error>

21#include <type_traits>

22#include

23

24namespace llvm {

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55template

57 template friend class ErrorOr;

58

59 static constexpr bool isRef = std::is_reference_v;

60

61 using wrap = std::reference_wrapper<std::remove_reference_t>;

62

63public:

64 using storage_type = std::conditional_t<isRef, wrap, T>;

65

66private:

67 using reference = std::remove_reference_t &;

68 using const_reference = const std::remove_reference_t &;

69 using pointer = std::remove_reference_t *;

70 using const_pointer = const std::remove_reference_t *;

71

72public:

73 template

75 std::enable_if_t<std::is_error_code_enum::value ||

76 std::is_error_condition_enum::value,

77 void *> = nullptr)

78 : HasError(true) {

79 new (getErrorStorage()) std::error_code(make_error_code(ErrorCode));

80 }

81

83 new (getErrorStorage()) std::error_code(EC);

84 }

85

86 template

88 std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr)

89 : HasError(false) {

90 new (getStorage()) storage_type(std::forward(Val));

91 }

92

94 copyConstruct(Other);

95 }

96

97 template

99 std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr) {

100 copyConstruct(Other);

101 }

102

103 template

106 std::enable_if_t<!std::is_convertible_v<OtherT, const T &>> * = nullptr) {

107 copyConstruct(Other);

108 }

109

111 moveConstruct(std::move(Other));

112 }

113

114 template

116 std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr) {

117 moveConstruct(std::move(Other));

118 }

119

120

121

122 template

125 std::enable_if_t<!std::is_convertible_v<OtherT, T>> * = nullptr) {

126 moveConstruct(std::move(Other));

127 }

128

130 copyAssign(Other);

131 return *this;

132 }

133

135 moveAssign(std::move(Other));

136 return *this;

137 }

138

140 if (!HasError)

141 getStorage()->~storage_type();

142 }

143

144

145 explicit operator bool() const {

146 return !HasError;

147 }

148

149 reference get() { return *getStorage(); }

150 const_reference get() const { return const_cast<ErrorOr *>(this)->get(); }

151

153 return HasError ? *getErrorStorage() : std::error_code();

154 }

155

157 return toPointer(getStorage());

158 }

159

160 const_pointer operator->() const { return toPointer(getStorage()); }

161

163 return *getStorage();

164 }

165

166 const_reference operator*() const { return *getStorage(); }

167

168private:

169 template

171 if (Other.HasError) {

172

173 HasError = false;

175 } else {

176

177 HasError = true;

178 new (getErrorStorage()) std::error_code(Other.getError());

179 }

180 }

181

182 template

183 static bool compareThisIfSameType(const T1 &a, const T1 &b) {

184 return &a == &b;

185 }

186

187 template <class T1, class T2>

188 static bool compareThisIfSameType(const T1 &a, const T2 &b) {

189 return false;

190 }

191

192 template

193 void copyAssign(const ErrorOr &Other) {

194 if (compareThisIfSameType(*this, Other))

195 return;

196

198 new (this) ErrorOr(Other);

199 }

200

201 template

202 void moveConstruct(ErrorOr &&Other) {

203 if (Other.HasError) {

204

205 HasError = false;

207 } else {

208

209 HasError = true;

210 new (getErrorStorage()) std::error_code(Other.getError());

211 }

212 }

213

214 template

215 void moveAssign(ErrorOr &&Other) {

216 if (compareThisIfSameType(*this, Other))

217 return;

218

221 }

222

223 pointer toPointer(pointer Val) {

224 return Val;

225 }

226

227 const_pointer toPointer(const_pointer Val) const { return Val; }

228

229 pointer toPointer(wrap *Val) {

230 return &Val->get();

231 }

232

233 const_pointer toPointer(const wrap *Val) const { return &Val->get(); }

234

236 assert(!HasError && "Cannot get value when an error exists!");

238 }

239

241 assert(!HasError && "Cannot get value when an error exists!");

243 }

244

245 std::error_code *getErrorStorage() {

246 assert(HasError && "Cannot get error when a value exists!");

247 return reinterpret_cast<std::error_code *>(&ErrorStorage);

248 }

249

250 const std::error_code *getErrorStorage() const {

251 return const_cast<ErrorOr *>(this)->getErrorStorage();

252 }

253

254 union {

257 };

258 bool HasError : 1;

259};

260

261template <class T, class E>

262std::enable_if_t<std::is_error_code_enum::value ||

263 std::is_error_condition_enum::value,

264 bool>

266 return Err.getError() == Code;

267}

268

269}

270

271#endif

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static LLVMTargetMachineRef wrap(const TargetMachine *P)

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

Represents either an error or a value T.

std::conditional_t< isRef, wrap, T > storage_type

const_reference get() const

ErrorOr(std::error_code EC)

ErrorOr(OtherT &&Val, std::enable_if_t< std::is_convertible_v< OtherT, T > > *=nullptr)

AlignedCharArrayUnion< std::error_code > ErrorStorage

ErrorOr(const ErrorOr &Other)

ErrorOr(E ErrorCode, std::enable_if_t< std::is_error_code_enum< E >::value||std::is_error_condition_enum< E >::value, void * >=nullptr)

const_reference operator*() const

ErrorOr(ErrorOr< OtherT > &&Other, std::enable_if_t< std::is_convertible_v< OtherT, T > > *=nullptr)

ErrorOr & operator=(const ErrorOr &Other)

std::error_code getError() const

ErrorOr(const ErrorOr< OtherT > &Other, std::enable_if_t< std::is_convertible_v< OtherT, T > > *=nullptr)

ErrorOr(const ErrorOr< OtherT > &Other, std::enable_if_t<!std::is_convertible_v< OtherT, const T & > > *=nullptr)

ErrorOr(ErrorOr< OtherT > &&Other, std::enable_if_t<!std::is_convertible_v< OtherT, T > > *=nullptr)

const_pointer operator->() const

ErrorOr & operator=(ErrorOr &&Other)

AlignedCharArrayUnion< storage_type > TStorage

This is an optimization pass for GlobalISel generic memory operations.

std::error_code make_error_code(BitcodeError E)

bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)

A suitably aligned and sized character array member which can hold elements of any type.