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"
26namespace serialization {
52 explicit operator bool()
const {
return T; }
73 explicit operator bool()
const {
return Index != 0; }
76 return reinterpret_cast<void *
>(
static_cast<uintptr_t>(Index)
96 return V.getOpaqueValue();
103 static constexpr int NumLowBitsAvailable = 3;
108 return V.getOpaqueValue();
113 static constexpr int NumLowBitsAvailable =
123 typedef llvm::APFixedPoint APFixedPoint;
124 typedef llvm::APSInt APSInt;
125 typedef llvm::APFloat APFloat;
158 void Profile(llvm::FoldingSetNodeID &
ID)
const;
160 template <
class T>
bool is()
const {
return isa<T>(Ptr); }
162 template <
class T>
T get()
const {
return cast<T>(Ptr); }
171 explicit operator bool()
const;
182 return !(LHS == RHS);
190 unsigned CallIndex, Version;
207 static_assert(
sizeof(
uintptr_t) <=
sizeof(uint64_t),
208 "pointer doesn't fit in 64 bits?");
221 return BaseOrMemberType::getFromOpaqueValue(
222 reinterpret_cast<void *
>(
Value));
226 void Profile(llvm::FoldingSetNodeID &
ID)
const;
229 return A.Value == B.Value;
232 return A.Value != B.Value;
258 bool AllowConstexprUnknown : 1;
260 struct ComplexAPSInt {
262 ComplexAPSInt() : Real(1), Imag(1) {}
264 struct ComplexAPFloat {
266 ComplexAPFloat() : Real(0.0), Imag(0.0) {}
271 unsigned NumElts = 0;
273 Vec(
const Vec &) =
delete;
274 Vec &operator=(
const Vec &) =
delete;
275 ~Vec() {
delete[] Elts; }
279 unsigned NumElts, ArrSize;
280 Arr(
unsigned NumElts,
unsigned ArrSize);
281 Arr(
const Arr &) =
delete;
282 Arr &operator=(
const Arr &) =
delete;
289 StructData(
unsigned NumBases,
unsigned NumFields);
290 StructData(
const StructData &) =
delete;
291 StructData &operator=(
const StructData &) =
delete;
295 const FieldDecl *
Field;
298 UnionData(
const UnionData &) =
delete;
299 UnionData &operator=(
const UnionData &) =
delete;
302 struct AddrLabelDiffData {
303 const AddrLabelExpr* LHSExpr;
304 const AddrLabelExpr* RHSExpr;
306 struct MemberPointerData;
309 typedef llvm::AlignedCharArrayUnion<
void *,
APSInt,
APFloat, ComplexAPSInt,
310 ComplexAPFloat, Vec, Arr, StructData,
311 UnionData, AddrLabelDiffData> DataType;
312 static const size_t DataSize =
sizeof(DataType);
320 AllowConstexprUnknown = IsConstexprUnknown;
327 MakeInt();
setInt(std::move(I));
331 MakeFloat();
setFloat(std::move(F));
335 MakeFixedPoint(std::move(FX));
359 bool IsNullPtr =
false)
373 bool IsNullPtr =
false)
383 bool IsNullPtr =
false)
396 MakeArray(InitElts, Size);
404 MakeStruct(NumBases, NumMembers);
422 MakeMemberPointer(
Member, IsDerivedMember,
Path);
442 DestroyDataAndMakeUninit();
458 void Profile(llvm::FoldingSetNodeID &
ID)
const;
489 assert(
isInt() &&
"Invalid accessor");
490 return *(APSInt *)(
char *)&
Data;
503 assert(
isFloat() &&
"Invalid accessor");
504 return *(APFloat *)(
char *)&
Data;
512 return *(APFixedPoint *)(
char *)&
Data;
520 return ((ComplexAPSInt *)(
char *)&
Data)->Real;
528 return ((ComplexAPSInt *)(
char *)&
Data)->Imag;
536 return ((ComplexAPFloat *)(
char *)&
Data)->Real;
544 return ((ComplexAPFloat *)(
char *)&
Data)->Imag;
563 assert(
isVector() &&
"Invalid accessor");
565 return ((Vec *)(
char *)&
Data)->Elts[I];
571 assert(
isVector() &&
"Invalid accessor");
572 return ((
const Vec *)(
const void *)&
Data)->NumElts;
576 assert(
isArray() &&
"Invalid accessor");
578 return ((Arr *)(
char *)&
Data)->Elts[I];
587 assert(
isArray() &&
"Invalid accessor");
595 assert(
isArray() &&
"Invalid accessor");
596 return ((
const Arr *)(
const void *)&
Data)->NumElts;
599 assert(
isArray() &&
"Invalid accessor");
600 return ((
const Arr *)(
const void *)&
Data)->ArrSize;
604 assert(
isStruct() &&
"Invalid accessor");
605 return ((
const StructData *)(
const char *)&
Data)->NumBases;
608 assert(
isStruct() &&
"Invalid accessor");
609 return ((
const StructData *)(
const char *)&
Data)->NumFields;
612 assert(
isStruct() &&
"Invalid accessor");
614 return ((StructData *)(
char *)&
Data)->Elts[i];
617 assert(
isStruct() &&
"Invalid accessor");
629 assert(
isUnion() &&
"Invalid accessor");
630 return ((
const UnionData *)(
const char *)&
Data)->Field;
633 assert(
isUnion() &&
"Invalid accessor");
634 return *((UnionData *)(
char *)&
Data)->
Value;
646 return ((
const AddrLabelDiffData *)(
const char *)&
Data)->LHSExpr;
650 return ((
const AddrLabelDiffData *)(
const char *)&
Data)->RHSExpr;
654 assert(
isInt() &&
"Invalid accessor");
655 *(APSInt *)(
char *)&
Data = std::move(I);
658 assert(
isFloat() &&
"Invalid accessor");
659 *(APFloat *)(
char *)&
Data = std::move(F);
663 *(APFixedPoint *)(
char *)&
Data = std::move(FX);
667 for (
unsigned i = 0; i != N; ++i)
668 InternalElts[i] =
E[i];
671 assert(R.getBitWidth() == I.getBitWidth() &&
672 "Invalid complex int (type mismatch).");
674 ((ComplexAPSInt *)(
char *)&
Data)->Real = std::move(R);
675 ((ComplexAPSInt *)(
char *)&
Data)->Imag = std::move(I);
678 assert(&R.getSemantics() == &I.getSemantics() &&
679 "Invalid complex float (type mismatch).");
681 ((ComplexAPFloat *)(
char *)&
Data)->Real = std::move(R);
682 ((ComplexAPFloat *)(
char *)&
Data)->Imag = std::move(I);
692 ((AddrLabelDiffData *)(
char *)&
Data)->LHSExpr = LHSExpr;
693 ((AddrLabelDiffData *)(
char *)&
Data)->RHSExpr = RHSExpr;
697 void DestroyDataAndMakeUninit();
699 assert(
isAbsent() &&
"Bad state change");
704 assert(
isAbsent() &&
"Bad state change");
705 new ((
void *)(
char *)&
Data) APFloat(0.0);
708 void MakeFixedPoint(APFixedPoint &&FX) {
709 assert(
isAbsent() &&
"Bad state change");
710 new ((
void *)(
char *)&
Data) APFixedPoint(std::move(FX));
714 assert(
isAbsent() &&
"Bad state change");
715 new ((
void *)(
char *)&
Data) Vec();
718 void MakeComplexInt() {
719 assert(
isAbsent() &&
"Bad state change");
720 new ((
void *)(
char *)&
Data) ComplexAPSInt();
723 void MakeComplexFloat() {
724 assert(
isAbsent() &&
"Bad state change");
725 new ((
void *)(
char *)&
Data) ComplexAPFloat();
729 void MakeArray(
unsigned InitElts,
unsigned Size);
730 void MakeStruct(
unsigned B,
unsigned M) {
731 assert(
isAbsent() &&
"Bad state change");
732 new ((
void *)(
char *)&
Data) StructData(B, M);
736 assert(
isAbsent() &&
"Bad state change");
737 new ((
void *)(
char *)&
Data) UnionData();
740 void MakeMemberPointer(
const ValueDecl *
Member,
bool IsDerivedMember,
741 ArrayRef<const CXXRecordDecl*>
Path);
742 void MakeAddrLabelDiff() {
743 assert(
isAbsent() &&
"Bad state change");
744 new ((
void *)(
char *)&
Data) AddrLabelDiffData();
752 MutableArrayRef<APValue> setVectorUninit(
unsigned N) {
753 assert(
isVector() &&
"Invalid accessor");
754 Vec *
V = ((Vec *)(
char *)&
Data);
757 return {
V->Elts,
V->NumElts};
759 MutableArrayRef<LValuePathEntry>
760 setLValueUninit(LValueBase B,
const CharUnits &O,
unsigned Size,
761 bool OnePastTheEnd,
bool IsNullPtr);
762 MutableArrayRef<const CXXRecordDecl *>
763 setMemberPointerUninit(
const ValueDecl *
Member,
bool IsDerivedMember,
770template<>
struct DenseMapInfo<
clang::APValue::LValueBase> {
enum clang::sema::@1727::IndirectLocalPathEntry::EntryKind Kind
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
friend llvm::hash_code hash_value(const LValueBase &Base)
friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS)
void Profile(llvm::FoldingSetNodeID &ID) const
unsigned getVersion() const
QualType getDynamicAllocType() const
QualType getTypeInfoType() const
friend bool operator==(const LValueBase &LHS, const LValueBase &RHS)
void * DynamicAllocType
The QualType, if this is a DynamicAllocLValue.
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
void * TypeInfoType
The type std::type_info, if this is a TypeInfoLValue.
void * getOpaqueValue() const
unsigned getCallIndex() const
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)
void Profile(llvm::FoldingSetNodeID &ID) const
ArrayRef< LValuePathEntry > Path
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
const APSInt & getComplexIntReal() const
bool hasArrayFiller() const
const LValueBase getLValueBase() 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.
APValue & getArrayInitializedElt(unsigned I)
ArrayRef< LValuePathEntry > getLValuePath() const
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
APValue & getStructField(unsigned i)
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
bool isLValueOnePastTheEnd() const
APValue(const APValue *E, unsigned N)
Creates a vector APValue with N elements.
void setFixedPoint(APFixedPoint FX)
unsigned getLValueVersion() const
bool isMemberPointerToDerivedMember() const
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.
bool needsCleanup() const
Returns whether the object performed allocations.
const APValue & getStructBase(unsigned i) const
APValue(LValueBase Base, const CharUnits &Offset, ArrayRef< LValuePathEntry > Path, bool OnePastTheEnd, bool IsNullPtr=false)
Creates an lvalue APValue with an lvalue path.
bool hasLValuePath() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
const AddrLabelExpr * getAddrLabelDiffRHS() const
CharUnits & getLValueOffset()
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
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
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, bool IsNullPtr)
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
bool isMemberPointer() const
const APSInt & getInt() const
const APFloat & getComplexFloatReal() const
unsigned getArraySize() const
APValue(APSInt R, APSInt I)
Creates an integer complex APValue with the given real and imaginary values.
bool toIntegralConstant(APSInt &Result, QualType SrcTy, const ASTContext &Ctx) const
Try to convert this value to an integral constant.
const CharUnits & getLValueOffset() const
bool allowConstexprUnknown() const
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
bool isFixedPoint() const
APValue & operator=(const APValue &RHS)
unsigned getLValueCallIndex() const
void setVector(const APValue *E, unsigned N)
@ 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
bool isNullPointer() 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
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 ...
Imports selected nodes from one AST context into another context, merging AST nodes where appropriate...
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()
static constexpr int NumLowBitsAvailable
DynamicAllocLValue(unsigned Index)
static DynamicAllocLValue getFromOpaqueValue(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(void *Value)
void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) 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.
@ Result
The result type of a method or function.
const FunctionProtoType * T
Diagnostic wrappers for TextAPI types for error reporting.
hash_code hash_value(const clang::tooling::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 void * getAsVoidPointer(clang::DynamicAllocLValue V)
static clang::DynamicAllocLValue getFromVoidPointer(void *P)
static void * getAsVoidPointer(clang::TypeInfoLValue V)
static clang::TypeInfoLValue getFromVoidPointer(void *P)