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
25namespace clang {
26namespace serialization {
27template <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.
44class TypeInfoLValue {
45  const Type *T;
46
47public:
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.
65class DynamicAllocLValue {
66  unsigned Index;
67
68public:
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
93namespace llvm {
94template<> 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
106template<> 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
118namespace 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]
122class APValue {
123  typedef llvm::APFixedPoint APFixedPoint;
124  typedef llvm::APSInt APSInt;
125  typedef llvm::APFloat APFloat;
126public:
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
257private:
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
316public:
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
631private:
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
683private:
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
704namespace llvm {
705template<> 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