21 #include "llvm/ADT/SmallString.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Support/raw_ostream.h"
24 using namespace clang;
28 llvm::PointerIntPair<APValue::LValueBase, 1, bool> BaseAndIsOnePastTheEnd;
51 if (Length == PathLength)
70 struct MemberPointerBase {
71 llvm::PointerIntPair<const ValueDecl*, 1, bool> MemberAndIsDerivedMember;
78 (DataSize -
sizeof(MemberPointerBase)) /
sizeof(
const CXXRecordDecl*);
89 if (Length == PathLength)
108 APValue::Arr::Arr(
unsigned NumElts,
unsigned Size) :
109 Elts(new
APValue[NumElts + (NumElts != Size ? 1 : 0)]),
110 NumElts(NumElts), ArrSize(Size) {}
111 APValue::Arr::~Arr() {
delete [] Elts; }
113 APValue::StructData::StructData(
unsigned NumBases,
unsigned NumFields) :
114 Elts(new
APValue[NumBases+NumFields]),
115 NumBases(NumBases), NumFields(NumFields) {}
116 APValue::StructData::~StructData() {
121 APValue::UnionData::~UnionData () {
139 setVector(((
const Vec *)(
const char *)RHS.Data.buffer)->Elts,
189 void APValue::DestroyDataAndMakeUninit() {
191 ((APSInt*)(
char*)Data.buffer)->~APSInt();
193 ((APFloat*)(
char*)Data.buffer)->~APFloat();
195 ((Vec*)(
char*)Data.buffer)->~Vec();
197 ((ComplexAPSInt*)(
char*)Data.buffer)->~ComplexAPSInt();
199 ((ComplexAPFloat*)(
char*)Data.buffer)->~ComplexAPFloat();
201 ((LV*)(
char*)Data.buffer)->~LV();
203 ((Arr*)(
char*)Data.buffer)->~Arr();
205 ((StructData*)(
char*)Data.buffer)->~StructData();
207 ((UnionData*)(
char*)Data.buffer)->~UnionData();
209 ((MemberPointerData*)(
char*)Data.buffer)->~MemberPointerData();
211 ((AddrLabelDiffData*)(
char*)Data.buffer)->~AddrLabelDiffData();
226 return getInt().needsCleanup();
232 "In _Complex float types, real and imaginary values always have the "
238 "In _Complex int types, real and imaginary values must have the "
242 return reinterpret_cast<const LV *
>(Data.buffer)->hasPathPtr();
247 llvm_unreachable(
"Unknown APValue kind!");
251 std::swap(
Kind, RHS.Kind);
252 char TmpData[DataSize];
253 memcpy(TmpData, Data.buffer, DataSize);
254 memcpy(Data.buffer, RHS.Data.buffer, DataSize);
255 memcpy(RHS.Data.buffer, TmpData, DataSize);
260 llvm::errs() <<
'\n';
266 V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven,
268 return V.convertToDouble();
274 OS <<
"Uninitialized";
277 OS <<
"Int: " <<
getInt();
298 OS <<
"LValue: <todo>";
316 for (
unsigned I = 1;
I != N; ++
I) {
324 for (
unsigned I = 1;
I != N; ++
I) {
335 OS <<
"MemberPointer: <todo>";
338 OS <<
"AddrLabelDiff: <todo>";
341 llvm_unreachable(
"Unknown APValue kind!");
347 Out <<
"<uninitialized>";
351 Out << (
getInt().getBoolValue() ?
"true" :
"false");
401 }
else if (!IsReference)
407 assert(Base.get<
const Expr *>() !=
nullptr &&
408 "Expecting non-null Expr");
414 Out <<
" + " << (O /
S);
430 ElemTy = VD->getType();
433 assert(E !=
nullptr &&
"Expecting non-null Expr");
440 for (
unsigned I = 0, N = Path.size();
I != N; ++
I) {
444 const Decl *BaseOrMember =
445 BaseOrMemberType::getFromOpaqueValue(Path[
I].BaseOrMember).getPointer();
446 if (
const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
450 const ValueDecl *VD = cast<ValueDecl>(BaseOrMember);
453 Out << *CastToBase <<
"::";
455 ElemTy = VD->getType();
459 Out <<
'[' << Path[
I].ArrayIndex <<
']';
480 for (
unsigned I = 1;
I != N; ++
I) {
500 for (
unsigned I = 0;
I != N; ++
I, ++BI) {
508 for (
const auto *FI : RD->
fields()) {
511 if (FI->isUnnamedBitfield())
continue;
522 Out <<
"." << *FD <<
" = ";
531 Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) <<
"::" << *VD;
542 llvm_unreachable(
"Unknown APValue kind!");
547 llvm::raw_string_ostream Out(Result);
554 assert(
isLValue() &&
"Invalid accessor");
555 return ((
const LV*)(
const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getPointer();
559 assert(
isLValue() &&
"Invalid accessor");
560 return ((
const LV*)(
const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getInt();
564 assert(
isLValue() &&
"Invalid accessor");
565 return ((
LV*)(
void*)Data.buffer)->Offset;
569 assert(
isLValue() &&
"Invalid accessor");
570 return ((
const LV*)(
const char*)Data.buffer)->hasPath();
575 const LV &LVal = *((
const LV*)(
const char*)Data.buffer);
576 return llvm::makeArrayRef(LVal.
getPath(), LVal.PathLength);
580 assert(
isLValue() &&
"Invalid accessor");
581 return ((
const LV*)(
const char*)Data.buffer)->CallIndex;
585 unsigned CallIndex) {
586 assert(
isLValue() &&
"Invalid accessor");
587 LV &LVal = *((
LV*)(
char*)Data.buffer);
588 LVal.BaseAndIsOnePastTheEnd.setPointer(B);
589 LVal.BaseAndIsOnePastTheEnd.setInt(
false);
591 LVal.CallIndex = CallIndex;
597 unsigned CallIndex) {
598 assert(
isLValue() &&
"Invalid accessor");
599 LV &LVal = *((
LV*)(
char*)Data.buffer);
600 LVal.BaseAndIsOnePastTheEnd.setPointer(B);
601 LVal.BaseAndIsOnePastTheEnd.setInt(IsOnePastTheEnd);
603 LVal.CallIndex = CallIndex;
612 return MPD.MemberAndIsDerivedMember.getPointer();
619 return MPD.MemberAndIsDerivedMember.getInt();
626 return llvm::makeArrayRef(MPD.
getPath(), MPD.PathLength);
629 void APValue::MakeLValue() {
630 assert(
isUninit() &&
"Bad state change");
631 static_assert(
sizeof(LV) <= DataSize,
"LV too big");
632 new ((
void*)(
char*)Data.buffer) LV();
636 void APValue::MakeArray(
unsigned InitElts,
unsigned Size) {
637 assert(
isUninit() &&
"Bad state change");
638 new ((
void*)(
char*)Data.buffer) Arr(InitElts, Size);
642 void APValue::MakeMemberPointer(
const ValueDecl *Member,
bool IsDerivedMember,
643 ArrayRef<const CXXRecordDecl*> Path) {
644 assert(
isUninit() &&
"Bad state change");
645 MemberPointerData *MPD =
new ((
void*)(
char*)Data.buffer) MemberPointerData;
647 MPD->MemberAndIsDerivedMember.setPointer(Member);
648 MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
649 MPD->resizePath(Path.size());
650 memcpy(MPD->getPath(), Path.data(), Path.size()*
sizeof(
const CXXRecordDecl*));
Defines the clang::ASTContext interface.
void resizePath(unsigned Length)
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
const FieldDecl * getUnionField() const
A (possibly-)qualified type.
C Language Family Type Representation.
bool isMemberPointer() const
QualType getRecordType(const RecordDecl *Decl) const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
bool hasLValuePath() const
bool isBooleanType() const
const LValuePathEntry * getPath() const
APFloat & getComplexFloatReal()
static double GetApproxValue(const llvm::APFloat &F)
RecordDecl - Represents a struct/union/class.
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool isReferenceType() const
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
unsigned getLValueCallIndex() const
CharUnits - This is an opaque type for sizes expressed in character units.
const ValueDecl * getMemberPointerDecl() const
unsigned getStructNumFields() const
field_range fields() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
bool needsCleanup() const
Returns whether the object performed allocations.
LValuePathEntry Path[InlinePathSpace]
base_class_iterator bases_begin()
LValuePathEntry * PathPtr
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
detail::InMemoryDirectory::const_iterator I
APSInt & getComplexIntReal()
APValue & getVectorElt(unsigned I)
static const unsigned InlinePathSpace
static CharUnits One()
One - Construct a CharUnits quantity of one.
APValue & getArrayFiller()
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
unsigned getArrayInitializedElts() const
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
bool isMemberPointerToDerivedMember() const
APValue & getStructField(unsigned i)
Represents a GCC generic vector type.
PathElem Path[InlinePathSpace]
APSInt & getComplexIntImag()
The result type of a method or function.
const clang::PrintingPolicy & getPrintingPolicy() const
bool isLValueOnePastTheEnd() const
void setVector(const APValue *E, unsigned N)
APValue & getStructBase(unsigned i)
APValue & getArrayInitializedElt(unsigned I)
unsigned getStructNumBases() const
const AddrLabelExpr * getAddrLabelDiffLHS() const
APValue & getUnionValue()
ValueKind getKind() const
const PathElem * getPath() const
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, unsigned CallIndex)
void setAddrLabelDiff(const AddrLabelExpr *LHSExpr, const AddrLabelExpr *RHSExpr)
void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const
LValuePathEntry * getPath()
const AddrLabelExpr * getAddrLabelDiffRHS() const
bool isZero() const
isZero - Test whether the quantity equals zero.
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
std::string getAsString(ASTContext &Ctx, QualType Ty) const
detail::InMemoryDirectory::const_iterator E
Defines the Diagnostic-related interfaces.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
void resizePath(unsigned Length)
ArrayRef< LValuePathEntry > getLValuePath() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
const T * getAs() const
Member-template getAs<specific type>'.
llvm::PointerUnion< const ValueDecl *, const Expr * > LValueBase
const CXXRecordDecl * PathElem
LabelDecl * getLabel() const
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).
APFloat & getComplexFloatImag()
const LValueBase getLValueBase() const
Represents a C++ struct/union/class.
base_class_iterator bases_end()
QualType getElementType() const
void setComplexInt(APSInt R, APSInt I)
void setUnion(const FieldDecl *Field, const APValue &Value)
unsigned getArraySize() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
unsigned getVectorLength() const
bool hasArrayFiller() const
void setComplexFloat(APFloat R, APFloat I)
static const unsigned InlinePathSpace
CharUnits & getLValueOffset()