14 #ifndef LLVM_CLANG_AST_APVALUE_H 15 #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" 27 class DiagnosticBuilder;
39 typedef llvm::APSInt APSInt;
40 typedef llvm::APFloat APFloat;
59 typedef llvm::PointerUnion<const ValueDecl *, const Expr *>
PtrTy;
65 : Ptr(P), CallIndex(I), Version(V) {}
68 bool is()
const {
return Ptr.is<T>(); }
71 T
get()
const {
return Ptr.get<T>(); }
74 T
dyn_cast()
const {
return Ptr.dyn_cast<T>(); }
80 explicit operator bool ()
const;
99 return Ptr == Other.Ptr && CallIndex == Other.CallIndex &&
100 Version == Other.Version;
105 unsigned CallIndex, Version;
122 struct ComplexAPSInt {
124 ComplexAPSInt() : Real(1), Imag(1) {}
126 struct ComplexAPFloat {
128 ComplexAPFloat() : Real(0.0), Imag(0.0) {}
134 Vec() : Elts(
nullptr), NumElts(0) {}
135 ~Vec() {
delete[] Elts; }
139 unsigned NumElts, ArrSize;
140 Arr(
unsigned NumElts,
unsigned ArrSize);
147 StructData(
unsigned NumBases,
unsigned NumFields);
156 struct AddrLabelDiffData {
163 typedef llvm::AlignedCharArrayUnion<
void *, APSInt, APFloat, ComplexAPSInt,
164 ComplexAPFloat, Vec, Arr, StructData,
165 UnionData, AddrLabelDiffData> DataType;
166 static const size_t DataSize =
sizeof(DataType);
173 MakeInt();
setInt(std::move(I));
176 MakeFloat();
setFloat(std::move(F));
190 bool IsNullPtr =
false)
192 MakeLValue();
setLValue(B, O, N, IsNullPtr);
195 bool OnePastTheEnd,
bool IsNullPtr =
false)
197 MakeLValue();
setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
200 MakeArray(InitElts, Size);
211 MakeMemberPointer(Member, IsDerivedMember, Path);
247 void dump(raw_ostream &OS)
const;
253 assert(
isInt() &&
"Invalid accessor");
254 return *(APSInt*)(
char*)Data.buffer;
267 assert(
isFloat() &&
"Invalid accessor");
268 return *(APFloat*)(
char*)Data.buffer;
276 return ((ComplexAPSInt*)(
char*)Data.buffer)->Real;
284 return ((ComplexAPSInt*)(
char*)Data.buffer)->Imag;
292 return ((ComplexAPFloat*)(
char*)Data.buffer)->Real;
300 return ((ComplexAPFloat*)(
char*)Data.buffer)->Imag;
319 assert(
isVector() &&
"Invalid accessor");
321 return ((Vec*)(
char*)Data.buffer)->Elts[I];
327 assert(
isVector() &&
"Invalid accessor");
328 return ((
const Vec*)(
const void *)Data.buffer)->NumElts;
332 assert(
isArray() &&
"Invalid accessor");
334 return ((Arr*)(
char*)Data.buffer)->Elts[I];
343 assert(
isArray() &&
"Invalid accessor");
351 assert(
isArray() &&
"Invalid accessor");
352 return ((
const Arr*)(
const void *)Data.buffer)->NumElts;
355 assert(
isArray() &&
"Invalid accessor");
356 return ((
const Arr*)(
const void *)Data.buffer)->ArrSize;
360 assert(
isStruct() &&
"Invalid accessor");
361 return ((
const StructData*)(
const char*)Data.buffer)->NumBases;
364 assert(
isStruct() &&
"Invalid accessor");
365 return ((
const StructData*)(
const char*)Data.buffer)->NumFields;
368 assert(
isStruct() &&
"Invalid accessor");
369 return ((StructData*)(
char*)Data.buffer)->Elts[i];
372 assert(
isStruct() &&
"Invalid accessor");
383 assert(
isUnion() &&
"Invalid accessor");
384 return ((
const UnionData*)(
const char*)Data.buffer)->Field;
387 assert(
isUnion() &&
"Invalid accessor");
388 return *((UnionData*)(
char*)Data.buffer)->
Value;
400 return ((
const AddrLabelDiffData*)(
const char*)Data.buffer)->LHSExpr;
404 return ((
const AddrLabelDiffData*)(
const char*)Data.buffer)->RHSExpr;
408 assert(
isInt() &&
"Invalid accessor");
409 *(APSInt *)(
char *)Data.buffer = std::move(I);
412 assert(
isFloat() &&
"Invalid accessor");
413 *(APFloat *)(
char *)Data.buffer = std::move(F);
416 assert(
isVector() &&
"Invalid accessor");
417 ((Vec*)(
char*)Data.buffer)->Elts =
new APValue[N];
418 ((Vec*)(
char*)Data.buffer)->NumElts = N;
419 for (
unsigned i = 0; i != N; ++i)
420 ((Vec*)(
char*)Data.buffer)->Elts[i] = E[i];
423 assert(R.getBitWidth() == I.getBitWidth() &&
424 "Invalid complex int (type mismatch).");
426 ((ComplexAPSInt *)(
char *)Data.buffer)->Real = std::move(R);
427 ((ComplexAPSInt *)(
char *)Data.buffer)->Imag = std::move(I);
430 assert(&R.getSemantics() == &I.getSemantics() &&
431 "Invalid complex float (type mismatch).");
433 ((ComplexAPFloat *)(
char *)Data.buffer)->Real = std::move(R);
434 ((ComplexAPFloat *)(
char *)Data.buffer)->Imag = std::move(I);
442 assert(
isUnion() &&
"Invalid accessor");
443 ((UnionData*)(
char*)Data.buffer)->Field = Field;
444 *((UnionData*)(
char*)Data.buffer)->Value = Value;
448 ((AddrLabelDiffData*)(
char*)Data.buffer)->LHSExpr = LHSExpr;
449 ((AddrLabelDiffData*)(
char*)Data.buffer)->RHSExpr = RHSExpr;
459 void DestroyDataAndMakeUninit();
462 DestroyDataAndMakeUninit();
465 assert(
isUninit() &&
"Bad state change");
466 new ((
void*)Data.buffer) APSInt(1);
470 assert(
isUninit() &&
"Bad state change");
471 new ((
void*)(
char*)Data.buffer) APFloat(0.0);
475 assert(
isUninit() &&
"Bad state change");
476 new ((
void*)(
char*)Data.buffer) Vec();
479 void MakeComplexInt() {
480 assert(
isUninit() &&
"Bad state change");
481 new ((
void*)(
char*)Data.buffer) ComplexAPSInt();
484 void MakeComplexFloat() {
485 assert(
isUninit() &&
"Bad state change");
486 new ((
void*)(
char*)Data.buffer) ComplexAPFloat();
490 void MakeArray(
unsigned InitElts,
unsigned Size);
491 void MakeStruct(
unsigned B,
unsigned M) {
492 assert(
isUninit() &&
"Bad state change");
493 new ((
void*)(
char*)Data.buffer) StructData(B, M);
497 assert(
isUninit() &&
"Bad state change");
498 new ((
void*)(
char*)Data.buffer) UnionData();
501 void MakeMemberPointer(
const ValueDecl *Member,
bool IsDerivedMember,
503 void MakeAddrLabelDiff() {
504 assert(
isUninit() &&
"Bad state change");
505 new ((
void*)(
char*)Data.buffer) AddrLabelDiffData();
unsigned getStructNumFields() const
A (possibly-)qualified type.
APValue(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
llvm::PointerUnion< const ValueDecl *, const Expr * > PtrTy
APValue(UninitStruct, unsigned B, unsigned M)
void * BaseOrMember
BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item in the path.
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
const APValue & getStructField(unsigned i) const
const AddrLabelExpr * getAddrLabelDiffLHS() const
APFloat & getComplexFloatReal()
ArrayRef< LValuePathEntry > getLValuePath() const
const APFloat & getComplexFloatReal() const
bool isAddrLabelDiff() const
const APValue & getArrayFiller() const
const APSInt & getComplexIntReal() const
bool isLValueOnePastTheEnd() const
const ValueDecl * getMemberPointerDecl() const
unsigned getVersion() const
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 getCallIndex() const
unsigned getArraySize() const
unsigned getLValueCallIndex() const
bool operator==(const LValueBase &Other) const
CharUnits - This is an opaque type for sizes expressed in character units.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
std::string getAsString(ASTContext &Ctx, QualType Ty) const
void setCallIndex(unsigned Index)
bool isComplexFloat() const
bool isComplexInt() const
void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const
bool needsCleanup() const
Returns whether the object performed allocations.
APSInt & getComplexIntReal()
APValue(UninitArray, unsigned InitElts, unsigned Size)
APValue & getVectorElt(unsigned I)
unsigned getLValueVersion() const
bool hasLValuePath() const
const APFloat & getComplexFloatImag() const
APValue & getArrayFiller()
uint64_t ArrayIndex
ArrayIndex - The array index of the next item in the path.
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 ...
const APSInt & getInt() const
APValue(const FieldDecl *D, const APValue &V=APValue())
APValue(APFloat R, APFloat I)
APValue & getStructField(unsigned i)
bool isNullPointer() const
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
void setVector(const APValue *E, unsigned N)
APValue & getStructBase(unsigned i)
unsigned getStructNumBases() const
LValueBase(T P, unsigned I=0, unsigned V=0)
APValue & getArrayInitializedElt(unsigned I)
const LValueBase getLValueBase() const
void * getOpaqueValue() const
const APSInt & getComplexIntImag() const
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, bool IsNullPtr)
const AddrLabelExpr * getAddrLabelDiffRHS() const
APValue & getUnionValue()
bool isMemberPointer() const
void setAddrLabelDiff(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
bool isMemberPointerToDerivedMember() const
const APValue & getStructBase(unsigned i) const
AddrLabelExpr - The GNU address of label extension, representing &&label.
Dataflow Directional Tag Classes.
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
unsigned getArrayInitializedElts() const
APValue(APSInt R, APSInt I)
APValue(LValueBase B, const CharUnits &O, NoLValuePath N, bool IsNullPtr=false)
bool toIntegralConstant(APSInt &Result, QualType SrcTy, const ASTContext &Ctx) const
Try to convert this value to an integral constant.
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
const APFloat & getFloat() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
ValueKind getKind() const
APFloat & getComplexFloatImag()
const CharUnits & getLValueOffset() const
APValue(LValueBase B, const CharUnits &O, ArrayRef< LValuePathEntry > Path, bool OnePastTheEnd, bool IsNullPtr=false)
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
void setComplexInt(APSInt R, APSInt I)
void setUnion(const FieldDecl *Field, const APValue &Value)
void setComplexFloat(APFloat R, APFloat I)
CharUnits & getLValueOffset()
unsigned getVectorLength() const