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");
428 Out << (Ctx.
getLangOpts().CPlusPlus11 ?
"nullptr" :
"0");
429 }
else if (IsReference) {
451 }
else if (!IsReference)
457 assert(Base.
get<
const Expr *>() !=
nullptr &&
458 "Expecting non-null Expr");
464 Out <<
" + " << (O / S);
480 ElemTy = VD->getType();
483 assert(E !=
nullptr &&
"Expecting non-null Expr");
490 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
494 const Decl *BaseOrMember =
495 BaseOrMemberType::getFromOpaqueValue(Path[I].BaseOrMember).getPointer();
496 if (
const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
500 const ValueDecl *VD = cast<ValueDecl>(BaseOrMember);
503 Out << *CastToBase <<
"::";
505 ElemTy = VD->getType();
509 Out <<
'[' << Path[I].ArrayIndex <<
']';
530 for (
unsigned I = 1; I != N; ++I) {
550 for (
unsigned I = 0; I != N; ++I, ++BI) {
558 for (
const auto *FI : RD->
fields()) {
561 if (FI->isUnnamedBitfield())
continue;
572 Out <<
"." << *FD <<
" = ";
581 Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) <<
"::" << *VD;
592 llvm_unreachable(
"Unknown APValue kind!");
597 llvm::raw_string_ostream Out(Result);
604 assert(
isLValue() &&
"Invalid accessor");
605 return ((
const LV*)(
const void*)Data.buffer)->Base;
609 assert(
isLValue() &&
"Invalid accessor");
610 return ((
const LV*)(
const void*)Data.buffer)->IsOnePastTheEnd;
614 assert(
isLValue() &&
"Invalid accessor");
615 return ((
LV*)(
void*)Data.buffer)->Offset;
619 assert(
isLValue() &&
"Invalid accessor");
620 return ((
const LV*)(
const char*)Data.buffer)->hasPath();
625 const LV &LVal = *((
const LV*)(
const char*)Data.buffer);
626 return llvm::makeArrayRef(LVal.
getPath(), LVal.PathLength);
630 assert(
isLValue() &&
"Invalid accessor");
631 return ((
const LV*)(
const char*)Data.buffer)->Base.getCallIndex();
635 assert(
isLValue() &&
"Invalid accessor");
636 return ((
const LV*)(
const char*)Data.buffer)->Base.getVersion();
640 assert(
isLValue() &&
"Invalid usage");
641 return ((
const LV*)(
const char*)Data.buffer)->IsNullPtr;
646 assert(
isLValue() &&
"Invalid accessor");
647 LV &LVal = *((
LV*)(
char*)Data.buffer);
649 LVal.IsOnePastTheEnd =
false;
652 LVal.IsNullPtr = IsNullPtr;
658 assert(
isLValue() &&
"Invalid accessor");
659 LV &LVal = *((
LV*)(
char*)Data.buffer);
661 LVal.IsOnePastTheEnd = IsOnePastTheEnd;
665 LVal.IsNullPtr = IsNullPtr;
672 return MPD.MemberAndIsDerivedMember.getPointer();
679 return MPD.MemberAndIsDerivedMember.getInt();
686 return llvm::makeArrayRef(MPD.
getPath(), MPD.PathLength);
689 void APValue::MakeLValue() {
690 assert(
isUninit() &&
"Bad state change");
691 static_assert(
sizeof(
LV) <= DataSize,
"LV too big");
692 new ((
void*)(
char*)Data.buffer)
LV();
696 void APValue::MakeArray(
unsigned InitElts,
unsigned Size) {
697 assert(
isUninit() &&
"Bad state change");
698 new ((
void*)(
char*)Data.buffer) Arr(InitElts, Size);
702 void APValue::MakeMemberPointer(
const ValueDecl *Member,
bool IsDerivedMember,
704 assert(
isUninit() &&
"Bad state change");
707 MPD->MemberAndIsDerivedMember.setPointer(Member);
708 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
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()
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool hasArrayFiller() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
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
StreamedQualTypeHelper stream(const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) 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).
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\, const ASTContext *Context=nullptr) const
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)
const LangOptions & getLangOpts() const
void setComplexFloat(APFloat R, APFloat I)
CharUnits & getLValueOffset()
unsigned getVectorLength() const