10b57cec5SDimitry Andric //===-- CGValue.h - LLVM CodeGen wrappers for llvm::Value* ------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // These classes implement wrappers around llvm::Value in order to 100b57cec5SDimitry Andric // fully represent the range of values for C L- and R- values. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_CGVALUE_H 150b57cec5SDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_CGVALUE_H 160b57cec5SDimitry Andric 17*0fca6ea1SDimitry Andric #include "Address.h" 18*0fca6ea1SDimitry Andric #include "CGPointerAuthInfo.h" 19*0fca6ea1SDimitry Andric #include "CodeGenTBAA.h" 20*0fca6ea1SDimitry Andric #include "EHScopeStack.h" 210b57cec5SDimitry Andric #include "clang/AST/ASTContext.h" 220b57cec5SDimitry Andric #include "clang/AST/Type.h" 230b57cec5SDimitry Andric #include "llvm/IR/Type.h" 24*0fca6ea1SDimitry Andric #include "llvm/IR/Value.h" 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric namespace llvm { 270b57cec5SDimitry Andric class Constant; 280b57cec5SDimitry Andric class MDNode; 290b57cec5SDimitry Andric } 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric namespace clang { 320b57cec5SDimitry Andric namespace CodeGen { 330b57cec5SDimitry Andric class AggValueSlot; 34*0fca6ea1SDimitry Andric class CGBuilderTy; 35480093f4SDimitry Andric class CodeGenFunction; 360b57cec5SDimitry Andric struct CGBitFieldInfo; 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric /// RValue - This trivial value class is used to represent the result of an 390b57cec5SDimitry Andric /// expression that is evaluated. It can be one of three things: either a 400b57cec5SDimitry Andric /// simple LLVM SSA value, a pair of SSA values for complex numbers, or the 410b57cec5SDimitry Andric /// address of an aggregate value in memory. 420b57cec5SDimitry Andric class RValue { 43*0fca6ea1SDimitry Andric friend struct DominatingValue<RValue>; 440b57cec5SDimitry Andric 45*0fca6ea1SDimitry Andric enum FlavorEnum { Scalar, Complex, Aggregate }; 460b57cec5SDimitry Andric 47*0fca6ea1SDimitry Andric union { 48*0fca6ea1SDimitry Andric // Stores first and second value. 49*0fca6ea1SDimitry Andric struct { 50*0fca6ea1SDimitry Andric llvm::Value *first; 51*0fca6ea1SDimitry Andric llvm::Value *second; 52*0fca6ea1SDimitry Andric } Vals; 53*0fca6ea1SDimitry Andric 54*0fca6ea1SDimitry Andric // Stores aggregate address. 55*0fca6ea1SDimitry Andric Address AggregateAddr; 56*0fca6ea1SDimitry Andric }; 57*0fca6ea1SDimitry Andric 58*0fca6ea1SDimitry Andric unsigned IsVolatile : 1; 59*0fca6ea1SDimitry Andric unsigned Flavor : 2; 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric public: 62*0fca6ea1SDimitry Andric RValue() : Vals{nullptr, nullptr}, Flavor(Scalar) {} 630b57cec5SDimitry Andric 64*0fca6ea1SDimitry Andric bool isScalar() const { return Flavor == Scalar; } 65*0fca6ea1SDimitry Andric bool isComplex() const { return Flavor == Complex; } 66*0fca6ea1SDimitry Andric bool isAggregate() const { return Flavor == Aggregate; } 67*0fca6ea1SDimitry Andric 68*0fca6ea1SDimitry Andric bool isVolatileQualified() const { return IsVolatile; } 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric /// getScalarVal() - Return the Value* of this scalar value. 710b57cec5SDimitry Andric llvm::Value *getScalarVal() const { 720b57cec5SDimitry Andric assert(isScalar() && "Not a scalar!"); 73*0fca6ea1SDimitry Andric return Vals.first; 740b57cec5SDimitry Andric } 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric /// getComplexVal - Return the real/imag components of this complex value. 770b57cec5SDimitry Andric /// 780b57cec5SDimitry Andric std::pair<llvm::Value *, llvm::Value *> getComplexVal() const { 79*0fca6ea1SDimitry Andric return std::make_pair(Vals.first, Vals.second); 800b57cec5SDimitry Andric } 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric /// getAggregateAddr() - Return the Value* of the address of the aggregate. 830b57cec5SDimitry Andric Address getAggregateAddress() const { 840b57cec5SDimitry Andric assert(isAggregate() && "Not an aggregate!"); 85*0fca6ea1SDimitry Andric return AggregateAddr; 860b57cec5SDimitry Andric } 87*0fca6ea1SDimitry Andric 88*0fca6ea1SDimitry Andric llvm::Value *getAggregatePointer(QualType PointeeType, 89*0fca6ea1SDimitry Andric CodeGenFunction &CGF) const { 90*0fca6ea1SDimitry Andric return getAggregateAddress().getBasePointer(); 910b57cec5SDimitry Andric } 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric static RValue getIgnored() { 940b57cec5SDimitry Andric // FIXME: should we make this a more explicit state? 950b57cec5SDimitry Andric return get(nullptr); 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric static RValue get(llvm::Value *V) { 990b57cec5SDimitry Andric RValue ER; 100*0fca6ea1SDimitry Andric ER.Vals.first = V; 101*0fca6ea1SDimitry Andric ER.Flavor = Scalar; 102*0fca6ea1SDimitry Andric ER.IsVolatile = false; 1030b57cec5SDimitry Andric return ER; 1040b57cec5SDimitry Andric } 105*0fca6ea1SDimitry Andric static RValue get(Address Addr, CodeGenFunction &CGF) { 106*0fca6ea1SDimitry Andric return RValue::get(Addr.emitRawPointer(CGF)); 107*0fca6ea1SDimitry Andric } 1080b57cec5SDimitry Andric static RValue getComplex(llvm::Value *V1, llvm::Value *V2) { 1090b57cec5SDimitry Andric RValue ER; 110*0fca6ea1SDimitry Andric ER.Vals = {V1, V2}; 111*0fca6ea1SDimitry Andric ER.Flavor = Complex; 112*0fca6ea1SDimitry Andric ER.IsVolatile = false; 1130b57cec5SDimitry Andric return ER; 1140b57cec5SDimitry Andric } 1150b57cec5SDimitry Andric static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) { 1160b57cec5SDimitry Andric return getComplex(C.first, C.second); 1170b57cec5SDimitry Andric } 1180b57cec5SDimitry Andric // FIXME: Aggregate rvalues need to retain information about whether they are 1190b57cec5SDimitry Andric // volatile or not. Remove default to find all places that probably get this 1200b57cec5SDimitry Andric // wrong. 121*0fca6ea1SDimitry Andric 122*0fca6ea1SDimitry Andric /// Convert an Address to an RValue. If the Address is not 123*0fca6ea1SDimitry Andric /// signed, create an RValue using the unsigned address. Otherwise, resign the 124*0fca6ea1SDimitry Andric /// address using the provided type. 1250b57cec5SDimitry Andric static RValue getAggregate(Address addr, bool isVolatile = false) { 1260b57cec5SDimitry Andric RValue ER; 127*0fca6ea1SDimitry Andric ER.AggregateAddr = addr; 128*0fca6ea1SDimitry Andric ER.Flavor = Aggregate; 129*0fca6ea1SDimitry Andric ER.IsVolatile = isVolatile; 1300b57cec5SDimitry Andric return ER; 1310b57cec5SDimitry Andric } 1320b57cec5SDimitry Andric }; 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric /// Does an ARC strong l-value have precise lifetime? 1350b57cec5SDimitry Andric enum ARCPreciseLifetime_t { 1360b57cec5SDimitry Andric ARCImpreciseLifetime, ARCPreciseLifetime 1370b57cec5SDimitry Andric }; 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric /// The source of the alignment of an l-value; an expression of 1400b57cec5SDimitry Andric /// confidence in the alignment actually matching the estimate. 1410b57cec5SDimitry Andric enum class AlignmentSource { 1420b57cec5SDimitry Andric /// The l-value was an access to a declared entity or something 1430b57cec5SDimitry Andric /// equivalently strong, like the address of an array allocated by a 1440b57cec5SDimitry Andric /// language runtime. 1450b57cec5SDimitry Andric Decl, 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric /// The l-value was considered opaque, so the alignment was 1480b57cec5SDimitry Andric /// determined from a type, but that type was an explicitly-aligned 1490b57cec5SDimitry Andric /// typedef. 1500b57cec5SDimitry Andric AttributedType, 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric /// The l-value was considered opaque, so the alignment was 1530b57cec5SDimitry Andric /// determined from a type. 1540b57cec5SDimitry Andric Type 1550b57cec5SDimitry Andric }; 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric /// Given that the base address has the given alignment source, what's 1580b57cec5SDimitry Andric /// our confidence in the alignment of the field? 1590b57cec5SDimitry Andric static inline AlignmentSource getFieldAlignmentSource(AlignmentSource Source) { 1600b57cec5SDimitry Andric // For now, we don't distinguish fields of opaque pointers from 1610b57cec5SDimitry Andric // top-level declarations, but maybe we should. 1620b57cec5SDimitry Andric return AlignmentSource::Decl; 1630b57cec5SDimitry Andric } 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric class LValueBaseInfo { 1660b57cec5SDimitry Andric AlignmentSource AlignSource; 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric public: 1690b57cec5SDimitry Andric explicit LValueBaseInfo(AlignmentSource Source = AlignmentSource::Type) 1700b57cec5SDimitry Andric : AlignSource(Source) {} 1710b57cec5SDimitry Andric AlignmentSource getAlignmentSource() const { return AlignSource; } 1720b57cec5SDimitry Andric void setAlignmentSource(AlignmentSource Source) { AlignSource = Source; } 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric void mergeForCast(const LValueBaseInfo &Info) { 1750b57cec5SDimitry Andric setAlignmentSource(Info.getAlignmentSource()); 1760b57cec5SDimitry Andric } 1770b57cec5SDimitry Andric }; 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric /// LValue - This represents an lvalue references. Because C/C++ allow 1800b57cec5SDimitry Andric /// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a 1810b57cec5SDimitry Andric /// bitrange. 1820b57cec5SDimitry Andric class LValue { 1830b57cec5SDimitry Andric enum { 1840b57cec5SDimitry Andric Simple, // This is a normal l-value, use getAddress(). 1850b57cec5SDimitry Andric VectorElt, // This is a vector element l-value (V[i]), use getVector* 1860b57cec5SDimitry Andric BitField, // This is a bitfield l-value, use getBitfield*. 1870b57cec5SDimitry Andric ExtVectorElt, // This is an extended vector subset, use getExtVectorComp 1885ffd83dbSDimitry Andric GlobalReg, // This is a register l-value, use getGlobalReg() 1895ffd83dbSDimitry Andric MatrixElt // This is a matrix element, use getVector* 1900b57cec5SDimitry Andric } LVType; 1910b57cec5SDimitry Andric 192*0fca6ea1SDimitry Andric union { 193*0fca6ea1SDimitry Andric Address Addr = Address::invalid(); 1940b57cec5SDimitry Andric llvm::Value *V; 195*0fca6ea1SDimitry Andric }; 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric union { 1980b57cec5SDimitry Andric // Index into a vector subscript: V[i] 1990b57cec5SDimitry Andric llvm::Value *VectorIdx; 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric // ExtVector element subset: V.xyx 2020b57cec5SDimitry Andric llvm::Constant *VectorElts; 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric // BitField start bit and size 2050b57cec5SDimitry Andric const CGBitFieldInfo *BitFieldInfo; 2060b57cec5SDimitry Andric }; 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andric QualType Type; 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric // 'const' is unused here 2110b57cec5SDimitry Andric Qualifiers Quals; 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric // objective-c's ivar 2140b57cec5SDimitry Andric bool Ivar:1; 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andric // objective-c's ivar is an array 2170b57cec5SDimitry Andric bool ObjIsArray:1; 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric // LValue is non-gc'able for any reason, including being a parameter or local 2200b57cec5SDimitry Andric // variable. 2210b57cec5SDimitry Andric bool NonGC: 1; 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric // Lvalue is a global reference of an objective-c object 2240b57cec5SDimitry Andric bool GlobalObjCRef : 1; 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric // Lvalue is a thread local reference 2270b57cec5SDimitry Andric bool ThreadLocalRef : 1; 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric // Lvalue has ARC imprecise lifetime. We store this inverted to try 2300b57cec5SDimitry Andric // to make the default bitfield pattern all-zeroes. 2310b57cec5SDimitry Andric bool ImpreciseLifetime : 1; 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric // This flag shows if a nontemporal load/stores should be used when accessing 2340b57cec5SDimitry Andric // this lvalue. 2350b57cec5SDimitry Andric bool Nontemporal : 1; 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric LValueBaseInfo BaseInfo; 2380b57cec5SDimitry Andric TBAAAccessInfo TBAAInfo; 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric Expr *BaseIvarExp; 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric private: 243*0fca6ea1SDimitry Andric void Initialize(QualType Type, Qualifiers Quals, Address Addr, 2440b57cec5SDimitry Andric LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) { 2450b57cec5SDimitry Andric this->Type = Type; 2460b57cec5SDimitry Andric this->Quals = Quals; 2470b57cec5SDimitry Andric const unsigned MaxAlign = 1U << 31; 248*0fca6ea1SDimitry Andric CharUnits Alignment = Addr.getAlignment(); 249*0fca6ea1SDimitry Andric assert((isGlobalReg() || !Alignment.isZero() || Type->isIncompleteType()) && 250*0fca6ea1SDimitry Andric "initializing l-value with zero alignment!"); 251*0fca6ea1SDimitry Andric if (Alignment.getQuantity() > MaxAlign) { 252*0fca6ea1SDimitry Andric assert(false && "Alignment exceeds allowed max!"); 253*0fca6ea1SDimitry Andric Alignment = CharUnits::fromQuantity(MaxAlign); 254*0fca6ea1SDimitry Andric } 255*0fca6ea1SDimitry Andric this->Addr = Addr; 2560b57cec5SDimitry Andric this->BaseInfo = BaseInfo; 2570b57cec5SDimitry Andric this->TBAAInfo = TBAAInfo; 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric // Initialize Objective-C flags. 2600b57cec5SDimitry Andric this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false; 2610b57cec5SDimitry Andric this->ImpreciseLifetime = false; 2620b57cec5SDimitry Andric this->Nontemporal = false; 2630b57cec5SDimitry Andric this->ThreadLocalRef = false; 2640b57cec5SDimitry Andric this->BaseIvarExp = nullptr; 2650b57cec5SDimitry Andric } 2660b57cec5SDimitry Andric 267*0fca6ea1SDimitry Andric void initializeSimpleLValue(Address Addr, QualType Type, 268*0fca6ea1SDimitry Andric LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo, 269*0fca6ea1SDimitry Andric ASTContext &Context) { 270*0fca6ea1SDimitry Andric Qualifiers QS = Type.getQualifiers(); 271*0fca6ea1SDimitry Andric QS.setObjCGCAttr(Context.getObjCGCAttrKind(Type)); 272*0fca6ea1SDimitry Andric LVType = Simple; 273*0fca6ea1SDimitry Andric Initialize(Type, QS, Addr, BaseInfo, TBAAInfo); 274*0fca6ea1SDimitry Andric assert(Addr.getBasePointer()->getType()->isPointerTy()); 275*0fca6ea1SDimitry Andric } 276*0fca6ea1SDimitry Andric 2770b57cec5SDimitry Andric public: 2780b57cec5SDimitry Andric bool isSimple() const { return LVType == Simple; } 2790b57cec5SDimitry Andric bool isVectorElt() const { return LVType == VectorElt; } 2800b57cec5SDimitry Andric bool isBitField() const { return LVType == BitField; } 2810b57cec5SDimitry Andric bool isExtVectorElt() const { return LVType == ExtVectorElt; } 2820b57cec5SDimitry Andric bool isGlobalReg() const { return LVType == GlobalReg; } 2835ffd83dbSDimitry Andric bool isMatrixElt() const { return LVType == MatrixElt; } 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric bool isVolatileQualified() const { return Quals.hasVolatile(); } 2860b57cec5SDimitry Andric bool isRestrictQualified() const { return Quals.hasRestrict(); } 2870b57cec5SDimitry Andric unsigned getVRQualifiers() const { 2880b57cec5SDimitry Andric return Quals.getCVRQualifiers() & ~Qualifiers::Const; 2890b57cec5SDimitry Andric } 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric QualType getType() const { return Type; } 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric Qualifiers::ObjCLifetime getObjCLifetime() const { 2940b57cec5SDimitry Andric return Quals.getObjCLifetime(); 2950b57cec5SDimitry Andric } 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric bool isObjCIvar() const { return Ivar; } 2980b57cec5SDimitry Andric void setObjCIvar(bool Value) { Ivar = Value; } 2990b57cec5SDimitry Andric 3000b57cec5SDimitry Andric bool isObjCArray() const { return ObjIsArray; } 3010b57cec5SDimitry Andric void setObjCArray(bool Value) { ObjIsArray = Value; } 3020b57cec5SDimitry Andric 3030b57cec5SDimitry Andric bool isNonGC () const { return NonGC; } 3040b57cec5SDimitry Andric void setNonGC(bool Value) { NonGC = Value; } 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andric bool isGlobalObjCRef() const { return GlobalObjCRef; } 3070b57cec5SDimitry Andric void setGlobalObjCRef(bool Value) { GlobalObjCRef = Value; } 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric bool isThreadLocalRef() const { return ThreadLocalRef; } 3100b57cec5SDimitry Andric void setThreadLocalRef(bool Value) { ThreadLocalRef = Value;} 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric ARCPreciseLifetime_t isARCPreciseLifetime() const { 3130b57cec5SDimitry Andric return ARCPreciseLifetime_t(!ImpreciseLifetime); 3140b57cec5SDimitry Andric } 3150b57cec5SDimitry Andric void setARCPreciseLifetime(ARCPreciseLifetime_t value) { 3160b57cec5SDimitry Andric ImpreciseLifetime = (value == ARCImpreciseLifetime); 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric bool isNontemporal() const { return Nontemporal; } 3190b57cec5SDimitry Andric void setNontemporal(bool Value) { Nontemporal = Value; } 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric bool isObjCWeak() const { 3220b57cec5SDimitry Andric return Quals.getObjCGCAttr() == Qualifiers::Weak; 3230b57cec5SDimitry Andric } 3240b57cec5SDimitry Andric bool isObjCStrong() const { 3250b57cec5SDimitry Andric return Quals.getObjCGCAttr() == Qualifiers::Strong; 3260b57cec5SDimitry Andric } 3270b57cec5SDimitry Andric 3280b57cec5SDimitry Andric bool isVolatile() const { 3290b57cec5SDimitry Andric return Quals.hasVolatile(); 3300b57cec5SDimitry Andric } 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric Expr *getBaseIvarExp() const { return BaseIvarExp; } 3330b57cec5SDimitry Andric void setBaseIvarExp(Expr *V) { BaseIvarExp = V; } 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric TBAAAccessInfo getTBAAInfo() const { return TBAAInfo; } 3360b57cec5SDimitry Andric void setTBAAInfo(TBAAAccessInfo Info) { TBAAInfo = Info; } 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric const Qualifiers &getQuals() const { return Quals; } 3390b57cec5SDimitry Andric Qualifiers &getQuals() { return Quals; } 3400b57cec5SDimitry Andric 3410b57cec5SDimitry Andric LangAS getAddressSpace() const { return Quals.getAddressSpace(); } 3420b57cec5SDimitry Andric 343*0fca6ea1SDimitry Andric CharUnits getAlignment() const { return Addr.getAlignment(); } 344*0fca6ea1SDimitry Andric void setAlignment(CharUnits A) { Addr.setAlignment(A); } 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric LValueBaseInfo getBaseInfo() const { return BaseInfo; } 3470b57cec5SDimitry Andric void setBaseInfo(LValueBaseInfo Info) { BaseInfo = Info; } 3480b57cec5SDimitry Andric 349*0fca6ea1SDimitry Andric KnownNonNull_t isKnownNonNull() const { return Addr.isKnownNonNull(); } 35006c3fb27SDimitry Andric LValue setKnownNonNull() { 351*0fca6ea1SDimitry Andric Addr.setKnownNonNull(); 35206c3fb27SDimitry Andric return *this; 35306c3fb27SDimitry Andric } 35406c3fb27SDimitry Andric 3550b57cec5SDimitry Andric // simple lvalue 356*0fca6ea1SDimitry Andric llvm::Value *getPointer(CodeGenFunction &CGF) const; 357*0fca6ea1SDimitry Andric llvm::Value *emitResignedPointer(QualType PointeeTy, 358*0fca6ea1SDimitry Andric CodeGenFunction &CGF) const; 359*0fca6ea1SDimitry Andric llvm::Value *emitRawPointer(CodeGenFunction &CGF) const; 360*0fca6ea1SDimitry Andric 361*0fca6ea1SDimitry Andric Address getAddress() const { return Addr; } 362*0fca6ea1SDimitry Andric 363*0fca6ea1SDimitry Andric void setAddress(Address address) { Addr = address; } 364*0fca6ea1SDimitry Andric 365*0fca6ea1SDimitry Andric CGPointerAuthInfo getPointerAuthInfo() const { 366*0fca6ea1SDimitry Andric return Addr.getPointerAuthInfo(); 3670b57cec5SDimitry Andric } 3680b57cec5SDimitry Andric 3690b57cec5SDimitry Andric // vector elt lvalue 3700b57cec5SDimitry Andric Address getVectorAddress() const { 371*0fca6ea1SDimitry Andric assert(isVectorElt()); 372*0fca6ea1SDimitry Andric return Addr; 373*0fca6ea1SDimitry Andric } 374*0fca6ea1SDimitry Andric llvm::Value *getRawVectorPointer(CodeGenFunction &CGF) const { 375*0fca6ea1SDimitry Andric assert(isVectorElt()); 376*0fca6ea1SDimitry Andric return Addr.emitRawPointer(CGF); 3770b57cec5SDimitry Andric } 3785ffd83dbSDimitry Andric llvm::Value *getVectorPointer() const { 3795ffd83dbSDimitry Andric assert(isVectorElt()); 380*0fca6ea1SDimitry Andric return Addr.getBasePointer(); 3815ffd83dbSDimitry Andric } 3825ffd83dbSDimitry Andric llvm::Value *getVectorIdx() const { 3835ffd83dbSDimitry Andric assert(isVectorElt()); 3845ffd83dbSDimitry Andric return VectorIdx; 3855ffd83dbSDimitry Andric } 3865ffd83dbSDimitry Andric 3875ffd83dbSDimitry Andric Address getMatrixAddress() const { 388*0fca6ea1SDimitry Andric assert(isMatrixElt()); 389*0fca6ea1SDimitry Andric return Addr; 3905ffd83dbSDimitry Andric } 3915ffd83dbSDimitry Andric llvm::Value *getMatrixPointer() const { 3925ffd83dbSDimitry Andric assert(isMatrixElt()); 393*0fca6ea1SDimitry Andric return Addr.getBasePointer(); 3945ffd83dbSDimitry Andric } 3955ffd83dbSDimitry Andric llvm::Value *getMatrixIdx() const { 3965ffd83dbSDimitry Andric assert(isMatrixElt()); 3975ffd83dbSDimitry Andric return VectorIdx; 3985ffd83dbSDimitry Andric } 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric // extended vector elements. 4010b57cec5SDimitry Andric Address getExtVectorAddress() const { 4020b57cec5SDimitry Andric assert(isExtVectorElt()); 403*0fca6ea1SDimitry Andric return Addr; 404*0fca6ea1SDimitry Andric } 405*0fca6ea1SDimitry Andric llvm::Value *getRawExtVectorPointer(CodeGenFunction &CGF) const { 406*0fca6ea1SDimitry Andric assert(isExtVectorElt()); 407*0fca6ea1SDimitry Andric return Addr.emitRawPointer(CGF); 4080b57cec5SDimitry Andric } 4090b57cec5SDimitry Andric llvm::Constant *getExtVectorElts() const { 4100b57cec5SDimitry Andric assert(isExtVectorElt()); 4110b57cec5SDimitry Andric return VectorElts; 4120b57cec5SDimitry Andric } 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric // bitfield lvalue 4150b57cec5SDimitry Andric Address getBitFieldAddress() const { 416*0fca6ea1SDimitry Andric assert(isBitField()); 417*0fca6ea1SDimitry Andric return Addr; 4180b57cec5SDimitry Andric } 419*0fca6ea1SDimitry Andric llvm::Value *getRawBitFieldPointer(CodeGenFunction &CGF) const { 420*0fca6ea1SDimitry Andric assert(isBitField()); 421*0fca6ea1SDimitry Andric return Addr.emitRawPointer(CGF); 422*0fca6ea1SDimitry Andric } 423*0fca6ea1SDimitry Andric 4240b57cec5SDimitry Andric const CGBitFieldInfo &getBitFieldInfo() const { 4250b57cec5SDimitry Andric assert(isBitField()); 4260b57cec5SDimitry Andric return *BitFieldInfo; 4270b57cec5SDimitry Andric } 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric // global register lvalue 4300b57cec5SDimitry Andric llvm::Value *getGlobalReg() const { assert(isGlobalReg()); return V; } 4310b57cec5SDimitry Andric 432*0fca6ea1SDimitry Andric static LValue MakeAddr(Address Addr, QualType type, ASTContext &Context, 4330b57cec5SDimitry Andric LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) { 4340b57cec5SDimitry Andric LValue R; 4350b57cec5SDimitry Andric R.LVType = Simple; 436*0fca6ea1SDimitry Andric R.initializeSimpleLValue(Addr, type, BaseInfo, TBAAInfo, Context); 437*0fca6ea1SDimitry Andric R.Addr = Addr; 438*0fca6ea1SDimitry Andric assert(Addr.getType()->isPointerTy()); 4390b57cec5SDimitry Andric return R; 4400b57cec5SDimitry Andric } 4410b57cec5SDimitry Andric 4420b57cec5SDimitry Andric static LValue MakeVectorElt(Address vecAddress, llvm::Value *Idx, 4430b57cec5SDimitry Andric QualType type, LValueBaseInfo BaseInfo, 4440b57cec5SDimitry Andric TBAAAccessInfo TBAAInfo) { 4450b57cec5SDimitry Andric LValue R; 4460b57cec5SDimitry Andric R.LVType = VectorElt; 4470b57cec5SDimitry Andric R.VectorIdx = Idx; 448*0fca6ea1SDimitry Andric R.Initialize(type, type.getQualifiers(), vecAddress, BaseInfo, TBAAInfo); 4490b57cec5SDimitry Andric return R; 4500b57cec5SDimitry Andric } 4510b57cec5SDimitry Andric 452*0fca6ea1SDimitry Andric static LValue MakeExtVectorElt(Address Addr, llvm::Constant *Elts, 4530b57cec5SDimitry Andric QualType type, LValueBaseInfo BaseInfo, 4540b57cec5SDimitry Andric TBAAAccessInfo TBAAInfo) { 4550b57cec5SDimitry Andric LValue R; 4560b57cec5SDimitry Andric R.LVType = ExtVectorElt; 4570b57cec5SDimitry Andric R.VectorElts = Elts; 458*0fca6ea1SDimitry Andric R.Initialize(type, type.getQualifiers(), Addr, BaseInfo, TBAAInfo); 4590b57cec5SDimitry Andric return R; 4600b57cec5SDimitry Andric } 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andric /// Create a new object to represent a bit-field access. 4630b57cec5SDimitry Andric /// 4640b57cec5SDimitry Andric /// \param Addr - The base address of the bit-field sequence this 4650b57cec5SDimitry Andric /// bit-field refers to. 4660b57cec5SDimitry Andric /// \param Info - The information describing how to perform the bit-field 4670b57cec5SDimitry Andric /// access. 4680b57cec5SDimitry Andric static LValue MakeBitfield(Address Addr, const CGBitFieldInfo &Info, 4690b57cec5SDimitry Andric QualType type, LValueBaseInfo BaseInfo, 4700b57cec5SDimitry Andric TBAAAccessInfo TBAAInfo) { 4710b57cec5SDimitry Andric LValue R; 4720b57cec5SDimitry Andric R.LVType = BitField; 4730b57cec5SDimitry Andric R.BitFieldInfo = &Info; 474*0fca6ea1SDimitry Andric R.Initialize(type, type.getQualifiers(), Addr, BaseInfo, TBAAInfo); 4750b57cec5SDimitry Andric return R; 4760b57cec5SDimitry Andric } 4770b57cec5SDimitry Andric 4780eae32dcSDimitry Andric static LValue MakeGlobalReg(llvm::Value *V, CharUnits alignment, 4790eae32dcSDimitry Andric QualType type) { 4800b57cec5SDimitry Andric LValue R; 4810b57cec5SDimitry Andric R.LVType = GlobalReg; 482*0fca6ea1SDimitry Andric R.Initialize(type, type.getQualifiers(), Address::invalid(), 4830b57cec5SDimitry Andric LValueBaseInfo(AlignmentSource::Decl), TBAAAccessInfo()); 484*0fca6ea1SDimitry Andric R.V = V; 4850b57cec5SDimitry Andric return R; 4860b57cec5SDimitry Andric } 4870b57cec5SDimitry Andric 4885ffd83dbSDimitry Andric static LValue MakeMatrixElt(Address matAddress, llvm::Value *Idx, 4895ffd83dbSDimitry Andric QualType type, LValueBaseInfo BaseInfo, 4905ffd83dbSDimitry Andric TBAAAccessInfo TBAAInfo) { 4915ffd83dbSDimitry Andric LValue R; 4925ffd83dbSDimitry Andric R.LVType = MatrixElt; 4935ffd83dbSDimitry Andric R.VectorIdx = Idx; 494*0fca6ea1SDimitry Andric R.Initialize(type, type.getQualifiers(), matAddress, BaseInfo, TBAAInfo); 4955ffd83dbSDimitry Andric return R; 4965ffd83dbSDimitry Andric } 4975ffd83dbSDimitry Andric 498*0fca6ea1SDimitry Andric RValue asAggregateRValue() const { 499*0fca6ea1SDimitry Andric return RValue::getAggregate(getAddress(), isVolatileQualified()); 5000b57cec5SDimitry Andric } 5010b57cec5SDimitry Andric }; 5020b57cec5SDimitry Andric 5030b57cec5SDimitry Andric /// An aggregate value slot. 5040b57cec5SDimitry Andric class AggValueSlot { 5050b57cec5SDimitry Andric /// The address. 5060eae32dcSDimitry Andric Address Addr; 5070b57cec5SDimitry Andric 5080b57cec5SDimitry Andric // Qualifiers 5090b57cec5SDimitry Andric Qualifiers Quals; 5100b57cec5SDimitry Andric 5110b57cec5SDimitry Andric /// DestructedFlag - This is set to true if some external code is 5120b57cec5SDimitry Andric /// responsible for setting up a destructor for the slot. Otherwise 5130b57cec5SDimitry Andric /// the code which constructs it should push the appropriate cleanup. 5140b57cec5SDimitry Andric bool DestructedFlag : 1; 5150b57cec5SDimitry Andric 5160b57cec5SDimitry Andric /// ObjCGCFlag - This is set to true if writing to the memory in the 5170b57cec5SDimitry Andric /// slot might require calling an appropriate Objective-C GC 5180b57cec5SDimitry Andric /// barrier. The exact interaction here is unnecessarily mysterious. 5190b57cec5SDimitry Andric bool ObjCGCFlag : 1; 5200b57cec5SDimitry Andric 5210b57cec5SDimitry Andric /// ZeroedFlag - This is set to true if the memory in the slot is 5220b57cec5SDimitry Andric /// known to be zero before the assignment into it. This means that 5230b57cec5SDimitry Andric /// zero fields don't need to be set. 5240b57cec5SDimitry Andric bool ZeroedFlag : 1; 5250b57cec5SDimitry Andric 5260b57cec5SDimitry Andric /// AliasedFlag - This is set to true if the slot might be aliased 5270b57cec5SDimitry Andric /// and it's not undefined behavior to access it through such an 5280b57cec5SDimitry Andric /// alias. Note that it's always undefined behavior to access a C++ 5290b57cec5SDimitry Andric /// object that's under construction through an alias derived from 5300b57cec5SDimitry Andric /// outside the construction process. 5310b57cec5SDimitry Andric /// 5320b57cec5SDimitry Andric /// This flag controls whether calls that produce the aggregate 5330b57cec5SDimitry Andric /// value may be evaluated directly into the slot, or whether they 5340b57cec5SDimitry Andric /// must be evaluated into an unaliased temporary and then memcpy'ed 5350b57cec5SDimitry Andric /// over. Since it's invalid in general to memcpy a non-POD C++ 5360b57cec5SDimitry Andric /// object, it's important that this flag never be set when 5370b57cec5SDimitry Andric /// evaluating an expression which constructs such an object. 5380b57cec5SDimitry Andric bool AliasedFlag : 1; 5390b57cec5SDimitry Andric 5400b57cec5SDimitry Andric /// This is set to true if the tail padding of this slot might overlap 5410b57cec5SDimitry Andric /// another object that may have already been initialized (and whose 5420b57cec5SDimitry Andric /// value must be preserved by this initialization). If so, we may only 5430b57cec5SDimitry Andric /// store up to the dsize of the type. Otherwise we can widen stores to 5440b57cec5SDimitry Andric /// the size of the type. 5450b57cec5SDimitry Andric bool OverlapFlag : 1; 5460b57cec5SDimitry Andric 5470b57cec5SDimitry Andric /// If is set to true, sanitizer checks are already generated for this address 5480b57cec5SDimitry Andric /// or not required. For instance, if this address represents an object 5490b57cec5SDimitry Andric /// created in 'new' expression, sanitizer checks for memory is made as a part 5500b57cec5SDimitry Andric /// of 'operator new' emission and object constructor should not generate 5510b57cec5SDimitry Andric /// them. 5520b57cec5SDimitry Andric bool SanitizerCheckedFlag : 1; 5530b57cec5SDimitry Andric 5540eae32dcSDimitry Andric AggValueSlot(Address Addr, Qualifiers Quals, bool DestructedFlag, 5550eae32dcSDimitry Andric bool ObjCGCFlag, bool ZeroedFlag, bool AliasedFlag, 5560eae32dcSDimitry Andric bool OverlapFlag, bool SanitizerCheckedFlag) 5570eae32dcSDimitry Andric : Addr(Addr), Quals(Quals), DestructedFlag(DestructedFlag), 5580eae32dcSDimitry Andric ObjCGCFlag(ObjCGCFlag), ZeroedFlag(ZeroedFlag), 5590eae32dcSDimitry Andric AliasedFlag(AliasedFlag), OverlapFlag(OverlapFlag), 5600eae32dcSDimitry Andric SanitizerCheckedFlag(SanitizerCheckedFlag) {} 5610eae32dcSDimitry Andric 5620b57cec5SDimitry Andric public: 5630b57cec5SDimitry Andric enum IsAliased_t { IsNotAliased, IsAliased }; 5640b57cec5SDimitry Andric enum IsDestructed_t { IsNotDestructed, IsDestructed }; 5650b57cec5SDimitry Andric enum IsZeroed_t { IsNotZeroed, IsZeroed }; 5660b57cec5SDimitry Andric enum Overlap_t { DoesNotOverlap, MayOverlap }; 5670b57cec5SDimitry Andric enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers }; 5680b57cec5SDimitry Andric enum IsSanitizerChecked_t { IsNotSanitizerChecked, IsSanitizerChecked }; 5690b57cec5SDimitry Andric 5700b57cec5SDimitry Andric /// ignored - Returns an aggregate value slot indicating that the 5710b57cec5SDimitry Andric /// aggregate value is being ignored. 5720b57cec5SDimitry Andric static AggValueSlot ignored() { 5730b57cec5SDimitry Andric return forAddr(Address::invalid(), Qualifiers(), IsNotDestructed, 5740b57cec5SDimitry Andric DoesNotNeedGCBarriers, IsNotAliased, DoesNotOverlap); 5750b57cec5SDimitry Andric } 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric /// forAddr - Make a slot for an aggregate value. 5780b57cec5SDimitry Andric /// 5790b57cec5SDimitry Andric /// \param quals - The qualifiers that dictate how the slot should 5800b57cec5SDimitry Andric /// be initialied. Only 'volatile' and the Objective-C lifetime 5810b57cec5SDimitry Andric /// qualifiers matter. 5820b57cec5SDimitry Andric /// 5830b57cec5SDimitry Andric /// \param isDestructed - true if something else is responsible 5840b57cec5SDimitry Andric /// for calling destructors on this object 5850b57cec5SDimitry Andric /// \param needsGC - true if the slot is potentially located 5860b57cec5SDimitry Andric /// somewhere that ObjC GC calls should be emitted for 5870b57cec5SDimitry Andric static AggValueSlot forAddr(Address addr, 5880b57cec5SDimitry Andric Qualifiers quals, 5890b57cec5SDimitry Andric IsDestructed_t isDestructed, 5900b57cec5SDimitry Andric NeedsGCBarriers_t needsGC, 5910b57cec5SDimitry Andric IsAliased_t isAliased, 5920b57cec5SDimitry Andric Overlap_t mayOverlap, 5930b57cec5SDimitry Andric IsZeroed_t isZeroed = IsNotZeroed, 5940b57cec5SDimitry Andric IsSanitizerChecked_t isChecked = IsNotSanitizerChecked) { 59506c3fb27SDimitry Andric if (addr.isValid()) 59606c3fb27SDimitry Andric addr.setKnownNonNull(); 5970eae32dcSDimitry Andric return AggValueSlot(addr, quals, isDestructed, needsGC, isZeroed, isAliased, 5980eae32dcSDimitry Andric mayOverlap, isChecked); 5990b57cec5SDimitry Andric } 6000b57cec5SDimitry Andric 601480093f4SDimitry Andric static AggValueSlot 602*0fca6ea1SDimitry Andric forLValue(const LValue &LV, IsDestructed_t isDestructed, 603480093f4SDimitry Andric NeedsGCBarriers_t needsGC, IsAliased_t isAliased, 604480093f4SDimitry Andric Overlap_t mayOverlap, IsZeroed_t isZeroed = IsNotZeroed, 6050b57cec5SDimitry Andric IsSanitizerChecked_t isChecked = IsNotSanitizerChecked) { 606*0fca6ea1SDimitry Andric return forAddr(LV.getAddress(), LV.getQuals(), isDestructed, needsGC, 6070b57cec5SDimitry Andric isAliased, mayOverlap, isZeroed, isChecked); 6080b57cec5SDimitry Andric } 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric IsDestructed_t isExternallyDestructed() const { 6110b57cec5SDimitry Andric return IsDestructed_t(DestructedFlag); 6120b57cec5SDimitry Andric } 6130b57cec5SDimitry Andric void setExternallyDestructed(bool destructed = true) { 6140b57cec5SDimitry Andric DestructedFlag = destructed; 6150b57cec5SDimitry Andric } 6160b57cec5SDimitry Andric 6170b57cec5SDimitry Andric Qualifiers getQualifiers() const { return Quals; } 6180b57cec5SDimitry Andric 6190b57cec5SDimitry Andric bool isVolatile() const { 6200b57cec5SDimitry Andric return Quals.hasVolatile(); 6210b57cec5SDimitry Andric } 6220b57cec5SDimitry Andric 6230b57cec5SDimitry Andric void setVolatile(bool flag) { 6240b57cec5SDimitry Andric if (flag) 6250b57cec5SDimitry Andric Quals.addVolatile(); 6260b57cec5SDimitry Andric else 6270b57cec5SDimitry Andric Quals.removeVolatile(); 6280b57cec5SDimitry Andric } 6290b57cec5SDimitry Andric 6300b57cec5SDimitry Andric Qualifiers::ObjCLifetime getObjCLifetime() const { 6310b57cec5SDimitry Andric return Quals.getObjCLifetime(); 6320b57cec5SDimitry Andric } 6330b57cec5SDimitry Andric 6340b57cec5SDimitry Andric NeedsGCBarriers_t requiresGCollection() const { 6350b57cec5SDimitry Andric return NeedsGCBarriers_t(ObjCGCFlag); 6360b57cec5SDimitry Andric } 6370b57cec5SDimitry Andric 638*0fca6ea1SDimitry Andric llvm::Value *getPointer(QualType PointeeTy, CodeGenFunction &CGF) const; 639*0fca6ea1SDimitry Andric 640*0fca6ea1SDimitry Andric llvm::Value *emitRawPointer(CodeGenFunction &CGF) const { 641*0fca6ea1SDimitry Andric return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr; 6420b57cec5SDimitry Andric } 6430b57cec5SDimitry Andric 6440b57cec5SDimitry Andric Address getAddress() const { 6450eae32dcSDimitry Andric return Addr; 6460b57cec5SDimitry Andric } 6470b57cec5SDimitry Andric 648*0fca6ea1SDimitry Andric bool isIgnored() const { return !Addr.isValid(); } 6490b57cec5SDimitry Andric 6500b57cec5SDimitry Andric CharUnits getAlignment() const { 6510eae32dcSDimitry Andric return Addr.getAlignment(); 6520b57cec5SDimitry Andric } 6530b57cec5SDimitry Andric 6540b57cec5SDimitry Andric IsAliased_t isPotentiallyAliased() const { 6550b57cec5SDimitry Andric return IsAliased_t(AliasedFlag); 6560b57cec5SDimitry Andric } 6570b57cec5SDimitry Andric 6580b57cec5SDimitry Andric Overlap_t mayOverlap() const { 6590b57cec5SDimitry Andric return Overlap_t(OverlapFlag); 6600b57cec5SDimitry Andric } 6610b57cec5SDimitry Andric 6620b57cec5SDimitry Andric bool isSanitizerChecked() const { 6630b57cec5SDimitry Andric return SanitizerCheckedFlag; 6640b57cec5SDimitry Andric } 6650b57cec5SDimitry Andric 6660b57cec5SDimitry Andric RValue asRValue() const { 6670b57cec5SDimitry Andric if (isIgnored()) { 6680b57cec5SDimitry Andric return RValue::getIgnored(); 6690b57cec5SDimitry Andric } else { 6700b57cec5SDimitry Andric return RValue::getAggregate(getAddress(), isVolatile()); 6710b57cec5SDimitry Andric } 6720b57cec5SDimitry Andric } 6730b57cec5SDimitry Andric 6740b57cec5SDimitry Andric void setZeroed(bool V = true) { ZeroedFlag = V; } 6750b57cec5SDimitry Andric IsZeroed_t isZeroed() const { 6760b57cec5SDimitry Andric return IsZeroed_t(ZeroedFlag); 6770b57cec5SDimitry Andric } 6780b57cec5SDimitry Andric 6790b57cec5SDimitry Andric /// Get the preferred size to use when storing a value to this slot. This 6800b57cec5SDimitry Andric /// is the type size unless that might overlap another object, in which 6810b57cec5SDimitry Andric /// case it's the dsize. 6820b57cec5SDimitry Andric CharUnits getPreferredSize(ASTContext &Ctx, QualType Type) const { 683e8d8bef9SDimitry Andric return mayOverlap() ? Ctx.getTypeInfoDataSizeInChars(Type).Width 6840b57cec5SDimitry Andric : Ctx.getTypeSizeInChars(Type); 6850b57cec5SDimitry Andric } 6860b57cec5SDimitry Andric }; 6870b57cec5SDimitry Andric 6880b57cec5SDimitry Andric } // end namespace CodeGen 6890b57cec5SDimitry Andric } // end namespace clang 6900b57cec5SDimitry Andric 6910b57cec5SDimitry Andric #endif 692