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