xref: /minix3/external/bsd/llvm/dist/clang/lib/CodeGen/CGValue.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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