Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:27

0001 //===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 //  This file defines the APValue class.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_CLANG_AST_APVALUE_H
0014 #define LLVM_CLANG_AST_APVALUE_H
0015 
0016 #include "clang/Basic/LLVM.h"
0017 #include "llvm/ADT/APFixedPoint.h"
0018 #include "llvm/ADT/APFloat.h"
0019 #include "llvm/ADT/APSInt.h"
0020 #include "llvm/ADT/FoldingSet.h"
0021 #include "llvm/ADT/PointerIntPair.h"
0022 #include "llvm/ADT/PointerUnion.h"
0023 #include "llvm/Support/AlignOf.h"
0024 
0025 namespace clang {
0026 namespace serialization {
0027 template <typename T> class BasicReaderBase;
0028 } // end namespace serialization
0029 
0030   class AddrLabelExpr;
0031   class ASTContext;
0032   class CharUnits;
0033   class CXXRecordDecl;
0034   class Decl;
0035   class DiagnosticBuilder;
0036   class Expr;
0037   class FieldDecl;
0038   struct PrintingPolicy;
0039   class Type;
0040   class ValueDecl;
0041   class QualType;
0042 
0043 /// Symbolic representation of typeid(T) for some type T.
0044 class TypeInfoLValue {
0045   const Type *T;
0046 
0047 public:
0048   TypeInfoLValue() : T() {}
0049   explicit TypeInfoLValue(const Type *T);
0050 
0051   const Type *getType() const { return T; }
0052   explicit operator bool() const { return T; }
0053 
0054   void *getOpaqueValue() { return const_cast<Type*>(T); }
0055   static TypeInfoLValue getFromOpaqueValue(void *Value) {
0056     TypeInfoLValue V;
0057     V.T = reinterpret_cast<const Type*>(Value);
0058     return V;
0059   }
0060 
0061   void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const;
0062 };
0063 
0064 /// Symbolic representation of a dynamic allocation.
0065 class DynamicAllocLValue {
0066   unsigned Index;
0067 
0068 public:
0069   DynamicAllocLValue() : Index(0) {}
0070   explicit DynamicAllocLValue(unsigned Index) : Index(Index + 1) {}
0071   unsigned getIndex() { return Index - 1; }
0072 
0073   explicit operator bool() const { return Index != 0; }
0074 
0075   void *getOpaqueValue() {
0076     return reinterpret_cast<void *>(static_cast<uintptr_t>(Index)
0077                                     << NumLowBitsAvailable);
0078   }
0079   static DynamicAllocLValue getFromOpaqueValue(void *Value) {
0080     DynamicAllocLValue V;
0081     V.Index = reinterpret_cast<uintptr_t>(Value) >> NumLowBitsAvailable;
0082     return V;
0083   }
0084 
0085   static unsigned getMaxIndex() {
0086     return (std::numeric_limits<unsigned>::max() >> NumLowBitsAvailable) - 1;
0087   }
0088 
0089   static constexpr int NumLowBitsAvailable = 3;
0090 };
0091 }
0092 
0093 namespace llvm {
0094 template<> struct PointerLikeTypeTraits<clang::TypeInfoLValue> {
0095   static void *getAsVoidPointer(clang::TypeInfoLValue V) {
0096     return V.getOpaqueValue();
0097   }
0098   static clang::TypeInfoLValue getFromVoidPointer(void *P) {
0099     return clang::TypeInfoLValue::getFromOpaqueValue(P);
0100   }
0101   // Validated by static_assert in APValue.cpp; hardcoded to avoid needing
0102   // to include Type.h.
0103   static constexpr int NumLowBitsAvailable = 3;
0104 };
0105 
0106 template<> struct PointerLikeTypeTraits<clang::DynamicAllocLValue> {
0107   static void *getAsVoidPointer(clang::DynamicAllocLValue V) {
0108     return V.getOpaqueValue();
0109   }
0110   static clang::DynamicAllocLValue getFromVoidPointer(void *P) {
0111     return clang::DynamicAllocLValue::getFromOpaqueValue(P);
0112   }
0113   static constexpr int NumLowBitsAvailable =
0114       clang::DynamicAllocLValue::NumLowBitsAvailable;
0115 };
0116 }
0117 
0118 namespace clang {
0119 /// APValue - This class implements a discriminated union of [uninitialized]
0120 /// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
0121 /// [Vector: N * APValue], [Array: N * APValue]
0122 class APValue {
0123   typedef llvm::APFixedPoint APFixedPoint;
0124   typedef llvm::APSInt APSInt;
0125   typedef llvm::APFloat APFloat;
0126 public:
0127   enum ValueKind {
0128     /// There is no such object (it's outside its lifetime).
0129     None,
0130     /// This object has an indeterminate value (C++ [basic.indet]).
0131     Indeterminate,
0132     Int,
0133     Float,
0134     FixedPoint,
0135     ComplexInt,
0136     ComplexFloat,
0137     LValue,
0138     Vector,
0139     Array,
0140     Struct,
0141     Union,
0142     MemberPointer,
0143     AddrLabelDiff
0144   };
0145 
0146   class LValueBase {
0147     typedef llvm::PointerUnion<const ValueDecl *, const Expr *, TypeInfoLValue,
0148                                DynamicAllocLValue>
0149         PtrTy;
0150 
0151   public:
0152     LValueBase() : Local{} {}
0153     LValueBase(const ValueDecl *P, unsigned I = 0, unsigned V = 0);
0154     LValueBase(const Expr *P, unsigned I = 0, unsigned V = 0);
0155     static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type);
0156     static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo);
0157 
0158     void Profile(llvm::FoldingSetNodeID &ID) const;
0159 
0160     template <class T> bool is() const { return isa<T>(Ptr); }
0161 
0162     template <class T> T get() const { return cast<T>(Ptr); }
0163 
0164     template <class T> T dyn_cast() const {
0165       return dyn_cast_if_present<T>(Ptr);
0166     }
0167 
0168     void *getOpaqueValue() const;
0169 
0170     bool isNull() const;
0171 
0172     explicit operator bool() const;
0173 
0174     unsigned getCallIndex() const;
0175     unsigned getVersion() const;
0176     QualType getTypeInfoType() const;
0177     QualType getDynamicAllocType() const;
0178 
0179     QualType getType() const;
0180 
0181     friend bool operator==(const LValueBase &LHS, const LValueBase &RHS);
0182     friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) {
0183       return !(LHS == RHS);
0184     }
0185     friend llvm::hash_code hash_value(const LValueBase &Base);
0186     friend struct llvm::DenseMapInfo<LValueBase>;
0187 
0188   private:
0189     PtrTy Ptr;
0190     struct LocalState {
0191       unsigned CallIndex, Version;
0192     };
0193     union {
0194       LocalState Local;
0195       /// The type std::type_info, if this is a TypeInfoLValue.
0196       void *TypeInfoType;
0197       /// The QualType, if this is a DynamicAllocLValue.
0198       void *DynamicAllocType;
0199     };
0200   };
0201 
0202   /// A FieldDecl or CXXRecordDecl, along with a flag indicating whether we
0203   /// mean a virtual or non-virtual base class subobject.
0204   typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
0205 
0206   /// A non-discriminated union of a base, field, or array index.
0207   class LValuePathEntry {
0208     static_assert(sizeof(uintptr_t) <= sizeof(uint64_t),
0209                   "pointer doesn't fit in 64 bits?");
0210     uint64_t Value;
0211 
0212   public:
0213     LValuePathEntry() : Value() {}
0214     LValuePathEntry(BaseOrMemberType BaseOrMember);
0215     static LValuePathEntry ArrayIndex(uint64_t Index) {
0216       LValuePathEntry Result;
0217       Result.Value = Index;
0218       return Result;
0219     }
0220 
0221     BaseOrMemberType getAsBaseOrMember() const {
0222       return BaseOrMemberType::getFromOpaqueValue(
0223           reinterpret_cast<void *>(Value));
0224     }
0225     uint64_t getAsArrayIndex() const { return Value; }
0226 
0227     void Profile(llvm::FoldingSetNodeID &ID) const;
0228 
0229     friend bool operator==(LValuePathEntry A, LValuePathEntry B) {
0230       return A.Value == B.Value;
0231     }
0232     friend bool operator!=(LValuePathEntry A, LValuePathEntry B) {
0233       return A.Value != B.Value;
0234     }
0235     friend llvm::hash_code hash_value(LValuePathEntry A) {
0236       return llvm::hash_value(A.Value);
0237     }
0238   };
0239   class LValuePathSerializationHelper {
0240     const void *Ty;
0241 
0242   public:
0243     ArrayRef<LValuePathEntry> Path;
0244 
0245     LValuePathSerializationHelper(ArrayRef<LValuePathEntry>, QualType);
0246     QualType getType();
0247   };
0248   struct NoLValuePath {};
0249   struct UninitArray {};
0250   struct UninitStruct {};
0251   struct ConstexprUnknown {};
0252 
0253   template <typename Impl> friend class clang::serialization::BasicReaderBase;
0254   friend class ASTImporter;
0255   friend class ASTNodeImporter;
0256 
0257 private:
0258   ValueKind Kind;
0259   bool AllowConstexprUnknown : 1;
0260 
0261   struct ComplexAPSInt {
0262     APSInt Real, Imag;
0263     ComplexAPSInt() : Real(1), Imag(1) {}
0264   };
0265   struct ComplexAPFloat {
0266     APFloat Real, Imag;
0267     ComplexAPFloat() : Real(0.0), Imag(0.0) {}
0268   };
0269   struct LV;
0270   struct Vec {
0271     APValue *Elts = nullptr;
0272     unsigned NumElts = 0;
0273     Vec() = default;
0274     Vec(const Vec &) = delete;
0275     Vec &operator=(const Vec &) = delete;
0276     ~Vec() { delete[] Elts; }
0277   };
0278   struct Arr {
0279     APValue *Elts;
0280     unsigned NumElts, ArrSize;
0281     Arr(unsigned NumElts, unsigned ArrSize);
0282     Arr(const Arr &) = delete;
0283     Arr &operator=(const Arr &) = delete;
0284     ~Arr();
0285   };
0286   struct StructData {
0287     APValue *Elts;
0288     unsigned NumBases;
0289     unsigned NumFields;
0290     StructData(unsigned NumBases, unsigned NumFields);
0291     StructData(const StructData &) = delete;
0292     StructData &operator=(const StructData &) = delete;
0293     ~StructData();
0294   };
0295   struct UnionData {
0296     const FieldDecl *Field;
0297     APValue *Value;
0298     UnionData();
0299     UnionData(const UnionData &) = delete;
0300     UnionData &operator=(const UnionData &) = delete;
0301     ~UnionData();
0302   };
0303   struct AddrLabelDiffData {
0304     const AddrLabelExpr* LHSExpr;
0305     const AddrLabelExpr* RHSExpr;
0306   };
0307   struct MemberPointerData;
0308 
0309   // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
0310   typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
0311                                       ComplexAPFloat, Vec, Arr, StructData,
0312                                       UnionData, AddrLabelDiffData> DataType;
0313   static const size_t DataSize = sizeof(DataType);
0314 
0315   DataType Data;
0316 
0317 public:
0318   bool allowConstexprUnknown() const { return AllowConstexprUnknown; }
0319 
0320   void setConstexprUnknown(bool IsConstexprUnknown = true) {
0321     AllowConstexprUnknown = IsConstexprUnknown;
0322   }
0323 
0324   /// Creates an empty APValue of type None.
0325   APValue() : Kind(None), AllowConstexprUnknown(false) {}
0326   /// Creates an integer APValue holding the given value.
0327   explicit APValue(APSInt I) : Kind(None), AllowConstexprUnknown(false) {
0328     MakeInt(); setInt(std::move(I));
0329   }
0330   /// Creates a float APValue holding the given value.
0331   explicit APValue(APFloat F) : Kind(None), AllowConstexprUnknown(false) {
0332     MakeFloat(); setFloat(std::move(F));
0333   }
0334   /// Creates a fixed-point APValue holding the given value.
0335   explicit APValue(APFixedPoint FX) : Kind(None), AllowConstexprUnknown(false) {
0336     MakeFixedPoint(std::move(FX));
0337   }
0338   /// Creates a vector APValue with \p N elements. The elements
0339   /// are read from \p E.
0340   explicit APValue(const APValue *E, unsigned N)
0341       : Kind(None), AllowConstexprUnknown(false) {
0342     MakeVector(); setVector(E, N);
0343   }
0344   /// Creates an integer complex APValue with the given real and imaginary
0345   /// values.
0346   APValue(APSInt R, APSInt I) : Kind(None), AllowConstexprUnknown(false) {
0347     MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
0348   }
0349   /// Creates a float complex APValue with the given real and imaginary values.
0350   APValue(APFloat R, APFloat I) : Kind(None), AllowConstexprUnknown(false) {
0351     MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
0352   }
0353   APValue(const APValue &RHS);
0354   APValue(APValue &&RHS);
0355   /// Creates an lvalue APValue without an lvalue path.
0356   /// \param Base The base of the lvalue.
0357   /// \param Offset The offset of the lvalue.
0358   /// \param IsNullPtr Whether this lvalue is a null pointer.
0359   APValue(LValueBase Base, const CharUnits &Offset, NoLValuePath,
0360           bool IsNullPtr = false)
0361       : Kind(None), AllowConstexprUnknown(false) {
0362     MakeLValue();
0363     setLValue(Base, Offset, NoLValuePath{}, IsNullPtr);
0364   }
0365   /// Creates an lvalue APValue with an lvalue path.
0366   /// \param Base The base of the lvalue.
0367   /// \param Offset The offset of the lvalue.
0368   /// \param Path The lvalue path.
0369   /// \param OnePastTheEnd Whether this lvalue is one-past-the-end of the
0370   /// subobject it points to.
0371   /// \param IsNullPtr Whether this lvalue is a null pointer.
0372   APValue(LValueBase Base, const CharUnits &Offset,
0373           ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
0374           bool IsNullPtr = false)
0375       : Kind(None), AllowConstexprUnknown(false) {
0376     MakeLValue();
0377     setLValue(Base, Offset, Path, OnePastTheEnd, IsNullPtr);
0378   }
0379   /// Creates a constexpr unknown lvalue APValue.
0380   /// \param Base The base of the lvalue.
0381   /// \param Offset The offset of the lvalue.
0382   /// \param IsNullPtr Whether this lvalue is a null pointer.
0383   APValue(LValueBase Base, const CharUnits &Offset, ConstexprUnknown,
0384           bool IsNullPtr = false)
0385       : Kind(None), AllowConstexprUnknown(true) {
0386     MakeLValue();
0387     setLValue(Base, Offset, NoLValuePath{}, IsNullPtr);
0388   }
0389 
0390   /// Creates a new array APValue.
0391   /// \param UninitArray Marker. Pass an empty UninitArray.
0392   /// \param InitElts Number of elements you're going to initialize in the
0393   /// array.
0394   /// \param Size Full size of the array.
0395   APValue(UninitArray, unsigned InitElts, unsigned Size)
0396       : Kind(None), AllowConstexprUnknown(false) {
0397     MakeArray(InitElts, Size);
0398   }
0399   /// Creates a new struct APValue.
0400   /// \param UninitStruct Marker. Pass an empty UninitStruct.
0401   /// \param NumBases Number of bases.
0402   /// \param NumMembers Number of members.
0403   APValue(UninitStruct, unsigned NumBases, unsigned NumMembers)
0404       : Kind(None), AllowConstexprUnknown(false) {
0405     MakeStruct(NumBases, NumMembers);
0406   }
0407   /// Creates a new union APValue.
0408   /// \param ActiveDecl The FieldDecl of the active union member.
0409   /// \param ActiveValue The value of the active union member.
0410   explicit APValue(const FieldDecl *ActiveDecl,
0411                    const APValue &ActiveValue = APValue())
0412       : Kind(None), AllowConstexprUnknown(false) {
0413     MakeUnion();
0414     setUnion(ActiveDecl, ActiveValue);
0415   }
0416   /// Creates a new member pointer APValue.
0417   /// \param Member Declaration of the member
0418   /// \param IsDerivedMember Whether member is a derived one.
0419   /// \param Path The path of the member.
0420   APValue(const ValueDecl *Member, bool IsDerivedMember,
0421           ArrayRef<const CXXRecordDecl *> Path)
0422       : Kind(None), AllowConstexprUnknown(false) {
0423     MakeMemberPointer(Member, IsDerivedMember, Path);
0424   }
0425   /// Creates a new address label diff APValue.
0426   /// \param LHSExpr The left-hand side of the difference.
0427   /// \param RHSExpr The right-hand side of the difference.
0428   APValue(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
0429       : Kind(None), AllowConstexprUnknown(false) {
0430     MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
0431   }
0432   static APValue IndeterminateValue() {
0433     APValue Result;
0434     Result.Kind = Indeterminate;
0435     return Result;
0436   }
0437 
0438   APValue &operator=(const APValue &RHS);
0439   APValue &operator=(APValue &&RHS);
0440 
0441   ~APValue() {
0442     if (Kind != None && Kind != Indeterminate)
0443       DestroyDataAndMakeUninit();
0444   }
0445 
0446   /// Returns whether the object performed allocations.
0447   ///
0448   /// If APValues are constructed via placement new, \c needsCleanup()
0449   /// indicates whether the destructor must be called in order to correctly
0450   /// free all allocated memory.
0451   bool needsCleanup() const;
0452 
0453   /// Swaps the contents of this and the given APValue.
0454   void swap(APValue &RHS);
0455 
0456   /// profile this value. There is no guarantee that values of different
0457   /// types will not produce the same profiled value, so the type should
0458   /// typically also be profiled if it's not implied by the context.
0459   void Profile(llvm::FoldingSetNodeID &ID) const;
0460 
0461   ValueKind getKind() const { return Kind; }
0462 
0463   bool isAbsent() const { return Kind == None; }
0464   bool isIndeterminate() const { return Kind == Indeterminate; }
0465   bool hasValue() const { return Kind != None && Kind != Indeterminate; }
0466 
0467   bool isInt() const { return Kind == Int; }
0468   bool isFloat() const { return Kind == Float; }
0469   bool isFixedPoint() const { return Kind == FixedPoint; }
0470   bool isComplexInt() const { return Kind == ComplexInt; }
0471   bool isComplexFloat() const { return Kind == ComplexFloat; }
0472   bool isLValue() const { return Kind == LValue; }
0473   bool isVector() const { return Kind == Vector; }
0474   bool isArray() const { return Kind == Array; }
0475   bool isStruct() const { return Kind == Struct; }
0476   bool isUnion() const { return Kind == Union; }
0477   bool isMemberPointer() const { return Kind == MemberPointer; }
0478   bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
0479 
0480   void dump() const;
0481   void dump(raw_ostream &OS, const ASTContext &Context) const;
0482 
0483   void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const;
0484   void printPretty(raw_ostream &OS, const PrintingPolicy &Policy, QualType Ty,
0485                    const ASTContext *Ctx = nullptr) const;
0486 
0487   std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
0488 
0489   APSInt &getInt() {
0490     assert(isInt() && "Invalid accessor");
0491     return *(APSInt *)(char *)&Data;
0492   }
0493   const APSInt &getInt() const {
0494     return const_cast<APValue*>(this)->getInt();
0495   }
0496 
0497   /// Try to convert this value to an integral constant. This works if it's an
0498   /// integer, null pointer, or offset from a null pointer. Returns true on
0499   /// success.
0500   bool toIntegralConstant(APSInt &Result, QualType SrcTy,
0501                           const ASTContext &Ctx) const;
0502 
0503   APFloat &getFloat() {
0504     assert(isFloat() && "Invalid accessor");
0505     return *(APFloat *)(char *)&Data;
0506   }
0507   const APFloat &getFloat() const {
0508     return const_cast<APValue*>(this)->getFloat();
0509   }
0510 
0511   APFixedPoint &getFixedPoint() {
0512     assert(isFixedPoint() && "Invalid accessor");
0513     return *(APFixedPoint *)(char *)&Data;
0514   }
0515   const APFixedPoint &getFixedPoint() const {
0516     return const_cast<APValue *>(this)->getFixedPoint();
0517   }
0518 
0519   APSInt &getComplexIntReal() {
0520     assert(isComplexInt() && "Invalid accessor");
0521     return ((ComplexAPSInt *)(char *)&Data)->Real;
0522   }
0523   const APSInt &getComplexIntReal() const {
0524     return const_cast<APValue*>(this)->getComplexIntReal();
0525   }
0526 
0527   APSInt &getComplexIntImag() {
0528     assert(isComplexInt() && "Invalid accessor");
0529     return ((ComplexAPSInt *)(char *)&Data)->Imag;
0530   }
0531   const APSInt &getComplexIntImag() const {
0532     return const_cast<APValue*>(this)->getComplexIntImag();
0533   }
0534 
0535   APFloat &getComplexFloatReal() {
0536     assert(isComplexFloat() && "Invalid accessor");
0537     return ((ComplexAPFloat *)(char *)&Data)->Real;
0538   }
0539   const APFloat &getComplexFloatReal() const {
0540     return const_cast<APValue*>(this)->getComplexFloatReal();
0541   }
0542 
0543   APFloat &getComplexFloatImag() {
0544     assert(isComplexFloat() && "Invalid accessor");
0545     return ((ComplexAPFloat *)(char *)&Data)->Imag;
0546   }
0547   const APFloat &getComplexFloatImag() const {
0548     return const_cast<APValue*>(this)->getComplexFloatImag();
0549   }
0550 
0551   const LValueBase getLValueBase() const;
0552   CharUnits &getLValueOffset();
0553   const CharUnits &getLValueOffset() const {
0554     return const_cast<APValue*>(this)->getLValueOffset();
0555   }
0556   bool isLValueOnePastTheEnd() const;
0557   bool hasLValuePath() const;
0558   ArrayRef<LValuePathEntry> getLValuePath() const;
0559   unsigned getLValueCallIndex() const;
0560   unsigned getLValueVersion() const;
0561   bool isNullPointer() const;
0562 
0563   APValue &getVectorElt(unsigned I) {
0564     assert(isVector() && "Invalid accessor");
0565     assert(I < getVectorLength() && "Index out of range");
0566     return ((Vec *)(char *)&Data)->Elts[I];
0567   }
0568   const APValue &getVectorElt(unsigned I) const {
0569     return const_cast<APValue*>(this)->getVectorElt(I);
0570   }
0571   unsigned getVectorLength() const {
0572     assert(isVector() && "Invalid accessor");
0573     return ((const Vec *)(const void *)&Data)->NumElts;
0574   }
0575 
0576   APValue &getArrayInitializedElt(unsigned I) {
0577     assert(isArray() && "Invalid accessor");
0578     assert(I < getArrayInitializedElts() && "Index out of range");
0579     return ((Arr *)(char *)&Data)->Elts[I];
0580   }
0581   const APValue &getArrayInitializedElt(unsigned I) const {
0582     return const_cast<APValue*>(this)->getArrayInitializedElt(I);
0583   }
0584   bool hasArrayFiller() const {
0585     return getArrayInitializedElts() != getArraySize();
0586   }
0587   APValue &getArrayFiller() {
0588     assert(isArray() && "Invalid accessor");
0589     assert(hasArrayFiller() && "No array filler");
0590     return ((Arr *)(char *)&Data)->Elts[getArrayInitializedElts()];
0591   }
0592   const APValue &getArrayFiller() const {
0593     return const_cast<APValue*>(this)->getArrayFiller();
0594   }
0595   unsigned getArrayInitializedElts() const {
0596     assert(isArray() && "Invalid accessor");
0597     return ((const Arr *)(const void *)&Data)->NumElts;
0598   }
0599   unsigned getArraySize() const {
0600     assert(isArray() && "Invalid accessor");
0601     return ((const Arr *)(const void *)&Data)->ArrSize;
0602   }
0603 
0604   unsigned getStructNumBases() const {
0605     assert(isStruct() && "Invalid accessor");
0606     return ((const StructData *)(const char *)&Data)->NumBases;
0607   }
0608   unsigned getStructNumFields() const {
0609     assert(isStruct() && "Invalid accessor");
0610     return ((const StructData *)(const char *)&Data)->NumFields;
0611   }
0612   APValue &getStructBase(unsigned i) {
0613     assert(isStruct() && "Invalid accessor");
0614     assert(i < getStructNumBases() && "base class index OOB");
0615     return ((StructData *)(char *)&Data)->Elts[i];
0616   }
0617   APValue &getStructField(unsigned i) {
0618     assert(isStruct() && "Invalid accessor");
0619     assert(i < getStructNumFields() && "field index OOB");
0620     return ((StructData *)(char *)&Data)->Elts[getStructNumBases() + i];
0621   }
0622   const APValue &getStructBase(unsigned i) const {
0623     return const_cast<APValue*>(this)->getStructBase(i);
0624   }
0625   const APValue &getStructField(unsigned i) const {
0626     return const_cast<APValue*>(this)->getStructField(i);
0627   }
0628 
0629   const FieldDecl *getUnionField() const {
0630     assert(isUnion() && "Invalid accessor");
0631     return ((const UnionData *)(const char *)&Data)->Field;
0632   }
0633   APValue &getUnionValue() {
0634     assert(isUnion() && "Invalid accessor");
0635     return *((UnionData *)(char *)&Data)->Value;
0636   }
0637   const APValue &getUnionValue() const {
0638     return const_cast<APValue*>(this)->getUnionValue();
0639   }
0640 
0641   const ValueDecl *getMemberPointerDecl() const;
0642   bool isMemberPointerToDerivedMember() const;
0643   ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
0644 
0645   const AddrLabelExpr* getAddrLabelDiffLHS() const {
0646     assert(isAddrLabelDiff() && "Invalid accessor");
0647     return ((const AddrLabelDiffData *)(const char *)&Data)->LHSExpr;
0648   }
0649   const AddrLabelExpr* getAddrLabelDiffRHS() const {
0650     assert(isAddrLabelDiff() && "Invalid accessor");
0651     return ((const AddrLabelDiffData *)(const char *)&Data)->RHSExpr;
0652   }
0653 
0654   void setInt(APSInt I) {
0655     assert(isInt() && "Invalid accessor");
0656     *(APSInt *)(char *)&Data = std::move(I);
0657   }
0658   void setFloat(APFloat F) {
0659     assert(isFloat() && "Invalid accessor");
0660     *(APFloat *)(char *)&Data = std::move(F);
0661   }
0662   void setFixedPoint(APFixedPoint FX) {
0663     assert(isFixedPoint() && "Invalid accessor");
0664     *(APFixedPoint *)(char *)&Data = std::move(FX);
0665   }
0666   void setVector(const APValue *E, unsigned N) {
0667     MutableArrayRef<APValue> InternalElts = setVectorUninit(N);
0668     for (unsigned i = 0; i != N; ++i)
0669       InternalElts[i] = E[i];
0670   }
0671   void setComplexInt(APSInt R, APSInt I) {
0672     assert(R.getBitWidth() == I.getBitWidth() &&
0673            "Invalid complex int (type mismatch).");
0674     assert(isComplexInt() && "Invalid accessor");
0675     ((ComplexAPSInt *)(char *)&Data)->Real = std::move(R);
0676     ((ComplexAPSInt *)(char *)&Data)->Imag = std::move(I);
0677   }
0678   void setComplexFloat(APFloat R, APFloat I) {
0679     assert(&R.getSemantics() == &I.getSemantics() &&
0680            "Invalid complex float (type mismatch).");
0681     assert(isComplexFloat() && "Invalid accessor");
0682     ((ComplexAPFloat *)(char *)&Data)->Real = std::move(R);
0683     ((ComplexAPFloat *)(char *)&Data)->Imag = std::move(I);
0684   }
0685   void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
0686                  bool IsNullPtr);
0687   void setLValue(LValueBase B, const CharUnits &O,
0688                  ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
0689                  bool IsNullPtr);
0690   void setUnion(const FieldDecl *Field, const APValue &Value);
0691   void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
0692                         const AddrLabelExpr* RHSExpr) {
0693     ((AddrLabelDiffData *)(char *)&Data)->LHSExpr = LHSExpr;
0694     ((AddrLabelDiffData *)(char *)&Data)->RHSExpr = RHSExpr;
0695   }
0696 
0697 private:
0698   void DestroyDataAndMakeUninit();
0699   void MakeInt() {
0700     assert(isAbsent() && "Bad state change");
0701     new ((void *)&Data) APSInt(1);
0702     Kind = Int;
0703   }
0704   void MakeFloat() {
0705     assert(isAbsent() && "Bad state change");
0706     new ((void *)(char *)&Data) APFloat(0.0);
0707     Kind = Float;
0708   }
0709   void MakeFixedPoint(APFixedPoint &&FX) {
0710     assert(isAbsent() && "Bad state change");
0711     new ((void *)(char *)&Data) APFixedPoint(std::move(FX));
0712     Kind = FixedPoint;
0713   }
0714   void MakeVector() {
0715     assert(isAbsent() && "Bad state change");
0716     new ((void *)(char *)&Data) Vec();
0717     Kind = Vector;
0718   }
0719   void MakeComplexInt() {
0720     assert(isAbsent() && "Bad state change");
0721     new ((void *)(char *)&Data) ComplexAPSInt();
0722     Kind = ComplexInt;
0723   }
0724   void MakeComplexFloat() {
0725     assert(isAbsent() && "Bad state change");
0726     new ((void *)(char *)&Data) ComplexAPFloat();
0727     Kind = ComplexFloat;
0728   }
0729   void MakeLValue();
0730   void MakeArray(unsigned InitElts, unsigned Size);
0731   void MakeStruct(unsigned B, unsigned M) {
0732     assert(isAbsent() && "Bad state change");
0733     new ((void *)(char *)&Data) StructData(B, M);
0734     Kind = Struct;
0735   }
0736   void MakeUnion() {
0737     assert(isAbsent() && "Bad state change");
0738     new ((void *)(char *)&Data) UnionData();
0739     Kind = Union;
0740   }
0741   void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
0742                          ArrayRef<const CXXRecordDecl*> Path);
0743   void MakeAddrLabelDiff() {
0744     assert(isAbsent() && "Bad state change");
0745     new ((void *)(char *)&Data) AddrLabelDiffData();
0746     Kind = AddrLabelDiff;
0747   }
0748 
0749 private:
0750   /// The following functions are used as part of initialization, during
0751   /// deserialization and importing. Reserve the space so that it can be
0752   /// filled in by those steps.
0753   MutableArrayRef<APValue> setVectorUninit(unsigned N) {
0754     assert(isVector() && "Invalid accessor");
0755     Vec *V = ((Vec *)(char *)&Data);
0756     V->Elts = new APValue[N];
0757     V->NumElts = N;
0758     return {V->Elts, V->NumElts};
0759   }
0760   MutableArrayRef<LValuePathEntry>
0761   setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size,
0762                   bool OnePastTheEnd, bool IsNullPtr);
0763   MutableArrayRef<const CXXRecordDecl *>
0764   setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember,
0765                          unsigned Size);
0766 };
0767 
0768 } // end namespace clang.
0769 
0770 namespace llvm {
0771 template<> struct DenseMapInfo<clang::APValue::LValueBase> {
0772   static clang::APValue::LValueBase getEmptyKey();
0773   static clang::APValue::LValueBase getTombstoneKey();
0774   static unsigned getHashValue(const clang::APValue::LValueBase &Base);
0775   static bool isEqual(const clang::APValue::LValueBase &LHS,
0776                       const clang::APValue::LValueBase &RHS);
0777 };
0778 }
0779 
0780 #endif