10b57cec5SDimitry Andric //===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file defines the APValue class. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_CLANG_AST_APVALUE_H 140b57cec5SDimitry Andric #define LLVM_CLANG_AST_APVALUE_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "clang/Basic/LLVM.h" 17e8d8bef9SDimitry Andric #include "llvm/ADT/APFixedPoint.h" 180b57cec5SDimitry Andric #include "llvm/ADT/APFloat.h" 190b57cec5SDimitry Andric #include "llvm/ADT/APSInt.h" 20e8d8bef9SDimitry Andric #include "llvm/ADT/FoldingSet.h" 210b57cec5SDimitry Andric #include "llvm/ADT/PointerIntPair.h" 220b57cec5SDimitry Andric #include "llvm/ADT/PointerUnion.h" 23e8d8bef9SDimitry Andric #include "llvm/Support/AlignOf.h" 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric namespace clang { 26e8d8bef9SDimitry Andric namespace serialization { 27e8d8bef9SDimitry Andric template <typename T> class BasicReaderBase; 28e8d8bef9SDimitry Andric } // end namespace serialization 29e8d8bef9SDimitry Andric 300b57cec5SDimitry Andric class AddrLabelExpr; 310b57cec5SDimitry Andric class ASTContext; 320b57cec5SDimitry Andric class CharUnits; 330b57cec5SDimitry Andric class CXXRecordDecl; 340b57cec5SDimitry Andric class Decl; 350b57cec5SDimitry Andric class DiagnosticBuilder; 360b57cec5SDimitry Andric class Expr; 370b57cec5SDimitry Andric class FieldDecl; 380b57cec5SDimitry Andric struct PrintingPolicy; 390b57cec5SDimitry Andric class Type; 400b57cec5SDimitry Andric class ValueDecl; 41e8d8bef9SDimitry Andric class QualType; 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric /// Symbolic representation of typeid(T) for some type T. 440b57cec5SDimitry Andric class TypeInfoLValue { 450b57cec5SDimitry Andric const Type *T; 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric public: TypeInfoLValue()480b57cec5SDimitry Andric TypeInfoLValue() : T() {} 490b57cec5SDimitry Andric explicit TypeInfoLValue(const Type *T); 500b57cec5SDimitry Andric getType()510b57cec5SDimitry Andric const Type *getType() const { return T; } 520b57cec5SDimitry Andric explicit operator bool() const { return T; } 530b57cec5SDimitry Andric getOpaqueValue()540b57cec5SDimitry Andric void *getOpaqueValue() { return const_cast<Type*>(T); } getFromOpaqueValue(void * Value)550b57cec5SDimitry Andric static TypeInfoLValue getFromOpaqueValue(void *Value) { 560b57cec5SDimitry Andric TypeInfoLValue V; 570b57cec5SDimitry Andric V.T = reinterpret_cast<const Type*>(Value); 580b57cec5SDimitry Andric return V; 590b57cec5SDimitry Andric } 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const; 620b57cec5SDimitry Andric }; 63a7dea167SDimitry Andric 64a7dea167SDimitry Andric /// Symbolic representation of a dynamic allocation. 65a7dea167SDimitry Andric class DynamicAllocLValue { 66a7dea167SDimitry Andric unsigned Index; 67a7dea167SDimitry Andric 68a7dea167SDimitry Andric public: DynamicAllocLValue()69a7dea167SDimitry Andric DynamicAllocLValue() : Index(0) {} DynamicAllocLValue(unsigned Index)70a7dea167SDimitry Andric explicit DynamicAllocLValue(unsigned Index) : Index(Index + 1) {} getIndex()71a7dea167SDimitry Andric unsigned getIndex() { return Index - 1; } 72a7dea167SDimitry Andric 73a7dea167SDimitry Andric explicit operator bool() const { return Index != 0; } 74a7dea167SDimitry Andric getOpaqueValue()75a7dea167SDimitry Andric void *getOpaqueValue() { 76a7dea167SDimitry Andric return reinterpret_cast<void *>(static_cast<uintptr_t>(Index) 77a7dea167SDimitry Andric << NumLowBitsAvailable); 78a7dea167SDimitry Andric } getFromOpaqueValue(void * Value)79a7dea167SDimitry Andric static DynamicAllocLValue getFromOpaqueValue(void *Value) { 80a7dea167SDimitry Andric DynamicAllocLValue V; 81a7dea167SDimitry Andric V.Index = reinterpret_cast<uintptr_t>(Value) >> NumLowBitsAvailable; 82a7dea167SDimitry Andric return V; 83a7dea167SDimitry Andric } 84a7dea167SDimitry Andric getMaxIndex()85a7dea167SDimitry Andric static unsigned getMaxIndex() { 86a7dea167SDimitry Andric return (std::numeric_limits<unsigned>::max() >> NumLowBitsAvailable) - 1; 87a7dea167SDimitry Andric } 88a7dea167SDimitry Andric 89a7dea167SDimitry Andric static constexpr int NumLowBitsAvailable = 3; 90a7dea167SDimitry Andric }; 910b57cec5SDimitry Andric } 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric namespace llvm { 940b57cec5SDimitry Andric template<> struct PointerLikeTypeTraits<clang::TypeInfoLValue> { 950b57cec5SDimitry Andric static void *getAsVoidPointer(clang::TypeInfoLValue V) { 960b57cec5SDimitry Andric return V.getOpaqueValue(); 970b57cec5SDimitry Andric } 980b57cec5SDimitry Andric static clang::TypeInfoLValue getFromVoidPointer(void *P) { 990b57cec5SDimitry Andric return clang::TypeInfoLValue::getFromOpaqueValue(P); 1000b57cec5SDimitry Andric } 1010b57cec5SDimitry Andric // Validated by static_assert in APValue.cpp; hardcoded to avoid needing 1020b57cec5SDimitry Andric // to include Type.h. 1030b57cec5SDimitry Andric static constexpr int NumLowBitsAvailable = 3; 1040b57cec5SDimitry Andric }; 105a7dea167SDimitry Andric 106a7dea167SDimitry Andric template<> struct PointerLikeTypeTraits<clang::DynamicAllocLValue> { 107a7dea167SDimitry Andric static void *getAsVoidPointer(clang::DynamicAllocLValue V) { 108a7dea167SDimitry Andric return V.getOpaqueValue(); 109a7dea167SDimitry Andric } 110a7dea167SDimitry Andric static clang::DynamicAllocLValue getFromVoidPointer(void *P) { 111a7dea167SDimitry Andric return clang::DynamicAllocLValue::getFromOpaqueValue(P); 112a7dea167SDimitry Andric } 113a7dea167SDimitry Andric static constexpr int NumLowBitsAvailable = 114a7dea167SDimitry Andric clang::DynamicAllocLValue::NumLowBitsAvailable; 115a7dea167SDimitry Andric }; 1160b57cec5SDimitry Andric } 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric namespace clang { 1190b57cec5SDimitry Andric /// APValue - This class implements a discriminated union of [uninitialized] 1200b57cec5SDimitry Andric /// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset], 1210b57cec5SDimitry Andric /// [Vector: N * APValue], [Array: N * APValue] 1220b57cec5SDimitry Andric class APValue { 123e8d8bef9SDimitry Andric typedef llvm::APFixedPoint APFixedPoint; 1240b57cec5SDimitry Andric typedef llvm::APSInt APSInt; 1250b57cec5SDimitry Andric typedef llvm::APFloat APFloat; 1260b57cec5SDimitry Andric public: 1270b57cec5SDimitry Andric enum ValueKind { 1280b57cec5SDimitry Andric /// There is no such object (it's outside its lifetime). 1290b57cec5SDimitry Andric None, 1300b57cec5SDimitry Andric /// This object has an indeterminate value (C++ [basic.indet]). 1310b57cec5SDimitry Andric Indeterminate, 1320b57cec5SDimitry Andric Int, 1330b57cec5SDimitry Andric Float, 1340b57cec5SDimitry Andric FixedPoint, 1350b57cec5SDimitry Andric ComplexInt, 1360b57cec5SDimitry Andric ComplexFloat, 1370b57cec5SDimitry Andric LValue, 1380b57cec5SDimitry Andric Vector, 1390b57cec5SDimitry Andric Array, 1400b57cec5SDimitry Andric Struct, 1410b57cec5SDimitry Andric Union, 1420b57cec5SDimitry Andric MemberPointer, 1430b57cec5SDimitry Andric AddrLabelDiff 1440b57cec5SDimitry Andric }; 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric class LValueBase { 147a7dea167SDimitry Andric typedef llvm::PointerUnion<const ValueDecl *, const Expr *, TypeInfoLValue, 148a7dea167SDimitry Andric DynamicAllocLValue> 1490b57cec5SDimitry Andric PtrTy; 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric public: 1520b57cec5SDimitry Andric LValueBase() : Local{} {} 1530b57cec5SDimitry Andric LValueBase(const ValueDecl *P, unsigned I = 0, unsigned V = 0); 1540b57cec5SDimitry Andric LValueBase(const Expr *P, unsigned I = 0, unsigned V = 0); 155a7dea167SDimitry Andric static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type); 1560b57cec5SDimitry Andric static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo); 1570b57cec5SDimitry Andric 158e8d8bef9SDimitry Andric void Profile(llvm::FoldingSetNodeID &ID) const; 159e8d8bef9SDimitry Andric 1600b57cec5SDimitry Andric template <class T> 1610b57cec5SDimitry Andric bool is() const { return Ptr.is<T>(); } 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric template <class T> 1640b57cec5SDimitry Andric T get() const { return Ptr.get<T>(); } 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric template <class T> 1670b57cec5SDimitry Andric T dyn_cast() const { return Ptr.dyn_cast<T>(); } 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric void *getOpaqueValue() const; 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric bool isNull() const; 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric explicit operator bool() const; 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric unsigned getCallIndex() const; 1760b57cec5SDimitry Andric unsigned getVersion() const; 1770b57cec5SDimitry Andric QualType getTypeInfoType() const; 178a7dea167SDimitry Andric QualType getDynamicAllocType() const; 1790b57cec5SDimitry Andric 180e8d8bef9SDimitry Andric QualType getType() const; 181e8d8bef9SDimitry Andric 1820b57cec5SDimitry Andric friend bool operator==(const LValueBase &LHS, const LValueBase &RHS); 1830b57cec5SDimitry Andric friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) { 1840b57cec5SDimitry Andric return !(LHS == RHS); 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric friend llvm::hash_code hash_value(const LValueBase &Base); 187e8d8bef9SDimitry Andric friend struct llvm::DenseMapInfo<LValueBase>; 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric private: 1900b57cec5SDimitry Andric PtrTy Ptr; 1910b57cec5SDimitry Andric struct LocalState { 1920b57cec5SDimitry Andric unsigned CallIndex, Version; 1930b57cec5SDimitry Andric }; 1940b57cec5SDimitry Andric union { 1950b57cec5SDimitry Andric LocalState Local; 1960b57cec5SDimitry Andric /// The type std::type_info, if this is a TypeInfoLValue. 1970b57cec5SDimitry Andric void *TypeInfoType; 198a7dea167SDimitry Andric /// The QualType, if this is a DynamicAllocLValue. 199a7dea167SDimitry Andric void *DynamicAllocType; 2000b57cec5SDimitry Andric }; 2010b57cec5SDimitry Andric }; 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric /// A FieldDecl or CXXRecordDecl, along with a flag indicating whether we 2040b57cec5SDimitry Andric /// mean a virtual or non-virtual base class subobject. 2050b57cec5SDimitry Andric typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType; 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric /// A non-discriminated union of a base, field, or array index. 2080b57cec5SDimitry Andric class LValuePathEntry { 2090b57cec5SDimitry Andric static_assert(sizeof(uintptr_t) <= sizeof(uint64_t), 2100b57cec5SDimitry Andric "pointer doesn't fit in 64 bits?"); 2110b57cec5SDimitry Andric uint64_t Value; 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric public: 2140b57cec5SDimitry Andric LValuePathEntry() : Value() {} 215e8d8bef9SDimitry Andric LValuePathEntry(BaseOrMemberType BaseOrMember); 2160b57cec5SDimitry Andric static LValuePathEntry ArrayIndex(uint64_t Index) { 2170b57cec5SDimitry Andric LValuePathEntry Result; 2180b57cec5SDimitry Andric Result.Value = Index; 2190b57cec5SDimitry Andric return Result; 2200b57cec5SDimitry Andric } 2210b57cec5SDimitry Andric 2220b57cec5SDimitry Andric BaseOrMemberType getAsBaseOrMember() const { 2230b57cec5SDimitry Andric return BaseOrMemberType::getFromOpaqueValue( 2240b57cec5SDimitry Andric reinterpret_cast<void *>(Value)); 2250b57cec5SDimitry Andric } 2260b57cec5SDimitry Andric uint64_t getAsArrayIndex() const { return Value; } 2270b57cec5SDimitry Andric 228e8d8bef9SDimitry Andric void Profile(llvm::FoldingSetNodeID &ID) const; 229e8d8bef9SDimitry Andric 2300b57cec5SDimitry Andric friend bool operator==(LValuePathEntry A, LValuePathEntry B) { 2310b57cec5SDimitry Andric return A.Value == B.Value; 2320b57cec5SDimitry Andric } 2330b57cec5SDimitry Andric friend bool operator!=(LValuePathEntry A, LValuePathEntry B) { 2340b57cec5SDimitry Andric return A.Value != B.Value; 2350b57cec5SDimitry Andric } 2360b57cec5SDimitry Andric friend llvm::hash_code hash_value(LValuePathEntry A) { 2370b57cec5SDimitry Andric return llvm::hash_value(A.Value); 2380b57cec5SDimitry Andric } 2390b57cec5SDimitry Andric }; 240e8d8bef9SDimitry Andric class LValuePathSerializationHelper { 241bdd1243dSDimitry Andric const void *Ty; 242e8d8bef9SDimitry Andric 243e8d8bef9SDimitry Andric public: 244e8d8bef9SDimitry Andric ArrayRef<LValuePathEntry> Path; 245e8d8bef9SDimitry Andric 246e8d8bef9SDimitry Andric LValuePathSerializationHelper(ArrayRef<LValuePathEntry>, QualType); 247e8d8bef9SDimitry Andric QualType getType(); 248e8d8bef9SDimitry Andric }; 2490b57cec5SDimitry Andric struct NoLValuePath {}; 2500b57cec5SDimitry Andric struct UninitArray {}; 2510b57cec5SDimitry Andric struct UninitStruct {}; 2520b57cec5SDimitry Andric 253e8d8bef9SDimitry Andric template <typename Impl> friend class clang::serialization::BasicReaderBase; 254e8d8bef9SDimitry Andric friend class ASTImporter; 255e8d8bef9SDimitry Andric friend class ASTNodeImporter; 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andric private: 2580b57cec5SDimitry Andric ValueKind Kind; 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric struct ComplexAPSInt { 2610b57cec5SDimitry Andric APSInt Real, Imag; 2620b57cec5SDimitry Andric ComplexAPSInt() : Real(1), Imag(1) {} 2630b57cec5SDimitry Andric }; 2640b57cec5SDimitry Andric struct ComplexAPFloat { 2650b57cec5SDimitry Andric APFloat Real, Imag; 2660b57cec5SDimitry Andric ComplexAPFloat() : Real(0.0), Imag(0.0) {} 2670b57cec5SDimitry Andric }; 2680b57cec5SDimitry Andric struct LV; 2690b57cec5SDimitry Andric struct Vec { 27006c3fb27SDimitry Andric APValue *Elts = nullptr; 27106c3fb27SDimitry Andric unsigned NumElts = 0; 27206c3fb27SDimitry Andric Vec() = default; 2735f757f3fSDimitry Andric Vec(const Vec &) = delete; 2745f757f3fSDimitry Andric Vec &operator=(const Vec &) = delete; 2750b57cec5SDimitry Andric ~Vec() { delete[] Elts; } 2760b57cec5SDimitry Andric }; 2770b57cec5SDimitry Andric struct Arr { 2780b57cec5SDimitry Andric APValue *Elts; 2790b57cec5SDimitry Andric unsigned NumElts, ArrSize; 2800b57cec5SDimitry Andric Arr(unsigned NumElts, unsigned ArrSize); 2815f757f3fSDimitry Andric Arr(const Arr &) = delete; 2825f757f3fSDimitry Andric Arr &operator=(const Arr &) = delete; 2830b57cec5SDimitry Andric ~Arr(); 2840b57cec5SDimitry Andric }; 2850b57cec5SDimitry Andric struct StructData { 2860b57cec5SDimitry Andric APValue *Elts; 2870b57cec5SDimitry Andric unsigned NumBases; 2880b57cec5SDimitry Andric unsigned NumFields; 2890b57cec5SDimitry Andric StructData(unsigned NumBases, unsigned NumFields); 2905f757f3fSDimitry Andric StructData(const StructData &) = delete; 2915f757f3fSDimitry Andric StructData &operator=(const StructData &) = delete; 2920b57cec5SDimitry Andric ~StructData(); 2930b57cec5SDimitry Andric }; 2940b57cec5SDimitry Andric struct UnionData { 2950b57cec5SDimitry Andric const FieldDecl *Field; 2960b57cec5SDimitry Andric APValue *Value; 2970b57cec5SDimitry Andric UnionData(); 2985f757f3fSDimitry Andric UnionData(const UnionData &) = delete; 2995f757f3fSDimitry Andric UnionData &operator=(const UnionData &) = delete; 3000b57cec5SDimitry Andric ~UnionData(); 3010b57cec5SDimitry Andric }; 3020b57cec5SDimitry Andric struct AddrLabelDiffData { 3030b57cec5SDimitry Andric const AddrLabelExpr* LHSExpr; 3040b57cec5SDimitry Andric const AddrLabelExpr* RHSExpr; 3050b57cec5SDimitry Andric }; 3060b57cec5SDimitry Andric struct MemberPointerData; 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric // We ensure elsewhere that Data is big enough for LV and MemberPointerData. 3090b57cec5SDimitry Andric typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt, 3100b57cec5SDimitry Andric ComplexAPFloat, Vec, Arr, StructData, 3110b57cec5SDimitry Andric UnionData, AddrLabelDiffData> DataType; 3120b57cec5SDimitry Andric static const size_t DataSize = sizeof(DataType); 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric DataType Data; 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric public: 3170b57cec5SDimitry Andric APValue() : Kind(None) {} 3180b57cec5SDimitry Andric explicit APValue(APSInt I) : Kind(None) { 3190b57cec5SDimitry Andric MakeInt(); setInt(std::move(I)); 3200b57cec5SDimitry Andric } 3210b57cec5SDimitry Andric explicit APValue(APFloat F) : Kind(None) { 3220b57cec5SDimitry Andric MakeFloat(); setFloat(std::move(F)); 3230b57cec5SDimitry Andric } 3240b57cec5SDimitry Andric explicit APValue(APFixedPoint FX) : Kind(None) { 3250b57cec5SDimitry Andric MakeFixedPoint(std::move(FX)); 3260b57cec5SDimitry Andric } 3270b57cec5SDimitry Andric explicit APValue(const APValue *E, unsigned N) : Kind(None) { 3280b57cec5SDimitry Andric MakeVector(); setVector(E, N); 3290b57cec5SDimitry Andric } 3300b57cec5SDimitry Andric APValue(APSInt R, APSInt I) : Kind(None) { 3310b57cec5SDimitry Andric MakeComplexInt(); setComplexInt(std::move(R), std::move(I)); 3320b57cec5SDimitry Andric } 3330b57cec5SDimitry Andric APValue(APFloat R, APFloat I) : Kind(None) { 3340b57cec5SDimitry Andric MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I)); 3350b57cec5SDimitry Andric } 3360b57cec5SDimitry Andric APValue(const APValue &RHS); 337e8d8bef9SDimitry Andric APValue(APValue &&RHS); 3380b57cec5SDimitry Andric APValue(LValueBase B, const CharUnits &O, NoLValuePath N, 3390b57cec5SDimitry Andric bool IsNullPtr = false) 3400b57cec5SDimitry Andric : Kind(None) { 3410b57cec5SDimitry Andric MakeLValue(); setLValue(B, O, N, IsNullPtr); 3420b57cec5SDimitry Andric } 3430b57cec5SDimitry Andric APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path, 3440b57cec5SDimitry Andric bool OnePastTheEnd, bool IsNullPtr = false) 3450b57cec5SDimitry Andric : Kind(None) { 3460b57cec5SDimitry Andric MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr); 3470b57cec5SDimitry Andric } 3480b57cec5SDimitry Andric APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(None) { 3490b57cec5SDimitry Andric MakeArray(InitElts, Size); 3500b57cec5SDimitry Andric } 3510b57cec5SDimitry Andric APValue(UninitStruct, unsigned B, unsigned M) : Kind(None) { 3520b57cec5SDimitry Andric MakeStruct(B, M); 3530b57cec5SDimitry Andric } 3540b57cec5SDimitry Andric explicit APValue(const FieldDecl *D, const APValue &V = APValue()) 3550b57cec5SDimitry Andric : Kind(None) { 3560b57cec5SDimitry Andric MakeUnion(); setUnion(D, V); 3570b57cec5SDimitry Andric } 3580b57cec5SDimitry Andric APValue(const ValueDecl *Member, bool IsDerivedMember, 3590b57cec5SDimitry Andric ArrayRef<const CXXRecordDecl*> Path) : Kind(None) { 3600b57cec5SDimitry Andric MakeMemberPointer(Member, IsDerivedMember, Path); 3610b57cec5SDimitry Andric } 3620b57cec5SDimitry Andric APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr) 3630b57cec5SDimitry Andric : Kind(None) { 3640b57cec5SDimitry Andric MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr); 3650b57cec5SDimitry Andric } 3660b57cec5SDimitry Andric static APValue IndeterminateValue() { 3670b57cec5SDimitry Andric APValue Result; 3680b57cec5SDimitry Andric Result.Kind = Indeterminate; 3690b57cec5SDimitry Andric return Result; 3700b57cec5SDimitry Andric } 3710b57cec5SDimitry Andric 372e8d8bef9SDimitry Andric APValue &operator=(const APValue &RHS); 373e8d8bef9SDimitry Andric APValue &operator=(APValue &&RHS); 374e8d8bef9SDimitry Andric 3750b57cec5SDimitry Andric ~APValue() { 3760b57cec5SDimitry Andric if (Kind != None && Kind != Indeterminate) 3770b57cec5SDimitry Andric DestroyDataAndMakeUninit(); 3780b57cec5SDimitry Andric } 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric /// Returns whether the object performed allocations. 3810b57cec5SDimitry Andric /// 3820b57cec5SDimitry Andric /// If APValues are constructed via placement new, \c needsCleanup() 3830b57cec5SDimitry Andric /// indicates whether the destructor must be called in order to correctly 3840b57cec5SDimitry Andric /// free all allocated memory. 3850b57cec5SDimitry Andric bool needsCleanup() const; 3860b57cec5SDimitry Andric 3870b57cec5SDimitry Andric /// Swaps the contents of this and the given APValue. 3880b57cec5SDimitry Andric void swap(APValue &RHS); 3890b57cec5SDimitry Andric 390e8d8bef9SDimitry Andric /// profile this value. There is no guarantee that values of different 391e8d8bef9SDimitry Andric /// types will not produce the same profiled value, so the type should 392e8d8bef9SDimitry Andric /// typically also be profiled if it's not implied by the context. 393e8d8bef9SDimitry Andric void Profile(llvm::FoldingSetNodeID &ID) const; 394e8d8bef9SDimitry Andric 3950b57cec5SDimitry Andric ValueKind getKind() const { return Kind; } 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andric bool isAbsent() const { return Kind == None; } 3980b57cec5SDimitry Andric bool isIndeterminate() const { return Kind == Indeterminate; } 3990b57cec5SDimitry Andric bool hasValue() const { return Kind != None && Kind != Indeterminate; } 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric bool isInt() const { return Kind == Int; } 4020b57cec5SDimitry Andric bool isFloat() const { return Kind == Float; } 4030b57cec5SDimitry Andric bool isFixedPoint() const { return Kind == FixedPoint; } 4040b57cec5SDimitry Andric bool isComplexInt() const { return Kind == ComplexInt; } 4050b57cec5SDimitry Andric bool isComplexFloat() const { return Kind == ComplexFloat; } 4060b57cec5SDimitry Andric bool isLValue() const { return Kind == LValue; } 4070b57cec5SDimitry Andric bool isVector() const { return Kind == Vector; } 4080b57cec5SDimitry Andric bool isArray() const { return Kind == Array; } 4090b57cec5SDimitry Andric bool isStruct() const { return Kind == Struct; } 4100b57cec5SDimitry Andric bool isUnion() const { return Kind == Union; } 4110b57cec5SDimitry Andric bool isMemberPointer() const { return Kind == MemberPointer; } 4120b57cec5SDimitry Andric bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; } 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric void dump() const; 4155ffd83dbSDimitry Andric void dump(raw_ostream &OS, const ASTContext &Context) const; 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const; 418e8d8bef9SDimitry Andric void printPretty(raw_ostream &OS, const PrintingPolicy &Policy, QualType Ty, 419e8d8bef9SDimitry Andric const ASTContext *Ctx = nullptr) const; 420e8d8bef9SDimitry Andric 4210b57cec5SDimitry Andric std::string getAsString(const ASTContext &Ctx, QualType Ty) const; 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric APSInt &getInt() { 4240b57cec5SDimitry Andric assert(isInt() && "Invalid accessor"); 425e8d8bef9SDimitry Andric return *(APSInt *)(char *)&Data; 4260b57cec5SDimitry Andric } 4270b57cec5SDimitry Andric const APSInt &getInt() const { 4280b57cec5SDimitry Andric return const_cast<APValue*>(this)->getInt(); 4290b57cec5SDimitry Andric } 4300b57cec5SDimitry Andric 4310b57cec5SDimitry Andric /// Try to convert this value to an integral constant. This works if it's an 4320b57cec5SDimitry Andric /// integer, null pointer, or offset from a null pointer. Returns true on 4330b57cec5SDimitry Andric /// success. 4340b57cec5SDimitry Andric bool toIntegralConstant(APSInt &Result, QualType SrcTy, 4350b57cec5SDimitry Andric const ASTContext &Ctx) const; 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andric APFloat &getFloat() { 4380b57cec5SDimitry Andric assert(isFloat() && "Invalid accessor"); 439e8d8bef9SDimitry Andric return *(APFloat *)(char *)&Data; 4400b57cec5SDimitry Andric } 4410b57cec5SDimitry Andric const APFloat &getFloat() const { 4420b57cec5SDimitry Andric return const_cast<APValue*>(this)->getFloat(); 4430b57cec5SDimitry Andric } 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andric APFixedPoint &getFixedPoint() { 4460b57cec5SDimitry Andric assert(isFixedPoint() && "Invalid accessor"); 447e8d8bef9SDimitry Andric return *(APFixedPoint *)(char *)&Data; 4480b57cec5SDimitry Andric } 4490b57cec5SDimitry Andric const APFixedPoint &getFixedPoint() const { 4500b57cec5SDimitry Andric return const_cast<APValue *>(this)->getFixedPoint(); 4510b57cec5SDimitry Andric } 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andric APSInt &getComplexIntReal() { 4540b57cec5SDimitry Andric assert(isComplexInt() && "Invalid accessor"); 455e8d8bef9SDimitry Andric return ((ComplexAPSInt *)(char *)&Data)->Real; 4560b57cec5SDimitry Andric } 4570b57cec5SDimitry Andric const APSInt &getComplexIntReal() const { 4580b57cec5SDimitry Andric return const_cast<APValue*>(this)->getComplexIntReal(); 4590b57cec5SDimitry Andric } 4600b57cec5SDimitry Andric 4610b57cec5SDimitry Andric APSInt &getComplexIntImag() { 4620b57cec5SDimitry Andric assert(isComplexInt() && "Invalid accessor"); 463e8d8bef9SDimitry Andric return ((ComplexAPSInt *)(char *)&Data)->Imag; 4640b57cec5SDimitry Andric } 4650b57cec5SDimitry Andric const APSInt &getComplexIntImag() const { 4660b57cec5SDimitry Andric return const_cast<APValue*>(this)->getComplexIntImag(); 4670b57cec5SDimitry Andric } 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andric APFloat &getComplexFloatReal() { 4700b57cec5SDimitry Andric assert(isComplexFloat() && "Invalid accessor"); 471e8d8bef9SDimitry Andric return ((ComplexAPFloat *)(char *)&Data)->Real; 4720b57cec5SDimitry Andric } 4730b57cec5SDimitry Andric const APFloat &getComplexFloatReal() const { 4740b57cec5SDimitry Andric return const_cast<APValue*>(this)->getComplexFloatReal(); 4750b57cec5SDimitry Andric } 4760b57cec5SDimitry Andric 4770b57cec5SDimitry Andric APFloat &getComplexFloatImag() { 4780b57cec5SDimitry Andric assert(isComplexFloat() && "Invalid accessor"); 479e8d8bef9SDimitry Andric return ((ComplexAPFloat *)(char *)&Data)->Imag; 4800b57cec5SDimitry Andric } 4810b57cec5SDimitry Andric const APFloat &getComplexFloatImag() const { 4820b57cec5SDimitry Andric return const_cast<APValue*>(this)->getComplexFloatImag(); 4830b57cec5SDimitry Andric } 4840b57cec5SDimitry Andric 4850b57cec5SDimitry Andric const LValueBase getLValueBase() const; 4860b57cec5SDimitry Andric CharUnits &getLValueOffset(); 4870b57cec5SDimitry Andric const CharUnits &getLValueOffset() const { 4880b57cec5SDimitry Andric return const_cast<APValue*>(this)->getLValueOffset(); 4890b57cec5SDimitry Andric } 4900b57cec5SDimitry Andric bool isLValueOnePastTheEnd() const; 4910b57cec5SDimitry Andric bool hasLValuePath() const; 4920b57cec5SDimitry Andric ArrayRef<LValuePathEntry> getLValuePath() const; 4930b57cec5SDimitry Andric unsigned getLValueCallIndex() const; 4940b57cec5SDimitry Andric unsigned getLValueVersion() const; 4950b57cec5SDimitry Andric bool isNullPointer() const; 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andric APValue &getVectorElt(unsigned I) { 4980b57cec5SDimitry Andric assert(isVector() && "Invalid accessor"); 4990b57cec5SDimitry Andric assert(I < getVectorLength() && "Index out of range"); 500e8d8bef9SDimitry Andric return ((Vec *)(char *)&Data)->Elts[I]; 5010b57cec5SDimitry Andric } 5020b57cec5SDimitry Andric const APValue &getVectorElt(unsigned I) const { 5030b57cec5SDimitry Andric return const_cast<APValue*>(this)->getVectorElt(I); 5040b57cec5SDimitry Andric } 5050b57cec5SDimitry Andric unsigned getVectorLength() const { 5060b57cec5SDimitry Andric assert(isVector() && "Invalid accessor"); 507e8d8bef9SDimitry Andric return ((const Vec *)(const void *)&Data)->NumElts; 5080b57cec5SDimitry Andric } 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andric APValue &getArrayInitializedElt(unsigned I) { 5110b57cec5SDimitry Andric assert(isArray() && "Invalid accessor"); 5120b57cec5SDimitry Andric assert(I < getArrayInitializedElts() && "Index out of range"); 513e8d8bef9SDimitry Andric return ((Arr *)(char *)&Data)->Elts[I]; 5140b57cec5SDimitry Andric } 5150b57cec5SDimitry Andric const APValue &getArrayInitializedElt(unsigned I) const { 5160b57cec5SDimitry Andric return const_cast<APValue*>(this)->getArrayInitializedElt(I); 5170b57cec5SDimitry Andric } 5180b57cec5SDimitry Andric bool hasArrayFiller() const { 5190b57cec5SDimitry Andric return getArrayInitializedElts() != getArraySize(); 5200b57cec5SDimitry Andric } 5210b57cec5SDimitry Andric APValue &getArrayFiller() { 5220b57cec5SDimitry Andric assert(isArray() && "Invalid accessor"); 5230b57cec5SDimitry Andric assert(hasArrayFiller() && "No array filler"); 524e8d8bef9SDimitry Andric return ((Arr *)(char *)&Data)->Elts[getArrayInitializedElts()]; 5250b57cec5SDimitry Andric } 5260b57cec5SDimitry Andric const APValue &getArrayFiller() const { 5270b57cec5SDimitry Andric return const_cast<APValue*>(this)->getArrayFiller(); 5280b57cec5SDimitry Andric } 5290b57cec5SDimitry Andric unsigned getArrayInitializedElts() const { 5300b57cec5SDimitry Andric assert(isArray() && "Invalid accessor"); 531e8d8bef9SDimitry Andric return ((const Arr *)(const void *)&Data)->NumElts; 5320b57cec5SDimitry Andric } 5330b57cec5SDimitry Andric unsigned getArraySize() const { 5340b57cec5SDimitry Andric assert(isArray() && "Invalid accessor"); 535e8d8bef9SDimitry Andric return ((const Arr *)(const void *)&Data)->ArrSize; 5360b57cec5SDimitry Andric } 5370b57cec5SDimitry Andric 5380b57cec5SDimitry Andric unsigned getStructNumBases() const { 5390b57cec5SDimitry Andric assert(isStruct() && "Invalid accessor"); 540e8d8bef9SDimitry Andric return ((const StructData *)(const char *)&Data)->NumBases; 5410b57cec5SDimitry Andric } 5420b57cec5SDimitry Andric unsigned getStructNumFields() const { 5430b57cec5SDimitry Andric assert(isStruct() && "Invalid accessor"); 544e8d8bef9SDimitry Andric return ((const StructData *)(const char *)&Data)->NumFields; 5450b57cec5SDimitry Andric } 5460b57cec5SDimitry Andric APValue &getStructBase(unsigned i) { 5470b57cec5SDimitry Andric assert(isStruct() && "Invalid accessor"); 548e8d8bef9SDimitry Andric assert(i < getStructNumBases() && "base class index OOB"); 549e8d8bef9SDimitry Andric return ((StructData *)(char *)&Data)->Elts[i]; 5500b57cec5SDimitry Andric } 5510b57cec5SDimitry Andric APValue &getStructField(unsigned i) { 5520b57cec5SDimitry Andric assert(isStruct() && "Invalid accessor"); 553e8d8bef9SDimitry Andric assert(i < getStructNumFields() && "field index OOB"); 554e8d8bef9SDimitry Andric return ((StructData *)(char *)&Data)->Elts[getStructNumBases() + i]; 5550b57cec5SDimitry Andric } 5560b57cec5SDimitry Andric const APValue &getStructBase(unsigned i) const { 5570b57cec5SDimitry Andric return const_cast<APValue*>(this)->getStructBase(i); 5580b57cec5SDimitry Andric } 5590b57cec5SDimitry Andric const APValue &getStructField(unsigned i) const { 5600b57cec5SDimitry Andric return const_cast<APValue*>(this)->getStructField(i); 5610b57cec5SDimitry Andric } 5620b57cec5SDimitry Andric 5630b57cec5SDimitry Andric const FieldDecl *getUnionField() const { 5640b57cec5SDimitry Andric assert(isUnion() && "Invalid accessor"); 565e8d8bef9SDimitry Andric return ((const UnionData *)(const char *)&Data)->Field; 5660b57cec5SDimitry Andric } 5670b57cec5SDimitry Andric APValue &getUnionValue() { 5680b57cec5SDimitry Andric assert(isUnion() && "Invalid accessor"); 569e8d8bef9SDimitry Andric return *((UnionData *)(char *)&Data)->Value; 5700b57cec5SDimitry Andric } 5710b57cec5SDimitry Andric const APValue &getUnionValue() const { 5720b57cec5SDimitry Andric return const_cast<APValue*>(this)->getUnionValue(); 5730b57cec5SDimitry Andric } 5740b57cec5SDimitry Andric 5750b57cec5SDimitry Andric const ValueDecl *getMemberPointerDecl() const; 5760b57cec5SDimitry Andric bool isMemberPointerToDerivedMember() const; 5770b57cec5SDimitry Andric ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const; 5780b57cec5SDimitry Andric 5790b57cec5SDimitry Andric const AddrLabelExpr* getAddrLabelDiffLHS() const { 5800b57cec5SDimitry Andric assert(isAddrLabelDiff() && "Invalid accessor"); 581e8d8bef9SDimitry Andric return ((const AddrLabelDiffData *)(const char *)&Data)->LHSExpr; 5820b57cec5SDimitry Andric } 5830b57cec5SDimitry Andric const AddrLabelExpr* getAddrLabelDiffRHS() const { 5840b57cec5SDimitry Andric assert(isAddrLabelDiff() && "Invalid accessor"); 585e8d8bef9SDimitry Andric return ((const AddrLabelDiffData *)(const char *)&Data)->RHSExpr; 5860b57cec5SDimitry Andric } 5870b57cec5SDimitry Andric 5880b57cec5SDimitry Andric void setInt(APSInt I) { 5890b57cec5SDimitry Andric assert(isInt() && "Invalid accessor"); 590e8d8bef9SDimitry Andric *(APSInt *)(char *)&Data = std::move(I); 5910b57cec5SDimitry Andric } 5920b57cec5SDimitry Andric void setFloat(APFloat F) { 5930b57cec5SDimitry Andric assert(isFloat() && "Invalid accessor"); 594e8d8bef9SDimitry Andric *(APFloat *)(char *)&Data = std::move(F); 5950b57cec5SDimitry Andric } 5960b57cec5SDimitry Andric void setFixedPoint(APFixedPoint FX) { 5970b57cec5SDimitry Andric assert(isFixedPoint() && "Invalid accessor"); 598e8d8bef9SDimitry Andric *(APFixedPoint *)(char *)&Data = std::move(FX); 5990b57cec5SDimitry Andric } 6000b57cec5SDimitry Andric void setVector(const APValue *E, unsigned N) { 601e8d8bef9SDimitry Andric MutableArrayRef<APValue> InternalElts = setVectorUninit(N); 6020b57cec5SDimitry Andric for (unsigned i = 0; i != N; ++i) 603e8d8bef9SDimitry Andric InternalElts[i] = E[i]; 6040b57cec5SDimitry Andric } 6050b57cec5SDimitry Andric void setComplexInt(APSInt R, APSInt I) { 6060b57cec5SDimitry Andric assert(R.getBitWidth() == I.getBitWidth() && 6070b57cec5SDimitry Andric "Invalid complex int (type mismatch)."); 6080b57cec5SDimitry Andric assert(isComplexInt() && "Invalid accessor"); 609e8d8bef9SDimitry Andric ((ComplexAPSInt *)(char *)&Data)->Real = std::move(R); 610e8d8bef9SDimitry Andric ((ComplexAPSInt *)(char *)&Data)->Imag = std::move(I); 6110b57cec5SDimitry Andric } 6120b57cec5SDimitry Andric void setComplexFloat(APFloat R, APFloat I) { 6130b57cec5SDimitry Andric assert(&R.getSemantics() == &I.getSemantics() && 6140b57cec5SDimitry Andric "Invalid complex float (type mismatch)."); 6150b57cec5SDimitry Andric assert(isComplexFloat() && "Invalid accessor"); 616e8d8bef9SDimitry Andric ((ComplexAPFloat *)(char *)&Data)->Real = std::move(R); 617e8d8bef9SDimitry Andric ((ComplexAPFloat *)(char *)&Data)->Imag = std::move(I); 6180b57cec5SDimitry Andric } 6190b57cec5SDimitry Andric void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, 6200b57cec5SDimitry Andric bool IsNullPtr); 6210b57cec5SDimitry Andric void setLValue(LValueBase B, const CharUnits &O, 6220b57cec5SDimitry Andric ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd, 6230b57cec5SDimitry Andric bool IsNullPtr); 624e8d8bef9SDimitry Andric void setUnion(const FieldDecl *Field, const APValue &Value); 6250b57cec5SDimitry Andric void setAddrLabelDiff(const AddrLabelExpr* LHSExpr, 6260b57cec5SDimitry Andric const AddrLabelExpr* RHSExpr) { 627e8d8bef9SDimitry Andric ((AddrLabelDiffData *)(char *)&Data)->LHSExpr = LHSExpr; 628e8d8bef9SDimitry Andric ((AddrLabelDiffData *)(char *)&Data)->RHSExpr = RHSExpr; 6290b57cec5SDimitry Andric } 6300b57cec5SDimitry Andric 6310b57cec5SDimitry Andric private: 6320b57cec5SDimitry Andric void DestroyDataAndMakeUninit(); 6330b57cec5SDimitry Andric void MakeInt() { 6340b57cec5SDimitry Andric assert(isAbsent() && "Bad state change"); 635e8d8bef9SDimitry Andric new ((void *)&Data) APSInt(1); 6360b57cec5SDimitry Andric Kind = Int; 6370b57cec5SDimitry Andric } 6380b57cec5SDimitry Andric void MakeFloat() { 6390b57cec5SDimitry Andric assert(isAbsent() && "Bad state change"); 640e8d8bef9SDimitry Andric new ((void *)(char *)&Data) APFloat(0.0); 6410b57cec5SDimitry Andric Kind = Float; 6420b57cec5SDimitry Andric } 6430b57cec5SDimitry Andric void MakeFixedPoint(APFixedPoint &&FX) { 6440b57cec5SDimitry Andric assert(isAbsent() && "Bad state change"); 645e8d8bef9SDimitry Andric new ((void *)(char *)&Data) APFixedPoint(std::move(FX)); 6460b57cec5SDimitry Andric Kind = FixedPoint; 6470b57cec5SDimitry Andric } 6480b57cec5SDimitry Andric void MakeVector() { 6490b57cec5SDimitry Andric assert(isAbsent() && "Bad state change"); 650e8d8bef9SDimitry Andric new ((void *)(char *)&Data) Vec(); 6510b57cec5SDimitry Andric Kind = Vector; 6520b57cec5SDimitry Andric } 6530b57cec5SDimitry Andric void MakeComplexInt() { 6540b57cec5SDimitry Andric assert(isAbsent() && "Bad state change"); 655e8d8bef9SDimitry Andric new ((void *)(char *)&Data) ComplexAPSInt(); 6560b57cec5SDimitry Andric Kind = ComplexInt; 6570b57cec5SDimitry Andric } 6580b57cec5SDimitry Andric void MakeComplexFloat() { 6590b57cec5SDimitry Andric assert(isAbsent() && "Bad state change"); 660e8d8bef9SDimitry Andric new ((void *)(char *)&Data) ComplexAPFloat(); 6610b57cec5SDimitry Andric Kind = ComplexFloat; 6620b57cec5SDimitry Andric } 6630b57cec5SDimitry Andric void MakeLValue(); 6640b57cec5SDimitry Andric void MakeArray(unsigned InitElts, unsigned Size); 6650b57cec5SDimitry Andric void MakeStruct(unsigned B, unsigned M) { 6660b57cec5SDimitry Andric assert(isAbsent() && "Bad state change"); 667e8d8bef9SDimitry Andric new ((void *)(char *)&Data) StructData(B, M); 6680b57cec5SDimitry Andric Kind = Struct; 6690b57cec5SDimitry Andric } 6700b57cec5SDimitry Andric void MakeUnion() { 6710b57cec5SDimitry Andric assert(isAbsent() && "Bad state change"); 672e8d8bef9SDimitry Andric new ((void *)(char *)&Data) UnionData(); 6730b57cec5SDimitry Andric Kind = Union; 6740b57cec5SDimitry Andric } 6750b57cec5SDimitry Andric void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember, 6760b57cec5SDimitry Andric ArrayRef<const CXXRecordDecl*> Path); 6770b57cec5SDimitry Andric void MakeAddrLabelDiff() { 6780b57cec5SDimitry Andric assert(isAbsent() && "Bad state change"); 679e8d8bef9SDimitry Andric new ((void *)(char *)&Data) AddrLabelDiffData(); 6800b57cec5SDimitry Andric Kind = AddrLabelDiff; 6810b57cec5SDimitry Andric } 682e8d8bef9SDimitry Andric 683e8d8bef9SDimitry Andric private: 684e8d8bef9SDimitry Andric /// The following functions are used as part of initialization, during 685e8d8bef9SDimitry Andric /// deserialization and importing. Reserve the space so that it can be 686e8d8bef9SDimitry Andric /// filled in by those steps. 687e8d8bef9SDimitry Andric MutableArrayRef<APValue> setVectorUninit(unsigned N) { 688e8d8bef9SDimitry Andric assert(isVector() && "Invalid accessor"); 689e8d8bef9SDimitry Andric Vec *V = ((Vec *)(char *)&Data); 690e8d8bef9SDimitry Andric V->Elts = new APValue[N]; 691e8d8bef9SDimitry Andric V->NumElts = N; 692e8d8bef9SDimitry Andric return {V->Elts, V->NumElts}; 693e8d8bef9SDimitry Andric } 694e8d8bef9SDimitry Andric MutableArrayRef<LValuePathEntry> 695e8d8bef9SDimitry Andric setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size, 696e8d8bef9SDimitry Andric bool OnePastTheEnd, bool IsNullPtr); 697e8d8bef9SDimitry Andric MutableArrayRef<const CXXRecordDecl *> 698e8d8bef9SDimitry Andric setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember, 699e8d8bef9SDimitry Andric unsigned Size); 7000b57cec5SDimitry Andric }; 7010b57cec5SDimitry Andric 7020b57cec5SDimitry Andric } // end namespace clang. 7030b57cec5SDimitry Andric 7040b57cec5SDimitry Andric namespace llvm { 7050b57cec5SDimitry Andric template<> struct DenseMapInfo<clang::APValue::LValueBase> { 7060b57cec5SDimitry Andric static clang::APValue::LValueBase getEmptyKey(); 7070b57cec5SDimitry Andric static clang::APValue::LValueBase getTombstoneKey(); 7080b57cec5SDimitry Andric static unsigned getHashValue(const clang::APValue::LValueBase &Base); 7090b57cec5SDimitry Andric static bool isEqual(const clang::APValue::LValueBase &LHS, 7100b57cec5SDimitry Andric const clang::APValue::LValueBase &RHS); 7110b57cec5SDimitry Andric }; 7120b57cec5SDimitry Andric } 7130b57cec5SDimitry Andric 7140b57cec5SDimitry Andric #endif 715