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);
624 assert(
isLValue() &&
"Invalid accessor");
625 return ((
const LV*)(
const void*)Data.buffer)->Base;
629 assert(
isLValue() &&
"Invalid accessor");
630 return ((
const LV*)(
const void*)Data.buffer)->IsOnePastTheEnd;
634 assert(
isLValue() &&
"Invalid accessor");
635 return ((
LV*)(
void*)Data.buffer)->Offset;
639 assert(
isLValue() &&
"Invalid accessor");
640 return ((
const LV*)(
const char*)Data.buffer)->hasPath();
645 const LV &LVal = *((
const LV*)(
const char*)Data.buffer);
646 return llvm::makeArrayRef(LVal.
getPath(), LVal.PathLength);
650 assert(
isLValue() &&
"Invalid accessor");
651 return ((
const LV*)(
const char*)Data.buffer)->Base.getCallIndex();
655 assert(
isLValue() &&
"Invalid accessor");
656 return ((
const LV*)(
const char*)Data.buffer)->Base.getVersion();
660 assert(
isLValue() &&
"Invalid usage");
661 return ((
const LV*)(
const char*)Data.buffer)->IsNullPtr;
666 assert(
isLValue() &&
"Invalid accessor");
667 LV &LVal = *((
LV*)(
char*)Data.buffer);
669 LVal.IsOnePastTheEnd =
false;
672 LVal.IsNullPtr = IsNullPtr;
678 assert(
isLValue() &&
"Invalid accessor");
679 LV &LVal = *((
LV*)(
char*)Data.buffer);
681 LVal.IsOnePastTheEnd = IsOnePastTheEnd;
685 LVal.IsNullPtr = IsNullPtr;
692 return MPD.MemberAndIsDerivedMember.getPointer();
699 return MPD.MemberAndIsDerivedMember.getInt();
706 return llvm::makeArrayRef(MPD.
getPath(), MPD.PathLength);
709 void APValue::MakeLValue() {
710 assert(
isUninit() &&
"Bad state change");
711 static_assert(
sizeof(
LV) <= DataSize,
"LV too big");
712 new ((
void*)(
char*)Data.buffer)
LV();
716 void APValue::MakeArray(
unsigned InitElts,
unsigned Size) {
717 assert(
isUninit() &&
"Bad state change");
718 new ((
void*)(
char*)Data.buffer) Arr(InitElts, Size);
722 void APValue::MakeMemberPointer(
const ValueDecl *Member,
bool IsDerivedMember,
724 assert(
isUninit() &&
"Bad state change");
727 MPD->MemberAndIsDerivedMember.setPointer(Member);
728 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
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...
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
bool toIntegralConstant(APSInt &Result, QualType SrcTy, const ASTContext &Ctx) const
Try to convert this value to an integral constant.
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.
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
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