21#include "llvm/Support/ErrorHandling.h"
22#include "llvm/Support/raw_ostream.h"
28 :
T(
T->getCanonicalTypeUnqualified().getTypePtr()) {}
40 "Type is insufficiently aligned");
45 : Ptr(
P), Local{I,
V} {}
51 Base.DynamicAllocType =
Type.getAsOpaquePtr();
65 if (
const ValueDecl *
D = dyn_cast<const ValueDecl*>()) {
74 Redecl = cast_or_null<ValueDecl>(Redecl->getPreviousDecl())) {
82 if (is<TypeInfoLValue>())
83 return getTypeInfoType();
85 if (is<DynamicAllocLValue>())
86 return getDynamicAllocType();
88 const Expr *
Base = get<const Expr*>();
93 llvm::dyn_cast<MaterializeTemporaryExpr>(
Base)) {
96 const Expr *Temp = MTE->getSubExpr();
101 if (!Adjustments.empty())
102 return Inner->getType();
105 return Base->getType();
109 return (is<TypeInfoLValue>() || is<DynamicAllocLValue>()) ? 0
114 return (is<TypeInfoLValue>() || is<DynamicAllocLValue>()) ? 0 : Local.Version;
118 assert(is<TypeInfoLValue>() &&
"not a type_info lvalue");
123 assert(is<DynamicAllocLValue>() &&
"not a dynamic allocation lvalue");
128 ID.AddPointer(Ptr.getOpaqueValue());
129 if (is<TypeInfoLValue>() || is<DynamicAllocLValue>())
131 ID.AddInteger(Local.CallIndex);
132 ID.AddInteger(Local.Version);
138 if (LHS.Ptr != RHS.Ptr)
142 return LHS.
Local.CallIndex == RHS.
Local.CallIndex &&
148 if (
const Decl *
D = BaseOrMember.getPointer())
150 Value =
reinterpret_cast<uintptr_t>(BaseOrMember.getOpaqueValue());
154 ID.AddInteger(
Value);
159 : Ty((const void *)ElemTy.getTypePtrOrNull()),
Path(
Path) {}
171 bool IsOnePastTheEnd : 1;
176 return Ptr.getOpaqueValue();
183APValue::LValueBase::operator
bool ()
const {
184 return static_cast<bool>(Ptr);
188llvm::DenseMapInfo<clang::APValue::LValueBase>::getEmptyKey() {
190 B.Ptr = DenseMapInfo<const ValueDecl*>::getEmptyKey();
195llvm::DenseMapInfo<clang::APValue::LValueBase>::getTombstoneKey() {
197 B.Ptr = DenseMapInfo<const ValueDecl*>::getTombstoneKey();
205 return llvm::hash_combine(
Base.getOpaqueValue(),
Base.getCallIndex(),
210unsigned llvm::DenseMapInfo<clang::APValue::LValueBase>::getHashValue(
215bool llvm::DenseMapInfo<clang::APValue::LValueBase>::isEqual(
222 static const unsigned InlinePathSpace =
237 if (Length == PathLength)
247 bool hasPathPtr()
const {
return hasPath() && PathLength > InlinePathSpace; }
251 return hasPathPtr() ? PathPtr :
Path;
256 struct MemberPointerBase {
257 llvm::PointerIntPair<const ValueDecl*, 1, bool> MemberAndIsDerivedMember;
263 static const unsigned InlinePathSpace =
264 (DataSize -
sizeof(MemberPointerBase)) /
sizeof(
const CXXRecordDecl*);
275 if (Length == PathLength)
284 bool hasPathPtr()
const {
return PathLength > InlinePathSpace; }
288 return hasPathPtr() ? PathPtr :
Path;
294APValue::Arr::Arr(
unsigned NumElts,
unsigned Size) :
295 Elts(new
APValue[NumElts + (NumElts != Size ? 1 : 0)]),
296 NumElts(NumElts), ArrSize(Size) {}
297APValue::Arr::~Arr() {
delete [] Elts; }
299APValue::StructData::StructData(
unsigned NumBases,
unsigned NumFields) :
300 Elts(new
APValue[NumBases+NumFields]),
301 NumBases(NumBases), NumFields(NumFields) {}
302APValue::StructData::~StructData() {
307APValue::UnionData::~UnionData () {
327 MakeFixedPoint(std::move(FXCopy));
332 setVector(((
const Vec *)(
const char *)&RHS.Data)->Elts,
395 DestroyDataAndMakeUninit();
403void APValue::DestroyDataAndMakeUninit() {
406 else if (Kind ==
Float)
407 ((APFloat *)(
char *)&Data)->~APFloat();
409 ((APFixedPoint *)(
char *)&Data)->~APFixedPoint();
411 ((Vec *)(
char *)&Data)->~Vec();
413 ((ComplexAPSInt *)(
char *)&Data)->~ComplexAPSInt();
415 ((ComplexAPFloat *)(
char *)&Data)->~ComplexAPFloat();
417 ((LV *)(
char *)&Data)->~LV();
418 else if (Kind ==
Array)
419 ((Arr *)(
char *)&Data)->~Arr();
421 ((StructData *)(
char *)&Data)->~StructData();
422 else if (Kind ==
Union)
423 ((UnionData *)(
char *)&Data)->~UnionData();
425 ((MemberPointerData *)(
char *)&Data)->~MemberPointerData();
427 ((AddrLabelDiffData *)(
char *)&Data)->~AddrLabelDiffData();
443 return getInt().needsCleanup();
451 "In _Complex float types, real and imaginary values always have the "
457 "In _Complex int types, real and imaginary values must have the "
461 return reinterpret_cast<const LV *
>(&Data)->hasPathPtr();
465 llvm_unreachable(
"Unknown APValue kind!");
469 std::swap(Kind, RHS.Kind);
470 std::swap(Data, RHS.Data);
475 for (
unsigned I = 0, N =
V.getBitWidth(); I < N; I += 32)
476 ID.AddInteger((uint32_t)
V.extractBitsAsZExtValue(std::min(32u, N - I), I));
525 llvm::FoldingSetNodeID FillerID;
529 ID.AddNodeID(FillerID);
540 ID.AddInteger(NumFillers);
547 llvm::FoldingSetNodeID ElemID;
549 if (ElemID != FillerID) {
550 ID.AddInteger(NumFillers);
551 ID.AddNodeID(ElemID);
619 llvm_unreachable(
"Unknown APValue kind!");
625 V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
627 return V.convertToDouble();
642 if (!Inits.back().isInt() || !Inits.back().getInt().isZero())
645 Inits = Inits.drop_back();
651 constexpr size_t MaxN = 36;
656 Inits.take_front(std::min(MaxN - Ellipsis.size() / 2, Inits.size()));
659 for (
auto &Val : Inits) {
662 int64_t Char64 = Val.getInt().getExtValue();
665 auto Ch =
static_cast<unsigned char>(Char64);
667 StringRef Escaped = escapeCStyle<EscapeChar::SingleAndDouble>(Ch);
668 if (Escaped.empty()) {
671 Buf.emplace_back(Ch);
677 Buf.append(Ellipsis);
708 Ty = AT->getValueType();
712 Out <<
"<out of lifetime>";
715 Out <<
"<uninitialized>";
719 Out << (
getInt().getBoolValue() ?
"true" :
"false");
757 Out << (Policy.
Nullptr ?
"nullptr" :
"0");
758 }
else if (IsReference) {
759 Out <<
"*(" << InnerTy.
stream(Policy) <<
"*)"
762 Out <<
"(" << Ty.
stream(Policy) <<
")"
777 if (S.isZero() || O % S) {
782 }
else if (!IsReference) {
789 TI.print(Out, Policy);
792 <<
Base.getDynamicAllocType().stream(Policy) <<
"#"
793 << DA.getIndex() <<
"}";
795 assert(
Base.get<
const Expr *>() !=
nullptr &&
796 "Expecting non-null Expr");
801 Out <<
" + " << (O / S);
818 TI.print(Out, Policy);
820 Out <<
"{*new " <<
Base.getDynamicAllocType().stream(Policy) <<
"#"
821 << DA.getIndex() <<
"}";
824 assert(
E !=
nullptr &&
"Expecting non-null Expr");
830 for (
unsigned I = 0, N =
Path.size(); I != N; ++I) {
834 const Decl *BaseOrMember =
Path[I].getAsBaseOrMember().getPointer();
835 if (
const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
840 const ValueDecl *VD = cast<ValueDecl>(BaseOrMember);
843 Out << *CastToBase <<
"::";
849 Out << (
Path[I].getAsArrayIndex() == 0 ?
".real" :
".imag");
853 Out <<
'[' <<
Path[I].getAsArrayIndex() <<
']';
879 for (; I != N; ++I) {
900 for (
unsigned I = 0; I != N; ++I, ++BI) {
908 for (
const auto *FI : RD->
fields()) {
911 if (FI->isUnnamedBitField())
923 Out <<
"." << *FD <<
" = ";
932 Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) <<
"::" << *VD;
943 llvm_unreachable(
"Unknown APValue kind!");
948 llvm::raw_string_ostream Out(
Result);
975 assert(
isLValue() &&
"Invalid accessor");
976 return ((
const LV *)(
const void *)&Data)->Base;
980 assert(
isLValue() &&
"Invalid accessor");
981 return ((
const LV *)(
const void *)&Data)->IsOnePastTheEnd;
985 assert(
isLValue() &&
"Invalid accessor");
986 return ((
LV *)(
void *)&Data)->Offset;
990 assert(
isLValue() &&
"Invalid accessor");
991 return ((
const LV *)(
const char *)&Data)->hasPath();
996 const LV &LVal = *((
const LV *)(
const char *)&Data);
1001 assert(
isLValue() &&
"Invalid accessor");
1002 return ((
const LV *)(
const char *)&Data)->Base.getCallIndex();
1006 assert(
isLValue() &&
"Invalid accessor");
1007 return ((
const LV *)(
const char *)&Data)->Base.getVersion();
1011 assert(
isLValue() &&
"Invalid usage");
1012 return ((
const LV *)(
const char *)&Data)->IsNullPtr;
1017 assert(
isLValue() &&
"Invalid accessor");
1018 LV &LVal = *((
LV *)(
char *)&Data);
1020 LVal.IsOnePastTheEnd =
false;
1023 LVal.IsNullPtr = IsNullPtr;
1027APValue::setLValueUninit(LValueBase B,
const CharUnits &O,
unsigned Size,
1028 bool IsOnePastTheEnd,
bool IsNullPtr) {
1029 assert(
isLValue() &&
"Invalid accessor");
1030 LV &LVal = *((LV *)(
char *)&Data);
1032 LVal.IsOnePastTheEnd = IsOnePastTheEnd;
1034 LVal.IsNullPtr = IsNullPtr;
1035 LVal.resizePath(Size);
1036 return {LVal.getPath(), Size};
1043 setLValueUninit(B, O,
Path.size(), IsOnePastTheEnd, IsNullPtr);
1051 assert(
isUnion() &&
"Invalid accessor");
1052 ((UnionData *)(
char *)&Data)->Field =
1053 Field ? Field->getCanonicalDecl() :
nullptr;
1054 *((UnionData *)(
char *)&Data)->
Value =
Value;
1061 return MPD.MemberAndIsDerivedMember.getPointer();
1068 return MPD.MemberAndIsDerivedMember.getInt();
1078void APValue::MakeLValue() {
1079 assert(
isAbsent() &&
"Bad state change");
1080 static_assert(
sizeof(LV) <= DataSize,
"LV too big");
1081 new ((
void *)(
char *)&Data) LV();
1085void APValue::MakeArray(
unsigned InitElts,
unsigned Size) {
1086 assert(
isAbsent() &&
"Bad state change");
1087 new ((
void *)(
char *)&Data) Arr(InitElts, Size);
1093 bool OnePastTheEnd,
bool IsNullPtr);
1096APValue::setMemberPointerUninit(
const ValueDecl *
Member,
bool IsDerivedMember,
1098 assert(
isAbsent() &&
"Bad state change");
1099 MemberPointerData *MPD =
new ((
void *)(
char *)&Data) MemberPointerData;
1101 MPD->MemberAndIsDerivedMember.setPointer(
1102 Member ? cast<ValueDecl>(
Member->getCanonicalDecl()) :
nullptr);
1103 MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
1104 MPD->resizePath(Size);
1105 return {MPD->getPath(), MPD->PathLength};
1108void APValue::MakeMemberPointer(
const ValueDecl *
Member,
bool IsDerivedMember,
1111 setMemberPointerUninit(
Member, IsDerivedMember,
Path.size());
1112 for (
unsigned I = 0; I !=
Path.size(); ++I)
1124 auto Merge = [&](
const APValue &
V) {
1125 return MergeLV(getLVForValue(
V, computation));
1128 switch (
V.getKind()) {
1145 for (
unsigned I = 0, N =
V.getStructNumBases(); I != N; ++I)
1146 if (Merge(
V.getStructBase(I)))
1148 for (
unsigned I = 0, N =
V.getStructNumFields(); I != N; ++I)
1149 if (Merge(
V.getStructField(I)))
1155 if (
V.getUnionField())
1156 Merge(
V.getUnionValue());
1160 for (
unsigned I = 0, N =
V.getArrayInitializedElts(); I != N; ++I)
1161 if (Merge(
V.getArrayInitializedElt(I)))
1163 if (
V.hasArrayFiller())
1164 Merge(
V.getArrayFiller());
1169 if (!
V.getLValueBase()) {
1171 }
else if (
const auto *VD =
1172 V.getLValueBase().dyn_cast<
const ValueDecl *>()) {
1175 }
else if (
const auto TI =
V.getLValueBase().dyn_cast<
TypeInfoLValue>()) {
1176 if (MergeLV(getLVForType(*TI.getType(), computation)))
1178 }
else if (
const Expr *
E =
V.getLValueBase().dyn_cast<
const Expr *>()) {
1185 auto *MTE = dyn_cast<MaterializeTemporaryExpr>(
E);
1188 if (MergeLV(
getLVForDecl(MTE->getExtendingDecl(), computation)))
1192 "unexpected LValueBase kind");
1201 if (
const NamedDecl *
D =
V.getMemberPointerDecl())
static double GetApproxValue(const llvm::APFloat &F)
static void profileIntValue(llvm::FoldingSetNodeID &ID, const llvm::APInt &V)
Profile the value of an APInt, excluding its bit-width.
static bool TryPrintAsStringLiteral(raw_ostream &Out, const PrintingPolicy &Policy, const ArrayType *ATy, ArrayRef< APValue > Inits)
MutableArrayRef< APValue::LValuePathEntry > setLValueUninit(APValue::LValueBase B, const CharUnits &O, unsigned Size, bool OnePastTheEnd, bool IsNullPtr)
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
static const Decl * getCanonicalDecl(const Decl *D)
C Language Family Type Representation.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
void Profile(llvm::FoldingSetNodeID &ID) const
unsigned getVersion() const
QualType getDynamicAllocType() const
QualType getTypeInfoType() const
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
void * getOpaqueValue() const
unsigned getCallIndex() const
A non-discriminated union of a base, field, or array index.
void Profile(llvm::FoldingSetNodeID &ID) const
LValuePathSerializationHelper(ArrayRef< LValuePathEntry >, QualType)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
const LValueBase getLValueBase() const
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)
const FieldDecl * getUnionField() const
APSInt & getComplexIntImag()
unsigned getStructNumFields() 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
unsigned getLValueVersion() const
bool isMemberPointerToDerivedMember() const
unsigned getArrayInitializedElts() const
void setComplexInt(APSInt R, APSInt I)
void Profile(llvm::FoldingSetNodeID &ID) const
profile this value.
unsigned getStructNumBases() const
APFixedPoint & getFixedPoint()
bool needsCleanup() const
Returns whether the object performed allocations.
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)
APValue & getVectorElt(unsigned I)
APValue & getArrayFiller()
unsigned getVectorLength() const
void setUnion(const FieldDecl *Field, const APValue &Value)
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, bool IsNullPtr)
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
bool isMemberPointer() const
unsigned getArraySize() const
bool toIntegralConstant(APSInt &Result, QualType SrcTy, const ASTContext &Ctx) const
Try to convert this value to an integral constant.
std::string getAsString(const ASTContext &Ctx, QualType Ty) 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).
bool isNullPointer() const
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
APValue & getStructBase(unsigned i)
const AddrLabelExpr * getAddrLabelDiffLHS() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
const clang::PrintingPolicy & getPrintingPolicy() const
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const
Make an APSInt of the appropriate width and signedness for the given Value and integer Type.
std::optional< CharUnits > getTypeSizeInCharsIfKnown(QualType Ty) const
LabelDecl * getLabel() const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
Represents a base class of a C++ class.
QualType getType() const
Retrieves the type of the base class.
Represents a C++ struct/union/class.
base_class_iterator bases_end()
base_class_iterator bases_begin()
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Complex values, per C99 6.2.5p11.
Decl - This represents one declaration (or definition), e.g.
Decl * getMostRecentDecl()
Retrieve the most recent declaration that declares the same entity as this declaration (which may be ...
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Symbolic representation of a dynamic allocation.
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
Represents a member of a struct/union/class.
LinkageInfo getLVForDecl(const NamedDecl *D, LVComputationKind computation)
getLVForDecl - Get the linkage and visibility for the given declaration.
static LinkageInfo external()
Linkage getLinkage() const
static LinkageInfo internal()
void merge(LinkageInfo other)
Merge both linkage and visibility.
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
This represents a decl that may have a name.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
static QualType getFromOpaquePtr(const void *Ptr)
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
StreamedQualTypeHelper stream(const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Represents a struct/union/class.
field_range fields() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
Symbolic representation of typeid(T) for some type T.
const Type * getType() const
void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const
The base class of the type hierarchy.
bool isBooleanType() const
bool isIncompleteArrayType() const
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isAnyCharacterType() const
Determine whether this type is any of the built-in character types.
bool isChar16Type() const
bool isAnyComplexType() const
bool isChar32Type() const
bool isWideCharType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a GCC generic vector type.
The JSON file list parser is used to communicate input to InstallAPI.
LLVM_READNONE bool isASCII(char c)
Returns true if a byte is an ASCII character.
LLVM_READONLY bool isPrintable(unsigned char c)
Return true if this character is an ASCII printable character; that is, a character that should take ...
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
@ Internal
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
@ SD_FullExpression
Full-expression storage duration (for temporaries).
@ Result
The result type of a method or function.
llvm::hash_code hash_value(const CustomizableOptional< T > &O)
const FunctionProtoType * T
U cast(CodeGen::Address addr)
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...
void resizePath(unsigned Length)
LValuePathEntry * PathPtr
const LValuePathEntry * getPath() const
LValuePathEntry * getPath()
const CXXRecordDecl * PathElem
void resizePath(unsigned Length)
const PathElem * getPath() const
Describes how types, statements, expressions, and declarations should be printed.
unsigned Nullptr
Whether we should use 'nullptr' rather than '0' as a null pointer constant.
unsigned EntireContentsOfLargeArray
Whether to print the entire array initializers, especially on non-type template parameters,...