10b57cec5SDimitry Andric //===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric //  This file defines the APValue class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_CLANG_AST_APVALUE_H
140b57cec5SDimitry Andric #define LLVM_CLANG_AST_APVALUE_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "clang/Basic/LLVM.h"
17e8d8bef9SDimitry Andric #include "llvm/ADT/APFixedPoint.h"
180b57cec5SDimitry Andric #include "llvm/ADT/APFloat.h"
190b57cec5SDimitry Andric #include "llvm/ADT/APSInt.h"
20e8d8bef9SDimitry Andric #include "llvm/ADT/FoldingSet.h"
210b57cec5SDimitry Andric #include "llvm/ADT/PointerIntPair.h"
220b57cec5SDimitry Andric #include "llvm/ADT/PointerUnion.h"
23e8d8bef9SDimitry Andric #include "llvm/Support/AlignOf.h"
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric namespace clang {
26e8d8bef9SDimitry Andric namespace serialization {
27e8d8bef9SDimitry Andric template <typename T> class BasicReaderBase;
28e8d8bef9SDimitry Andric } // end namespace serialization
29e8d8bef9SDimitry Andric 
300b57cec5SDimitry Andric   class AddrLabelExpr;
310b57cec5SDimitry Andric   class ASTContext;
320b57cec5SDimitry Andric   class CharUnits;
330b57cec5SDimitry Andric   class CXXRecordDecl;
340b57cec5SDimitry Andric   class Decl;
350b57cec5SDimitry Andric   class DiagnosticBuilder;
360b57cec5SDimitry Andric   class Expr;
370b57cec5SDimitry Andric   class FieldDecl;
380b57cec5SDimitry Andric   struct PrintingPolicy;
390b57cec5SDimitry Andric   class Type;
400b57cec5SDimitry Andric   class ValueDecl;
41e8d8bef9SDimitry Andric   class QualType;
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric /// Symbolic representation of typeid(T) for some type T.
440b57cec5SDimitry Andric class TypeInfoLValue {
450b57cec5SDimitry Andric   const Type *T;
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric public:
TypeInfoLValue()480b57cec5SDimitry Andric   TypeInfoLValue() : T() {}
490b57cec5SDimitry Andric   explicit TypeInfoLValue(const Type *T);
500b57cec5SDimitry Andric 
getType()510b57cec5SDimitry Andric   const Type *getType() const { return T; }
520b57cec5SDimitry Andric   explicit operator bool() const { return T; }
530b57cec5SDimitry Andric 
getOpaqueValue()540b57cec5SDimitry Andric   void *getOpaqueValue() { return const_cast<Type*>(T); }
getFromOpaqueValue(void * Value)550b57cec5SDimitry Andric   static TypeInfoLValue getFromOpaqueValue(void *Value) {
560b57cec5SDimitry Andric     TypeInfoLValue V;
570b57cec5SDimitry Andric     V.T = reinterpret_cast<const Type*>(Value);
580b57cec5SDimitry Andric     return V;
590b57cec5SDimitry Andric   }
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric   void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const;
620b57cec5SDimitry Andric };
63a7dea167SDimitry Andric 
64a7dea167SDimitry Andric /// Symbolic representation of a dynamic allocation.
65a7dea167SDimitry Andric class DynamicAllocLValue {
66a7dea167SDimitry Andric   unsigned Index;
67a7dea167SDimitry Andric 
68a7dea167SDimitry Andric public:
DynamicAllocLValue()69a7dea167SDimitry Andric   DynamicAllocLValue() : Index(0) {}
DynamicAllocLValue(unsigned Index)70a7dea167SDimitry Andric   explicit DynamicAllocLValue(unsigned Index) : Index(Index + 1) {}
getIndex()71a7dea167SDimitry Andric   unsigned getIndex() { return Index - 1; }
72a7dea167SDimitry Andric 
73a7dea167SDimitry Andric   explicit operator bool() const { return Index != 0; }
74a7dea167SDimitry Andric 
getOpaqueValue()75a7dea167SDimitry Andric   void *getOpaqueValue() {
76a7dea167SDimitry Andric     return reinterpret_cast<void *>(static_cast<uintptr_t>(Index)
77a7dea167SDimitry Andric                                     << NumLowBitsAvailable);
78a7dea167SDimitry Andric   }
getFromOpaqueValue(void * Value)79a7dea167SDimitry Andric   static DynamicAllocLValue getFromOpaqueValue(void *Value) {
80a7dea167SDimitry Andric     DynamicAllocLValue V;
81a7dea167SDimitry Andric     V.Index = reinterpret_cast<uintptr_t>(Value) >> NumLowBitsAvailable;
82a7dea167SDimitry Andric     return V;
83a7dea167SDimitry Andric   }
84a7dea167SDimitry Andric 
getMaxIndex()85a7dea167SDimitry Andric   static unsigned getMaxIndex() {
86a7dea167SDimitry Andric     return (std::numeric_limits<unsigned>::max() >> NumLowBitsAvailable) - 1;
87a7dea167SDimitry Andric   }
88a7dea167SDimitry Andric 
89a7dea167SDimitry Andric   static constexpr int NumLowBitsAvailable = 3;
90a7dea167SDimitry Andric };
910b57cec5SDimitry Andric }
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric namespace llvm {
940b57cec5SDimitry Andric template<> struct PointerLikeTypeTraits<clang::TypeInfoLValue> {
950b57cec5SDimitry Andric   static void *getAsVoidPointer(clang::TypeInfoLValue V) {
960b57cec5SDimitry Andric     return V.getOpaqueValue();
970b57cec5SDimitry Andric   }
980b57cec5SDimitry Andric   static clang::TypeInfoLValue getFromVoidPointer(void *P) {
990b57cec5SDimitry Andric     return clang::TypeInfoLValue::getFromOpaqueValue(P);
1000b57cec5SDimitry Andric   }
1010b57cec5SDimitry Andric   // Validated by static_assert in APValue.cpp; hardcoded to avoid needing
1020b57cec5SDimitry Andric   // to include Type.h.
1030b57cec5SDimitry Andric   static constexpr int NumLowBitsAvailable = 3;
1040b57cec5SDimitry Andric };
105a7dea167SDimitry Andric 
106a7dea167SDimitry Andric template<> struct PointerLikeTypeTraits<clang::DynamicAllocLValue> {
107a7dea167SDimitry Andric   static void *getAsVoidPointer(clang::DynamicAllocLValue V) {
108a7dea167SDimitry Andric     return V.getOpaqueValue();
109a7dea167SDimitry Andric   }
110a7dea167SDimitry Andric   static clang::DynamicAllocLValue getFromVoidPointer(void *P) {
111a7dea167SDimitry Andric     return clang::DynamicAllocLValue::getFromOpaqueValue(P);
112a7dea167SDimitry Andric   }
113a7dea167SDimitry Andric   static constexpr int NumLowBitsAvailable =
114a7dea167SDimitry Andric       clang::DynamicAllocLValue::NumLowBitsAvailable;
115a7dea167SDimitry Andric };
1160b57cec5SDimitry Andric }
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric namespace clang {
1190b57cec5SDimitry Andric /// APValue - This class implements a discriminated union of [uninitialized]
1200b57cec5SDimitry Andric /// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
1210b57cec5SDimitry Andric /// [Vector: N * APValue], [Array: N * APValue]
1220b57cec5SDimitry Andric class APValue {
123e8d8bef9SDimitry Andric   typedef llvm::APFixedPoint APFixedPoint;
1240b57cec5SDimitry Andric   typedef llvm::APSInt APSInt;
1250b57cec5SDimitry Andric   typedef llvm::APFloat APFloat;
1260b57cec5SDimitry Andric public:
1270b57cec5SDimitry Andric   enum ValueKind {
1280b57cec5SDimitry Andric     /// There is no such object (it's outside its lifetime).
1290b57cec5SDimitry Andric     None,
1300b57cec5SDimitry Andric     /// This object has an indeterminate value (C++ [basic.indet]).
1310b57cec5SDimitry Andric     Indeterminate,
1320b57cec5SDimitry Andric     Int,
1330b57cec5SDimitry Andric     Float,
1340b57cec5SDimitry Andric     FixedPoint,
1350b57cec5SDimitry Andric     ComplexInt,
1360b57cec5SDimitry Andric     ComplexFloat,
1370b57cec5SDimitry Andric     LValue,
1380b57cec5SDimitry Andric     Vector,
1390b57cec5SDimitry Andric     Array,
1400b57cec5SDimitry Andric     Struct,
1410b57cec5SDimitry Andric     Union,
1420b57cec5SDimitry Andric     MemberPointer,
1430b57cec5SDimitry Andric     AddrLabelDiff
1440b57cec5SDimitry Andric   };
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric   class LValueBase {
147a7dea167SDimitry Andric     typedef llvm::PointerUnion<const ValueDecl *, const Expr *, TypeInfoLValue,
148a7dea167SDimitry Andric                                DynamicAllocLValue>
1490b57cec5SDimitry Andric         PtrTy;
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric   public:
1520b57cec5SDimitry Andric     LValueBase() : Local{} {}
1530b57cec5SDimitry Andric     LValueBase(const ValueDecl *P, unsigned I = 0, unsigned V = 0);
1540b57cec5SDimitry Andric     LValueBase(const Expr *P, unsigned I = 0, unsigned V = 0);
155a7dea167SDimitry Andric     static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type);
1560b57cec5SDimitry Andric     static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo);
1570b57cec5SDimitry Andric 
158e8d8bef9SDimitry Andric     void Profile(llvm::FoldingSetNodeID &ID) const;
159e8d8bef9SDimitry Andric 
1600b57cec5SDimitry Andric     template <class T>
1610b57cec5SDimitry Andric     bool is() const { return Ptr.is<T>(); }
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric     template <class T>
1640b57cec5SDimitry Andric     T get() const { return Ptr.get<T>(); }
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric     template <class T>
1670b57cec5SDimitry Andric     T dyn_cast() const { return Ptr.dyn_cast<T>(); }
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric     void *getOpaqueValue() const;
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric     bool isNull() const;
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric     explicit operator bool() const;
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric     unsigned getCallIndex() const;
1760b57cec5SDimitry Andric     unsigned getVersion() const;
1770b57cec5SDimitry Andric     QualType getTypeInfoType() const;
178a7dea167SDimitry Andric     QualType getDynamicAllocType() const;
1790b57cec5SDimitry Andric 
180e8d8bef9SDimitry Andric     QualType getType() const;
181e8d8bef9SDimitry Andric 
1820b57cec5SDimitry Andric     friend bool operator==(const LValueBase &LHS, const LValueBase &RHS);
1830b57cec5SDimitry Andric     friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) {
1840b57cec5SDimitry Andric       return !(LHS == RHS);
1850b57cec5SDimitry Andric     }
1860b57cec5SDimitry Andric     friend llvm::hash_code hash_value(const LValueBase &Base);
187e8d8bef9SDimitry Andric     friend struct llvm::DenseMapInfo<LValueBase>;
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric   private:
1900b57cec5SDimitry Andric     PtrTy Ptr;
1910b57cec5SDimitry Andric     struct LocalState {
1920b57cec5SDimitry Andric       unsigned CallIndex, Version;
1930b57cec5SDimitry Andric     };
1940b57cec5SDimitry Andric     union {
1950b57cec5SDimitry Andric       LocalState Local;
1960b57cec5SDimitry Andric       /// The type std::type_info, if this is a TypeInfoLValue.
1970b57cec5SDimitry Andric       void *TypeInfoType;
198a7dea167SDimitry Andric       /// The QualType, if this is a DynamicAllocLValue.
199a7dea167SDimitry Andric       void *DynamicAllocType;
2000b57cec5SDimitry Andric     };
2010b57cec5SDimitry Andric   };
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric   /// A FieldDecl or CXXRecordDecl, along with a flag indicating whether we
2040b57cec5SDimitry Andric   /// mean a virtual or non-virtual base class subobject.
2050b57cec5SDimitry Andric   typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
2060b57cec5SDimitry Andric 
2070b57cec5SDimitry Andric   /// A non-discriminated union of a base, field, or array index.
2080b57cec5SDimitry Andric   class LValuePathEntry {
2090b57cec5SDimitry Andric     static_assert(sizeof(uintptr_t) <= sizeof(uint64_t),
2100b57cec5SDimitry Andric                   "pointer doesn't fit in 64 bits?");
2110b57cec5SDimitry Andric     uint64_t Value;
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric   public:
2140b57cec5SDimitry Andric     LValuePathEntry() : Value() {}
215e8d8bef9SDimitry Andric     LValuePathEntry(BaseOrMemberType BaseOrMember);
2160b57cec5SDimitry Andric     static LValuePathEntry ArrayIndex(uint64_t Index) {
2170b57cec5SDimitry Andric       LValuePathEntry Result;
2180b57cec5SDimitry Andric       Result.Value = Index;
2190b57cec5SDimitry Andric       return Result;
2200b57cec5SDimitry Andric     }
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric     BaseOrMemberType getAsBaseOrMember() const {
2230b57cec5SDimitry Andric       return BaseOrMemberType::getFromOpaqueValue(
2240b57cec5SDimitry Andric           reinterpret_cast<void *>(Value));
2250b57cec5SDimitry Andric     }
2260b57cec5SDimitry Andric     uint64_t getAsArrayIndex() const { return Value; }
2270b57cec5SDimitry Andric 
228e8d8bef9SDimitry Andric     void Profile(llvm::FoldingSetNodeID &ID) const;
229e8d8bef9SDimitry Andric 
2300b57cec5SDimitry Andric     friend bool operator==(LValuePathEntry A, LValuePathEntry B) {
2310b57cec5SDimitry Andric       return A.Value == B.Value;
2320b57cec5SDimitry Andric     }
2330b57cec5SDimitry Andric     friend bool operator!=(LValuePathEntry A, LValuePathEntry B) {
2340b57cec5SDimitry Andric       return A.Value != B.Value;
2350b57cec5SDimitry Andric     }
2360b57cec5SDimitry Andric     friend llvm::hash_code hash_value(LValuePathEntry A) {
2370b57cec5SDimitry Andric       return llvm::hash_value(A.Value);
2380b57cec5SDimitry Andric     }
2390b57cec5SDimitry Andric   };
240e8d8bef9SDimitry Andric   class LValuePathSerializationHelper {
241bdd1243dSDimitry Andric     const void *Ty;
242e8d8bef9SDimitry Andric 
243e8d8bef9SDimitry Andric   public:
244e8d8bef9SDimitry Andric     ArrayRef<LValuePathEntry> Path;
245e8d8bef9SDimitry Andric 
246e8d8bef9SDimitry Andric     LValuePathSerializationHelper(ArrayRef<LValuePathEntry>, QualType);
247e8d8bef9SDimitry Andric     QualType getType();
248e8d8bef9SDimitry Andric   };
2490b57cec5SDimitry Andric   struct NoLValuePath {};
2500b57cec5SDimitry Andric   struct UninitArray {};
2510b57cec5SDimitry Andric   struct UninitStruct {};
2520b57cec5SDimitry Andric 
253e8d8bef9SDimitry Andric   template <typename Impl> friend class clang::serialization::BasicReaderBase;
254e8d8bef9SDimitry Andric   friend class ASTImporter;
255e8d8bef9SDimitry Andric   friend class ASTNodeImporter;
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric private:
2580b57cec5SDimitry Andric   ValueKind Kind;
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric   struct ComplexAPSInt {
2610b57cec5SDimitry Andric     APSInt Real, Imag;
2620b57cec5SDimitry Andric     ComplexAPSInt() : Real(1), Imag(1) {}
2630b57cec5SDimitry Andric   };
2640b57cec5SDimitry Andric   struct ComplexAPFloat {
2650b57cec5SDimitry Andric     APFloat Real, Imag;
2660b57cec5SDimitry Andric     ComplexAPFloat() : Real(0.0), Imag(0.0) {}
2670b57cec5SDimitry Andric   };
2680b57cec5SDimitry Andric   struct LV;
2690b57cec5SDimitry Andric   struct Vec {
27006c3fb27SDimitry Andric     APValue *Elts = nullptr;
27106c3fb27SDimitry Andric     unsigned NumElts = 0;
27206c3fb27SDimitry Andric     Vec() = default;
2735f757f3fSDimitry Andric     Vec(const Vec &) = delete;
2745f757f3fSDimitry Andric     Vec &operator=(const Vec &) = delete;
2750b57cec5SDimitry Andric     ~Vec() { delete[] Elts; }
2760b57cec5SDimitry Andric   };
2770b57cec5SDimitry Andric   struct Arr {
2780b57cec5SDimitry Andric     APValue *Elts;
2790b57cec5SDimitry Andric     unsigned NumElts, ArrSize;
2800b57cec5SDimitry Andric     Arr(unsigned NumElts, unsigned ArrSize);
2815f757f3fSDimitry Andric     Arr(const Arr &) = delete;
2825f757f3fSDimitry Andric     Arr &operator=(const Arr &) = delete;
2830b57cec5SDimitry Andric     ~Arr();
2840b57cec5SDimitry Andric   };
2850b57cec5SDimitry Andric   struct StructData {
2860b57cec5SDimitry Andric     APValue *Elts;
2870b57cec5SDimitry Andric     unsigned NumBases;
2880b57cec5SDimitry Andric     unsigned NumFields;
2890b57cec5SDimitry Andric     StructData(unsigned NumBases, unsigned NumFields);
2905f757f3fSDimitry Andric     StructData(const StructData &) = delete;
2915f757f3fSDimitry Andric     StructData &operator=(const StructData &) = delete;
2920b57cec5SDimitry Andric     ~StructData();
2930b57cec5SDimitry Andric   };
2940b57cec5SDimitry Andric   struct UnionData {
2950b57cec5SDimitry Andric     const FieldDecl *Field;
2960b57cec5SDimitry Andric     APValue *Value;
2970b57cec5SDimitry Andric     UnionData();
2985f757f3fSDimitry Andric     UnionData(const UnionData &) = delete;
2995f757f3fSDimitry Andric     UnionData &operator=(const UnionData &) = delete;
3000b57cec5SDimitry Andric     ~UnionData();
3010b57cec5SDimitry Andric   };
3020b57cec5SDimitry Andric   struct AddrLabelDiffData {
3030b57cec5SDimitry Andric     const AddrLabelExpr* LHSExpr;
3040b57cec5SDimitry Andric     const AddrLabelExpr* RHSExpr;
3050b57cec5SDimitry Andric   };
3060b57cec5SDimitry Andric   struct MemberPointerData;
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric   // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
3090b57cec5SDimitry Andric   typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
3100b57cec5SDimitry Andric                                       ComplexAPFloat, Vec, Arr, StructData,
3110b57cec5SDimitry Andric                                       UnionData, AddrLabelDiffData> DataType;
3120b57cec5SDimitry Andric   static const size_t DataSize = sizeof(DataType);
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric   DataType Data;
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric public:
3170b57cec5SDimitry Andric   APValue() : Kind(None) {}
3180b57cec5SDimitry Andric   explicit APValue(APSInt I) : Kind(None) {
3190b57cec5SDimitry Andric     MakeInt(); setInt(std::move(I));
3200b57cec5SDimitry Andric   }
3210b57cec5SDimitry Andric   explicit APValue(APFloat F) : Kind(None) {
3220b57cec5SDimitry Andric     MakeFloat(); setFloat(std::move(F));
3230b57cec5SDimitry Andric   }
3240b57cec5SDimitry Andric   explicit APValue(APFixedPoint FX) : Kind(None) {
3250b57cec5SDimitry Andric     MakeFixedPoint(std::move(FX));
3260b57cec5SDimitry Andric   }
3270b57cec5SDimitry Andric   explicit APValue(const APValue *E, unsigned N) : Kind(None) {
3280b57cec5SDimitry Andric     MakeVector(); setVector(E, N);
3290b57cec5SDimitry Andric   }
3300b57cec5SDimitry Andric   APValue(APSInt R, APSInt I) : Kind(None) {
3310b57cec5SDimitry Andric     MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
3320b57cec5SDimitry Andric   }
3330b57cec5SDimitry Andric   APValue(APFloat R, APFloat I) : Kind(None) {
3340b57cec5SDimitry Andric     MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
3350b57cec5SDimitry Andric   }
3360b57cec5SDimitry Andric   APValue(const APValue &RHS);
337e8d8bef9SDimitry Andric   APValue(APValue &&RHS);
3380b57cec5SDimitry Andric   APValue(LValueBase B, const CharUnits &O, NoLValuePath N,
3390b57cec5SDimitry Andric           bool IsNullPtr = false)
3400b57cec5SDimitry Andric       : Kind(None) {
3410b57cec5SDimitry Andric     MakeLValue(); setLValue(B, O, N, IsNullPtr);
3420b57cec5SDimitry Andric   }
3430b57cec5SDimitry Andric   APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
3440b57cec5SDimitry Andric           bool OnePastTheEnd, bool IsNullPtr = false)
3450b57cec5SDimitry Andric       : Kind(None) {
3460b57cec5SDimitry Andric     MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
3470b57cec5SDimitry Andric   }
3480b57cec5SDimitry Andric   APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(None) {
3490b57cec5SDimitry Andric     MakeArray(InitElts, Size);
3500b57cec5SDimitry Andric   }
3510b57cec5SDimitry Andric   APValue(UninitStruct, unsigned B, unsigned M) : Kind(None) {
3520b57cec5SDimitry Andric     MakeStruct(B, M);
3530b57cec5SDimitry Andric   }
3540b57cec5SDimitry Andric   explicit APValue(const FieldDecl *D, const APValue &V = APValue())
3550b57cec5SDimitry Andric       : Kind(None) {
3560b57cec5SDimitry Andric     MakeUnion(); setUnion(D, V);
3570b57cec5SDimitry Andric   }
3580b57cec5SDimitry Andric   APValue(const ValueDecl *Member, bool IsDerivedMember,
3590b57cec5SDimitry Andric           ArrayRef<const CXXRecordDecl*> Path) : Kind(None) {
3600b57cec5SDimitry Andric     MakeMemberPointer(Member, IsDerivedMember, Path);
3610b57cec5SDimitry Andric   }
3620b57cec5SDimitry Andric   APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
3630b57cec5SDimitry Andric       : Kind(None) {
3640b57cec5SDimitry Andric     MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
3650b57cec5SDimitry Andric   }
3660b57cec5SDimitry Andric   static APValue IndeterminateValue() {
3670b57cec5SDimitry Andric     APValue Result;
3680b57cec5SDimitry Andric     Result.Kind = Indeterminate;
3690b57cec5SDimitry Andric     return Result;
3700b57cec5SDimitry Andric   }
3710b57cec5SDimitry Andric 
372e8d8bef9SDimitry Andric   APValue &operator=(const APValue &RHS);
373e8d8bef9SDimitry Andric   APValue &operator=(APValue &&RHS);
374e8d8bef9SDimitry Andric 
3750b57cec5SDimitry Andric   ~APValue() {
3760b57cec5SDimitry Andric     if (Kind != None && Kind != Indeterminate)
3770b57cec5SDimitry Andric       DestroyDataAndMakeUninit();
3780b57cec5SDimitry Andric   }
3790b57cec5SDimitry Andric 
3800b57cec5SDimitry Andric   /// Returns whether the object performed allocations.
3810b57cec5SDimitry Andric   ///
3820b57cec5SDimitry Andric   /// If APValues are constructed via placement new, \c needsCleanup()
3830b57cec5SDimitry Andric   /// indicates whether the destructor must be called in order to correctly
3840b57cec5SDimitry Andric   /// free all allocated memory.
3850b57cec5SDimitry Andric   bool needsCleanup() const;
3860b57cec5SDimitry Andric 
3870b57cec5SDimitry Andric   /// Swaps the contents of this and the given APValue.
3880b57cec5SDimitry Andric   void swap(APValue &RHS);
3890b57cec5SDimitry Andric 
390e8d8bef9SDimitry Andric   /// profile this value. There is no guarantee that values of different
391e8d8bef9SDimitry Andric   /// types will not produce the same profiled value, so the type should
392e8d8bef9SDimitry Andric   /// typically also be profiled if it's not implied by the context.
393e8d8bef9SDimitry Andric   void Profile(llvm::FoldingSetNodeID &ID) const;
394e8d8bef9SDimitry Andric 
3950b57cec5SDimitry Andric   ValueKind getKind() const { return Kind; }
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric   bool isAbsent() const { return Kind == None; }
3980b57cec5SDimitry Andric   bool isIndeterminate() const { return Kind == Indeterminate; }
3990b57cec5SDimitry Andric   bool hasValue() const { return Kind != None && Kind != Indeterminate; }
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric   bool isInt() const { return Kind == Int; }
4020b57cec5SDimitry Andric   bool isFloat() const { return Kind == Float; }
4030b57cec5SDimitry Andric   bool isFixedPoint() const { return Kind == FixedPoint; }
4040b57cec5SDimitry Andric   bool isComplexInt() const { return Kind == ComplexInt; }
4050b57cec5SDimitry Andric   bool isComplexFloat() const { return Kind == ComplexFloat; }
4060b57cec5SDimitry Andric   bool isLValue() const { return Kind == LValue; }
4070b57cec5SDimitry Andric   bool isVector() const { return Kind == Vector; }
4080b57cec5SDimitry Andric   bool isArray() const { return Kind == Array; }
4090b57cec5SDimitry Andric   bool isStruct() const { return Kind == Struct; }
4100b57cec5SDimitry Andric   bool isUnion() const { return Kind == Union; }
4110b57cec5SDimitry Andric   bool isMemberPointer() const { return Kind == MemberPointer; }
4120b57cec5SDimitry Andric   bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
4130b57cec5SDimitry Andric 
4140b57cec5SDimitry Andric   void dump() const;
4155ffd83dbSDimitry Andric   void dump(raw_ostream &OS, const ASTContext &Context) const;
4160b57cec5SDimitry Andric 
4170b57cec5SDimitry Andric   void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const;
418e8d8bef9SDimitry Andric   void printPretty(raw_ostream &OS, const PrintingPolicy &Policy, QualType Ty,
419e8d8bef9SDimitry Andric                    const ASTContext *Ctx = nullptr) const;
420e8d8bef9SDimitry Andric 
4210b57cec5SDimitry Andric   std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
4220b57cec5SDimitry Andric 
4230b57cec5SDimitry Andric   APSInt &getInt() {
4240b57cec5SDimitry Andric     assert(isInt() && "Invalid accessor");
425e8d8bef9SDimitry Andric     return *(APSInt *)(char *)&Data;
4260b57cec5SDimitry Andric   }
4270b57cec5SDimitry Andric   const APSInt &getInt() const {
4280b57cec5SDimitry Andric     return const_cast<APValue*>(this)->getInt();
4290b57cec5SDimitry Andric   }
4300b57cec5SDimitry Andric 
4310b57cec5SDimitry Andric   /// Try to convert this value to an integral constant. This works if it's an
4320b57cec5SDimitry Andric   /// integer, null pointer, or offset from a null pointer. Returns true on
4330b57cec5SDimitry Andric   /// success.
4340b57cec5SDimitry Andric   bool toIntegralConstant(APSInt &Result, QualType SrcTy,
4350b57cec5SDimitry Andric                           const ASTContext &Ctx) const;
4360b57cec5SDimitry Andric 
4370b57cec5SDimitry Andric   APFloat &getFloat() {
4380b57cec5SDimitry Andric     assert(isFloat() && "Invalid accessor");
439e8d8bef9SDimitry Andric     return *(APFloat *)(char *)&Data;
4400b57cec5SDimitry Andric   }
4410b57cec5SDimitry Andric   const APFloat &getFloat() const {
4420b57cec5SDimitry Andric     return const_cast<APValue*>(this)->getFloat();
4430b57cec5SDimitry Andric   }
4440b57cec5SDimitry Andric 
4450b57cec5SDimitry Andric   APFixedPoint &getFixedPoint() {
4460b57cec5SDimitry Andric     assert(isFixedPoint() && "Invalid accessor");
447e8d8bef9SDimitry Andric     return *(APFixedPoint *)(char *)&Data;
4480b57cec5SDimitry Andric   }
4490b57cec5SDimitry Andric   const APFixedPoint &getFixedPoint() const {
4500b57cec5SDimitry Andric     return const_cast<APValue *>(this)->getFixedPoint();
4510b57cec5SDimitry Andric   }
4520b57cec5SDimitry Andric 
4530b57cec5SDimitry Andric   APSInt &getComplexIntReal() {
4540b57cec5SDimitry Andric     assert(isComplexInt() && "Invalid accessor");
455e8d8bef9SDimitry Andric     return ((ComplexAPSInt *)(char *)&Data)->Real;
4560b57cec5SDimitry Andric   }
4570b57cec5SDimitry Andric   const APSInt &getComplexIntReal() const {
4580b57cec5SDimitry Andric     return const_cast<APValue*>(this)->getComplexIntReal();
4590b57cec5SDimitry Andric   }
4600b57cec5SDimitry Andric 
4610b57cec5SDimitry Andric   APSInt &getComplexIntImag() {
4620b57cec5SDimitry Andric     assert(isComplexInt() && "Invalid accessor");
463e8d8bef9SDimitry Andric     return ((ComplexAPSInt *)(char *)&Data)->Imag;
4640b57cec5SDimitry Andric   }
4650b57cec5SDimitry Andric   const APSInt &getComplexIntImag() const {
4660b57cec5SDimitry Andric     return const_cast<APValue*>(this)->getComplexIntImag();
4670b57cec5SDimitry Andric   }
4680b57cec5SDimitry Andric 
4690b57cec5SDimitry Andric   APFloat &getComplexFloatReal() {
4700b57cec5SDimitry Andric     assert(isComplexFloat() && "Invalid accessor");
471e8d8bef9SDimitry Andric     return ((ComplexAPFloat *)(char *)&Data)->Real;
4720b57cec5SDimitry Andric   }
4730b57cec5SDimitry Andric   const APFloat &getComplexFloatReal() const {
4740b57cec5SDimitry Andric     return const_cast<APValue*>(this)->getComplexFloatReal();
4750b57cec5SDimitry Andric   }
4760b57cec5SDimitry Andric 
4770b57cec5SDimitry Andric   APFloat &getComplexFloatImag() {
4780b57cec5SDimitry Andric     assert(isComplexFloat() && "Invalid accessor");
479e8d8bef9SDimitry Andric     return ((ComplexAPFloat *)(char *)&Data)->Imag;
4800b57cec5SDimitry Andric   }
4810b57cec5SDimitry Andric   const APFloat &getComplexFloatImag() const {
4820b57cec5SDimitry Andric     return const_cast<APValue*>(this)->getComplexFloatImag();
4830b57cec5SDimitry Andric   }
4840b57cec5SDimitry Andric 
4850b57cec5SDimitry Andric   const LValueBase getLValueBase() const;
4860b57cec5SDimitry Andric   CharUnits &getLValueOffset();
4870b57cec5SDimitry Andric   const CharUnits &getLValueOffset() const {
4880b57cec5SDimitry Andric     return const_cast<APValue*>(this)->getLValueOffset();
4890b57cec5SDimitry Andric   }
4900b57cec5SDimitry Andric   bool isLValueOnePastTheEnd() const;
4910b57cec5SDimitry Andric   bool hasLValuePath() const;
4920b57cec5SDimitry Andric   ArrayRef<LValuePathEntry> getLValuePath() const;
4930b57cec5SDimitry Andric   unsigned getLValueCallIndex() const;
4940b57cec5SDimitry Andric   unsigned getLValueVersion() const;
4950b57cec5SDimitry Andric   bool isNullPointer() const;
4960b57cec5SDimitry Andric 
4970b57cec5SDimitry Andric   APValue &getVectorElt(unsigned I) {
4980b57cec5SDimitry Andric     assert(isVector() && "Invalid accessor");
4990b57cec5SDimitry Andric     assert(I < getVectorLength() && "Index out of range");
500e8d8bef9SDimitry Andric     return ((Vec *)(char *)&Data)->Elts[I];
5010b57cec5SDimitry Andric   }
5020b57cec5SDimitry Andric   const APValue &getVectorElt(unsigned I) const {
5030b57cec5SDimitry Andric     return const_cast<APValue*>(this)->getVectorElt(I);
5040b57cec5SDimitry Andric   }
5050b57cec5SDimitry Andric   unsigned getVectorLength() const {
5060b57cec5SDimitry Andric     assert(isVector() && "Invalid accessor");
507e8d8bef9SDimitry Andric     return ((const Vec *)(const void *)&Data)->NumElts;
5080b57cec5SDimitry Andric   }
5090b57cec5SDimitry Andric 
5100b57cec5SDimitry Andric   APValue &getArrayInitializedElt(unsigned I) {
5110b57cec5SDimitry Andric     assert(isArray() && "Invalid accessor");
5120b57cec5SDimitry Andric     assert(I < getArrayInitializedElts() && "Index out of range");
513e8d8bef9SDimitry Andric     return ((Arr *)(char *)&Data)->Elts[I];
5140b57cec5SDimitry Andric   }
5150b57cec5SDimitry Andric   const APValue &getArrayInitializedElt(unsigned I) const {
5160b57cec5SDimitry Andric     return const_cast<APValue*>(this)->getArrayInitializedElt(I);
5170b57cec5SDimitry Andric   }
5180b57cec5SDimitry Andric   bool hasArrayFiller() const {
5190b57cec5SDimitry Andric     return getArrayInitializedElts() != getArraySize();
5200b57cec5SDimitry Andric   }
5210b57cec5SDimitry Andric   APValue &getArrayFiller() {
5220b57cec5SDimitry Andric     assert(isArray() && "Invalid accessor");
5230b57cec5SDimitry Andric     assert(hasArrayFiller() && "No array filler");
524e8d8bef9SDimitry Andric     return ((Arr *)(char *)&Data)->Elts[getArrayInitializedElts()];
5250b57cec5SDimitry Andric   }
5260b57cec5SDimitry Andric   const APValue &getArrayFiller() const {
5270b57cec5SDimitry Andric     return const_cast<APValue*>(this)->getArrayFiller();
5280b57cec5SDimitry Andric   }
5290b57cec5SDimitry Andric   unsigned getArrayInitializedElts() const {
5300b57cec5SDimitry Andric     assert(isArray() && "Invalid accessor");
531e8d8bef9SDimitry Andric     return ((const Arr *)(const void *)&Data)->NumElts;
5320b57cec5SDimitry Andric   }
5330b57cec5SDimitry Andric   unsigned getArraySize() const {
5340b57cec5SDimitry Andric     assert(isArray() && "Invalid accessor");
535e8d8bef9SDimitry Andric     return ((const Arr *)(const void *)&Data)->ArrSize;
5360b57cec5SDimitry Andric   }
5370b57cec5SDimitry Andric 
5380b57cec5SDimitry Andric   unsigned getStructNumBases() const {
5390b57cec5SDimitry Andric     assert(isStruct() && "Invalid accessor");
540e8d8bef9SDimitry Andric     return ((const StructData *)(const char *)&Data)->NumBases;
5410b57cec5SDimitry Andric   }
5420b57cec5SDimitry Andric   unsigned getStructNumFields() const {
5430b57cec5SDimitry Andric     assert(isStruct() && "Invalid accessor");
544e8d8bef9SDimitry Andric     return ((const StructData *)(const char *)&Data)->NumFields;
5450b57cec5SDimitry Andric   }
5460b57cec5SDimitry Andric   APValue &getStructBase(unsigned i) {
5470b57cec5SDimitry Andric     assert(isStruct() && "Invalid accessor");
548e8d8bef9SDimitry Andric     assert(i < getStructNumBases() && "base class index OOB");
549e8d8bef9SDimitry Andric     return ((StructData *)(char *)&Data)->Elts[i];
5500b57cec5SDimitry Andric   }
5510b57cec5SDimitry Andric   APValue &getStructField(unsigned i) {
5520b57cec5SDimitry Andric     assert(isStruct() && "Invalid accessor");
553e8d8bef9SDimitry Andric     assert(i < getStructNumFields() && "field index OOB");
554e8d8bef9SDimitry Andric     return ((StructData *)(char *)&Data)->Elts[getStructNumBases() + i];
5550b57cec5SDimitry Andric   }
5560b57cec5SDimitry Andric   const APValue &getStructBase(unsigned i) const {
5570b57cec5SDimitry Andric     return const_cast<APValue*>(this)->getStructBase(i);
5580b57cec5SDimitry Andric   }
5590b57cec5SDimitry Andric   const APValue &getStructField(unsigned i) const {
5600b57cec5SDimitry Andric     return const_cast<APValue*>(this)->getStructField(i);
5610b57cec5SDimitry Andric   }
5620b57cec5SDimitry Andric 
5630b57cec5SDimitry Andric   const FieldDecl *getUnionField() const {
5640b57cec5SDimitry Andric     assert(isUnion() && "Invalid accessor");
565e8d8bef9SDimitry Andric     return ((const UnionData *)(const char *)&Data)->Field;
5660b57cec5SDimitry Andric   }
5670b57cec5SDimitry Andric   APValue &getUnionValue() {
5680b57cec5SDimitry Andric     assert(isUnion() && "Invalid accessor");
569e8d8bef9SDimitry Andric     return *((UnionData *)(char *)&Data)->Value;
5700b57cec5SDimitry Andric   }
5710b57cec5SDimitry Andric   const APValue &getUnionValue() const {
5720b57cec5SDimitry Andric     return const_cast<APValue*>(this)->getUnionValue();
5730b57cec5SDimitry Andric   }
5740b57cec5SDimitry Andric 
5750b57cec5SDimitry Andric   const ValueDecl *getMemberPointerDecl() const;
5760b57cec5SDimitry Andric   bool isMemberPointerToDerivedMember() const;
5770b57cec5SDimitry Andric   ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
5780b57cec5SDimitry Andric 
5790b57cec5SDimitry Andric   const AddrLabelExpr* getAddrLabelDiffLHS() const {
5800b57cec5SDimitry Andric     assert(isAddrLabelDiff() && "Invalid accessor");
581e8d8bef9SDimitry Andric     return ((const AddrLabelDiffData *)(const char *)&Data)->LHSExpr;
5820b57cec5SDimitry Andric   }
5830b57cec5SDimitry Andric   const AddrLabelExpr* getAddrLabelDiffRHS() const {
5840b57cec5SDimitry Andric     assert(isAddrLabelDiff() && "Invalid accessor");
585e8d8bef9SDimitry Andric     return ((const AddrLabelDiffData *)(const char *)&Data)->RHSExpr;
5860b57cec5SDimitry Andric   }
5870b57cec5SDimitry Andric 
5880b57cec5SDimitry Andric   void setInt(APSInt I) {
5890b57cec5SDimitry Andric     assert(isInt() && "Invalid accessor");
590e8d8bef9SDimitry Andric     *(APSInt *)(char *)&Data = std::move(I);
5910b57cec5SDimitry Andric   }
5920b57cec5SDimitry Andric   void setFloat(APFloat F) {
5930b57cec5SDimitry Andric     assert(isFloat() && "Invalid accessor");
594e8d8bef9SDimitry Andric     *(APFloat *)(char *)&Data = std::move(F);
5950b57cec5SDimitry Andric   }
5960b57cec5SDimitry Andric   void setFixedPoint(APFixedPoint FX) {
5970b57cec5SDimitry Andric     assert(isFixedPoint() && "Invalid accessor");
598e8d8bef9SDimitry Andric     *(APFixedPoint *)(char *)&Data = std::move(FX);
5990b57cec5SDimitry Andric   }
6000b57cec5SDimitry Andric   void setVector(const APValue *E, unsigned N) {
601e8d8bef9SDimitry Andric     MutableArrayRef<APValue> InternalElts = setVectorUninit(N);
6020b57cec5SDimitry Andric     for (unsigned i = 0; i != N; ++i)
603e8d8bef9SDimitry Andric       InternalElts[i] = E[i];
6040b57cec5SDimitry Andric   }
6050b57cec5SDimitry Andric   void setComplexInt(APSInt R, APSInt I) {
6060b57cec5SDimitry Andric     assert(R.getBitWidth() == I.getBitWidth() &&
6070b57cec5SDimitry Andric            "Invalid complex int (type mismatch).");
6080b57cec5SDimitry Andric     assert(isComplexInt() && "Invalid accessor");
609e8d8bef9SDimitry Andric     ((ComplexAPSInt *)(char *)&Data)->Real = std::move(R);
610e8d8bef9SDimitry Andric     ((ComplexAPSInt *)(char *)&Data)->Imag = std::move(I);
6110b57cec5SDimitry Andric   }
6120b57cec5SDimitry Andric   void setComplexFloat(APFloat R, APFloat I) {
6130b57cec5SDimitry Andric     assert(&R.getSemantics() == &I.getSemantics() &&
6140b57cec5SDimitry Andric            "Invalid complex float (type mismatch).");
6150b57cec5SDimitry Andric     assert(isComplexFloat() && "Invalid accessor");
616e8d8bef9SDimitry Andric     ((ComplexAPFloat *)(char *)&Data)->Real = std::move(R);
617e8d8bef9SDimitry Andric     ((ComplexAPFloat *)(char *)&Data)->Imag = std::move(I);
6180b57cec5SDimitry Andric   }
6190b57cec5SDimitry Andric   void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
6200b57cec5SDimitry Andric                  bool IsNullPtr);
6210b57cec5SDimitry Andric   void setLValue(LValueBase B, const CharUnits &O,
6220b57cec5SDimitry Andric                  ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
6230b57cec5SDimitry Andric                  bool IsNullPtr);
624e8d8bef9SDimitry Andric   void setUnion(const FieldDecl *Field, const APValue &Value);
6250b57cec5SDimitry Andric   void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
6260b57cec5SDimitry Andric                         const AddrLabelExpr* RHSExpr) {
627e8d8bef9SDimitry Andric     ((AddrLabelDiffData *)(char *)&Data)->LHSExpr = LHSExpr;
628e8d8bef9SDimitry Andric     ((AddrLabelDiffData *)(char *)&Data)->RHSExpr = RHSExpr;
6290b57cec5SDimitry Andric   }
6300b57cec5SDimitry Andric 
6310b57cec5SDimitry Andric private:
6320b57cec5SDimitry Andric   void DestroyDataAndMakeUninit();
6330b57cec5SDimitry Andric   void MakeInt() {
6340b57cec5SDimitry Andric     assert(isAbsent() && "Bad state change");
635e8d8bef9SDimitry Andric     new ((void *)&Data) APSInt(1);
6360b57cec5SDimitry Andric     Kind = Int;
6370b57cec5SDimitry Andric   }
6380b57cec5SDimitry Andric   void MakeFloat() {
6390b57cec5SDimitry Andric     assert(isAbsent() && "Bad state change");
640e8d8bef9SDimitry Andric     new ((void *)(char *)&Data) APFloat(0.0);
6410b57cec5SDimitry Andric     Kind = Float;
6420b57cec5SDimitry Andric   }
6430b57cec5SDimitry Andric   void MakeFixedPoint(APFixedPoint &&FX) {
6440b57cec5SDimitry Andric     assert(isAbsent() && "Bad state change");
645e8d8bef9SDimitry Andric     new ((void *)(char *)&Data) APFixedPoint(std::move(FX));
6460b57cec5SDimitry Andric     Kind = FixedPoint;
6470b57cec5SDimitry Andric   }
6480b57cec5SDimitry Andric   void MakeVector() {
6490b57cec5SDimitry Andric     assert(isAbsent() && "Bad state change");
650e8d8bef9SDimitry Andric     new ((void *)(char *)&Data) Vec();
6510b57cec5SDimitry Andric     Kind = Vector;
6520b57cec5SDimitry Andric   }
6530b57cec5SDimitry Andric   void MakeComplexInt() {
6540b57cec5SDimitry Andric     assert(isAbsent() && "Bad state change");
655e8d8bef9SDimitry Andric     new ((void *)(char *)&Data) ComplexAPSInt();
6560b57cec5SDimitry Andric     Kind = ComplexInt;
6570b57cec5SDimitry Andric   }
6580b57cec5SDimitry Andric   void MakeComplexFloat() {
6590b57cec5SDimitry Andric     assert(isAbsent() && "Bad state change");
660e8d8bef9SDimitry Andric     new ((void *)(char *)&Data) ComplexAPFloat();
6610b57cec5SDimitry Andric     Kind = ComplexFloat;
6620b57cec5SDimitry Andric   }
6630b57cec5SDimitry Andric   void MakeLValue();
6640b57cec5SDimitry Andric   void MakeArray(unsigned InitElts, unsigned Size);
6650b57cec5SDimitry Andric   void MakeStruct(unsigned B, unsigned M) {
6660b57cec5SDimitry Andric     assert(isAbsent() && "Bad state change");
667e8d8bef9SDimitry Andric     new ((void *)(char *)&Data) StructData(B, M);
6680b57cec5SDimitry Andric     Kind = Struct;
6690b57cec5SDimitry Andric   }
6700b57cec5SDimitry Andric   void MakeUnion() {
6710b57cec5SDimitry Andric     assert(isAbsent() && "Bad state change");
672e8d8bef9SDimitry Andric     new ((void *)(char *)&Data) UnionData();
6730b57cec5SDimitry Andric     Kind = Union;
6740b57cec5SDimitry Andric   }
6750b57cec5SDimitry Andric   void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
6760b57cec5SDimitry Andric                          ArrayRef<const CXXRecordDecl*> Path);
6770b57cec5SDimitry Andric   void MakeAddrLabelDiff() {
6780b57cec5SDimitry Andric     assert(isAbsent() && "Bad state change");
679e8d8bef9SDimitry Andric     new ((void *)(char *)&Data) AddrLabelDiffData();
6800b57cec5SDimitry Andric     Kind = AddrLabelDiff;
6810b57cec5SDimitry Andric   }
682e8d8bef9SDimitry Andric 
683e8d8bef9SDimitry Andric private:
684e8d8bef9SDimitry Andric   /// The following functions are used as part of initialization, during
685e8d8bef9SDimitry Andric   /// deserialization and importing. Reserve the space so that it can be
686e8d8bef9SDimitry Andric   /// filled in by those steps.
687e8d8bef9SDimitry Andric   MutableArrayRef<APValue> setVectorUninit(unsigned N) {
688e8d8bef9SDimitry Andric     assert(isVector() && "Invalid accessor");
689e8d8bef9SDimitry Andric     Vec *V = ((Vec *)(char *)&Data);
690e8d8bef9SDimitry Andric     V->Elts = new APValue[N];
691e8d8bef9SDimitry Andric     V->NumElts = N;
692e8d8bef9SDimitry Andric     return {V->Elts, V->NumElts};
693e8d8bef9SDimitry Andric   }
694e8d8bef9SDimitry Andric   MutableArrayRef<LValuePathEntry>
695e8d8bef9SDimitry Andric   setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size,
696e8d8bef9SDimitry Andric                   bool OnePastTheEnd, bool IsNullPtr);
697e8d8bef9SDimitry Andric   MutableArrayRef<const CXXRecordDecl *>
698e8d8bef9SDimitry Andric   setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember,
699e8d8bef9SDimitry Andric                          unsigned Size);
7000b57cec5SDimitry Andric };
7010b57cec5SDimitry Andric 
7020b57cec5SDimitry Andric } // end namespace clang.
7030b57cec5SDimitry Andric 
7040b57cec5SDimitry Andric namespace llvm {
7050b57cec5SDimitry Andric template<> struct DenseMapInfo<clang::APValue::LValueBase> {
7060b57cec5SDimitry Andric   static clang::APValue::LValueBase getEmptyKey();
7070b57cec5SDimitry Andric   static clang::APValue::LValueBase getTombstoneKey();
7080b57cec5SDimitry Andric   static unsigned getHashValue(const clang::APValue::LValueBase &Base);
7090b57cec5SDimitry Andric   static bool isEqual(const clang::APValue::LValueBase &LHS,
7100b57cec5SDimitry Andric                       const clang::APValue::LValueBase &RHS);
7110b57cec5SDimitry Andric };
7120b57cec5SDimitry Andric }
7130b57cec5SDimitry Andric 
7140b57cec5SDimitry Andric #endif
715