1//===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- 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// This file defines the APValue class.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_AST_APVALUE_H
14#define LLVM_CLANG_AST_APVALUE_H
15
16#include "clang/AST/CharUnits.h"
17#include "clang/AST/Reflection.h"
18#include "clang/Basic/LLVM.h"
19#include "llvm/ADT/APFixedPoint.h"
20#include "llvm/ADT/APFloat.h"
21#include "llvm/ADT/APSInt.h"
22#include "llvm/ADT/FoldingSet.h"
23#include "llvm/ADT/PointerIntPair.h"
24#include "llvm/ADT/PointerUnion.h"
25#include "llvm/ADT/STLFunctionalExtras.h"
26#include "llvm/ADT/bit.h"
27#include "llvm/Support/AlignOf.h"
28#include "llvm/Support/Compiler.h"
29
30namespace clang {
31namespace serialization {
32template <typename T> class BasicReaderBase;
33} // end namespace serialization
34
35 class AddrLabelExpr;
36 class ASTContext;
37 class CXXRecordDecl;
38 class Decl;
39 class DiagnosticBuilder;
40 class Expr;
41 class FieldDecl;
42 struct PrintingPolicy;
43 class Type;
44 class ValueDecl;
45 class QualType;
46
47/// Symbolic representation of typeid(T) for some type T.
48class TypeInfoLValue {
49 const Type *T;
50
51public:
52 TypeInfoLValue() : T() {}
53 explicit TypeInfoLValue(const Type *T);
54
55 const Type *getType() const { return T; }
56 explicit operator bool() const { return T; }
57
58 const void *getOpaqueValue() const { return T; }
59 static TypeInfoLValue getFromOpaqueValue(const void *Value) {
60 TypeInfoLValue V;
61 V.T = reinterpret_cast<const Type*>(Value);
62 return V;
63 }
64
65 void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const;
66};
67
68/// Kind of source for a dynamic allocation.
69enum class DynAllocKind {
70 New, // new expression
71 ArrayNew, // new[] expression
72 StdAllocator, // std::allocator::allocate call
73 None, // not a dynamic allocation
74 BuiltinOperatorNew, // __operator_builtin_new call
75 ALLOC_KIND_MAX = BuiltinOperatorNew
76};
77
78/// Symbolic representation of a dynamic allocation.
79class DynamicAllocLValue {
80public:
81 static constexpr int NumLowBitsAvailable = 2;
82 static constexpr int NumAllocKindBits = 3;
83 static_assert((1 << NumAllocKindBits) - 1 >=
84 static_cast<int>(DynAllocKind::ALLOC_KIND_MAX));
85
86private:
87 // lower NumAlignmentBits: alignment exponent
88 // remaining bits: allocation index incremented by one
89 // value of zero indicates distinct empty state
90 LLVM_PREFERRED_TYPE(DynAllocKind)
91 uintptr_t AllocKind : NumAllocKindBits;
92 uintptr_t Index : sizeof(uintptr_t) * CHAR_BIT - NumAllocKindBits;
93
94public:
95 DynamicAllocLValue() : AllocKind(0), Index(0) {}
96 explicit DynamicAllocLValue(unsigned Idx, DynAllocKind AllocKind)
97 : AllocKind(llvm::to_underlying(E: AllocKind)), Index(Idx + 1) {
98 assert(Idx <= getMaxIndex() && "Index is out of range");
99 }
100 unsigned getIndex() const { return Index - 1; }
101 DynAllocKind getAllocKind() const {
102 return static_cast<DynAllocKind>(AllocKind);
103 }
104
105 explicit operator bool() const { return Index != 0; }
106
107 const void *getOpaqueValue() const {
108 return reinterpret_cast<const void *>(
109 (Index << NumAllocKindBits | AllocKind) << NumLowBitsAvailable);
110 }
111 static DynamicAllocLValue getFromOpaqueValue(const void *Value) {
112 DynamicAllocLValue V;
113 uintptr_t Combined =
114 reinterpret_cast<uintptr_t>(Value) >> NumLowBitsAvailable;
115 V.AllocKind = Combined & (1 << NumAllocKindBits) - 1;
116 V.Index = Combined >> NumAllocKindBits;
117 return V;
118 }
119
120 static uintptr_t getMaxIndex() {
121 return (std::numeric_limits<uintptr_t>::max() >>
122 (NumLowBitsAvailable + NumAllocKindBits)) -
123 1;
124 }
125};
126static_assert(sizeof(DynamicAllocLValue) == sizeof(uintptr_t));
127}
128
129namespace llvm {
130template<> struct PointerLikeTypeTraits<clang::TypeInfoLValue> {
131 static const void *getAsVoidPointer(clang::TypeInfoLValue V) {
132 return V.getOpaqueValue();
133 }
134 static clang::TypeInfoLValue getFromVoidPointer(const void *P) {
135 return clang::TypeInfoLValue::getFromOpaqueValue(Value: P);
136 }
137 // Validated by static_assert in APValue.cpp; hardcoded to avoid needing
138 // to include Type.h.
139 static constexpr int NumLowBitsAvailable = 3;
140};
141
142template<> struct PointerLikeTypeTraits<clang::DynamicAllocLValue> {
143 static const void *getAsVoidPointer(clang::DynamicAllocLValue V) {
144 return V.getOpaqueValue();
145 }
146 static clang::DynamicAllocLValue getFromVoidPointer(const void *P) {
147 return clang::DynamicAllocLValue::getFromOpaqueValue(Value: P);
148 }
149 static constexpr int NumLowBitsAvailable =
150 clang::DynamicAllocLValue::NumLowBitsAvailable;
151};
152}
153
154namespace clang {
155/// APValue - This class implements a discriminated union of [uninitialized]
156/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
157/// [Vector: N * APValue], [Array: N * APValue]
158class LLVM_ATTRIBUTE_WARN_UNUSED APValue {
159 typedef llvm::APFixedPoint APFixedPoint;
160 typedef llvm::APSInt APSInt;
161 typedef llvm::APFloat APFloat;
162public:
163 enum ValueKind {
164 /// There is no such object (it's outside its lifetime).
165 None,
166 /// This object has an indeterminate value (C++ [basic.indet]).
167 Indeterminate,
168 Int,
169 Float,
170 FixedPoint,
171 ComplexInt,
172 ComplexFloat,
173 LValue,
174 Vector,
175 Matrix,
176 Array,
177 Struct,
178 Union,
179 MemberPointer,
180 AddrLabelDiff,
181 Reflection
182 };
183
184 class alignas(uint64_t) LValueBase {
185 typedef llvm::PointerUnion<const ValueDecl *, const Expr *, TypeInfoLValue,
186 DynamicAllocLValue>
187 PtrTy;
188
189 public:
190 LValueBase() : Local{} {}
191 LValueBase(const ValueDecl *P, unsigned I = 0, unsigned V = 0);
192 LValueBase(const Expr *P, unsigned I = 0, unsigned V = 0);
193 static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type);
194 static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo);
195
196 void Profile(llvm::FoldingSetNodeID &ID) const;
197
198 template <class T> bool is() const { return isa<T>(Ptr); }
199
200 template <class T> T get() const { return cast<T>(Ptr); }
201
202 template <class T> T dyn_cast() const {
203 return dyn_cast_if_present<T>(Ptr);
204 }
205
206 void *getOpaqueValue() const;
207
208 bool isNull() const;
209
210 explicit operator bool() const;
211
212 unsigned getCallIndex() const;
213 unsigned getVersion() const;
214 QualType getTypeInfoType() const;
215 QualType getDynamicAllocType() const;
216
217 QualType getType() const;
218
219 friend bool operator==(const LValueBase &LHS, const LValueBase &RHS);
220 friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) {
221 return !(LHS == RHS);
222 }
223 friend llvm::hash_code hash_value(const LValueBase &Base);
224 friend struct llvm::DenseMapInfo<LValueBase>;
225
226 private:
227 PtrTy Ptr;
228 struct LocalState {
229 unsigned CallIndex, Version;
230 };
231 union {
232 LocalState Local;
233 /// The type std::type_info, if this is a TypeInfoLValue.
234 void *TypeInfoType;
235 /// The QualType, if this is a DynamicAllocLValue.
236 void *DynamicAllocType;
237 };
238 };
239
240 /// A FieldDecl or CXXRecordDecl, along with a flag indicating whether we
241 /// mean a virtual or non-virtual base class subobject.
242 typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
243
244 /// A non-discriminated union of a base, field, or array index.
245 class LValuePathEntry {
246 static_assert(sizeof(uintptr_t) <= sizeof(uint64_t),
247 "pointer doesn't fit in 64 bits?");
248 uint64_t Value;
249
250 public:
251 LValuePathEntry() : Value() {}
252 LValuePathEntry(BaseOrMemberType BaseOrMember);
253 static LValuePathEntry ArrayIndex(uint64_t Index) {
254 LValuePathEntry Result;
255 Result.Value = Index;
256 return Result;
257 }
258
259 BaseOrMemberType getAsBaseOrMember() const {
260 return BaseOrMemberType::getFromOpaqueValue(
261 V: reinterpret_cast<void *>(Value));
262 }
263 uint64_t getAsArrayIndex() const { return Value; }
264
265 void Profile(llvm::FoldingSetNodeID &ID) const;
266
267 friend bool operator==(LValuePathEntry A, LValuePathEntry B) {
268 return A.Value == B.Value;
269 }
270 friend bool operator!=(LValuePathEntry A, LValuePathEntry B) {
271 return A.Value != B.Value;
272 }
273 friend llvm::hash_code hash_value(LValuePathEntry A) {
274 return llvm::hash_value(value: A.Value);
275 }
276 };
277 class LValuePathSerializationHelper {
278 const void *Ty;
279
280 public:
281 ArrayRef<LValuePathEntry> Path;
282
283 LValuePathSerializationHelper(ArrayRef<LValuePathEntry>, QualType);
284 QualType getType();
285 };
286 struct NoLValuePath {};
287 struct UninitArray {};
288 struct UninitStruct {};
289 struct ConstexprUnknown {};
290
291 template <typename Impl> friend class clang::serialization::BasicReaderBase;
292 friend class ASTImporter;
293 friend class ASTNodeImporter;
294
295private:
296 ValueKind Kind;
297 bool AllowConstexprUnknown : 1;
298
299 struct ComplexAPSInt {
300 APSInt Real, Imag;
301 ComplexAPSInt() : Real(1), Imag(1) {}
302 };
303 struct ComplexAPFloat {
304 APFloat Real, Imag;
305 ComplexAPFloat() : Real(0.0), Imag(0.0) {}
306 };
307 struct LV;
308 struct Vec {
309 APValue *Elts = nullptr;
310 unsigned NumElts = 0;
311 Vec() = default;
312 Vec(const Vec &) = delete;
313 Vec &operator=(const Vec &) = delete;
314 ~Vec() { delete[] Elts; }
315 };
316 struct Mat {
317 APValue *Elts = nullptr;
318 unsigned NumRows = 0;
319 unsigned NumCols = 0;
320 Mat() = default;
321 Mat(const Mat &) = delete;
322 Mat &operator=(const Mat &) = delete;
323 ~Mat() { delete[] Elts; }
324 };
325 struct Arr {
326 APValue *Elts;
327 unsigned NumElts, ArrSize;
328 Arr(unsigned NumElts, unsigned ArrSize);
329 Arr(const Arr &) = delete;
330 Arr &operator=(const Arr &) = delete;
331 ~Arr();
332 };
333 struct StructData {
334 APValue *Elts;
335 unsigned NumBases;
336 unsigned NumFields;
337 unsigned NumVirtualBases;
338 StructData(unsigned NumBases, unsigned NumFields, unsigned NumVirtualBases);
339 StructData(const StructData &) = delete;
340 StructData &operator=(const StructData &) = delete;
341 ~StructData();
342 };
343 struct UnionData {
344 const FieldDecl *Field;
345 APValue *Value;
346 UnionData();
347 UnionData(const UnionData &) = delete;
348 UnionData &operator=(const UnionData &) = delete;
349 ~UnionData();
350 };
351 struct AddrLabelDiffData {
352 const AddrLabelExpr* LHSExpr;
353 const AddrLabelExpr* RHSExpr;
354 };
355 struct ReflectionData {
356 // OperandKind will eventually have support for
357 // Null, TypeSourceInfo, TemplateReference, NamespaceReference, DeclRefExpr.
358 // Operand stores the opaque pointer of the reflection operand.
359 // Depending on the value of OperandKind, we can perform the
360 // corresponding cast to the associated type.
361 // If OperandKind is Null, then the ReflectionData represents
362 // a null reflection, and therefore Operand should be a nullptr.
363 ReflectionKind OperandKind;
364 const void *Operand;
365 };
366 struct MemberPointerData;
367
368 // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
369 typedef llvm::AlignedCharArrayUnion<
370 void *, APSInt, APFloat, ComplexAPSInt, ComplexAPFloat, Vec, Mat, Arr,
371 StructData, UnionData, AddrLabelDiffData, ReflectionData>
372 DataType;
373 static const size_t DataSize = sizeof(DataType);
374
375 DataType Data;
376
377public:
378 bool allowConstexprUnknown() const { return AllowConstexprUnknown; }
379
380 void setConstexprUnknown(bool IsConstexprUnknown = true) {
381 AllowConstexprUnknown = IsConstexprUnknown;
382 }
383
384 /// Creates an empty APValue of type None.
385 APValue() : Kind(None), AllowConstexprUnknown(false) {}
386 /// Creates an integer APValue holding the given value.
387 explicit APValue(APSInt I) : Kind(None), AllowConstexprUnknown(false) {
388 MakeInt(I: std::move(I));
389 }
390 /// Creates a float APValue holding the given value.
391 explicit APValue(APFloat F) : Kind(None), AllowConstexprUnknown(false) {
392 MakeFloat(F: std::move(F));
393 }
394 /// Creates a fixed-point APValue holding the given value.
395 explicit APValue(APFixedPoint FX) : Kind(None), AllowConstexprUnknown(false) {
396 MakeFixedPoint(FX: std::move(FX));
397 }
398 /// Creates a vector APValue with \p N elements. The elements
399 /// are read from \p E.
400 explicit APValue(const APValue *E, unsigned N)
401 : Kind(None), AllowConstexprUnknown(false) {
402 MakeVector(); setVector(E, N);
403 }
404 /// Creates a matrix APValue with given dimensions. The elements
405 /// are read from \p E and assumed to be in row-major order.
406 explicit APValue(const APValue *E, unsigned NumRows, unsigned NumCols)
407 : Kind(None), AllowConstexprUnknown(false) {
408 MakeMatrix();
409 setMatrix(E, NumRows, NumCols);
410 }
411 /// Creates an integer complex APValue with the given real and imaginary
412 /// values.
413 APValue(APSInt R, APSInt I) : Kind(None), AllowConstexprUnknown(false) {
414 MakeComplexInt(); setComplexInt(R: std::move(R), I: std::move(I));
415 }
416 /// Creates a float complex APValue with the given real and imaginary values.
417 APValue(APFloat R, APFloat I) : Kind(None), AllowConstexprUnknown(false) {
418 MakeComplexFloat(); setComplexFloat(R: std::move(R), I: std::move(I));
419 }
420 APValue(const APValue &RHS);
421 APValue(APValue &&RHS);
422 /// Creates an lvalue APValue without an lvalue path.
423 /// \param Base The base of the lvalue.
424 /// \param Offset The offset of the lvalue.
425 /// \param IsNullPtr Whether this lvalue is a null pointer.
426 APValue(LValueBase Base, CharUnits Offset, NoLValuePath,
427 bool IsNullPtr = false)
428 : Kind(None), AllowConstexprUnknown(false) {
429 MakeLValue();
430 setLValue(B: Base, O: Offset, NoLValuePath{}, IsNullPtr);
431 }
432 /// Creates an lvalue APValue with an lvalue path.
433 /// \param Base The base of the lvalue.
434 /// \param Offset The offset of the lvalue.
435 /// \param Path The lvalue path.
436 /// \param OnePastTheEnd Whether this lvalue is one-past-the-end of the
437 /// subobject it points to.
438 /// \param IsNullPtr Whether this lvalue is a null pointer.
439 APValue(LValueBase Base, CharUnits Offset, ArrayRef<LValuePathEntry> Path,
440 bool OnePastTheEnd, bool IsNullPtr = false)
441 : Kind(None), AllowConstexprUnknown(false) {
442 MakeLValue();
443 setLValue(B: Base, O: Offset, Path, OnePastTheEnd, IsNullPtr);
444 }
445 /// Creates a constexpr unknown lvalue APValue.
446 /// \param Base The base of the lvalue.
447 /// \param Offset The offset of the lvalue.
448 /// \param IsNullPtr Whether this lvalue is a null pointer.
449 APValue(LValueBase Base, CharUnits Offset, ConstexprUnknown,
450 bool IsNullPtr = false)
451 : Kind(None), AllowConstexprUnknown(true) {
452 MakeLValue();
453 setLValue(B: Base, O: Offset, NoLValuePath{}, IsNullPtr);
454 }
455
456 /// Creates a new array APValue.
457 /// \param UninitArray Marker. Pass an empty UninitArray.
458 /// \param InitElts Number of elements you're going to initialize in the
459 /// array.
460 /// \param Size Full size of the array.
461 APValue(UninitArray, unsigned InitElts, unsigned Size)
462 : Kind(None), AllowConstexprUnknown(false) {
463 MakeArray(InitElts, Size);
464 }
465
466 /// Creates a new Reflection APValue.
467 /// \param OperandKind The kind of reflection.
468 /// \param Operand The entity being reflected.
469 APValue(ReflectionKind OperandKind, const void *Operand) : Kind(None) {
470 MakeReflection(OperandKind, Operand);
471 }
472
473 /// Creates a new struct APValue.
474 /// \param UninitStruct Marker. Pass an empty UninitStruct.
475 /// \param NumBases Number of bases.
476 /// \param NumMembers Number of members.
477 /// \param NumVirtualBases Number of virtual bases.
478 APValue(UninitStruct, unsigned NumBases, unsigned NumMembers,
479 unsigned NumVirtualBases = 0)
480 : Kind(None), AllowConstexprUnknown(false) {
481 MakeStruct(B: NumBases, M: NumMembers, V: NumVirtualBases);
482 }
483 /// Creates a new union APValue.
484 /// \param ActiveDecl The FieldDecl of the active union member.
485 /// \param ActiveValue The value of the active union member.
486 explicit APValue(const FieldDecl *ActiveDecl,
487 const APValue &ActiveValue = APValue())
488 : Kind(None), AllowConstexprUnknown(false) {
489 MakeUnion();
490 setUnion(Field: ActiveDecl, Value: ActiveValue);
491 }
492 /// Creates a new member pointer APValue.
493 /// \param Member Declaration of the member
494 /// \param IsDerivedMember Whether member is a derived one.
495 /// \param Path The path of the member.
496 APValue(const ValueDecl *Member, bool IsDerivedMember,
497 ArrayRef<const CXXRecordDecl *> Path)
498 : Kind(None), AllowConstexprUnknown(false) {
499 MakeMemberPointer(Member, IsDerivedMember, Path);
500 }
501 /// Creates a new address label diff APValue.
502 /// \param LHSExpr The left-hand side of the difference.
503 /// \param RHSExpr The right-hand side of the difference.
504 APValue(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
505 : Kind(None), AllowConstexprUnknown(false) {
506 MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
507 }
508 static APValue IndeterminateValue() {
509 APValue Result;
510 Result.Kind = Indeterminate;
511 return Result;
512 }
513
514 APValue &operator=(const APValue &RHS);
515 APValue &operator=(APValue &&RHS);
516
517 ~APValue() {
518 if (Kind != None && Kind != Indeterminate)
519 DestroyDataAndMakeUninit();
520 }
521
522 /// Returns whether the object performed allocations.
523 ///
524 /// If APValues are constructed via placement new, \c needsCleanup()
525 /// indicates whether the destructor must be called in order to correctly
526 /// free all allocated memory.
527 bool needsCleanup() const;
528
529 /// Swaps the contents of this and the given APValue.
530 void swap(APValue &RHS);
531
532 /// profile this value. There is no guarantee that values of different
533 /// types will not produce the same profiled value, so the type should
534 /// typically also be profiled if it's not implied by the context.
535 void Profile(llvm::FoldingSetNodeID &ID) const;
536
537 ValueKind getKind() const { return Kind; }
538
539 /// Visit this value and every recursively nested value. Iteration order
540 /// is unspecified.
541 ///
542 /// Visitation stops if \p Visitor returns false.
543 void visit(llvm::function_ref<bool(const APValue &)> Visitor) const;
544
545 bool isAbsent() const { return Kind == None; }
546 bool isIndeterminate() const { return Kind == Indeterminate; }
547 bool hasValue() const { return Kind != None && Kind != Indeterminate; }
548
549 bool isInt() const { return Kind == Int; }
550 bool isFloat() const { return Kind == Float; }
551 bool isFixedPoint() const { return Kind == FixedPoint; }
552 bool isComplexInt() const { return Kind == ComplexInt; }
553 bool isComplexFloat() const { return Kind == ComplexFloat; }
554 bool isLValue() const { return Kind == LValue; }
555 bool isVector() const { return Kind == Vector; }
556 bool isMatrix() const { return Kind == Matrix; }
557 bool isArray() const { return Kind == Array; }
558 bool isStruct() const { return Kind == Struct; }
559 bool isUnion() const { return Kind == Union; }
560 bool isMemberPointer() const { return Kind == MemberPointer; }
561 bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
562 bool isReflection() const { return Kind == Reflection; }
563
564 void dump() const;
565 void dump(raw_ostream &OS, const ASTContext &Context) const;
566
567 void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const;
568 void printPretty(raw_ostream &OS, const PrintingPolicy &Policy, QualType Ty,
569 const ASTContext *Ctx = nullptr) const;
570
571 std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
572
573 APSInt &getInt() {
574 assert(isInt() && "Invalid accessor");
575 return *(APSInt *)(char *)&Data;
576 }
577 const APSInt &getInt() const {
578 return const_cast<APValue*>(this)->getInt();
579 }
580
581 /// Try to convert this value to an integral constant. This works if it's an
582 /// integer, null pointer, or offset from a null pointer. Returns true on
583 /// success.
584 bool toIntegralConstant(APSInt &Result, QualType SrcTy,
585 const ASTContext &Ctx) const;
586
587 APFloat &getFloat() {
588 assert(isFloat() && "Invalid accessor");
589 return *(APFloat *)(char *)&Data;
590 }
591 const APFloat &getFloat() const {
592 return const_cast<APValue*>(this)->getFloat();
593 }
594
595 APFixedPoint &getFixedPoint() {
596 assert(isFixedPoint() && "Invalid accessor");
597 return *(APFixedPoint *)(char *)&Data;
598 }
599 const APFixedPoint &getFixedPoint() const {
600 return const_cast<APValue *>(this)->getFixedPoint();
601 }
602
603 APSInt &getComplexIntReal() {
604 assert(isComplexInt() && "Invalid accessor");
605 return ((ComplexAPSInt *)(char *)&Data)->Real;
606 }
607 const APSInt &getComplexIntReal() const {
608 return const_cast<APValue*>(this)->getComplexIntReal();
609 }
610
611 APSInt &getComplexIntImag() {
612 assert(isComplexInt() && "Invalid accessor");
613 return ((ComplexAPSInt *)(char *)&Data)->Imag;
614 }
615 const APSInt &getComplexIntImag() const {
616 return const_cast<APValue*>(this)->getComplexIntImag();
617 }
618
619 APFloat &getComplexFloatReal() {
620 assert(isComplexFloat() && "Invalid accessor");
621 return ((ComplexAPFloat *)(char *)&Data)->Real;
622 }
623 const APFloat &getComplexFloatReal() const {
624 return const_cast<APValue*>(this)->getComplexFloatReal();
625 }
626
627 APFloat &getComplexFloatImag() {
628 assert(isComplexFloat() && "Invalid accessor");
629 return ((ComplexAPFloat *)(char *)&Data)->Imag;
630 }
631 const APFloat &getComplexFloatImag() const {
632 return const_cast<APValue*>(this)->getComplexFloatImag();
633 }
634
635 const LValueBase getLValueBase() const;
636 CharUnits &getLValueOffset();
637 CharUnits getLValueOffset() const {
638 return const_cast<APValue*>(this)->getLValueOffset();
639 }
640 bool isLValueOnePastTheEnd() const;
641 bool hasLValuePath() const;
642 ArrayRef<LValuePathEntry> getLValuePath() const;
643 unsigned getLValueCallIndex() const;
644 unsigned getLValueVersion() const;
645 bool isNullPointer() const;
646
647 APValue &getVectorElt(unsigned I) {
648 assert(isVector() && "Invalid accessor");
649 assert(I < getVectorLength() && "Index out of range");
650 return ((Vec *)(char *)&Data)->Elts[I];
651 }
652 const APValue &getVectorElt(unsigned I) const {
653 return const_cast<APValue*>(this)->getVectorElt(I);
654 }
655 unsigned getVectorLength() const {
656 assert(isVector() && "Invalid accessor");
657 return ((const Vec *)(const void *)&Data)->NumElts;
658 }
659
660 unsigned getMatrixNumRows() const {
661 assert(isMatrix() && "Invalid accessor");
662 return ((const Mat *)(const void *)&Data)->NumRows;
663 }
664 unsigned getMatrixNumColumns() const {
665 assert(isMatrix() && "Invalid accessor");
666 return ((const Mat *)(const void *)&Data)->NumCols;
667 }
668 unsigned getMatrixNumElements() const {
669 return getMatrixNumRows() * getMatrixNumColumns();
670 }
671 APValue &getMatrixElt(unsigned Idx) {
672 assert(isMatrix() && "Invalid accessor");
673 assert(Idx < getMatrixNumElements() && "Index out of range");
674 return ((Mat *)(char *)&Data)->Elts[Idx];
675 }
676 const APValue &getMatrixElt(unsigned Idx) const {
677 return const_cast<APValue *>(this)->getMatrixElt(Idx);
678 }
679 APValue &getMatrixElt(unsigned Row, unsigned Col) {
680 assert(isMatrix() && "Invalid accessor");
681 assert(Row < getMatrixNumRows() && "Row index out of range");
682 assert(Col < getMatrixNumColumns() && "Column index out of range");
683 // Matrix elements are stored in row-major order.
684 unsigned I = Row * getMatrixNumColumns() + Col;
685 return getMatrixElt(Idx: I);
686 }
687 const APValue &getMatrixElt(unsigned Row, unsigned Col) const {
688 return const_cast<APValue *>(this)->getMatrixElt(Row, Col);
689 }
690
691 APValue &getArrayInitializedElt(unsigned I) {
692 assert(isArray() && "Invalid accessor");
693 assert(I < getArrayInitializedElts() && "Index out of range");
694 return ((Arr *)(char *)&Data)->Elts[I];
695 }
696 const APValue &getArrayInitializedElt(unsigned I) const {
697 return const_cast<APValue*>(this)->getArrayInitializedElt(I);
698 }
699 bool hasArrayFiller() const {
700 return getArrayInitializedElts() != getArraySize();
701 }
702 APValue &getArrayFiller() {
703 assert(isArray() && "Invalid accessor");
704 assert(hasArrayFiller() && "No array filler");
705 return ((Arr *)(char *)&Data)->Elts[getArrayInitializedElts()];
706 }
707 const APValue &getArrayFiller() const {
708 return const_cast<APValue*>(this)->getArrayFiller();
709 }
710 unsigned getArrayInitializedElts() const {
711 assert(isArray() && "Invalid accessor");
712 return ((const Arr *)(const void *)&Data)->NumElts;
713 }
714 unsigned getArraySize() const {
715 assert(isArray() && "Invalid accessor");
716 return ((const Arr *)(const void *)&Data)->ArrSize;
717 }
718
719 unsigned getStructNumBases() const {
720 assert(isStruct() && "Invalid accessor");
721 return ((const StructData *)(const char *)&Data)->NumBases;
722 }
723 unsigned getStructNumFields() const {
724 assert(isStruct() && "Invalid accessor");
725 return ((const StructData *)(const char *)&Data)->NumFields;
726 }
727 unsigned getStructNumVirtualBases() const {
728 assert(isStruct() && "Invalid accessor");
729 return ((const StructData *)(const char *)&Data)->NumVirtualBases;
730 }
731 APValue &getStructBase(unsigned i) {
732 assert(isStruct() && "Invalid accessor");
733 assert(i < getStructNumBases() && "base class index OOB");
734 return ((StructData *)(char *)&Data)->Elts[i];
735 }
736 APValue &getStructField(unsigned i) {
737 assert(isStruct() && "Invalid accessor");
738 assert(i < getStructNumFields() && "field index OOB");
739 return ((StructData *)(char *)&Data)->Elts[getStructNumBases() + i];
740 }
741 APValue &getStructVirtualBase(unsigned i) {
742 assert(isStruct() && "Invalid accessor");
743 assert(i < getStructNumVirtualBases() && "virtual base class index OOB");
744 return ((StructData *)(char *)&Data)
745 ->Elts[getStructNumBases() + getStructNumFields() + i];
746 }
747 const APValue &getStructBase(unsigned i) const {
748 return const_cast<APValue*>(this)->getStructBase(i);
749 }
750 const APValue &getStructField(unsigned i) const {
751 return const_cast<APValue*>(this)->getStructField(i);
752 }
753 const APValue &getStructVirtualBase(unsigned i) const {
754 return const_cast<APValue *>(this)->getStructVirtualBase(i);
755 }
756
757 const FieldDecl *getUnionField() const {
758 assert(isUnion() && "Invalid accessor");
759 return ((const UnionData *)(const char *)&Data)->Field;
760 }
761 APValue &getUnionValue() {
762 assert(isUnion() && "Invalid accessor");
763 return *((UnionData *)(char *)&Data)->Value;
764 }
765 const APValue &getUnionValue() const {
766 return const_cast<APValue*>(this)->getUnionValue();
767 }
768
769 const ValueDecl *getMemberPointerDecl() const;
770 bool isMemberPointerToDerivedMember() const;
771 ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
772
773 const AddrLabelExpr* getAddrLabelDiffLHS() const {
774 assert(isAddrLabelDiff() && "Invalid accessor");
775 return ((const AddrLabelDiffData *)(const char *)&Data)->LHSExpr;
776 }
777 const AddrLabelExpr* getAddrLabelDiffRHS() const {
778 assert(isAddrLabelDiff() && "Invalid accessor");
779 return ((const AddrLabelDiffData *)(const char *)&Data)->RHSExpr;
780 }
781
782 ReflectionKind getReflectionOperandKind() const {
783 assert(isReflection() && "Invalid accessor");
784 return ((const ReflectionData *)(const char *)&Data)->OperandKind;
785 }
786
787 const void *getReflectionOpaqueOperand() const {
788 assert(isReflection() && "Invalid accessor");
789 return ((const ReflectionData *)(const char *)&Data)->Operand;
790 }
791
792 void setInt(APSInt I) {
793 assert(isInt() && "Invalid accessor");
794 *(APSInt *)(char *)&Data = std::move(I);
795 }
796 void setFloat(APFloat F) {
797 assert(isFloat() && "Invalid accessor");
798 *(APFloat *)(char *)&Data = std::move(F);
799 }
800 void setFixedPoint(APFixedPoint FX) {
801 assert(isFixedPoint() && "Invalid accessor");
802 *(APFixedPoint *)(char *)&Data = std::move(FX);
803 }
804 void setVector(const APValue *E, unsigned N) {
805 MutableArrayRef<APValue> InternalElts = setVectorUninit(N);
806 for (unsigned i = 0; i != N; ++i)
807 InternalElts[i] = E[i];
808 }
809 void setMatrix(const APValue *E, unsigned NumRows, unsigned NumCols) {
810 MutableArrayRef<APValue> InternalElts = setMatrixUninit(NumRows, NumCols);
811 for (unsigned i = 0; i != NumRows * NumCols; ++i)
812 InternalElts[i] = E[i];
813 }
814 void setComplexInt(APSInt R, APSInt I) {
815 assert(R.getBitWidth() == I.getBitWidth() &&
816 "Invalid complex int (type mismatch).");
817 assert(isComplexInt() && "Invalid accessor");
818 ((ComplexAPSInt *)(char *)&Data)->Real = std::move(R);
819 ((ComplexAPSInt *)(char *)&Data)->Imag = std::move(I);
820 }
821 void setComplexFloat(APFloat R, APFloat I) {
822 assert(&R.getSemantics() == &I.getSemantics() &&
823 "Invalid complex float (type mismatch).");
824 assert(isComplexFloat() && "Invalid accessor");
825 ((ComplexAPFloat *)(char *)&Data)->Real = std::move(R);
826 ((ComplexAPFloat *)(char *)&Data)->Imag = std::move(I);
827 }
828 void setLValue(LValueBase B, CharUnits O, NoLValuePath, bool IsNullPtr);
829 void setLValue(LValueBase B, CharUnits O, ArrayRef<LValuePathEntry> Path,
830 bool OnePastTheEnd, bool IsNullPtr);
831 void setUnion(const FieldDecl *Field, const APValue &Value);
832 void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
833 const AddrLabelExpr* RHSExpr) {
834 ((AddrLabelDiffData *)(char *)&Data)->LHSExpr = LHSExpr;
835 ((AddrLabelDiffData *)(char *)&Data)->RHSExpr = RHSExpr;
836 }
837
838private:
839 void DestroyDataAndMakeUninit();
840 void MakeReflection(ReflectionKind OperandKind, const void *Operand) {
841 assert(isAbsent() && "Bad state change");
842 new ((void *)(char *)Data.buffer) ReflectionData{.OperandKind: OperandKind, .Operand: Operand};
843 Kind = Reflection;
844 }
845 void MakeInt(const APSInt &I) {
846 assert(isAbsent() && "Bad state change");
847 new ((void *)&Data) APSInt(std::move(I));
848 Kind = Int;
849 }
850 void MakeInt(APSInt &&I) {
851 assert(isAbsent() && "Bad state change");
852 new ((void *)&Data) APSInt(std::move(I));
853 Kind = Int;
854 }
855 void MakeFloat(const APFloat &F) {
856 assert(isAbsent() && "Bad state change");
857 new ((void *)(char *)&Data) APFloat(F);
858 Kind = Float;
859 }
860 void MakeFloat(APFloat &&F) {
861 assert(isAbsent() && "Bad state change");
862 new ((void *)(char *)&Data) APFloat(std::move(F));
863 Kind = Float;
864 }
865 void MakeFixedPoint(APFixedPoint &&FX) {
866 assert(isAbsent() && "Bad state change");
867 new ((void *)(char *)&Data) APFixedPoint(std::move(FX));
868 Kind = FixedPoint;
869 }
870 void MakeVector() {
871 assert(isAbsent() && "Bad state change");
872 new ((void *)(char *)&Data) Vec();
873 Kind = Vector;
874 }
875 void MakeMatrix() {
876 assert(isAbsent() && "Bad state change");
877 new ((void *)(char *)&Data) Mat();
878 Kind = Matrix;
879 }
880 void MakeComplexInt() {
881 assert(isAbsent() && "Bad state change");
882 new ((void *)(char *)&Data) ComplexAPSInt();
883 Kind = ComplexInt;
884 }
885 void MakeComplexFloat() {
886 assert(isAbsent() && "Bad state change");
887 new ((void *)(char *)&Data) ComplexAPFloat();
888 Kind = ComplexFloat;
889 }
890 void MakeLValue();
891 void MakeArray(unsigned InitElts, unsigned Size);
892 void MakeStruct(unsigned B, unsigned M, unsigned V) {
893 assert(isAbsent() && "Bad state change");
894 new ((void *)(char *)&Data) StructData(B, M, V);
895 Kind = Struct;
896 }
897 void MakeUnion() {
898 assert(isAbsent() && "Bad state change");
899 new ((void *)(char *)&Data) UnionData();
900 Kind = Union;
901 }
902 void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
903 ArrayRef<const CXXRecordDecl*> Path);
904 void MakeAddrLabelDiff() {
905 assert(isAbsent() && "Bad state change");
906 new ((void *)(char *)&Data) AddrLabelDiffData();
907 Kind = AddrLabelDiff;
908 }
909
910private:
911 /// The following functions are used as part of initialization, during
912 /// deserialization and importing. Reserve the space so that it can be
913 /// filled in by those steps.
914 MutableArrayRef<APValue> setVectorUninit(unsigned N) {
915 assert(isVector() && "Invalid accessor");
916 Vec *V = ((Vec *)(char *)&Data);
917 V->Elts = new APValue[N];
918 V->NumElts = N;
919 return {V->Elts, V->NumElts};
920 }
921 MutableArrayRef<APValue> setMatrixUninit(unsigned NumRows, unsigned NumCols) {
922 assert(isMatrix() && "Invalid accessor");
923 Mat *M = ((Mat *)(char *)&Data);
924 unsigned NumElts = NumRows * NumCols;
925 M->Elts = new APValue[NumElts];
926 M->NumRows = NumRows;
927 M->NumCols = NumCols;
928 return {M->Elts, NumElts};
929 }
930 MutableArrayRef<LValuePathEntry> setLValueUninit(LValueBase B, CharUnits O,
931 unsigned Size,
932 bool OnePastTheEnd,
933 bool IsNullPtr);
934 MutableArrayRef<const CXXRecordDecl *>
935 setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember,
936 unsigned Size);
937};
938
939} // end namespace clang.
940
941namespace llvm {
942template<> struct DenseMapInfo<clang::APValue::LValueBase> {
943 static unsigned getHashValue(const clang::APValue::LValueBase &Base);
944 static bool isEqual(const clang::APValue::LValueBase &LHS,
945 const clang::APValue::LValueBase &RHS);
946};
947}
948
949#endif
950