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/Support/AlignOf.h"
26#include "llvm/Support/Compiler.h"
54 explicit operator bool()
const {
return T; }
75 explicit operator bool()
const {
return Index != 0; }
78 return reinterpret_cast<const void *
>(
static_cast<uintptr_t>(Index)
98 return V.getOpaqueValue();
110 return V.getOpaqueValue();
125 typedef llvm::APFixedPoint APFixedPoint;
126 typedef llvm::APSInt APSInt;
127 typedef llvm::APFloat APFloat;
162 void Profile(llvm::FoldingSetNodeID &ID)
const;
164 template <
class T>
bool is()
const {
return isa<T>(Ptr); }
169 return dyn_cast_if_present<T>(Ptr);
172 void *getOpaqueValue()
const;
176 explicit operator bool()
const;
178 unsigned getCallIndex()
const;
179 unsigned getVersion()
const;
181 QualType getDynamicAllocType()
const;
187 return !(LHS == RHS);
195 unsigned CallIndex, Version;
212 static_assert(
sizeof(
uintptr_t) <=
sizeof(uint64_t),
213 "pointer doesn't fit in 64 bits?");
226 return BaseOrMemberType::getFromOpaqueValue(
227 reinterpret_cast<void *
>(Value));
231 void Profile(llvm::FoldingSetNodeID &ID)
const;
234 return A.Value == B.Value;
237 return A.Value != B.Value;
263 bool AllowConstexprUnknown : 1;
265 struct ComplexAPSInt {
267 ComplexAPSInt() : Real(1), Imag(1) {}
269 struct ComplexAPFloat {
271 ComplexAPFloat() : Real(0.0), Imag(0.0) {}
276 unsigned NumElts = 0;
278 Vec(
const Vec &) =
delete;
279 Vec &operator=(
const Vec &) =
delete;
280 ~Vec() {
delete[] Elts; }
284 unsigned NumRows = 0;
285 unsigned NumCols = 0;
287 Mat(
const Mat &) =
delete;
288 Mat &operator=(
const Mat &) =
delete;
289 ~Mat() {
delete[] Elts; }
293 unsigned NumElts, ArrSize;
294 Arr(
unsigned NumElts,
unsigned ArrSize);
295 Arr(
const Arr &) =
delete;
296 Arr &operator=(
const Arr &) =
delete;
303 unsigned NumVirtualBases;
304 StructData(
unsigned NumBases,
unsigned NumFields,
unsigned NumVirtualBases);
305 StructData(
const StructData &) =
delete;
306 StructData &operator=(
const StructData &) =
delete;
310 const FieldDecl *
Field;
313 UnionData(
const UnionData &) =
delete;
314 UnionData &operator=(
const UnionData &) =
delete;
317 struct AddrLabelDiffData {
318 const AddrLabelExpr* LHSExpr;
319 const AddrLabelExpr* RHSExpr;
321 struct ReflectionData {
332 struct MemberPointerData;
335 typedef llvm::AlignedCharArrayUnion<
336 void *,
APSInt,
APFloat, ComplexAPSInt, ComplexAPFloat, Vec, Mat, Arr,
337 StructData, UnionData, AddrLabelDiffData, ReflectionData>
339 static const size_t DataSize =
sizeof(DataType);
347 AllowConstexprUnknown = IsConstexprUnknown;
354 MakeInt(std::move(I));
358 MakeFloat(std::move(F));
362 MakeFixedPoint(std::move(FX));
367 : Kind(
None), AllowConstexprUnknown(
false) {
373 : Kind(
None), AllowConstexprUnknown(
false) {
393 bool IsNullPtr =
false)
394 : Kind(
None), AllowConstexprUnknown(
false) {
406 bool OnePastTheEnd,
bool IsNullPtr =
false)
407 : Kind(
None), AllowConstexprUnknown(
false) {
416 bool IsNullPtr =
false)
417 : Kind(
None), AllowConstexprUnknown(
true) {
428 : Kind(
None), AllowConstexprUnknown(
false) {
429 MakeArray(InitElts, Size);
436 MakeReflection(OperandKind, Operand);
445 unsigned NumVirtualBases = 0)
446 : Kind(
None), AllowConstexprUnknown(
false) {
447 MakeStruct(NumBases, NumMembers, NumVirtualBases);
454 : Kind(
None), AllowConstexprUnknown(
false) {
464 : Kind(
None), AllowConstexprUnknown(
false) {
465 MakeMemberPointer(
Member, IsDerivedMember, Path);
471 : Kind(
None), AllowConstexprUnknown(
false) {
485 DestroyDataAndMakeUninit();
493 bool needsCleanup()
const;
501 void Profile(llvm::FoldingSetNodeID &ID)
const;
534 assert(
isInt() &&
"Invalid accessor");
535 return *(APSInt *)(
char *)&Data;
548 assert(
isFloat() &&
"Invalid accessor");
549 return *(APFloat *)(
char *)&Data;
557 return *(APFixedPoint *)(
char *)&Data;
565 return ((ComplexAPSInt *)(
char *)&Data)->Real;
573 return ((ComplexAPSInt *)(
char *)&Data)->Imag;
581 return ((ComplexAPFloat *)(
char *)&Data)->Real;
589 return ((ComplexAPFloat *)(
char *)&Data)->Imag;
595 const LValueBase getLValueBase()
const;
600 bool isLValueOnePastTheEnd()
const;
601 bool hasLValuePath()
const;
603 unsigned getLValueCallIndex()
const;
604 unsigned getLValueVersion()
const;
605 bool isNullPointer()
const;
608 assert(
isVector() &&
"Invalid accessor");
610 return ((Vec *)(
char *)&Data)->Elts[I];
616 assert(
isVector() &&
"Invalid accessor");
617 return ((
const Vec *)(
const void *)&Data)->NumElts;
621 assert(
isMatrix() &&
"Invalid accessor");
622 return ((
const Mat *)(
const void *)&Data)->NumRows;
625 assert(
isMatrix() &&
"Invalid accessor");
626 return ((
const Mat *)(
const void *)&Data)->NumCols;
632 assert(
isMatrix() &&
"Invalid accessor");
634 return ((Mat *)(
char *)&Data)->Elts[Idx];
640 assert(
isMatrix() &&
"Invalid accessor");
652 assert(
isArray() &&
"Invalid accessor");
654 return ((Arr *)(
char *)&Data)->Elts[I];
663 assert(
isArray() &&
"Invalid accessor");
671 assert(
isArray() &&
"Invalid accessor");
672 return ((
const Arr *)(
const void *)&Data)->NumElts;
675 assert(
isArray() &&
"Invalid accessor");
676 return ((
const Arr *)(
const void *)&Data)->ArrSize;
680 assert(
isStruct() &&
"Invalid accessor");
681 return ((
const StructData *)(
const char *)&Data)->NumBases;
684 assert(
isStruct() &&
"Invalid accessor");
685 return ((
const StructData *)(
const char *)&Data)->NumFields;
688 assert(
isStruct() &&
"Invalid accessor");
689 return ((
const StructData *)(
const char *)&Data)->NumVirtualBases;
692 assert(
isStruct() &&
"Invalid accessor");
694 return ((StructData *)(
char *)&Data)->Elts[i];
697 assert(
isStruct() &&
"Invalid accessor");
702 assert(
isStruct() &&
"Invalid accessor");
704 return ((StructData *)(
char *)&Data)
718 assert(
isUnion() &&
"Invalid accessor");
719 return ((
const UnionData *)(
const char *)&Data)->Field;
722 assert(
isUnion() &&
"Invalid accessor");
723 return *((UnionData *)(
char *)&Data)->Value;
729 const ValueDecl *getMemberPointerDecl()
const;
730 bool isMemberPointerToDerivedMember()
const;
735 return ((
const AddrLabelDiffData *)(
const char *)&Data)->LHSExpr;
739 return ((
const AddrLabelDiffData *)(
const char *)&Data)->RHSExpr;
744 return ((
const ReflectionData *)(
const char *)&Data)->OperandKind;
749 return ((
const ReflectionData *)(
const char *)&Data)->Operand;
753 assert(
isInt() &&
"Invalid accessor");
754 *(APSInt *)(
char *)&Data = std::move(I);
757 assert(
isFloat() &&
"Invalid accessor");
758 *(APFloat *)(
char *)&Data = std::move(F);
762 *(APFixedPoint *)(
char *)&Data = std::move(FX);
766 for (
unsigned i = 0; i != N; ++i)
767 InternalElts[i] = E[i];
771 for (
unsigned i = 0; i != NumRows * NumCols; ++i)
772 InternalElts[i] = E[i];
775 assert(R.getBitWidth() == I.getBitWidth() &&
776 "Invalid complex int (type mismatch).");
778 ((ComplexAPSInt *)(
char *)&Data)->Real = std::move(R);
779 ((ComplexAPSInt *)(
char *)&Data)->Imag = std::move(I);
782 assert(&R.getSemantics() == &I.getSemantics() &&
783 "Invalid complex float (type mismatch).");
785 ((ComplexAPFloat *)(
char *)&Data)->Real = std::move(R);
786 ((ComplexAPFloat *)(
char *)&Data)->Imag = std::move(I);
788 void setLValue(LValueBase B,
CharUnits O, NoLValuePath,
bool IsNullPtr);
790 bool OnePastTheEnd,
bool IsNullPtr);
794 ((AddrLabelDiffData *)(
char *)&Data)->LHSExpr = LHSExpr;
795 ((AddrLabelDiffData *)(
char *)&Data)->RHSExpr = RHSExpr;
799 void DestroyDataAndMakeUninit();
800 void MakeReflection(
ReflectionKind OperandKind,
const void *Operand) {
801 assert(isAbsent() &&
"Bad state change");
802 new ((
void *)(
char *)
Data.buffer) ReflectionData{OperandKind, Operand};
805 void MakeInt(
const APSInt &I) {
806 assert(isAbsent() &&
"Bad state change");
807 new ((
void *)&Data)
APSInt(std::move(I));
810 void MakeInt(
APSInt &&I) {
811 assert(isAbsent() &&
"Bad state change");
812 new ((
void *)&Data)
APSInt(std::move(I));
815 void MakeFloat(
const APFloat &F) {
816 assert(isAbsent() &&
"Bad state change");
817 new ((
void *)(
char *)&Data)
APFloat(F);
820 void MakeFloat(APFloat &&F) {
821 assert(isAbsent() &&
"Bad state change");
822 new ((
void *)(
char *)&Data)
APFloat(std::move(F));
825 void MakeFixedPoint(APFixedPoint &&FX) {
826 assert(isAbsent() &&
"Bad state change");
827 new ((
void *)(
char *)&Data) APFixedPoint(std::move(FX));
831 assert(isAbsent() &&
"Bad state change");
832 new ((
void *)(
char *)&Data) Vec();
836 assert(isAbsent() &&
"Bad state change");
837 new ((
void *)(
char *)&Data) Mat();
840 void MakeComplexInt() {
841 assert(isAbsent() &&
"Bad state change");
842 new ((
void *)(
char *)&Data) ComplexAPSInt();
845 void MakeComplexFloat() {
846 assert(isAbsent() &&
"Bad state change");
847 new ((
void *)(
char *)&Data) ComplexAPFloat();
851 void MakeArray(
unsigned InitElts,
unsigned Size);
852 void MakeStruct(
unsigned B,
unsigned M,
unsigned V) {
853 assert(isAbsent() &&
"Bad state change");
854 new ((
void *)(
char *)&Data) StructData(B, M,
V);
858 assert(isAbsent() &&
"Bad state change");
859 new ((
void *)(
char *)&Data) UnionData();
862 void MakeMemberPointer(
const ValueDecl *Member,
bool IsDerivedMember,
863 ArrayRef<const CXXRecordDecl*> Path);
864 void MakeAddrLabelDiff() {
865 assert(isAbsent() &&
"Bad state change");
866 new ((
void *)(
char *)&Data) AddrLabelDiffData();
874 MutableArrayRef<APValue> setVectorUninit(
unsigned N) {
875 assert(
isVector() &&
"Invalid accessor");
876 Vec *
V = ((Vec *)(
char *)&Data);
879 return {
V->Elts,
V->NumElts};
881 MutableArrayRef<APValue> setMatrixUninit(
unsigned NumRows,
unsigned NumCols) {
882 assert(isMatrix() &&
"Invalid accessor");
883 Mat *M = ((Mat *)(
char *)&Data);
884 unsigned NumElts = NumRows * NumCols;
885 M->Elts =
new APValue[NumElts];
886 M->NumRows = NumRows;
887 M->NumCols = NumCols;
888 return {M->Elts, NumElts};
890 MutableArrayRef<LValuePathEntry> setLValueUninit(LValueBase B, CharUnits O,
894 MutableArrayRef<const CXXRecordDecl *>
895 setMemberPointerUninit(
const ValueDecl *Member,
bool IsDerivedMember,
902template<>
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.
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.
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
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