20 #include "llvm/Support/ErrorHandling.h" 21 #include "llvm/Support/raw_ostream.h" 22 using namespace clang;
30 bool IsOnePastTheEnd : 1;
35 return Ptr.getOpaqueValue();
42 APValue::LValueBase::operator
bool ()
const {
43 return static_cast<bool>(Ptr);
64 llvm::FoldingSetNodeID
ID;
68 return ID.ComputeHash();
78 static const unsigned InlinePathSpace =
89 LV() { PathLength = (unsigned)-1; }
90 ~LV() { resizePath(0); }
93 if (Length == PathLength)
102 bool hasPath()
const {
return PathLength != (unsigned)-1; }
103 bool hasPathPtr()
const {
return hasPath() && PathLength > InlinePathSpace; }
107 return hasPathPtr() ? PathPtr : Path;
112 struct MemberPointerBase {
113 llvm::PointerIntPair<const ValueDecl*, 1, bool> MemberAndIsDerivedMember;
119 static const unsigned InlinePathSpace =
120 (DataSize -
sizeof(MemberPointerBase)) /
sizeof(
const CXXRecordDecl*);
123 PathElem Path[InlinePathSpace];
131 if (Length == PathLength)
137 PathPtr =
new PathElem[Length];
140 bool hasPathPtr()
const {
return PathLength > InlinePathSpace; }
142 PathElem *
getPath() {
return hasPathPtr() ? PathPtr : Path; }
144 return hasPathPtr() ? PathPtr : Path;
150 APValue::Arr::Arr(
unsigned NumElts,
unsigned Size) :
151 Elts(
new APValue[NumElts + (NumElts != Size ? 1 : 0)]),
152 NumElts(NumElts), ArrSize(Size) {}
153 APValue::Arr::~Arr() {
delete [] Elts; }
155 APValue::StructData::StructData(
unsigned NumBases,
unsigned NumFields) :
156 Elts(
new APValue[NumBases+NumFields]),
157 NumBases(NumBases), NumFields(NumFields) {}
158 APValue::StructData::~StructData() {
162 APValue::UnionData::UnionData() : Field(
nullptr),
Value(
new APValue) {}
163 APValue::UnionData::~UnionData () {
181 setVector(((
const Vec *)(
const char *)RHS.Data.buffer)->Elts,
231 void APValue::DestroyDataAndMakeUninit() {
233 ((APSInt*)(
char*)Data.buffer)->~APSInt();
235 ((APFloat*)(
char*)Data.buffer)->~APFloat();
237 ((Vec*)(
char*)Data.buffer)->~Vec();
239 ((ComplexAPSInt*)(
char*)Data.buffer)->~ComplexAPSInt();
241 ((ComplexAPFloat*)(
char*)Data.buffer)->~ComplexAPFloat();
243 ((
LV*)(
char*)Data.buffer)->~
LV();
245 ((Arr*)(
char*)Data.buffer)->~Arr();
247 ((StructData*)(
char*)Data.buffer)->~StructData();
249 ((UnionData*)(
char*)Data.buffer)->~UnionData();
253 ((AddrLabelDiffData*)(
char*)Data.buffer)->~AddrLabelDiffData();
268 return getInt().needsCleanup();
274 "In _Complex float types, real and imaginary values always have the " 280 "In _Complex int types, real and imaginary values must have the " 284 return reinterpret_cast<const LV *
>(Data.buffer)->hasPathPtr();
289 llvm_unreachable(
"Unknown APValue kind!");
293 std::swap(
Kind, RHS.Kind);
294 char TmpData[DataSize];
295 memcpy(TmpData, Data.buffer, DataSize);
296 memcpy(Data.buffer, RHS.Data.buffer, DataSize);
297 memcpy(RHS.Data.buffer, TmpData, DataSize);
302 llvm::errs() <<
'\n';
308 V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
310 return V.convertToDouble();
316 OS <<
"Uninitialized";
319 OS <<
"Int: " <<
getInt();
340 OS <<
"LValue: <todo>";
358 for (
unsigned I = 1; I != N; ++I) {
366 for (
unsigned I = 1; I != N; ++I) {
377 OS <<
"MemberPointer: <todo>";
380 OS <<
"AddrLabelDiff: <todo>";
383 llvm_unreachable(
"Unknown APValue kind!");
389 Out <<
"<uninitialized>";
393 Out << (
getInt().getBoolValue() ?
"true" :
"false");
443 }
else if (!IsReference)
449 assert(Base.
get<
const Expr *>() !=
nullptr &&
450 "Expecting non-null Expr");
456 Out <<
" + " << (O / S);
472 ElemTy = VD->getType();
475 assert(E !=
nullptr &&
"Expecting non-null Expr");
482 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
486 const Decl *BaseOrMember =
487 BaseOrMemberType::getFromOpaqueValue(Path[I].BaseOrMember).getPointer();
488 if (
const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
492 const ValueDecl *VD = cast<ValueDecl>(BaseOrMember);
495 Out << *CastToBase <<
"::";
497 ElemTy = VD->getType();
501 Out <<
'[' << Path[I].ArrayIndex <<
']';
522 for (
unsigned I = 1; I != N; ++I) {
542 for (
unsigned I = 0; I != N; ++I, ++BI) {
550 for (
const auto *FI : RD->
fields()) {
553 if (FI->isUnnamedBitfield())
continue;
564 Out <<
"." << *FD <<
" = ";
573 Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) <<
"::" << *VD;
584 llvm_unreachable(
"Unknown APValue kind!");
589 llvm::raw_string_ostream Out(Result);
596 assert(
isLValue() &&
"Invalid accessor");
597 return ((
const LV*)(
const void*)Data.buffer)->Base;
601 assert(
isLValue() &&
"Invalid accessor");
602 return ((
const LV*)(
const void*)Data.buffer)->IsOnePastTheEnd;
606 assert(
isLValue() &&
"Invalid accessor");
607 return ((
LV*)(
void*)Data.buffer)->Offset;
611 assert(
isLValue() &&
"Invalid accessor");
612 return ((
const LV*)(
const char*)Data.buffer)->hasPath();
617 const LV &LVal = *((
const LV*)(
const char*)Data.buffer);
618 return llvm::makeArrayRef(LVal.
getPath(), LVal.PathLength);
622 assert(
isLValue() &&
"Invalid accessor");
623 return ((
const LV*)(
const char*)Data.buffer)->Base.getCallIndex();
627 assert(
isLValue() &&
"Invalid accessor");
628 return ((
const LV*)(
const char*)Data.buffer)->Base.getVersion();
632 assert(
isLValue() &&
"Invalid usage");
633 return ((
const LV*)(
const char*)Data.buffer)->IsNullPtr;
638 assert(
isLValue() &&
"Invalid accessor");
639 LV &LVal = *((
LV*)(
char*)Data.buffer);
641 LVal.IsOnePastTheEnd =
false;
644 LVal.IsNullPtr = IsNullPtr;
650 assert(
isLValue() &&
"Invalid accessor");
651 LV &LVal = *((
LV*)(
char*)Data.buffer);
653 LVal.IsOnePastTheEnd = IsOnePastTheEnd;
657 LVal.IsNullPtr = IsNullPtr;
664 return MPD.MemberAndIsDerivedMember.getPointer();
671 return MPD.MemberAndIsDerivedMember.getInt();
678 return llvm::makeArrayRef(MPD.
getPath(), MPD.PathLength);
681 void APValue::MakeLValue() {
682 assert(
isUninit() &&
"Bad state change");
683 static_assert(
sizeof(
LV) <= DataSize,
"LV too big");
684 new ((
void*)(
char*)Data.buffer)
LV();
688 void APValue::MakeArray(
unsigned InitElts,
unsigned Size) {
689 assert(
isUninit() &&
"Bad state change");
690 new ((
void*)(
char*)Data.buffer) Arr(InitElts, Size);
694 void APValue::MakeMemberPointer(
const ValueDecl *Member,
bool IsDerivedMember,
696 assert(
isUninit() &&
"Bad state change");
699 MPD->MemberAndIsDerivedMember.setPointer(Member);
700 MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
unsigned getStructNumFields() const
Defines the clang::ASTContext interface.
void resizePath(unsigned Length)
A (possibly-)qualified type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
C Language Family Type Representation.
Decl - This represents one declaration (or definition), e.g.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Represents an array type, per C99 6.7.5.2 - Array Declarators.
bool isZero() const
isZero - Test whether the quantity equals zero.
const LValuePathEntry * getPath() const
const AddrLabelExpr * getAddrLabelDiffLHS() const
QualType getElementType() const
APFloat & getComplexFloatReal()
const T * getAs() const
Member-template getAs<specific type>'.
ArrayRef< LValuePathEntry > getLValuePath() const
static double GetApproxValue(const llvm::APFloat &F)
bool isLValueOnePastTheEnd() const
const ValueDecl * getMemberPointerDecl() const
Represents a struct/union/class.
unsigned getVersion() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
field_range fields() const
Represents a member of a struct/union/class.
unsigned getCallIndex() const
bool isReferenceType() const
const PathElem * getPath() const
unsigned getArraySize() const
unsigned getLValueCallIndex() const
CharUnits - This is an opaque type for sizes expressed in character units.
const clang::PrintingPolicy & getPrintingPolicy() const
std::string getAsString(ASTContext &Ctx, QualType Ty) const
void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, const ASTContext *Context=nullptr) const
base_class_iterator bases_begin()
LValuePathEntry * PathPtr
bool needsCleanup() const
Returns whether the object performed allocations.
APSInt & getComplexIntReal()
APValue & getVectorElt(unsigned I)
unsigned getLValueVersion() const
static CharUnits One()
One - Construct a CharUnits quantity of one.
bool hasLValuePath() const
APValue & getArrayFiller()
bool hasArrayFiller() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Expr - This represents one expression.
APValue & getStructField(unsigned i)
QualType getRecordType(const RecordDecl *Decl) const
Represents a GCC generic vector type.
bool isNullPointer() const
APSInt & getComplexIntImag()
The result type of a method or function.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const FieldDecl * getUnionField() const
void setVector(const APValue *E, unsigned N)
APValue & getStructBase(unsigned i)
unsigned getStructNumBases() const
APValue & getArrayInitializedElt(unsigned I)
const LValueBase getLValueBase() const
void * getOpaqueValue() const
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, bool IsNullPtr)
const AddrLabelExpr * getAddrLabelDiffRHS() const
APValue & getUnionValue()
bool isMemberPointer() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
void setAddrLabelDiff(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
LValuePathEntry * getPath()
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
bool isMemberPointerToDerivedMember() const
Dataflow Directional Tag Classes.
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
bool isBooleanType() const
unsigned getArrayInitializedElts() const
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
void resizePath(unsigned Length)
LabelDecl * getLabel() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
const CXXRecordDecl * PathElem
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
Represents a base class of a C++ class.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
ValueKind getKind() const
APFloat & getComplexFloatImag()
Represents a C++ struct/union/class.
base_class_iterator bases_end()
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
void setComplexInt(APSInt R, APSInt I)
void setUnion(const FieldDecl *Field, const APValue &Value)
void setComplexFloat(APFloat R, APFloat I)
CharUnits & getLValueOffset()
unsigned getVectorLength() const