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);
68 static constexpr
int NumLowBitsAvailable = 3;
77 typedef llvm::APSInt APSInt;
78 typedef llvm::APFloat APFloat;
100 typedef llvm::PointerUnion<const ValueDecl *, const Expr *, TypeInfoLValue>
110 bool is()
const {
return Ptr.is<T>(); }
113 T
get()
const {
return Ptr.get<T>(); }
122 explicit operator bool()
const;
124 unsigned getCallIndex()
const;
125 unsigned getVersion()
const;
130 return !(LHS == RHS);
137 unsigned CallIndex, Version;
152 static_assert(
sizeof(
uintptr_t) <=
sizeof(uint64_t),
153 "pointer doesn't fit in 64 bits?");
159 : Value{
reinterpret_cast<uintptr_t>(BaseOrMember.getOpaqueValue())} {}
162 Result.Value = Index;
167 return BaseOrMemberType::getFromOpaqueValue(
168 reinterpret_cast<void *>(Value));
173 return A.Value == B.Value;
176 return A.Value != B.Value;
192 struct ComplexAPSInt {
194 ComplexAPSInt() : Real(1), Imag(1) {}
196 struct ComplexAPFloat {
198 ComplexAPFloat() : Real(0.0), Imag(0.0) {}
204 Vec() : Elts(nullptr), NumElts(0) {}
205 ~Vec() {
delete[] Elts; }
209 unsigned NumElts, ArrSize;
210 Arr(
unsigned NumElts,
unsigned ArrSize);
217 StructData(
unsigned NumBases,
unsigned NumFields);
226 struct AddrLabelDiffData {
233 typedef llvm::AlignedCharArrayUnion<
void *, APSInt, APFloat, ComplexAPSInt,
234 ComplexAPFloat, Vec, Arr, StructData,
235 UnionData, AddrLabelDiffData> DataType;
236 static const size_t DataSize =
sizeof(DataType);
243 MakeInt(); setInt(std::move(I));
246 MakeFloat(); setFloat(std::move(F));
249 MakeFixedPoint(std::move(FX));
252 MakeVector(); setVector(E, N);
255 MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
258 MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
263 bool IsNullPtr =
false)
265 MakeLValue(); setLValue(B, O, N, IsNullPtr);
268 bool OnePastTheEnd,
bool IsNullPtr =
false)
270 MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
273 MakeArray(InitElts, Size);
280 MakeUnion(); setUnion(D,
V);
284 MakeMemberPointer(Member, IsDerivedMember, Path);
288 MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
292 Result.Kind = Indeterminate;
297 if (Kind !=
None && Kind != Indeterminate)
298 DestroyDataAndMakeUninit();
306 bool needsCleanup()
const;
315 bool hasValue()
const {
return Kind !=
None && Kind != Indeterminate; }
317 bool isInt()
const {
return Kind == Int; }
318 bool isFloat()
const {
return Kind == Float; }
324 bool isArray()
const {
return Kind == Array; }
331 void dump(raw_ostream &OS)
const;
337 assert(isInt() &&
"Invalid accessor");
338 return *(APSInt*)(
char*)Data.buffer;
341 return const_cast<APValue*
>(
this)->getInt();
351 assert(isFloat() &&
"Invalid accessor");
352 return *(APFloat*)(
char*)Data.buffer;
355 return const_cast<APValue*
>(
this)->getFloat();
359 assert(isFixedPoint() &&
"Invalid accessor");
363 return const_cast<APValue *
>(
this)->getFixedPoint();
367 assert(isComplexInt() &&
"Invalid accessor");
368 return ((ComplexAPSInt*)(
char*)Data.buffer)->Real;
371 return const_cast<APValue*
>(
this)->getComplexIntReal();
375 assert(isComplexInt() &&
"Invalid accessor");
376 return ((ComplexAPSInt*)(
char*)Data.buffer)->Imag;
379 return const_cast<APValue*
>(
this)->getComplexIntImag();
383 assert(isComplexFloat() &&
"Invalid accessor");
384 return ((ComplexAPFloat*)(
char*)Data.buffer)->Real;
387 return const_cast<APValue*
>(
this)->getComplexFloatReal();
391 assert(isComplexFloat() &&
"Invalid accessor");
392 return ((ComplexAPFloat*)(
char*)Data.buffer)->Imag;
395 return const_cast<APValue*
>(
this)->getComplexFloatImag();
401 return const_cast<APValue*
>(
this)->getLValueOffset();
403 bool isLValueOnePastTheEnd()
const;
404 bool hasLValuePath()
const;
406 unsigned getLValueCallIndex()
const;
407 unsigned getLValueVersion()
const;
408 bool isNullPointer()
const;
411 assert(
isVector() &&
"Invalid accessor");
412 assert(I < getVectorLength() &&
"Index out of range");
413 return ((Vec*)(
char*)Data.buffer)->Elts[I];
416 return const_cast<APValue*
>(
this)->getVectorElt(I);
419 assert(
isVector() &&
"Invalid accessor");
420 return ((
const Vec*)(
const void *)Data.buffer)->NumElts;
424 assert(isArray() &&
"Invalid accessor");
425 assert(I < getArrayInitializedElts() &&
"Index out of range");
426 return ((Arr*)(
char*)Data.buffer)->Elts[I];
429 return const_cast<APValue*
>(
this)->getArrayInitializedElt(I);
432 return getArrayInitializedElts() != getArraySize();
435 assert(isArray() &&
"Invalid accessor");
436 assert(hasArrayFiller() &&
"No array filler");
437 return ((Arr*)(
char*)Data.buffer)->Elts[getArrayInitializedElts()];
440 return const_cast<APValue*
>(
this)->getArrayFiller();
443 assert(isArray() &&
"Invalid accessor");
444 return ((
const Arr*)(
const void *)Data.buffer)->NumElts;
447 assert(isArray() &&
"Invalid accessor");
448 return ((
const Arr*)(
const void *)Data.buffer)->ArrSize;
452 assert(isStruct() &&
"Invalid accessor");
453 return ((
const StructData*)(
const char*)Data.buffer)->NumBases;
456 assert(isStruct() &&
"Invalid accessor");
457 return ((
const StructData*)(
const char*)Data.buffer)->NumFields;
460 assert(isStruct() &&
"Invalid accessor");
461 return ((StructData*)(
char*)Data.buffer)->Elts[
i];
464 assert(isStruct() &&
"Invalid accessor");
465 return ((StructData*)(
char*)Data.buffer)->Elts[getStructNumBases() +
i];
468 return const_cast<APValue*
>(
this)->getStructBase(i);
471 return const_cast<APValue*
>(
this)->getStructField(i);
475 assert(isUnion() &&
"Invalid accessor");
476 return ((
const UnionData*)(
const char*)Data.buffer)->Field;
479 assert(isUnion() &&
"Invalid accessor");
480 return *((UnionData*)(
char*)Data.buffer)->
Value;
483 return const_cast<APValue*
>(
this)->getUnionValue();
486 const ValueDecl *getMemberPointerDecl()
const;
487 bool isMemberPointerToDerivedMember()
const;
491 assert(isAddrLabelDiff() &&
"Invalid accessor");
492 return ((
const AddrLabelDiffData*)(
const char*)Data.buffer)->LHSExpr;
495 assert(isAddrLabelDiff() &&
"Invalid accessor");
496 return ((
const AddrLabelDiffData*)(
const char*)Data.buffer)->RHSExpr;
500 assert(isInt() &&
"Invalid accessor");
501 *(APSInt *)(
char *)Data.buffer = std::move(I);
504 assert(isFloat() &&
"Invalid accessor");
505 *(APFloat *)(
char *)Data.buffer = std::move(F);
508 assert(isFixedPoint() &&
"Invalid accessor");
512 assert(
isVector() &&
"Invalid accessor");
513 ((Vec*)(
char*)Data.buffer)->Elts =
new APValue[N];
514 ((Vec*)(
char*)Data.buffer)->NumElts = N;
515 for (
unsigned i = 0;
i != N; ++
i)
516 ((Vec*)(
char*)Data.buffer)->Elts[
i] = E[
i];
519 assert(R.getBitWidth() == I.getBitWidth() &&
520 "Invalid complex int (type mismatch).");
521 assert(isComplexInt() &&
"Invalid accessor");
522 ((ComplexAPSInt *)(
char *)Data.buffer)->Real = std::move(R);
523 ((ComplexAPSInt *)(
char *)Data.buffer)->Imag = std::move(I);
526 assert(&R.getSemantics() == &I.getSemantics() &&
527 "Invalid complex float (type mismatch).");
528 assert(isComplexFloat() &&
"Invalid accessor");
529 ((ComplexAPFloat *)(
char *)Data.buffer)->Real = std::move(R);
530 ((ComplexAPFloat *)(
char *)Data.buffer)->Imag = std::move(I);
538 assert(isUnion() &&
"Invalid accessor");
539 ((UnionData*)(
char*)Data.buffer)->Field = Field;
540 *((UnionData*)(
char*)Data.buffer)->Value = Value;
544 ((AddrLabelDiffData*)(
char*)Data.buffer)->LHSExpr = LHSExpr;
545 ((AddrLabelDiffData*)(
char*)Data.buffer)->RHSExpr = RHSExpr;
555 void DestroyDataAndMakeUninit();
557 assert(isAbsent() &&
"Bad state change");
558 new ((
void*)Data.buffer) APSInt(1);
562 assert(isAbsent() &&
"Bad state change");
563 new ((
void*)(
char*)Data.buffer) APFloat(0.0);
567 assert(isAbsent() &&
"Bad state change");
568 new ((
void *)(
char *)Data.buffer)
APFixedPoint(std::move(FX));
572 assert(isAbsent() &&
"Bad state change");
573 new ((
void*)(
char*)Data.buffer) Vec();
576 void MakeComplexInt() {
577 assert(isAbsent() &&
"Bad state change");
578 new ((
void*)(
char*)Data.buffer) ComplexAPSInt();
581 void MakeComplexFloat() {
582 assert(isAbsent() &&
"Bad state change");
583 new ((
void*)(
char*)Data.buffer) ComplexAPFloat();
587 void MakeArray(
unsigned InitElts,
unsigned Size);
588 void MakeStruct(
unsigned B,
unsigned M) {
589 assert(isAbsent() &&
"Bad state change");
590 new ((
void*)(
char*)Data.buffer) StructData(B, M);
594 assert(isAbsent() &&
"Bad state change");
595 new ((
void*)(
char*)Data.buffer) UnionData();
598 void MakeMemberPointer(
const ValueDecl *Member,
bool IsDerivedMember,
600 void MakeAddrLabelDiff() {
601 assert(isAbsent() &&
"Bad state change");
602 new ((
void*)(
char*)Data.buffer) AddrLabelDiffData();
603 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
unsigned getArraySize() const
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
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.
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...
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.
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.
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]...
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)
APFixedPoint & getFixedPoint()
void setComplexFloat(APFloat R, APFloat I)
friend bool operator!=(LValuePathEntry A, LValuePathEntry B)
unsigned getVectorLength() const