Go to the documentation of this file.
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/raw_ostream.h"
23 using namespace clang;
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*>()) {
73 for (
auto *Redecl = cast<ValueDecl>(D->getMostRecentDecl()); Redecl;
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 clang::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())
149 BaseOrMember.setPointer(D->getCanonicalDecl());
150 Value =
reinterpret_cast<uintptr_t>(BaseOrMember.getOpaqueValue());
159 : ElemTy((const void *)ElemTy.getTypePtrOrNull()), Path(Path) {}
171 bool IsOnePastTheEnd : 1;
176 return Ptr.getOpaqueValue();
183 APValue::LValueBase::operator
bool ()
const {
184 return static_cast<bool>(Ptr);
190 B.Ptr = DenseMapInfo<const ValueDecl*>::getEmptyKey();
197 B.Ptr = DenseMapInfo<const ValueDecl*>::getTombstoneKey();
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*);
267 PathElem Path[InlinePathSpace];
275 if (Length == PathLength)
281 PathPtr =
new PathElem[Length];
284 bool hasPathPtr()
const {
return PathLength > InlinePathSpace; }
286 PathElem *
getPath() {
return hasPathPtr() ? PathPtr : Path; }
288 return hasPathPtr() ? PathPtr : Path;
294 APValue::Arr::Arr(
unsigned NumElts,
unsigned Size) :
295 Elts(new
APValue[NumElts + (NumElts != Size ? 1 : 0)]),
296 NumElts(NumElts), ArrSize(Size) {}
297 APValue::Arr::~Arr() {
delete [] Elts; }
299 APValue::StructData::StructData(
unsigned NumBases,
unsigned NumFields) :
300 Elts(new
APValue[NumBases+NumFields]),
301 NumBases(NumBases), NumFields(NumFields) {}
302 APValue::StructData::~StructData() {
307 APValue::UnionData::~UnionData () {
327 MakeFixedPoint(std::move(FXCopy));
332 setVector(((
const Vec *)(
const char *)&RHS.Data)->Elts,
394 DestroyDataAndMakeUninit();
401 void APValue::DestroyDataAndMakeUninit() {
404 else if (Kind ==
Float)
405 ((APFloat *)(
char *)&Data)->~APFloat();
407 ((APFixedPoint *)(
char *)&Data)->~APFixedPoint();
409 ((Vec *)(
char *)&Data)->~Vec();
411 ((ComplexAPSInt *)(
char *)&Data)->~ComplexAPSInt();
413 ((ComplexAPFloat *)(
char *)&Data)->~ComplexAPFloat();
415 ((LV *)(
char *)&Data)->~LV();
416 else if (Kind ==
Array)
417 ((Arr *)(
char *)&Data)->~Arr();
419 ((StructData *)(
char *)&Data)->~StructData();
420 else if (Kind ==
Union)
421 ((UnionData *)(
char *)&Data)->~UnionData();
423 ((MemberPointerData *)(
char *)&Data)->~MemberPointerData();
425 ((AddrLabelDiffData *)(
char *)&Data)->~AddrLabelDiffData();
441 return getInt().needsCleanup();
449 "In _Complex float types, real and imaginary values always have the "
455 "In _Complex int types, real and imaginary values must have the "
459 return reinterpret_cast<const LV *
>(&Data)->hasPathPtr();
463 llvm_unreachable(
"Unknown APValue kind!");
467 std::swap(Kind, RHS.Kind);
468 std::swap(Data, RHS.Data);
473 for (
unsigned I = 0, N =
V.getBitWidth(); I < N; I += 32)
474 ID.AddInteger((uint32_t)
V.extractBitsAsZExtValue(
std::min(32u, N - I), I));
523 llvm::FoldingSetNodeID FillerID;
527 ID.AddNodeID(FillerID);
538 ID.AddInteger(NumFillers);
545 llvm::FoldingSetNodeID ElemID;
547 if (ElemID != FillerID) {
548 ID.AddInteger(NumFillers);
549 ID.AddNodeID(ElemID);
617 llvm_unreachable(
"Unknown APValue kind!");
623 V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
625 return V.convertToDouble();
640 if (!Inits.back().getInt().isZero())
643 Inits = Inits.drop_back();
649 constexpr
size_t MaxN = 36;
654 Inits.take_front(
std::min(MaxN - Ellipsis.size() / 2, Inits.size()));
657 for (
auto &Val : Inits) {
658 int64_t Char64 = Val.getInt().getExtValue();
661 auto Ch =
static_cast<unsigned char>(Char64);
663 StringRef Escaped = escapeCStyle<EscapeChar::SingleAndDouble>(Ch);
664 if (Escaped.empty()) {
667 Buf.emplace_back(Ch);
673 Buf.append(Ellipsis);
705 Out <<
"<out of lifetime>";
708 Out <<
"<uninitialized>";
712 Out << (
getInt().getBoolValue() ?
"true" :
"false");
750 Out << (Policy.
Nullptr ?
"nullptr" :
"0");
751 }
else if (IsReference) {
752 Out <<
"*(" << InnerTy.
stream(Policy) <<
"*)"
755 Out <<
"(" << Ty.
stream(Policy) <<
")"
770 if (S.isZero() || O % S) {
775 }
else if (!IsReference) {
782 TI.print(Out, Policy);
785 <<
Base.getDynamicAllocType().stream(Policy) <<
"#"
786 << DA.getIndex() <<
"}";
788 assert(
Base.get<
const Expr *>() !=
nullptr &&
789 "Expecting non-null Expr");
794 Out <<
" + " << (O / S);
811 TI.print(Out, Policy);
813 Out <<
"{*new " <<
Base.getDynamicAllocType().stream(Policy) <<
"#"
814 << DA.getIndex() <<
"}";
817 assert(E !=
nullptr &&
"Expecting non-null Expr");
823 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
827 const Decl *BaseOrMember = Path[I].getAsBaseOrMember().getPointer();
828 if (
const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
833 const ValueDecl *VD = cast<ValueDecl>(BaseOrMember);
836 Out << *CastToBase <<
"::";
838 ElemTy = VD->getType();
842 Out <<
'[' << Path[I].getAsArrayIndex() <<
']';
868 for (; I != N; ++I) {
889 for (
unsigned I = 0; I != N; ++I, ++BI) {
897 for (
const auto *FI : RD->
fields()) {
900 if (FI->isUnnamedBitfield())
continue;
911 Out <<
"." << *FD <<
" = ";
920 Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) <<
"::" << *VD;
931 llvm_unreachable(
"Unknown APValue kind!");
936 llvm::raw_string_ostream Out(Result);
963 assert(
isLValue() &&
"Invalid accessor");
964 return ((
const LV *)(
const void *)&Data)->Base;
968 assert(
isLValue() &&
"Invalid accessor");
969 return ((
const LV *)(
const void *)&Data)->IsOnePastTheEnd;
973 assert(
isLValue() &&
"Invalid accessor");
974 return ((
LV *)(
void *)&Data)->Offset;
978 assert(
isLValue() &&
"Invalid accessor");
979 return ((
const LV *)(
const char *)&Data)->hasPath();
984 const LV &LVal = *((
const LV *)(
const char *)&Data);
985 return llvm::makeArrayRef(LVal.
getPath(), LVal.PathLength);
989 assert(
isLValue() &&
"Invalid accessor");
990 return ((
const LV *)(
const char *)&Data)->Base.getCallIndex();
994 assert(
isLValue() &&
"Invalid accessor");
995 return ((
const LV *)(
const char *)&Data)->Base.getVersion();
999 assert(
isLValue() &&
"Invalid usage");
1000 return ((
const LV *)(
const char *)&Data)->IsNullPtr;
1005 assert(
isLValue() &&
"Invalid accessor");
1006 LV &LVal = *((
LV *)(
char *)&Data);
1008 LVal.IsOnePastTheEnd =
false;
1011 LVal.IsNullPtr = IsNullPtr;
1015 APValue::setLValueUninit(LValueBase B,
const CharUnits &O,
unsigned Size,
1016 bool IsOnePastTheEnd,
bool IsNullPtr) {
1017 assert(
isLValue() &&
"Invalid accessor");
1018 LV &LVal = *((LV *)(
char *)&Data);
1020 LVal.IsOnePastTheEnd = IsOnePastTheEnd;
1022 LVal.IsNullPtr = IsNullPtr;
1023 LVal.resizePath(Size);
1024 return {LVal.getPath(), Size};
1031 setLValueUninit(B, O, Path.size(), IsOnePastTheEnd, IsNullPtr);
1033 memcpy(InternalPath.data(), Path.data(),
1039 assert(
isUnion() &&
"Invalid accessor");
1040 ((UnionData *)(
char *)&Data)->Field =
1041 Field ? Field->getCanonicalDecl() :
nullptr;
1042 *((UnionData *)(
char *)&Data)->
Value =
Value;
1049 return MPD.MemberAndIsDerivedMember.getPointer();
1056 return MPD.MemberAndIsDerivedMember.getInt();
1063 return llvm::makeArrayRef(MPD.
getPath(), MPD.PathLength);
1066 void APValue::MakeLValue() {
1067 assert(
isAbsent() &&
"Bad state change");
1068 static_assert(
sizeof(LV) <= DataSize,
"LV too big");
1069 new ((
void *)(
char *)&Data) LV();
1073 void APValue::MakeArray(
unsigned InitElts,
unsigned Size) {
1074 assert(
isAbsent() &&
"Bad state change");
1075 new ((
void *)(
char *)&Data) Arr(InitElts, Size);
1079 MutableArrayRef<APValue::LValuePathEntry>
1081 bool OnePastTheEnd,
bool IsNullPtr);
1083 MutableArrayRef<const CXXRecordDecl *>
1084 APValue::setMemberPointerUninit(
const ValueDecl *Member,
bool IsDerivedMember,
1086 assert(
isAbsent() &&
"Bad state change");
1087 MemberPointerData *MPD =
new ((
void *)(
char *)&Data) MemberPointerData;
1089 MPD->MemberAndIsDerivedMember.setPointer(
1090 Member ? cast<ValueDecl>(
Member->getCanonicalDecl()) :
nullptr);
1091 MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
1092 MPD->resizePath(Size);
1093 return {MPD->getPath(), MPD->PathLength};
1096 void APValue::MakeMemberPointer(
const ValueDecl *Member,
bool IsDerivedMember,
1098 MutableArrayRef<const CXXRecordDecl *> InternalPath =
1099 setMemberPointerUninit(Member, IsDerivedMember, Path.size());
1100 for (
unsigned I = 0; I != Path.size(); ++I)
1112 auto Merge = [&](
const APValue &
V) {
1113 return MergeLV(getLVForValue(
V, computation));
1116 switch (
V.getKind()) {
1133 for (
unsigned I = 0, N =
V.getStructNumBases(); I != N; ++I)
1134 if (Merge(
V.getStructBase(I)))
1136 for (
unsigned I = 0, N =
V.getStructNumFields(); I != N; ++I)
1137 if (Merge(
V.getStructField(I)))
1143 if (
V.getUnionField())
1144 Merge(
V.getUnionValue());
1148 for (
unsigned I = 0, N =
V.getArrayInitializedElts(); I != N; ++I)
1149 if (Merge(
V.getArrayInitializedElt(I)))
1151 if (
V.hasArrayFiller())
1152 Merge(
V.getArrayFiller());
1157 if (!
V.getLValueBase()) {
1159 }
else if (
const auto *VD =
1160 V.getLValueBase().dyn_cast<
const ValueDecl *>()) {
1163 }
else if (
const auto TI =
V.getLValueBase().dyn_cast<
TypeInfoLValue>()) {
1164 if (MergeLV(getLVForType(*TI.getType(), computation)))
1166 }
else if (
const Expr *E =
V.getLValueBase().dyn_cast<
const Expr *>()) {
1173 auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
1176 if (MergeLV(
getLVForDecl(MTE->getExtendingDecl(), computation)))
1180 "unexpected LValueBase kind");
1189 if (
const NamedDecl *D =
V.getMemberPointerDecl())
void setComplexInt(APSInt R, APSInt I)
unsigned EntireContentsOfLargeArray
Whether to print the entire array initializers, especially on non-type template parameters,...
@ InternalLinkage
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
static void profileIntValue(llvm::FoldingSetNodeID &ID, const llvm::APInt &V)
Profile the value of an APInt, excluding its bit-width.
bool isRecordType() const
unsigned Nullptr
Whether we should use 'nullptr' rather than '0' as a null pointer constant.
ValueKind getKind() const
QualType getType() const
Retrieves the type of the base class.
LLVM_READONLY bool isPrintable(unsigned char c)
Return true if this character is an ASCII printable character; that is, a character that should take ...
CharUnits & getLValueOffset()
unsigned getCallIndex() const
APValue & operator=(const APValue &RHS)
unsigned getStructNumFields() const
QualType getTypeInfoType() const
ArrayRef< LValuePathEntry > getLValuePath() const
const typedef CXXRecordDecl * PathElem
void setUnion(const FieldDecl *Field, const APValue &Value)
bool isLValueOnePastTheEnd() const
static double GetApproxValue(const llvm::APFloat &F)
This represents a decl that may have a name.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
bool isWideCharType() const
APFixedPoint & getFixedPoint()
void setComplexFloat(APFloat R, APFloat I)
A (possibly-)qualified type.
static bool isEqual(const clang::APValue::LValueBase &LHS, const clang::APValue::LValueBase &RHS)
U cast(CodeGen::Address addr)
Represents a member of a struct/union/class.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
void * getOpaqueValue() const
bool needsCleanup() const
Returns whether the object performed allocations.
unsigned getArraySize() const
static clang::APValue::LValueBase getTombstoneKey()
QualType getDynamicAllocType() const
@ None
There is no such object (it's outside its lifetime).
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
Describes how types, statements, expressions, and declarations should be printed.
StreamedQualTypeHelper stream(const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
base_class_iterator bases_end()
const ValueDecl * getMemberPointerDecl() const
The base class of the type hierarchy.
static SVal getValue(SVal val, SValBuilder &svalBuilder)
const PathElem * getPath() const
static unsigned getHashValue(const clang::APValue::LValueBase &Base)
llvm::hash_code hash_value(const clang::SanitizerMask &Arg)
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...
void merge(LinkageInfo other)
Merge both linkage and visibility.
bool isReferenceType() const
APFloat & getComplexFloatReal()
__DEVICE__ int min(int __a, int __b)
static LinkageInfo internal()
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
bool hasLValuePath() const
const Type * getType() const
LValuePathSerializationHelper(ArrayRef< LValuePathEntry >, QualType)
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
bool isAnyCharacterType() const
Determine whether this type is any of the built-in character types.
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
Represents a GCC generic vector type.
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Represents an array type, per C99 6.7.5.2 - Array Declarators.
llvm::hash_code hash_value(const APValue::LValueBase &Base)
unsigned getStructNumBases() const
APValue & getStructBase(unsigned i)
const LValuePathEntry * getPath() const
LValuePathEntry * getPath()
APSInt & getComplexIntReal()
static CharUnits One()
One - Construct a CharUnits quantity of one.
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
unsigned getLValueCallIndex() const
APValue & getVectorElt(unsigned I)
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
const FieldDecl * getUnionField() const
MutableArrayRef< APValue::LValuePathEntry > setLValueUninit(APValue::LValueBase B, const CharUnits &O, unsigned Size, bool OnePastTheEnd, bool IsNullPtr)
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
bool hasArrayFiller() const
APValue & getArrayInitializedElt(unsigned I)
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, bool IsNullPtr)
unsigned getLValueVersion() const
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
const T * castAs() const
Member-template castAs<specific type>.
APValue & getArrayFiller()
Represents a C++ struct/union/class.
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
void setAddrLabelDiff(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
void resizePath(unsigned Length)
void Profile(llvm::FoldingSetNodeID &ID) const
profile this value.
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
static bool TryPrintAsStringLiteral(raw_ostream &Out, const PrintingPolicy &Policy, const ArrayType *ATy, ArrayRef< APValue > Inits)
Symbolic representation of a dynamic allocation.
bool isZero() const
isZero - Test whether the quantity equals zero.
static const Decl * getCanonicalDecl(const Decl *D)
void setVector(const APValue *E, unsigned N)
bool isIncompleteArrayType() const
const clang::PrintingPolicy & getPrintingPolicy() const
field_range fields() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Decl - This represents one declaration (or definition), e.g.
const LValueBase getLValueBase() const
Linkage getLinkage() const
APValue & getStructField(unsigned i)
APValue & getUnionValue()
Symbolic representation of typeid(T) for some type T.
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.
bool isNullPointer() const
bool isMemberPointer() const
APSInt & getComplexIntImag()
bool toIntegralConstant(APSInt &Result, QualType SrcTy, const ASTContext &Ctx) const
Try to convert this value to an integral constant.
static QualType getFromOpaquePtr(const void *Ptr)
void resizePath(unsigned Length)
bool isBooleanType() const
LValuePathEntry * PathPtr
static LinkageInfo external()
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
const AddrLabelExpr * getAddrLabelDiffRHS() const
static clang::APValue::LValueBase getEmptyKey()
void Profile(llvm::FoldingSetNodeID &ID) const
APFloat & getComplexFloatImag()
base_class_iterator bases_begin()
Represents a base class of a C++ class.
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...
unsigned getVectorLength() const
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
bool isMemberPointerToDerivedMember() const
Optional< CharUnits > getTypeSizeInCharsIfKnown(QualType Ty) const
CharUnits - This is an opaque type for sizes expressed in character units.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
LinkageInfo getLVForDecl(const NamedDecl *D, LVComputationKind computation)
getLVForDecl - Get the linkage and visibility for the given declaration.
QualType getElementType() const
This represents one expression.
unsigned getArrayInitializedElts() const
bool isChar16Type() const
unsigned getVersion() const
A non-discriminated union of a base, field, or array index.
LabelDecl * getLabel() const
Represents a struct/union/class.
bool isChar32Type() const
void Profile(llvm::FoldingSetNodeID &ID) const
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
LLVM_READNONE bool isASCII(char c)
Returns true if a byte is an ASCII character.
const AddrLabelExpr * getAddrLabelDiffLHS() const
void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.