CGValue.h revision 198092
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 20namespace llvm { 21 class Constant; 22 class Value; 23} 24 25namespace clang { 26 class ObjCPropertyRefExpr; 27 class ObjCImplicitSetterGetterRefExpr; 28 29namespace 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. 35class 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; 42public: 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. 107class 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 llvm::Value *V; 122 123 union { 124 // Index into a vector subscript: V[i] 125 llvm::Value *VectorIdx; 126 127 // ExtVector element subset: V.xyx 128 llvm::Constant *VectorElts; 129 130 // BitField start bit and size 131 struct { 132 unsigned short StartBit; 133 unsigned short Size; 134 bool IsSigned; 135 } BitfieldData; 136 137 // Obj-C property reference expression 138 const ObjCPropertyRefExpr *PropertyRefExpr; 139 // ObjC 'implicit' property reference expression 140 const ObjCImplicitSetterGetterRefExpr *KVCRefExpr; 141 }; 142 143 // 'const' is unused here 144 Qualifiers Quals; 145 146 // objective-c's ivar 147 bool Ivar:1; 148 149 // objective-c's ivar is an array 150 bool ObjIsArray:1; 151 152 // LValue is non-gc'able for any reason, including being a parameter or local 153 // variable. 154 bool NonGC: 1; 155 156 // Lvalue is a global reference of an objective-c object 157 bool GlobalObjCRef : 1; 158 159 Expr *BaseIvarExp; 160private: 161 void SetQualifiers(Qualifiers Quals) { 162 this->Quals = Quals; 163 164 // FIXME: Convenient place to set objc flags to 0. This should really be 165 // done in a user-defined constructor instead. 166 this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false; 167 this->BaseIvarExp = 0; 168 } 169 170public: 171 bool isSimple() const { return LVType == Simple; } 172 bool isVectorElt() const { return LVType == VectorElt; } 173 bool isBitfield() const { return LVType == BitField; } 174 bool isExtVectorElt() const { return LVType == ExtVectorElt; } 175 bool isPropertyRef() const { return LVType == PropertyRef; } 176 bool isKVCRef() const { return LVType == KVCRef; } 177 178 bool isVolatileQualified() const { return Quals.hasVolatile(); } 179 bool isRestrictQualified() const { return Quals.hasRestrict(); } 180 unsigned getVRQualifiers() const { 181 return Quals.getCVRQualifiers() & ~Qualifiers::Const; 182 } 183 184 bool isObjCIvar() const { return Ivar; } 185 bool isObjCArray() const { return ObjIsArray; } 186 bool isNonGC () const { return NonGC; } 187 bool isGlobalObjCRef() const { return GlobalObjCRef; } 188 bool isObjCWeak() const { return Quals.getObjCGCAttr() == Qualifiers::Weak; } 189 bool isObjCStrong() const { return Quals.getObjCGCAttr() == Qualifiers::Strong; } 190 191 Expr *getBaseIvarExp() const { return BaseIvarExp; } 192 void setBaseIvarExp(Expr *V) { BaseIvarExp = V; } 193 194 unsigned getAddressSpace() const { return Quals.getAddressSpace(); } 195 196 static void SetObjCIvar(LValue& R, bool iValue) { 197 R.Ivar = iValue; 198 } 199 static void SetObjCArray(LValue& R, bool iValue) { 200 R.ObjIsArray = iValue; 201 } 202 static void SetGlobalObjCRef(LValue& R, bool iValue) { 203 R.GlobalObjCRef = iValue; 204 } 205 206 static void SetObjCNonGC(LValue& R, bool iValue) { 207 R.NonGC = iValue; 208 } 209 210 // simple lvalue 211 llvm::Value *getAddress() const { assert(isSimple()); return V; } 212 // vector elt lvalue 213 llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; } 214 llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; } 215 // extended vector elements. 216 llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; } 217 llvm::Constant *getExtVectorElts() const { 218 assert(isExtVectorElt()); 219 return VectorElts; 220 } 221 // bitfield lvalue 222 llvm::Value *getBitfieldAddr() const { assert(isBitfield()); return V; } 223 unsigned short getBitfieldStartBit() const { 224 assert(isBitfield()); 225 return BitfieldData.StartBit; 226 } 227 unsigned short getBitfieldSize() const { 228 assert(isBitfield()); 229 return BitfieldData.Size; 230 } 231 bool isBitfieldSigned() const { 232 assert(isBitfield()); 233 return BitfieldData.IsSigned; 234 } 235 // property ref lvalue 236 const ObjCPropertyRefExpr *getPropertyRefExpr() const { 237 assert(isPropertyRef()); 238 return PropertyRefExpr; 239 } 240 241 // 'implicit' property ref lvalue 242 const ObjCImplicitSetterGetterRefExpr *getKVCRefExpr() const { 243 assert(isKVCRef()); 244 return KVCRefExpr; 245 } 246 247 static LValue MakeAddr(llvm::Value *V, Qualifiers Quals) { 248 LValue R; 249 R.LVType = Simple; 250 R.V = V; 251 R.SetQualifiers(Quals); 252 return R; 253 } 254 255 static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx, 256 unsigned CVR) { 257 LValue R; 258 R.LVType = VectorElt; 259 R.V = Vec; 260 R.VectorIdx = Idx; 261 R.SetQualifiers(Qualifiers::fromCVRMask(CVR)); 262 return R; 263 } 264 265 static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts, 266 unsigned CVR) { 267 LValue R; 268 R.LVType = ExtVectorElt; 269 R.V = Vec; 270 R.VectorElts = Elts; 271 R.SetQualifiers(Qualifiers::fromCVRMask(CVR)); 272 return R; 273 } 274 275 static LValue MakeBitfield(llvm::Value *V, unsigned short StartBit, 276 unsigned short Size, bool IsSigned, 277 unsigned CVR) { 278 LValue R; 279 R.LVType = BitField; 280 R.V = V; 281 R.BitfieldData.StartBit = StartBit; 282 R.BitfieldData.Size = Size; 283 R.BitfieldData.IsSigned = IsSigned; 284 R.SetQualifiers(Qualifiers::fromCVRMask(CVR)); 285 return R; 286 } 287 288 // FIXME: It is probably bad that we aren't emitting the target when we build 289 // the lvalue. However, this complicates the code a bit, and I haven't figured 290 // out how to make it go wrong yet. 291 static LValue MakePropertyRef(const ObjCPropertyRefExpr *E, 292 unsigned CVR) { 293 LValue R; 294 R.LVType = PropertyRef; 295 R.PropertyRefExpr = E; 296 R.SetQualifiers(Qualifiers::fromCVRMask(CVR)); 297 return R; 298 } 299 300 static LValue MakeKVCRef(const ObjCImplicitSetterGetterRefExpr *E, 301 unsigned CVR) { 302 LValue R; 303 R.LVType = KVCRef; 304 R.KVCRefExpr = E; 305 R.SetQualifiers(Qualifiers::fromCVRMask(CVR)); 306 return R; 307 } 308}; 309 310} // end namespace CodeGen 311} // end namespace clang 312 313#endif 314