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

1

2

3

4

5

6

7

8

9

10

11

12

13

14#ifndef LLVM_SUPPORT_CASTING_H

15#define LLVM_SUPPORT_CASTING_H

16

19#include

20#include

21#include

22#include <type_traits>

23

24namespace llvm {

25

26

27

28

29

30

31

32

33

36

37

39};

40

46

49 }

50};

51

52

53

54

55

56

57

58

59

60

61

62

63template <typename To, typename From, typename Enabler = void> struct isa_impl {

64 static inline bool doit(const From &Val) { return To::classof(&Val); }

65};

66

67

68template <typename To, typename From>

69struct isa_impl<To, From, std::enable_if_t<std::is_base_of_v<To, From>>> {

70 static inline bool doit(const From &) { return true; }

71};

72

73template <typename To, typename From> struct isa_impl_cl {

74 static inline bool doit(const From &Val) {

76 }

77};

78

80 static inline bool doit(const From &Val) {

82 }

83};

84

85template <typename To, typename From>

87 static inline bool doit(const std::unique_ptr &Val) {

88 assert(Val && "isa<> used on a null pointer");

90 }

91};

92

93template <typename To, typename From> struct isa_impl_cl<To, From *> {

94 static inline bool doit(const From *Val) {

95 assert(Val && "isa<> used on a null pointer");

97 }

98};

99

100template <typename To, typename From> struct isa_impl_cl<To, From *const> {

101 static inline bool doit(const From *Val) {

102 assert(Val && "isa<> used on a null pointer");

104 }

105};

106

108 static inline bool doit(const From *Val) {

109 assert(Val && "isa<> used on a null pointer");

111 }

112};

113

114template <typename To, typename From>

116 static inline bool doit(const From *Val) {

117 assert(Val && "isa<> used on a null pointer");

119 }

120};

121

122template <typename To, typename From, typename SimpleFrom>

124

125

130 }

131};

132

133template <typename To, typename FromTy>

135

136 static bool doit(const FromTy &Val) {

138 }

139};

140

141

142

143

144

145template <class To, class From> struct cast_retty;

146

147

148

150 using ret_type = To &;

151};

153 using ret_type = const To &;

154};

155

157 using ret_type = To *;

158};

159

161 using ret_type = const To *;

162};

163

165 using ret_type = const To *;

166};

167

168template <class To, class From>

170private:

172 using ResultType = std::remove_pointer_t;

173

174public:

175 using ret_type = std::unique_ptr;

176};

177

178template <class To, class From, class SimpleFrom> struct cast_retty_wrap {

179

180

181

183};

184

185template <class To, class FromTy> struct cast_retty_wrap<To, FromTy, FromTy> {

186

188};

189

190template <class To, class From> struct cast_retty {

193};

194

195

196

197

198

199

200

201

202template <class To, class From, class SimpleFrom> struct cast_convert_val {

203

208 }

209};

210

211template <class To, class FromTy> struct cast_convert_val<To, FromTy, FromTy> {

212

214 return *(std::remove_reference_t<typename cast_retty<To, FromTy>::ret_type>

215 *)&const_cast<FromTy &>(Val);

216 }

217};

218

219template <class To, class FromTy>

221

224 Val);

225 }

226};

227

228

229

230

231

234 std::is_same_v<X, typename simplify_type::SimpleType>;

235};

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252template <typename To, typename From, typename Enable = void>

256 To, const From,

258 }

259};

260

261

262

263

264

265template <typename To, typename From>

267 static inline bool isPossible(const std::optional &f) {

268 assert(f && "CastIsPossible::isPossible called on a nullopt!");

270 To, const From,

272 }

273};

274

275

276

277template <typename To, typename From>

280};

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

303};

304

305

306

307

308template <typename To, typename From, typename Derived>

311 if (!Derived::isPossible(f))

312 return Derived::castFailed();

313 return Derived::doCast(f);

314 }

315};

316

318

319

320template <typename OptionalDerived, typename Default>

321using SelfType = std::conditional_t<std::is_same_v<OptionalDerived, void>,

322 Default, OptionalDerived>;

323}

324

325

326

327

328template <typename To, typename From, typename Derived = void>

333 To, From *,

334 detail::SelfType<Derived, ValueFromPointerCast<To, From>>> {

335 static inline To doCast(From *f) { return To(f); }

336};

337

338

339

340

341

342template <typename To, typename From, typename Derived = void>

346 std::remove_reference_t<typename cast_retty<To, From>::ret_type>>;

347

349 return CastResultType((typename CastResultType::element_type *)f.release());

350 }

351

353

355 if (!Self::isPossible(f.get()))

357 return doCast(std::move(f));

358 }

359};

360

361

362

363

364template <typename To, typename From, typename Derived = void>

368 std::optional, From,

369 detail::SelfType<Derived, OptionalValueCast<To, From>>> {

370 static inline std::optional castFailed() { return std::optional{}; }

371

372 static inline std::optional doCast(const From &f) { return To(f); }

373};

374

375

376

377

378

379

380

381

382

383

384

385

386

387template <typename To, typename From, typename ForwardTo>

389

390 using DecayedFrom = std::remove_cv_t<std::remove_pointer_t>;

391

394

396 return ForwardTo::isPossible(const_cast<NonConstFrom>(f));

397 }

398

399 static inline decltype(auto) castFailed() { return ForwardTo::castFailed(); }

400

401 static inline decltype(auto) doCast(const From &f) {

402 return ForwardTo::doCast(const_cast<NonConstFrom>(f));

403 }

404

406 return ForwardTo::doCastIfPossible(const_cast<NonConstFrom>(f));

407 }

408};

409

410

411

412

413

414

415

416

417

418

419

420

421

422template <typename To, typename From, typename ForwardTo>

425 return ForwardTo::isPossible(&f);

426 }

427

428 static inline decltype(auto) doCast(const From &f) {

429 return *ForwardTo::doCast(&f);

430 }

431};

432

433

434

435

436

437

438

439

440

441

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

458

459

460

461

462

463

464

465

466

467

468

469

470

471

472

473

474

475template <typename To, typename From, typename Enable = void>

478

480

485 }

486

487

488

489

491

496 }

497};

498

499

500

501

502template <typename To, typename From>

503struct CastInfo<To, From, std::enable_if_t<!is_simple_type::value>> {

507

509 return SimplifiedSelf::isPossible(

511 }

512

515 }

516

518 return SimplifiedSelf::castFailed();

519 }

520

522 return SimplifiedSelf::doCastIfPossible(

524 }

525};

526

527

528

529

530

531

532template <typename To, typename From>

534

535

536

537

538template <typename To, typename From>

540};

541

542

543

544

545

546

547template <typename To, typename From>

548[[nodiscard]] inline bool isa(const From &Val) {

550}

551

552template <typename First, typename Second, typename... Rest, typename From>

553[[nodiscard]] inline bool isa(const From &Val) {

554 return isa(Val) || isa<Second, Rest...>(Val);

555}

556

557

558

559

560

561

562

563

564template <typename To, typename From>

565[[nodiscard]] inline decltype(auto) cast(const From &Val) {

566 assert(isa(Val) && "cast() argument of incompatible type!");

568}

569

570template <typename To, typename From>

571[[nodiscard]] inline decltype(auto) cast(From &Val) {

572 assert(isa(Val) && "cast() argument of incompatible type!");

574}

575

576template <typename To, typename From>

577[[nodiscard]] inline decltype(auto) cast(From *Val) {

578 assert(isa(Val) && "cast() argument of incompatible type!");

580}

581

582template <typename To, typename From>

583[[nodiscard]] inline decltype(auto) cast(std::unique_ptr &&Val) {

584 assert(isa(Val) && "cast() argument of incompatible type!");

586}

587

588

589

590

591

592template

594 std::is_pointer_v || std::is_constructible_v<T, std::nullptr_t>;

595

596

597

598

599

600

601

602template <typename T, typename Enable = void> struct ValueIsPresent {

604 static inline bool isPresent(const T &t) { return true; }

605 static inline decltype(auto) unwrapValue(T &t) { return t; }

606};

607

608

611 static inline bool isPresent(const std::optional &t) {

612 return t.has_value();

613 }

614 static inline decltype(auto) unwrapValue(std::optional &t) { return *t; }

615};

616

617

618

619template

622 static inline bool isPresent(const T &t) { return t != T(nullptr); }

623 static inline decltype(auto) unwrapValue(T &t) { return t; }

624};

625

627

628

629template inline bool isPresent(const T &t) {

632}

633

634

635template inline decltype(auto) unwrapValue(T &t) {

637}

638}

639

640

641

642

643

644

645

646

647

648template <typename To, typename From>

649[[nodiscard]] inline decltype(auto) dyn_cast(const From &Val) {

652}

653

654template <typename To, typename From>

658}

659

660template <typename To, typename From>

664}

665

666template <typename To, typename From>

667[[nodiscard]] inline decltype(auto) dyn_cast(std::unique_ptr &Val) {

670}

671

672

673

674template <typename... X, class Y>

677 return false;

678 return isa<X...>(Val);

679}

680

681template <typename... X, class Y>

684}

685

686

687

688template <class X, class Y>

692 assert(isa(Val) && "cast_if_present() argument of incompatible type!");

694}

695

696template <class X, class Y> [[nodiscard]] inline auto cast_if_present(Y &Val) {

699 assert(isa(Val) && "cast_if_present() argument of incompatible type!");

701}

702

703template <class X, class Y> [[nodiscard]] inline auto cast_if_present(Y *Val) {

706 assert(isa(Val) && "cast_if_present() argument of incompatible type!");

708}

709

710template <class X, class Y>

715}

716

717

718

719

721 return cast_if_present(Val);

722}

723

725 return cast_if_present(Val);

726}

727

729 return cast_if_present(Val);

730}

731

732template <class X, class Y> auto cast_or_null(std::unique_ptr &&Val) {

733 return cast_if_present(std::move(Val));

734}

735

736

737

742}

743

748}

749

754}

755

756

757

758

760 return dyn_cast_if_present(Val);

761}

762

764 return dyn_cast_if_present(Val);

765}

766

768 return dyn_cast_if_present(Val);

769}

770

771

772

773

774

775

776template <class X, class Y>

777[[nodiscard]] inline typename CastInfo<X, std::unique_ptr>::CastResultType

779 if (!isa(Val))

780 return nullptr;

781 return cast(std::move(Val));

782}

783

784template <class X, class Y>

786 return unique_dyn_cast<X, Y>(Val);

787}

788

789

790

791template <class X, class Y>

792[[nodiscard]] inline typename CastInfo<X, std::unique_ptr>::CastResultType

794 if (!Val)

795 return nullptr;

796 return unique_dyn_cast<X, Y>(Val);

797}

798

799template <class X, class Y>

801 return unique_dyn_cast_or_null<X, Y>(Val);

802}

803

804

805

806

807

808

809

810

811

812

815 template [[nodiscard]] bool operator()(const T &Val) const {

816 return isa<Types...>(Val);

817 }

818};

819

821 template [[nodiscard]] bool operator()(const T &Val) const {

823 }

824};

825}

826

827

828

829

830

831

832

833

834

835template <typename... Types>

837

838

839

840

841

842

843

844

845

846template <typename... Types>

847inline constexpr detail::IsaAndPresentCheckPredicate<Types...>

849

850}

851

852#endif

BlockVerifier::State From

static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")

static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")

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

std::conditional_t< std::is_same_v< OptionalDerived, void >, Default, OptionalDerived > SelfType

A helper to derive the type to use with Self for cast traits, when the provided CRTP derived type is ...

bool isPresent(const T &t)

decltype(auto) unwrapValue(T &t)

This is an optimization pass for GlobalISel generic memory operations.

auto cast_if_present(const Y &Val)

cast_if_present - Functionally identical to cast, except that a null value is accepted.

CastInfo< X, std::unique_ptr< Y > >::CastResultType unique_dyn_cast(std::unique_ptr< Y > &Val)

unique_dyn_cast - Given a unique_ptr, try to return a unique_ptr, taking ownership of the in...

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

auto dyn_cast_if_present(const Y &Val)

dyn_cast_if_present - Functionally identical to dyn_cast, except that a null (or none in the case ...

auto cast_or_null(const Y &Val)

constexpr detail::IsaAndPresentCheckPredicate< Types... > IsaAndPresentPred

Function object wrapper for the llvm::isa_and_present type check.

bool isa_and_nonnull(const Y &Val)

auto dyn_cast_or_null(const Y &Val)

bool isa_and_present(const Y &Val)

isa_and_present - Functionally identical to isa, except that a null value is accepted.

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

@ First

Helpers to iterate all locations in the MemoryEffectsBase class.

constexpr bool IsNullable

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

CastInfo< X, std::unique_ptr< Y > >::CastResultType unique_dyn_cast_or_null(std::unique_ptr< Y > &Val)

@ Default

The result values are uniform if and only if all operands are uniform.

constexpr detail::IsaCheckPredicate< Types... > IsaPred

Function object wrapper for the llvm::isa type check.

Implement std::hash so that hash_code can be used in STL containers.

typename simplify_type< From >::SimpleType SimpleFrom

static decltype(auto) castFailed()

static bool isPossible(From &f)

static decltype(auto) doCast(From &f)

static decltype(auto) doCastIfPossible(From &f)

This struct provides a method for customizing the way a cast is performed.

static CastReturnType castFailed()

static CastReturnType doCast(const From &f)

static CastReturnType doCastIfPossible(const From &f)

typename cast_retty< To, From >::ret_type CastReturnType

static bool isPossible(const From &f)

static bool isPossible(const std::optional< From > &f)

This struct provides a way to check if a given cast is possible.

static bool isPossible(const From &f)

Provides a cast trait that strips const from types to make it easier to implement a const-version of ...

static decltype(auto) castFailed()

static decltype(auto) doCastIfPossible(const From &f)

std::conditional_t< std::is_pointer_v< From >, DecayedFrom *, DecayedFrom & > NonConstFrom

static decltype(auto) doCast(const From &f)

static bool isPossible(const From &f)

std::remove_cv_t< std::remove_pointer_t< From > > DecayedFrom

This cast trait just provides the default implementation of doCastIfPossible to make CastInfo special...

static To doCastIfPossible(From f)

Provides a cast trait that uses a defined pointer to pointer cast as a base for reference-to-referenc...

static bool isPossible(const From &f)

static decltype(auto) doCast(const From &f)

All of these cast traits are meant to be implementations for useful casts that users may want to use ...

This cast trait provides std::optional casting.

static std::optional< To > doCast(const From &f)

static std::optional< To > castFailed()

This cast trait provides std::unique_ptr casting.

std::unique_ptr< std::remove_reference_t< typename cast_retty< To, From >::ret_type > > CastResultType

detail::SelfType< Derived, UniquePtrCast< To, From > > Self

static CastResultType doCast(std::unique_ptr< From > &&f)

static CastResultType doCastIfPossible(std::unique_ptr< From > &f)

static CastResultType castFailed()

This cast trait provides casting for the specific case of casting to a value-typed object from a poin...

static To doCast(From *f)

static decltype(auto) unwrapValue(T &t)

static bool isPresent(const T &t)

static decltype(auto) unwrapValue(std::optional< T > &t)

static bool isPresent(const std::optional< T > &t)

ValueIsPresent provides a way to check if a value is, well, present.

static bool isPresent(const T &t)

static decltype(auto) unwrapValue(T &t)

static cast_retty< To, FromTy >::ret_type doit(const FromTy &Val)

static cast_retty< To, FromTy * >::ret_type doit(const FromTy *Val)

static cast_retty< To, From >::ret_type doit(const From &Val)

std::unique_ptr< ResultType > ret_type

typename cast_retty_impl< To, FromTy >::ret_type ret_type

typename cast_retty< To, SimpleFrom >::ret_type ret_type

typename cast_retty_wrap< To, From, typename simplify_type< From >::SimpleType >::ret_type ret_type

bool operator()(const T &Val) const

bool operator()(const T &Val) const

static bool doit(const From &)

static bool doit(const From *Val)

static bool doit(const From *Val)

static bool doit(const From &Val)

static bool doit(const From *Val)

static bool doit(const From *Val)

static bool doit(const std::unique_ptr< From > &Val)

static bool doit(const From &Val)

static bool doit(const FromTy &Val)

static bool doit(const From &Val)

static bool doit(const From &Val)

typename add_const_past_pointer< NonConstSimpleType >::type SimpleType

typename add_lvalue_reference_if_not_pointer< SimpleType >::type RetType

typename simplify_type< From >::SimpleType NonConstSimpleType

static RetType getSimplifiedValue(const From &Val)

Define a template that can be specialized by smart pointers to reflect the fact that they are automat...

static SimpleType & getSimplifiedValue(From &Val)