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