1 //===-- llvm/OperandTraits.h - OperandTraits class definition ---------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the traits classes that are handy for enforcing the correct
11 // layout of various User subclasses. It also provides the means for accessing
12 // the operands in the most efficient manner.
15 #ifndef LLVM_OPERAND_TRAITS_H
16 #define LLVM_OPERAND_TRAITS_H
18 #include "llvm/User.h"
22 //===----------------------------------------------------------------------===//
23 // FixedNumOperands Trait Class
24 //===----------------------------------------------------------------------===//
26 template <unsigned ARITY>
27 struct FixedNumOperandTraits {
28 static Use *op_begin(User* U) {
29 return reinterpret_cast<Use*>(U) - ARITY;
31 static Use *op_end(User* U) {
32 return reinterpret_cast<Use*>(U);
34 static unsigned operands(const User*) {
39 prefix(); // DO NOT IMPLEMENT
43 struct overlay : prefix, U {
44 overlay(); // DO NOT IMPLEMENT
47 static inline void *allocate(unsigned); // FIXME
50 //===----------------------------------------------------------------------===//
51 // OptionalOperands Trait Class
52 //===----------------------------------------------------------------------===//
54 template <unsigned ARITY = 1>
55 struct OptionalOperandTraits : FixedNumOperandTraits<ARITY> {
56 static unsigned operands(const User *U) {
57 return U->getNumOperands();
61 //===----------------------------------------------------------------------===//
62 // VariadicOperand Trait Class
63 //===----------------------------------------------------------------------===//
65 template <unsigned MINARITY = 0>
66 struct VariadicOperandTraits {
67 static Use *op_begin(User* U) {
68 return reinterpret_cast<Use*>(U) - U->getNumOperands();
70 static Use *op_end(User* U) {
71 return reinterpret_cast<Use*>(U);
73 static unsigned operands(const User *U) {
74 return U->getNumOperands();
76 static inline void *allocate(unsigned); // FIXME
79 //===----------------------------------------------------------------------===//
80 // HungoffOperand Trait Class
81 //===----------------------------------------------------------------------===//
83 template <unsigned MINARITY = 1>
84 struct HungoffOperandTraits {
85 static Use *op_begin(User* U) {
86 return U->OperandList;
88 static Use *op_end(User* U) {
89 return U->OperandList + U->getNumOperands();
91 static unsigned operands(const User *U) {
92 return U->getNumOperands();
94 static inline void *allocate(unsigned); // FIXME
97 /// Macro for generating in-class operand accessor declarations.
98 /// It should only be called in the public section of the interface.
100 #define DECLARE_TRANSPARENT_OPERAND_ACCESSORS(VALUECLASS) \
102 inline VALUECLASS *getOperand(unsigned) const; \
103 inline void setOperand(unsigned, VALUECLASS*); \
105 template <unsigned> inline Use &Op(); \
106 template <unsigned> inline const Use &Op() const; \
108 inline unsigned getNumOperands() const
110 /// Macro for generating out-of-class operand accessor definitions
111 #define DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CLASS, VALUECLASS) \
112 VALUECLASS *CLASS::getOperand(unsigned i_nocapture) const { \
113 assert(i_nocapture < OperandTraits<CLASS>::operands(this) \
114 && "getOperand() out of range!"); \
115 return static_cast<VALUECLASS*>( \
116 OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this))[i_nocapture]); \
118 void CLASS::setOperand(unsigned i_nocapture, VALUECLASS *Val_nocapture) { \
119 assert(i_nocapture < OperandTraits<CLASS>::operands(this) \
120 && "setOperand() out of range!"); \
121 OperandTraits<CLASS>::op_begin(this)[i_nocapture] = Val_nocapture; \
123 unsigned CLASS::getNumOperands() const { \
124 return OperandTraits<CLASS>::operands(this); \
126 template <unsigned Idx_nocapture> Use &CLASS::Op() { \
127 return OperandTraits<CLASS>::op_begin(this)[Idx_nocapture]; \
129 template <unsigned Idx_nocapture> const Use &CLASS::Op() const { \
130 return OperandTraits<CLASS>::op_begin( \
131 const_cast<CLASS*>(this))[Idx_nocapture]; \
135 /// Macro for generating out-of-class operand accessor
136 /// definitions with casted result
137 #define DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(CLASS, VALUECLASS) \
138 VALUECLASS *CLASS::getOperand(unsigned i_nocapture) const { \
139 assert(i_nocapture < OperandTraits<CLASS>::operands(this) \
140 && "getOperand() out of range!"); \
141 return cast<VALUECLASS>( \
142 OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this))[i_nocapture]); \
144 void CLASS::setOperand(unsigned i_nocapture, VALUECLASS *Val_nocapture) { \
145 assert(i_nocapture < OperandTraits<CLASS>::operands(this) \
146 && "setOperand() out of range!"); \
147 OperandTraits<CLASS>::op_begin(this)[i_nocapture] = Val_nocapture; \
149 unsigned CLASS::getNumOperands() const { \
150 return OperandTraits<CLASS>::operands(this); \
152 template <unsigned Idx_nocapture> Use &CLASS::Op() { \
153 return OperandTraits<CLASS>::op_begin(this)[Idx_nocapture]; \
155 template <unsigned Idx_nocapture> const Use &CLASS::Op() const { \
156 return OperandTraits<CLASS>::op_begin( \
157 const_cast<CLASS*>(this))[Idx_nocapture]; \
161 } // End llvm namespace