1 //===-- CGValue.h - LLVM CodeGen wrappers for llvm::Value* ------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // These classes implement wrappers around llvm::Value in order to 11 // fully represent the range of values for C L- and R- values. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef CLANG_CODEGEN_CGVALUE_H 16 #define CLANG_CODEGEN_CGVALUE_H 17 18 #include "clang/AST/Type.h" 19 20 namespace llvm { 21 class Constant; 22 class Value; 23 } 24 25 namespace clang { 26 class ObjCPropertyRefExpr; 27 class ObjCKVCRefExpr; 28 29 namespace CodeGen { 30 31 /// RValue - This trivial value class is used to represent the result of an 32 /// expression that is evaluated. It can be one of three things: either a 33 /// simple LLVM SSA value, a pair of SSA values for complex numbers, or the 34 /// address of an aggregate value in memory. 35 class RValue { 36 llvm::Value *V1, *V2; 37 // TODO: Encode this into the low bit of pointer for more efficient 38 // return-by-value. 39 enum { Scalar, Complex, Aggregate } Flavor; 40 41 bool Volatile:1; 42 public: 43 44 bool isScalar() const { return Flavor == Scalar; } 45 bool isComplex() const { return Flavor == Complex; } 46 bool isAggregate() const { return Flavor == Aggregate; } 47 48 bool isVolatileQualified() const { return Volatile; } 49 50 /// getScalar() - Return the Value* of this scalar value. 51 llvm::Value *getScalarVal() const { 52 assert(isScalar() && "Not a scalar!"); 53 return V1; 54 } 55 56 /// getComplexVal - Return the real/imag components of this complex value. 57 /// 58 std::pair<llvm::Value *, llvm::Value *> getComplexVal() const { 59 return std::pair<llvm::Value *, llvm::Value *>(V1, V2); 60 } 61 62 /// getAggregateAddr() - Return the Value* of the address of the aggregate. 63 llvm::Value *getAggregateAddr() const { 64 assert(isAggregate() && "Not an aggregate!"); 65 return V1; 66 } 67 68 static RValue get(llvm::Value *V) { 69 RValue ER; 70 ER.V1 = V; 71 ER.Flavor = Scalar; 72 ER.Volatile = false; 73 return ER; 74 } 75 static RValue getComplex(llvm::Value *V1, llvm::Value *V2) { 76 RValue ER; 77 ER.V1 = V1; 78 ER.V2 = V2; 79 ER.Flavor = Complex; 80 ER.Volatile = false; 81 return ER; 82 } 83 static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) { 84 RValue ER; 85 ER.V1 = C.first; 86 ER.V2 = C.second; 87 ER.Flavor = Complex; 88 ER.Volatile = false; 89 return ER; 90 } 91 // FIXME: Aggregate rvalues need to retain information about whether they are 92 // volatile or not. Remove default to find all places that probably get this 93 // wrong. 94 static RValue getAggregate(llvm::Value *V, bool Vol = false) { 95 RValue ER; 96 ER.V1 = V; 97 ER.Flavor = Aggregate; 98 ER.Volatile = Vol; 99 return ER; 100 } 101 }; 102 103 104 /// LValue - This represents an lvalue references. Because C/C++ allow 105 /// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a 106 /// bitrange. 107 class LValue { 108 // FIXME: alignment? 109 110 enum { 111 Simple, // This is a normal l-value, use getAddress(). 112 VectorElt, // This is a vector element l-value (V[i]), use getVector* 113 BitField, // This is a bitfield l-value, use getBitfield*. 114 ExtVectorElt, // This is an extended vector subset, use getExtVectorComp 115 PropertyRef, // This is an Objective-C property reference, use 116 // getPropertyRefExpr 117 KVCRef // This is an objective-c 'implicit' property ref, 118 // use getKVCRefExpr 119 } LVType; 120 121 enum ObjCType { 122 None = 0, // object with no gc attribute. 123 Weak, // __weak object expression 124 Strong // __strong object expression 125 }; 126 127 llvm::Value *V; 128 129 union { 130 // Index into a vector subscript: V[i] 131 llvm::Value *VectorIdx; 132 133 // ExtVector element subset: V.xyx 134 llvm::Constant *VectorElts; 135 136 // BitField start bit and size 137 struct { 138 unsigned short StartBit; 139 unsigned short Size; 140 bool IsSigned; 141 } BitfieldData; 142 143 // Obj-C property reference expression 144 const ObjCPropertyRefExpr *PropertyRefExpr; 145 // ObjC 'implicit' property reference expression 146 const ObjCKVCRefExpr *KVCRefExpr; 147 }; 148 149 bool Volatile:1; 150 // FIXME: set but never used, what effect should it have? 151 bool Restrict:1; 152 153 // objective-c's ivar 154 bool Ivar:1; 155 156 // LValue is non-gc'able for any reason, including being a parameter or local 157 // variable. 158 bool NonGC: 1; 159 160 // Lvalue is a global reference of an objective-c object 161 bool GlobalObjCRef : 1; 162 163 // objective-c's gc attributes 164 unsigned ObjCType : 2; 165 166 // address space 167 unsigned AddressSpace; 168 169 private: 170 static void SetQualifiers(unsigned Qualifiers, LValue& R) { 171 R.Volatile = (Qualifiers&QualType::Volatile)!=0; 172 R.Restrict = (Qualifiers&QualType::Restrict)!=0; 173 // FIXME: Convenient place to set objc flags to 0. This should really be 174 // done in a user-defined constructor instead. 175 R.ObjCType = None; 176 R.Ivar = R.NonGC = R.GlobalObjCRef = false; 177 } 178 179 public: 180 bool isSimple() const { return LVType == Simple; } 181 bool isVectorElt() const { return LVType == VectorElt; } 182 bool isBitfield() const { return LVType == BitField; } 183 bool isExtVectorElt() const { return LVType == ExtVectorElt; } 184 bool isPropertyRef() const { return LVType == PropertyRef; } 185 bool isKVCRef() const { return LVType == KVCRef; } 186 187 bool isVolatileQualified() const { return Volatile; } 188 bool isRestrictQualified() const { return Restrict; } 189 unsigned getQualifiers() const { 190 return (Volatile ? QualType::Volatile : 0) | 191 (Restrict ? QualType::Restrict : 0); 192 } 193 194 bool isObjCIvar() const { return Ivar; } 195 bool isNonGC () const { return NonGC; } 196 bool isGlobalObjCRef() const { return GlobalObjCRef; } 197 bool isObjCWeak() const { return ObjCType == Weak; } 198 bool isObjCStrong() const { return ObjCType == Strong; } 199 200 unsigned getAddressSpace() const { return AddressSpace; } 201 202 static void SetObjCIvar(LValue& R, bool iValue) { 203 R.Ivar = iValue; 204 } 205 206 static void SetGlobalObjCRef(LValue& R, bool iValue) { 207 R.GlobalObjCRef = iValue; 208 } 209 210 static void SetObjCNonGC(LValue& R, bool iValue) { 211 R.NonGC = iValue; 212 } 213 static void SetObjCType(QualType::GCAttrTypes GCAttrs, LValue& R) { 214 if (GCAttrs == QualType::Weak) 215 R.ObjCType = Weak; 216 else if (GCAttrs == QualType::Strong) 217 R.ObjCType = Strong; 218 else 219 R.ObjCType = None; 220 } 221 222 // simple lvalue 223 llvm::Value *getAddress() const { assert(isSimple()); return V; } 224 // vector elt lvalue 225 llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; } 226 llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; } 227 // extended vector elements. 228 llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; } 229 llvm::Constant *getExtVectorElts() const { 230 assert(isExtVectorElt()); 231 return VectorElts; 232 } 233 // bitfield lvalue 234 llvm::Value *getBitfieldAddr() const { assert(isBitfield()); return V; } 235 unsigned short getBitfieldStartBit() const { 236 assert(isBitfield()); 237 return BitfieldData.StartBit; 238 } 239 unsigned short getBitfieldSize() const { 240 assert(isBitfield()); 241 return BitfieldData.Size; 242 } 243 bool isBitfieldSigned() const { 244 assert(isBitfield()); 245 return BitfieldData.IsSigned; 246 } 247 // property ref lvalue 248 const ObjCPropertyRefExpr *getPropertyRefExpr() const { 249 assert(isPropertyRef()); 250 return PropertyRefExpr; 251 } 252 253 // 'implicit' property ref lvalue 254 const ObjCKVCRefExpr *getKVCRefExpr() const { 255 assert(isKVCRef()); 256 return KVCRefExpr; 257 } 258 259 static LValue MakeAddr(llvm::Value *V, unsigned Qualifiers, 260 QualType::GCAttrTypes GCAttrs = QualType::GCNone, 261 unsigned AddressSpace = 0) { 262 LValue R; 263 R.LVType = Simple; 264 R.V = V; 265 SetQualifiers(Qualifiers,R); 266 R.AddressSpace = AddressSpace; 267 SetObjCType(GCAttrs, R); 268 return R; 269 } 270 271 static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx, 272 unsigned Qualifiers) { 273 LValue R; 274 R.LVType = VectorElt; 275 R.V = Vec; 276 R.VectorIdx = Idx; 277 SetQualifiers(Qualifiers,R); 278 return R; 279 } 280 281 static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts, 282 unsigned Qualifiers) { 283 LValue R; 284 R.LVType = ExtVectorElt; 285 R.V = Vec; 286 R.VectorElts = Elts; 287 SetQualifiers(Qualifiers,R); 288 return R; 289 } 290 291 static LValue MakeBitfield(llvm::Value *V, unsigned short StartBit, 292 unsigned short Size, bool IsSigned, 293 unsigned Qualifiers) { 294 LValue R; 295 R.LVType = BitField; 296 R.V = V; 297 R.BitfieldData.StartBit = StartBit; 298 R.BitfieldData.Size = Size; 299 R.BitfieldData.IsSigned = IsSigned; 300 SetQualifiers(Qualifiers,R); 301 return R; 302 } 303 304 // FIXME: It is probably bad that we aren't emitting the target when we build 305 // the lvalue. However, this complicates the code a bit, and I haven't figured 306 // out how to make it go wrong yet. 307 static LValue MakePropertyRef(const ObjCPropertyRefExpr *E, 308 unsigned Qualifiers) { 309 LValue R; 310 R.LVType = PropertyRef; 311 R.PropertyRefExpr = E; 312 SetQualifiers(Qualifiers,R); 313 return R; 314 } 315 316 static LValue MakeKVCRef(const ObjCKVCRefExpr *E, unsigned Qualifiers) { 317 LValue R; 318 R.LVType = KVCRef; 319 R.KVCRefExpr = E; 320 SetQualifiers(Qualifiers,R); 321 return R; 322 } 323 }; 324 325 } // end namespace CodeGen 326 } // end namespace clang 327 328 #endif 329