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 
23 namespace 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.
37 class TypeInfoLValue {
38   const Type *T;
39 
40 public:
TypeInfoLValue()41   TypeInfoLValue() : T() {}
42   explicit TypeInfoLValue(const Type *T);
43 
getType()44   const Type *getType() const { return T; }
45   explicit operator bool() const { return T; }
46 
getOpaqueValue()47   void *getOpaqueValue() { return const_cast<Type*>(T); }
getFromOpaqueValue(void * Value)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.
58 class DynamicAllocLValue {
59   unsigned Index;
60 
61 public:
DynamicAllocLValue()62   DynamicAllocLValue() : Index(0) {}
DynamicAllocLValue(unsigned Index)63   explicit DynamicAllocLValue(unsigned Index) : Index(Index + 1) {}
getIndex()64   unsigned getIndex() { return Index - 1; }
65 
66   explicit operator bool() const { return Index != 0; }
67 
getOpaqueValue()68   void *getOpaqueValue() {
69     return reinterpret_cast<void *>(static_cast<uintptr_t>(Index)
70                                     << NumLowBitsAvailable);
71   }
getFromOpaqueValue(void * Value)72   static DynamicAllocLValue getFromOpaqueValue(void *Value) {
73     DynamicAllocLValue V;
74     V.Index = reinterpret_cast<uintptr_t>(Value) >> NumLowBitsAvailable;
75     return V;
76   }
77 
getMaxIndex()78   static unsigned getMaxIndex() {
79     return (std::numeric_limits<unsigned>::max() >> NumLowBitsAvailable) - 1;
80   }
81 
82   static constexpr int NumLowBitsAvailable = 3;
83 };
84 }
85 
86 namespace llvm {
87 template<> 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 
99 template<> 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 
111 namespace 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]
115 class APValue {
116   typedef llvm::APSInt APSInt;
117   typedef llvm::APFloat APFloat;
118 public:
119   enum ValueKind : uint8_t {
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 
233 private:
234   ValueKind Kind;
235   // CHERI-only: ensure that we emit an NULL-derived ap
236   bool MustBeNullDerivedCap = true;
237 
238   struct ComplexAPSInt {
239     APSInt Real, Imag;
240     ComplexAPSInt() : Real(1), Imag(1) {}
241   };
242   struct ComplexAPFloat {
243     APFloat Real, Imag;
244     ComplexAPFloat() : Real(0.0), Imag(0.0) {}
245   };
246   struct LV;
247   struct Vec {
248     APValue *Elts;
249     unsigned NumElts;
250     Vec() : Elts(nullptr), NumElts(0) {}
251     ~Vec() { delete[] Elts; }
252   };
253   struct Arr {
254     APValue *Elts;
255     unsigned NumElts, ArrSize;
256     Arr(unsigned NumElts, unsigned ArrSize);
257     ~Arr();
258   };
259   struct StructData {
260     APValue *Elts;
261     unsigned NumBases;
262     unsigned NumFields;
263     StructData(unsigned NumBases, unsigned NumFields);
264     ~StructData();
265   };
266   struct UnionData {
267     const FieldDecl *Field;
268     APValue *Value;
269     UnionData();
270     ~UnionData();
271   };
272   struct AddrLabelDiffData {
273     const AddrLabelExpr* LHSExpr;
274     const AddrLabelExpr* RHSExpr;
275   };
276   struct MemberPointerData;
277 
278   // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
279   typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
280                                       ComplexAPFloat, Vec, Arr, StructData,
281                                       UnionData, AddrLabelDiffData> DataType;
282   static const size_t DataSize = sizeof(DataType);
283 
284   DataType Data;
285 
286 public:
287   APValue() : Kind(None) {}
288   explicit APValue(APSInt I) : Kind(None) {
289     MakeInt(); setInt(std::move(I));
290   }
291   explicit APValue(APFloat F) : Kind(None) {
292     MakeFloat(); setFloat(std::move(F));
293   }
294   explicit APValue(APFixedPoint FX) : Kind(None) {
295     MakeFixedPoint(std::move(FX));
296   }
297   explicit APValue(const APValue *E, unsigned N) : Kind(None) {
298     MakeVector(); setVector(E, N);
299   }
300   APValue(APSInt R, APSInt I) : Kind(None) {
301     MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
302   }
303   APValue(APFloat R, APFloat I) : Kind(None) {
304     MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
305   }
306   APValue(const APValue &RHS);
307   APValue(APValue &&RHS) : Kind(None) { swap(RHS); }
308   APValue(LValueBase B, const CharUnits &O, NoLValuePath N,
309           bool IsNullPtr = false)
310       : Kind(None) {
311     MakeLValue(); setLValue(B, O, N, IsNullPtr);
312   }
313   APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
314           bool OnePastTheEnd, bool IsNullPtr = false)
315       : Kind(None) {
316     MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
317   }
318   APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(None) {
319     MakeArray(InitElts, Size);
320   }
321   APValue(UninitStruct, unsigned B, unsigned M) : Kind(None) {
322     MakeStruct(B, M);
323   }
324   explicit APValue(const FieldDecl *D, const APValue &V = APValue())
325       : Kind(None) {
326     MakeUnion(); setUnion(D, V);
327   }
328   APValue(const ValueDecl *Member, bool IsDerivedMember,
329           ArrayRef<const CXXRecordDecl*> Path) : Kind(None) {
330     MakeMemberPointer(Member, IsDerivedMember, Path);
331   }
332   APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
333       : Kind(None) {
334     MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
335   }
336   static APValue IndeterminateValue() {
337     APValue Result;
338     Result.Kind = Indeterminate;
339     return Result;
340   }
341 
342   ~APValue() {
343     if (Kind != None && Kind != Indeterminate)
344       DestroyDataAndMakeUninit();
345   }
346 
347   /// Returns whether the object performed allocations.
348   ///
349   /// If APValues are constructed via placement new, \c needsCleanup()
350   /// indicates whether the destructor must be called in order to correctly
351   /// free all allocated memory.
352   bool needsCleanup() const;
353 
354   /// Swaps the contents of this and the given APValue.
355   void swap(APValue &RHS);
356 
357   ValueKind getKind() const { return Kind; }
358 
359   bool isAbsent() const { return Kind == None; }
360   bool isIndeterminate() const { return Kind == Indeterminate; }
361   bool hasValue() const { return Kind != None && Kind != Indeterminate; }
362 
363   bool isInt() const { return Kind == Int; }
364   bool isFloat() const { return Kind == Float; }
365   bool isFixedPoint() const { return Kind == FixedPoint; }
366   bool isComplexInt() const { return Kind == ComplexInt; }
367   bool isComplexFloat() const { return Kind == ComplexFloat; }
368   bool isLValue() const { return Kind == LValue; }
369   bool isVector() const { return Kind == Vector; }
370   bool isArray() const { return Kind == Array; }
371   bool isStruct() const { return Kind == Struct; }
372   bool isUnion() const { return Kind == Union; }
373   bool isMemberPointer() const { return Kind == MemberPointer; }
374   bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
375 
376   void dump() const;
377   void dump(raw_ostream &OS, const ASTContext &Context) const;
378 
379   void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const;
380   std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
381 
382   APSInt &getInt() {
383     assert(isInt() && "Invalid accessor");
384     return *(APSInt*)(char*)Data.buffer;
385   }
386   const APSInt &getInt() const {
387     return const_cast<APValue*>(this)->getInt();
388   }
389 
390   /// Try to convert this value to an integral constant. This works if it's an
391   /// integer, null pointer, or offset from a null pointer. Returns true on
392   /// success.
393   bool toIntegralConstant(APSInt &Result, QualType SrcTy,
394                           const ASTContext &Ctx) const;
395 
396   APFloat &getFloat() {
397     assert(isFloat() && "Invalid accessor");
398     return *(APFloat*)(char*)Data.buffer;
399   }
400   const APFloat &getFloat() const {
401     return const_cast<APValue*>(this)->getFloat();
402   }
403 
404   APFixedPoint &getFixedPoint() {
405     assert(isFixedPoint() && "Invalid accessor");
406     return *(APFixedPoint *)(char *)Data.buffer;
407   }
408   const APFixedPoint &getFixedPoint() const {
409     return const_cast<APValue *>(this)->getFixedPoint();
410   }
411 
412   APSInt &getComplexIntReal() {
413     assert(isComplexInt() && "Invalid accessor");
414     return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
415   }
416   const APSInt &getComplexIntReal() const {
417     return const_cast<APValue*>(this)->getComplexIntReal();
418   }
419 
420   APSInt &getComplexIntImag() {
421     assert(isComplexInt() && "Invalid accessor");
422     return ((ComplexAPSInt*)(char*)Data.buffer)->Imag;
423   }
424   const APSInt &getComplexIntImag() const {
425     return const_cast<APValue*>(this)->getComplexIntImag();
426   }
427 
428   APFloat &getComplexFloatReal() {
429     assert(isComplexFloat() && "Invalid accessor");
430     return ((ComplexAPFloat*)(char*)Data.buffer)->Real;
431   }
432   const APFloat &getComplexFloatReal() const {
433     return const_cast<APValue*>(this)->getComplexFloatReal();
434   }
435 
436   APFloat &getComplexFloatImag() {
437     assert(isComplexFloat() && "Invalid accessor");
438     return ((ComplexAPFloat*)(char*)Data.buffer)->Imag;
439   }
440   const APFloat &getComplexFloatImag() const {
441     return const_cast<APValue*>(this)->getComplexFloatImag();
442   }
443 
444   const LValueBase getLValueBase() const;
445   CharUnits &getLValueOffset();
446   const CharUnits &getLValueOffset() const {
447     return const_cast<APValue*>(this)->getLValueOffset();
448   }
449   bool isLValueOnePastTheEnd() const;
450   bool hasLValuePath() const;
451   ArrayRef<LValuePathEntry> getLValuePath() const;
452   unsigned getLValueCallIndex() const;
453   unsigned getLValueVersion() const;
454   bool isNullPointer() const;
455 
456   APValue &getVectorElt(unsigned I) {
457     assert(isVector() && "Invalid accessor");
458     assert(I < getVectorLength() && "Index out of range");
459     return ((Vec*)(char*)Data.buffer)->Elts[I];
460   }
461   const APValue &getVectorElt(unsigned I) const {
462     return const_cast<APValue*>(this)->getVectorElt(I);
463   }
464   unsigned getVectorLength() const {
465     assert(isVector() && "Invalid accessor");
466     return ((const Vec*)(const void *)Data.buffer)->NumElts;
467   }
468 
469   APValue &getArrayInitializedElt(unsigned I) {
470     assert(isArray() && "Invalid accessor");
471     assert(I < getArrayInitializedElts() && "Index out of range");
472     return ((Arr*)(char*)Data.buffer)->Elts[I];
473   }
474   const APValue &getArrayInitializedElt(unsigned I) const {
475     return const_cast<APValue*>(this)->getArrayInitializedElt(I);
476   }
477   bool hasArrayFiller() const {
478     return getArrayInitializedElts() != getArraySize();
479   }
480   APValue &getArrayFiller() {
481     assert(isArray() && "Invalid accessor");
482     assert(hasArrayFiller() && "No array filler");
483     return ((Arr*)(char*)Data.buffer)->Elts[getArrayInitializedElts()];
484   }
485   const APValue &getArrayFiller() const {
486     return const_cast<APValue*>(this)->getArrayFiller();
487   }
488   unsigned getArrayInitializedElts() const {
489     assert(isArray() && "Invalid accessor");
490     return ((const Arr*)(const void *)Data.buffer)->NumElts;
491   }
492   unsigned getArraySize() const {
493     assert(isArray() && "Invalid accessor");
494     return ((const Arr*)(const void *)Data.buffer)->ArrSize;
495   }
496 
497   unsigned getStructNumBases() const {
498     assert(isStruct() && "Invalid accessor");
499     return ((const StructData*)(const char*)Data.buffer)->NumBases;
500   }
501   unsigned getStructNumFields() const {
502     assert(isStruct() && "Invalid accessor");
503     return ((const StructData*)(const char*)Data.buffer)->NumFields;
504   }
505   APValue &getStructBase(unsigned i) {
506     assert(isStruct() && "Invalid accessor");
507     return ((StructData*)(char*)Data.buffer)->Elts[i];
508   }
509   APValue &getStructField(unsigned i) {
510     assert(isStruct() && "Invalid accessor");
511     return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i];
512   }
513   const APValue &getStructBase(unsigned i) const {
514     return const_cast<APValue*>(this)->getStructBase(i);
515   }
516   const APValue &getStructField(unsigned i) const {
517     return const_cast<APValue*>(this)->getStructField(i);
518   }
519 
520   const FieldDecl *getUnionField() const {
521     assert(isUnion() && "Invalid accessor");
522     return ((const UnionData*)(const char*)Data.buffer)->Field;
523   }
524   APValue &getUnionValue() {
525     assert(isUnion() && "Invalid accessor");
526     return *((UnionData*)(char*)Data.buffer)->Value;
527   }
528   const APValue &getUnionValue() const {
529     return const_cast<APValue*>(this)->getUnionValue();
530   }
531 
532   const ValueDecl *getMemberPointerDecl() const;
533   bool isMemberPointerToDerivedMember() const;
534   ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
535 
536   const AddrLabelExpr* getAddrLabelDiffLHS() const {
537     assert(isAddrLabelDiff() && "Invalid accessor");
538     return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr;
539   }
540   const AddrLabelExpr* getAddrLabelDiffRHS() const {
541     assert(isAddrLabelDiff() && "Invalid accessor");
542     return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr;
543   }
544 
545   void setInt(APSInt I) {
546     assert(isInt() && "Invalid accessor");
547     *(APSInt *)(char *)Data.buffer = std::move(I);
548   }
549   void setFloat(APFloat F) {
550     assert(isFloat() && "Invalid accessor");
551     *(APFloat *)(char *)Data.buffer = std::move(F);
552   }
553   void setFixedPoint(APFixedPoint FX) {
554     assert(isFixedPoint() && "Invalid accessor");
555     *(APFixedPoint *)(char *)Data.buffer = std::move(FX);
556   }
557   void setVector(const APValue *E, unsigned N) {
558     assert(isVector() && "Invalid accessor");
559     ((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
560     ((Vec*)(char*)Data.buffer)->NumElts = N;
561     for (unsigned i = 0; i != N; ++i)
562       ((Vec*)(char*)Data.buffer)->Elts[i] = E[i];
563   }
564   void setComplexInt(APSInt R, APSInt I) {
565     assert(R.getBitWidth() == I.getBitWidth() &&
566            "Invalid complex int (type mismatch).");
567     assert(isComplexInt() && "Invalid accessor");
568     ((ComplexAPSInt *)(char *)Data.buffer)->Real = std::move(R);
569     ((ComplexAPSInt *)(char *)Data.buffer)->Imag = std::move(I);
570   }
571   void setComplexFloat(APFloat R, APFloat I) {
572     assert(&R.getSemantics() == &I.getSemantics() &&
573            "Invalid complex float (type mismatch).");
574     assert(isComplexFloat() && "Invalid accessor");
575     ((ComplexAPFloat *)(char *)Data.buffer)->Real = std::move(R);
576     ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
577   }
578   void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
579                  bool IsNullPtr);
580   void setLValue(LValueBase B, const CharUnits &O,
581                  ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
582                  bool IsNullPtr);
583   void setUnion(const FieldDecl *Field, const APValue &Value) {
584     assert(isUnion() && "Invalid accessor");
585     ((UnionData*)(char*)Data.buffer)->Field = Field;
586     *((UnionData*)(char*)Data.buffer)->Value = Value;
587   }
588   void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
589                         const AddrLabelExpr* RHSExpr) {
590     ((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr;
591     ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr;
592   }
593 
594   /// Assign by swapping from a copy of the RHS.
595   APValue &operator=(APValue RHS) {
596     swap(RHS);
597     return *this;
598   }
599 
600   void setMustBeNullDerivedCap(bool NewValue) {
601     assert(isInt() || isLValue() || isMemberPointer());
602     MustBeNullDerivedCap = NewValue;
603   }
604 
605   bool mustBeNullDerivedCap() const {
606     assert(isInt() || isLValue() || isMemberPointer());
607     return MustBeNullDerivedCap;
608   }
609 
610 private:
611   void DestroyDataAndMakeUninit();
612   void MakeInt() {
613     assert(isAbsent() && "Bad state change");
614     new ((void*)Data.buffer) APSInt(1);
615     Kind = Int;
616   }
617   void MakeFloat() {
618     assert(isAbsent() && "Bad state change");
619     new ((void*)(char*)Data.buffer) APFloat(0.0);
620     Kind = Float;
621   }
622   void MakeFixedPoint(APFixedPoint &&FX) {
623     assert(isAbsent() && "Bad state change");
624     new ((void *)(char *)Data.buffer) APFixedPoint(std::move(FX));
625     Kind = FixedPoint;
626   }
627   void MakeVector() {
628     assert(isAbsent() && "Bad state change");
629     new ((void*)(char*)Data.buffer) Vec();
630     Kind = Vector;
631   }
632   void MakeComplexInt() {
633     assert(isAbsent() && "Bad state change");
634     new ((void*)(char*)Data.buffer) ComplexAPSInt();
635     Kind = ComplexInt;
636   }
637   void MakeComplexFloat() {
638     assert(isAbsent() && "Bad state change");
639     new ((void*)(char*)Data.buffer) ComplexAPFloat();
640     Kind = ComplexFloat;
641   }
642   void MakeLValue();
643   void MakeArray(unsigned InitElts, unsigned Size);
644   void MakeStruct(unsigned B, unsigned M) {
645     assert(isAbsent() && "Bad state change");
646     new ((void*)(char*)Data.buffer) StructData(B, M);
647     Kind = Struct;
648   }
649   void MakeUnion() {
650     assert(isAbsent() && "Bad state change");
651     new ((void*)(char*)Data.buffer) UnionData();
652     Kind = Union;
653   }
654   void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
655                          ArrayRef<const CXXRecordDecl*> Path);
656   void MakeAddrLabelDiff() {
657     assert(isAbsent() && "Bad state change");
658     new ((void*)(char*)Data.buffer) AddrLabelDiffData();
659     Kind = AddrLabelDiff;
660   }
661 };
662 
663 } // end namespace clang.
664 
665 namespace llvm {
666 template<> struct DenseMapInfo<clang::APValue::LValueBase> {
667   static clang::APValue::LValueBase getEmptyKey();
668   static clang::APValue::LValueBase getTombstoneKey();
669   static unsigned getHashValue(const clang::APValue::LValueBase &Base);
670   static bool isEqual(const clang::APValue::LValueBase &LHS,
671                       const clang::APValue::LValueBase &RHS);
672 };
673 }
674 
675 #endif
676