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