xref: /freebsd/contrib/llvm-project/clang/lib/CIR/CodeGen/CIRGenValue.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
2*700637cbSDimitry Andric //
3*700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*700637cbSDimitry Andric //
7*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
8*700637cbSDimitry Andric //
9*700637cbSDimitry Andric // These classes implement wrappers around mlir::Value in order to fully
10*700637cbSDimitry Andric // represent the range of values for C L- and R- values.
11*700637cbSDimitry Andric //
12*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
13*700637cbSDimitry Andric 
14*700637cbSDimitry Andric #ifndef CLANG_LIB_CIR_CIRGENVALUE_H
15*700637cbSDimitry Andric #define CLANG_LIB_CIR_CIRGENVALUE_H
16*700637cbSDimitry Andric 
17*700637cbSDimitry Andric #include "Address.h"
18*700637cbSDimitry Andric 
19*700637cbSDimitry Andric #include "clang/AST/CharUnits.h"
20*700637cbSDimitry Andric #include "clang/AST/Type.h"
21*700637cbSDimitry Andric 
22*700637cbSDimitry Andric #include "CIRGenRecordLayout.h"
23*700637cbSDimitry Andric #include "mlir/IR/Value.h"
24*700637cbSDimitry Andric 
25*700637cbSDimitry Andric #include "clang/CIR/MissingFeatures.h"
26*700637cbSDimitry Andric 
27*700637cbSDimitry Andric namespace clang::CIRGen {
28*700637cbSDimitry Andric 
29*700637cbSDimitry Andric /// This trivial value class is used to represent the result of an
30*700637cbSDimitry Andric /// expression that is evaluated. It can be one of three things: either a
31*700637cbSDimitry Andric /// simple MLIR SSA value, a pair of SSA values for complex numbers, or the
32*700637cbSDimitry Andric /// address of an aggregate value in memory.
33*700637cbSDimitry Andric class RValue {
34*700637cbSDimitry Andric   enum Flavor { Scalar, Complex, Aggregate };
35*700637cbSDimitry Andric 
36*700637cbSDimitry Andric   union {
37*700637cbSDimitry Andric     mlir::Value value;
38*700637cbSDimitry Andric 
39*700637cbSDimitry Andric     // Stores aggregate address.
40*700637cbSDimitry Andric     Address aggregateAddr;
41*700637cbSDimitry Andric   };
42*700637cbSDimitry Andric 
43*700637cbSDimitry Andric   unsigned isVolatile : 1;
44*700637cbSDimitry Andric   unsigned flavor : 2;
45*700637cbSDimitry Andric 
46*700637cbSDimitry Andric public:
RValue()47*700637cbSDimitry Andric   RValue() : value(nullptr), flavor(Scalar) {}
48*700637cbSDimitry Andric 
isScalar()49*700637cbSDimitry Andric   bool isScalar() const { return flavor == Scalar; }
isComplex()50*700637cbSDimitry Andric   bool isComplex() const { return flavor == Complex; }
isAggregate()51*700637cbSDimitry Andric   bool isAggregate() const { return flavor == Aggregate; }
52*700637cbSDimitry Andric 
isVolatileQualified()53*700637cbSDimitry Andric   bool isVolatileQualified() const { return isVolatile; }
54*700637cbSDimitry Andric 
55*700637cbSDimitry Andric   /// Return the value of this scalar value.
getValue()56*700637cbSDimitry Andric   mlir::Value getValue() const {
57*700637cbSDimitry Andric     assert(isScalar() && "Not a scalar!");
58*700637cbSDimitry Andric     return value;
59*700637cbSDimitry Andric   }
60*700637cbSDimitry Andric 
61*700637cbSDimitry Andric   /// Return the value of the address of the aggregate.
getAggregateAddress()62*700637cbSDimitry Andric   Address getAggregateAddress() const {
63*700637cbSDimitry Andric     assert(isAggregate() && "Not an aggregate!");
64*700637cbSDimitry Andric     return aggregateAddr;
65*700637cbSDimitry Andric   }
66*700637cbSDimitry Andric 
getAggregatePointer(QualType pointeeType)67*700637cbSDimitry Andric   mlir::Value getAggregatePointer(QualType pointeeType) const {
68*700637cbSDimitry Andric     return getAggregateAddress().getPointer();
69*700637cbSDimitry Andric   }
70*700637cbSDimitry Andric 
getIgnored()71*700637cbSDimitry Andric   static RValue getIgnored() {
72*700637cbSDimitry Andric     // FIXME: should we make this a more explicit state?
73*700637cbSDimitry Andric     return get(nullptr);
74*700637cbSDimitry Andric   }
75*700637cbSDimitry Andric 
get(mlir::Value v)76*700637cbSDimitry Andric   static RValue get(mlir::Value v) {
77*700637cbSDimitry Andric     RValue er;
78*700637cbSDimitry Andric     er.value = v;
79*700637cbSDimitry Andric     er.flavor = Scalar;
80*700637cbSDimitry Andric     er.isVolatile = false;
81*700637cbSDimitry Andric     return er;
82*700637cbSDimitry Andric   }
83*700637cbSDimitry Andric 
getComplex(mlir::Value v)84*700637cbSDimitry Andric   static RValue getComplex(mlir::Value v) {
85*700637cbSDimitry Andric     RValue er;
86*700637cbSDimitry Andric     er.value = v;
87*700637cbSDimitry Andric     er.flavor = Complex;
88*700637cbSDimitry Andric     er.isVolatile = false;
89*700637cbSDimitry Andric     return er;
90*700637cbSDimitry Andric   }
91*700637cbSDimitry Andric 
92*700637cbSDimitry Andric   // volatile or not.  Remove default to find all places that probably get this
93*700637cbSDimitry Andric   // wrong.
94*700637cbSDimitry Andric 
95*700637cbSDimitry Andric   /// Convert an Address to an RValue. If the Address is not
96*700637cbSDimitry Andric   /// signed, create an RValue using the unsigned address. Otherwise, resign the
97*700637cbSDimitry Andric   /// address using the provided type.
98*700637cbSDimitry Andric   static RValue getAggregate(Address addr, bool isVolatile = false) {
99*700637cbSDimitry Andric     RValue er;
100*700637cbSDimitry Andric     er.aggregateAddr = addr;
101*700637cbSDimitry Andric     er.flavor = Aggregate;
102*700637cbSDimitry Andric     er.isVolatile = isVolatile;
103*700637cbSDimitry Andric     return er;
104*700637cbSDimitry Andric   }
105*700637cbSDimitry Andric };
106*700637cbSDimitry Andric 
107*700637cbSDimitry Andric /// The source of the alignment of an l-value; an expression of
108*700637cbSDimitry Andric /// confidence in the alignment actually matching the estimate.
109*700637cbSDimitry Andric enum class AlignmentSource {
110*700637cbSDimitry Andric   /// The l-value was an access to a declared entity or something
111*700637cbSDimitry Andric   /// equivalently strong, like the address of an array allocated by a
112*700637cbSDimitry Andric   /// language runtime.
113*700637cbSDimitry Andric   Decl,
114*700637cbSDimitry Andric 
115*700637cbSDimitry Andric   /// The l-value was considered opaque, so the alignment was
116*700637cbSDimitry Andric   /// determined from a type, but that type was an explicitly-aligned
117*700637cbSDimitry Andric   /// typedef.
118*700637cbSDimitry Andric   AttributedType,
119*700637cbSDimitry Andric 
120*700637cbSDimitry Andric   /// The l-value was considered opaque, so the alignment was
121*700637cbSDimitry Andric   /// determined from a type.
122*700637cbSDimitry Andric   Type
123*700637cbSDimitry Andric };
124*700637cbSDimitry Andric 
125*700637cbSDimitry Andric /// Given that the base address has the given alignment source, what's
126*700637cbSDimitry Andric /// our confidence in the alignment of the field?
getFieldAlignmentSource(AlignmentSource source)127*700637cbSDimitry Andric static inline AlignmentSource getFieldAlignmentSource(AlignmentSource source) {
128*700637cbSDimitry Andric   // For now, we don't distinguish fields of opaque pointers from
129*700637cbSDimitry Andric   // top-level declarations, but maybe we should.
130*700637cbSDimitry Andric   return AlignmentSource::Decl;
131*700637cbSDimitry Andric }
132*700637cbSDimitry Andric 
133*700637cbSDimitry Andric class LValueBaseInfo {
134*700637cbSDimitry Andric   AlignmentSource alignSource;
135*700637cbSDimitry Andric 
136*700637cbSDimitry Andric public:
137*700637cbSDimitry Andric   explicit LValueBaseInfo(AlignmentSource source = AlignmentSource::Type)
alignSource(source)138*700637cbSDimitry Andric       : alignSource(source) {}
getAlignmentSource()139*700637cbSDimitry Andric   AlignmentSource getAlignmentSource() const { return alignSource; }
setAlignmentSource(AlignmentSource source)140*700637cbSDimitry Andric   void setAlignmentSource(AlignmentSource source) { alignSource = source; }
141*700637cbSDimitry Andric 
mergeForCast(const LValueBaseInfo & info)142*700637cbSDimitry Andric   void mergeForCast(const LValueBaseInfo &info) {
143*700637cbSDimitry Andric     setAlignmentSource(info.getAlignmentSource());
144*700637cbSDimitry Andric   }
145*700637cbSDimitry Andric };
146*700637cbSDimitry Andric 
147*700637cbSDimitry Andric class LValue {
148*700637cbSDimitry Andric   enum {
149*700637cbSDimitry Andric     Simple,       // This is a normal l-value, use getAddress().
150*700637cbSDimitry Andric     VectorElt,    // This is a vector element l-value (V[i]), use getVector*
151*700637cbSDimitry Andric     BitField,     // This is a bitfield l-value, use getBitfield*.
152*700637cbSDimitry Andric     ExtVectorElt, // This is an extended vector subset, use getExtVectorComp
153*700637cbSDimitry Andric     GlobalReg,    // This is a register l-value, use getGlobalReg()
154*700637cbSDimitry Andric     MatrixElt     // This is a matrix element, use getVector*
155*700637cbSDimitry Andric   } lvType;
156*700637cbSDimitry Andric   clang::QualType type;
157*700637cbSDimitry Andric   clang::Qualifiers quals;
158*700637cbSDimitry Andric 
159*700637cbSDimitry Andric   // The alignment to use when accessing this lvalue. (For vector elements,
160*700637cbSDimitry Andric   // this is the alignment of the whole vector)
161*700637cbSDimitry Andric   unsigned alignment;
162*700637cbSDimitry Andric   mlir::Value v;
163*700637cbSDimitry Andric   mlir::Value vectorIdx; // Index for vector subscript
164*700637cbSDimitry Andric   mlir::Type elementType;
165*700637cbSDimitry Andric   LValueBaseInfo baseInfo;
166*700637cbSDimitry Andric   const CIRGenBitFieldInfo *bitFieldInfo{nullptr};
167*700637cbSDimitry Andric 
initialize(clang::QualType type,clang::Qualifiers quals,clang::CharUnits alignment,LValueBaseInfo baseInfo)168*700637cbSDimitry Andric   void initialize(clang::QualType type, clang::Qualifiers quals,
169*700637cbSDimitry Andric                   clang::CharUnits alignment, LValueBaseInfo baseInfo) {
170*700637cbSDimitry Andric     assert((!alignment.isZero() || type->isIncompleteType()) &&
171*700637cbSDimitry Andric            "initializing l-value with zero alignment!");
172*700637cbSDimitry Andric     this->type = type;
173*700637cbSDimitry Andric     this->quals = quals;
174*700637cbSDimitry Andric     const unsigned maxAlign = 1U << 31;
175*700637cbSDimitry Andric     this->alignment = alignment.getQuantity() <= maxAlign
176*700637cbSDimitry Andric                           ? alignment.getQuantity()
177*700637cbSDimitry Andric                           : maxAlign;
178*700637cbSDimitry Andric     assert(this->alignment == alignment.getQuantity() &&
179*700637cbSDimitry Andric            "Alignment exceeds allowed max!");
180*700637cbSDimitry Andric     this->baseInfo = baseInfo;
181*700637cbSDimitry Andric   }
182*700637cbSDimitry Andric 
183*700637cbSDimitry Andric public:
isSimple()184*700637cbSDimitry Andric   bool isSimple() const { return lvType == Simple; }
isVectorElt()185*700637cbSDimitry Andric   bool isVectorElt() const { return lvType == VectorElt; }
isBitField()186*700637cbSDimitry Andric   bool isBitField() const { return lvType == BitField; }
isVolatile()187*700637cbSDimitry Andric   bool isVolatile() const { return quals.hasVolatile(); }
188*700637cbSDimitry Andric 
isVolatileQualified()189*700637cbSDimitry Andric   bool isVolatileQualified() const { return quals.hasVolatile(); }
190*700637cbSDimitry Andric 
getVRQualifiers()191*700637cbSDimitry Andric   unsigned getVRQualifiers() const {
192*700637cbSDimitry Andric     return quals.getCVRQualifiers() & ~clang::Qualifiers::Const;
193*700637cbSDimitry Andric   }
194*700637cbSDimitry Andric 
getType()195*700637cbSDimitry Andric   clang::QualType getType() const { return type; }
196*700637cbSDimitry Andric 
getPointer()197*700637cbSDimitry Andric   mlir::Value getPointer() const { return v; }
198*700637cbSDimitry Andric 
getAlignment()199*700637cbSDimitry Andric   clang::CharUnits getAlignment() const {
200*700637cbSDimitry Andric     return clang::CharUnits::fromQuantity(alignment);
201*700637cbSDimitry Andric   }
setAlignment(clang::CharUnits a)202*700637cbSDimitry Andric   void setAlignment(clang::CharUnits a) { alignment = a.getQuantity(); }
203*700637cbSDimitry Andric 
getAddress()204*700637cbSDimitry Andric   Address getAddress() const {
205*700637cbSDimitry Andric     return Address(getPointer(), elementType, getAlignment());
206*700637cbSDimitry Andric   }
207*700637cbSDimitry Andric 
getQuals()208*700637cbSDimitry Andric   const clang::Qualifiers &getQuals() const { return quals; }
getQuals()209*700637cbSDimitry Andric   clang::Qualifiers &getQuals() { return quals; }
210*700637cbSDimitry Andric 
getBaseInfo()211*700637cbSDimitry Andric   LValueBaseInfo getBaseInfo() const { return baseInfo; }
setBaseInfo(LValueBaseInfo info)212*700637cbSDimitry Andric   void setBaseInfo(LValueBaseInfo info) { baseInfo = info; }
213*700637cbSDimitry Andric 
makeAddr(Address address,clang::QualType t,LValueBaseInfo baseInfo)214*700637cbSDimitry Andric   static LValue makeAddr(Address address, clang::QualType t,
215*700637cbSDimitry Andric                          LValueBaseInfo baseInfo) {
216*700637cbSDimitry Andric     // Classic codegen sets the objc gc qualifier here. That requires an
217*700637cbSDimitry Andric     // ASTContext, which is passed in from CIRGenFunction::makeAddrLValue.
218*700637cbSDimitry Andric     assert(!cir::MissingFeatures::objCGC());
219*700637cbSDimitry Andric 
220*700637cbSDimitry Andric     LValue r;
221*700637cbSDimitry Andric     r.lvType = Simple;
222*700637cbSDimitry Andric     r.v = address.getPointer();
223*700637cbSDimitry Andric     r.elementType = address.getElementType();
224*700637cbSDimitry Andric     r.initialize(t, t.getQualifiers(), address.getAlignment(), baseInfo);
225*700637cbSDimitry Andric     return r;
226*700637cbSDimitry Andric   }
227*700637cbSDimitry Andric 
getVectorAddress()228*700637cbSDimitry Andric   Address getVectorAddress() const {
229*700637cbSDimitry Andric     return Address(getVectorPointer(), elementType, getAlignment());
230*700637cbSDimitry Andric   }
231*700637cbSDimitry Andric 
getVectorPointer()232*700637cbSDimitry Andric   mlir::Value getVectorPointer() const {
233*700637cbSDimitry Andric     assert(isVectorElt());
234*700637cbSDimitry Andric     return v;
235*700637cbSDimitry Andric   }
236*700637cbSDimitry Andric 
getVectorIdx()237*700637cbSDimitry Andric   mlir::Value getVectorIdx() const {
238*700637cbSDimitry Andric     assert(isVectorElt());
239*700637cbSDimitry Andric     return vectorIdx;
240*700637cbSDimitry Andric   }
241*700637cbSDimitry Andric 
makeVectorElt(Address vecAddress,mlir::Value index,clang::QualType t,LValueBaseInfo baseInfo)242*700637cbSDimitry Andric   static LValue makeVectorElt(Address vecAddress, mlir::Value index,
243*700637cbSDimitry Andric                               clang::QualType t, LValueBaseInfo baseInfo) {
244*700637cbSDimitry Andric     LValue r;
245*700637cbSDimitry Andric     r.lvType = VectorElt;
246*700637cbSDimitry Andric     r.v = vecAddress.getPointer();
247*700637cbSDimitry Andric     r.elementType = vecAddress.getElementType();
248*700637cbSDimitry Andric     r.vectorIdx = index;
249*700637cbSDimitry Andric     r.initialize(t, t.getQualifiers(), vecAddress.getAlignment(), baseInfo);
250*700637cbSDimitry Andric     return r;
251*700637cbSDimitry Andric   }
252*700637cbSDimitry Andric 
253*700637cbSDimitry Andric   // bitfield lvalue
getBitFieldAddress()254*700637cbSDimitry Andric   Address getBitFieldAddress() const {
255*700637cbSDimitry Andric     return Address(getBitFieldPointer(), elementType, getAlignment());
256*700637cbSDimitry Andric   }
257*700637cbSDimitry Andric 
getBitFieldPointer()258*700637cbSDimitry Andric   mlir::Value getBitFieldPointer() const {
259*700637cbSDimitry Andric     assert(isBitField());
260*700637cbSDimitry Andric     return v;
261*700637cbSDimitry Andric   }
262*700637cbSDimitry Andric 
getBitFieldInfo()263*700637cbSDimitry Andric   const CIRGenBitFieldInfo &getBitFieldInfo() const {
264*700637cbSDimitry Andric     assert(isBitField());
265*700637cbSDimitry Andric     return *bitFieldInfo;
266*700637cbSDimitry Andric   }
267*700637cbSDimitry Andric 
268*700637cbSDimitry Andric   /// Create a new object to represent a bit-field access.
269*700637cbSDimitry Andric   ///
270*700637cbSDimitry Andric   /// \param Addr - The base address of the bit-field sequence this
271*700637cbSDimitry Andric   /// bit-field refers to.
272*700637cbSDimitry Andric   /// \param Info - The information describing how to perform the bit-field
273*700637cbSDimitry Andric   /// access.
makeBitfield(Address addr,const CIRGenBitFieldInfo & info,clang::QualType type,LValueBaseInfo baseInfo)274*700637cbSDimitry Andric   static LValue makeBitfield(Address addr, const CIRGenBitFieldInfo &info,
275*700637cbSDimitry Andric                              clang::QualType type, LValueBaseInfo baseInfo) {
276*700637cbSDimitry Andric     LValue r;
277*700637cbSDimitry Andric     r.lvType = BitField;
278*700637cbSDimitry Andric     r.v = addr.getPointer();
279*700637cbSDimitry Andric     r.elementType = addr.getElementType();
280*700637cbSDimitry Andric     r.bitFieldInfo = &info;
281*700637cbSDimitry Andric     r.initialize(type, type.getQualifiers(), addr.getAlignment(), baseInfo);
282*700637cbSDimitry Andric     return r;
283*700637cbSDimitry Andric   }
284*700637cbSDimitry Andric };
285*700637cbSDimitry Andric 
286*700637cbSDimitry Andric /// An aggregate value slot.
287*700637cbSDimitry Andric class AggValueSlot {
288*700637cbSDimitry Andric 
289*700637cbSDimitry Andric   Address addr;
290*700637cbSDimitry Andric   clang::Qualifiers quals;
291*700637cbSDimitry Andric 
292*700637cbSDimitry Andric   /// This is set to true if some external code is responsible for setting up a
293*700637cbSDimitry Andric   /// destructor for the slot.  Otherwise the code which constructs it should
294*700637cbSDimitry Andric   /// push the appropriate cleanup.
295*700637cbSDimitry Andric   LLVM_PREFERRED_TYPE(bool)
296*700637cbSDimitry Andric   LLVM_ATTRIBUTE_UNUSED unsigned destructedFlag : 1;
297*700637cbSDimitry Andric 
298*700637cbSDimitry Andric   /// This is set to true if the memory in the slot is known to be zero before
299*700637cbSDimitry Andric   /// the assignment into it.  This means that zero fields don't need to be set.
300*700637cbSDimitry Andric   LLVM_PREFERRED_TYPE(bool)
301*700637cbSDimitry Andric   unsigned zeroedFlag : 1;
302*700637cbSDimitry Andric 
303*700637cbSDimitry Andric   /// This is set to true if the slot might be aliased and it's not undefined
304*700637cbSDimitry Andric   /// behavior to access it through such an alias.  Note that it's always
305*700637cbSDimitry Andric   /// undefined behavior to access a C++ object that's under construction
306*700637cbSDimitry Andric   /// through an alias derived from outside the construction process.
307*700637cbSDimitry Andric   ///
308*700637cbSDimitry Andric   /// This flag controls whether calls that produce the aggregate
309*700637cbSDimitry Andric   /// value may be evaluated directly into the slot, or whether they
310*700637cbSDimitry Andric   /// must be evaluated into an unaliased temporary and then memcpy'ed
311*700637cbSDimitry Andric   /// over.  Since it's invalid in general to memcpy a non-POD C++
312*700637cbSDimitry Andric   /// object, it's important that this flag never be set when
313*700637cbSDimitry Andric   /// evaluating an expression which constructs such an object.
314*700637cbSDimitry Andric   LLVM_PREFERRED_TYPE(bool)
315*700637cbSDimitry Andric   LLVM_ATTRIBUTE_UNUSED unsigned aliasedFlag : 1;
316*700637cbSDimitry Andric 
317*700637cbSDimitry Andric   /// This is set to true if the tail padding of this slot might overlap
318*700637cbSDimitry Andric   /// another object that may have already been initialized (and whose
319*700637cbSDimitry Andric   /// value must be preserved by this initialization). If so, we may only
320*700637cbSDimitry Andric   /// store up to the dsize of the type. Otherwise we can widen stores to
321*700637cbSDimitry Andric   /// the size of the type.
322*700637cbSDimitry Andric   LLVM_PREFERRED_TYPE(bool)
323*700637cbSDimitry Andric   LLVM_ATTRIBUTE_UNUSED unsigned overlapFlag : 1;
324*700637cbSDimitry Andric 
325*700637cbSDimitry Andric public:
326*700637cbSDimitry Andric   enum IsDestructed_t { IsNotDestructed, IsDestructed };
327*700637cbSDimitry Andric   enum IsZeroed_t { IsNotZeroed, IsZeroed };
328*700637cbSDimitry Andric   enum IsAliased_t { IsNotAliased, IsAliased };
329*700637cbSDimitry Andric   enum Overlap_t { MayOverlap, DoesNotOverlap };
330*700637cbSDimitry Andric 
331*700637cbSDimitry Andric   /// Returns an aggregate value slot indicating that the aggregate
332*700637cbSDimitry Andric   /// value is being ignored.
ignored()333*700637cbSDimitry Andric   static AggValueSlot ignored() {
334*700637cbSDimitry Andric     return forAddr(Address::invalid(), clang::Qualifiers(), IsNotDestructed,
335*700637cbSDimitry Andric                    IsNotAliased, DoesNotOverlap);
336*700637cbSDimitry Andric   }
337*700637cbSDimitry Andric 
AggValueSlot(Address addr,clang::Qualifiers quals,bool destructedFlag,bool zeroedFlag,bool aliasedFlag,bool overlapFlag)338*700637cbSDimitry Andric   AggValueSlot(Address addr, clang::Qualifiers quals, bool destructedFlag,
339*700637cbSDimitry Andric                bool zeroedFlag, bool aliasedFlag, bool overlapFlag)
340*700637cbSDimitry Andric       : addr(addr), quals(quals), destructedFlag(destructedFlag),
341*700637cbSDimitry Andric         zeroedFlag(zeroedFlag), aliasedFlag(aliasedFlag),
342*700637cbSDimitry Andric         overlapFlag(overlapFlag) {}
343*700637cbSDimitry Andric 
344*700637cbSDimitry Andric   static AggValueSlot forAddr(Address addr, clang::Qualifiers quals,
345*700637cbSDimitry Andric                               IsDestructed_t isDestructed,
346*700637cbSDimitry Andric                               IsAliased_t isAliased, Overlap_t mayOverlap,
347*700637cbSDimitry Andric                               IsZeroed_t isZeroed = IsNotZeroed) {
348*700637cbSDimitry Andric     return AggValueSlot(addr, quals, isDestructed, isZeroed, isAliased,
349*700637cbSDimitry Andric                         mayOverlap);
350*700637cbSDimitry Andric   }
351*700637cbSDimitry Andric 
352*700637cbSDimitry Andric   static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed,
353*700637cbSDimitry Andric                                 IsAliased_t isAliased, Overlap_t mayOverlap,
354*700637cbSDimitry Andric                                 IsZeroed_t isZeroed = IsNotZeroed) {
355*700637cbSDimitry Andric     return forAddr(LV.getAddress(), LV.getQuals(), isDestructed, isAliased,
356*700637cbSDimitry Andric                    mayOverlap, isZeroed);
357*700637cbSDimitry Andric   }
358*700637cbSDimitry Andric 
getQualifiers()359*700637cbSDimitry Andric   clang::Qualifiers getQualifiers() const { return quals; }
360*700637cbSDimitry Andric 
getAddress()361*700637cbSDimitry Andric   Address getAddress() const { return addr; }
362*700637cbSDimitry Andric 
isIgnored()363*700637cbSDimitry Andric   bool isIgnored() const { return !addr.isValid(); }
364*700637cbSDimitry Andric 
getPointer()365*700637cbSDimitry Andric   mlir::Value getPointer() const { return addr.getPointer(); }
366*700637cbSDimitry Andric 
isZeroed()367*700637cbSDimitry Andric   IsZeroed_t isZeroed() const { return IsZeroed_t(zeroedFlag); }
368*700637cbSDimitry Andric 
asRValue()369*700637cbSDimitry Andric   RValue asRValue() const {
370*700637cbSDimitry Andric     if (isIgnored())
371*700637cbSDimitry Andric       return RValue::getIgnored();
372*700637cbSDimitry Andric     assert(!cir::MissingFeatures::aggValueSlot());
373*700637cbSDimitry Andric     return RValue::getAggregate(getAddress());
374*700637cbSDimitry Andric   }
375*700637cbSDimitry Andric };
376*700637cbSDimitry Andric 
377*700637cbSDimitry Andric } // namespace clang::CIRGen
378*700637cbSDimitry Andric 
379*700637cbSDimitry Andric #endif // CLANG_LIB_CIR_CIRGENVALUE_H
380