13 #ifndef LLVM_CLANG_AST_APVALUE_H 14 #define LLVM_CLANG_AST_APVALUE_H 18 #include "llvm/ADT/APFloat.h" 19 #include "llvm/ADT/APSInt.h" 20 #include "llvm/ADT/PointerIntPair.h" 21 #include "llvm/ADT/PointerUnion.h" 29 class DiagnosticBuilder;
32 struct PrintingPolicy;
45 explicit operator bool()
const {
return T; }
50 V.T =
reinterpret_cast<const Type*
>(
Value);
66 explicit operator bool()
const {
return Index != 0; }
69 return reinterpret_cast<void *
>(
static_cast<uintptr_t>(Index)
70 << NumLowBitsAvailable);
74 V.Index =
reinterpret_cast<uintptr_t>(
Value) >> NumLowBitsAvailable;
82 static constexpr
int NumLowBitsAvailable = 3;
96 static constexpr
int NumLowBitsAvailable = 3;
106 static constexpr
int NumLowBitsAvailable =
117 typedef llvm::APFloat APFloat;
145 LValueBase(
const ValueDecl *
P,
unsigned I = 0,
unsigned V = 0);
146 LValueBase(
const Expr *P,
unsigned I = 0,
unsigned V = 0);
151 bool is()
const {
return Ptr.is<T>(); }
154 T
get()
const {
return Ptr.get<T>(); }
163 explicit operator bool()
const;
165 unsigned getCallIndex()
const;
166 unsigned getVersion()
const;
168 QualType getDynamicAllocType()
const;
172 return !(LHS == RHS);
179 unsigned CallIndex, Version;
196 static_assert(
sizeof(
uintptr_t) <=
sizeof(uint64_t),
197 "pointer doesn't fit in 64 bits?");
203 : Value{
reinterpret_cast<uintptr_t>(BaseOrMember.getOpaqueValue())} {}
206 Result.Value = Index;
211 return BaseOrMemberType::getFromOpaqueValue(
212 reinterpret_cast<void *>(Value));
217 return A.Value == B.Value;
220 return A.Value != B.Value;
236 struct ComplexAPSInt {
238 ComplexAPSInt() : Real(1), Imag(1) {}
240 struct ComplexAPFloat {
242 ComplexAPFloat() : Real(0.0), Imag(0.0) {}
248 Vec() : Elts(nullptr), NumElts(0) {}
249 ~Vec() {
delete[] Elts; }
253 unsigned NumElts, ArrSize;
254 Arr(
unsigned NumElts,
unsigned ArrSize);
261 StructData(
unsigned NumBases,
unsigned NumFields);
270 struct AddrLabelDiffData {
277 typedef llvm::AlignedCharArrayUnion<
void *,
APSInt, APFloat, ComplexAPSInt,
278 ComplexAPFloat, Vec, Arr, StructData,
279 UnionData, AddrLabelDiffData> DataType;
280 static const size_t DataSize =
sizeof(DataType);
287 MakeInt(); setInt(std::move(I));
290 MakeFloat(); setFloat(std::move(F));
293 MakeFixedPoint(std::move(FX));
296 MakeVector(); setVector(E, N);
299 MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
302 MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
307 bool IsNullPtr =
false)
309 MakeLValue(); setLValue(B, O, N, IsNullPtr);
312 bool OnePastTheEnd,
bool IsNullPtr =
false)
314 MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
317 MakeArray(InitElts, Size);
324 MakeUnion(); setUnion(D,
V);
328 MakeMemberPointer(Member, IsDerivedMember, Path);
332 MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
336 Result.Kind = Indeterminate;
341 if (Kind !=
None && Kind != Indeterminate)
342 DestroyDataAndMakeUninit();
350 bool needsCleanup()
const;
359 bool hasValue()
const {
return Kind !=
None && Kind != Indeterminate; }
361 bool isInt()
const {
return Kind == Int; }
362 bool isFloat()
const {
return Kind == Float; }
368 bool isArray()
const {
return Kind == Array; }
375 void dump(raw_ostream &OS)
const;
381 assert(isInt() &&
"Invalid accessor");
382 return *(APSInt*)(
char*)Data.buffer;
385 return const_cast<APValue*
>(
this)->getInt();
395 assert(isFloat() &&
"Invalid accessor");
396 return *(APFloat*)(
char*)Data.buffer;
399 return const_cast<APValue*
>(
this)->getFloat();
403 assert(isFixedPoint() &&
"Invalid accessor");
407 return const_cast<APValue *
>(
this)->getFixedPoint();
411 assert(isComplexInt() &&
"Invalid accessor");
412 return ((ComplexAPSInt*)(
char*)Data.buffer)->Real;
415 return const_cast<APValue*
>(
this)->getComplexIntReal();
419 assert(isComplexInt() &&
"Invalid accessor");
420 return ((ComplexAPSInt*)(
char*)Data.buffer)->Imag;
423 return const_cast<APValue*
>(
this)->getComplexIntImag();
427 assert(isComplexFloat() &&
"Invalid accessor");
428 return ((ComplexAPFloat*)(
char*)Data.buffer)->Real;
431 return const_cast<APValue*
>(
this)->getComplexFloatReal();
435 assert(isComplexFloat() &&
"Invalid accessor");
436 return ((ComplexAPFloat*)(
char*)Data.buffer)->Imag;
439 return const_cast<APValue*
>(
this)->getComplexFloatImag();
445 return const_cast<APValue*
>(
this)->getLValueOffset();
447 bool isLValueOnePastTheEnd()
const;
448 bool hasLValuePath()
const;
450 unsigned getLValueCallIndex()
const;
451 unsigned getLValueVersion()
const;
452 bool isNullPointer()
const;
455 assert(
isVector() &&
"Invalid accessor");
456 assert(I < getVectorLength() &&
"Index out of range");
457 return ((Vec*)(
char*)Data.buffer)->Elts[I];
460 return const_cast<APValue*
>(
this)->getVectorElt(I);
463 assert(
isVector() &&
"Invalid accessor");
464 return ((
const Vec*)(
const void *)Data.buffer)->NumElts;
468 assert(isArray() &&
"Invalid accessor");
469 assert(I < getArrayInitializedElts() &&
"Index out of range");
470 return ((Arr*)(
char*)Data.buffer)->Elts[I];
473 return const_cast<APValue*
>(
this)->getArrayInitializedElt(I);
476 return getArrayInitializedElts() != getArraySize();
479 assert(isArray() &&
"Invalid accessor");
480 assert(hasArrayFiller() &&
"No array filler");
481 return ((Arr*)(
char*)Data.buffer)->Elts[getArrayInitializedElts()];
484 return const_cast<APValue*
>(
this)->getArrayFiller();
487 assert(isArray() &&
"Invalid accessor");
488 return ((
const Arr*)(
const void *)Data.buffer)->NumElts;
491 assert(isArray() &&
"Invalid accessor");
492 return ((
const Arr*)(
const void *)Data.buffer)->ArrSize;
496 assert(isStruct() &&
"Invalid accessor");
497 return ((
const StructData*)(
const char*)Data.buffer)->NumBases;
500 assert(isStruct() &&
"Invalid accessor");
501 return ((
const StructData*)(
const char*)Data.buffer)->NumFields;
504 assert(isStruct() &&
"Invalid accessor");
505 return ((StructData*)(
char*)Data.buffer)->Elts[i];
508 assert(isStruct() &&
"Invalid accessor");
509 return ((StructData*)(
char*)Data.buffer)->Elts[getStructNumBases() + i];
512 return const_cast<APValue*
>(
this)->getStructBase(i);
515 return const_cast<APValue*
>(
this)->getStructField(i);
519 assert(isUnion() &&
"Invalid accessor");
520 return ((
const UnionData*)(
const char*)Data.buffer)->Field;
523 assert(isUnion() &&
"Invalid accessor");
524 return *((UnionData*)(
char*)Data.buffer)->
Value;
527 return const_cast<APValue*
>(
this)->getUnionValue();
530 const ValueDecl *getMemberPointerDecl()
const;
531 bool isMemberPointerToDerivedMember()
const;
535 assert(isAddrLabelDiff() &&
"Invalid accessor");
536 return ((
const AddrLabelDiffData*)(
const char*)Data.buffer)->LHSExpr;
539 assert(isAddrLabelDiff() &&
"Invalid accessor");
540 return ((
const AddrLabelDiffData*)(
const char*)Data.buffer)->RHSExpr;
544 assert(isInt() &&
"Invalid accessor");
545 *(APSInt *)(
char *)Data.buffer = std::move(I);
548 assert(isFloat() &&
"Invalid accessor");
549 *(APFloat *)(
char *)Data.buffer = std::move(F);
552 assert(isFixedPoint() &&
"Invalid accessor");
556 assert(
isVector() &&
"Invalid accessor");
557 ((Vec*)(
char*)Data.buffer)->Elts =
new APValue[N];
558 ((Vec*)(
char*)Data.buffer)->NumElts = N;
559 for (
unsigned i = 0; i != N; ++i)
560 ((Vec*)(
char*)Data.buffer)->Elts[i] = E[i];
563 assert(R.getBitWidth() == I.getBitWidth() &&
564 "Invalid complex int (type mismatch).");
565 assert(isComplexInt() &&
"Invalid accessor");
566 ((ComplexAPSInt *)(
char *)Data.buffer)->Real = std::move(R);
567 ((ComplexAPSInt *)(
char *)Data.buffer)->Imag = std::move(I);
570 assert(&R.getSemantics() == &I.getSemantics() &&
571 "Invalid complex float (type mismatch).");
572 assert(isComplexFloat() &&
"Invalid accessor");
573 ((ComplexAPFloat *)(
char *)Data.buffer)->Real = std::move(R);
574 ((ComplexAPFloat *)(
char *)Data.buffer)->Imag = std::move(I);
582 assert(isUnion() &&
"Invalid accessor");
583 ((UnionData*)(
char*)Data.buffer)->Field = Field;
584 *((UnionData*)(
char*)Data.buffer)->Value = Value;
588 ((AddrLabelDiffData*)(
char*)Data.buffer)->LHSExpr = LHSExpr;
589 ((AddrLabelDiffData*)(
char*)Data.buffer)->RHSExpr = RHSExpr;
599 void DestroyDataAndMakeUninit();
601 assert(isAbsent() &&
"Bad state change");
602 new ((
void*)Data.buffer)
APSInt(1);
606 assert(isAbsent() &&
"Bad state change");
607 new ((
void*)(
char*)Data.buffer) APFloat(0.0);
611 assert(isAbsent() &&
"Bad state change");
612 new ((
void *)(
char *)Data.buffer)
APFixedPoint(std::move(FX));
616 assert(isAbsent() &&
"Bad state change");
617 new ((
void*)(
char*)Data.buffer) Vec();
620 void MakeComplexInt() {
621 assert(isAbsent() &&
"Bad state change");
622 new ((
void*)(
char*)Data.buffer) ComplexAPSInt();
625 void MakeComplexFloat() {
626 assert(isAbsent() &&
"Bad state change");
627 new ((
void*)(
char*)Data.buffer) ComplexAPFloat();
631 void MakeArray(
unsigned InitElts,
unsigned Size);
632 void MakeStruct(
unsigned B,
unsigned M) {
633 assert(isAbsent() &&
"Bad state change");
634 new ((
void*)(
char*)Data.buffer) StructData(B, M);
638 assert(isAbsent() &&
"Bad state change");
639 new ((
void*)(
char*)Data.buffer) UnionData();
642 void MakeMemberPointer(
const ValueDecl *Member,
bool IsDerivedMember,
644 void MakeAddrLabelDiff() {
645 assert(isAbsent() &&
"Bad state change");
646 new ((
void*)(
char*)Data.buffer) AddrLabelDiffData();
647 Kind = AddrLabelDiff;
unsigned getStructNumFields() const
static LValuePathEntry ArrayIndex(uint64_t Index)
const APFixedPoint & getFixedPoint() const
A (possibly-)qualified type.
bool operator==(CanQual< T > x, CanQual< U > y)
APValue(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be placed into a PointerUnion...
static void * getAsVoidPointer(clang::TypeInfoLValue V)
APValue(UninitStruct, unsigned B, unsigned M)
The base class of the type hierarchy.
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
friend bool operator==(LValuePathEntry A, LValuePathEntry B)
const APValue & getStructField(unsigned i) const
bool isIndeterminate() const
const AddrLabelExpr * getAddrLabelDiffLHS() const
APFloat & getComplexFloatReal()
static APValue IndeterminateValue()
const APFloat & getComplexFloatReal() const
Describes how types, statements, expressions, and declarations should be printed. ...
bool isAddrLabelDiff() const
const APValue & getArrayFiller() const
const APSInt & getComplexIntReal() const
uint64_t getAsArrayIndex() const
static clang::TypeInfoLValue getFromVoidPointer(void *P)
APValue & operator=(APValue RHS)
Assign by swapping from a copy of the RHS.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
APValue(const APValue *E, unsigned N)
Represents a member of a struct/union/class.
const APValue & getUnionValue() const
static constexpr int NumLowBitsAvailable
unsigned getArraySize() const
__DEVICE__ int max(int __a, int __b)
Symbolic representation of typeid(T) for some type T.
void * TypeInfoType
The type std::type_info, if this is a TypeInfoLValue.
CharUnits - This is an opaque type for sizes expressed in character units.
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
bool isComplexFloat() const
bool isFixedPoint() const
bool isComplexInt() const
APSInt & getComplexIntReal()
APValue(UninitArray, unsigned InitElts, unsigned Size)
APValue & getVectorElt(unsigned I)
The APFixedPoint class works similarly to APInt/APSInt in that it is a functional replacement for a s...
const APFloat & getComplexFloatImag() const
APValue & getArrayFiller()
BaseOrMemberType getAsBaseOrMember() const
bool hasArrayFiller() const
const APValue & getVectorElt(unsigned I) const
static unsigned getMaxIndex()
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
This represents one expression.
const Type * getType() const
llvm::StringRef getAsString(SyncScope S)
A non-discriminated union of a base, field, or array index.
void * DynamicAllocType
The QualType, if this is a DynamicAllocLValue.
const APSInt & getInt() const
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
DynamicAllocLValue(unsigned Index)
llvm::hash_code hash_value(const clang::SanitizerMask &Arg)
static bool isVector(QualType QT, QualType ElementType)
This helper function returns true if QT is a vector type that has element type ElementType.
APValue(const FieldDecl *D, const APValue &V=APValue())
APValue(APFloat R, APFloat I)
APValue & getStructField(unsigned i)
APSInt & getComplexIntImag()
const APValue & getArrayInitializedElt(unsigned I) const
The result type of a method or function.
Symbolic representation of a dynamic allocation.
APValue(const ValueDecl *Member, bool IsDerivedMember, ArrayRef< const CXXRecordDecl *> Path)
const FieldDecl * getUnionField() const
friend llvm::hash_code hash_value(LValuePathEntry A)
void setVector(const APValue *E, unsigned N)
APValue & getStructBase(unsigned i)
unsigned getStructNumBases() const
APValue & getArrayInitializedElt(unsigned I)
This object has an indeterminate value (C++ [basic.indet]).
const APSInt & getComplexIntImag() const
LValuePathEntry(BaseOrMemberType BaseOrMember)
const AddrLabelExpr * getAddrLabelDiffRHS() const
APValue & getUnionValue()
bool isMemberPointer() const
void setAddrLabelDiff(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
Defines the fixed point number interface.
const APValue & getStructBase(unsigned i) const
AddrLabelExpr - The GNU address of label extension, representing &&label.
Optional< types::ID > Type
Dataflow Directional Tag Classes.
void setFixedPoint(APFixedPoint FX)
Reads an AST files chain containing the contents of a translation unit.
static DynamicAllocLValue getFromOpaqueValue(void *Value)
unsigned getArrayInitializedElts() const
APValue(APSInt R, APSInt I)
APValue(LValueBase B, const CharUnits &O, NoLValuePath N, bool IsNullPtr=false)
const APFloat & getFloat() const
friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
static void * getAsVoidPointer(clang::DynamicAllocLValue V)
ValueKind getKind() const
APFloat & getComplexFloatImag()
const CharUnits & getLValueOffset() const
There is no such object (it's outside its lifetime).
APValue(LValueBase B, const CharUnits &O, ArrayRef< LValuePathEntry > Path, bool OnePastTheEnd, bool IsNullPtr=false)
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...
Writes an AST file containing the contents of a translation unit.
void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const
static TypeInfoLValue getFromOpaqueValue(void *Value)
void setComplexInt(APSInt R, APSInt I)
void setUnion(const FieldDecl *Field, const APValue &Value)
static clang::DynamicAllocLValue getFromVoidPointer(void *P)
APFixedPoint & getFixedPoint()
void setComplexFloat(APFloat R, APFloat I)
friend bool operator!=(LValuePathEntry A, LValuePathEntry B)
unsigned getVectorLength() const