LLVM API Documentation
00001 //===-- llvm/OperandTraits.h - OperandTraits class definition ---*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the traits classes that are handy for enforcing the correct 00011 // layout of various User subclasses. It also provides the means for accessing 00012 // the operands in the most efficient manner. 00013 // 00014 00015 #ifndef LLVM_IR_OPERANDTRAITS_H 00016 #define LLVM_IR_OPERANDTRAITS_H 00017 00018 #include "llvm/IR/User.h" 00019 00020 namespace llvm { 00021 00022 //===----------------------------------------------------------------------===// 00023 // FixedNumOperand Trait Class 00024 //===----------------------------------------------------------------------===// 00025 00026 /// FixedNumOperandTraits - determine the allocation regime of the Use array 00027 /// when it is a prefix to the User object, and the number of Use objects is 00028 /// known at compile time. 00029 00030 template <typename SubClass, unsigned ARITY> 00031 struct FixedNumOperandTraits { 00032 static Use *op_begin(SubClass* U) { 00033 return reinterpret_cast<Use*>(U) - ARITY; 00034 } 00035 static Use *op_end(SubClass* U) { 00036 return reinterpret_cast<Use*>(U); 00037 } 00038 static unsigned operands(const User*) { 00039 return ARITY; 00040 } 00041 }; 00042 00043 //===----------------------------------------------------------------------===// 00044 // OptionalOperand Trait Class 00045 //===----------------------------------------------------------------------===// 00046 00047 /// OptionalOperandTraits - when the number of operands may change at runtime. 00048 /// Naturally it may only decrease, because the allocations may not change. 00049 00050 template <typename SubClass, unsigned ARITY = 1> 00051 struct OptionalOperandTraits : public FixedNumOperandTraits<SubClass, ARITY> { 00052 static unsigned operands(const User *U) { 00053 return U->getNumOperands(); 00054 } 00055 }; 00056 00057 //===----------------------------------------------------------------------===// 00058 // VariadicOperand Trait Class 00059 //===----------------------------------------------------------------------===// 00060 00061 /// VariadicOperandTraits - determine the allocation regime of the Use array 00062 /// when it is a prefix to the User object, and the number of Use objects is 00063 /// only known at allocation time. 00064 00065 template <typename SubClass, unsigned MINARITY = 0> 00066 struct VariadicOperandTraits { 00067 static Use *op_begin(SubClass* U) { 00068 return reinterpret_cast<Use*>(U) - static_cast<User*>(U)->getNumOperands(); 00069 } 00070 static Use *op_end(SubClass* U) { 00071 return reinterpret_cast<Use*>(U); 00072 } 00073 static unsigned operands(const User *U) { 00074 return U->getNumOperands(); 00075 } 00076 }; 00077 00078 //===----------------------------------------------------------------------===// 00079 // HungoffOperand Trait Class 00080 //===----------------------------------------------------------------------===// 00081 00082 /// HungoffOperandTraits - determine the allocation regime of the Use array 00083 /// when it is not a prefix to the User object, but allocated at an unrelated 00084 /// heap address. 00085 /// Assumes that the User subclass that is determined by this traits class 00086 /// has an OperandList member of type User::op_iterator. [Note: this is now 00087 /// trivially satisfied, because User has that member for historic reasons.] 00088 /// 00089 /// This is the traits class that is needed when the Use array must be 00090 /// resizable. 00091 00092 template <unsigned MINARITY = 1> 00093 struct HungoffOperandTraits { 00094 static Use *op_begin(User* U) { 00095 return U->OperandList; 00096 } 00097 static Use *op_end(User* U) { 00098 return U->OperandList + U->getNumOperands(); 00099 } 00100 static unsigned operands(const User *U) { 00101 return U->getNumOperands(); 00102 } 00103 }; 00104 00105 /// Macro for generating in-class operand accessor declarations. 00106 /// It should only be called in the public section of the interface. 00107 /// 00108 #define DECLARE_TRANSPARENT_OPERAND_ACCESSORS(VALUECLASS) \ 00109 public: \ 00110 inline VALUECLASS *getOperand(unsigned) const; \ 00111 inline void setOperand(unsigned, VALUECLASS*); \ 00112 inline op_iterator op_begin(); \ 00113 inline const_op_iterator op_begin() const; \ 00114 inline op_iterator op_end(); \ 00115 inline const_op_iterator op_end() const; \ 00116 protected: \ 00117 template <int> inline Use &Op(); \ 00118 template <int> inline const Use &Op() const; \ 00119 public: \ 00120 inline unsigned getNumOperands() const 00121 00122 /// Macro for generating out-of-class operand accessor definitions 00123 #define DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CLASS, VALUECLASS) \ 00124 CLASS::op_iterator CLASS::op_begin() { \ 00125 return OperandTraits<CLASS>::op_begin(this); \ 00126 } \ 00127 CLASS::const_op_iterator CLASS::op_begin() const { \ 00128 return OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this)); \ 00129 } \ 00130 CLASS::op_iterator CLASS::op_end() { \ 00131 return OperandTraits<CLASS>::op_end(this); \ 00132 } \ 00133 CLASS::const_op_iterator CLASS::op_end() const { \ 00134 return OperandTraits<CLASS>::op_end(const_cast<CLASS*>(this)); \ 00135 } \ 00136 VALUECLASS *CLASS::getOperand(unsigned i_nocapture) const { \ 00137 assert(i_nocapture < OperandTraits<CLASS>::operands(this) \ 00138 && "getOperand() out of range!"); \ 00139 return cast_or_null<VALUECLASS>( \ 00140 OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this))[i_nocapture].get()); \ 00141 } \ 00142 void CLASS::setOperand(unsigned i_nocapture, VALUECLASS *Val_nocapture) { \ 00143 assert(i_nocapture < OperandTraits<CLASS>::operands(this) \ 00144 && "setOperand() out of range!"); \ 00145 OperandTraits<CLASS>::op_begin(this)[i_nocapture] = Val_nocapture; \ 00146 } \ 00147 unsigned CLASS::getNumOperands() const { \ 00148 return OperandTraits<CLASS>::operands(this); \ 00149 } \ 00150 template <int Idx_nocapture> Use &CLASS::Op() { \ 00151 return this->OpFrom<Idx_nocapture>(this); \ 00152 } \ 00153 template <int Idx_nocapture> const Use &CLASS::Op() const { \ 00154 return this->OpFrom<Idx_nocapture>(this); \ 00155 } 00156 00157 00158 } // End llvm namespace 00159 00160 #endif