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;
56 typedef llvm::PointerUnion<const ValueDecl *, const Expr *>
LValueBase;
71 struct ComplexAPSInt {
73 ComplexAPSInt() : Real(1), Imag(1) {}
75 struct ComplexAPFloat {
77 ComplexAPFloat() : Real(0.0), Imag(0.0) {}
83 Vec() : Elts(
nullptr), NumElts(0) {}
84 ~Vec() {
delete[] Elts; }
88 unsigned NumElts, ArrSize;
89 Arr(
unsigned NumElts,
unsigned ArrSize);
96 StructData(
unsigned NumBases,
unsigned NumFields);
105 struct AddrLabelDiffData {
112 typedef llvm::AlignedCharArrayUnion<
void *, APSInt, APFloat, ComplexAPSInt,
113 ComplexAPFloat, Vec, Arr, StructData,
114 UnionData, AddrLabelDiffData> DataType;
115 static const size_t DataSize =
sizeof(DataType);
122 MakeInt();
setInt(std::move(I));
125 MakeFloat();
setFloat(std::move(F));
139 bool IsNullPtr =
false)
141 MakeLValue();
setLValue(B, O, N, CallIndex, IsNullPtr);
144 bool OnePastTheEnd,
unsigned CallIndex,
bool IsNullPtr =
false)
146 MakeLValue();
setLValue(B, O, Path, OnePastTheEnd, CallIndex, IsNullPtr);
149 MakeArray(InitElts, Size);
160 MakeMemberPointer(Member, IsDerivedMember, Path);
196 void dump(raw_ostream &OS)
const;
202 assert(
isInt() &&
"Invalid accessor");
203 return *(APSInt*)(
char*)Data.buffer;
210 assert(
isFloat() &&
"Invalid accessor");
211 return *(APFloat*)(
char*)Data.buffer;
219 return ((ComplexAPSInt*)(
char*)Data.buffer)->Real;
227 return ((ComplexAPSInt*)(
char*)Data.buffer)->Imag;
235 return ((ComplexAPFloat*)(
char*)Data.buffer)->Real;
243 return ((ComplexAPFloat*)(
char*)Data.buffer)->Imag;
261 assert(
isVector() &&
"Invalid accessor");
263 return ((Vec*)(
char*)Data.buffer)->Elts[I];
269 assert(
isVector() &&
"Invalid accessor");
270 return ((
const Vec*)(
const void *)Data.buffer)->NumElts;
274 assert(
isArray() &&
"Invalid accessor");
276 return ((Arr*)(
char*)Data.buffer)->Elts[I];
285 assert(
isArray() &&
"Invalid accessor");
293 assert(
isArray() &&
"Invalid accessor");
294 return ((
const Arr*)(
const void *)Data.buffer)->NumElts;
297 assert(
isArray() &&
"Invalid accessor");
298 return ((
const Arr*)(
const void *)Data.buffer)->ArrSize;
302 assert(
isStruct() &&
"Invalid accessor");
303 return ((
const StructData*)(
const char*)Data.buffer)->NumBases;
306 assert(
isStruct() &&
"Invalid accessor");
307 return ((
const StructData*)(
const char*)Data.buffer)->NumFields;
310 assert(
isStruct() &&
"Invalid accessor");
311 return ((StructData*)(
char*)Data.buffer)->Elts[i];
314 assert(
isStruct() &&
"Invalid accessor");
325 assert(
isUnion() &&
"Invalid accessor");
326 return ((
const UnionData*)(
const char*)Data.buffer)->Field;
329 assert(
isUnion() &&
"Invalid accessor");
330 return *((UnionData*)(
char*)Data.buffer)->
Value;
342 return ((
const AddrLabelDiffData*)(
const char*)Data.buffer)->LHSExpr;
346 return ((
const AddrLabelDiffData*)(
const char*)Data.buffer)->RHSExpr;
350 assert(
isInt() &&
"Invalid accessor");
351 *(APSInt *)(
char *)Data.buffer = std::move(I);
354 assert(
isFloat() &&
"Invalid accessor");
355 *(APFloat *)(
char *)Data.buffer = std::move(F);
358 assert(
isVector() &&
"Invalid accessor");
359 ((Vec*)(
char*)Data.buffer)->Elts =
new APValue[N];
360 ((Vec*)(
char*)Data.buffer)->NumElts = N;
361 for (
unsigned i = 0; i != N; ++i)
362 ((Vec*)(
char*)Data.buffer)->Elts[i] = E[i];
365 assert(R.getBitWidth() == I.getBitWidth() &&
366 "Invalid complex int (type mismatch).");
368 ((ComplexAPSInt *)(
char *)Data.buffer)->Real = std::move(R);
369 ((ComplexAPSInt *)(
char *)Data.buffer)->Imag = std::move(I);
372 assert(&R.getSemantics() == &I.getSemantics() &&
373 "Invalid complex float (type mismatch).");
375 ((ComplexAPFloat *)(
char *)Data.buffer)->Real = std::move(R);
376 ((ComplexAPFloat *)(
char *)Data.buffer)->Imag = std::move(I);
379 unsigned CallIndex,
bool IsNullPtr);
382 unsigned CallIndex,
bool IsNullPtr);
384 assert(
isUnion() &&
"Invalid accessor");
385 ((UnionData*)(
char*)Data.buffer)->Field = Field;
386 *((UnionData*)(
char*)Data.buffer)->Value = Value;
390 ((AddrLabelDiffData*)(
char*)Data.buffer)->LHSExpr = LHSExpr;
391 ((AddrLabelDiffData*)(
char*)Data.buffer)->RHSExpr = RHSExpr;
401 void DestroyDataAndMakeUninit();
404 DestroyDataAndMakeUninit();
407 assert(
isUninit() &&
"Bad state change");
408 new ((
void*)Data.buffer) APSInt(1);
412 assert(
isUninit() &&
"Bad state change");
413 new ((
void*)(
char*)Data.buffer) APFloat(0.0);
417 assert(
isUninit() &&
"Bad state change");
418 new ((
void*)(
char*)Data.buffer) Vec();
421 void MakeComplexInt() {
422 assert(
isUninit() &&
"Bad state change");
423 new ((
void*)(
char*)Data.buffer) ComplexAPSInt();
426 void MakeComplexFloat() {
427 assert(
isUninit() &&
"Bad state change");
428 new ((
void*)(
char*)Data.buffer) ComplexAPFloat();
432 void MakeArray(
unsigned InitElts,
unsigned Size);
433 void MakeStruct(
unsigned B,
unsigned M) {
434 assert(
isUninit() &&
"Bad state change");
435 new ((
void*)(
char*)Data.buffer) StructData(B, M);
439 assert(
isUninit() &&
"Bad state change");
440 new ((
void*)(
char*)Data.buffer) UnionData();
443 void MakeMemberPointer(
const ValueDecl *Member,
bool IsDerivedMember,
445 void MakeAddrLabelDiff() {
446 assert(
isUninit() &&
"Bad state change");
447 new ((
void*)(
char*)Data.buffer) AddrLabelDiffData();
unsigned getStructNumFields() const
A (possibly-)qualified type.
APValue(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
APValue(LValueBase B, const CharUnits &O, ArrayRef< LValuePathEntry > Path, bool OnePastTheEnd, unsigned CallIndex, bool IsNullPtr=false)
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
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)
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
const APValue & getUnionValue() const
unsigned getArraySize() const
unsigned getLValueCallIndex() 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
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)
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
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
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
APValue & getArrayInitializedElt(unsigned I)
const LValueBase getLValueBase() const
const APSInt & getComplexIntImag() const
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)
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
const APFloat & getFloat() const
llvm::PointerUnion< const ValueDecl *, const Expr * > LValueBase
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
ValueKind getKind() const
APFloat & getComplexFloatImag()
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, unsigned CallIndex, bool IsNullPtr)
const CharUnits & getLValueOffset() const
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
void setComplexInt(APSInt R, APSInt I)
APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex, bool IsNullPtr=false)
void setUnion(const FieldDecl *Field, const APValue &Value)
void setComplexFloat(APFloat R, APFloat I)
CharUnits & getLValueOffset()
unsigned getVectorLength() const