Home | History | Annotate | Line # | Download | only in AST
      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/Basic/LLVM.h"
     17 #include "llvm/ADT/APFixedPoint.h"
     18 #include "llvm/ADT/APFloat.h"
     19 #include "llvm/ADT/APSInt.h"
     20 #include "llvm/ADT/FoldingSet.h"
     21 #include "llvm/ADT/PointerIntPair.h"
     22 #include "llvm/ADT/PointerUnion.h"
     23 #include "llvm/Support/AlignOf.h"
     24 
     25 namespace clang {
     26 namespace serialization {
     27 template <typename T> class BasicReaderBase;
     28 } // end namespace serialization
     29 
     30   class AddrLabelExpr;
     31   class ASTContext;
     32   class CharUnits;
     33   class CXXRecordDecl;
     34   class Decl;
     35   class DiagnosticBuilder;
     36   class Expr;
     37   class FieldDecl;
     38   struct PrintingPolicy;
     39   class Type;
     40   class ValueDecl;
     41   class QualType;
     42 
     43 /// Symbolic representation of typeid(T) for some type T.
     44 class TypeInfoLValue {
     45   const Type *T;
     46 
     47 public:
     48   TypeInfoLValue() : T() {}
     49   explicit TypeInfoLValue(const Type *T);
     50 
     51   const Type *getType() const { return T; }
     52   explicit operator bool() const { return T; }
     53 
     54   void *getOpaqueValue() { return const_cast<Type*>(T); }
     55   static TypeInfoLValue getFromOpaqueValue(void *Value) {
     56     TypeInfoLValue V;
     57     V.T = reinterpret_cast<const Type*>(Value);
     58     return V;
     59   }
     60 
     61   void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const;
     62 };
     63 
     64 /// Symbolic representation of a dynamic allocation.
     65 class DynamicAllocLValue {
     66   unsigned Index;
     67 
     68 public:
     69   DynamicAllocLValue() : Index(0) {}
     70   explicit DynamicAllocLValue(unsigned Index) : Index(Index + 1) {}
     71   unsigned getIndex() { return Index - 1; }
     72 
     73   explicit operator bool() const { return Index != 0; }
     74 
     75   void *getOpaqueValue() {
     76     return reinterpret_cast<void *>(static_cast<uintptr_t>(Index)
     77                                     << NumLowBitsAvailable);
     78   }
     79   static DynamicAllocLValue getFromOpaqueValue(void *Value) {
     80     DynamicAllocLValue V;
     81     V.Index = reinterpret_cast<uintptr_t>(Value) >> NumLowBitsAvailable;
     82     return V;
     83   }
     84 
     85   static unsigned getMaxIndex() {
     86     return (std::numeric_limits<unsigned>::max() >> NumLowBitsAvailable) - 1;
     87   }
     88 
     89   static constexpr int NumLowBitsAvailable = 3;
     90 };
     91 }
     92 
     93 namespace llvm {
     94 template<> struct PointerLikeTypeTraits<clang::TypeInfoLValue> {
     95   static void *getAsVoidPointer(clang::TypeInfoLValue V) {
     96     return V.getOpaqueValue();
     97   }
     98   static clang::TypeInfoLValue getFromVoidPointer(void *P) {
     99     return clang::TypeInfoLValue::getFromOpaqueValue(P);
    100   }
    101   // Validated by static_assert in APValue.cpp; hardcoded to avoid needing
    102   // to include Type.h.
    103   static constexpr int NumLowBitsAvailable = 3;
    104 };
    105 
    106 template<> struct PointerLikeTypeTraits<clang::DynamicAllocLValue> {
    107   static void *getAsVoidPointer(clang::DynamicAllocLValue V) {
    108     return V.getOpaqueValue();
    109   }
    110   static clang::DynamicAllocLValue getFromVoidPointer(void *P) {
    111     return clang::DynamicAllocLValue::getFromOpaqueValue(P);
    112   }
    113   static constexpr int NumLowBitsAvailable =
    114       clang::DynamicAllocLValue::NumLowBitsAvailable;
    115 };
    116 }
    117 
    118 namespace clang {
    119 /// APValue - This class implements a discriminated union of [uninitialized]
    120 /// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
    121 /// [Vector: N * APValue], [Array: N * APValue]
    122 class APValue {
    123   typedef llvm::APFixedPoint APFixedPoint;
    124   typedef llvm::APSInt APSInt;
    125   typedef llvm::APFloat APFloat;
    126 public:
    127   enum ValueKind {
    128     /// There is no such object (it's outside its lifetime).
    129     None,
    130     /// This object has an indeterminate value (C++ [basic.indet]).
    131     Indeterminate,
    132     Int,
    133     Float,
    134     FixedPoint,
    135     ComplexInt,
    136     ComplexFloat,
    137     LValue,
    138     Vector,
    139     Array,
    140     Struct,
    141     Union,
    142     MemberPointer,
    143     AddrLabelDiff
    144   };
    145 
    146   class LValueBase {
    147     typedef llvm::PointerUnion<const ValueDecl *, const Expr *, TypeInfoLValue,
    148                                DynamicAllocLValue>
    149         PtrTy;
    150 
    151   public:
    152     LValueBase() : Local{} {}
    153     LValueBase(const ValueDecl *P, unsigned I = 0, unsigned V = 0);
    154     LValueBase(const Expr *P, unsigned I = 0, unsigned V = 0);
    155     static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type);
    156     static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo);
    157 
    158     void Profile(llvm::FoldingSetNodeID &ID) const;
    159 
    160     template <class T>
    161     bool is() const { return Ptr.is<T>(); }
    162 
    163     template <class T>
    164     T get() const { return Ptr.get<T>(); }
    165 
    166     template <class T>
    167     T dyn_cast() const { return Ptr.dyn_cast<T>(); }
    168 
    169     void *getOpaqueValue() const;
    170 
    171     bool isNull() const;
    172 
    173     explicit operator bool() const;
    174 
    175     unsigned getCallIndex() const;
    176     unsigned getVersion() const;
    177     QualType getTypeInfoType() const;
    178     QualType getDynamicAllocType() const;
    179 
    180     QualType getType() const;
    181 
    182     friend bool operator==(const LValueBase &LHS, const LValueBase &RHS);
    183     friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) {
    184       return !(LHS == RHS);
    185     }
    186     friend llvm::hash_code hash_value(const LValueBase &Base);
    187     friend struct llvm::DenseMapInfo<LValueBase>;
    188 
    189   private:
    190     PtrTy Ptr;
    191     struct LocalState {
    192       unsigned CallIndex, Version;
    193     };
    194     union {
    195       LocalState Local;
    196       /// The type std::type_info, if this is a TypeInfoLValue.
    197       void *TypeInfoType;
    198       /// The QualType, if this is a DynamicAllocLValue.
    199       void *DynamicAllocType;
    200     };
    201   };
    202 
    203   /// A FieldDecl or CXXRecordDecl, along with a flag indicating whether we
    204   /// mean a virtual or non-virtual base class subobject.
    205   typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
    206 
    207   /// A non-discriminated union of a base, field, or array index.
    208   class LValuePathEntry {
    209     static_assert(sizeof(uintptr_t) <= sizeof(uint64_t),
    210                   "pointer doesn't fit in 64 bits?");
    211     uint64_t Value;
    212 
    213   public:
    214     LValuePathEntry() : Value() {}
    215     LValuePathEntry(BaseOrMemberType BaseOrMember);
    216     static LValuePathEntry ArrayIndex(uint64_t Index) {
    217       LValuePathEntry Result;
    218       Result.Value = Index;
    219       return Result;
    220     }
    221 
    222     BaseOrMemberType getAsBaseOrMember() const {
    223       return BaseOrMemberType::getFromOpaqueValue(
    224           reinterpret_cast<void *>(Value));
    225     }
    226     uint64_t getAsArrayIndex() const { return Value; }
    227 
    228     void Profile(llvm::FoldingSetNodeID &ID) const;
    229 
    230     friend bool operator==(LValuePathEntry A, LValuePathEntry B) {
    231       return A.Value == B.Value;
    232     }
    233     friend bool operator!=(LValuePathEntry A, LValuePathEntry B) {
    234       return A.Value != B.Value;
    235     }
    236     friend llvm::hash_code hash_value(LValuePathEntry A) {
    237       return llvm::hash_value(A.Value);
    238     }
    239   };
    240   class LValuePathSerializationHelper {
    241     const void *ElemTy;
    242 
    243   public:
    244     ArrayRef<LValuePathEntry> Path;
    245 
    246     LValuePathSerializationHelper(ArrayRef<LValuePathEntry>, QualType);
    247     QualType getType();
    248   };
    249   struct NoLValuePath {};
    250   struct UninitArray {};
    251   struct UninitStruct {};
    252 
    253   template <typename Impl> friend class clang::serialization::BasicReaderBase;
    254   friend class ASTImporter;
    255   friend class ASTNodeImporter;
    256 
    257 private:
    258   ValueKind Kind;
    259 
    260   struct ComplexAPSInt {
    261     APSInt Real, Imag;
    262     ComplexAPSInt() : Real(1), Imag(1) {}
    263   };
    264   struct ComplexAPFloat {
    265     APFloat Real, Imag;
    266     ComplexAPFloat() : Real(0.0), Imag(0.0) {}
    267   };
    268   struct LV;
    269   struct Vec {
    270     APValue *Elts;
    271     unsigned NumElts;
    272     Vec() : Elts(nullptr), NumElts(0) {}
    273     ~Vec() { delete[] Elts; }
    274   };
    275   struct Arr {
    276     APValue *Elts;
    277     unsigned NumElts, ArrSize;
    278     Arr(unsigned NumElts, unsigned ArrSize);
    279     ~Arr();
    280   };
    281   struct StructData {
    282     APValue *Elts;
    283     unsigned NumBases;
    284     unsigned NumFields;
    285     StructData(unsigned NumBases, unsigned NumFields);
    286     ~StructData();
    287   };
    288   struct UnionData {
    289     const FieldDecl *Field;
    290     APValue *Value;
    291     UnionData();
    292     ~UnionData();
    293   };
    294   struct AddrLabelDiffData {
    295     const AddrLabelExpr* LHSExpr;
    296     const AddrLabelExpr* RHSExpr;
    297   };
    298   struct MemberPointerData;
    299 
    300   // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
    301   typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
    302                                       ComplexAPFloat, Vec, Arr, StructData,
    303                                       UnionData, AddrLabelDiffData> DataType;
    304   static const size_t DataSize = sizeof(DataType);
    305 
    306   DataType Data;
    307 
    308 public:
    309   APValue() : Kind(None) {}
    310   explicit APValue(APSInt I) : Kind(None) {
    311     MakeInt(); setInt(std::move(I));
    312   }
    313   explicit APValue(APFloat F) : Kind(None) {
    314     MakeFloat(); setFloat(std::move(F));
    315   }
    316   explicit APValue(APFixedPoint FX) : Kind(None) {
    317     MakeFixedPoint(std::move(FX));
    318   }
    319   explicit APValue(const APValue *E, unsigned N) : Kind(None) {
    320     MakeVector(); setVector(E, N);
    321   }
    322   APValue(APSInt R, APSInt I) : Kind(None) {
    323     MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
    324   }
    325   APValue(APFloat R, APFloat I) : Kind(None) {
    326     MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
    327   }
    328   APValue(const APValue &RHS);
    329   APValue(APValue &&RHS);
    330   APValue(LValueBase B, const CharUnits &O, NoLValuePath N,
    331           bool IsNullPtr = false)
    332       : Kind(None) {
    333     MakeLValue(); setLValue(B, O, N, IsNullPtr);
    334   }
    335   APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
    336           bool OnePastTheEnd, bool IsNullPtr = false)
    337       : Kind(None) {
    338     MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
    339   }
    340   APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(None) {
    341     MakeArray(InitElts, Size);
    342   }
    343   APValue(UninitStruct, unsigned B, unsigned M) : Kind(None) {
    344     MakeStruct(B, M);
    345   }
    346   explicit APValue(const FieldDecl *D, const APValue &V = APValue())
    347       : Kind(None) {
    348     MakeUnion(); setUnion(D, V);
    349   }
    350   APValue(const ValueDecl *Member, bool IsDerivedMember,
    351           ArrayRef<const CXXRecordDecl*> Path) : Kind(None) {
    352     MakeMemberPointer(Member, IsDerivedMember, Path);
    353   }
    354   APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
    355       : Kind(None) {
    356     MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
    357   }
    358   static APValue IndeterminateValue() {
    359     APValue Result;
    360     Result.Kind = Indeterminate;
    361     return Result;
    362   }
    363 
    364   APValue &operator=(const APValue &RHS);
    365   APValue &operator=(APValue &&RHS);
    366 
    367   ~APValue() {
    368     if (Kind != None && Kind != Indeterminate)
    369       DestroyDataAndMakeUninit();
    370   }
    371 
    372   /// Returns whether the object performed allocations.
    373   ///
    374   /// If APValues are constructed via placement new, \c needsCleanup()
    375   /// indicates whether the destructor must be called in order to correctly
    376   /// free all allocated memory.
    377   bool needsCleanup() const;
    378 
    379   /// Swaps the contents of this and the given APValue.
    380   void swap(APValue &RHS);
    381 
    382   /// profile this value. There is no guarantee that values of different
    383   /// types will not produce the same profiled value, so the type should
    384   /// typically also be profiled if it's not implied by the context.
    385   void Profile(llvm::FoldingSetNodeID &ID) const;
    386 
    387   ValueKind getKind() const { return Kind; }
    388 
    389   bool isAbsent() const { return Kind == None; }
    390   bool isIndeterminate() const { return Kind == Indeterminate; }
    391   bool hasValue() const { return Kind != None && Kind != Indeterminate; }
    392 
    393   bool isInt() const { return Kind == Int; }
    394   bool isFloat() const { return Kind == Float; }
    395   bool isFixedPoint() const { return Kind == FixedPoint; }
    396   bool isComplexInt() const { return Kind == ComplexInt; }
    397   bool isComplexFloat() const { return Kind == ComplexFloat; }
    398   bool isLValue() const { return Kind == LValue; }
    399   bool isVector() const { return Kind == Vector; }
    400   bool isArray() const { return Kind == Array; }
    401   bool isStruct() const { return Kind == Struct; }
    402   bool isUnion() const { return Kind == Union; }
    403   bool isMemberPointer() const { return Kind == MemberPointer; }
    404   bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
    405 
    406   void dump() const;
    407   void dump(raw_ostream &OS, const ASTContext &Context) const;
    408 
    409   void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const;
    410   void printPretty(raw_ostream &OS, const PrintingPolicy &Policy, QualType Ty,
    411                    const ASTContext *Ctx = nullptr) const;
    412 
    413   std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
    414 
    415   APSInt &getInt() {
    416     assert(isInt() && "Invalid accessor");
    417     return *(APSInt *)(char *)&Data;
    418   }
    419   const APSInt &getInt() const {
    420     return const_cast<APValue*>(this)->getInt();
    421   }
    422 
    423   /// Try to convert this value to an integral constant. This works if it's an
    424   /// integer, null pointer, or offset from a null pointer. Returns true on
    425   /// success.
    426   bool toIntegralConstant(APSInt &Result, QualType SrcTy,
    427                           const ASTContext &Ctx) const;
    428 
    429   APFloat &getFloat() {
    430     assert(isFloat() && "Invalid accessor");
    431     return *(APFloat *)(char *)&Data;
    432   }
    433   const APFloat &getFloat() const {
    434     return const_cast<APValue*>(this)->getFloat();
    435   }
    436 
    437   APFixedPoint &getFixedPoint() {
    438     assert(isFixedPoint() && "Invalid accessor");
    439     return *(APFixedPoint *)(char *)&Data;
    440   }
    441   const APFixedPoint &getFixedPoint() const {
    442     return const_cast<APValue *>(this)->getFixedPoint();
    443   }
    444 
    445   APSInt &getComplexIntReal() {
    446     assert(isComplexInt() && "Invalid accessor");
    447     return ((ComplexAPSInt *)(char *)&Data)->Real;
    448   }
    449   const APSInt &getComplexIntReal() const {
    450     return const_cast<APValue*>(this)->getComplexIntReal();
    451   }
    452 
    453   APSInt &getComplexIntImag() {
    454     assert(isComplexInt() && "Invalid accessor");
    455     return ((ComplexAPSInt *)(char *)&Data)->Imag;
    456   }
    457   const APSInt &getComplexIntImag() const {
    458     return const_cast<APValue*>(this)->getComplexIntImag();
    459   }
    460 
    461   APFloat &getComplexFloatReal() {
    462     assert(isComplexFloat() && "Invalid accessor");
    463     return ((ComplexAPFloat *)(char *)&Data)->Real;
    464   }
    465   const APFloat &getComplexFloatReal() const {
    466     return const_cast<APValue*>(this)->getComplexFloatReal();
    467   }
    468 
    469   APFloat &getComplexFloatImag() {
    470     assert(isComplexFloat() && "Invalid accessor");
    471     return ((ComplexAPFloat *)(char *)&Data)->Imag;
    472   }
    473   const APFloat &getComplexFloatImag() const {
    474     return const_cast<APValue*>(this)->getComplexFloatImag();
    475   }
    476 
    477   const LValueBase getLValueBase() const;
    478   CharUnits &getLValueOffset();
    479   const CharUnits &getLValueOffset() const {
    480     return const_cast<APValue*>(this)->getLValueOffset();
    481   }
    482   bool isLValueOnePastTheEnd() const;
    483   bool hasLValuePath() const;
    484   ArrayRef<LValuePathEntry> getLValuePath() const;
    485   unsigned getLValueCallIndex() const;
    486   unsigned getLValueVersion() const;
    487   bool isNullPointer() const;
    488 
    489   APValue &getVectorElt(unsigned I) {
    490     assert(isVector() && "Invalid accessor");
    491     assert(I < getVectorLength() && "Index out of range");
    492     return ((Vec *)(char *)&Data)->Elts[I];
    493   }
    494   const APValue &getVectorElt(unsigned I) const {
    495     return const_cast<APValue*>(this)->getVectorElt(I);
    496   }
    497   unsigned getVectorLength() const {
    498     assert(isVector() && "Invalid accessor");
    499     return ((const Vec *)(const void *)&Data)->NumElts;
    500   }
    501 
    502   APValue &getArrayInitializedElt(unsigned I) {
    503     assert(isArray() && "Invalid accessor");
    504     assert(I < getArrayInitializedElts() && "Index out of range");
    505     return ((Arr *)(char *)&Data)->Elts[I];
    506   }
    507   const APValue &getArrayInitializedElt(unsigned I) const {
    508     return const_cast<APValue*>(this)->getArrayInitializedElt(I);
    509   }
    510   bool hasArrayFiller() const {
    511     return getArrayInitializedElts() != getArraySize();
    512   }
    513   APValue &getArrayFiller() {
    514     assert(isArray() && "Invalid accessor");
    515     assert(hasArrayFiller() && "No array filler");
    516     return ((Arr *)(char *)&Data)->Elts[getArrayInitializedElts()];
    517   }
    518   const APValue &getArrayFiller() const {
    519     return const_cast<APValue*>(this)->getArrayFiller();
    520   }
    521   unsigned getArrayInitializedElts() const {
    522     assert(isArray() && "Invalid accessor");
    523     return ((const Arr *)(const void *)&Data)->NumElts;
    524   }
    525   unsigned getArraySize() const {
    526     assert(isArray() && "Invalid accessor");
    527     return ((const Arr *)(const void *)&Data)->ArrSize;
    528   }
    529 
    530   unsigned getStructNumBases() const {
    531     assert(isStruct() && "Invalid accessor");
    532     return ((const StructData *)(const char *)&Data)->NumBases;
    533   }
    534   unsigned getStructNumFields() const {
    535     assert(isStruct() && "Invalid accessor");
    536     return ((const StructData *)(const char *)&Data)->NumFields;
    537   }
    538   APValue &getStructBase(unsigned i) {
    539     assert(isStruct() && "Invalid accessor");
    540     assert(i < getStructNumBases() && "base class index OOB");
    541     return ((StructData *)(char *)&Data)->Elts[i];
    542   }
    543   APValue &getStructField(unsigned i) {
    544     assert(isStruct() && "Invalid accessor");
    545     assert(i < getStructNumFields() && "field index OOB");
    546     return ((StructData *)(char *)&Data)->Elts[getStructNumBases() + i];
    547   }
    548   const APValue &getStructBase(unsigned i) const {
    549     return const_cast<APValue*>(this)->getStructBase(i);
    550   }
    551   const APValue &getStructField(unsigned i) const {
    552     return const_cast<APValue*>(this)->getStructField(i);
    553   }
    554 
    555   const FieldDecl *getUnionField() const {
    556     assert(isUnion() && "Invalid accessor");
    557     return ((const UnionData *)(const char *)&Data)->Field;
    558   }
    559   APValue &getUnionValue() {
    560     assert(isUnion() && "Invalid accessor");
    561     return *((UnionData *)(char *)&Data)->Value;
    562   }
    563   const APValue &getUnionValue() const {
    564     return const_cast<APValue*>(this)->getUnionValue();
    565   }
    566 
    567   const ValueDecl *getMemberPointerDecl() const;
    568   bool isMemberPointerToDerivedMember() const;
    569   ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
    570 
    571   const AddrLabelExpr* getAddrLabelDiffLHS() const {
    572     assert(isAddrLabelDiff() && "Invalid accessor");
    573     return ((const AddrLabelDiffData *)(const char *)&Data)->LHSExpr;
    574   }
    575   const AddrLabelExpr* getAddrLabelDiffRHS() const {
    576     assert(isAddrLabelDiff() && "Invalid accessor");
    577     return ((const AddrLabelDiffData *)(const char *)&Data)->RHSExpr;
    578   }
    579 
    580   void setInt(APSInt I) {
    581     assert(isInt() && "Invalid accessor");
    582     *(APSInt *)(char *)&Data = std::move(I);
    583   }
    584   void setFloat(APFloat F) {
    585     assert(isFloat() && "Invalid accessor");
    586     *(APFloat *)(char *)&Data = std::move(F);
    587   }
    588   void setFixedPoint(APFixedPoint FX) {
    589     assert(isFixedPoint() && "Invalid accessor");
    590     *(APFixedPoint *)(char *)&Data = std::move(FX);
    591   }
    592   void setVector(const APValue *E, unsigned N) {
    593     MutableArrayRef<APValue> InternalElts = setVectorUninit(N);
    594     for (unsigned i = 0; i != N; ++i)
    595       InternalElts[i] = E[i];
    596   }
    597   void setComplexInt(APSInt R, APSInt I) {
    598     assert(R.getBitWidth() == I.getBitWidth() &&
    599            "Invalid complex int (type mismatch).");
    600     assert(isComplexInt() && "Invalid accessor");
    601     ((ComplexAPSInt *)(char *)&Data)->Real = std::move(R);
    602     ((ComplexAPSInt *)(char *)&Data)->Imag = std::move(I);
    603   }
    604   void setComplexFloat(APFloat R, APFloat I) {
    605     assert(&R.getSemantics() == &I.getSemantics() &&
    606            "Invalid complex float (type mismatch).");
    607     assert(isComplexFloat() && "Invalid accessor");
    608     ((ComplexAPFloat *)(char *)&Data)->Real = std::move(R);
    609     ((ComplexAPFloat *)(char *)&Data)->Imag = std::move(I);
    610   }
    611   void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
    612                  bool IsNullPtr);
    613   void setLValue(LValueBase B, const CharUnits &O,
    614                  ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
    615                  bool IsNullPtr);
    616   void setUnion(const FieldDecl *Field, const APValue &Value);
    617   void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
    618                         const AddrLabelExpr* RHSExpr) {
    619     ((AddrLabelDiffData *)(char *)&Data)->LHSExpr = LHSExpr;
    620     ((AddrLabelDiffData *)(char *)&Data)->RHSExpr = RHSExpr;
    621   }
    622 
    623 private:
    624   void DestroyDataAndMakeUninit();
    625   void MakeInt() {
    626     assert(isAbsent() && "Bad state change");
    627     new ((void *)&Data) APSInt(1);
    628     Kind = Int;
    629   }
    630   void MakeFloat() {
    631     assert(isAbsent() && "Bad state change");
    632     new ((void *)(char *)&Data) APFloat(0.0);
    633     Kind = Float;
    634   }
    635   void MakeFixedPoint(APFixedPoint &&FX) {
    636     assert(isAbsent() && "Bad state change");
    637     new ((void *)(char *)&Data) APFixedPoint(std::move(FX));
    638     Kind = FixedPoint;
    639   }
    640   void MakeVector() {
    641     assert(isAbsent() && "Bad state change");
    642     new ((void *)(char *)&Data) Vec();
    643     Kind = Vector;
    644   }
    645   void MakeComplexInt() {
    646     assert(isAbsent() && "Bad state change");
    647     new ((void *)(char *)&Data) ComplexAPSInt();
    648     Kind = ComplexInt;
    649   }
    650   void MakeComplexFloat() {
    651     assert(isAbsent() && "Bad state change");
    652     new ((void *)(char *)&Data) ComplexAPFloat();
    653     Kind = ComplexFloat;
    654   }
    655   void MakeLValue();
    656   void MakeArray(unsigned InitElts, unsigned Size);
    657   void MakeStruct(unsigned B, unsigned M) {
    658     assert(isAbsent() && "Bad state change");
    659     new ((void *)(char *)&Data) StructData(B, M);
    660     Kind = Struct;
    661   }
    662   void MakeUnion() {
    663     assert(isAbsent() && "Bad state change");
    664     new ((void *)(char *)&Data) UnionData();
    665     Kind = Union;
    666   }
    667   void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
    668                          ArrayRef<const CXXRecordDecl*> Path);
    669   void MakeAddrLabelDiff() {
    670     assert(isAbsent() && "Bad state change");
    671     new ((void *)(char *)&Data) AddrLabelDiffData();
    672     Kind = AddrLabelDiff;
    673   }
    674 
    675 private:
    676   /// The following functions are used as part of initialization, during
    677   /// deserialization and importing. Reserve the space so that it can be
    678   /// filled in by those steps.
    679   MutableArrayRef<APValue> setVectorUninit(unsigned N) {
    680     assert(isVector() && "Invalid accessor");
    681     Vec *V = ((Vec *)(char *)&Data);
    682     V->Elts = new APValue[N];
    683     V->NumElts = N;
    684     return {V->Elts, V->NumElts};
    685   }
    686   MutableArrayRef<LValuePathEntry>
    687   setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size,
    688                   bool OnePastTheEnd, bool IsNullPtr);
    689   MutableArrayRef<const CXXRecordDecl *>
    690   setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember,
    691                          unsigned Size);
    692 };
    693 
    694 } // end namespace clang.
    695 
    696 namespace llvm {
    697 template<> struct DenseMapInfo<clang::APValue::LValueBase> {
    698   static clang::APValue::LValueBase getEmptyKey();
    699   static clang::APValue::LValueBase getTombstoneKey();
    700   static unsigned getHashValue(const clang::APValue::LValueBase &Base);
    701   static bool isEqual(const clang::APValue::LValueBase &LHS,
    702                       const clang::APValue::LValueBase &RHS);
    703 };
    704 }
    705 
    706 #endif
    707