xref: /openbsd-src/gnu/llvm/clang/lib/CodeGen/CGValue.h (revision 12c855180aad702bbcca06e0398d774beeafb155)
1e5dd7070Spatrick //===-- CGValue.h - LLVM CodeGen wrappers for llvm::Value* ------*- C++ -*-===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // These classes implement wrappers around llvm::Value in order to
10e5dd7070Spatrick // fully represent the range of values for C L- and R- values.
11e5dd7070Spatrick //
12e5dd7070Spatrick //===----------------------------------------------------------------------===//
13e5dd7070Spatrick 
14e5dd7070Spatrick #ifndef LLVM_CLANG_LIB_CODEGEN_CGVALUE_H
15e5dd7070Spatrick #define LLVM_CLANG_LIB_CODEGEN_CGVALUE_H
16e5dd7070Spatrick 
17e5dd7070Spatrick #include "clang/AST/ASTContext.h"
18e5dd7070Spatrick #include "clang/AST/Type.h"
19e5dd7070Spatrick #include "llvm/IR/Value.h"
20e5dd7070Spatrick #include "llvm/IR/Type.h"
21e5dd7070Spatrick #include "Address.h"
22e5dd7070Spatrick #include "CodeGenTBAA.h"
23e5dd7070Spatrick 
24e5dd7070Spatrick namespace llvm {
25e5dd7070Spatrick   class Constant;
26e5dd7070Spatrick   class MDNode;
27e5dd7070Spatrick }
28e5dd7070Spatrick 
29e5dd7070Spatrick namespace clang {
30e5dd7070Spatrick namespace CodeGen {
31e5dd7070Spatrick   class AggValueSlot;
32e5dd7070Spatrick   class CodeGenFunction;
33e5dd7070Spatrick   struct CGBitFieldInfo;
34e5dd7070Spatrick 
35e5dd7070Spatrick /// RValue - This trivial value class is used to represent the result of an
36e5dd7070Spatrick /// expression that is evaluated.  It can be one of three things: either a
37e5dd7070Spatrick /// simple LLVM SSA value, a pair of SSA values for complex numbers, or the
38e5dd7070Spatrick /// address of an aggregate value in memory.
39e5dd7070Spatrick class RValue {
40e5dd7070Spatrick   enum Flavor { Scalar, Complex, Aggregate };
41e5dd7070Spatrick 
42e5dd7070Spatrick   // The shift to make to an aggregate's alignment to make it look
43e5dd7070Spatrick   // like a pointer.
44e5dd7070Spatrick   enum { AggAlignShift = 4 };
45e5dd7070Spatrick 
46e5dd7070Spatrick   // Stores first value and flavor.
47e5dd7070Spatrick   llvm::PointerIntPair<llvm::Value *, 2, Flavor> V1;
48e5dd7070Spatrick   // Stores second value and volatility.
49e5dd7070Spatrick   llvm::PointerIntPair<llvm::Value *, 1, bool> V2;
50*12c85518Srobert   // Stores element type for aggregate values.
51*12c85518Srobert   llvm::Type *ElementType;
52e5dd7070Spatrick 
53e5dd7070Spatrick public:
isScalar()54e5dd7070Spatrick   bool isScalar() const { return V1.getInt() == Scalar; }
isComplex()55e5dd7070Spatrick   bool isComplex() const { return V1.getInt() == Complex; }
isAggregate()56e5dd7070Spatrick   bool isAggregate() const { return V1.getInt() == Aggregate; }
57e5dd7070Spatrick 
isVolatileQualified()58e5dd7070Spatrick   bool isVolatileQualified() const { return V2.getInt(); }
59e5dd7070Spatrick 
60e5dd7070Spatrick   /// getScalarVal() - Return the Value* of this scalar value.
getScalarVal()61e5dd7070Spatrick   llvm::Value *getScalarVal() const {
62e5dd7070Spatrick     assert(isScalar() && "Not a scalar!");
63e5dd7070Spatrick     return V1.getPointer();
64e5dd7070Spatrick   }
65e5dd7070Spatrick 
66e5dd7070Spatrick   /// getComplexVal - Return the real/imag components of this complex value.
67e5dd7070Spatrick   ///
getComplexVal()68e5dd7070Spatrick   std::pair<llvm::Value *, llvm::Value *> getComplexVal() const {
69e5dd7070Spatrick     return std::make_pair(V1.getPointer(), V2.getPointer());
70e5dd7070Spatrick   }
71e5dd7070Spatrick 
72e5dd7070Spatrick   /// getAggregateAddr() - Return the Value* of the address of the aggregate.
getAggregateAddress()73e5dd7070Spatrick   Address getAggregateAddress() const {
74e5dd7070Spatrick     assert(isAggregate() && "Not an aggregate!");
75e5dd7070Spatrick     auto align = reinterpret_cast<uintptr_t>(V2.getPointer()) >> AggAlignShift;
76*12c85518Srobert     return Address(
77*12c85518Srobert         V1.getPointer(), ElementType, CharUnits::fromQuantity(align));
78e5dd7070Spatrick   }
getAggregatePointer()79e5dd7070Spatrick   llvm::Value *getAggregatePointer() const {
80e5dd7070Spatrick     assert(isAggregate() && "Not an aggregate!");
81e5dd7070Spatrick     return V1.getPointer();
82e5dd7070Spatrick   }
83e5dd7070Spatrick 
getIgnored()84e5dd7070Spatrick   static RValue getIgnored() {
85e5dd7070Spatrick     // FIXME: should we make this a more explicit state?
86e5dd7070Spatrick     return get(nullptr);
87e5dd7070Spatrick   }
88e5dd7070Spatrick 
get(llvm::Value * V)89e5dd7070Spatrick   static RValue get(llvm::Value *V) {
90e5dd7070Spatrick     RValue ER;
91e5dd7070Spatrick     ER.V1.setPointer(V);
92e5dd7070Spatrick     ER.V1.setInt(Scalar);
93e5dd7070Spatrick     ER.V2.setInt(false);
94e5dd7070Spatrick     return ER;
95e5dd7070Spatrick   }
getComplex(llvm::Value * V1,llvm::Value * V2)96e5dd7070Spatrick   static RValue getComplex(llvm::Value *V1, llvm::Value *V2) {
97e5dd7070Spatrick     RValue ER;
98e5dd7070Spatrick     ER.V1.setPointer(V1);
99e5dd7070Spatrick     ER.V2.setPointer(V2);
100e5dd7070Spatrick     ER.V1.setInt(Complex);
101e5dd7070Spatrick     ER.V2.setInt(false);
102e5dd7070Spatrick     return ER;
103e5dd7070Spatrick   }
getComplex(const std::pair<llvm::Value *,llvm::Value * > & C)104e5dd7070Spatrick   static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) {
105e5dd7070Spatrick     return getComplex(C.first, C.second);
106e5dd7070Spatrick   }
107e5dd7070Spatrick   // FIXME: Aggregate rvalues need to retain information about whether they are
108e5dd7070Spatrick   // volatile or not.  Remove default to find all places that probably get this
109e5dd7070Spatrick   // wrong.
110e5dd7070Spatrick   static RValue getAggregate(Address addr, bool isVolatile = false) {
111e5dd7070Spatrick     RValue ER;
112e5dd7070Spatrick     ER.V1.setPointer(addr.getPointer());
113e5dd7070Spatrick     ER.V1.setInt(Aggregate);
114*12c85518Srobert     ER.ElementType = addr.getElementType();
115e5dd7070Spatrick 
116e5dd7070Spatrick     auto align = static_cast<uintptr_t>(addr.getAlignment().getQuantity());
117e5dd7070Spatrick     ER.V2.setPointer(reinterpret_cast<llvm::Value*>(align << AggAlignShift));
118e5dd7070Spatrick     ER.V2.setInt(isVolatile);
119e5dd7070Spatrick     return ER;
120e5dd7070Spatrick   }
121e5dd7070Spatrick };
122e5dd7070Spatrick 
123e5dd7070Spatrick /// Does an ARC strong l-value have precise lifetime?
124e5dd7070Spatrick enum ARCPreciseLifetime_t {
125e5dd7070Spatrick   ARCImpreciseLifetime, ARCPreciseLifetime
126e5dd7070Spatrick };
127e5dd7070Spatrick 
128e5dd7070Spatrick /// The source of the alignment of an l-value; an expression of
129e5dd7070Spatrick /// confidence in the alignment actually matching the estimate.
130e5dd7070Spatrick enum class AlignmentSource {
131e5dd7070Spatrick   /// The l-value was an access to a declared entity or something
132e5dd7070Spatrick   /// equivalently strong, like the address of an array allocated by a
133e5dd7070Spatrick   /// language runtime.
134e5dd7070Spatrick   Decl,
135e5dd7070Spatrick 
136e5dd7070Spatrick   /// The l-value was considered opaque, so the alignment was
137e5dd7070Spatrick   /// determined from a type, but that type was an explicitly-aligned
138e5dd7070Spatrick   /// typedef.
139e5dd7070Spatrick   AttributedType,
140e5dd7070Spatrick 
141e5dd7070Spatrick   /// The l-value was considered opaque, so the alignment was
142e5dd7070Spatrick   /// determined from a type.
143e5dd7070Spatrick   Type
144e5dd7070Spatrick };
145e5dd7070Spatrick 
146e5dd7070Spatrick /// Given that the base address has the given alignment source, what's
147e5dd7070Spatrick /// our confidence in the alignment of the field?
getFieldAlignmentSource(AlignmentSource Source)148e5dd7070Spatrick static inline AlignmentSource getFieldAlignmentSource(AlignmentSource Source) {
149e5dd7070Spatrick   // For now, we don't distinguish fields of opaque pointers from
150e5dd7070Spatrick   // top-level declarations, but maybe we should.
151e5dd7070Spatrick   return AlignmentSource::Decl;
152e5dd7070Spatrick }
153e5dd7070Spatrick 
154e5dd7070Spatrick class LValueBaseInfo {
155e5dd7070Spatrick   AlignmentSource AlignSource;
156e5dd7070Spatrick 
157e5dd7070Spatrick public:
158e5dd7070Spatrick   explicit LValueBaseInfo(AlignmentSource Source = AlignmentSource::Type)
AlignSource(Source)159e5dd7070Spatrick     : AlignSource(Source) {}
getAlignmentSource()160e5dd7070Spatrick   AlignmentSource getAlignmentSource() const { return AlignSource; }
setAlignmentSource(AlignmentSource Source)161e5dd7070Spatrick   void setAlignmentSource(AlignmentSource Source) { AlignSource = Source; }
162e5dd7070Spatrick 
mergeForCast(const LValueBaseInfo & Info)163e5dd7070Spatrick   void mergeForCast(const LValueBaseInfo &Info) {
164e5dd7070Spatrick     setAlignmentSource(Info.getAlignmentSource());
165e5dd7070Spatrick   }
166e5dd7070Spatrick };
167e5dd7070Spatrick 
168e5dd7070Spatrick /// LValue - This represents an lvalue references.  Because C/C++ allow
169e5dd7070Spatrick /// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a
170e5dd7070Spatrick /// bitrange.
171e5dd7070Spatrick class LValue {
172e5dd7070Spatrick   enum {
173e5dd7070Spatrick     Simple,       // This is a normal l-value, use getAddress().
174e5dd7070Spatrick     VectorElt,    // This is a vector element l-value (V[i]), use getVector*
175e5dd7070Spatrick     BitField,     // This is a bitfield l-value, use getBitfield*.
176e5dd7070Spatrick     ExtVectorElt, // This is an extended vector subset, use getExtVectorComp
177ec727ea7Spatrick     GlobalReg,    // This is a register l-value, use getGlobalReg()
178ec727ea7Spatrick     MatrixElt     // This is a matrix element, use getVector*
179e5dd7070Spatrick   } LVType;
180e5dd7070Spatrick 
181e5dd7070Spatrick   llvm::Value *V;
182*12c85518Srobert   llvm::Type *ElementType;
183e5dd7070Spatrick 
184e5dd7070Spatrick   union {
185e5dd7070Spatrick     // Index into a vector subscript: V[i]
186e5dd7070Spatrick     llvm::Value *VectorIdx;
187e5dd7070Spatrick 
188e5dd7070Spatrick     // ExtVector element subset: V.xyx
189e5dd7070Spatrick     llvm::Constant *VectorElts;
190e5dd7070Spatrick 
191e5dd7070Spatrick     // BitField start bit and size
192e5dd7070Spatrick     const CGBitFieldInfo *BitFieldInfo;
193e5dd7070Spatrick   };
194e5dd7070Spatrick 
195e5dd7070Spatrick   QualType Type;
196e5dd7070Spatrick 
197e5dd7070Spatrick   // 'const' is unused here
198e5dd7070Spatrick   Qualifiers Quals;
199e5dd7070Spatrick 
200e5dd7070Spatrick   // The alignment to use when accessing this lvalue.  (For vector elements,
201e5dd7070Spatrick   // this is the alignment of the whole vector.)
202e5dd7070Spatrick   unsigned Alignment;
203e5dd7070Spatrick 
204e5dd7070Spatrick   // objective-c's ivar
205e5dd7070Spatrick   bool Ivar:1;
206e5dd7070Spatrick 
207e5dd7070Spatrick   // objective-c's ivar is an array
208e5dd7070Spatrick   bool ObjIsArray:1;
209e5dd7070Spatrick 
210e5dd7070Spatrick   // LValue is non-gc'able for any reason, including being a parameter or local
211e5dd7070Spatrick   // variable.
212e5dd7070Spatrick   bool NonGC: 1;
213e5dd7070Spatrick 
214e5dd7070Spatrick   // Lvalue is a global reference of an objective-c object
215e5dd7070Spatrick   bool GlobalObjCRef : 1;
216e5dd7070Spatrick 
217e5dd7070Spatrick   // Lvalue is a thread local reference
218e5dd7070Spatrick   bool ThreadLocalRef : 1;
219e5dd7070Spatrick 
220e5dd7070Spatrick   // Lvalue has ARC imprecise lifetime.  We store this inverted to try
221e5dd7070Spatrick   // to make the default bitfield pattern all-zeroes.
222e5dd7070Spatrick   bool ImpreciseLifetime : 1;
223e5dd7070Spatrick 
224e5dd7070Spatrick   // This flag shows if a nontemporal load/stores should be used when accessing
225e5dd7070Spatrick   // this lvalue.
226e5dd7070Spatrick   bool Nontemporal : 1;
227e5dd7070Spatrick 
228e5dd7070Spatrick   LValueBaseInfo BaseInfo;
229e5dd7070Spatrick   TBAAAccessInfo TBAAInfo;
230e5dd7070Spatrick 
231e5dd7070Spatrick   Expr *BaseIvarExp;
232e5dd7070Spatrick 
233e5dd7070Spatrick private:
Initialize(QualType Type,Qualifiers Quals,CharUnits Alignment,LValueBaseInfo BaseInfo,TBAAAccessInfo TBAAInfo)234e5dd7070Spatrick   void Initialize(QualType Type, Qualifiers Quals, CharUnits Alignment,
235e5dd7070Spatrick                   LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) {
236e5dd7070Spatrick     assert((!Alignment.isZero() || Type->isIncompleteType()) &&
237e5dd7070Spatrick            "initializing l-value with zero alignment!");
238*12c85518Srobert     if (isGlobalReg())
239*12c85518Srobert       assert(ElementType == nullptr && "Global reg does not store elem type");
240*12c85518Srobert     else
241*12c85518Srobert       assert(llvm::cast<llvm::PointerType>(V->getType())
242*12c85518Srobert                  ->isOpaqueOrPointeeTypeMatches(ElementType) &&
243*12c85518Srobert              "Pointer element type mismatch");
244*12c85518Srobert 
245e5dd7070Spatrick     this->Type = Type;
246e5dd7070Spatrick     this->Quals = Quals;
247e5dd7070Spatrick     const unsigned MaxAlign = 1U << 31;
248e5dd7070Spatrick     this->Alignment = Alignment.getQuantity() <= MaxAlign
249e5dd7070Spatrick                           ? Alignment.getQuantity()
250e5dd7070Spatrick                           : MaxAlign;
251e5dd7070Spatrick     assert(this->Alignment == Alignment.getQuantity() &&
252e5dd7070Spatrick            "Alignment exceeds allowed max!");
253e5dd7070Spatrick     this->BaseInfo = BaseInfo;
254e5dd7070Spatrick     this->TBAAInfo = TBAAInfo;
255e5dd7070Spatrick 
256e5dd7070Spatrick     // Initialize Objective-C flags.
257e5dd7070Spatrick     this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false;
258e5dd7070Spatrick     this->ImpreciseLifetime = false;
259e5dd7070Spatrick     this->Nontemporal = false;
260e5dd7070Spatrick     this->ThreadLocalRef = false;
261e5dd7070Spatrick     this->BaseIvarExp = nullptr;
262e5dd7070Spatrick   }
263e5dd7070Spatrick 
264e5dd7070Spatrick public:
isSimple()265e5dd7070Spatrick   bool isSimple() const { return LVType == Simple; }
isVectorElt()266e5dd7070Spatrick   bool isVectorElt() const { return LVType == VectorElt; }
isBitField()267e5dd7070Spatrick   bool isBitField() const { return LVType == BitField; }
isExtVectorElt()268e5dd7070Spatrick   bool isExtVectorElt() const { return LVType == ExtVectorElt; }
isGlobalReg()269e5dd7070Spatrick   bool isGlobalReg() const { return LVType == GlobalReg; }
isMatrixElt()270ec727ea7Spatrick   bool isMatrixElt() const { return LVType == MatrixElt; }
271e5dd7070Spatrick 
isVolatileQualified()272e5dd7070Spatrick   bool isVolatileQualified() const { return Quals.hasVolatile(); }
isRestrictQualified()273e5dd7070Spatrick   bool isRestrictQualified() const { return Quals.hasRestrict(); }
getVRQualifiers()274e5dd7070Spatrick   unsigned getVRQualifiers() const {
275e5dd7070Spatrick     return Quals.getCVRQualifiers() & ~Qualifiers::Const;
276e5dd7070Spatrick   }
277e5dd7070Spatrick 
getType()278e5dd7070Spatrick   QualType getType() const { return Type; }
279e5dd7070Spatrick 
getObjCLifetime()280e5dd7070Spatrick   Qualifiers::ObjCLifetime getObjCLifetime() const {
281e5dd7070Spatrick     return Quals.getObjCLifetime();
282e5dd7070Spatrick   }
283e5dd7070Spatrick 
isObjCIvar()284e5dd7070Spatrick   bool isObjCIvar() const { return Ivar; }
setObjCIvar(bool Value)285e5dd7070Spatrick   void setObjCIvar(bool Value) { Ivar = Value; }
286e5dd7070Spatrick 
isObjCArray()287e5dd7070Spatrick   bool isObjCArray() const { return ObjIsArray; }
setObjCArray(bool Value)288e5dd7070Spatrick   void setObjCArray(bool Value) { ObjIsArray = Value; }
289e5dd7070Spatrick 
isNonGC()290e5dd7070Spatrick   bool isNonGC () const { return NonGC; }
setNonGC(bool Value)291e5dd7070Spatrick   void setNonGC(bool Value) { NonGC = Value; }
292e5dd7070Spatrick 
isGlobalObjCRef()293e5dd7070Spatrick   bool isGlobalObjCRef() const { return GlobalObjCRef; }
setGlobalObjCRef(bool Value)294e5dd7070Spatrick   void setGlobalObjCRef(bool Value) { GlobalObjCRef = Value; }
295e5dd7070Spatrick 
isThreadLocalRef()296e5dd7070Spatrick   bool isThreadLocalRef() const { return ThreadLocalRef; }
setThreadLocalRef(bool Value)297e5dd7070Spatrick   void setThreadLocalRef(bool Value) { ThreadLocalRef = Value;}
298e5dd7070Spatrick 
isARCPreciseLifetime()299e5dd7070Spatrick   ARCPreciseLifetime_t isARCPreciseLifetime() const {
300e5dd7070Spatrick     return ARCPreciseLifetime_t(!ImpreciseLifetime);
301e5dd7070Spatrick   }
setARCPreciseLifetime(ARCPreciseLifetime_t value)302e5dd7070Spatrick   void setARCPreciseLifetime(ARCPreciseLifetime_t value) {
303e5dd7070Spatrick     ImpreciseLifetime = (value == ARCImpreciseLifetime);
304e5dd7070Spatrick   }
isNontemporal()305e5dd7070Spatrick   bool isNontemporal() const { return Nontemporal; }
setNontemporal(bool Value)306e5dd7070Spatrick   void setNontemporal(bool Value) { Nontemporal = Value; }
307e5dd7070Spatrick 
isObjCWeak()308e5dd7070Spatrick   bool isObjCWeak() const {
309e5dd7070Spatrick     return Quals.getObjCGCAttr() == Qualifiers::Weak;
310e5dd7070Spatrick   }
isObjCStrong()311e5dd7070Spatrick   bool isObjCStrong() const {
312e5dd7070Spatrick     return Quals.getObjCGCAttr() == Qualifiers::Strong;
313e5dd7070Spatrick   }
314e5dd7070Spatrick 
isVolatile()315e5dd7070Spatrick   bool isVolatile() const {
316e5dd7070Spatrick     return Quals.hasVolatile();
317e5dd7070Spatrick   }
318e5dd7070Spatrick 
getBaseIvarExp()319e5dd7070Spatrick   Expr *getBaseIvarExp() const { return BaseIvarExp; }
setBaseIvarExp(Expr * V)320e5dd7070Spatrick   void setBaseIvarExp(Expr *V) { BaseIvarExp = V; }
321e5dd7070Spatrick 
getTBAAInfo()322e5dd7070Spatrick   TBAAAccessInfo getTBAAInfo() const { return TBAAInfo; }
setTBAAInfo(TBAAAccessInfo Info)323e5dd7070Spatrick   void setTBAAInfo(TBAAAccessInfo Info) { TBAAInfo = Info; }
324e5dd7070Spatrick 
getQuals()325e5dd7070Spatrick   const Qualifiers &getQuals() const { return Quals; }
getQuals()326e5dd7070Spatrick   Qualifiers &getQuals() { return Quals; }
327e5dd7070Spatrick 
getAddressSpace()328e5dd7070Spatrick   LangAS getAddressSpace() const { return Quals.getAddressSpace(); }
329e5dd7070Spatrick 
getAlignment()330e5dd7070Spatrick   CharUnits getAlignment() const { return CharUnits::fromQuantity(Alignment); }
setAlignment(CharUnits A)331e5dd7070Spatrick   void setAlignment(CharUnits A) { Alignment = A.getQuantity(); }
332e5dd7070Spatrick 
getBaseInfo()333e5dd7070Spatrick   LValueBaseInfo getBaseInfo() const { return BaseInfo; }
setBaseInfo(LValueBaseInfo Info)334e5dd7070Spatrick   void setBaseInfo(LValueBaseInfo Info) { BaseInfo = Info; }
335e5dd7070Spatrick 
336e5dd7070Spatrick   // simple lvalue
getPointer(CodeGenFunction & CGF)337e5dd7070Spatrick   llvm::Value *getPointer(CodeGenFunction &CGF) const {
338e5dd7070Spatrick     assert(isSimple());
339e5dd7070Spatrick     return V;
340e5dd7070Spatrick   }
getAddress(CodeGenFunction & CGF)341e5dd7070Spatrick   Address getAddress(CodeGenFunction &CGF) const {
342*12c85518Srobert     return Address(getPointer(CGF), ElementType, getAlignment());
343e5dd7070Spatrick   }
setAddress(Address address)344e5dd7070Spatrick   void setAddress(Address address) {
345e5dd7070Spatrick     assert(isSimple());
346e5dd7070Spatrick     V = address.getPointer();
347*12c85518Srobert     ElementType = address.getElementType();
348e5dd7070Spatrick     Alignment = address.getAlignment().getQuantity();
349e5dd7070Spatrick   }
350e5dd7070Spatrick 
351e5dd7070Spatrick   // vector elt lvalue
getVectorAddress()352e5dd7070Spatrick   Address getVectorAddress() const {
353*12c85518Srobert     return Address(getVectorPointer(), ElementType, getAlignment());
354e5dd7070Spatrick   }
getVectorPointer()355ec727ea7Spatrick   llvm::Value *getVectorPointer() const {
356ec727ea7Spatrick     assert(isVectorElt());
357ec727ea7Spatrick     return V;
358ec727ea7Spatrick   }
getVectorIdx()359ec727ea7Spatrick   llvm::Value *getVectorIdx() const {
360ec727ea7Spatrick     assert(isVectorElt());
361ec727ea7Spatrick     return VectorIdx;
362ec727ea7Spatrick   }
363ec727ea7Spatrick 
getMatrixAddress()364ec727ea7Spatrick   Address getMatrixAddress() const {
365*12c85518Srobert     return Address(getMatrixPointer(), ElementType, getAlignment());
366ec727ea7Spatrick   }
getMatrixPointer()367ec727ea7Spatrick   llvm::Value *getMatrixPointer() const {
368ec727ea7Spatrick     assert(isMatrixElt());
369ec727ea7Spatrick     return V;
370ec727ea7Spatrick   }
getMatrixIdx()371ec727ea7Spatrick   llvm::Value *getMatrixIdx() const {
372ec727ea7Spatrick     assert(isMatrixElt());
373ec727ea7Spatrick     return VectorIdx;
374ec727ea7Spatrick   }
375e5dd7070Spatrick 
376e5dd7070Spatrick   // extended vector elements.
getExtVectorAddress()377e5dd7070Spatrick   Address getExtVectorAddress() const {
378*12c85518Srobert     return Address(getExtVectorPointer(), ElementType, getAlignment());
379e5dd7070Spatrick   }
getExtVectorPointer()380e5dd7070Spatrick   llvm::Value *getExtVectorPointer() const {
381e5dd7070Spatrick     assert(isExtVectorElt());
382e5dd7070Spatrick     return V;
383e5dd7070Spatrick   }
getExtVectorElts()384e5dd7070Spatrick   llvm::Constant *getExtVectorElts() const {
385e5dd7070Spatrick     assert(isExtVectorElt());
386e5dd7070Spatrick     return VectorElts;
387e5dd7070Spatrick   }
388e5dd7070Spatrick 
389e5dd7070Spatrick   // bitfield lvalue
getBitFieldAddress()390e5dd7070Spatrick   Address getBitFieldAddress() const {
391*12c85518Srobert     return Address(getBitFieldPointer(), ElementType, getAlignment());
392e5dd7070Spatrick   }
getBitFieldPointer()393e5dd7070Spatrick   llvm::Value *getBitFieldPointer() const { assert(isBitField()); return V; }
getBitFieldInfo()394e5dd7070Spatrick   const CGBitFieldInfo &getBitFieldInfo() const {
395e5dd7070Spatrick     assert(isBitField());
396e5dd7070Spatrick     return *BitFieldInfo;
397e5dd7070Spatrick   }
398e5dd7070Spatrick 
399e5dd7070Spatrick   // global register lvalue
getGlobalReg()400e5dd7070Spatrick   llvm::Value *getGlobalReg() const { assert(isGlobalReg()); return V; }
401e5dd7070Spatrick 
MakeAddr(Address address,QualType type,ASTContext & Context,LValueBaseInfo BaseInfo,TBAAAccessInfo TBAAInfo)402e5dd7070Spatrick   static LValue MakeAddr(Address address, QualType type, ASTContext &Context,
403e5dd7070Spatrick                          LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) {
404e5dd7070Spatrick     Qualifiers qs = type.getQualifiers();
405e5dd7070Spatrick     qs.setObjCGCAttr(Context.getObjCGCAttrKind(type));
406e5dd7070Spatrick 
407e5dd7070Spatrick     LValue R;
408e5dd7070Spatrick     R.LVType = Simple;
409e5dd7070Spatrick     assert(address.getPointer()->getType()->isPointerTy());
410e5dd7070Spatrick     R.V = address.getPointer();
411*12c85518Srobert     R.ElementType = address.getElementType();
412e5dd7070Spatrick     R.Initialize(type, qs, address.getAlignment(), BaseInfo, TBAAInfo);
413e5dd7070Spatrick     return R;
414e5dd7070Spatrick   }
415e5dd7070Spatrick 
MakeVectorElt(Address vecAddress,llvm::Value * Idx,QualType type,LValueBaseInfo BaseInfo,TBAAAccessInfo TBAAInfo)416e5dd7070Spatrick   static LValue MakeVectorElt(Address vecAddress, llvm::Value *Idx,
417e5dd7070Spatrick                               QualType type, LValueBaseInfo BaseInfo,
418e5dd7070Spatrick                               TBAAAccessInfo TBAAInfo) {
419e5dd7070Spatrick     LValue R;
420e5dd7070Spatrick     R.LVType = VectorElt;
421e5dd7070Spatrick     R.V = vecAddress.getPointer();
422*12c85518Srobert     R.ElementType = vecAddress.getElementType();
423e5dd7070Spatrick     R.VectorIdx = Idx;
424e5dd7070Spatrick     R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(),
425e5dd7070Spatrick                  BaseInfo, TBAAInfo);
426e5dd7070Spatrick     return R;
427e5dd7070Spatrick   }
428e5dd7070Spatrick 
MakeExtVectorElt(Address vecAddress,llvm::Constant * Elts,QualType type,LValueBaseInfo BaseInfo,TBAAAccessInfo TBAAInfo)429e5dd7070Spatrick   static LValue MakeExtVectorElt(Address vecAddress, llvm::Constant *Elts,
430e5dd7070Spatrick                                  QualType type, LValueBaseInfo BaseInfo,
431e5dd7070Spatrick                                  TBAAAccessInfo TBAAInfo) {
432e5dd7070Spatrick     LValue R;
433e5dd7070Spatrick     R.LVType = ExtVectorElt;
434e5dd7070Spatrick     R.V = vecAddress.getPointer();
435*12c85518Srobert     R.ElementType = vecAddress.getElementType();
436e5dd7070Spatrick     R.VectorElts = Elts;
437e5dd7070Spatrick     R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(),
438e5dd7070Spatrick                  BaseInfo, TBAAInfo);
439e5dd7070Spatrick     return R;
440e5dd7070Spatrick   }
441e5dd7070Spatrick 
442e5dd7070Spatrick   /// Create a new object to represent a bit-field access.
443e5dd7070Spatrick   ///
444e5dd7070Spatrick   /// \param Addr - The base address of the bit-field sequence this
445e5dd7070Spatrick   /// bit-field refers to.
446e5dd7070Spatrick   /// \param Info - The information describing how to perform the bit-field
447e5dd7070Spatrick   /// access.
MakeBitfield(Address Addr,const CGBitFieldInfo & Info,QualType type,LValueBaseInfo BaseInfo,TBAAAccessInfo TBAAInfo)448e5dd7070Spatrick   static LValue MakeBitfield(Address Addr, const CGBitFieldInfo &Info,
449e5dd7070Spatrick                              QualType type, LValueBaseInfo BaseInfo,
450e5dd7070Spatrick                              TBAAAccessInfo TBAAInfo) {
451e5dd7070Spatrick     LValue R;
452e5dd7070Spatrick     R.LVType = BitField;
453e5dd7070Spatrick     R.V = Addr.getPointer();
454*12c85518Srobert     R.ElementType = Addr.getElementType();
455e5dd7070Spatrick     R.BitFieldInfo = &Info;
456e5dd7070Spatrick     R.Initialize(type, type.getQualifiers(), Addr.getAlignment(), BaseInfo,
457e5dd7070Spatrick                  TBAAInfo);
458e5dd7070Spatrick     return R;
459e5dd7070Spatrick   }
460e5dd7070Spatrick 
MakeGlobalReg(llvm::Value * V,CharUnits alignment,QualType type)461*12c85518Srobert   static LValue MakeGlobalReg(llvm::Value *V, CharUnits alignment,
462*12c85518Srobert                               QualType type) {
463e5dd7070Spatrick     LValue R;
464e5dd7070Spatrick     R.LVType = GlobalReg;
465*12c85518Srobert     R.V = V;
466*12c85518Srobert     R.ElementType = nullptr;
467*12c85518Srobert     R.Initialize(type, type.getQualifiers(), alignment,
468e5dd7070Spatrick                  LValueBaseInfo(AlignmentSource::Decl), TBAAAccessInfo());
469e5dd7070Spatrick     return R;
470e5dd7070Spatrick   }
471e5dd7070Spatrick 
MakeMatrixElt(Address matAddress,llvm::Value * Idx,QualType type,LValueBaseInfo BaseInfo,TBAAAccessInfo TBAAInfo)472ec727ea7Spatrick   static LValue MakeMatrixElt(Address matAddress, llvm::Value *Idx,
473ec727ea7Spatrick                               QualType type, LValueBaseInfo BaseInfo,
474ec727ea7Spatrick                               TBAAAccessInfo TBAAInfo) {
475ec727ea7Spatrick     LValue R;
476ec727ea7Spatrick     R.LVType = MatrixElt;
477ec727ea7Spatrick     R.V = matAddress.getPointer();
478*12c85518Srobert     R.ElementType = matAddress.getElementType();
479ec727ea7Spatrick     R.VectorIdx = Idx;
480ec727ea7Spatrick     R.Initialize(type, type.getQualifiers(), matAddress.getAlignment(),
481ec727ea7Spatrick                  BaseInfo, TBAAInfo);
482ec727ea7Spatrick     return R;
483ec727ea7Spatrick   }
484ec727ea7Spatrick 
asAggregateRValue(CodeGenFunction & CGF)485e5dd7070Spatrick   RValue asAggregateRValue(CodeGenFunction &CGF) const {
486e5dd7070Spatrick     return RValue::getAggregate(getAddress(CGF), isVolatileQualified());
487e5dd7070Spatrick   }
488e5dd7070Spatrick };
489e5dd7070Spatrick 
490e5dd7070Spatrick /// An aggregate value slot.
491e5dd7070Spatrick class AggValueSlot {
492e5dd7070Spatrick   /// The address.
493*12c85518Srobert   Address Addr;
494e5dd7070Spatrick 
495e5dd7070Spatrick   // Qualifiers
496e5dd7070Spatrick   Qualifiers Quals;
497e5dd7070Spatrick 
498e5dd7070Spatrick   /// DestructedFlag - This is set to true if some external code is
499e5dd7070Spatrick   /// responsible for setting up a destructor for the slot.  Otherwise
500e5dd7070Spatrick   /// the code which constructs it should push the appropriate cleanup.
501e5dd7070Spatrick   bool DestructedFlag : 1;
502e5dd7070Spatrick 
503e5dd7070Spatrick   /// ObjCGCFlag - This is set to true if writing to the memory in the
504e5dd7070Spatrick   /// slot might require calling an appropriate Objective-C GC
505e5dd7070Spatrick   /// barrier.  The exact interaction here is unnecessarily mysterious.
506e5dd7070Spatrick   bool ObjCGCFlag : 1;
507e5dd7070Spatrick 
508e5dd7070Spatrick   /// ZeroedFlag - This is set to true if the memory in the slot is
509e5dd7070Spatrick   /// known to be zero before the assignment into it.  This means that
510e5dd7070Spatrick   /// zero fields don't need to be set.
511e5dd7070Spatrick   bool ZeroedFlag : 1;
512e5dd7070Spatrick 
513e5dd7070Spatrick   /// AliasedFlag - This is set to true if the slot might be aliased
514e5dd7070Spatrick   /// and it's not undefined behavior to access it through such an
515e5dd7070Spatrick   /// alias.  Note that it's always undefined behavior to access a C++
516e5dd7070Spatrick   /// object that's under construction through an alias derived from
517e5dd7070Spatrick   /// outside the construction process.
518e5dd7070Spatrick   ///
519e5dd7070Spatrick   /// This flag controls whether calls that produce the aggregate
520e5dd7070Spatrick   /// value may be evaluated directly into the slot, or whether they
521e5dd7070Spatrick   /// must be evaluated into an unaliased temporary and then memcpy'ed
522e5dd7070Spatrick   /// over.  Since it's invalid in general to memcpy a non-POD C++
523e5dd7070Spatrick   /// object, it's important that this flag never be set when
524e5dd7070Spatrick   /// evaluating an expression which constructs such an object.
525e5dd7070Spatrick   bool AliasedFlag : 1;
526e5dd7070Spatrick 
527e5dd7070Spatrick   /// This is set to true if the tail padding of this slot might overlap
528e5dd7070Spatrick   /// another object that may have already been initialized (and whose
529e5dd7070Spatrick   /// value must be preserved by this initialization). If so, we may only
530e5dd7070Spatrick   /// store up to the dsize of the type. Otherwise we can widen stores to
531e5dd7070Spatrick   /// the size of the type.
532e5dd7070Spatrick   bool OverlapFlag : 1;
533e5dd7070Spatrick 
534e5dd7070Spatrick   /// If is set to true, sanitizer checks are already generated for this address
535e5dd7070Spatrick   /// or not required. For instance, if this address represents an object
536e5dd7070Spatrick   /// created in 'new' expression, sanitizer checks for memory is made as a part
537e5dd7070Spatrick   /// of 'operator new' emission and object constructor should not generate
538e5dd7070Spatrick   /// them.
539e5dd7070Spatrick   bool SanitizerCheckedFlag : 1;
540e5dd7070Spatrick 
AggValueSlot(Address Addr,Qualifiers Quals,bool DestructedFlag,bool ObjCGCFlag,bool ZeroedFlag,bool AliasedFlag,bool OverlapFlag,bool SanitizerCheckedFlag)541*12c85518Srobert   AggValueSlot(Address Addr, Qualifiers Quals, bool DestructedFlag,
542*12c85518Srobert                bool ObjCGCFlag, bool ZeroedFlag, bool AliasedFlag,
543*12c85518Srobert                bool OverlapFlag, bool SanitizerCheckedFlag)
544*12c85518Srobert       : Addr(Addr), Quals(Quals), DestructedFlag(DestructedFlag),
545*12c85518Srobert         ObjCGCFlag(ObjCGCFlag), ZeroedFlag(ZeroedFlag),
546*12c85518Srobert         AliasedFlag(AliasedFlag), OverlapFlag(OverlapFlag),
547*12c85518Srobert         SanitizerCheckedFlag(SanitizerCheckedFlag) {}
548*12c85518Srobert 
549e5dd7070Spatrick public:
550e5dd7070Spatrick   enum IsAliased_t { IsNotAliased, IsAliased };
551e5dd7070Spatrick   enum IsDestructed_t { IsNotDestructed, IsDestructed };
552e5dd7070Spatrick   enum IsZeroed_t { IsNotZeroed, IsZeroed };
553e5dd7070Spatrick   enum Overlap_t { DoesNotOverlap, MayOverlap };
554e5dd7070Spatrick   enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers };
555e5dd7070Spatrick   enum IsSanitizerChecked_t { IsNotSanitizerChecked, IsSanitizerChecked };
556e5dd7070Spatrick 
557e5dd7070Spatrick   /// ignored - Returns an aggregate value slot indicating that the
558e5dd7070Spatrick   /// aggregate value is being ignored.
ignored()559e5dd7070Spatrick   static AggValueSlot ignored() {
560e5dd7070Spatrick     return forAddr(Address::invalid(), Qualifiers(), IsNotDestructed,
561e5dd7070Spatrick                    DoesNotNeedGCBarriers, IsNotAliased, DoesNotOverlap);
562e5dd7070Spatrick   }
563e5dd7070Spatrick 
564e5dd7070Spatrick   /// forAddr - Make a slot for an aggregate value.
565e5dd7070Spatrick   ///
566e5dd7070Spatrick   /// \param quals - The qualifiers that dictate how the slot should
567e5dd7070Spatrick   /// be initialied. Only 'volatile' and the Objective-C lifetime
568e5dd7070Spatrick   /// qualifiers matter.
569e5dd7070Spatrick   ///
570e5dd7070Spatrick   /// \param isDestructed - true if something else is responsible
571e5dd7070Spatrick   ///   for calling destructors on this object
572e5dd7070Spatrick   /// \param needsGC - true if the slot is potentially located
573e5dd7070Spatrick   ///   somewhere that ObjC GC calls should be emitted for
574e5dd7070Spatrick   static AggValueSlot forAddr(Address addr,
575e5dd7070Spatrick                               Qualifiers quals,
576e5dd7070Spatrick                               IsDestructed_t isDestructed,
577e5dd7070Spatrick                               NeedsGCBarriers_t needsGC,
578e5dd7070Spatrick                               IsAliased_t isAliased,
579e5dd7070Spatrick                               Overlap_t mayOverlap,
580e5dd7070Spatrick                               IsZeroed_t isZeroed = IsNotZeroed,
581e5dd7070Spatrick                        IsSanitizerChecked_t isChecked = IsNotSanitizerChecked) {
582*12c85518Srobert     return AggValueSlot(addr, quals, isDestructed, needsGC, isZeroed, isAliased,
583*12c85518Srobert                         mayOverlap, isChecked);
584e5dd7070Spatrick   }
585e5dd7070Spatrick 
586e5dd7070Spatrick   static AggValueSlot
587e5dd7070Spatrick   forLValue(const LValue &LV, CodeGenFunction &CGF, IsDestructed_t isDestructed,
588e5dd7070Spatrick             NeedsGCBarriers_t needsGC, IsAliased_t isAliased,
589e5dd7070Spatrick             Overlap_t mayOverlap, IsZeroed_t isZeroed = IsNotZeroed,
590e5dd7070Spatrick             IsSanitizerChecked_t isChecked = IsNotSanitizerChecked) {
591e5dd7070Spatrick     return forAddr(LV.getAddress(CGF), LV.getQuals(), isDestructed, needsGC,
592e5dd7070Spatrick                    isAliased, mayOverlap, isZeroed, isChecked);
593e5dd7070Spatrick   }
594e5dd7070Spatrick 
isExternallyDestructed()595e5dd7070Spatrick   IsDestructed_t isExternallyDestructed() const {
596e5dd7070Spatrick     return IsDestructed_t(DestructedFlag);
597e5dd7070Spatrick   }
598e5dd7070Spatrick   void setExternallyDestructed(bool destructed = true) {
599e5dd7070Spatrick     DestructedFlag = destructed;
600e5dd7070Spatrick   }
601e5dd7070Spatrick 
getQualifiers()602e5dd7070Spatrick   Qualifiers getQualifiers() const { return Quals; }
603e5dd7070Spatrick 
isVolatile()604e5dd7070Spatrick   bool isVolatile() const {
605e5dd7070Spatrick     return Quals.hasVolatile();
606e5dd7070Spatrick   }
607e5dd7070Spatrick 
setVolatile(bool flag)608e5dd7070Spatrick   void setVolatile(bool flag) {
609e5dd7070Spatrick     if (flag)
610e5dd7070Spatrick       Quals.addVolatile();
611e5dd7070Spatrick     else
612e5dd7070Spatrick       Quals.removeVolatile();
613e5dd7070Spatrick   }
614e5dd7070Spatrick 
getObjCLifetime()615e5dd7070Spatrick   Qualifiers::ObjCLifetime getObjCLifetime() const {
616e5dd7070Spatrick     return Quals.getObjCLifetime();
617e5dd7070Spatrick   }
618e5dd7070Spatrick 
requiresGCollection()619e5dd7070Spatrick   NeedsGCBarriers_t requiresGCollection() const {
620e5dd7070Spatrick     return NeedsGCBarriers_t(ObjCGCFlag);
621e5dd7070Spatrick   }
622e5dd7070Spatrick 
getPointer()623e5dd7070Spatrick   llvm::Value *getPointer() const {
624*12c85518Srobert     return Addr.getPointer();
625e5dd7070Spatrick   }
626e5dd7070Spatrick 
getAddress()627e5dd7070Spatrick   Address getAddress() const {
628*12c85518Srobert     return Addr;
629e5dd7070Spatrick   }
630e5dd7070Spatrick 
isIgnored()631e5dd7070Spatrick   bool isIgnored() const {
632*12c85518Srobert     return !Addr.isValid();
633e5dd7070Spatrick   }
634e5dd7070Spatrick 
getAlignment()635e5dd7070Spatrick   CharUnits getAlignment() const {
636*12c85518Srobert     return Addr.getAlignment();
637e5dd7070Spatrick   }
638e5dd7070Spatrick 
isPotentiallyAliased()639e5dd7070Spatrick   IsAliased_t isPotentiallyAliased() const {
640e5dd7070Spatrick     return IsAliased_t(AliasedFlag);
641e5dd7070Spatrick   }
642e5dd7070Spatrick 
mayOverlap()643e5dd7070Spatrick   Overlap_t mayOverlap() const {
644e5dd7070Spatrick     return Overlap_t(OverlapFlag);
645e5dd7070Spatrick   }
646e5dd7070Spatrick 
isSanitizerChecked()647e5dd7070Spatrick   bool isSanitizerChecked() const {
648e5dd7070Spatrick     return SanitizerCheckedFlag;
649e5dd7070Spatrick   }
650e5dd7070Spatrick 
asRValue()651e5dd7070Spatrick   RValue asRValue() const {
652e5dd7070Spatrick     if (isIgnored()) {
653e5dd7070Spatrick       return RValue::getIgnored();
654e5dd7070Spatrick     } else {
655e5dd7070Spatrick       return RValue::getAggregate(getAddress(), isVolatile());
656e5dd7070Spatrick     }
657e5dd7070Spatrick   }
658e5dd7070Spatrick 
659e5dd7070Spatrick   void setZeroed(bool V = true) { ZeroedFlag = V; }
isZeroed()660e5dd7070Spatrick   IsZeroed_t isZeroed() const {
661e5dd7070Spatrick     return IsZeroed_t(ZeroedFlag);
662e5dd7070Spatrick   }
663e5dd7070Spatrick 
664e5dd7070Spatrick   /// Get the preferred size to use when storing a value to this slot. This
665e5dd7070Spatrick   /// is the type size unless that might overlap another object, in which
666e5dd7070Spatrick   /// case it's the dsize.
getPreferredSize(ASTContext & Ctx,QualType Type)667e5dd7070Spatrick   CharUnits getPreferredSize(ASTContext &Ctx, QualType Type) const {
668a9ac8606Spatrick     return mayOverlap() ? Ctx.getTypeInfoDataSizeInChars(Type).Width
669e5dd7070Spatrick                         : Ctx.getTypeSizeInChars(Type);
670e5dd7070Spatrick   }
671e5dd7070Spatrick };
672e5dd7070Spatrick 
673e5dd7070Spatrick }  // end namespace CodeGen
674e5dd7070Spatrick }  // end namespace clang
675e5dd7070Spatrick 
676e5dd7070Spatrick #endif
677