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 *Ty;
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 = nullptr;
271     unsigned NumElts = 0;
272     Vec() = default;
273     Vec(const Vec &) = delete;
274     Vec &operator=(const Vec &) = delete;
275     ~Vec() { delete[] Elts; }
276   };
277   struct Arr {
278     APValue *Elts;
279     unsigned NumElts, ArrSize;
280     Arr(unsigned NumElts, unsigned ArrSize);
281     Arr(const Arr &) = delete;
282     Arr &operator=(const Arr &) = delete;
283     ~Arr();
284   };
285   struct StructData {
286     APValue *Elts;
287     unsigned NumBases;
288     unsigned NumFields;
289     StructData(unsigned NumBases, unsigned NumFields);
290     StructData(const StructData &) = delete;
291     StructData &operator=(const StructData &) = delete;
292     ~StructData();
293   };
294   struct UnionData {
295     const FieldDecl *Field;
296     APValue *Value;
297     UnionData();
298     UnionData(const UnionData &) = delete;
299     UnionData &operator=(const UnionData &) = delete;
300     ~UnionData();
301   };
302   struct AddrLabelDiffData {
303     const AddrLabelExpr* LHSExpr;
304     const AddrLabelExpr* RHSExpr;
305   };
306   struct MemberPointerData;
307 
308   // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
309   typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
310                                       ComplexAPFloat, Vec, Arr, StructData,
311                                       UnionData, AddrLabelDiffData> DataType;
312   static const size_t DataSize = sizeof(DataType);
313 
314   DataType Data;
315 
316 public:
317   APValue() : Kind(None) {}
318   explicit APValue(APSInt I) : Kind(None) {
319     MakeInt(); setInt(std::move(I));
320   }
321   explicit APValue(APFloat F) : Kind(None) {
322     MakeFloat(); setFloat(std::move(F));
323   }
324   explicit APValue(APFixedPoint FX) : Kind(None) {
325     MakeFixedPoint(std::move(FX));
326   }
327   explicit APValue(const APValue *E, unsigned N) : Kind(None) {
328     MakeVector(); setVector(E, N);
329   }
330   APValue(APSInt R, APSInt I) : Kind(None) {
331     MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
332   }
333   APValue(APFloat R, APFloat I) : Kind(None) {
334     MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
335   }
336   APValue(const APValue &RHS);
337   APValue(APValue &&RHS);
338   APValue(LValueBase B, const CharUnits &O, NoLValuePath N,
339           bool IsNullPtr = false)
340       : Kind(None) {
341     MakeLValue(); setLValue(B, O, N, IsNullPtr);
342   }
343   APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
344           bool OnePastTheEnd, bool IsNullPtr = false)
345       : Kind(None) {
346     MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
347   }
348   APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(None) {
349     MakeArray(InitElts, Size);
350   }
351   APValue(UninitStruct, unsigned B, unsigned M) : Kind(None) {
352     MakeStruct(B, M);
353   }
354   explicit APValue(const FieldDecl *D, const APValue &V = APValue())
355       : Kind(None) {
356     MakeUnion(); setUnion(D, V);
357   }
358   APValue(const ValueDecl *Member, bool IsDerivedMember,
359           ArrayRef<const CXXRecordDecl*> Path) : Kind(None) {
360     MakeMemberPointer(Member, IsDerivedMember, Path);
361   }
362   APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
363       : Kind(None) {
364     MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
365   }
366   static APValue IndeterminateValue() {
367     APValue Result;
368     Result.Kind = Indeterminate;
369     return Result;
370   }
371 
372   APValue &operator=(const APValue &RHS);
373   APValue &operator=(APValue &&RHS);
374 
375   ~APValue() {
376     if (Kind != None && Kind != Indeterminate)
377       DestroyDataAndMakeUninit();
378   }
379 
380   /// Returns whether the object performed allocations.
381   ///
382   /// If APValues are constructed via placement new, \c needsCleanup()
383   /// indicates whether the destructor must be called in order to correctly
384   /// free all allocated memory.
385   bool needsCleanup() const;
386 
387   /// Swaps the contents of this and the given APValue.
388   void swap(APValue &RHS);
389 
390   /// profile this value. There is no guarantee that values of different
391   /// types will not produce the same profiled value, so the type should
392   /// typically also be profiled if it's not implied by the context.
393   void Profile(llvm::FoldingSetNodeID &ID) const;
394 
395   ValueKind getKind() const { return Kind; }
396 
397   bool isAbsent() const { return Kind == None; }
398   bool isIndeterminate() const { return Kind == Indeterminate; }
399   bool hasValue() const { return Kind != None && Kind != Indeterminate; }
400 
401   bool isInt() const { return Kind == Int; }
402   bool isFloat() const { return Kind == Float; }
403   bool isFixedPoint() const { return Kind == FixedPoint; }
404   bool isComplexInt() const { return Kind == ComplexInt; }
405   bool isComplexFloat() const { return Kind == ComplexFloat; }
406   bool isLValue() const { return Kind == LValue; }
407   bool isVector() const { return Kind == Vector; }
408   bool isArray() const { return Kind == Array; }
409   bool isStruct() const { return Kind == Struct; }
410   bool isUnion() const { return Kind == Union; }
411   bool isMemberPointer() const { return Kind == MemberPointer; }
412   bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
413 
414   void dump() const;
415   void dump(raw_ostream &OS, const ASTContext &Context) const;
416 
417   void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const;
418   void printPretty(raw_ostream &OS, const PrintingPolicy &Policy, QualType Ty,
419                    const ASTContext *Ctx = nullptr) const;
420 
421   std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
422 
423   APSInt &getInt() {
424     assert(isInt() && "Invalid accessor");
425     return *(APSInt *)(char *)&Data;
426   }
427   const APSInt &getInt() const {
428     return const_cast<APValue*>(this)->getInt();
429   }
430 
431   /// Try to convert this value to an integral constant. This works if it's an
432   /// integer, null pointer, or offset from a null pointer. Returns true on
433   /// success.
434   bool toIntegralConstant(APSInt &Result, QualType SrcTy,
435                           const ASTContext &Ctx) const;
436 
437   APFloat &getFloat() {
438     assert(isFloat() && "Invalid accessor");
439     return *(APFloat *)(char *)&Data;
440   }
441   const APFloat &getFloat() const {
442     return const_cast<APValue*>(this)->getFloat();
443   }
444 
445   APFixedPoint &getFixedPoint() {
446     assert(isFixedPoint() && "Invalid accessor");
447     return *(APFixedPoint *)(char *)&Data;
448   }
449   const APFixedPoint &getFixedPoint() const {
450     return const_cast<APValue *>(this)->getFixedPoint();
451   }
452 
453   APSInt &getComplexIntReal() {
454     assert(isComplexInt() && "Invalid accessor");
455     return ((ComplexAPSInt *)(char *)&Data)->Real;
456   }
457   const APSInt &getComplexIntReal() const {
458     return const_cast<APValue*>(this)->getComplexIntReal();
459   }
460 
461   APSInt &getComplexIntImag() {
462     assert(isComplexInt() && "Invalid accessor");
463     return ((ComplexAPSInt *)(char *)&Data)->Imag;
464   }
465   const APSInt &getComplexIntImag() const {
466     return const_cast<APValue*>(this)->getComplexIntImag();
467   }
468 
469   APFloat &getComplexFloatReal() {
470     assert(isComplexFloat() && "Invalid accessor");
471     return ((ComplexAPFloat *)(char *)&Data)->Real;
472   }
473   const APFloat &getComplexFloatReal() const {
474     return const_cast<APValue*>(this)->getComplexFloatReal();
475   }
476 
477   APFloat &getComplexFloatImag() {
478     assert(isComplexFloat() && "Invalid accessor");
479     return ((ComplexAPFloat *)(char *)&Data)->Imag;
480   }
481   const APFloat &getComplexFloatImag() const {
482     return const_cast<APValue*>(this)->getComplexFloatImag();
483   }
484 
485   const LValueBase getLValueBase() const;
486   CharUnits &getLValueOffset();
487   const CharUnits &getLValueOffset() const {
488     return const_cast<APValue*>(this)->getLValueOffset();
489   }
490   bool isLValueOnePastTheEnd() const;
491   bool hasLValuePath() const;
492   ArrayRef<LValuePathEntry> getLValuePath() const;
493   unsigned getLValueCallIndex() const;
494   unsigned getLValueVersion() const;
495   bool isNullPointer() const;
496 
497   APValue &getVectorElt(unsigned I) {
498     assert(isVector() && "Invalid accessor");
499     assert(I < getVectorLength() && "Index out of range");
500     return ((Vec *)(char *)&Data)->Elts[I];
501   }
502   const APValue &getVectorElt(unsigned I) const {
503     return const_cast<APValue*>(this)->getVectorElt(I);
504   }
505   unsigned getVectorLength() const {
506     assert(isVector() && "Invalid accessor");
507     return ((const Vec *)(const void *)&Data)->NumElts;
508   }
509 
510   APValue &getArrayInitializedElt(unsigned I) {
511     assert(isArray() && "Invalid accessor");
512     assert(I < getArrayInitializedElts() && "Index out of range");
513     return ((Arr *)(char *)&Data)->Elts[I];
514   }
515   const APValue &getArrayInitializedElt(unsigned I) const {
516     return const_cast<APValue*>(this)->getArrayInitializedElt(I);
517   }
518   bool hasArrayFiller() const {
519     return getArrayInitializedElts() != getArraySize();
520   }
521   APValue &getArrayFiller() {
522     assert(isArray() && "Invalid accessor");
523     assert(hasArrayFiller() && "No array filler");
524     return ((Arr *)(char *)&Data)->Elts[getArrayInitializedElts()];
525   }
526   const APValue &getArrayFiller() const {
527     return const_cast<APValue*>(this)->getArrayFiller();
528   }
529   unsigned getArrayInitializedElts() const {
530     assert(isArray() && "Invalid accessor");
531     return ((const Arr *)(const void *)&Data)->NumElts;
532   }
533   unsigned getArraySize() const {
534     assert(isArray() && "Invalid accessor");
535     return ((const Arr *)(const void *)&Data)->ArrSize;
536   }
537 
538   unsigned getStructNumBases() const {
539     assert(isStruct() && "Invalid accessor");
540     return ((const StructData *)(const char *)&Data)->NumBases;
541   }
542   unsigned getStructNumFields() const {
543     assert(isStruct() && "Invalid accessor");
544     return ((const StructData *)(const char *)&Data)->NumFields;
545   }
546   APValue &getStructBase(unsigned i) {
547     assert(isStruct() && "Invalid accessor");
548     assert(i < getStructNumBases() && "base class index OOB");
549     return ((StructData *)(char *)&Data)->Elts[i];
550   }
551   APValue &getStructField(unsigned i) {
552     assert(isStruct() && "Invalid accessor");
553     assert(i < getStructNumFields() && "field index OOB");
554     return ((StructData *)(char *)&Data)->Elts[getStructNumBases() + i];
555   }
556   const APValue &getStructBase(unsigned i) const {
557     return const_cast<APValue*>(this)->getStructBase(i);
558   }
559   const APValue &getStructField(unsigned i) const {
560     return const_cast<APValue*>(this)->getStructField(i);
561   }
562 
563   const FieldDecl *getUnionField() const {
564     assert(isUnion() && "Invalid accessor");
565     return ((const UnionData *)(const char *)&Data)->Field;
566   }
567   APValue &getUnionValue() {
568     assert(isUnion() && "Invalid accessor");
569     return *((UnionData *)(char *)&Data)->Value;
570   }
571   const APValue &getUnionValue() const {
572     return const_cast<APValue*>(this)->getUnionValue();
573   }
574 
575   const ValueDecl *getMemberPointerDecl() const;
576   bool isMemberPointerToDerivedMember() const;
577   ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
578 
579   const AddrLabelExpr* getAddrLabelDiffLHS() const {
580     assert(isAddrLabelDiff() && "Invalid accessor");
581     return ((const AddrLabelDiffData *)(const char *)&Data)->LHSExpr;
582   }
583   const AddrLabelExpr* getAddrLabelDiffRHS() const {
584     assert(isAddrLabelDiff() && "Invalid accessor");
585     return ((const AddrLabelDiffData *)(const char *)&Data)->RHSExpr;
586   }
587 
588   void setInt(APSInt I) {
589     assert(isInt() && "Invalid accessor");
590     *(APSInt *)(char *)&Data = std::move(I);
591   }
592   void setFloat(APFloat F) {
593     assert(isFloat() && "Invalid accessor");
594     *(APFloat *)(char *)&Data = std::move(F);
595   }
596   void setFixedPoint(APFixedPoint FX) {
597     assert(isFixedPoint() && "Invalid accessor");
598     *(APFixedPoint *)(char *)&Data = std::move(FX);
599   }
600   void setVector(const APValue *E, unsigned N) {
601     MutableArrayRef<APValue> InternalElts = setVectorUninit(N);
602     for (unsigned i = 0; i != N; ++i)
603       InternalElts[i] = E[i];
604   }
605   void setComplexInt(APSInt R, APSInt I) {
606     assert(R.getBitWidth() == I.getBitWidth() &&
607            "Invalid complex int (type mismatch).");
608     assert(isComplexInt() && "Invalid accessor");
609     ((ComplexAPSInt *)(char *)&Data)->Real = std::move(R);
610     ((ComplexAPSInt *)(char *)&Data)->Imag = std::move(I);
611   }
612   void setComplexFloat(APFloat R, APFloat I) {
613     assert(&R.getSemantics() == &I.getSemantics() &&
614            "Invalid complex float (type mismatch).");
615     assert(isComplexFloat() && "Invalid accessor");
616     ((ComplexAPFloat *)(char *)&Data)->Real = std::move(R);
617     ((ComplexAPFloat *)(char *)&Data)->Imag = std::move(I);
618   }
619   void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
620                  bool IsNullPtr);
621   void setLValue(LValueBase B, const CharUnits &O,
622                  ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
623                  bool IsNullPtr);
624   void setUnion(const FieldDecl *Field, const APValue &Value);
625   void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
626                         const AddrLabelExpr* RHSExpr) {
627     ((AddrLabelDiffData *)(char *)&Data)->LHSExpr = LHSExpr;
628     ((AddrLabelDiffData *)(char *)&Data)->RHSExpr = RHSExpr;
629   }
630 
631 private:
632   void DestroyDataAndMakeUninit();
633   void MakeInt() {
634     assert(isAbsent() && "Bad state change");
635     new ((void *)&Data) APSInt(1);
636     Kind = Int;
637   }
638   void MakeFloat() {
639     assert(isAbsent() && "Bad state change");
640     new ((void *)(char *)&Data) APFloat(0.0);
641     Kind = Float;
642   }
643   void MakeFixedPoint(APFixedPoint &&FX) {
644     assert(isAbsent() && "Bad state change");
645     new ((void *)(char *)&Data) APFixedPoint(std::move(FX));
646     Kind = FixedPoint;
647   }
648   void MakeVector() {
649     assert(isAbsent() && "Bad state change");
650     new ((void *)(char *)&Data) Vec();
651     Kind = Vector;
652   }
653   void MakeComplexInt() {
654     assert(isAbsent() && "Bad state change");
655     new ((void *)(char *)&Data) ComplexAPSInt();
656     Kind = ComplexInt;
657   }
658   void MakeComplexFloat() {
659     assert(isAbsent() && "Bad state change");
660     new ((void *)(char *)&Data) ComplexAPFloat();
661     Kind = ComplexFloat;
662   }
663   void MakeLValue();
664   void MakeArray(unsigned InitElts, unsigned Size);
665   void MakeStruct(unsigned B, unsigned M) {
666     assert(isAbsent() && "Bad state change");
667     new ((void *)(char *)&Data) StructData(B, M);
668     Kind = Struct;
669   }
670   void MakeUnion() {
671     assert(isAbsent() && "Bad state change");
672     new ((void *)(char *)&Data) UnionData();
673     Kind = Union;
674   }
675   void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
676                          ArrayRef<const CXXRecordDecl*> Path);
677   void MakeAddrLabelDiff() {
678     assert(isAbsent() && "Bad state change");
679     new ((void *)(char *)&Data) AddrLabelDiffData();
680     Kind = AddrLabelDiff;
681   }
682 
683 private:
684   /// The following functions are used as part of initialization, during
685   /// deserialization and importing. Reserve the space so that it can be
686   /// filled in by those steps.
687   MutableArrayRef<APValue> setVectorUninit(unsigned N) {
688     assert(isVector() && "Invalid accessor");
689     Vec *V = ((Vec *)(char *)&Data);
690     V->Elts = new APValue[N];
691     V->NumElts = N;
692     return {V->Elts, V->NumElts};
693   }
694   MutableArrayRef<LValuePathEntry>
695   setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size,
696                   bool OnePastTheEnd, bool IsNullPtr);
697   MutableArrayRef<const CXXRecordDecl *>
698   setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember,
699                          unsigned Size);
700 };
701 
702 } // end namespace clang.
703 
704 namespace llvm {
705 template<> struct DenseMapInfo<clang::APValue::LValueBase> {
706   static clang::APValue::LValueBase getEmptyKey();
707   static clang::APValue::LValueBase getTombstoneKey();
708   static unsigned getHashValue(const clang::APValue::LValueBase &Base);
709   static bool isEqual(const clang::APValue::LValueBase &LHS,
710                       const clang::APValue::LValueBase &RHS);
711 };
712 }
713 
714 #endif
715