xref: /llvm-project/clang/include/clang/AST/APValue.h (revision 563c7c5539f05e7f8cbb42565c1f24466019f38b)
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> bool is() const { return isa<T>(Ptr); }
161 
162     template <class T> T get() const { return cast<T>(Ptr); }
163 
164     template <class T> T dyn_cast() const {
165       return dyn_cast_if_present<T>(Ptr);
166     }
167 
168     void *getOpaqueValue() const;
169 
170     bool isNull() const;
171 
172     explicit operator bool() const;
173 
174     unsigned getCallIndex() const;
175     unsigned getVersion() const;
176     QualType getTypeInfoType() const;
177     QualType getDynamicAllocType() const;
178 
179     QualType getType() const;
180 
181     friend bool operator==(const LValueBase &LHS, const LValueBase &RHS);
182     friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) {
183       return !(LHS == RHS);
184     }
185     friend llvm::hash_code hash_value(const LValueBase &Base);
186     friend struct llvm::DenseMapInfo<LValueBase>;
187 
188   private:
189     PtrTy Ptr;
190     struct LocalState {
191       unsigned CallIndex, Version;
192     };
193     union {
194       LocalState Local;
195       /// The type std::type_info, if this is a TypeInfoLValue.
196       void *TypeInfoType;
197       /// The QualType, if this is a DynamicAllocLValue.
198       void *DynamicAllocType;
199     };
200   };
201 
202   /// A FieldDecl or CXXRecordDecl, along with a flag indicating whether we
203   /// mean a virtual or non-virtual base class subobject.
204   typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
205 
206   /// A non-discriminated union of a base, field, or array index.
207   class LValuePathEntry {
208     static_assert(sizeof(uintptr_t) <= sizeof(uint64_t),
209                   "pointer doesn't fit in 64 bits?");
210     uint64_t Value;
211 
212   public:
213     LValuePathEntry() : Value() {}
214     LValuePathEntry(BaseOrMemberType BaseOrMember);
215     static LValuePathEntry ArrayIndex(uint64_t Index) {
216       LValuePathEntry Result;
217       Result.Value = Index;
218       return Result;
219     }
220 
221     BaseOrMemberType getAsBaseOrMember() const {
222       return BaseOrMemberType::getFromOpaqueValue(
223           reinterpret_cast<void *>(Value));
224     }
225     uint64_t getAsArrayIndex() const { return Value; }
226 
227     void Profile(llvm::FoldingSetNodeID &ID) const;
228 
229     friend bool operator==(LValuePathEntry A, LValuePathEntry B) {
230       return A.Value == B.Value;
231     }
232     friend bool operator!=(LValuePathEntry A, LValuePathEntry B) {
233       return A.Value != B.Value;
234     }
235     friend llvm::hash_code hash_value(LValuePathEntry A) {
236       return llvm::hash_value(A.Value);
237     }
238   };
239   class LValuePathSerializationHelper {
240     const void *Ty;
241 
242   public:
243     ArrayRef<LValuePathEntry> Path;
244 
245     LValuePathSerializationHelper(ArrayRef<LValuePathEntry>, QualType);
246     QualType getType();
247   };
248   struct NoLValuePath {};
249   struct UninitArray {};
250   struct UninitStruct {};
251   struct ConstexprUnknown {};
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   bool AllowConstexprUnknown : 1;
260 
261   struct ComplexAPSInt {
262     APSInt Real, Imag;
263     ComplexAPSInt() : Real(1), Imag(1) {}
264   };
265   struct ComplexAPFloat {
266     APFloat Real, Imag;
267     ComplexAPFloat() : Real(0.0), Imag(0.0) {}
268   };
269   struct LV;
270   struct Vec {
271     APValue *Elts = nullptr;
272     unsigned NumElts = 0;
273     Vec() = default;
274     Vec(const Vec &) = delete;
275     Vec &operator=(const Vec &) = delete;
276     ~Vec() { delete[] Elts; }
277   };
278   struct Arr {
279     APValue *Elts;
280     unsigned NumElts, ArrSize;
281     Arr(unsigned NumElts, unsigned ArrSize);
282     Arr(const Arr &) = delete;
283     Arr &operator=(const Arr &) = delete;
284     ~Arr();
285   };
286   struct StructData {
287     APValue *Elts;
288     unsigned NumBases;
289     unsigned NumFields;
290     StructData(unsigned NumBases, unsigned NumFields);
291     StructData(const StructData &) = delete;
292     StructData &operator=(const StructData &) = delete;
293     ~StructData();
294   };
295   struct UnionData {
296     const FieldDecl *Field;
297     APValue *Value;
298     UnionData();
299     UnionData(const UnionData &) = delete;
300     UnionData &operator=(const UnionData &) = delete;
301     ~UnionData();
302   };
303   struct AddrLabelDiffData {
304     const AddrLabelExpr* LHSExpr;
305     const AddrLabelExpr* RHSExpr;
306   };
307   struct MemberPointerData;
308 
309   // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
310   typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
311                                       ComplexAPFloat, Vec, Arr, StructData,
312                                       UnionData, AddrLabelDiffData> DataType;
313   static const size_t DataSize = sizeof(DataType);
314 
315   DataType Data;
316 
317 public:
318   bool allowConstexprUnknown() const { return AllowConstexprUnknown; }
319 
320   void setConstexprUnknown(bool IsConstexprUnknown = true) {
321     AllowConstexprUnknown = IsConstexprUnknown;
322   }
323 
324   /// Creates an empty APValue of type None.
325   APValue() : Kind(None), AllowConstexprUnknown(false) {}
326   /// Creates an integer APValue holding the given value.
327   explicit APValue(APSInt I) : Kind(None), AllowConstexprUnknown(false) {
328     MakeInt(); setInt(std::move(I));
329   }
330   /// Creates a float APValue holding the given value.
331   explicit APValue(APFloat F) : Kind(None), AllowConstexprUnknown(false) {
332     MakeFloat(); setFloat(std::move(F));
333   }
334   /// Creates a fixed-point APValue holding the given value.
335   explicit APValue(APFixedPoint FX) : Kind(None), AllowConstexprUnknown(false) {
336     MakeFixedPoint(std::move(FX));
337   }
338   /// Creates a vector APValue with \p N elements. The elements
339   /// are read from \p E.
340   explicit APValue(const APValue *E, unsigned N)
341       : Kind(None), AllowConstexprUnknown(false) {
342     MakeVector(); setVector(E, N);
343   }
344   /// Creates an integer complex APValue with the given real and imaginary
345   /// values.
346   APValue(APSInt R, APSInt I) : Kind(None), AllowConstexprUnknown(false) {
347     MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
348   }
349   /// Creates a float complex APValue with the given real and imaginary values.
350   APValue(APFloat R, APFloat I) : Kind(None), AllowConstexprUnknown(false) {
351     MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
352   }
353   APValue(const APValue &RHS);
354   APValue(APValue &&RHS);
355   /// Creates an lvalue APValue without an lvalue path.
356   /// \param Base The base of the lvalue.
357   /// \param Offset The offset of the lvalue.
358   /// \param IsNullPtr Whether this lvalue is a null pointer.
359   APValue(LValueBase Base, const CharUnits &Offset, NoLValuePath,
360           bool IsNullPtr = false)
361       : Kind(None), AllowConstexprUnknown(false) {
362     MakeLValue();
363     setLValue(Base, Offset, NoLValuePath{}, IsNullPtr);
364   }
365   /// Creates an lvalue APValue with an lvalue path.
366   /// \param Base The base of the lvalue.
367   /// \param Offset The offset of the lvalue.
368   /// \param Path The lvalue path.
369   /// \param OnePastTheEnd Whether this lvalue is one-past-the-end of the
370   /// subobject it points to.
371   /// \param IsNullPtr Whether this lvalue is a null pointer.
372   APValue(LValueBase Base, const CharUnits &Offset,
373           ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
374           bool IsNullPtr = false)
375       : Kind(None), AllowConstexprUnknown(false) {
376     MakeLValue();
377     setLValue(Base, Offset, Path, OnePastTheEnd, IsNullPtr);
378   }
379   /// Creates a constexpr unknown lvalue APValue.
380   /// \param Base The base of the lvalue.
381   /// \param Offset The offset of the lvalue.
382   /// \param IsNullPtr Whether this lvalue is a null pointer.
383   APValue(LValueBase Base, const CharUnits &Offset, ConstexprUnknown,
384           bool IsNullPtr = false)
385       : Kind(None), AllowConstexprUnknown(true) {
386     MakeLValue();
387     setLValue(Base, Offset, NoLValuePath{}, IsNullPtr);
388   }
389 
390   /// Creates a new array APValue.
391   /// \param UninitArray Marker. Pass an empty UninitArray.
392   /// \param InitElts Number of elements you're going to initialize in the
393   /// array.
394   /// \param Size Full size of the array.
395   APValue(UninitArray, unsigned InitElts, unsigned Size)
396       : Kind(None), AllowConstexprUnknown(false) {
397     MakeArray(InitElts, Size);
398   }
399   /// Creates a new struct APValue.
400   /// \param UninitStruct Marker. Pass an empty UninitStruct.
401   /// \param NumBases Number of bases.
402   /// \param NumMembers Number of members.
403   APValue(UninitStruct, unsigned NumBases, unsigned NumMembers)
404       : Kind(None), AllowConstexprUnknown(false) {
405     MakeStruct(NumBases, NumMembers);
406   }
407   /// Creates a new union APValue.
408   /// \param ActiveDecl The FieldDecl of the active union member.
409   /// \param ActiveValue The value of the active union member.
410   explicit APValue(const FieldDecl *ActiveDecl,
411                    const APValue &ActiveValue = APValue())
412       : Kind(None), AllowConstexprUnknown(false) {
413     MakeUnion();
414     setUnion(ActiveDecl, ActiveValue);
415   }
416   /// Creates a new member pointer APValue.
417   /// \param Member Declaration of the member
418   /// \param IsDerivedMember Whether member is a derived one.
419   /// \param Path The path of the member.
420   APValue(const ValueDecl *Member, bool IsDerivedMember,
421           ArrayRef<const CXXRecordDecl *> Path)
422       : Kind(None), AllowConstexprUnknown(false) {
423     MakeMemberPointer(Member, IsDerivedMember, Path);
424   }
425   /// Creates a new address label diff APValue.
426   /// \param LHSExpr The left-hand side of the difference.
427   /// \param RHSExpr The right-hand side of the difference.
428   APValue(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
429       : Kind(None), AllowConstexprUnknown(false) {
430     MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
431   }
432   static APValue IndeterminateValue() {
433     APValue Result;
434     Result.Kind = Indeterminate;
435     return Result;
436   }
437 
438   APValue &operator=(const APValue &RHS);
439   APValue &operator=(APValue &&RHS);
440 
441   ~APValue() {
442     if (Kind != None && Kind != Indeterminate)
443       DestroyDataAndMakeUninit();
444   }
445 
446   /// Returns whether the object performed allocations.
447   ///
448   /// If APValues are constructed via placement new, \c needsCleanup()
449   /// indicates whether the destructor must be called in order to correctly
450   /// free all allocated memory.
451   bool needsCleanup() const;
452 
453   /// Swaps the contents of this and the given APValue.
454   void swap(APValue &RHS);
455 
456   /// profile this value. There is no guarantee that values of different
457   /// types will not produce the same profiled value, so the type should
458   /// typically also be profiled if it's not implied by the context.
459   void Profile(llvm::FoldingSetNodeID &ID) const;
460 
461   ValueKind getKind() const { return Kind; }
462 
463   bool isAbsent() const { return Kind == None; }
464   bool isIndeterminate() const { return Kind == Indeterminate; }
465   bool hasValue() const { return Kind != None && Kind != Indeterminate; }
466 
467   bool isInt() const { return Kind == Int; }
468   bool isFloat() const { return Kind == Float; }
469   bool isFixedPoint() const { return Kind == FixedPoint; }
470   bool isComplexInt() const { return Kind == ComplexInt; }
471   bool isComplexFloat() const { return Kind == ComplexFloat; }
472   bool isLValue() const { return Kind == LValue; }
473   bool isVector() const { return Kind == Vector; }
474   bool isArray() const { return Kind == Array; }
475   bool isStruct() const { return Kind == Struct; }
476   bool isUnion() const { return Kind == Union; }
477   bool isMemberPointer() const { return Kind == MemberPointer; }
478   bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
479 
480   void dump() const;
481   void dump(raw_ostream &OS, const ASTContext &Context) const;
482 
483   void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const;
484   void printPretty(raw_ostream &OS, const PrintingPolicy &Policy, QualType Ty,
485                    const ASTContext *Ctx = nullptr) const;
486 
487   std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
488 
489   APSInt &getInt() {
490     assert(isInt() && "Invalid accessor");
491     return *(APSInt *)(char *)&Data;
492   }
493   const APSInt &getInt() const {
494     return const_cast<APValue*>(this)->getInt();
495   }
496 
497   /// Try to convert this value to an integral constant. This works if it's an
498   /// integer, null pointer, or offset from a null pointer. Returns true on
499   /// success.
500   bool toIntegralConstant(APSInt &Result, QualType SrcTy,
501                           const ASTContext &Ctx) const;
502 
503   APFloat &getFloat() {
504     assert(isFloat() && "Invalid accessor");
505     return *(APFloat *)(char *)&Data;
506   }
507   const APFloat &getFloat() const {
508     return const_cast<APValue*>(this)->getFloat();
509   }
510 
511   APFixedPoint &getFixedPoint() {
512     assert(isFixedPoint() && "Invalid accessor");
513     return *(APFixedPoint *)(char *)&Data;
514   }
515   const APFixedPoint &getFixedPoint() const {
516     return const_cast<APValue *>(this)->getFixedPoint();
517   }
518 
519   APSInt &getComplexIntReal() {
520     assert(isComplexInt() && "Invalid accessor");
521     return ((ComplexAPSInt *)(char *)&Data)->Real;
522   }
523   const APSInt &getComplexIntReal() const {
524     return const_cast<APValue*>(this)->getComplexIntReal();
525   }
526 
527   APSInt &getComplexIntImag() {
528     assert(isComplexInt() && "Invalid accessor");
529     return ((ComplexAPSInt *)(char *)&Data)->Imag;
530   }
531   const APSInt &getComplexIntImag() const {
532     return const_cast<APValue*>(this)->getComplexIntImag();
533   }
534 
535   APFloat &getComplexFloatReal() {
536     assert(isComplexFloat() && "Invalid accessor");
537     return ((ComplexAPFloat *)(char *)&Data)->Real;
538   }
539   const APFloat &getComplexFloatReal() const {
540     return const_cast<APValue*>(this)->getComplexFloatReal();
541   }
542 
543   APFloat &getComplexFloatImag() {
544     assert(isComplexFloat() && "Invalid accessor");
545     return ((ComplexAPFloat *)(char *)&Data)->Imag;
546   }
547   const APFloat &getComplexFloatImag() const {
548     return const_cast<APValue*>(this)->getComplexFloatImag();
549   }
550 
551   const LValueBase getLValueBase() const;
552   CharUnits &getLValueOffset();
553   const CharUnits &getLValueOffset() const {
554     return const_cast<APValue*>(this)->getLValueOffset();
555   }
556   bool isLValueOnePastTheEnd() const;
557   bool hasLValuePath() const;
558   ArrayRef<LValuePathEntry> getLValuePath() const;
559   unsigned getLValueCallIndex() const;
560   unsigned getLValueVersion() const;
561   bool isNullPointer() const;
562 
563   APValue &getVectorElt(unsigned I) {
564     assert(isVector() && "Invalid accessor");
565     assert(I < getVectorLength() && "Index out of range");
566     return ((Vec *)(char *)&Data)->Elts[I];
567   }
568   const APValue &getVectorElt(unsigned I) const {
569     return const_cast<APValue*>(this)->getVectorElt(I);
570   }
571   unsigned getVectorLength() const {
572     assert(isVector() && "Invalid accessor");
573     return ((const Vec *)(const void *)&Data)->NumElts;
574   }
575 
576   APValue &getArrayInitializedElt(unsigned I) {
577     assert(isArray() && "Invalid accessor");
578     assert(I < getArrayInitializedElts() && "Index out of range");
579     return ((Arr *)(char *)&Data)->Elts[I];
580   }
581   const APValue &getArrayInitializedElt(unsigned I) const {
582     return const_cast<APValue*>(this)->getArrayInitializedElt(I);
583   }
584   bool hasArrayFiller() const {
585     return getArrayInitializedElts() != getArraySize();
586   }
587   APValue &getArrayFiller() {
588     assert(isArray() && "Invalid accessor");
589     assert(hasArrayFiller() && "No array filler");
590     return ((Arr *)(char *)&Data)->Elts[getArrayInitializedElts()];
591   }
592   const APValue &getArrayFiller() const {
593     return const_cast<APValue*>(this)->getArrayFiller();
594   }
595   unsigned getArrayInitializedElts() const {
596     assert(isArray() && "Invalid accessor");
597     return ((const Arr *)(const void *)&Data)->NumElts;
598   }
599   unsigned getArraySize() const {
600     assert(isArray() && "Invalid accessor");
601     return ((const Arr *)(const void *)&Data)->ArrSize;
602   }
603 
604   unsigned getStructNumBases() const {
605     assert(isStruct() && "Invalid accessor");
606     return ((const StructData *)(const char *)&Data)->NumBases;
607   }
608   unsigned getStructNumFields() const {
609     assert(isStruct() && "Invalid accessor");
610     return ((const StructData *)(const char *)&Data)->NumFields;
611   }
612   APValue &getStructBase(unsigned i) {
613     assert(isStruct() && "Invalid accessor");
614     assert(i < getStructNumBases() && "base class index OOB");
615     return ((StructData *)(char *)&Data)->Elts[i];
616   }
617   APValue &getStructField(unsigned i) {
618     assert(isStruct() && "Invalid accessor");
619     assert(i < getStructNumFields() && "field index OOB");
620     return ((StructData *)(char *)&Data)->Elts[getStructNumBases() + i];
621   }
622   const APValue &getStructBase(unsigned i) const {
623     return const_cast<APValue*>(this)->getStructBase(i);
624   }
625   const APValue &getStructField(unsigned i) const {
626     return const_cast<APValue*>(this)->getStructField(i);
627   }
628 
629   const FieldDecl *getUnionField() const {
630     assert(isUnion() && "Invalid accessor");
631     return ((const UnionData *)(const char *)&Data)->Field;
632   }
633   APValue &getUnionValue() {
634     assert(isUnion() && "Invalid accessor");
635     return *((UnionData *)(char *)&Data)->Value;
636   }
637   const APValue &getUnionValue() const {
638     return const_cast<APValue*>(this)->getUnionValue();
639   }
640 
641   const ValueDecl *getMemberPointerDecl() const;
642   bool isMemberPointerToDerivedMember() const;
643   ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
644 
645   const AddrLabelExpr* getAddrLabelDiffLHS() const {
646     assert(isAddrLabelDiff() && "Invalid accessor");
647     return ((const AddrLabelDiffData *)(const char *)&Data)->LHSExpr;
648   }
649   const AddrLabelExpr* getAddrLabelDiffRHS() const {
650     assert(isAddrLabelDiff() && "Invalid accessor");
651     return ((const AddrLabelDiffData *)(const char *)&Data)->RHSExpr;
652   }
653 
654   void setInt(APSInt I) {
655     assert(isInt() && "Invalid accessor");
656     *(APSInt *)(char *)&Data = std::move(I);
657   }
658   void setFloat(APFloat F) {
659     assert(isFloat() && "Invalid accessor");
660     *(APFloat *)(char *)&Data = std::move(F);
661   }
662   void setFixedPoint(APFixedPoint FX) {
663     assert(isFixedPoint() && "Invalid accessor");
664     *(APFixedPoint *)(char *)&Data = std::move(FX);
665   }
666   void setVector(const APValue *E, unsigned N) {
667     MutableArrayRef<APValue> InternalElts = setVectorUninit(N);
668     for (unsigned i = 0; i != N; ++i)
669       InternalElts[i] = E[i];
670   }
671   void setComplexInt(APSInt R, APSInt I) {
672     assert(R.getBitWidth() == I.getBitWidth() &&
673            "Invalid complex int (type mismatch).");
674     assert(isComplexInt() && "Invalid accessor");
675     ((ComplexAPSInt *)(char *)&Data)->Real = std::move(R);
676     ((ComplexAPSInt *)(char *)&Data)->Imag = std::move(I);
677   }
678   void setComplexFloat(APFloat R, APFloat I) {
679     assert(&R.getSemantics() == &I.getSemantics() &&
680            "Invalid complex float (type mismatch).");
681     assert(isComplexFloat() && "Invalid accessor");
682     ((ComplexAPFloat *)(char *)&Data)->Real = std::move(R);
683     ((ComplexAPFloat *)(char *)&Data)->Imag = std::move(I);
684   }
685   void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
686                  bool IsNullPtr);
687   void setLValue(LValueBase B, const CharUnits &O,
688                  ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
689                  bool IsNullPtr);
690   void setUnion(const FieldDecl *Field, const APValue &Value);
691   void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
692                         const AddrLabelExpr* RHSExpr) {
693     ((AddrLabelDiffData *)(char *)&Data)->LHSExpr = LHSExpr;
694     ((AddrLabelDiffData *)(char *)&Data)->RHSExpr = RHSExpr;
695   }
696 
697 private:
698   void DestroyDataAndMakeUninit();
699   void MakeInt() {
700     assert(isAbsent() && "Bad state change");
701     new ((void *)&Data) APSInt(1);
702     Kind = Int;
703   }
704   void MakeFloat() {
705     assert(isAbsent() && "Bad state change");
706     new ((void *)(char *)&Data) APFloat(0.0);
707     Kind = Float;
708   }
709   void MakeFixedPoint(APFixedPoint &&FX) {
710     assert(isAbsent() && "Bad state change");
711     new ((void *)(char *)&Data) APFixedPoint(std::move(FX));
712     Kind = FixedPoint;
713   }
714   void MakeVector() {
715     assert(isAbsent() && "Bad state change");
716     new ((void *)(char *)&Data) Vec();
717     Kind = Vector;
718   }
719   void MakeComplexInt() {
720     assert(isAbsent() && "Bad state change");
721     new ((void *)(char *)&Data) ComplexAPSInt();
722     Kind = ComplexInt;
723   }
724   void MakeComplexFloat() {
725     assert(isAbsent() && "Bad state change");
726     new ((void *)(char *)&Data) ComplexAPFloat();
727     Kind = ComplexFloat;
728   }
729   void MakeLValue();
730   void MakeArray(unsigned InitElts, unsigned Size);
731   void MakeStruct(unsigned B, unsigned M) {
732     assert(isAbsent() && "Bad state change");
733     new ((void *)(char *)&Data) StructData(B, M);
734     Kind = Struct;
735   }
736   void MakeUnion() {
737     assert(isAbsent() && "Bad state change");
738     new ((void *)(char *)&Data) UnionData();
739     Kind = Union;
740   }
741   void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
742                          ArrayRef<const CXXRecordDecl*> Path);
743   void MakeAddrLabelDiff() {
744     assert(isAbsent() && "Bad state change");
745     new ((void *)(char *)&Data) AddrLabelDiffData();
746     Kind = AddrLabelDiff;
747   }
748 
749 private:
750   /// The following functions are used as part of initialization, during
751   /// deserialization and importing. Reserve the space so that it can be
752   /// filled in by those steps.
753   MutableArrayRef<APValue> setVectorUninit(unsigned N) {
754     assert(isVector() && "Invalid accessor");
755     Vec *V = ((Vec *)(char *)&Data);
756     V->Elts = new APValue[N];
757     V->NumElts = N;
758     return {V->Elts, V->NumElts};
759   }
760   MutableArrayRef<LValuePathEntry>
761   setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size,
762                   bool OnePastTheEnd, bool IsNullPtr);
763   MutableArrayRef<const CXXRecordDecl *>
764   setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember,
765                          unsigned Size);
766 };
767 
768 } // end namespace clang.
769 
770 namespace llvm {
771 template<> struct DenseMapInfo<clang::APValue::LValueBase> {
772   static clang::APValue::LValueBase getEmptyKey();
773   static clang::APValue::LValueBase getTombstoneKey();
774   static unsigned getHashValue(const clang::APValue::LValueBase &Base);
775   static bool isEqual(const clang::APValue::LValueBase &LHS,
776                       const clang::APValue::LValueBase &RHS);
777 };
778 }
779 
780 #endif
781