File indexing completed on 2026-05-10 08:44:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_IR_VALUE_H
0014 #define LLVM_IR_VALUE_H
0015
0016 #include "llvm-c/Types.h"
0017 #include "llvm/ADT/STLExtras.h"
0018 #include "llvm/ADT/StringRef.h"
0019 #include "llvm/ADT/iterator_range.h"
0020 #include "llvm/IR/Use.h"
0021 #include "llvm/Support/Alignment.h"
0022 #include "llvm/Support/CBindingWrapping.h"
0023 #include "llvm/Support/Casting.h"
0024 #include <cassert>
0025 #include <iterator>
0026 #include <memory>
0027
0028 namespace llvm {
0029
0030 class APInt;
0031 class Argument;
0032 class BasicBlock;
0033 class Constant;
0034 class ConstantData;
0035 class ConstantAggregate;
0036 class DataLayout;
0037 class Function;
0038 class GlobalAlias;
0039 class GlobalIFunc;
0040 class GlobalObject;
0041 class GlobalValue;
0042 class GlobalVariable;
0043 class InlineAsm;
0044 class Instruction;
0045 class LLVMContext;
0046 class MDNode;
0047 class Module;
0048 class ModuleSlotTracker;
0049 class raw_ostream;
0050 template<typename ValueTy> class StringMapEntry;
0051 class Twine;
0052 class Type;
0053 class User;
0054
0055 using ValueName = StringMapEntry<Value *>;
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 class Value {
0075 const unsigned char SubclassID;
0076 unsigned char HasValueHandle : 1;
0077
0078 protected:
0079
0080
0081
0082
0083
0084 unsigned char SubclassOptionalData : 7;
0085
0086 private:
0087
0088
0089
0090
0091
0092 unsigned short SubclassData;
0093
0094 protected:
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107 enum : unsigned { NumUserOperandsBits = 27 };
0108 unsigned NumUserOperands : NumUserOperandsBits;
0109
0110
0111 unsigned IsUsedByMD : 1;
0112 unsigned HasName : 1;
0113 unsigned HasMetadata : 1;
0114 unsigned HasHungOffUses : 1;
0115 unsigned HasDescriptor : 1;
0116
0117 private:
0118 Type *VTy;
0119 Use *UseList;
0120
0121 friend class ValueAsMetadata;
0122 friend class ValueHandleBase;
0123
0124 template <typename UseT>
0125 class use_iterator_impl {
0126 friend class Value;
0127
0128 UseT *U;
0129
0130 explicit use_iterator_impl(UseT *u) : U(u) {}
0131
0132 public:
0133 using iterator_category = std::forward_iterator_tag;
0134 using value_type = UseT;
0135 using difference_type = std::ptrdiff_t;
0136 using pointer = value_type *;
0137 using reference = value_type &;
0138
0139 use_iterator_impl() : U() {}
0140
0141 bool operator==(const use_iterator_impl &x) const { return U == x.U; }
0142 bool operator!=(const use_iterator_impl &x) const { return !operator==(x); }
0143
0144 use_iterator_impl &operator++() {
0145 assert(U && "Cannot increment end iterator!");
0146 U = U->getNext();
0147 return *this;
0148 }
0149
0150 use_iterator_impl operator++(int) {
0151 auto tmp = *this;
0152 ++*this;
0153 return tmp;
0154 }
0155
0156 UseT &operator*() const {
0157 assert(U && "Cannot dereference end iterator!");
0158 return *U;
0159 }
0160
0161 UseT *operator->() const { return &operator*(); }
0162
0163 operator use_iterator_impl<const UseT>() const {
0164 return use_iterator_impl<const UseT>(U);
0165 }
0166 };
0167
0168 template <typename UserTy>
0169 class user_iterator_impl {
0170 use_iterator_impl<Use> UI;
0171 explicit user_iterator_impl(Use *U) : UI(U) {}
0172 friend class Value;
0173
0174 public:
0175 using iterator_category = std::forward_iterator_tag;
0176 using value_type = UserTy *;
0177 using difference_type = std::ptrdiff_t;
0178 using pointer = value_type *;
0179 using reference = value_type &;
0180
0181 user_iterator_impl() = default;
0182
0183 bool operator==(const user_iterator_impl &x) const { return UI == x.UI; }
0184 bool operator!=(const user_iterator_impl &x) const { return !operator==(x); }
0185
0186
0187 bool atEnd() const { return *this == user_iterator_impl(); }
0188
0189 user_iterator_impl &operator++() {
0190 ++UI;
0191 return *this;
0192 }
0193
0194 user_iterator_impl operator++(int) {
0195 auto tmp = *this;
0196 ++*this;
0197 return tmp;
0198 }
0199
0200
0201 UserTy *operator*() const {
0202 return UI->getUser();
0203 }
0204
0205 UserTy *operator->() const { return operator*(); }
0206
0207 operator user_iterator_impl<const UserTy>() const {
0208 return user_iterator_impl<const UserTy>(*UI);
0209 }
0210
0211 Use &getUse() const { return *UI; }
0212 };
0213
0214 protected:
0215 Value(Type *Ty, unsigned scid);
0216
0217
0218
0219
0220
0221
0222 ~Value();
0223
0224 public:
0225 Value(const Value &) = delete;
0226 Value &operator=(const Value &) = delete;
0227
0228
0229 void deleteValue();
0230
0231
0232 void dump() const;
0233
0234
0235
0236 void print(raw_ostream &O, bool IsForDebug = false) const;
0237 void print(raw_ostream &O, ModuleSlotTracker &MST,
0238 bool IsForDebug = false) const;
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248 void printAsOperand(raw_ostream &O, bool PrintType = true,
0249 const Module *M = nullptr) const;
0250 void printAsOperand(raw_ostream &O, bool PrintType,
0251 ModuleSlotTracker &MST) const;
0252
0253
0254
0255 Type *getType() const { return VTy; }
0256
0257
0258 LLVMContext &getContext() const;
0259
0260
0261 bool hasName() const { return HasName; }
0262 ValueName *getValueName() const;
0263 void setValueName(ValueName *VN);
0264
0265 private:
0266 void destroyValueName();
0267 enum class ReplaceMetadataUses { No, Yes };
0268 void doRAUW(Value *New, ReplaceMetadataUses);
0269 void setNameImpl(const Twine &Name);
0270
0271 public:
0272
0273
0274
0275
0276
0277 StringRef getName() const;
0278
0279
0280
0281
0282
0283
0284 void setName(const Twine &Name);
0285
0286
0287
0288
0289
0290
0291 void takeName(Value *V);
0292
0293 #ifndef NDEBUG
0294 std::string getNameOrAsOperand() const;
0295 #endif
0296
0297
0298
0299
0300
0301
0302 void replaceAllUsesWith(Value *V);
0303
0304
0305
0306
0307
0308 void replaceNonMetadataUsesWith(Value *V);
0309
0310
0311
0312
0313
0314 void replaceUsesWithIf(Value *New,
0315 llvm::function_ref<bool(Use &U)> ShouldReplace);
0316
0317
0318
0319
0320
0321
0322 void replaceUsesOutsideBlock(Value *V, BasicBlock *BB);
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334 void assertModuleIsMaterializedImpl() const;
0335
0336
0337
0338 void assertModuleIsMaterialized() const {
0339 #ifndef NDEBUG
0340 assertModuleIsMaterializedImpl();
0341 #endif
0342 }
0343
0344 bool use_empty() const {
0345 assertModuleIsMaterialized();
0346 return UseList == nullptr;
0347 }
0348
0349 bool materialized_use_empty() const {
0350 return UseList == nullptr;
0351 }
0352
0353 using use_iterator = use_iterator_impl<Use>;
0354 using const_use_iterator = use_iterator_impl<const Use>;
0355
0356 use_iterator materialized_use_begin() { return use_iterator(UseList); }
0357 const_use_iterator materialized_use_begin() const {
0358 return const_use_iterator(UseList);
0359 }
0360 use_iterator use_begin() {
0361 assertModuleIsMaterialized();
0362 return materialized_use_begin();
0363 }
0364 const_use_iterator use_begin() const {
0365 assertModuleIsMaterialized();
0366 return materialized_use_begin();
0367 }
0368 use_iterator use_end() { return use_iterator(); }
0369 const_use_iterator use_end() const { return const_use_iterator(); }
0370 iterator_range<use_iterator> materialized_uses() {
0371 return make_range(materialized_use_begin(), use_end());
0372 }
0373 iterator_range<const_use_iterator> materialized_uses() const {
0374 return make_range(materialized_use_begin(), use_end());
0375 }
0376 iterator_range<use_iterator> uses() {
0377 assertModuleIsMaterialized();
0378 return materialized_uses();
0379 }
0380 iterator_range<const_use_iterator> uses() const {
0381 assertModuleIsMaterialized();
0382 return materialized_uses();
0383 }
0384
0385 bool user_empty() const {
0386 assertModuleIsMaterialized();
0387 return UseList == nullptr;
0388 }
0389
0390 using user_iterator = user_iterator_impl<User>;
0391 using const_user_iterator = user_iterator_impl<const User>;
0392
0393 user_iterator materialized_user_begin() { return user_iterator(UseList); }
0394 const_user_iterator materialized_user_begin() const {
0395 return const_user_iterator(UseList);
0396 }
0397 user_iterator user_begin() {
0398 assertModuleIsMaterialized();
0399 return materialized_user_begin();
0400 }
0401 const_user_iterator user_begin() const {
0402 assertModuleIsMaterialized();
0403 return materialized_user_begin();
0404 }
0405 user_iterator user_end() { return user_iterator(); }
0406 const_user_iterator user_end() const { return const_user_iterator(); }
0407 User *user_back() {
0408 assertModuleIsMaterialized();
0409 return *materialized_user_begin();
0410 }
0411 const User *user_back() const {
0412 assertModuleIsMaterialized();
0413 return *materialized_user_begin();
0414 }
0415 iterator_range<user_iterator> materialized_users() {
0416 return make_range(materialized_user_begin(), user_end());
0417 }
0418 iterator_range<const_user_iterator> materialized_users() const {
0419 return make_range(materialized_user_begin(), user_end());
0420 }
0421 iterator_range<user_iterator> users() {
0422 assertModuleIsMaterialized();
0423 return materialized_users();
0424 }
0425 iterator_range<const_user_iterator> users() const {
0426 assertModuleIsMaterialized();
0427 return materialized_users();
0428 }
0429
0430
0431
0432
0433
0434 bool hasOneUse() const { return hasSingleElement(uses()); }
0435
0436
0437 bool hasNUses(unsigned N) const;
0438
0439
0440
0441
0442 bool hasNUsesOrMore(unsigned N) const;
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452 bool hasOneUser() const;
0453
0454
0455
0456 Use *getSingleUndroppableUse();
0457 const Use *getSingleUndroppableUse() const {
0458 return const_cast<Value *>(this)->getSingleUndroppableUse();
0459 }
0460
0461
0462
0463 User *getUniqueUndroppableUser();
0464 const User *getUniqueUndroppableUser() const {
0465 return const_cast<Value *>(this)->getUniqueUndroppableUser();
0466 }
0467
0468
0469
0470
0471
0472 bool hasNUndroppableUses(unsigned N) const;
0473
0474
0475
0476
0477 bool hasNUndroppableUsesOrMore(unsigned N) const;
0478
0479
0480
0481
0482
0483
0484
0485
0486 void dropDroppableUses(llvm::function_ref<bool(const Use *)> ShouldDrop =
0487 [](const Use *) { return true; });
0488
0489
0490 void dropDroppableUsesIn(User &Usr);
0491
0492
0493 static void dropDroppableUse(Use &U);
0494
0495
0496 bool isUsedInBasicBlock(const BasicBlock *BB) const;
0497
0498
0499
0500
0501
0502 unsigned getNumUses() const;
0503
0504
0505 void addUse(Use &U) { U.addToList(&UseList); }
0506
0507
0508
0509
0510
0511
0512
0513 enum ValueTy {
0514 #define HANDLE_VALUE(Name) Name##Val,
0515 #include "llvm/IR/Value.def"
0516
0517
0518 #define HANDLE_CONSTANT_MARKER(Marker, Constant) Marker = Constant##Val,
0519 #include "llvm/IR/Value.def"
0520 };
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532 unsigned getValueID() const {
0533 return SubclassID;
0534 }
0535
0536
0537
0538
0539 unsigned getRawSubclassOptionalData() const {
0540 return SubclassOptionalData;
0541 }
0542
0543
0544 void clearSubclassOptionalData() {
0545 SubclassOptionalData = 0;
0546 }
0547
0548
0549 bool hasSameSubclassOptionalData(const Value *V) const {
0550 return SubclassOptionalData == V->SubclassOptionalData;
0551 }
0552
0553
0554 bool hasValueHandle() const { return HasValueHandle; }
0555
0556
0557 bool isUsedByMetadata() const { return IsUsedByMD; }
0558
0559 protected:
0560
0561
0562
0563
0564
0565 MDNode *getMetadata(unsigned KindID) const {
0566 if (!HasMetadata)
0567 return nullptr;
0568 return getMetadataImpl(KindID);
0569 }
0570 MDNode *getMetadata(StringRef Kind) const;
0571
0572
0573
0574
0575
0576
0577 void getMetadata(unsigned KindID, SmallVectorImpl<MDNode *> &MDs) const;
0578 void getMetadata(StringRef Kind, SmallVectorImpl<MDNode *> &MDs) const;
0579
0580
0581
0582
0583
0584
0585 void
0586 getAllMetadata(SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const;
0587
0588
0589 bool hasMetadata() const { return (bool)HasMetadata; }
0590
0591
0592
0593 bool hasMetadata(unsigned KindID) const {
0594 return getMetadata(KindID) != nullptr;
0595 }
0596 bool hasMetadata(StringRef Kind) const {
0597 return getMetadata(Kind) != nullptr;
0598 }
0599
0600
0601
0602
0603
0604
0605
0606 void setMetadata(unsigned KindID, MDNode *Node);
0607 void setMetadata(StringRef Kind, MDNode *Node);
0608
0609
0610
0611
0612 void addMetadata(unsigned KindID, MDNode &MD);
0613 void addMetadata(StringRef Kind, MDNode &MD);
0614
0615
0616
0617
0618
0619 bool eraseMetadata(unsigned KindID);
0620
0621
0622 void eraseMetadataIf(function_ref<bool(unsigned, MDNode *)> Pred);
0623
0624
0625 void clearMetadata();
0626
0627
0628
0629
0630 MDNode *getMetadataImpl(unsigned KindID) const;
0631
0632 public:
0633
0634
0635
0636
0637 bool isSwiftError() const;
0638
0639
0640
0641
0642
0643 const Value *stripPointerCasts() const;
0644 Value *stripPointerCasts() {
0645 return const_cast<Value *>(
0646 static_cast<const Value *>(this)->stripPointerCasts());
0647 }
0648
0649
0650
0651
0652
0653 const Value *stripPointerCastsAndAliases() const;
0654 Value *stripPointerCastsAndAliases() {
0655 return const_cast<Value *>(
0656 static_cast<const Value *>(this)->stripPointerCastsAndAliases());
0657 }
0658
0659
0660
0661
0662
0663
0664 const Value *stripPointerCastsSameRepresentation() const;
0665 Value *stripPointerCastsSameRepresentation() {
0666 return const_cast<Value *>(static_cast<const Value *>(this)
0667 ->stripPointerCastsSameRepresentation());
0668 }
0669
0670
0671
0672
0673
0674
0675
0676 const Value *stripPointerCastsForAliasAnalysis() const;
0677 Value *stripPointerCastsForAliasAnalysis() {
0678 return const_cast<Value *>(static_cast<const Value *>(this)
0679 ->stripPointerCastsForAliasAnalysis());
0680 }
0681
0682
0683
0684
0685
0686 const Value *stripInBoundsConstantOffsets() const;
0687 Value *stripInBoundsConstantOffsets() {
0688 return const_cast<Value *>(
0689 static_cast<const Value *>(this)->stripInBoundsConstantOffsets());
0690 }
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720
0721 const Value *stripAndAccumulateConstantOffsets(
0722 const DataLayout &DL, APInt &Offset, bool AllowNonInbounds,
0723 bool AllowInvariantGroup = false,
0724 function_ref<bool(Value &Value, APInt &Offset)> ExternalAnalysis =
0725 nullptr) const;
0726
0727 Value *stripAndAccumulateConstantOffsets(
0728 const DataLayout &DL, APInt &Offset, bool AllowNonInbounds,
0729 bool AllowInvariantGroup = false,
0730 function_ref<bool(Value &Value, APInt &Offset)> ExternalAnalysis =
0731 nullptr) {
0732 return const_cast<Value *>(
0733 static_cast<const Value *>(this)->stripAndAccumulateConstantOffsets(
0734 DL, Offset, AllowNonInbounds, AllowInvariantGroup,
0735 ExternalAnalysis));
0736 }
0737
0738
0739
0740 const Value *stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL,
0741 APInt &Offset) const {
0742 return stripAndAccumulateConstantOffsets(DL, Offset,
0743 false);
0744 }
0745 Value *stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL,
0746 APInt &Offset) {
0747 return stripAndAccumulateConstantOffsets(DL, Offset,
0748 false);
0749 }
0750
0751
0752
0753
0754
0755 const Value *stripInBoundsOffsets(function_ref<void(const Value *)> Func =
0756 [](const Value *) {}) const;
0757 inline Value *stripInBoundsOffsets(function_ref<void(const Value *)> Func =
0758 [](const Value *) {}) {
0759 return const_cast<Value *>(
0760 static_cast<const Value *>(this)->stripInBoundsOffsets(Func));
0761 }
0762
0763
0764
0765 std::optional<int64_t> getPointerOffsetFrom(const Value *Other,
0766 const DataLayout &DL) const;
0767
0768
0769
0770
0771
0772 bool canBeFreed() const;
0773
0774
0775
0776
0777
0778
0779
0780
0781
0782
0783 uint64_t getPointerDereferenceableBytes(const DataLayout &DL,
0784 bool &CanBeNull,
0785 bool &CanBeFreed) const;
0786
0787
0788
0789
0790
0791 Align getPointerAlignment(const DataLayout &DL) const;
0792
0793
0794
0795
0796
0797
0798
0799 const Value *DoPHITranslation(const BasicBlock *CurBB,
0800 const BasicBlock *PredBB) const;
0801 Value *DoPHITranslation(const BasicBlock *CurBB, const BasicBlock *PredBB) {
0802 return const_cast<Value *>(
0803 static_cast<const Value *>(this)->DoPHITranslation(CurBB, PredBB));
0804 }
0805
0806
0807
0808
0809
0810 static constexpr unsigned MaxAlignmentExponent = 32;
0811 static constexpr uint64_t MaximumAlignment = 1ULL << MaxAlignmentExponent;
0812
0813
0814
0815
0816
0817
0818
0819 void mutateType(Type *Ty) {
0820 VTy = Ty;
0821 }
0822
0823
0824
0825
0826
0827 template <class Compare> void sortUseList(Compare Cmp);
0828
0829
0830 void reverseUseList();
0831
0832 private:
0833
0834
0835
0836
0837
0838
0839
0840
0841 template <class Compare>
0842 static Use *mergeUseLists(Use *L, Use *R, Compare Cmp) {
0843 Use *Merged;
0844 Use **Next = &Merged;
0845
0846 while (true) {
0847 if (!L) {
0848 *Next = R;
0849 break;
0850 }
0851 if (!R) {
0852 *Next = L;
0853 break;
0854 }
0855 if (Cmp(*R, *L)) {
0856 *Next = R;
0857 Next = &R->Next;
0858 R = R->Next;
0859 } else {
0860 *Next = L;
0861 Next = &L->Next;
0862 L = L->Next;
0863 }
0864 }
0865
0866 return Merged;
0867 }
0868
0869 protected:
0870 unsigned short getSubclassDataFromValue() const { return SubclassData; }
0871 void setValueSubclassData(unsigned short D) { SubclassData = D; }
0872 };
0873
0874 struct ValueDeleter { void operator()(Value *V) { V->deleteValue(); } };
0875
0876
0877
0878
0879 using unique_value = std::unique_ptr<Value, ValueDeleter>;
0880
0881 inline raw_ostream &operator<<(raw_ostream &OS, const Value &V) {
0882 V.print(OS);
0883 return OS;
0884 }
0885
0886 void Use::set(Value *V) {
0887 if (Val) removeFromList();
0888 Val = V;
0889 if (V) V->addUse(*this);
0890 }
0891
0892 Value *Use::operator=(Value *RHS) {
0893 set(RHS);
0894 return RHS;
0895 }
0896
0897 const Use &Use::operator=(const Use &RHS) {
0898 set(RHS.Val);
0899 return *this;
0900 }
0901
0902 template <class Compare> void Value::sortUseList(Compare Cmp) {
0903 if (!UseList || !UseList->Next)
0904
0905 return;
0906
0907
0908
0909
0910
0911
0912 const unsigned MaxSlots = 32;
0913 Use *Slots[MaxSlots];
0914
0915
0916 Use *Next = UseList->Next;
0917 UseList->Next = nullptr;
0918 unsigned NumSlots = 1;
0919 Slots[0] = UseList;
0920
0921
0922 while (Next->Next) {
0923 Use *Current = Next;
0924 Next = Current->Next;
0925
0926
0927 Current->Next = nullptr;
0928
0929
0930 unsigned I;
0931 for (I = 0; I < NumSlots; ++I) {
0932 if (!Slots[I])
0933 break;
0934
0935
0936
0937
0938
0939 Current = mergeUseLists(Slots[I], Current, Cmp);
0940 Slots[I] = nullptr;
0941 }
0942
0943 if (I == NumSlots) {
0944 ++NumSlots;
0945 assert(NumSlots <= MaxSlots && "Use list bigger than 2^32");
0946 }
0947
0948
0949 Slots[I] = Current;
0950 }
0951
0952
0953 assert(Next && "Expected one more Use");
0954 assert(!Next->Next && "Expected only one Use");
0955 UseList = Next;
0956 for (unsigned I = 0; I < NumSlots; ++I)
0957 if (Slots[I])
0958
0959
0960 UseList = mergeUseLists(Slots[I], UseList, Cmp);
0961
0962
0963 for (Use *I = UseList, **Prev = &UseList; I; I = I->Next) {
0964 I->Prev = Prev;
0965 Prev = &I->Next;
0966 }
0967 }
0968
0969
0970
0971
0972 template <> struct isa_impl<Constant, Value> {
0973 static inline bool doit(const Value &Val) {
0974 static_assert(Value::ConstantFirstVal == 0, "Val.getValueID() >= Value::ConstantFirstVal");
0975 return Val.getValueID() <= Value::ConstantLastVal;
0976 }
0977 };
0978
0979 template <> struct isa_impl<ConstantData, Value> {
0980 static inline bool doit(const Value &Val) {
0981 return Val.getValueID() >= Value::ConstantDataFirstVal &&
0982 Val.getValueID() <= Value::ConstantDataLastVal;
0983 }
0984 };
0985
0986 template <> struct isa_impl<ConstantAggregate, Value> {
0987 static inline bool doit(const Value &Val) {
0988 return Val.getValueID() >= Value::ConstantAggregateFirstVal &&
0989 Val.getValueID() <= Value::ConstantAggregateLastVal;
0990 }
0991 };
0992
0993 template <> struct isa_impl<Argument, Value> {
0994 static inline bool doit (const Value &Val) {
0995 return Val.getValueID() == Value::ArgumentVal;
0996 }
0997 };
0998
0999 template <> struct isa_impl<InlineAsm, Value> {
1000 static inline bool doit(const Value &Val) {
1001 return Val.getValueID() == Value::InlineAsmVal;
1002 }
1003 };
1004
1005 template <> struct isa_impl<Instruction, Value> {
1006 static inline bool doit(const Value &Val) {
1007 return Val.getValueID() >= Value::InstructionVal;
1008 }
1009 };
1010
1011 template <> struct isa_impl<BasicBlock, Value> {
1012 static inline bool doit(const Value &Val) {
1013 return Val.getValueID() == Value::BasicBlockVal;
1014 }
1015 };
1016
1017 template <> struct isa_impl<Function, Value> {
1018 static inline bool doit(const Value &Val) {
1019 return Val.getValueID() == Value::FunctionVal;
1020 }
1021 };
1022
1023 template <> struct isa_impl<GlobalVariable, Value> {
1024 static inline bool doit(const Value &Val) {
1025 return Val.getValueID() == Value::GlobalVariableVal;
1026 }
1027 };
1028
1029 template <> struct isa_impl<GlobalAlias, Value> {
1030 static inline bool doit(const Value &Val) {
1031 return Val.getValueID() == Value::GlobalAliasVal;
1032 }
1033 };
1034
1035 template <> struct isa_impl<GlobalIFunc, Value> {
1036 static inline bool doit(const Value &Val) {
1037 return Val.getValueID() == Value::GlobalIFuncVal;
1038 }
1039 };
1040
1041 template <> struct isa_impl<GlobalValue, Value> {
1042 static inline bool doit(const Value &Val) {
1043 return isa<GlobalObject>(Val) || isa<GlobalAlias>(Val);
1044 }
1045 };
1046
1047 template <> struct isa_impl<GlobalObject, Value> {
1048 static inline bool doit(const Value &Val) {
1049 return isa<GlobalVariable>(Val) || isa<Function>(Val) ||
1050 isa<GlobalIFunc>(Val);
1051 }
1052 };
1053
1054
1055 DEFINE_ISA_CONVERSION_FUNCTIONS(Value, LLVMValueRef)
1056
1057
1058 inline Value **unwrap(LLVMValueRef *Vals) {
1059 return reinterpret_cast<Value**>(Vals);
1060 }
1061
1062 template<typename T>
1063 inline T **unwrap(LLVMValueRef *Vals, unsigned Length) {
1064 #ifndef NDEBUG
1065 for (LLVMValueRef *I = Vals, *E = Vals + Length; I != E; ++I)
1066 unwrap<T>(*I);
1067 #endif
1068 (void)Length;
1069 return reinterpret_cast<T**>(Vals);
1070 }
1071
1072 inline LLVMValueRef *wrap(const Value **Vals) {
1073 return reinterpret_cast<LLVMValueRef*>(const_cast<Value**>(Vals));
1074 }
1075
1076 }
1077
1078 #endif