Go to the documentation of this file.
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"
26 namespace 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;
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?");
218 Result.Value = Index;
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;
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");
627 new ((
void *)&Data)
APSInt(1);
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,
697 template<>
struct DenseMapInfo<
clang::APValue::LValueBase> {
void setComplexInt(APSInt R, APSInt I)
static void * getAsVoidPointer(clang::DynamicAllocLValue V)
const APValue & getArrayFiller() const
__DEVICE__ int max(int __a, int __b)
const APSInt & getComplexIntReal() const
ValueKind getKind() const
const CharUnits & getLValueOffset() const
YAML serialization mapping.
CharUnits & getLValueOffset()
A little helper class used to produce diagnostics.
unsigned getCallIndex() const
bool isIndeterminate() const
const APValue & getStructField(unsigned i) const
APValue & operator=(const APValue &RHS)
unsigned getStructNumFields() const
QualType getTypeInfoType() const
ArrayRef< LValuePathEntry > getLValuePath() const
void setUnion(const FieldDecl *Field, const APValue &Value)
friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS)
bool isLValueOnePastTheEnd() const
APFixedPoint & getFixedPoint()
void setComplexFloat(APFloat R, APFloat I)
A (possibly-)qualified type.
APValue(const APValue *E, unsigned N)
Represents a member of a struct/union/class.
void * getOpaqueValue() const
APValue(UninitStruct, unsigned B, unsigned M)
bool needsCleanup() const
Returns whether the object performed allocations.
unsigned getArraySize() const
static clang::DynamicAllocLValue getFromVoidPointer(void *P)
QualType getDynamicAllocType() const
@ None
There is no such object (it's outside its lifetime).
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
friend bool operator!=(LValuePathEntry A, LValuePathEntry B)
Describes how types, statements, expressions, and declarations should be printed.
static clang::TypeInfoLValue getFromVoidPointer(void *P)
static APValue IndeterminateValue()
static void * getAsVoidPointer(clang::TypeInfoLValue V)
bool isAddrLabelDiff() const
const ValueDecl * getMemberPointerDecl() const
The base class of the type hierarchy.
DynamicAllocLValue(unsigned Index)
llvm::hash_code hash_value(const clang::SanitizerMask &Arg)
uint64_t getAsArrayIndex() const
APFloat & getComplexFloatReal()
APValue(const FieldDecl *D, const APValue &V=APValue())
static constexpr int NumLowBitsAvailable
const APFloat & getComplexFloatImag() const
bool hasLValuePath() const
const Type * getType() const
const APFloat & getComplexFloatReal() const
LValuePathSerializationHelper(ArrayRef< LValuePathEntry >, QualType)
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const APValue & getUnionValue() const
bool isComplexInt() const
bool isComplexFloat() const
unsigned getStructNumBases() const
APValue & getStructBase(unsigned i)
friend bool operator==(const LValueBase &LHS, const LValueBase &RHS)
friend bool operator==(LValuePathEntry A, LValuePathEntry B)
APSInt & getComplexIntReal()
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
unsigned getLValueCallIndex() const
APValue(UninitArray, unsigned InitElts, unsigned Size)
APValue & getVectorElt(unsigned I)
const APValue & getArrayInitializedElt(unsigned I) const
const FieldDecl * getUnionField() const
MutableArrayRef< APValue::LValuePathEntry > setLValueUninit(APValue::LValueBase B, const CharUnits &O, unsigned Size, bool OnePastTheEnd, bool IsNullPtr)
bool hasArrayFiller() const
const APValue & getVectorElt(unsigned I) const
bool isFixedPoint() const
APValue & getArrayInitializedElt(unsigned I)
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
const APSInt & getInt() const
const APValue & getStructBase(unsigned i) const
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, bool IsNullPtr)
unsigned getLValueVersion() const
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
Imports selected nodes from one AST context into another context, merging AST nodes where appropriate...
void setFixedPoint(APFixedPoint FX)
APValue & getArrayFiller()
Represents a C++ struct/union/class.
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
void setAddrLabelDiff(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
void Profile(llvm::FoldingSetNodeID &ID) const
profile this value.
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Symbolic representation of a dynamic allocation.
void setVector(const APValue *E, unsigned N)
Decl - This represents one declaration (or definition), e.g.
const APSInt & getComplexIntImag() const
AddrLabelExpr - The GNU address of label extension, representing &&label.
const LValueBase getLValueBase() const
friend llvm::hash_code hash_value(LValuePathEntry A)
APValue & getStructField(unsigned i)
APValue & getUnionValue()
APValue(APFloat R, APFloat I)
Symbolic representation of typeid(T) for some type T.
APValue(APSInt R, APSInt I)
bool isNullPointer() const
bool isMemberPointer() const
APSInt & getComplexIntImag()
bool toIntegralConstant(APSInt &Result, QualType SrcTy, const ASTContext &Ctx) const
Try to convert this value to an integral constant.
const APFloat & getFloat() const
BaseOrMemberType getAsBaseOrMember() const
static LValuePathEntry ArrayIndex(uint64_t Index)
static unsigned getMaxIndex()
friend llvm::hash_code hash_value(const LValueBase &Base)
const AddrLabelExpr * getAddrLabelDiffRHS() const
void Profile(llvm::FoldingSetNodeID &ID) const
APFloat & getComplexFloatImag()
static TypeInfoLValue getFromOpaqueValue(void *Value)
void * TypeInfoType
The type std::type_info, if this is a TypeInfoLValue.
APValue(const ValueDecl *Member, bool IsDerivedMember, ArrayRef< const CXXRecordDecl * > Path)
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...
unsigned getVectorLength() const
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
ArrayRef< LValuePathEntry > Path
bool isMemberPointerToDerivedMember() const
const APFixedPoint & getFixedPoint() const
CharUnits - This is an opaque type for sizes expressed in character units.
static DynamicAllocLValue getFromOpaqueValue(void *Value)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
This represents one expression.
void * DynamicAllocType
The QualType, if this is a DynamicAllocLValue.
unsigned getArrayInitializedElts() const
unsigned getVersion() const
A non-discriminated union of a base, field, or array index.
APValue(LValueBase B, const CharUnits &O, NoLValuePath N, bool IsNullPtr=false)
void Profile(llvm::FoldingSetNodeID &ID) const
APValue(LValueBase B, const CharUnits &O, ArrayRef< LValuePathEntry > Path, bool OnePastTheEnd, bool IsNullPtr=false)
const AddrLabelExpr * getAddrLabelDiffLHS() const
APValue(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const