File indexing completed on 2026-05-10 08:44:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_IR_OPERANDTRAITS_H
0015 #define LLVM_IR_OPERANDTRAITS_H
0016
0017 #include "llvm/IR/User.h"
0018
0019 namespace llvm {
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 template <typename SubClass, unsigned ARITY>
0030 struct FixedNumOperandTraits {
0031 static Use *op_begin(SubClass* U) {
0032 static_assert(
0033 !std::is_polymorphic<SubClass>::value,
0034 "adding virtual methods to subclasses of User breaks use lists");
0035 return reinterpret_cast<Use*>(U) - ARITY;
0036 }
0037 static Use *op_end(SubClass* U) {
0038 return reinterpret_cast<Use*>(U);
0039 }
0040 static unsigned operands(const User*) {
0041 return ARITY;
0042 }
0043 };
0044
0045
0046
0047
0048
0049
0050
0051
0052 template <typename SubClass, unsigned ARITY = 1>
0053 struct OptionalOperandTraits : public FixedNumOperandTraits<SubClass, ARITY> {
0054 static unsigned operands(const User *U) {
0055 return U->getNumOperands();
0056 }
0057 };
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 template <typename SubClass> struct VariadicOperandTraits {
0068 static Use *op_begin(SubClass* U) {
0069 static_assert(
0070 !std::is_polymorphic<SubClass>::value,
0071 "adding virtual methods to subclasses of User breaks use lists");
0072 return reinterpret_cast<Use*>(U) - static_cast<User*>(U)->getNumOperands();
0073 }
0074 static Use *op_end(SubClass* U) {
0075 return reinterpret_cast<Use*>(U);
0076 }
0077 static unsigned operands(const User *U) {
0078 return U->getNumOperands();
0079 }
0080 };
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093 struct HungoffOperandTraits {
0094 static Use *op_begin(User* U) {
0095 return U->getHungOffOperands();
0096 }
0097 static Use *op_end(User* U) {
0098 return U->getHungOffOperands() + U->getNumOperands();
0099 }
0100 static unsigned operands(const User *U) {
0101 return U->getNumOperands();
0102 }
0103 };
0104
0105
0106
0107
0108 #define DECLARE_TRANSPARENT_OPERAND_ACCESSORS(VALUECLASS) \
0109 public: \
0110 inline VALUECLASS *getOperand(unsigned) const; \
0111 inline void setOperand(unsigned, VALUECLASS*); \
0112 inline op_iterator op_begin(); \
0113 inline const_op_iterator op_begin() const; \
0114 inline op_iterator op_end(); \
0115 inline const_op_iterator op_end() const; \
0116 protected: \
0117 template <int> inline Use &Op(); \
0118 template <int> inline const Use &Op() const; \
0119 public: \
0120 inline unsigned getNumOperands() const
0121
0122
0123 #define DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CLASS, VALUECLASS) \
0124 CLASS::op_iterator CLASS::op_begin() { \
0125 return OperandTraits<CLASS>::op_begin(this); \
0126 } \
0127 CLASS::const_op_iterator CLASS::op_begin() const { \
0128 return OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this)); \
0129 } \
0130 CLASS::op_iterator CLASS::op_end() { \
0131 return OperandTraits<CLASS>::op_end(this); \
0132 } \
0133 CLASS::const_op_iterator CLASS::op_end() const { \
0134 return OperandTraits<CLASS>::op_end(const_cast<CLASS*>(this)); \
0135 } \
0136 VALUECLASS *CLASS::getOperand(unsigned i_nocapture) const { \
0137 assert(i_nocapture < OperandTraits<CLASS>::operands(this) \
0138 && "getOperand() out of range!"); \
0139 return cast_or_null<VALUECLASS>( \
0140 OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this))[i_nocapture].get()); \
0141 } \
0142 void CLASS::setOperand(unsigned i_nocapture, VALUECLASS *Val_nocapture) { \
0143 assert(i_nocapture < OperandTraits<CLASS>::operands(this) \
0144 && "setOperand() out of range!"); \
0145 OperandTraits<CLASS>::op_begin(this)[i_nocapture] = Val_nocapture; \
0146 } \
0147 unsigned CLASS::getNumOperands() const { \
0148 return OperandTraits<CLASS>::operands(this); \
0149 } \
0150 template <int Idx_nocapture> Use &CLASS::Op() { \
0151 return this->OpFrom<Idx_nocapture>(this); \
0152 } \
0153 template <int Idx_nocapture> const Use &CLASS::Op() const { \
0154 return this->OpFrom<Idx_nocapture>(this); \
0155 }
0156
0157
0158 }
0159
0160 #endif