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