1*f4a2713aSLionel Sambuc //===-- CGValue.h - LLVM CodeGen wrappers for llvm::Value* ------*- C++ -*-===// 2*f4a2713aSLionel Sambuc // 3*f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure 4*f4a2713aSLionel Sambuc // 5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details. 7*f4a2713aSLionel Sambuc // 8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 9*f4a2713aSLionel Sambuc // 10*f4a2713aSLionel Sambuc // These classes implement wrappers around llvm::Value in order to 11*f4a2713aSLionel Sambuc // fully represent the range of values for C L- and R- values. 12*f4a2713aSLionel Sambuc // 13*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 14*f4a2713aSLionel Sambuc 15*f4a2713aSLionel Sambuc #ifndef CLANG_CODEGEN_CGVALUE_H 16*f4a2713aSLionel Sambuc #define CLANG_CODEGEN_CGVALUE_H 17*f4a2713aSLionel Sambuc 18*f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h" 19*f4a2713aSLionel Sambuc #include "clang/AST/CharUnits.h" 20*f4a2713aSLionel Sambuc #include "clang/AST/Type.h" 21*f4a2713aSLionel Sambuc #include "llvm/IR/Value.h" 22*f4a2713aSLionel Sambuc 23*f4a2713aSLionel Sambuc namespace llvm { 24*f4a2713aSLionel Sambuc class Constant; 25*f4a2713aSLionel Sambuc class MDNode; 26*f4a2713aSLionel Sambuc } 27*f4a2713aSLionel Sambuc 28*f4a2713aSLionel Sambuc namespace clang { 29*f4a2713aSLionel Sambuc namespace CodeGen { 30*f4a2713aSLionel Sambuc class AggValueSlot; 31*f4a2713aSLionel Sambuc struct CGBitFieldInfo; 32*f4a2713aSLionel Sambuc 33*f4a2713aSLionel Sambuc /// RValue - This trivial value class is used to represent the result of an 34*f4a2713aSLionel Sambuc /// expression that is evaluated. It can be one of three things: either a 35*f4a2713aSLionel Sambuc /// simple LLVM SSA value, a pair of SSA values for complex numbers, or the 36*f4a2713aSLionel Sambuc /// address of an aggregate value in memory. 37*f4a2713aSLionel Sambuc class RValue { 38*f4a2713aSLionel Sambuc enum Flavor { Scalar, Complex, Aggregate }; 39*f4a2713aSLionel Sambuc 40*f4a2713aSLionel Sambuc // Stores first value and flavor. 41*f4a2713aSLionel Sambuc llvm::PointerIntPair<llvm::Value *, 2, Flavor> V1; 42*f4a2713aSLionel Sambuc // Stores second value and volatility. 43*f4a2713aSLionel Sambuc llvm::PointerIntPair<llvm::Value *, 1, bool> V2; 44*f4a2713aSLionel Sambuc 45*f4a2713aSLionel Sambuc public: 46*f4a2713aSLionel Sambuc bool isScalar() const { return V1.getInt() == Scalar; } 47*f4a2713aSLionel Sambuc bool isComplex() const { return V1.getInt() == Complex; } 48*f4a2713aSLionel Sambuc bool isAggregate() const { return V1.getInt() == Aggregate; } 49*f4a2713aSLionel Sambuc 50*f4a2713aSLionel Sambuc bool isVolatileQualified() const { return V2.getInt(); } 51*f4a2713aSLionel Sambuc 52*f4a2713aSLionel Sambuc /// getScalarVal() - Return the Value* of this scalar value. 53*f4a2713aSLionel Sambuc llvm::Value *getScalarVal() const { 54*f4a2713aSLionel Sambuc assert(isScalar() && "Not a scalar!"); 55*f4a2713aSLionel Sambuc return V1.getPointer(); 56*f4a2713aSLionel Sambuc } 57*f4a2713aSLionel Sambuc 58*f4a2713aSLionel Sambuc /// getComplexVal - Return the real/imag components of this complex value. 59*f4a2713aSLionel Sambuc /// 60*f4a2713aSLionel Sambuc std::pair<llvm::Value *, llvm::Value *> getComplexVal() const { 61*f4a2713aSLionel Sambuc return std::make_pair(V1.getPointer(), V2.getPointer()); 62*f4a2713aSLionel Sambuc } 63*f4a2713aSLionel Sambuc 64*f4a2713aSLionel Sambuc /// getAggregateAddr() - Return the Value* of the address of the aggregate. 65*f4a2713aSLionel Sambuc llvm::Value *getAggregateAddr() const { 66*f4a2713aSLionel Sambuc assert(isAggregate() && "Not an aggregate!"); 67*f4a2713aSLionel Sambuc return V1.getPointer(); 68*f4a2713aSLionel Sambuc } 69*f4a2713aSLionel Sambuc 70*f4a2713aSLionel Sambuc static RValue get(llvm::Value *V) { 71*f4a2713aSLionel Sambuc RValue ER; 72*f4a2713aSLionel Sambuc ER.V1.setPointer(V); 73*f4a2713aSLionel Sambuc ER.V1.setInt(Scalar); 74*f4a2713aSLionel Sambuc ER.V2.setInt(false); 75*f4a2713aSLionel Sambuc return ER; 76*f4a2713aSLionel Sambuc } 77*f4a2713aSLionel Sambuc static RValue getComplex(llvm::Value *V1, llvm::Value *V2) { 78*f4a2713aSLionel Sambuc RValue ER; 79*f4a2713aSLionel Sambuc ER.V1.setPointer(V1); 80*f4a2713aSLionel Sambuc ER.V2.setPointer(V2); 81*f4a2713aSLionel Sambuc ER.V1.setInt(Complex); 82*f4a2713aSLionel Sambuc ER.V2.setInt(false); 83*f4a2713aSLionel Sambuc return ER; 84*f4a2713aSLionel Sambuc } 85*f4a2713aSLionel Sambuc static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) { 86*f4a2713aSLionel Sambuc return getComplex(C.first, C.second); 87*f4a2713aSLionel Sambuc } 88*f4a2713aSLionel Sambuc // FIXME: Aggregate rvalues need to retain information about whether they are 89*f4a2713aSLionel Sambuc // volatile or not. Remove default to find all places that probably get this 90*f4a2713aSLionel Sambuc // wrong. 91*f4a2713aSLionel Sambuc static RValue getAggregate(llvm::Value *V, bool Volatile = false) { 92*f4a2713aSLionel Sambuc RValue ER; 93*f4a2713aSLionel Sambuc ER.V1.setPointer(V); 94*f4a2713aSLionel Sambuc ER.V1.setInt(Aggregate); 95*f4a2713aSLionel Sambuc ER.V2.setInt(Volatile); 96*f4a2713aSLionel Sambuc return ER; 97*f4a2713aSLionel Sambuc } 98*f4a2713aSLionel Sambuc }; 99*f4a2713aSLionel Sambuc 100*f4a2713aSLionel Sambuc /// Does an ARC strong l-value have precise lifetime? 101*f4a2713aSLionel Sambuc enum ARCPreciseLifetime_t { 102*f4a2713aSLionel Sambuc ARCImpreciseLifetime, ARCPreciseLifetime 103*f4a2713aSLionel Sambuc }; 104*f4a2713aSLionel Sambuc 105*f4a2713aSLionel Sambuc /// LValue - This represents an lvalue references. Because C/C++ allow 106*f4a2713aSLionel Sambuc /// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a 107*f4a2713aSLionel Sambuc /// bitrange. 108*f4a2713aSLionel Sambuc class LValue { 109*f4a2713aSLionel Sambuc enum { 110*f4a2713aSLionel Sambuc Simple, // This is a normal l-value, use getAddress(). 111*f4a2713aSLionel Sambuc VectorElt, // This is a vector element l-value (V[i]), use getVector* 112*f4a2713aSLionel Sambuc BitField, // This is a bitfield l-value, use getBitfield*. 113*f4a2713aSLionel Sambuc ExtVectorElt // This is an extended vector subset, use getExtVectorComp 114*f4a2713aSLionel Sambuc } LVType; 115*f4a2713aSLionel Sambuc 116*f4a2713aSLionel Sambuc llvm::Value *V; 117*f4a2713aSLionel Sambuc 118*f4a2713aSLionel Sambuc union { 119*f4a2713aSLionel Sambuc // Index into a vector subscript: V[i] 120*f4a2713aSLionel Sambuc llvm::Value *VectorIdx; 121*f4a2713aSLionel Sambuc 122*f4a2713aSLionel Sambuc // ExtVector element subset: V.xyx 123*f4a2713aSLionel Sambuc llvm::Constant *VectorElts; 124*f4a2713aSLionel Sambuc 125*f4a2713aSLionel Sambuc // BitField start bit and size 126*f4a2713aSLionel Sambuc const CGBitFieldInfo *BitFieldInfo; 127*f4a2713aSLionel Sambuc }; 128*f4a2713aSLionel Sambuc 129*f4a2713aSLionel Sambuc QualType Type; 130*f4a2713aSLionel Sambuc 131*f4a2713aSLionel Sambuc // 'const' is unused here 132*f4a2713aSLionel Sambuc Qualifiers Quals; 133*f4a2713aSLionel Sambuc 134*f4a2713aSLionel Sambuc // The alignment to use when accessing this lvalue. (For vector elements, 135*f4a2713aSLionel Sambuc // this is the alignment of the whole vector.) 136*f4a2713aSLionel Sambuc int64_t Alignment; 137*f4a2713aSLionel Sambuc 138*f4a2713aSLionel Sambuc // objective-c's ivar 139*f4a2713aSLionel Sambuc bool Ivar:1; 140*f4a2713aSLionel Sambuc 141*f4a2713aSLionel Sambuc // objective-c's ivar is an array 142*f4a2713aSLionel Sambuc bool ObjIsArray:1; 143*f4a2713aSLionel Sambuc 144*f4a2713aSLionel Sambuc // LValue is non-gc'able for any reason, including being a parameter or local 145*f4a2713aSLionel Sambuc // variable. 146*f4a2713aSLionel Sambuc bool NonGC: 1; 147*f4a2713aSLionel Sambuc 148*f4a2713aSLionel Sambuc // Lvalue is a global reference of an objective-c object 149*f4a2713aSLionel Sambuc bool GlobalObjCRef : 1; 150*f4a2713aSLionel Sambuc 151*f4a2713aSLionel Sambuc // Lvalue is a thread local reference 152*f4a2713aSLionel Sambuc bool ThreadLocalRef : 1; 153*f4a2713aSLionel Sambuc 154*f4a2713aSLionel Sambuc // Lvalue has ARC imprecise lifetime. We store this inverted to try 155*f4a2713aSLionel Sambuc // to make the default bitfield pattern all-zeroes. 156*f4a2713aSLionel Sambuc bool ImpreciseLifetime : 1; 157*f4a2713aSLionel Sambuc 158*f4a2713aSLionel Sambuc Expr *BaseIvarExp; 159*f4a2713aSLionel Sambuc 160*f4a2713aSLionel Sambuc /// Used by struct-path-aware TBAA. 161*f4a2713aSLionel Sambuc QualType TBAABaseType; 162*f4a2713aSLionel Sambuc /// Offset relative to the base type. 163*f4a2713aSLionel Sambuc uint64_t TBAAOffset; 164*f4a2713aSLionel Sambuc 165*f4a2713aSLionel Sambuc /// TBAAInfo - TBAA information to attach to dereferences of this LValue. 166*f4a2713aSLionel Sambuc llvm::MDNode *TBAAInfo; 167*f4a2713aSLionel Sambuc 168*f4a2713aSLionel Sambuc private: 169*f4a2713aSLionel Sambuc void Initialize(QualType Type, Qualifiers Quals, 170*f4a2713aSLionel Sambuc CharUnits Alignment, 171*f4a2713aSLionel Sambuc llvm::MDNode *TBAAInfo = 0) { 172*f4a2713aSLionel Sambuc this->Type = Type; 173*f4a2713aSLionel Sambuc this->Quals = Quals; 174*f4a2713aSLionel Sambuc this->Alignment = Alignment.getQuantity(); 175*f4a2713aSLionel Sambuc assert(this->Alignment == Alignment.getQuantity() && 176*f4a2713aSLionel Sambuc "Alignment exceeds allowed max!"); 177*f4a2713aSLionel Sambuc 178*f4a2713aSLionel Sambuc // Initialize Objective-C flags. 179*f4a2713aSLionel Sambuc this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false; 180*f4a2713aSLionel Sambuc this->ImpreciseLifetime = false; 181*f4a2713aSLionel Sambuc this->ThreadLocalRef = false; 182*f4a2713aSLionel Sambuc this->BaseIvarExp = 0; 183*f4a2713aSLionel Sambuc 184*f4a2713aSLionel Sambuc // Initialize fields for TBAA. 185*f4a2713aSLionel Sambuc this->TBAABaseType = Type; 186*f4a2713aSLionel Sambuc this->TBAAOffset = 0; 187*f4a2713aSLionel Sambuc this->TBAAInfo = TBAAInfo; 188*f4a2713aSLionel Sambuc } 189*f4a2713aSLionel Sambuc 190*f4a2713aSLionel Sambuc public: 191*f4a2713aSLionel Sambuc bool isSimple() const { return LVType == Simple; } 192*f4a2713aSLionel Sambuc bool isVectorElt() const { return LVType == VectorElt; } 193*f4a2713aSLionel Sambuc bool isBitField() const { return LVType == BitField; } 194*f4a2713aSLionel Sambuc bool isExtVectorElt() const { return LVType == ExtVectorElt; } 195*f4a2713aSLionel Sambuc 196*f4a2713aSLionel Sambuc bool isVolatileQualified() const { return Quals.hasVolatile(); } 197*f4a2713aSLionel Sambuc bool isRestrictQualified() const { return Quals.hasRestrict(); } 198*f4a2713aSLionel Sambuc unsigned getVRQualifiers() const { 199*f4a2713aSLionel Sambuc return Quals.getCVRQualifiers() & ~Qualifiers::Const; 200*f4a2713aSLionel Sambuc } 201*f4a2713aSLionel Sambuc 202*f4a2713aSLionel Sambuc QualType getType() const { return Type; } 203*f4a2713aSLionel Sambuc 204*f4a2713aSLionel Sambuc Qualifiers::ObjCLifetime getObjCLifetime() const { 205*f4a2713aSLionel Sambuc return Quals.getObjCLifetime(); 206*f4a2713aSLionel Sambuc } 207*f4a2713aSLionel Sambuc 208*f4a2713aSLionel Sambuc bool isObjCIvar() const { return Ivar; } 209*f4a2713aSLionel Sambuc void setObjCIvar(bool Value) { Ivar = Value; } 210*f4a2713aSLionel Sambuc 211*f4a2713aSLionel Sambuc bool isObjCArray() const { return ObjIsArray; } 212*f4a2713aSLionel Sambuc void setObjCArray(bool Value) { ObjIsArray = Value; } 213*f4a2713aSLionel Sambuc 214*f4a2713aSLionel Sambuc bool isNonGC () const { return NonGC; } 215*f4a2713aSLionel Sambuc void setNonGC(bool Value) { NonGC = Value; } 216*f4a2713aSLionel Sambuc 217*f4a2713aSLionel Sambuc bool isGlobalObjCRef() const { return GlobalObjCRef; } 218*f4a2713aSLionel Sambuc void setGlobalObjCRef(bool Value) { GlobalObjCRef = Value; } 219*f4a2713aSLionel Sambuc 220*f4a2713aSLionel Sambuc bool isThreadLocalRef() const { return ThreadLocalRef; } 221*f4a2713aSLionel Sambuc void setThreadLocalRef(bool Value) { ThreadLocalRef = Value;} 222*f4a2713aSLionel Sambuc 223*f4a2713aSLionel Sambuc ARCPreciseLifetime_t isARCPreciseLifetime() const { 224*f4a2713aSLionel Sambuc return ARCPreciseLifetime_t(!ImpreciseLifetime); 225*f4a2713aSLionel Sambuc } 226*f4a2713aSLionel Sambuc void setARCPreciseLifetime(ARCPreciseLifetime_t value) { 227*f4a2713aSLionel Sambuc ImpreciseLifetime = (value == ARCImpreciseLifetime); 228*f4a2713aSLionel Sambuc } 229*f4a2713aSLionel Sambuc 230*f4a2713aSLionel Sambuc bool isObjCWeak() const { 231*f4a2713aSLionel Sambuc return Quals.getObjCGCAttr() == Qualifiers::Weak; 232*f4a2713aSLionel Sambuc } 233*f4a2713aSLionel Sambuc bool isObjCStrong() const { 234*f4a2713aSLionel Sambuc return Quals.getObjCGCAttr() == Qualifiers::Strong; 235*f4a2713aSLionel Sambuc } 236*f4a2713aSLionel Sambuc 237*f4a2713aSLionel Sambuc bool isVolatile() const { 238*f4a2713aSLionel Sambuc return Quals.hasVolatile(); 239*f4a2713aSLionel Sambuc } 240*f4a2713aSLionel Sambuc 241*f4a2713aSLionel Sambuc Expr *getBaseIvarExp() const { return BaseIvarExp; } 242*f4a2713aSLionel Sambuc void setBaseIvarExp(Expr *V) { BaseIvarExp = V; } 243*f4a2713aSLionel Sambuc 244*f4a2713aSLionel Sambuc QualType getTBAABaseType() const { return TBAABaseType; } 245*f4a2713aSLionel Sambuc void setTBAABaseType(QualType T) { TBAABaseType = T; } 246*f4a2713aSLionel Sambuc 247*f4a2713aSLionel Sambuc uint64_t getTBAAOffset() const { return TBAAOffset; } 248*f4a2713aSLionel Sambuc void setTBAAOffset(uint64_t O) { TBAAOffset = O; } 249*f4a2713aSLionel Sambuc 250*f4a2713aSLionel Sambuc llvm::MDNode *getTBAAInfo() const { return TBAAInfo; } 251*f4a2713aSLionel Sambuc void setTBAAInfo(llvm::MDNode *N) { TBAAInfo = N; } 252*f4a2713aSLionel Sambuc 253*f4a2713aSLionel Sambuc const Qualifiers &getQuals() const { return Quals; } 254*f4a2713aSLionel Sambuc Qualifiers &getQuals() { return Quals; } 255*f4a2713aSLionel Sambuc 256*f4a2713aSLionel Sambuc unsigned getAddressSpace() const { return Quals.getAddressSpace(); } 257*f4a2713aSLionel Sambuc 258*f4a2713aSLionel Sambuc CharUnits getAlignment() const { return CharUnits::fromQuantity(Alignment); } 259*f4a2713aSLionel Sambuc void setAlignment(CharUnits A) { Alignment = A.getQuantity(); } 260*f4a2713aSLionel Sambuc 261*f4a2713aSLionel Sambuc // simple lvalue 262*f4a2713aSLionel Sambuc llvm::Value *getAddress() const { assert(isSimple()); return V; } 263*f4a2713aSLionel Sambuc void setAddress(llvm::Value *address) { 264*f4a2713aSLionel Sambuc assert(isSimple()); 265*f4a2713aSLionel Sambuc V = address; 266*f4a2713aSLionel Sambuc } 267*f4a2713aSLionel Sambuc 268*f4a2713aSLionel Sambuc // vector elt lvalue 269*f4a2713aSLionel Sambuc llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; } 270*f4a2713aSLionel Sambuc llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; } 271*f4a2713aSLionel Sambuc 272*f4a2713aSLionel Sambuc // extended vector elements. 273*f4a2713aSLionel Sambuc llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; } 274*f4a2713aSLionel Sambuc llvm::Constant *getExtVectorElts() const { 275*f4a2713aSLionel Sambuc assert(isExtVectorElt()); 276*f4a2713aSLionel Sambuc return VectorElts; 277*f4a2713aSLionel Sambuc } 278*f4a2713aSLionel Sambuc 279*f4a2713aSLionel Sambuc // bitfield lvalue 280*f4a2713aSLionel Sambuc llvm::Value *getBitFieldAddr() const { 281*f4a2713aSLionel Sambuc assert(isBitField()); 282*f4a2713aSLionel Sambuc return V; 283*f4a2713aSLionel Sambuc } 284*f4a2713aSLionel Sambuc const CGBitFieldInfo &getBitFieldInfo() const { 285*f4a2713aSLionel Sambuc assert(isBitField()); 286*f4a2713aSLionel Sambuc return *BitFieldInfo; 287*f4a2713aSLionel Sambuc } 288*f4a2713aSLionel Sambuc 289*f4a2713aSLionel Sambuc static LValue MakeAddr(llvm::Value *address, QualType type, 290*f4a2713aSLionel Sambuc CharUnits alignment, ASTContext &Context, 291*f4a2713aSLionel Sambuc llvm::MDNode *TBAAInfo = 0) { 292*f4a2713aSLionel Sambuc Qualifiers qs = type.getQualifiers(); 293*f4a2713aSLionel Sambuc qs.setObjCGCAttr(Context.getObjCGCAttrKind(type)); 294*f4a2713aSLionel Sambuc 295*f4a2713aSLionel Sambuc LValue R; 296*f4a2713aSLionel Sambuc R.LVType = Simple; 297*f4a2713aSLionel Sambuc R.V = address; 298*f4a2713aSLionel Sambuc R.Initialize(type, qs, alignment, TBAAInfo); 299*f4a2713aSLionel Sambuc return R; 300*f4a2713aSLionel Sambuc } 301*f4a2713aSLionel Sambuc 302*f4a2713aSLionel Sambuc static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx, 303*f4a2713aSLionel Sambuc QualType type, CharUnits Alignment) { 304*f4a2713aSLionel Sambuc LValue R; 305*f4a2713aSLionel Sambuc R.LVType = VectorElt; 306*f4a2713aSLionel Sambuc R.V = Vec; 307*f4a2713aSLionel Sambuc R.VectorIdx = Idx; 308*f4a2713aSLionel Sambuc R.Initialize(type, type.getQualifiers(), Alignment); 309*f4a2713aSLionel Sambuc return R; 310*f4a2713aSLionel Sambuc } 311*f4a2713aSLionel Sambuc 312*f4a2713aSLionel Sambuc static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts, 313*f4a2713aSLionel Sambuc QualType type, CharUnits Alignment) { 314*f4a2713aSLionel Sambuc LValue R; 315*f4a2713aSLionel Sambuc R.LVType = ExtVectorElt; 316*f4a2713aSLionel Sambuc R.V = Vec; 317*f4a2713aSLionel Sambuc R.VectorElts = Elts; 318*f4a2713aSLionel Sambuc R.Initialize(type, type.getQualifiers(), Alignment); 319*f4a2713aSLionel Sambuc return R; 320*f4a2713aSLionel Sambuc } 321*f4a2713aSLionel Sambuc 322*f4a2713aSLionel Sambuc /// \brief Create a new object to represent a bit-field access. 323*f4a2713aSLionel Sambuc /// 324*f4a2713aSLionel Sambuc /// \param Addr - The base address of the bit-field sequence this 325*f4a2713aSLionel Sambuc /// bit-field refers to. 326*f4a2713aSLionel Sambuc /// \param Info - The information describing how to perform the bit-field 327*f4a2713aSLionel Sambuc /// access. 328*f4a2713aSLionel Sambuc static LValue MakeBitfield(llvm::Value *Addr, 329*f4a2713aSLionel Sambuc const CGBitFieldInfo &Info, 330*f4a2713aSLionel Sambuc QualType type, CharUnits Alignment) { 331*f4a2713aSLionel Sambuc LValue R; 332*f4a2713aSLionel Sambuc R.LVType = BitField; 333*f4a2713aSLionel Sambuc R.V = Addr; 334*f4a2713aSLionel Sambuc R.BitFieldInfo = &Info; 335*f4a2713aSLionel Sambuc R.Initialize(type, type.getQualifiers(), Alignment); 336*f4a2713aSLionel Sambuc return R; 337*f4a2713aSLionel Sambuc } 338*f4a2713aSLionel Sambuc 339*f4a2713aSLionel Sambuc RValue asAggregateRValue() const { 340*f4a2713aSLionel Sambuc // FIMXE: Alignment 341*f4a2713aSLionel Sambuc return RValue::getAggregate(getAddress(), isVolatileQualified()); 342*f4a2713aSLionel Sambuc } 343*f4a2713aSLionel Sambuc }; 344*f4a2713aSLionel Sambuc 345*f4a2713aSLionel Sambuc /// An aggregate value slot. 346*f4a2713aSLionel Sambuc class AggValueSlot { 347*f4a2713aSLionel Sambuc /// The address. 348*f4a2713aSLionel Sambuc llvm::Value *Addr; 349*f4a2713aSLionel Sambuc 350*f4a2713aSLionel Sambuc // Qualifiers 351*f4a2713aSLionel Sambuc Qualifiers Quals; 352*f4a2713aSLionel Sambuc 353*f4a2713aSLionel Sambuc unsigned short Alignment; 354*f4a2713aSLionel Sambuc 355*f4a2713aSLionel Sambuc /// DestructedFlag - This is set to true if some external code is 356*f4a2713aSLionel Sambuc /// responsible for setting up a destructor for the slot. Otherwise 357*f4a2713aSLionel Sambuc /// the code which constructs it should push the appropriate cleanup. 358*f4a2713aSLionel Sambuc bool DestructedFlag : 1; 359*f4a2713aSLionel Sambuc 360*f4a2713aSLionel Sambuc /// ObjCGCFlag - This is set to true if writing to the memory in the 361*f4a2713aSLionel Sambuc /// slot might require calling an appropriate Objective-C GC 362*f4a2713aSLionel Sambuc /// barrier. The exact interaction here is unnecessarily mysterious. 363*f4a2713aSLionel Sambuc bool ObjCGCFlag : 1; 364*f4a2713aSLionel Sambuc 365*f4a2713aSLionel Sambuc /// ZeroedFlag - This is set to true if the memory in the slot is 366*f4a2713aSLionel Sambuc /// known to be zero before the assignment into it. This means that 367*f4a2713aSLionel Sambuc /// zero fields don't need to be set. 368*f4a2713aSLionel Sambuc bool ZeroedFlag : 1; 369*f4a2713aSLionel Sambuc 370*f4a2713aSLionel Sambuc /// AliasedFlag - This is set to true if the slot might be aliased 371*f4a2713aSLionel Sambuc /// and it's not undefined behavior to access it through such an 372*f4a2713aSLionel Sambuc /// alias. Note that it's always undefined behavior to access a C++ 373*f4a2713aSLionel Sambuc /// object that's under construction through an alias derived from 374*f4a2713aSLionel Sambuc /// outside the construction process. 375*f4a2713aSLionel Sambuc /// 376*f4a2713aSLionel Sambuc /// This flag controls whether calls that produce the aggregate 377*f4a2713aSLionel Sambuc /// value may be evaluated directly into the slot, or whether they 378*f4a2713aSLionel Sambuc /// must be evaluated into an unaliased temporary and then memcpy'ed 379*f4a2713aSLionel Sambuc /// over. Since it's invalid in general to memcpy a non-POD C++ 380*f4a2713aSLionel Sambuc /// object, it's important that this flag never be set when 381*f4a2713aSLionel Sambuc /// evaluating an expression which constructs such an object. 382*f4a2713aSLionel Sambuc bool AliasedFlag : 1; 383*f4a2713aSLionel Sambuc 384*f4a2713aSLionel Sambuc public: 385*f4a2713aSLionel Sambuc enum IsAliased_t { IsNotAliased, IsAliased }; 386*f4a2713aSLionel Sambuc enum IsDestructed_t { IsNotDestructed, IsDestructed }; 387*f4a2713aSLionel Sambuc enum IsZeroed_t { IsNotZeroed, IsZeroed }; 388*f4a2713aSLionel Sambuc enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers }; 389*f4a2713aSLionel Sambuc 390*f4a2713aSLionel Sambuc /// ignored - Returns an aggregate value slot indicating that the 391*f4a2713aSLionel Sambuc /// aggregate value is being ignored. 392*f4a2713aSLionel Sambuc static AggValueSlot ignored() { 393*f4a2713aSLionel Sambuc return forAddr(0, CharUnits(), Qualifiers(), IsNotDestructed, 394*f4a2713aSLionel Sambuc DoesNotNeedGCBarriers, IsNotAliased); 395*f4a2713aSLionel Sambuc } 396*f4a2713aSLionel Sambuc 397*f4a2713aSLionel Sambuc /// forAddr - Make a slot for an aggregate value. 398*f4a2713aSLionel Sambuc /// 399*f4a2713aSLionel Sambuc /// \param quals - The qualifiers that dictate how the slot should 400*f4a2713aSLionel Sambuc /// be initialied. Only 'volatile' and the Objective-C lifetime 401*f4a2713aSLionel Sambuc /// qualifiers matter. 402*f4a2713aSLionel Sambuc /// 403*f4a2713aSLionel Sambuc /// \param isDestructed - true if something else is responsible 404*f4a2713aSLionel Sambuc /// for calling destructors on this object 405*f4a2713aSLionel Sambuc /// \param needsGC - true if the slot is potentially located 406*f4a2713aSLionel Sambuc /// somewhere that ObjC GC calls should be emitted for 407*f4a2713aSLionel Sambuc static AggValueSlot forAddr(llvm::Value *addr, CharUnits align, 408*f4a2713aSLionel Sambuc Qualifiers quals, 409*f4a2713aSLionel Sambuc IsDestructed_t isDestructed, 410*f4a2713aSLionel Sambuc NeedsGCBarriers_t needsGC, 411*f4a2713aSLionel Sambuc IsAliased_t isAliased, 412*f4a2713aSLionel Sambuc IsZeroed_t isZeroed = IsNotZeroed) { 413*f4a2713aSLionel Sambuc AggValueSlot AV; 414*f4a2713aSLionel Sambuc AV.Addr = addr; 415*f4a2713aSLionel Sambuc AV.Alignment = align.getQuantity(); 416*f4a2713aSLionel Sambuc AV.Quals = quals; 417*f4a2713aSLionel Sambuc AV.DestructedFlag = isDestructed; 418*f4a2713aSLionel Sambuc AV.ObjCGCFlag = needsGC; 419*f4a2713aSLionel Sambuc AV.ZeroedFlag = isZeroed; 420*f4a2713aSLionel Sambuc AV.AliasedFlag = isAliased; 421*f4a2713aSLionel Sambuc return AV; 422*f4a2713aSLionel Sambuc } 423*f4a2713aSLionel Sambuc 424*f4a2713aSLionel Sambuc static AggValueSlot forLValue(const LValue &LV, 425*f4a2713aSLionel Sambuc IsDestructed_t isDestructed, 426*f4a2713aSLionel Sambuc NeedsGCBarriers_t needsGC, 427*f4a2713aSLionel Sambuc IsAliased_t isAliased, 428*f4a2713aSLionel Sambuc IsZeroed_t isZeroed = IsNotZeroed) { 429*f4a2713aSLionel Sambuc return forAddr(LV.getAddress(), LV.getAlignment(), 430*f4a2713aSLionel Sambuc LV.getQuals(), isDestructed, needsGC, isAliased, isZeroed); 431*f4a2713aSLionel Sambuc } 432*f4a2713aSLionel Sambuc 433*f4a2713aSLionel Sambuc IsDestructed_t isExternallyDestructed() const { 434*f4a2713aSLionel Sambuc return IsDestructed_t(DestructedFlag); 435*f4a2713aSLionel Sambuc } 436*f4a2713aSLionel Sambuc void setExternallyDestructed(bool destructed = true) { 437*f4a2713aSLionel Sambuc DestructedFlag = destructed; 438*f4a2713aSLionel Sambuc } 439*f4a2713aSLionel Sambuc 440*f4a2713aSLionel Sambuc Qualifiers getQualifiers() const { return Quals; } 441*f4a2713aSLionel Sambuc 442*f4a2713aSLionel Sambuc bool isVolatile() const { 443*f4a2713aSLionel Sambuc return Quals.hasVolatile(); 444*f4a2713aSLionel Sambuc } 445*f4a2713aSLionel Sambuc 446*f4a2713aSLionel Sambuc void setVolatile(bool flag) { 447*f4a2713aSLionel Sambuc Quals.setVolatile(flag); 448*f4a2713aSLionel Sambuc } 449*f4a2713aSLionel Sambuc 450*f4a2713aSLionel Sambuc Qualifiers::ObjCLifetime getObjCLifetime() const { 451*f4a2713aSLionel Sambuc return Quals.getObjCLifetime(); 452*f4a2713aSLionel Sambuc } 453*f4a2713aSLionel Sambuc 454*f4a2713aSLionel Sambuc NeedsGCBarriers_t requiresGCollection() const { 455*f4a2713aSLionel Sambuc return NeedsGCBarriers_t(ObjCGCFlag); 456*f4a2713aSLionel Sambuc } 457*f4a2713aSLionel Sambuc 458*f4a2713aSLionel Sambuc llvm::Value *getAddr() const { 459*f4a2713aSLionel Sambuc return Addr; 460*f4a2713aSLionel Sambuc } 461*f4a2713aSLionel Sambuc 462*f4a2713aSLionel Sambuc bool isIgnored() const { 463*f4a2713aSLionel Sambuc return Addr == 0; 464*f4a2713aSLionel Sambuc } 465*f4a2713aSLionel Sambuc 466*f4a2713aSLionel Sambuc CharUnits getAlignment() const { 467*f4a2713aSLionel Sambuc return CharUnits::fromQuantity(Alignment); 468*f4a2713aSLionel Sambuc } 469*f4a2713aSLionel Sambuc 470*f4a2713aSLionel Sambuc IsAliased_t isPotentiallyAliased() const { 471*f4a2713aSLionel Sambuc return IsAliased_t(AliasedFlag); 472*f4a2713aSLionel Sambuc } 473*f4a2713aSLionel Sambuc 474*f4a2713aSLionel Sambuc // FIXME: Alignment? 475*f4a2713aSLionel Sambuc RValue asRValue() const { 476*f4a2713aSLionel Sambuc return RValue::getAggregate(getAddr(), isVolatile()); 477*f4a2713aSLionel Sambuc } 478*f4a2713aSLionel Sambuc 479*f4a2713aSLionel Sambuc void setZeroed(bool V = true) { ZeroedFlag = V; } 480*f4a2713aSLionel Sambuc IsZeroed_t isZeroed() const { 481*f4a2713aSLionel Sambuc return IsZeroed_t(ZeroedFlag); 482*f4a2713aSLionel Sambuc } 483*f4a2713aSLionel Sambuc }; 484*f4a2713aSLionel Sambuc 485*f4a2713aSLionel Sambuc } // end namespace CodeGen 486*f4a2713aSLionel Sambuc } // end namespace clang 487*f4a2713aSLionel Sambuc 488*f4a2713aSLionel Sambuc #endif 489