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