123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file defines the APValue class.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_AST_APVALUE_H
- #define LLVM_CLANG_AST_APVALUE_H
- #include "clang/Basic/LLVM.h"
- #include "llvm/ADT/APFixedPoint.h"
- #include "llvm/ADT/APFloat.h"
- #include "llvm/ADT/APSInt.h"
- #include "llvm/ADT/FoldingSet.h"
- #include "llvm/ADT/PointerIntPair.h"
- #include "llvm/ADT/PointerUnion.h"
- #include "llvm/Support/AlignOf.h"
- namespace clang {
- namespace serialization {
- template <typename T> class BasicReaderBase;
- } // end namespace serialization
- class AddrLabelExpr;
- class ASTContext;
- class CharUnits;
- class CXXRecordDecl;
- class Decl;
- class DiagnosticBuilder;
- class Expr;
- class FieldDecl;
- struct PrintingPolicy;
- class Type;
- class ValueDecl;
- class QualType;
- /// Symbolic representation of typeid(T) for some type T.
- class TypeInfoLValue {
- const Type *T;
- public:
- TypeInfoLValue() : T() {}
- explicit TypeInfoLValue(const Type *T);
- const Type *getType() const { return T; }
- explicit operator bool() const { return T; }
- void *getOpaqueValue() { return const_cast<Type*>(T); }
- static TypeInfoLValue getFromOpaqueValue(void *Value) {
- TypeInfoLValue V;
- V.T = reinterpret_cast<const Type*>(Value);
- return V;
- }
- void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const;
- };
- /// Symbolic representation of a dynamic allocation.
- class DynamicAllocLValue {
- unsigned Index;
- public:
- DynamicAllocLValue() : Index(0) {}
- explicit DynamicAllocLValue(unsigned Index) : Index(Index + 1) {}
- unsigned getIndex() { return Index - 1; }
- explicit operator bool() const { return Index != 0; }
- void *getOpaqueValue() {
- return reinterpret_cast<void *>(static_cast<uintptr_t>(Index)
- << NumLowBitsAvailable);
- }
- static DynamicAllocLValue getFromOpaqueValue(void *Value) {
- DynamicAllocLValue V;
- V.Index = reinterpret_cast<uintptr_t>(Value) >> NumLowBitsAvailable;
- return V;
- }
- static unsigned getMaxIndex() {
- return (std::numeric_limits<unsigned>::max() >> NumLowBitsAvailable) - 1;
- }
- static constexpr int NumLowBitsAvailable = 3;
- };
- }
- namespace llvm {
- template<> struct PointerLikeTypeTraits<clang::TypeInfoLValue> {
- static void *getAsVoidPointer(clang::TypeInfoLValue V) {
- return V.getOpaqueValue();
- }
- static clang::TypeInfoLValue getFromVoidPointer(void *P) {
- return clang::TypeInfoLValue::getFromOpaqueValue(P);
- }
- // Validated by static_assert in APValue.cpp; hardcoded to avoid needing
- // to include Type.h.
- static constexpr int NumLowBitsAvailable = 3;
- };
- template<> struct PointerLikeTypeTraits<clang::DynamicAllocLValue> {
- static void *getAsVoidPointer(clang::DynamicAllocLValue V) {
- return V.getOpaqueValue();
- }
- static clang::DynamicAllocLValue getFromVoidPointer(void *P) {
- return clang::DynamicAllocLValue::getFromOpaqueValue(P);
- }
- static constexpr int NumLowBitsAvailable =
- clang::DynamicAllocLValue::NumLowBitsAvailable;
- };
- }
- namespace clang {
- /// APValue - This class implements a discriminated union of [uninitialized]
- /// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
- /// [Vector: N * APValue], [Array: N * APValue]
- class APValue {
- typedef llvm::APFixedPoint APFixedPoint;
- typedef llvm::APSInt APSInt;
- typedef llvm::APFloat APFloat;
- public:
- enum ValueKind {
- /// There is no such object (it's outside its lifetime).
- None,
- /// This object has an indeterminate value (C++ [basic.indet]).
- Indeterminate,
- Int,
- Float,
- FixedPoint,
- ComplexInt,
- ComplexFloat,
- LValue,
- Vector,
- Array,
- Struct,
- Union,
- MemberPointer,
- AddrLabelDiff
- };
- class LValueBase {
- typedef llvm::PointerUnion<const ValueDecl *, const Expr *, TypeInfoLValue,
- DynamicAllocLValue>
- PtrTy;
- public:
- LValueBase() : Local{} {}
- LValueBase(const ValueDecl *P, unsigned I = 0, unsigned V = 0);
- LValueBase(const Expr *P, unsigned I = 0, unsigned V = 0);
- static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type);
- static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo);
- void Profile(llvm::FoldingSetNodeID &ID) const;
- template <class T>
- bool is() const { return Ptr.is<T>(); }
- template <class T>
- T get() const { return Ptr.get<T>(); }
- template <class T>
- T dyn_cast() const { return Ptr.dyn_cast<T>(); }
- void *getOpaqueValue() const;
- bool isNull() const;
- explicit operator bool() const;
- unsigned getCallIndex() const;
- unsigned getVersion() const;
- QualType getTypeInfoType() const;
- QualType getDynamicAllocType() const;
- QualType getType() const;
- friend bool operator==(const LValueBase &LHS, const LValueBase &RHS);
- friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) {
- return !(LHS == RHS);
- }
- friend llvm::hash_code hash_value(const LValueBase &Base);
- friend struct llvm::DenseMapInfo<LValueBase>;
- private:
- PtrTy Ptr;
- struct LocalState {
- unsigned CallIndex, Version;
- };
- union {
- LocalState Local;
- /// The type std::type_info, if this is a TypeInfoLValue.
- void *TypeInfoType;
- /// The QualType, if this is a DynamicAllocLValue.
- void *DynamicAllocType;
- };
- };
- /// A FieldDecl or CXXRecordDecl, along with a flag indicating whether we
- /// mean a virtual or non-virtual base class subobject.
- typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
- /// A non-discriminated union of a base, field, or array index.
- class LValuePathEntry {
- static_assert(sizeof(uintptr_t) <= sizeof(uint64_t),
- "pointer doesn't fit in 64 bits?");
- uint64_t Value;
- public:
- LValuePathEntry() : Value() {}
- LValuePathEntry(BaseOrMemberType BaseOrMember);
- static LValuePathEntry ArrayIndex(uint64_t Index) {
- LValuePathEntry Result;
- Result.Value = Index;
- return Result;
- }
- BaseOrMemberType getAsBaseOrMember() const {
- return BaseOrMemberType::getFromOpaqueValue(
- reinterpret_cast<void *>(Value));
- }
- uint64_t getAsArrayIndex() const { return Value; }
- void Profile(llvm::FoldingSetNodeID &ID) const;
- friend bool operator==(LValuePathEntry A, LValuePathEntry B) {
- return A.Value == B.Value;
- }
- friend bool operator!=(LValuePathEntry A, LValuePathEntry B) {
- return A.Value != B.Value;
- }
- friend llvm::hash_code hash_value(LValuePathEntry A) {
- return llvm::hash_value(A.Value);
- }
- };
- class LValuePathSerializationHelper {
- const void *ElemTy;
- public:
- ArrayRef<LValuePathEntry> Path;
- LValuePathSerializationHelper(ArrayRef<LValuePathEntry>, QualType);
- QualType getType();
- };
- struct NoLValuePath {};
- struct UninitArray {};
- struct UninitStruct {};
- template <typename Impl> friend class clang::serialization::BasicReaderBase;
- friend class ASTImporter;
- friend class ASTNodeImporter;
- private:
- ValueKind Kind;
- struct ComplexAPSInt {
- APSInt Real, Imag;
- ComplexAPSInt() : Real(1), Imag(1) {}
- };
- struct ComplexAPFloat {
- APFloat Real, Imag;
- ComplexAPFloat() : Real(0.0), Imag(0.0) {}
- };
- struct LV;
- struct Vec {
- APValue *Elts;
- unsigned NumElts;
- Vec() : Elts(nullptr), NumElts(0) {}
- ~Vec() { delete[] Elts; }
- };
- struct Arr {
- APValue *Elts;
- unsigned NumElts, ArrSize;
- Arr(unsigned NumElts, unsigned ArrSize);
- ~Arr();
- };
- struct StructData {
- APValue *Elts;
- unsigned NumBases;
- unsigned NumFields;
- StructData(unsigned NumBases, unsigned NumFields);
- ~StructData();
- };
- struct UnionData {
- const FieldDecl *Field;
- APValue *Value;
- UnionData();
- ~UnionData();
- };
- struct AddrLabelDiffData {
- const AddrLabelExpr* LHSExpr;
- const AddrLabelExpr* RHSExpr;
- };
- struct MemberPointerData;
- // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
- typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
- ComplexAPFloat, Vec, Arr, StructData,
- UnionData, AddrLabelDiffData> DataType;
- static const size_t DataSize = sizeof(DataType);
- DataType Data;
- public:
- APValue() : Kind(None) {}
- explicit APValue(APSInt I) : Kind(None) {
- MakeInt(); setInt(std::move(I));
- }
- explicit APValue(APFloat F) : Kind(None) {
- MakeFloat(); setFloat(std::move(F));
- }
- explicit APValue(APFixedPoint FX) : Kind(None) {
- MakeFixedPoint(std::move(FX));
- }
- explicit APValue(const APValue *E, unsigned N) : Kind(None) {
- MakeVector(); setVector(E, N);
- }
- APValue(APSInt R, APSInt I) : Kind(None) {
- MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
- }
- APValue(APFloat R, APFloat I) : Kind(None) {
- MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
- }
- APValue(const APValue &RHS);
- APValue(APValue &&RHS);
- APValue(LValueBase B, const CharUnits &O, NoLValuePath N,
- bool IsNullPtr = false)
- : Kind(None) {
- MakeLValue(); setLValue(B, O, N, IsNullPtr);
- }
- APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
- bool OnePastTheEnd, bool IsNullPtr = false)
- : Kind(None) {
- MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
- }
- APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(None) {
- MakeArray(InitElts, Size);
- }
- APValue(UninitStruct, unsigned B, unsigned M) : Kind(None) {
- MakeStruct(B, M);
- }
- explicit APValue(const FieldDecl *D, const APValue &V = APValue())
- : Kind(None) {
- MakeUnion(); setUnion(D, V);
- }
- APValue(const ValueDecl *Member, bool IsDerivedMember,
- ArrayRef<const CXXRecordDecl*> Path) : Kind(None) {
- MakeMemberPointer(Member, IsDerivedMember, Path);
- }
- APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
- : Kind(None) {
- MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
- }
- static APValue IndeterminateValue() {
- APValue Result;
- Result.Kind = Indeterminate;
- return Result;
- }
- APValue &operator=(const APValue &RHS);
- APValue &operator=(APValue &&RHS);
- ~APValue() {
- if (Kind != None && Kind != Indeterminate)
- DestroyDataAndMakeUninit();
- }
- /// Returns whether the object performed allocations.
- ///
- /// If APValues are constructed via placement new, \c needsCleanup()
- /// indicates whether the destructor must be called in order to correctly
- /// free all allocated memory.
- bool needsCleanup() const;
- /// Swaps the contents of this and the given APValue.
- void swap(APValue &RHS);
- /// profile this value. There is no guarantee that values of different
- /// types will not produce the same profiled value, so the type should
- /// typically also be profiled if it's not implied by the context.
- void Profile(llvm::FoldingSetNodeID &ID) const;
- ValueKind getKind() const { return Kind; }
- bool isAbsent() const { return Kind == None; }
- bool isIndeterminate() const { return Kind == Indeterminate; }
- bool hasValue() const { return Kind != None && Kind != Indeterminate; }
- bool isInt() const { return Kind == Int; }
- bool isFloat() const { return Kind == Float; }
- bool isFixedPoint() const { return Kind == FixedPoint; }
- bool isComplexInt() const { return Kind == ComplexInt; }
- bool isComplexFloat() const { return Kind == ComplexFloat; }
- bool isLValue() const { return Kind == LValue; }
- bool isVector() const { return Kind == Vector; }
- bool isArray() const { return Kind == Array; }
- bool isStruct() const { return Kind == Struct; }
- bool isUnion() const { return Kind == Union; }
- bool isMemberPointer() const { return Kind == MemberPointer; }
- bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
- void dump() const;
- void dump(raw_ostream &OS, const ASTContext &Context) const;
- void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const;
- void printPretty(raw_ostream &OS, const PrintingPolicy &Policy, QualType Ty,
- const ASTContext *Ctx = nullptr) const;
- std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
- APSInt &getInt() {
- assert(isInt() && "Invalid accessor");
- return *(APSInt *)(char *)&Data;
- }
- const APSInt &getInt() const {
- return const_cast<APValue*>(this)->getInt();
- }
- /// Try to convert this value to an integral constant. This works if it's an
- /// integer, null pointer, or offset from a null pointer. Returns true on
- /// success.
- bool toIntegralConstant(APSInt &Result, QualType SrcTy,
- const ASTContext &Ctx) const;
- APFloat &getFloat() {
- assert(isFloat() && "Invalid accessor");
- return *(APFloat *)(char *)&Data;
- }
- const APFloat &getFloat() const {
- return const_cast<APValue*>(this)->getFloat();
- }
- APFixedPoint &getFixedPoint() {
- assert(isFixedPoint() && "Invalid accessor");
- return *(APFixedPoint *)(char *)&Data;
- }
- const APFixedPoint &getFixedPoint() const {
- return const_cast<APValue *>(this)->getFixedPoint();
- }
- APSInt &getComplexIntReal() {
- assert(isComplexInt() && "Invalid accessor");
- return ((ComplexAPSInt *)(char *)&Data)->Real;
- }
- const APSInt &getComplexIntReal() const {
- return const_cast<APValue*>(this)->getComplexIntReal();
- }
- APSInt &getComplexIntImag() {
- assert(isComplexInt() && "Invalid accessor");
- return ((ComplexAPSInt *)(char *)&Data)->Imag;
- }
- const APSInt &getComplexIntImag() const {
- return const_cast<APValue*>(this)->getComplexIntImag();
- }
- APFloat &getComplexFloatReal() {
- assert(isComplexFloat() && "Invalid accessor");
- return ((ComplexAPFloat *)(char *)&Data)->Real;
- }
- const APFloat &getComplexFloatReal() const {
- return const_cast<APValue*>(this)->getComplexFloatReal();
- }
- APFloat &getComplexFloatImag() {
- assert(isComplexFloat() && "Invalid accessor");
- return ((ComplexAPFloat *)(char *)&Data)->Imag;
- }
- const APFloat &getComplexFloatImag() const {
- return const_cast<APValue*>(this)->getComplexFloatImag();
- }
- const LValueBase getLValueBase() const;
- CharUnits &getLValueOffset();
- const CharUnits &getLValueOffset() const {
- return const_cast<APValue*>(this)->getLValueOffset();
- }
- bool isLValueOnePastTheEnd() const;
- bool hasLValuePath() const;
- ArrayRef<LValuePathEntry> getLValuePath() const;
- unsigned getLValueCallIndex() const;
- unsigned getLValueVersion() const;
- bool isNullPointer() const;
- APValue &getVectorElt(unsigned I) {
- assert(isVector() && "Invalid accessor");
- assert(I < getVectorLength() && "Index out of range");
- return ((Vec *)(char *)&Data)->Elts[I];
- }
- const APValue &getVectorElt(unsigned I) const {
- return const_cast<APValue*>(this)->getVectorElt(I);
- }
- unsigned getVectorLength() const {
- assert(isVector() && "Invalid accessor");
- return ((const Vec *)(const void *)&Data)->NumElts;
- }
- APValue &getArrayInitializedElt(unsigned I) {
- assert(isArray() && "Invalid accessor");
- assert(I < getArrayInitializedElts() && "Index out of range");
- return ((Arr *)(char *)&Data)->Elts[I];
- }
- const APValue &getArrayInitializedElt(unsigned I) const {
- return const_cast<APValue*>(this)->getArrayInitializedElt(I);
- }
- bool hasArrayFiller() const {
- return getArrayInitializedElts() != getArraySize();
- }
- APValue &getArrayFiller() {
- assert(isArray() && "Invalid accessor");
- assert(hasArrayFiller() && "No array filler");
- return ((Arr *)(char *)&Data)->Elts[getArrayInitializedElts()];
- }
- const APValue &getArrayFiller() const {
- return const_cast<APValue*>(this)->getArrayFiller();
- }
- unsigned getArrayInitializedElts() const {
- assert(isArray() && "Invalid accessor");
- return ((const Arr *)(const void *)&Data)->NumElts;
- }
- unsigned getArraySize() const {
- assert(isArray() && "Invalid accessor");
- return ((const Arr *)(const void *)&Data)->ArrSize;
- }
- unsigned getStructNumBases() const {
- assert(isStruct() && "Invalid accessor");
- return ((const StructData *)(const char *)&Data)->NumBases;
- }
- unsigned getStructNumFields() const {
- assert(isStruct() && "Invalid accessor");
- return ((const StructData *)(const char *)&Data)->NumFields;
- }
- APValue &getStructBase(unsigned i) {
- assert(isStruct() && "Invalid accessor");
- assert(i < getStructNumBases() && "base class index OOB");
- return ((StructData *)(char *)&Data)->Elts[i];
- }
- APValue &getStructField(unsigned i) {
- assert(isStruct() && "Invalid accessor");
- assert(i < getStructNumFields() && "field index OOB");
- return ((StructData *)(char *)&Data)->Elts[getStructNumBases() + i];
- }
- const APValue &getStructBase(unsigned i) const {
- return const_cast<APValue*>(this)->getStructBase(i);
- }
- const APValue &getStructField(unsigned i) const {
- return const_cast<APValue*>(this)->getStructField(i);
- }
- const FieldDecl *getUnionField() const {
- assert(isUnion() && "Invalid accessor");
- return ((const UnionData *)(const char *)&Data)->Field;
- }
- APValue &getUnionValue() {
- assert(isUnion() && "Invalid accessor");
- return *((UnionData *)(char *)&Data)->Value;
- }
- const APValue &getUnionValue() const {
- return const_cast<APValue*>(this)->getUnionValue();
- }
- const ValueDecl *getMemberPointerDecl() const;
- bool isMemberPointerToDerivedMember() const;
- ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
- const AddrLabelExpr* getAddrLabelDiffLHS() const {
- assert(isAddrLabelDiff() && "Invalid accessor");
- return ((const AddrLabelDiffData *)(const char *)&Data)->LHSExpr;
- }
- const AddrLabelExpr* getAddrLabelDiffRHS() const {
- assert(isAddrLabelDiff() && "Invalid accessor");
- return ((const AddrLabelDiffData *)(const char *)&Data)->RHSExpr;
- }
- void setInt(APSInt I) {
- assert(isInt() && "Invalid accessor");
- *(APSInt *)(char *)&Data = std::move(I);
- }
- void setFloat(APFloat F) {
- assert(isFloat() && "Invalid accessor");
- *(APFloat *)(char *)&Data = std::move(F);
- }
- void setFixedPoint(APFixedPoint FX) {
- assert(isFixedPoint() && "Invalid accessor");
- *(APFixedPoint *)(char *)&Data = std::move(FX);
- }
- void setVector(const APValue *E, unsigned N) {
- MutableArrayRef<APValue> InternalElts = setVectorUninit(N);
- for (unsigned i = 0; i != N; ++i)
- InternalElts[i] = E[i];
- }
- void setComplexInt(APSInt R, APSInt I) {
- assert(R.getBitWidth() == I.getBitWidth() &&
- "Invalid complex int (type mismatch).");
- assert(isComplexInt() && "Invalid accessor");
- ((ComplexAPSInt *)(char *)&Data)->Real = std::move(R);
- ((ComplexAPSInt *)(char *)&Data)->Imag = std::move(I);
- }
- void setComplexFloat(APFloat R, APFloat I) {
- assert(&R.getSemantics() == &I.getSemantics() &&
- "Invalid complex float (type mismatch).");
- assert(isComplexFloat() && "Invalid accessor");
- ((ComplexAPFloat *)(char *)&Data)->Real = std::move(R);
- ((ComplexAPFloat *)(char *)&Data)->Imag = std::move(I);
- }
- void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
- bool IsNullPtr);
- void setLValue(LValueBase B, const CharUnits &O,
- ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
- bool IsNullPtr);
- void setUnion(const FieldDecl *Field, const APValue &Value);
- void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
- const AddrLabelExpr* RHSExpr) {
- ((AddrLabelDiffData *)(char *)&Data)->LHSExpr = LHSExpr;
- ((AddrLabelDiffData *)(char *)&Data)->RHSExpr = RHSExpr;
- }
- private:
- void DestroyDataAndMakeUninit();
- void MakeInt() {
- assert(isAbsent() && "Bad state change");
- new ((void *)&Data) APSInt(1);
- Kind = Int;
- }
- void MakeFloat() {
- assert(isAbsent() && "Bad state change");
- new ((void *)(char *)&Data) APFloat(0.0);
- Kind = Float;
- }
- void MakeFixedPoint(APFixedPoint &&FX) {
- assert(isAbsent() && "Bad state change");
- new ((void *)(char *)&Data) APFixedPoint(std::move(FX));
- Kind = FixedPoint;
- }
- void MakeVector() {
- assert(isAbsent() && "Bad state change");
- new ((void *)(char *)&Data) Vec();
- Kind = Vector;
- }
- void MakeComplexInt() {
- assert(isAbsent() && "Bad state change");
- new ((void *)(char *)&Data) ComplexAPSInt();
- Kind = ComplexInt;
- }
- void MakeComplexFloat() {
- assert(isAbsent() && "Bad state change");
- new ((void *)(char *)&Data) ComplexAPFloat();
- Kind = ComplexFloat;
- }
- void MakeLValue();
- void MakeArray(unsigned InitElts, unsigned Size);
- void MakeStruct(unsigned B, unsigned M) {
- assert(isAbsent() && "Bad state change");
- new ((void *)(char *)&Data) StructData(B, M);
- Kind = Struct;
- }
- void MakeUnion() {
- assert(isAbsent() && "Bad state change");
- new ((void *)(char *)&Data) UnionData();
- Kind = Union;
- }
- void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
- ArrayRef<const CXXRecordDecl*> Path);
- void MakeAddrLabelDiff() {
- assert(isAbsent() && "Bad state change");
- new ((void *)(char *)&Data) AddrLabelDiffData();
- Kind = AddrLabelDiff;
- }
- private:
- /// The following functions are used as part of initialization, during
- /// deserialization and importing. Reserve the space so that it can be
- /// filled in by those steps.
- MutableArrayRef<APValue> setVectorUninit(unsigned N) {
- assert(isVector() && "Invalid accessor");
- Vec *V = ((Vec *)(char *)&Data);
- V->Elts = new APValue[N];
- V->NumElts = N;
- return {V->Elts, V->NumElts};
- }
- MutableArrayRef<LValuePathEntry>
- setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size,
- bool OnePastTheEnd, bool IsNullPtr);
- MutableArrayRef<const CXXRecordDecl *>
- setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember,
- unsigned Size);
- };
- } // end namespace clang.
- namespace llvm {
- template<> struct DenseMapInfo<clang::APValue::LValueBase> {
- static clang::APValue::LValueBase getEmptyKey();
- static clang::APValue::LValueBase getTombstoneKey();
- static unsigned getHashValue(const clang::APValue::LValueBase &Base);
- static bool isEqual(const clang::APValue::LValueBase &LHS,
- const clang::APValue::LValueBase &RHS);
- };
- }
- #endif
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|