13#ifndef LLVM_CLANG_AST_APVALUE_H
14#define LLVM_CLANG_AST_APVALUE_H
19#include "llvm/ADT/APFixedPoint.h"
20#include "llvm/ADT/APFloat.h"
21#include "llvm/ADT/APSInt.h"
22#include "llvm/ADT/FoldingSet.h"
23#include "llvm/ADT/PointerIntPair.h"
24#include "llvm/ADT/PointerUnion.h"
25#include "llvm/ADT/STLFunctionalExtras.h"
26#include "llvm/ADT/bit.h"
27#include "llvm/Support/AlignOf.h"
28#include "llvm/Support/Compiler.h"
56 explicit operator bool()
const {
return T; }
97 : AllocKind(
llvm::to_underlying(AllocKind)), Index(Idx + 1) {
98 assert(Idx <=
getMaxIndex() &&
"Index is out of range");
105 explicit operator bool()
const {
return Index != 0; }
108 return reinterpret_cast<const void *
>(
121 return (std::numeric_limits<uintptr_t>::max() >>
126static_assert(
sizeof(DynamicAllocLValue) ==
sizeof(
uintptr_t));
132 return V.getOpaqueValue();
144 return V.getOpaqueValue();
159 typedef llvm::APFixedPoint APFixedPoint;
160 typedef llvm::APSInt APSInt;
161 typedef llvm::APFloat APFloat;
196 void Profile(llvm::FoldingSetNodeID &ID)
const;
198 template <
class T>
bool is()
const {
return isa<T>(Ptr); }
203 return dyn_cast_if_present<T>(Ptr);
206 void *getOpaqueValue()
const;
210 explicit operator bool()
const;
212 unsigned getCallIndex()
const;
213 unsigned getVersion()
const;
215 QualType getDynamicAllocType()
const;
221 return !(LHS == RHS);
229 unsigned CallIndex, Version;
246 static_assert(
sizeof(
uintptr_t) <=
sizeof(uint64_t),
247 "pointer doesn't fit in 64 bits?");
260 return BaseOrMemberType::getFromOpaqueValue(
261 reinterpret_cast<void *
>(Value));
265 void Profile(llvm::FoldingSetNodeID &ID)
const;
268 return A.Value == B.Value;
271 return A.Value != B.Value;
297 bool AllowConstexprUnknown : 1;
299 struct ComplexAPSInt {
301 ComplexAPSInt() : Real(1), Imag(1) {}
303 struct ComplexAPFloat {
305 ComplexAPFloat() : Real(0.0), Imag(0.0) {}
310 unsigned NumElts = 0;
312 Vec(
const Vec &) =
delete;
313 Vec &operator=(
const Vec &) =
delete;
314 ~Vec() {
delete[] Elts; }
318 unsigned NumRows = 0;
319 unsigned NumCols = 0;
321 Mat(
const Mat &) =
delete;
322 Mat &operator=(
const Mat &) =
delete;
323 ~Mat() {
delete[] Elts; }
327 unsigned NumElts, ArrSize;
328 Arr(
unsigned NumElts,
unsigned ArrSize);
329 Arr(
const Arr &) =
delete;
330 Arr &operator=(
const Arr &) =
delete;
337 unsigned NumVirtualBases;
338 StructData(
unsigned NumBases,
unsigned NumFields,
unsigned NumVirtualBases);
339 StructData(
const StructData &) =
delete;
340 StructData &operator=(
const StructData &) =
delete;
344 const FieldDecl *
Field;
347 UnionData(
const UnionData &) =
delete;
348 UnionData &operator=(
const UnionData &) =
delete;
351 struct AddrLabelDiffData {
352 const AddrLabelExpr* LHSExpr;
353 const AddrLabelExpr* RHSExpr;
355 struct ReflectionData {
366 struct MemberPointerData;
369 typedef llvm::AlignedCharArrayUnion<
370 void *,
APSInt,
APFloat, ComplexAPSInt, ComplexAPFloat, Vec, Mat, Arr,
371 StructData, UnionData, AddrLabelDiffData, ReflectionData>
373 static const size_t DataSize =
sizeof(DataType);
381 AllowConstexprUnknown = IsConstexprUnknown;
388 MakeInt(std::move(I));
392 MakeFloat(std::move(F));
396 MakeFixedPoint(std::move(FX));
401 : Kind(
None), AllowConstexprUnknown(
false) {
407 : Kind(
None), AllowConstexprUnknown(
false) {
427 bool IsNullPtr =
false)
428 : Kind(
None), AllowConstexprUnknown(
false) {
440 bool OnePastTheEnd,
bool IsNullPtr =
false)
441 : Kind(
None), AllowConstexprUnknown(
false) {
450 bool IsNullPtr =
false)
451 : Kind(
None), AllowConstexprUnknown(
true) {
462 : Kind(
None), AllowConstexprUnknown(
false) {
463 MakeArray(InitElts, Size);
470 MakeReflection(OperandKind, Operand);
479 unsigned NumVirtualBases = 0)
480 : Kind(
None), AllowConstexprUnknown(
false) {
481 MakeStruct(NumBases, NumMembers, NumVirtualBases);
488 : Kind(
None), AllowConstexprUnknown(
false) {
498 : Kind(
None), AllowConstexprUnknown(
false) {
499 MakeMemberPointer(
Member, IsDerivedMember, Path);
505 : Kind(
None), AllowConstexprUnknown(
false) {
519 DestroyDataAndMakeUninit();
527 bool needsCleanup()
const;
535 void Profile(llvm::FoldingSetNodeID &ID)
const;
543 void visit(llvm::function_ref<
bool(
const APValue &)> Visitor)
const;
574 assert(
isInt() &&
"Invalid accessor");
575 return *(APSInt *)(
char *)&Data;
588 assert(
isFloat() &&
"Invalid accessor");
589 return *(APFloat *)(
char *)&Data;
597 return *(APFixedPoint *)(
char *)&Data;
605 return ((ComplexAPSInt *)(
char *)&Data)->Real;
613 return ((ComplexAPSInt *)(
char *)&Data)->Imag;
621 return ((ComplexAPFloat *)(
char *)&Data)->Real;
629 return ((ComplexAPFloat *)(
char *)&Data)->Imag;
635 const LValueBase getLValueBase()
const;
640 bool isLValueOnePastTheEnd()
const;
641 bool hasLValuePath()
const;
643 unsigned getLValueCallIndex()
const;
644 unsigned getLValueVersion()
const;
645 bool isNullPointer()
const;
648 assert(
isVector() &&
"Invalid accessor");
650 return ((Vec *)(
char *)&Data)->Elts[I];
656 assert(
isVector() &&
"Invalid accessor");
657 return ((
const Vec *)(
const void *)&Data)->NumElts;
661 assert(
isMatrix() &&
"Invalid accessor");
662 return ((
const Mat *)(
const void *)&Data)->NumRows;
665 assert(
isMatrix() &&
"Invalid accessor");
666 return ((
const Mat *)(
const void *)&Data)->NumCols;
672 assert(
isMatrix() &&
"Invalid accessor");
674 return ((Mat *)(
char *)&Data)->Elts[Idx];
680 assert(
isMatrix() &&
"Invalid accessor");
692 assert(
isArray() &&
"Invalid accessor");
694 return ((Arr *)(
char *)&Data)->Elts[I];
703 assert(
isArray() &&
"Invalid accessor");
711 assert(
isArray() &&
"Invalid accessor");
712 return ((
const Arr *)(
const void *)&Data)->NumElts;
715 assert(
isArray() &&
"Invalid accessor");
716 return ((
const Arr *)(
const void *)&Data)->ArrSize;
720 assert(
isStruct() &&
"Invalid accessor");
721 return ((
const StructData *)(
const char *)&Data)->NumBases;
724 assert(
isStruct() &&
"Invalid accessor");
725 return ((
const StructData *)(
const char *)&Data)->NumFields;
728 assert(
isStruct() &&
"Invalid accessor");
729 return ((
const StructData *)(
const char *)&Data)->NumVirtualBases;
732 assert(
isStruct() &&
"Invalid accessor");
734 return ((StructData *)(
char *)&Data)->Elts[i];
737 assert(
isStruct() &&
"Invalid accessor");
742 assert(
isStruct() &&
"Invalid accessor");
744 return ((StructData *)(
char *)&Data)
758 assert(
isUnion() &&
"Invalid accessor");
759 return ((
const UnionData *)(
const char *)&Data)->Field;
762 assert(
isUnion() &&
"Invalid accessor");
763 return *((UnionData *)(
char *)&Data)->Value;
769 const ValueDecl *getMemberPointerDecl()
const;
770 bool isMemberPointerToDerivedMember()
const;
775 return ((
const AddrLabelDiffData *)(
const char *)&Data)->LHSExpr;
779 return ((
const AddrLabelDiffData *)(
const char *)&Data)->RHSExpr;
784 return ((
const ReflectionData *)(
const char *)&Data)->OperandKind;
789 return ((
const ReflectionData *)(
const char *)&Data)->Operand;
793 assert(
isInt() &&
"Invalid accessor");
794 *(APSInt *)(
char *)&Data = std::move(I);
797 assert(
isFloat() &&
"Invalid accessor");
798 *(APFloat *)(
char *)&Data = std::move(F);
802 *(APFixedPoint *)(
char *)&Data = std::move(FX);
806 for (
unsigned i = 0; i != N; ++i)
807 InternalElts[i] = E[i];
811 for (
unsigned i = 0; i != NumRows * NumCols; ++i)
812 InternalElts[i] = E[i];
815 assert(R.getBitWidth() == I.getBitWidth() &&
816 "Invalid complex int (type mismatch).");
818 ((ComplexAPSInt *)(
char *)&Data)->Real = std::move(R);
819 ((ComplexAPSInt *)(
char *)&Data)->Imag = std::move(I);
822 assert(&R.getSemantics() == &I.getSemantics() &&
823 "Invalid complex float (type mismatch).");
825 ((ComplexAPFloat *)(
char *)&Data)->Real = std::move(R);
826 ((ComplexAPFloat *)(
char *)&Data)->Imag = std::move(I);
828 void setLValue(LValueBase B,
CharUnits O, NoLValuePath,
bool IsNullPtr);
830 bool OnePastTheEnd,
bool IsNullPtr);
834 ((AddrLabelDiffData *)(
char *)&Data)->LHSExpr = LHSExpr;
835 ((AddrLabelDiffData *)(
char *)&Data)->RHSExpr = RHSExpr;
839 void DestroyDataAndMakeUninit();
840 void MakeReflection(
ReflectionKind OperandKind,
const void *Operand) {
841 assert(isAbsent() &&
"Bad state change");
842 new ((
void *)(
char *)
Data.buffer) ReflectionData{OperandKind, Operand};
845 void MakeInt(
const APSInt &I) {
846 assert(isAbsent() &&
"Bad state change");
847 new ((
void *)&Data)
APSInt(std::move(I));
850 void MakeInt(
APSInt &&I) {
851 assert(isAbsent() &&
"Bad state change");
852 new ((
void *)&Data)
APSInt(std::move(I));
855 void MakeFloat(
const APFloat &F) {
856 assert(isAbsent() &&
"Bad state change");
857 new ((
void *)(
char *)&Data)
APFloat(F);
860 void MakeFloat(APFloat &&F) {
861 assert(isAbsent() &&
"Bad state change");
862 new ((
void *)(
char *)&Data)
APFloat(std::move(F));
865 void MakeFixedPoint(APFixedPoint &&FX) {
866 assert(isAbsent() &&
"Bad state change");
867 new ((
void *)(
char *)&Data) APFixedPoint(std::move(FX));
871 assert(isAbsent() &&
"Bad state change");
872 new ((
void *)(
char *)&Data) Vec();
876 assert(isAbsent() &&
"Bad state change");
877 new ((
void *)(
char *)&Data) Mat();
880 void MakeComplexInt() {
881 assert(isAbsent() &&
"Bad state change");
882 new ((
void *)(
char *)&Data) ComplexAPSInt();
885 void MakeComplexFloat() {
886 assert(isAbsent() &&
"Bad state change");
887 new ((
void *)(
char *)&Data) ComplexAPFloat();
891 void MakeArray(
unsigned InitElts,
unsigned Size);
892 void MakeStruct(
unsigned B,
unsigned M,
unsigned V) {
893 assert(isAbsent() &&
"Bad state change");
894 new ((
void *)(
char *)&Data) StructData(B, M,
V);
898 assert(isAbsent() &&
"Bad state change");
899 new ((
void *)(
char *)&Data) UnionData();
902 void MakeMemberPointer(
const ValueDecl *Member,
bool IsDerivedMember,
903 ArrayRef<const CXXRecordDecl*> Path);
904 void MakeAddrLabelDiff() {
905 assert(isAbsent() &&
"Bad state change");
906 new ((
void *)(
char *)&Data) AddrLabelDiffData();
914 MutableArrayRef<APValue> setVectorUninit(
unsigned N) {
915 assert(
isVector() &&
"Invalid accessor");
916 Vec *
V = ((Vec *)(
char *)&Data);
919 return {
V->Elts,
V->NumElts};
921 MutableArrayRef<APValue> setMatrixUninit(
unsigned NumRows,
unsigned NumCols) {
922 assert(isMatrix() &&
"Invalid accessor");
923 Mat *M = ((Mat *)(
char *)&Data);
924 unsigned NumElts = NumRows * NumCols;
925 M->Elts =
new APValue[NumElts];
926 M->NumRows = NumRows;
927 M->NumCols = NumCols;
928 return {M->Elts, NumElts};
930 MutableArrayRef<LValuePathEntry> setLValueUninit(LValueBase B, CharUnits O,
934 MutableArrayRef<const CXXRecordDecl *>
935 setMemberPointerUninit(
const ValueDecl *Member,
bool IsDerivedMember,
942template<>
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(APFloat F)
Creates a float APValue holding the given value.
const APValue & getMatrixElt(unsigned Idx) const
APValue & getArrayInitializedElt(unsigned I)
const void * getReflectionOpaqueOperand() const
APValue(ReflectionKind OperandKind, const void *Operand)
Creates a new Reflection APValue.
APValue & getStructField(unsigned i)
bool isReflection() const
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
ReflectionKind getReflectionOperandKind() const
APValue & getStructVirtualBase(unsigned i)
const APValue & getMatrixElt(unsigned Row, unsigned Col) const
APValue(LValueBase Base, CharUnits Offset, ArrayRef< LValuePathEntry > Path, bool OnePastTheEnd, bool IsNullPtr=false)
Creates an lvalue APValue with an lvalue path.
APValue(const APValue *E, unsigned N)
Creates a vector APValue with N elements.
void setFixedPoint(APFixedPoint FX)
unsigned getArrayInitializedElts() const
static APValue IndeterminateValue()
void setLValue(LValueBase B, CharUnits O, NoLValuePath, bool IsNullPtr)
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 & 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)
APValue(LValueBase Base, CharUnits Offset, ConstexprUnknown, bool IsNullPtr=false)
Creates a constexpr unknown lvalue APValue.
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
APValue & getArrayFiller()
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(LValueBase Base, CharUnits Offset, NoLValuePath, bool IsNullPtr=false)
Creates an lvalue APValue without an lvalue path.
CharUnits getLValueOffset() const
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
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.
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.
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.
DynamicAllocLValue(unsigned Idx, DynAllocKind AllocKind)
static constexpr int NumAllocKindBits
const void * getOpaqueValue() const
static constexpr int NumLowBitsAvailable
static uintptr_t getMaxIndex()
unsigned getIndex() const
DynAllocKind getAllocKind() const
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.
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
DynAllocKind
Kind of source for a dynamic allocation.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
@ Result
The result type of a method or function.
const FunctionProtoType * T
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