13#ifndef LLVM_CLANG_AST_APVALUE_H
14#define LLVM_CLANG_AST_APVALUE_H
17#include "llvm/ADT/APFixedPoint.h"
18#include "llvm/ADT/APFloat.h"
19#include "llvm/ADT/APSInt.h"
20#include "llvm/ADT/FoldingSet.h"
21#include "llvm/ADT/PointerIntPair.h"
22#include "llvm/ADT/PointerUnion.h"
23#include "llvm/Support/AlignOf.h"
26namespace serialization {
52 explicit operator bool()
const {
return T; }
73 explicit operator bool()
const {
return Index != 0; }
76 return reinterpret_cast<void *
>(
static_cast<uintptr_t>(Index)
96 return V.getOpaqueValue();
103 static constexpr int NumLowBitsAvailable = 3;
108 return V.getOpaqueValue();
113 static constexpr int NumLowBitsAvailable =
123 typedef llvm::APFixedPoint APFixedPoint;
124 typedef llvm::APSInt APSInt;
125 typedef llvm::APFloat APFloat;
158 void Profile(llvm::FoldingSetNodeID &ID)
const;
161 bool is()
const {
return Ptr.is<T>(); }
164 T
get()
const {
return Ptr.get<T>(); }
173 explicit operator bool()
const;
184 return !(LHS == RHS);
192 unsigned CallIndex, Version;
209 static_assert(
sizeof(
uintptr_t) <=
sizeof(uint64_t),
210 "pointer doesn't fit in 64 bits?");
223 return BaseOrMemberType::getFromOpaqueValue(
224 reinterpret_cast<void *
>(
Value));
228 void Profile(llvm::FoldingSetNodeID &ID)
const;
231 return A.Value == B.Value;
234 return A.Value != B.Value;
237 return llvm::hash_value(A.Value);
260 struct ComplexAPSInt {
262 ComplexAPSInt() : Real(1), Imag(1) {}
264 struct ComplexAPFloat {
266 ComplexAPFloat() : Real(0.0), Imag(0.0) {}
272 Vec() : Elts(nullptr), NumElts(0) {}
273 ~Vec() {
delete[] Elts; }
277 unsigned NumElts, ArrSize;
278 Arr(
unsigned NumElts,
unsigned ArrSize);
285 StructData(
unsigned NumBases,
unsigned NumFields);
289 const FieldDecl *
Field;
294 struct AddrLabelDiffData {
295 const AddrLabelExpr* LHSExpr;
296 const AddrLabelExpr* RHSExpr;
298 struct MemberPointerData;
301 typedef llvm::AlignedCharArrayUnion<
void *,
APSInt,
APFloat, ComplexAPSInt,
302 ComplexAPFloat, Vec, Arr, StructData,
303 UnionData, AddrLabelDiffData> DataType;
304 static const size_t DataSize =
sizeof(DataType);
311 MakeInt();
setInt(std::move(I));
314 MakeFloat();
setFloat(std::move(F));
317 MakeFixedPoint(std::move(FX));
331 bool IsNullPtr =
false)
333 MakeLValue();
setLValue(B, O, N, IsNullPtr);
336 bool OnePastTheEnd,
bool IsNullPtr =
false)
338 MakeLValue();
setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
341 MakeArray(InitElts, Size);
352 MakeMemberPointer(
Member, IsDerivedMember, Path);
369 DestroyDataAndMakeUninit();
385 void Profile(llvm::FoldingSetNodeID &ID)
const;
416 assert(
isInt() &&
"Invalid accessor");
417 return *(APSInt *)(
char *)&
Data;
430 assert(
isFloat() &&
"Invalid accessor");
431 return *(APFloat *)(
char *)&
Data;
439 return *(APFixedPoint *)(
char *)&
Data;
447 return ((ComplexAPSInt *)(
char *)&
Data)->Real;
455 return ((ComplexAPSInt *)(
char *)&
Data)->Imag;
463 return ((ComplexAPFloat *)(
char *)&
Data)->Real;
471 return ((ComplexAPFloat *)(
char *)&
Data)->Imag;
490 assert(
isVector() &&
"Invalid accessor");
492 return ((Vec *)(
char *)&
Data)->Elts[I];
498 assert(
isVector() &&
"Invalid accessor");
499 return ((
const Vec *)(
const void *)&
Data)->NumElts;
503 assert(
isArray() &&
"Invalid accessor");
505 return ((Arr *)(
char *)&
Data)->Elts[I];
514 assert(
isArray() &&
"Invalid accessor");
522 assert(
isArray() &&
"Invalid accessor");
523 return ((
const Arr *)(
const void *)&
Data)->NumElts;
526 assert(
isArray() &&
"Invalid accessor");
527 return ((
const Arr *)(
const void *)&
Data)->ArrSize;
531 assert(
isStruct() &&
"Invalid accessor");
532 return ((
const StructData *)(
const char *)&
Data)->NumBases;
535 assert(
isStruct() &&
"Invalid accessor");
536 return ((
const StructData *)(
const char *)&
Data)->NumFields;
539 assert(
isStruct() &&
"Invalid accessor");
541 return ((StructData *)(
char *)&
Data)->Elts[i];
544 assert(
isStruct() &&
"Invalid accessor");
556 assert(
isUnion() &&
"Invalid accessor");
557 return ((
const UnionData *)(
const char *)&
Data)->Field;
560 assert(
isUnion() &&
"Invalid accessor");
561 return *((UnionData *)(
char *)&
Data)->
Value;
573 return ((
const AddrLabelDiffData *)(
const char *)&
Data)->LHSExpr;
577 return ((
const AddrLabelDiffData *)(
const char *)&
Data)->RHSExpr;
581 assert(
isInt() &&
"Invalid accessor");
582 *(APSInt *)(
char *)&
Data = std::move(I);
585 assert(
isFloat() &&
"Invalid accessor");
586 *(APFloat *)(
char *)&
Data = std::move(F);
590 *(APFixedPoint *)(
char *)&
Data = std::move(FX);
594 for (
unsigned i = 0; i != N; ++i)
595 InternalElts[i] = E[i];
598 assert(R.getBitWidth() == I.getBitWidth() &&
599 "Invalid complex int (type mismatch).");
601 ((ComplexAPSInt *)(
char *)&
Data)->Real = std::move(R);
602 ((ComplexAPSInt *)(
char *)&
Data)->Imag = std::move(I);
605 assert(&R.getSemantics() == &I.getSemantics() &&
606 "Invalid complex float (type mismatch).");
608 ((ComplexAPFloat *)(
char *)&
Data)->Real = std::move(R);
609 ((ComplexAPFloat *)(
char *)&
Data)->Imag = std::move(I);
619 ((AddrLabelDiffData *)(
char *)&
Data)->LHSExpr = LHSExpr;
620 ((AddrLabelDiffData *)(
char *)&
Data)->RHSExpr = RHSExpr;
624 void DestroyDataAndMakeUninit();
626 assert(
isAbsent() &&
"Bad state change");
631 assert(
isAbsent() &&
"Bad state change");
632 new ((
void *)(
char *)&
Data) APFloat(0.0);
635 void MakeFixedPoint(APFixedPoint &&FX) {
636 assert(
isAbsent() &&
"Bad state change");
637 new ((
void *)(
char *)&
Data) APFixedPoint(std::move(FX));
641 assert(
isAbsent() &&
"Bad state change");
642 new ((
void *)(
char *)&
Data) Vec();
645 void MakeComplexInt() {
646 assert(
isAbsent() &&
"Bad state change");
647 new ((
void *)(
char *)&
Data) ComplexAPSInt();
650 void MakeComplexFloat() {
651 assert(
isAbsent() &&
"Bad state change");
652 new ((
void *)(
char *)&
Data) ComplexAPFloat();
656 void MakeArray(
unsigned InitElts,
unsigned Size);
657 void MakeStruct(
unsigned B,
unsigned M) {
658 assert(
isAbsent() &&
"Bad state change");
659 new ((
void *)(
char *)&
Data) StructData(B, M);
663 assert(
isAbsent() &&
"Bad state change");
664 new ((
void *)(
char *)&
Data) UnionData();
667 void MakeMemberPointer(
const ValueDecl *
Member,
bool IsDerivedMember,
668 ArrayRef<const CXXRecordDecl*> Path);
669 void MakeAddrLabelDiff() {
670 assert(
isAbsent() &&
"Bad state change");
671 new ((
void *)(
char *)&
Data) AddrLabelDiffData();
679 MutableArrayRef<APValue> setVectorUninit(
unsigned N) {
680 assert(
isVector() &&
"Invalid accessor");
681 Vec *
V = ((Vec *)(
char *)&
Data);
684 return {
V->Elts,
V->NumElts};
686 MutableArrayRef<LValuePathEntry>
688 bool OnePastTheEnd,
bool IsNullPtr);
689 MutableArrayRef<const CXXRecordDecl *>
690 setMemberPointerUninit(
const ValueDecl *
Member,
bool IsDerivedMember,
697template<>
struct DenseMapInfo<
clang::APValue::LValueBase> {
MutableArrayRef< APValue::LValuePathEntry > setLValueUninit(APValue::LValueBase B, const CharUnits &O, unsigned Size, bool OnePastTheEnd, bool IsNullPtr)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
friend llvm::hash_code hash_value(const LValueBase &Base)
friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS)
void Profile(llvm::FoldingSetNodeID &ID) const
unsigned getVersion() const
QualType getDynamicAllocType() const
QualType getTypeInfoType() const
friend bool operator==(const LValueBase &LHS, const LValueBase &RHS)
void * DynamicAllocType
The QualType, if this is a DynamicAllocLValue.
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
void * TypeInfoType
The type std::type_info, if this is a TypeInfoLValue.
void * getOpaqueValue() const
unsigned getCallIndex() const
A non-discriminated union of a base, field, or array index.
BaseOrMemberType getAsBaseOrMember() const
uint64_t getAsArrayIndex() const
friend llvm::hash_code hash_value(LValuePathEntry A)
friend bool operator!=(LValuePathEntry A, LValuePathEntry B)
static LValuePathEntry ArrayIndex(uint64_t Index)
friend bool operator==(LValuePathEntry A, LValuePathEntry B)
void Profile(llvm::FoldingSetNodeID &ID) const
ArrayRef< LValuePathEntry > Path
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
const APSInt & getComplexIntReal() const
APValue(LValueBase B, const CharUnits &O, ArrayRef< LValuePathEntry > Path, bool OnePastTheEnd, bool IsNullPtr=false)
APValue(UninitStruct, unsigned B, unsigned M)
bool hasArrayFiller() const
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
ArrayRef< LValuePathEntry > getLValuePath() const
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
APValue & getStructField(unsigned i)
const FieldDecl * getUnionField() const
const APFloat & getFloat() const
APSInt & getComplexIntImag()
unsigned getStructNumFields() const
APValue(LValueBase B, const CharUnits &O, NoLValuePath N, bool IsNullPtr=false)
const APValue & getArrayInitializedElt(unsigned I) const
APValue(APFloat R, APFloat I)
bool isComplexInt() const
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
A FieldDecl or CXXRecordDecl, along with a flag indicating whether we mean a virtual or non-virtual b...
ValueKind getKind() const
bool isLValueOnePastTheEnd() const
APValue(const APValue *E, unsigned N)
void setFixedPoint(APFixedPoint FX)
unsigned getLValueVersion() const
bool isMemberPointerToDerivedMember() const
unsigned getArrayInitializedElts() const
static APValue IndeterminateValue()
void setComplexInt(APSInt R, APSInt I)
const APFixedPoint & getFixedPoint() const
void Profile(llvm::FoldingSetNodeID &ID) const
profile this value.
unsigned getStructNumBases() const
APFixedPoint & getFixedPoint()
APValue(const ValueDecl *Member, bool IsDerivedMember, ArrayRef< const CXXRecordDecl * > Path)
bool needsCleanup() const
Returns whether the object performed allocations.
const APValue & getStructBase(unsigned i) const
bool hasLValuePath() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
const AddrLabelExpr * getAddrLabelDiffRHS() const
CharUnits & getLValueOffset()
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
void setAddrLabelDiff(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
void setComplexFloat(APFloat R, APFloat I)
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
APValue & getArrayFiller()
const APValue & getArrayFiller() const
const APFloat & getComplexFloatImag() const
unsigned getVectorLength() const
const APValue & getUnionValue() const
const APValue & getVectorElt(unsigned I) const
APValue(UninitArray, unsigned InitElts, unsigned Size)
void setUnion(const FieldDecl *Field, const APValue &Value)
APValue(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
bool isIndeterminate() const
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, bool IsNullPtr)
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
bool isMemberPointer() const
const APSInt & getInt() const
const APFloat & getComplexFloatReal() const
APValue(const FieldDecl *D, const APValue &V=APValue())
unsigned getArraySize() const
APValue(APSInt R, APSInt I)
bool toIntegralConstant(APSInt &Result, QualType SrcTy, const ASTContext &Ctx) const
Try to convert this value to an integral constant.
const CharUnits & getLValueOffset() const
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
bool isFixedPoint() const
APValue & operator=(const APValue &RHS)
unsigned getLValueCallIndex() const
void setVector(const APValue *E, unsigned N)
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
const APValue & getStructField(unsigned i) const
const APSInt & getComplexIntImag() const
bool isNullPointer() const
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
APValue & getStructBase(unsigned i)
const AddrLabelExpr * getAddrLabelDiffLHS() const
bool isAddrLabelDiff() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Imports selected nodes from one AST context into another context, merging AST nodes where appropriate...
AddrLabelExpr - The GNU address of label extension, representing &&label.
Represents a C++ struct/union/class.
CharUnits - This is an opaque type for sizes expressed in character units.
Decl - This represents one declaration (or definition), e.g.
A little helper class used to produce diagnostics.
Symbolic representation of a dynamic allocation.
static unsigned getMaxIndex()
static constexpr int NumLowBitsAvailable
DynamicAllocLValue(unsigned Index)
static DynamicAllocLValue getFromOpaqueValue(void *Value)
This represents one expression.
Represents a member of a struct/union/class.
A (possibly-)qualified type.
Symbolic representation of typeid(T) for some type T.
const Type * getType() const
static TypeInfoLValue getFromOpaqueValue(void *Value)
void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const
The base class of the type hierarchy.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
@ Result
The result type of a method or function.
YAML serialization mapping.
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
Describes how types, statements, expressions, and declarations should be printed.
static void * getAsVoidPointer(clang::DynamicAllocLValue V)
static clang::DynamicAllocLValue getFromVoidPointer(void *P)
static void * getAsVoidPointer(clang::TypeInfoLValue V)
static clang::TypeInfoLValue getFromVoidPointer(void *P)