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 StructData(
unsigned NumBases,
unsigned NumFields);
301 StructData(
const StructData &) =
delete;
302 StructData &operator=(
const StructData &) =
delete;
306 const FieldDecl *
Field;
309 UnionData(
const UnionData &) =
delete;
310 UnionData &operator=(
const UnionData &) =
delete;
313 struct AddrLabelDiffData {
314 const AddrLabelExpr* LHSExpr;
315 const AddrLabelExpr* RHSExpr;
317 struct MemberPointerData;
320 typedef llvm::AlignedCharArrayUnion<
void *,
APSInt,
APFloat, ComplexAPSInt,
321 ComplexAPFloat, Vec, Mat, Arr, StructData,
322 UnionData, AddrLabelDiffData>
324 static const size_t DataSize =
sizeof(DataType);
332 AllowConstexprUnknown = IsConstexprUnknown;
339 MakeInt();
setInt(std::move(I));
343 MakeFloat();
setFloat(std::move(F));
347 MakeFixedPoint(std::move(FX));
352 : Kind(
None), AllowConstexprUnknown(
false) {
358 : Kind(
None), AllowConstexprUnknown(
false) {
378 bool IsNullPtr =
false)
379 : Kind(
None), AllowConstexprUnknown(
false) {
392 bool IsNullPtr =
false)
393 : Kind(
None), AllowConstexprUnknown(
false) {
402 bool IsNullPtr =
false)
403 : Kind(
None), AllowConstexprUnknown(
true) {
414 : Kind(
None), AllowConstexprUnknown(
false) {
415 MakeArray(InitElts, Size);
422 : Kind(
None), AllowConstexprUnknown(
false) {
423 MakeStruct(NumBases, NumMembers);
430 : Kind(
None), AllowConstexprUnknown(
false) {
440 : Kind(
None), AllowConstexprUnknown(
false) {
441 MakeMemberPointer(
Member, IsDerivedMember, Path);
447 : Kind(
None), AllowConstexprUnknown(
false) {
461 DestroyDataAndMakeUninit();
469 bool needsCleanup()
const;
477 void Profile(llvm::FoldingSetNodeID &ID)
const;
509 assert(
isInt() &&
"Invalid accessor");
510 return *(APSInt *)(
char *)&Data;
523 assert(
isFloat() &&
"Invalid accessor");
524 return *(APFloat *)(
char *)&Data;
532 return *(APFixedPoint *)(
char *)&Data;
540 return ((ComplexAPSInt *)(
char *)&Data)->Real;
548 return ((ComplexAPSInt *)(
char *)&Data)->Imag;
556 return ((ComplexAPFloat *)(
char *)&Data)->Real;
564 return ((ComplexAPFloat *)(
char *)&Data)->Imag;
570 const LValueBase getLValueBase()
const;
575 bool isLValueOnePastTheEnd()
const;
576 bool hasLValuePath()
const;
578 unsigned getLValueCallIndex()
const;
579 unsigned getLValueVersion()
const;
580 bool isNullPointer()
const;
583 assert(
isVector() &&
"Invalid accessor");
585 return ((Vec *)(
char *)&Data)->Elts[I];
591 assert(
isVector() &&
"Invalid accessor");
592 return ((
const Vec *)(
const void *)&Data)->NumElts;
596 assert(
isMatrix() &&
"Invalid accessor");
597 return ((
const Mat *)(
const void *)&Data)->NumRows;
600 assert(
isMatrix() &&
"Invalid accessor");
601 return ((
const Mat *)(
const void *)&Data)->NumCols;
607 assert(
isMatrix() &&
"Invalid accessor");
609 return ((Mat *)(
char *)&Data)->Elts[Idx];
615 assert(
isMatrix() &&
"Invalid accessor");
627 assert(
isArray() &&
"Invalid accessor");
629 return ((Arr *)(
char *)&Data)->Elts[I];
638 assert(
isArray() &&
"Invalid accessor");
646 assert(
isArray() &&
"Invalid accessor");
647 return ((
const Arr *)(
const void *)&Data)->NumElts;
650 assert(
isArray() &&
"Invalid accessor");
651 return ((
const Arr *)(
const void *)&Data)->ArrSize;
655 assert(
isStruct() &&
"Invalid accessor");
656 return ((
const StructData *)(
const char *)&Data)->NumBases;
659 assert(
isStruct() &&
"Invalid accessor");
660 return ((
const StructData *)(
const char *)&Data)->NumFields;
663 assert(
isStruct() &&
"Invalid accessor");
665 return ((StructData *)(
char *)&Data)->Elts[i];
668 assert(
isStruct() &&
"Invalid accessor");
680 assert(
isUnion() &&
"Invalid accessor");
681 return ((
const UnionData *)(
const char *)&Data)->Field;
684 assert(
isUnion() &&
"Invalid accessor");
685 return *((UnionData *)(
char *)&Data)->Value;
691 const ValueDecl *getMemberPointerDecl()
const;
692 bool isMemberPointerToDerivedMember()
const;
697 return ((
const AddrLabelDiffData *)(
const char *)&Data)->LHSExpr;
701 return ((
const AddrLabelDiffData *)(
const char *)&Data)->RHSExpr;
705 assert(
isInt() &&
"Invalid accessor");
706 *(APSInt *)(
char *)&Data = std::move(I);
709 assert(
isFloat() &&
"Invalid accessor");
710 *(APFloat *)(
char *)&Data = std::move(F);
714 *(APFixedPoint *)(
char *)&Data = std::move(FX);
718 for (
unsigned i = 0; i != N; ++i)
719 InternalElts[i] = E[i];
723 for (
unsigned i = 0; i != NumRows * NumCols; ++i)
724 InternalElts[i] = E[i];
727 assert(R.getBitWidth() == I.getBitWidth() &&
728 "Invalid complex int (type mismatch).");
730 ((ComplexAPSInt *)(
char *)&Data)->Real = std::move(R);
731 ((ComplexAPSInt *)(
char *)&Data)->Imag = std::move(I);
734 assert(&R.getSemantics() == &I.getSemantics() &&
735 "Invalid complex float (type mismatch).");
737 ((ComplexAPFloat *)(
char *)&Data)->Real = std::move(R);
738 ((ComplexAPFloat *)(
char *)&Data)->Imag = std::move(I);
740 void setLValue(LValueBase B,
const CharUnits &O, NoLValuePath,
742 void setLValue(LValueBase B,
const CharUnits &O,
748 ((AddrLabelDiffData *)(
char *)&Data)->LHSExpr = LHSExpr;
749 ((AddrLabelDiffData *)(
char *)&Data)->RHSExpr = RHSExpr;
753 void DestroyDataAndMakeUninit();
755 assert(isAbsent() &&
"Bad state change");
760 assert(isAbsent() &&
"Bad state change");
761 new ((
void *)(
char *)&Data) APFloat(0.0);
764 void MakeFixedPoint(APFixedPoint &&FX) {
765 assert(isAbsent() &&
"Bad state change");
766 new ((
void *)(
char *)&Data) APFixedPoint(std::move(FX));
770 assert(isAbsent() &&
"Bad state change");
771 new ((
void *)(
char *)&Data) Vec();
775 assert(isAbsent() &&
"Bad state change");
776 new ((
void *)(
char *)&Data) Mat();
779 void MakeComplexInt() {
780 assert(isAbsent() &&
"Bad state change");
781 new ((
void *)(
char *)&Data) ComplexAPSInt();
784 void MakeComplexFloat() {
785 assert(isAbsent() &&
"Bad state change");
786 new ((
void *)(
char *)&Data) ComplexAPFloat();
790 void MakeArray(
unsigned InitElts,
unsigned Size);
791 void MakeStruct(
unsigned B,
unsigned M) {
792 assert(isAbsent() &&
"Bad state change");
793 new ((
void *)(
char *)&Data) StructData(B, M);
797 assert(isAbsent() &&
"Bad state change");
798 new ((
void *)(
char *)&Data) UnionData();
801 void MakeMemberPointer(
const ValueDecl *Member,
bool IsDerivedMember,
802 ArrayRef<const CXXRecordDecl*> Path);
803 void MakeAddrLabelDiff() {
804 assert(isAbsent() &&
"Bad state change");
805 new ((
void *)(
char *)&Data) AddrLabelDiffData();
806 Kind = AddrLabelDiff;
813 MutableArrayRef<APValue> setVectorUninit(
unsigned N) {
814 assert(
isVector() &&
"Invalid accessor");
815 Vec *
V = ((Vec *)(
char *)&Data);
818 return {
V->Elts,
V->NumElts};
820 MutableArrayRef<APValue> setMatrixUninit(
unsigned NumRows,
unsigned NumCols) {
821 assert(isMatrix() &&
"Invalid accessor");
822 Mat *M = ((Mat *)(
char *)&Data);
823 unsigned NumElts = NumRows * NumCols;
824 M->Elts =
new APValue[NumElts];
825 M->NumRows = NumRows;
826 M->NumCols = NumCols;
827 return {M->Elts, NumElts};
829 MutableArrayRef<LValuePathEntry>
830 setLValueUninit(LValueBase B,
const CharUnits &O,
unsigned Size,
831 bool OnePastTheEnd,
bool IsNullPtr);
832 MutableArrayRef<const CXXRecordDecl *>
833 setMemberPointerUninit(
const ValueDecl *Member,
bool IsDerivedMember,
840template<>
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
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
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.
APValue(UninitStruct, unsigned NumBases, unsigned NumMembers)
Creates a new struct 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.
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 & 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 ...
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 clang::APValue::LValueBase getTombstoneKey()
static clang::APValue::LValueBase getEmptyKey()
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