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;
261 assert(
isFloat() &&
"Invalid accessor");
262 return *(APFloat*)(
char*)Data.buffer;
270 return ((ComplexAPSInt*)(
char*)Data.buffer)->Real;
278 return ((ComplexAPSInt*)(
char*)Data.buffer)->Imag;
286 return ((ComplexAPFloat*)(
char*)Data.buffer)->Real;
294 return ((ComplexAPFloat*)(
char*)Data.buffer)->Imag;
313 assert(
isVector() &&
"Invalid accessor");
315 return ((Vec*)(
char*)Data.buffer)->Elts[I];
321 assert(
isVector() &&
"Invalid accessor");
322 return ((
const Vec*)(
const void *)Data.buffer)->NumElts;
326 assert(
isArray() &&
"Invalid accessor");
328 return ((Arr*)(
char*)Data.buffer)->Elts[I];
337 assert(
isArray() &&
"Invalid accessor");
345 assert(
isArray() &&
"Invalid accessor");
346 return ((
const Arr*)(
const void *)Data.buffer)->NumElts;
349 assert(
isArray() &&
"Invalid accessor");
350 return ((
const Arr*)(
const void *)Data.buffer)->ArrSize;
354 assert(
isStruct() &&
"Invalid accessor");
355 return ((
const StructData*)(
const char*)Data.buffer)->NumBases;
358 assert(
isStruct() &&
"Invalid accessor");
359 return ((
const StructData*)(
const char*)Data.buffer)->NumFields;
362 assert(
isStruct() &&
"Invalid accessor");
363 return ((StructData*)(
char*)Data.buffer)->Elts[i];
366 assert(
isStruct() &&
"Invalid accessor");
377 assert(
isUnion() &&
"Invalid accessor");
378 return ((
const UnionData*)(
const char*)Data.buffer)->Field;
381 assert(
isUnion() &&
"Invalid accessor");
382 return *((UnionData*)(
char*)Data.buffer)->
Value;
394 return ((
const AddrLabelDiffData*)(
const char*)Data.buffer)->LHSExpr;
398 return ((
const AddrLabelDiffData*)(
const char*)Data.buffer)->RHSExpr;
402 assert(
isInt() &&
"Invalid accessor");
403 *(APSInt *)(
char *)Data.buffer = std::move(I);
406 assert(
isFloat() &&
"Invalid accessor");
407 *(APFloat *)(
char *)Data.buffer = std::move(F);
410 assert(
isVector() &&
"Invalid accessor");
411 ((Vec*)(
char*)Data.buffer)->Elts =
new APValue[N];
412 ((Vec*)(
char*)Data.buffer)->NumElts = N;
413 for (
unsigned i = 0; i != N; ++i)
414 ((Vec*)(
char*)Data.buffer)->Elts[i] = E[i];
417 assert(R.getBitWidth() == I.getBitWidth() &&
418 "Invalid complex int (type mismatch).");
420 ((ComplexAPSInt *)(
char *)Data.buffer)->Real = std::move(R);
421 ((ComplexAPSInt *)(
char *)Data.buffer)->Imag = std::move(I);
424 assert(&R.getSemantics() == &I.getSemantics() &&
425 "Invalid complex float (type mismatch).");
427 ((ComplexAPFloat *)(
char *)Data.buffer)->Real = std::move(R);
428 ((ComplexAPFloat *)(
char *)Data.buffer)->Imag = std::move(I);
436 assert(
isUnion() &&
"Invalid accessor");
437 ((UnionData*)(
char*)Data.buffer)->Field = Field;
438 *((UnionData*)(
char*)Data.buffer)->Value = Value;
442 ((AddrLabelDiffData*)(
char*)Data.buffer)->LHSExpr = LHSExpr;
443 ((AddrLabelDiffData*)(
char*)Data.buffer)->RHSExpr = RHSExpr;
453 void DestroyDataAndMakeUninit();
456 DestroyDataAndMakeUninit();
459 assert(
isUninit() &&
"Bad state change");
460 new ((
void*)Data.buffer) APSInt(1);
464 assert(
isUninit() &&
"Bad state change");
465 new ((
void*)(
char*)Data.buffer) APFloat(0.0);
469 assert(
isUninit() &&
"Bad state change");
470 new ((
void*)(
char*)Data.buffer) Vec();
473 void MakeComplexInt() {
474 assert(
isUninit() &&
"Bad state change");
475 new ((
void*)(
char*)Data.buffer) ComplexAPSInt();
478 void MakeComplexFloat() {
479 assert(
isUninit() &&
"Bad state change");
480 new ((
void*)(
char*)Data.buffer) ComplexAPFloat();
484 void MakeArray(
unsigned InitElts,
unsigned Size);
485 void MakeStruct(
unsigned B,
unsigned M) {
486 assert(
isUninit() &&
"Bad state change");
487 new ((
void*)(
char*)Data.buffer) StructData(B, M);
491 assert(
isUninit() &&
"Bad state change");
492 new ((
void*)(
char*)Data.buffer) UnionData();
495 void MakeMemberPointer(
const ValueDecl *Member,
bool IsDerivedMember,
497 void MakeAddrLabelDiff() {
498 assert(
isUninit() &&
"Bad state change");
499 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
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)
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