13#ifndef LLVM_CLANG_AST_APVALUE_H
14#define LLVM_CLANG_AST_APVALUE_H
17#include "llvm/ADT/APFixedPoint.h"
18#include "llvm/ADT/APFloat.h"
19#include "llvm/ADT/APSInt.h"
20#include "llvm/ADT/FoldingSet.h"
21#include "llvm/ADT/PointerIntPair.h"
22#include "llvm/ADT/PointerUnion.h"
23#include "llvm/Support/AlignOf.h"
52 explicit operator bool()
const {
return T; }
73 explicit operator bool()
const {
return Index != 0; }
76 return reinterpret_cast<const void *
>(
static_cast<uintptr_t>(Index)
96 return V.getOpaqueValue();
108 return V.getOpaqueValue();
123 typedef llvm::APFixedPoint APFixedPoint;
124 typedef llvm::APSInt APSInt;
125 typedef llvm::APFloat APFloat;
159 void Profile(llvm::FoldingSetNodeID &ID)
const;
161 template <
class T>
bool is()
const {
return isa<T>(Ptr); }
166 return dyn_cast_if_present<T>(Ptr);
169 void *getOpaqueValue()
const;
173 explicit operator bool()
const;
175 unsigned getCallIndex()
const;
176 unsigned getVersion()
const;
178 QualType getDynamicAllocType()
const;
184 return !(LHS == RHS);
192 unsigned CallIndex, Version;
209 static_assert(
sizeof(
uintptr_t) <=
sizeof(uint64_t),
210 "pointer doesn't fit in 64 bits?");
223 return BaseOrMemberType::getFromOpaqueValue(
224 reinterpret_cast<void *
>(Value));
228 void Profile(llvm::FoldingSetNodeID &ID)
const;
231 return A.Value == B.Value;
234 return A.Value != B.Value;
260 bool AllowConstexprUnknown : 1;
262 struct ComplexAPSInt {
264 ComplexAPSInt() : Real(1), Imag(1) {}
266 struct ComplexAPFloat {
268 ComplexAPFloat() : Real(0.0), Imag(0.0) {}
273 unsigned NumElts = 0;
275 Vec(
const Vec &) =
delete;
276 Vec &operator=(
const Vec &) =
delete;
277 ~Vec() {
delete[] Elts; }
281 unsigned NumRows = 0;
282 unsigned NumCols = 0;
284 Mat(
const Mat &) =
delete;
285 Mat &operator=(
const Mat &) =
delete;
286 ~Mat() {
delete[] Elts; }
290 unsigned NumElts, ArrSize;
291 Arr(
unsigned NumElts,
unsigned ArrSize);
292 Arr(
const Arr &) =
delete;
293 Arr &operator=(
const Arr &) =
delete;
300 unsigned NumVirtualBases;
301 StructData(
unsigned NumBases,
unsigned NumFields,
unsigned NumVirtualBases);
302 StructData(
const StructData &) =
delete;
303 StructData &operator=(
const StructData &) =
delete;
307 const FieldDecl *
Field;
310 UnionData(
const UnionData &) =
delete;
311 UnionData &operator=(
const UnionData &) =
delete;
314 struct AddrLabelDiffData {
315 const AddrLabelExpr* LHSExpr;
316 const AddrLabelExpr* RHSExpr;
318 struct MemberPointerData;
321 typedef llvm::AlignedCharArrayUnion<
void *,
APSInt,
APFloat, ComplexAPSInt,
322 ComplexAPFloat, Vec, Mat, Arr, StructData,
323 UnionData, AddrLabelDiffData>
325 static const size_t DataSize =
sizeof(DataType);
333 AllowConstexprUnknown = IsConstexprUnknown;
340 MakeInt();
setInt(std::move(I));
344 MakeFloat();
setFloat(std::move(F));
348 MakeFixedPoint(std::move(FX));
353 : Kind(
None), AllowConstexprUnknown(
false) {
359 : Kind(
None), AllowConstexprUnknown(
false) {
379 bool IsNullPtr =
false)
380 : Kind(
None), AllowConstexprUnknown(
false) {
393 bool IsNullPtr =
false)
394 : Kind(
None), AllowConstexprUnknown(
false) {
403 bool IsNullPtr =
false)
404 : Kind(
None), AllowConstexprUnknown(
true) {
415 : Kind(
None), AllowConstexprUnknown(
false) {
416 MakeArray(InitElts, Size);
424 unsigned NumVirtualBases = 0)
425 : Kind(
None), AllowConstexprUnknown(
false) {
426 MakeStruct(NumBases, NumMembers, NumVirtualBases);
433 : Kind(
None), AllowConstexprUnknown(
false) {
443 : Kind(
None), AllowConstexprUnknown(
false) {
444 MakeMemberPointer(
Member, IsDerivedMember, Path);
450 : Kind(
None), AllowConstexprUnknown(
false) {
464 DestroyDataAndMakeUninit();
472 bool needsCleanup()
const;
480 void Profile(llvm::FoldingSetNodeID &ID)
const;
512 assert(
isInt() &&
"Invalid accessor");
513 return *(APSInt *)(
char *)&Data;
526 assert(
isFloat() &&
"Invalid accessor");
527 return *(APFloat *)(
char *)&Data;
535 return *(APFixedPoint *)(
char *)&Data;
543 return ((ComplexAPSInt *)(
char *)&Data)->Real;
551 return ((ComplexAPSInt *)(
char *)&Data)->Imag;
559 return ((ComplexAPFloat *)(
char *)&Data)->Real;
567 return ((ComplexAPFloat *)(
char *)&Data)->Imag;
573 const LValueBase getLValueBase()
const;
578 bool isLValueOnePastTheEnd()
const;
579 bool hasLValuePath()
const;
581 unsigned getLValueCallIndex()
const;
582 unsigned getLValueVersion()
const;
583 bool isNullPointer()
const;
586 assert(
isVector() &&
"Invalid accessor");
588 return ((Vec *)(
char *)&Data)->Elts[I];
594 assert(
isVector() &&
"Invalid accessor");
595 return ((
const Vec *)(
const void *)&Data)->NumElts;
599 assert(
isMatrix() &&
"Invalid accessor");
600 return ((
const Mat *)(
const void *)&Data)->NumRows;
603 assert(
isMatrix() &&
"Invalid accessor");
604 return ((
const Mat *)(
const void *)&Data)->NumCols;
610 assert(
isMatrix() &&
"Invalid accessor");
612 return ((Mat *)(
char *)&Data)->Elts[Idx];
618 assert(
isMatrix() &&
"Invalid accessor");
630 assert(
isArray() &&
"Invalid accessor");
632 return ((Arr *)(
char *)&Data)->Elts[I];
641 assert(
isArray() &&
"Invalid accessor");
649 assert(
isArray() &&
"Invalid accessor");
650 return ((
const Arr *)(
const void *)&Data)->NumElts;
653 assert(
isArray() &&
"Invalid accessor");
654 return ((
const Arr *)(
const void *)&Data)->ArrSize;
658 assert(
isStruct() &&
"Invalid accessor");
659 return ((
const StructData *)(
const char *)&Data)->NumBases;
662 assert(
isStruct() &&
"Invalid accessor");
663 return ((
const StructData *)(
const char *)&Data)->NumFields;
666 assert(
isStruct() &&
"Invalid accessor");
667 return ((
const StructData *)(
const char *)&Data)->NumVirtualBases;
670 assert(
isStruct() &&
"Invalid accessor");
672 return ((StructData *)(
char *)&Data)->Elts[i];
675 assert(
isStruct() &&
"Invalid accessor");
680 assert(
isStruct() &&
"Invalid accessor");
682 return ((StructData *)(
char *)&Data)
696 assert(
isUnion() &&
"Invalid accessor");
697 return ((
const UnionData *)(
const char *)&Data)->Field;
700 assert(
isUnion() &&
"Invalid accessor");
701 return *((UnionData *)(
char *)&Data)->Value;
707 const ValueDecl *getMemberPointerDecl()
const;
708 bool isMemberPointerToDerivedMember()
const;
713 return ((
const AddrLabelDiffData *)(
const char *)&Data)->LHSExpr;
717 return ((
const AddrLabelDiffData *)(
const char *)&Data)->RHSExpr;
721 assert(
isInt() &&
"Invalid accessor");
722 *(APSInt *)(
char *)&Data = std::move(I);
725 assert(
isFloat() &&
"Invalid accessor");
726 *(APFloat *)(
char *)&Data = std::move(F);
730 *(APFixedPoint *)(
char *)&Data = std::move(FX);
734 for (
unsigned i = 0; i != N; ++i)
735 InternalElts[i] = E[i];
739 for (
unsigned i = 0; i != NumRows * NumCols; ++i)
740 InternalElts[i] = E[i];
743 assert(R.getBitWidth() == I.getBitWidth() &&
744 "Invalid complex int (type mismatch).");
746 ((ComplexAPSInt *)(
char *)&Data)->Real = std::move(R);
747 ((ComplexAPSInt *)(
char *)&Data)->Imag = std::move(I);
750 assert(&R.getSemantics() == &I.getSemantics() &&
751 "Invalid complex float (type mismatch).");
753 ((ComplexAPFloat *)(
char *)&Data)->Real = std::move(R);
754 ((ComplexAPFloat *)(
char *)&Data)->Imag = std::move(I);
756 void setLValue(LValueBase B,
const CharUnits &O, NoLValuePath,
758 void setLValue(LValueBase B,
const CharUnits &O,
764 ((AddrLabelDiffData *)(
char *)&Data)->LHSExpr = LHSExpr;
765 ((AddrLabelDiffData *)(
char *)&Data)->RHSExpr = RHSExpr;
769 void DestroyDataAndMakeUninit();
771 assert(isAbsent() &&
"Bad state change");
776 assert(isAbsent() &&
"Bad state change");
777 new ((
void *)(
char *)&Data) APFloat(0.0);
780 void MakeFixedPoint(APFixedPoint &&FX) {
781 assert(isAbsent() &&
"Bad state change");
782 new ((
void *)(
char *)&Data) APFixedPoint(std::move(FX));
786 assert(isAbsent() &&
"Bad state change");
787 new ((
void *)(
char *)&Data) Vec();
791 assert(isAbsent() &&
"Bad state change");
792 new ((
void *)(
char *)&Data) Mat();
795 void MakeComplexInt() {
796 assert(isAbsent() &&
"Bad state change");
797 new ((
void *)(
char *)&Data) ComplexAPSInt();
800 void MakeComplexFloat() {
801 assert(isAbsent() &&
"Bad state change");
802 new ((
void *)(
char *)&Data) ComplexAPFloat();
806 void MakeArray(
unsigned InitElts,
unsigned Size);
807 void MakeStruct(
unsigned B,
unsigned M,
unsigned V) {
808 assert(isAbsent() &&
"Bad state change");
809 new ((
void *)(
char *)&Data) StructData(B, M,
V);
813 assert(isAbsent() &&
"Bad state change");
814 new ((
void *)(
char *)&Data) UnionData();
817 void MakeMemberPointer(
const ValueDecl *Member,
bool IsDerivedMember,
818 ArrayRef<const CXXRecordDecl*> Path);
819 void MakeAddrLabelDiff() {
820 assert(isAbsent() &&
"Bad state change");
821 new ((
void *)(
char *)&Data) AddrLabelDiffData();
829 MutableArrayRef<APValue> setVectorUninit(
unsigned N) {
830 assert(
isVector() &&
"Invalid accessor");
831 Vec *
V = ((Vec *)(
char *)&Data);
834 return {
V->Elts,
V->NumElts};
836 MutableArrayRef<APValue> setMatrixUninit(
unsigned NumRows,
unsigned NumCols) {
837 assert(isMatrix() &&
"Invalid accessor");
838 Mat *M = ((Mat *)(
char *)&Data);
839 unsigned NumElts = NumRows * NumCols;
840 M->Elts =
new APValue[NumElts];
841 M->NumRows = NumRows;
842 M->NumCols = NumCols;
843 return {M->Elts, NumElts};
845 MutableArrayRef<LValuePathEntry>
846 setLValueUninit(LValueBase B,
const CharUnits &O,
unsigned Size,
847 bool OnePastTheEnd,
bool IsNullPtr);
848 MutableArrayRef<const CXXRecordDecl *>
849 setMemberPointerUninit(
const ValueDecl *Member,
bool IsDerivedMember,
856template<>
struct DenseMapInfo<
clang::APValue::LValueBase> {
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.
static bool isVector(QualType QT, QualType ElementType)
This helper function returns true if QT is a vector type that has element type ElementType.
friend llvm::hash_code hash_value(const LValueBase &Base)
friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS)
void * DynamicAllocType
The QualType, if this is a DynamicAllocLValue.
void * TypeInfoType
The type std::type_info, if this is a TypeInfoLValue.
A non-discriminated union of a base, field, or array index.
BaseOrMemberType getAsBaseOrMember() const
uint64_t getAsArrayIndex() const
friend llvm::hash_code hash_value(LValuePathEntry A)
friend bool operator!=(LValuePathEntry A, LValuePathEntry B)
static LValuePathEntry ArrayIndex(uint64_t Index)
friend bool operator==(LValuePathEntry A, LValuePathEntry B)
ArrayRef< LValuePathEntry > Path
LValuePathSerializationHelper(ArrayRef< LValuePathEntry >, QualType)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
const APSInt & getComplexIntReal() const
bool hasArrayFiller() const
APValue(LValueBase Base, const CharUnits &Offset, NoLValuePath, bool IsNullPtr=false)
Creates an lvalue APValue without an lvalue path.
APValue(APFloat F)
Creates a float APValue holding the given value.
const APValue & getMatrixElt(unsigned Idx) const
APValue & getArrayInitializedElt(unsigned I)
APValue & getStructField(unsigned i)
APValue(const APValue *E, unsigned NumRows, unsigned NumCols)
Creates a matrix APValue with given dimensions.
unsigned getMatrixNumColumns() const
APValue(APSInt I)
Creates an integer APValue holding the given value.
const FieldDecl * getUnionField() const
const APFloat & getFloat() const
APSInt & getComplexIntImag()
unsigned getStructNumFields() const
const APValue & getArrayInitializedElt(unsigned I) const
APValue(APFloat R, APFloat I)
Creates a float complex APValue with the given real and imaginary values.
void setConstexprUnknown(bool IsConstexprUnknown=true)
APValue(const FieldDecl *ActiveDecl, const APValue &ActiveValue=APValue())
Creates a new union APValue.
bool isComplexInt() const
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...
ValueKind getKind() const
APValue & getStructVirtualBase(unsigned i)
const APValue & getMatrixElt(unsigned Row, unsigned Col) const
APValue(const APValue *E, unsigned N)
Creates a vector APValue with N elements.
void setFixedPoint(APFixedPoint FX)
unsigned getArrayInitializedElts() const
static APValue IndeterminateValue()
void setComplexInt(APSInt R, APSInt I)
const APFixedPoint & getFixedPoint() const
void Profile(llvm::FoldingSetNodeID &ID) const
profile this value.
unsigned getStructNumBases() const
APFixedPoint & getFixedPoint()
APValue(const ValueDecl *Member, bool IsDerivedMember, ArrayRef< const CXXRecordDecl * > Path)
Creates a new member pointer APValue.
const APValue & getStructBase(unsigned i) const
friend class ASTNodeImporter
unsigned getStructNumVirtualBases() const
APValue(LValueBase Base, const CharUnits &Offset, ArrayRef< LValuePathEntry > Path, bool OnePastTheEnd, bool IsNullPtr=false)
Creates an lvalue APValue with an lvalue path.
APValue & getUnionValue()
void setMatrix(const APValue *E, unsigned NumRows, unsigned NumCols)
const AddrLabelExpr * getAddrLabelDiffRHS() const
CharUnits & getLValueOffset()
void setAddrLabelDiff(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
void setComplexFloat(APFloat R, APFloat I)
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
APValue & getArrayFiller()
APValue(LValueBase Base, const CharUnits &Offset, ConstexprUnknown, bool IsNullPtr=false)
Creates a constexpr unknown lvalue APValue.
const APValue & getArrayFiller() const
const APFloat & getComplexFloatImag() const
unsigned getVectorLength() const
const APValue & getUnionValue() const
const APValue & getVectorElt(unsigned I) const
APValue(UninitArray, unsigned InitElts, unsigned Size)
Creates a new array APValue.
void setUnion(const FieldDecl *Field, const APValue &Value)
APValue(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
Creates a new address label diff APValue.
bool isIndeterminate() const
unsigned getMatrixNumRows() const
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, bool IsNullPtr)
bool isMemberPointer() const
const APSInt & getInt() const
APValue & getMatrixElt(unsigned Row, unsigned Col)
const APFloat & getComplexFloatReal() const
unsigned getArraySize() const
APValue(APSInt R, APSInt I)
Creates an integer complex APValue with the given real and imaginary values.
APValue(UninitStruct, unsigned NumBases, unsigned NumMembers, unsigned NumVirtualBases=0)
Creates a new struct APValue.
const CharUnits & getLValueOffset() const
bool allowConstexprUnknown() const
bool isFixedPoint() const
void setVector(const APValue *E, unsigned N)
APValue & getMatrixElt(unsigned Idx)
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
const APValue & getStructVirtualBase(unsigned i) const
const APValue & getStructField(unsigned i) const
const APSInt & getComplexIntImag() const
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
APValue & getStructBase(unsigned i)
APValue(APFixedPoint FX)
Creates a fixed-point APValue holding the given value.
const AddrLabelExpr * getAddrLabelDiffLHS() const
unsigned getMatrixNumElements() const
bool isAddrLabelDiff() const
APValue()
Creates an empty APValue of type None.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
AddrLabelExpr - The GNU address of label extension, representing &&label.
Represents a C++ struct/union/class.
CharUnits - This is an opaque type for sizes expressed in character units.
Decl - This represents one declaration (or definition), e.g.
A little helper class used to produce diagnostics.
Symbolic representation of a dynamic allocation.
static unsigned getMaxIndex()
const void * getOpaqueValue() const
static constexpr int NumLowBitsAvailable
DynamicAllocLValue(unsigned Index)
static DynamicAllocLValue getFromOpaqueValue(const void *Value)
This represents one expression.
Represents a member of a struct/union/class.
A (possibly-)qualified type.
Symbolic representation of typeid(T) for some type T.
const Type * getType() const
static TypeInfoLValue getFromOpaqueValue(const void *Value)
void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const
const void * getOpaqueValue() const
The base class of the type hierarchy.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
@ AddrLabelDiff
Difference between two AddrLabelExpr.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
@ Result
The result type of a method or function.
llvm::StringRef getAsString(SyncScope S)
U cast(CodeGen::Address addr)
Diagnostic wrappers for TextAPI types for error reporting.
hash_code hash_value(const clang::dependencies::ModuleID &ID)
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
Describes how types, statements, expressions, and declarations should be printed.
static bool isEqual(const clang::APValue::LValueBase &LHS, const clang::APValue::LValueBase &RHS)
static unsigned getHashValue(const clang::APValue::LValueBase &Base)
static constexpr int NumLowBitsAvailable
static const void * getAsVoidPointer(clang::DynamicAllocLValue V)
static clang::DynamicAllocLValue getFromVoidPointer(const void *P)
static clang::TypeInfoLValue getFromVoidPointer(const void *P)
static const void * getAsVoidPointer(clang::TypeInfoLValue V)
static constexpr int NumLowBitsAvailable