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);
100 const FieldDecl *
Field;
105 struct AddrLabelDiffData {
106 const AddrLabelExpr* LHSExpr;
107 const AddrLabelExpr* RHSExpr;
109 struct MemberPointerData;
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));
140 MakeLValue();
setLValue(B, O, N, CallIndex);
143 bool OnePastTheEnd,
unsigned CallIndex)
145 MakeLValue();
setLValue(B, O, Path, OnePastTheEnd, CallIndex);
148 MakeArray(InitElts, Size);
159 MakeMemberPointer(Member, IsDerivedMember, Path);
195 void dump(raw_ostream &OS)
const;
201 assert(
isInt() &&
"Invalid accessor");
202 return *(APSInt*)(
char*)Data.buffer;
209 assert(
isFloat() &&
"Invalid accessor");
210 return *(APFloat*)(
char*)Data.buffer;
218 return ((ComplexAPSInt*)(
char*)Data.buffer)->Real;
226 return ((ComplexAPSInt*)(
char*)Data.buffer)->Imag;
234 return ((ComplexAPFloat*)(
char*)Data.buffer)->Real;
242 return ((ComplexAPFloat*)(
char*)Data.buffer)->Imag;
259 assert(
isVector() &&
"Invalid accessor");
261 return ((Vec*)(
char*)Data.buffer)->Elts[
I];
267 assert(
isVector() &&
"Invalid accessor");
268 return ((
const Vec*)(
const void *)Data.buffer)->NumElts;
272 assert(
isArray() &&
"Invalid accessor");
274 return ((Arr*)(
char*)Data.buffer)->Elts[
I];
283 assert(
isArray() &&
"Invalid accessor");
291 assert(
isArray() &&
"Invalid accessor");
292 return ((
const Arr*)(
const void *)Data.buffer)->NumElts;
295 assert(
isArray() &&
"Invalid accessor");
296 return ((
const Arr*)(
const void *)Data.buffer)->ArrSize;
300 assert(
isStruct() &&
"Invalid accessor");
301 return ((
const StructData*)(
const char*)Data.buffer)->NumBases;
304 assert(
isStruct() &&
"Invalid accessor");
305 return ((
const StructData*)(
const char*)Data.buffer)->NumFields;
308 assert(
isStruct() &&
"Invalid accessor");
309 return ((StructData*)(
char*)Data.buffer)->Elts[i];
312 assert(
isStruct() &&
"Invalid accessor");
323 assert(
isUnion() &&
"Invalid accessor");
324 return ((
const UnionData*)(
const char*)Data.buffer)->Field;
327 assert(
isUnion() &&
"Invalid accessor");
328 return *((UnionData*)(
char*)Data.buffer)->
Value;
340 return ((
const AddrLabelDiffData*)(
const char*)Data.buffer)->LHSExpr;
344 return ((
const AddrLabelDiffData*)(
const char*)Data.buffer)->RHSExpr;
348 assert(
isInt() &&
"Invalid accessor");
349 *(APSInt *)(
char *)Data.buffer = std::move(I);
352 assert(
isFloat() &&
"Invalid accessor");
353 *(APFloat *)(
char *)Data.buffer = std::move(F);
356 assert(
isVector() &&
"Invalid accessor");
357 ((Vec*)(
char*)Data.buffer)->Elts =
new APValue[N];
358 ((Vec*)(
char*)Data.buffer)->NumElts = N;
359 for (
unsigned i = 0; i != N; ++i)
360 ((Vec*)(
char*)Data.buffer)->Elts[i] = E[i];
363 assert(R.getBitWidth() == I.getBitWidth() &&
364 "Invalid complex int (type mismatch).");
366 ((ComplexAPSInt *)(
char *)Data.buffer)->Real = std::move(R);
367 ((ComplexAPSInt *)(
char *)Data.buffer)->Imag = std::move(I);
370 assert(&R.getSemantics() == &I.getSemantics() &&
371 "Invalid complex float (type mismatch).");
373 ((ComplexAPFloat *)(
char *)Data.buffer)->Real = std::move(R);
374 ((ComplexAPFloat *)(
char *)Data.buffer)->Imag = std::move(I);
382 assert(
isUnion() &&
"Invalid accessor");
383 ((UnionData*)(
char*)Data.buffer)->Field = Field;
384 *((UnionData*)(
char*)Data.buffer)->Value = Value;
388 ((AddrLabelDiffData*)(
char*)Data.buffer)->LHSExpr = LHSExpr;
389 ((AddrLabelDiffData*)(
char*)Data.buffer)->RHSExpr = RHSExpr;
399 void DestroyDataAndMakeUninit();
402 DestroyDataAndMakeUninit();
405 assert(
isUninit() &&
"Bad state change");
406 new ((
void*)Data.buffer) APSInt(1);
410 assert(
isUninit() &&
"Bad state change");
411 new ((
void*)(
char*)Data.buffer) APFloat(0.0);
415 assert(
isUninit() &&
"Bad state change");
416 new ((
void*)(
char*)Data.buffer) Vec();
419 void MakeComplexInt() {
420 assert(
isUninit() &&
"Bad state change");
421 new ((
void*)(
char*)Data.buffer) ComplexAPSInt();
424 void MakeComplexFloat() {
425 assert(
isUninit() &&
"Bad state change");
426 new ((
void*)(
char*)Data.buffer) ComplexAPFloat();
430 void MakeArray(
unsigned InitElts,
unsigned Size);
431 void MakeStruct(
unsigned B,
unsigned M) {
432 assert(
isUninit() &&
"Bad state change");
433 new ((
void*)(
char*)Data.buffer) StructData(B, M);
437 assert(
isUninit() &&
"Bad state change");
438 new ((
void*)(
char*)Data.buffer) UnionData();
441 void MakeMemberPointer(
const ValueDecl *Member,
bool IsDerivedMember,
442 ArrayRef<const CXXRecordDecl*> Path);
443 void MakeAddrLabelDiff() {
444 assert(
isUninit() &&
"Bad state change");
445 new ((
void*)(
char*)Data.buffer) AddrLabelDiffData();
const FieldDecl * getUnionField() const
A (possibly-)qualified type.
const APFloat & getComplexFloatImag() const
const APValue & getArrayInitializedElt(unsigned I) const
APValue(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex)
const APValue & getStructBase(unsigned i) const
APValue(UninitStruct, unsigned B, unsigned M)
bool isMemberPointer() const
void * BaseOrMember
BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item in the path.
const APFloat & getFloat() const
bool hasLValuePath() const
APFloat & getComplexFloatReal()
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
bool isComplexInt() 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...
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...
const ValueDecl * getMemberPointerDecl() const
unsigned getStructNumFields() const
bool needsCleanup() const
Returns whether the object performed allocations.
detail::InMemoryDirectory::const_iterator I
APSInt & getComplexIntReal()
APValue(UninitArray, unsigned InitElts, unsigned Size)
APValue & getVectorElt(unsigned I)
bool isAddrLabelDiff() const
const APSInt & getInt() const
APValue & getArrayFiller()
uint64_t ArrayIndex
ArrayIndex - The array index of the next item in the path.
const APFloat & getComplexFloatReal() const
unsigned getArrayInitializedElts() const
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
bool isMemberPointerToDerivedMember() const
bool isComplexFloat() const
APValue(const FieldDecl *D, const APValue &V=APValue())
APValue(APFloat R, APFloat I)
APValue & getStructField(unsigned i)
APSInt & getComplexIntImag()
bool isLValueOnePastTheEnd() const
void setVector(const APValue *E, unsigned N)
APValue & getStructBase(unsigned i)
APValue & getArrayInitializedElt(unsigned I)
unsigned getStructNumBases() const
const AddrLabelExpr * getAddrLabelDiffLHS() const
APValue & getUnionValue()
ValueKind getKind() const
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, unsigned CallIndex)
void setAddrLabelDiff(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const
const AddrLabelExpr * getAddrLabelDiffRHS() const
AddrLabelExpr - The GNU address of label extension, representing &&label.
APValue(LValueBase B, const CharUnits &O, ArrayRef< LValuePathEntry > Path, bool OnePastTheEnd, unsigned CallIndex)
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
const APValue & getVectorElt(unsigned I) const
std::string getAsString(ASTContext &Ctx, QualType Ty) const
detail::InMemoryDirectory::const_iterator E
APValue(const ValueDecl *Member, bool IsDerivedMember, ArrayRef< const CXXRecordDecl * > Path)
APValue(APSInt R, APSInt I)
ArrayRef< LValuePathEntry > getLValuePath() const
const CharUnits & getLValueOffset() const
const APSInt & getComplexIntReal() const
llvm::PointerUnion< const ValueDecl *, const Expr * > LValueBase
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
APFloat & getComplexFloatImag()
const LValueBase getLValueBase() const
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
void setComplexInt(APSInt R, APSInt I)
const APValue & getArrayFiller() const
void setUnion(const FieldDecl *Field, const APValue &Value)
unsigned getArraySize() const
const APValue & getUnionValue() const
unsigned getVectorLength() const
const APValue & getStructField(unsigned i) const
bool hasArrayFiller() const
void setComplexFloat(APFloat R, APFloat I)
CharUnits & getLValueOffset()
const APSInt & getComplexIntImag() const