19 #include "llvm/Support/ErrorHandling.h" 20 #include "llvm/Support/raw_ostream.h" 21 using namespace clang;
26 : T(T->getCanonicalTypeUnqualified().getTypePtr()) {}
38 "Type is insufficiently aligned");
41 : Ptr(P), Local{I, V} {}
43 : Ptr(P),
Local{I, V} {}
62 return (is<TypeInfoLValue>() || is<DynamicAllocLValue>()) ? 0
67 return (is<TypeInfoLValue>() || is<DynamicAllocLValue>()) ? 0 :
Local.Version;
71 assert(is<TypeInfoLValue>() &&
"not a type_info lvalue");
76 assert(is<DynamicAllocLValue>() &&
"not a dynamic allocation lvalue");
83 if (LHS.Ptr != RHS.Ptr)
87 return LHS.
Local.CallIndex == RHS.
Local.CallIndex &&
98 bool IsOnePastTheEnd : 1;
103 return Ptr.getOpaqueValue();
110 APValue::LValueBase::operator
bool ()
const {
111 return static_cast<bool>(Ptr);
147 static const unsigned InlinePathSpace =
158 LV() { PathLength = (unsigned)-1; }
162 if (Length == PathLength)
171 bool hasPath()
const {
return PathLength != (unsigned)-1; }
172 bool hasPathPtr()
const {
return hasPath() && PathLength > InlinePathSpace; }
176 return hasPathPtr() ? PathPtr : Path;
181 struct MemberPointerBase {
182 llvm::PointerIntPair<const ValueDecl*, 1, bool> MemberAndIsDerivedMember;
188 static const unsigned InlinePathSpace =
189 (DataSize -
sizeof(MemberPointerBase)) /
sizeof(
const CXXRecordDecl*);
192 PathElem Path[InlinePathSpace];
200 if (Length == PathLength)
206 PathPtr =
new PathElem[Length];
209 bool hasPathPtr()
const {
return PathLength > InlinePathSpace; }
211 PathElem *
getPath() {
return hasPathPtr() ? PathPtr : Path; }
213 return hasPathPtr() ? PathPtr : Path;
219 APValue::Arr::Arr(
unsigned NumElts,
unsigned Size) :
220 Elts(
new APValue[NumElts + (NumElts != Size ? 1 : 0)]),
221 NumElts(NumElts), ArrSize(Size) {}
222 APValue::Arr::~Arr() {
delete [] Elts; }
224 APValue::StructData::StructData(
unsigned NumBases,
unsigned NumFields) :
225 Elts(
new APValue[NumBases+NumFields]),
226 NumBases(NumBases), NumFields(NumFields) {}
227 APValue::StructData::~StructData() {
231 APValue::UnionData::UnionData() : Field(
nullptr),
Value(
new APValue) {}
232 APValue::UnionData::~UnionData () {
252 MakeFixedPoint(std::move(FXCopy));
257 setVector(((
const Vec *)(
const char *)RHS.Data.buffer)->Elts,
307 void APValue::DestroyDataAndMakeUninit() {
309 ((APSInt*)(
char*)Data.buffer)->~APSInt();
311 ((APFloat*)(
char*)Data.buffer)->~APFloat();
315 ((Vec*)(
char*)Data.buffer)->~Vec();
317 ((ComplexAPSInt*)(
char*)Data.buffer)->~ComplexAPSInt();
319 ((ComplexAPFloat*)(
char*)Data.buffer)->~ComplexAPFloat();
321 ((
LV*)(
char*)Data.buffer)->~
LV();
323 ((Arr*)(
char*)Data.buffer)->~Arr();
325 ((StructData*)(
char*)Data.buffer)->~StructData();
327 ((UnionData*)(
char*)Data.buffer)->~UnionData();
331 ((AddrLabelDiffData*)(
char*)Data.buffer)->~AddrLabelDiffData();
347 return getInt().needsCleanup();
355 "In _Complex float types, real and imaginary values always have the " 361 "In _Complex int types, real and imaginary values must have the " 365 return reinterpret_cast<const LV *
>(Data.buffer)->hasPathPtr();
370 llvm_unreachable(
"Unknown APValue kind!");
374 std::swap(
Kind, RHS.Kind);
375 char TmpData[DataSize];
376 memcpy(TmpData, Data.buffer, DataSize);
377 memcpy(Data.buffer, RHS.Data.buffer, DataSize);
378 memcpy(RHS.Data.buffer, TmpData, DataSize);
383 llvm::errs() <<
'\n';
389 V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
391 return V.convertToDouble();
400 OS <<
"Indeterminate";
403 OS <<
"Int: " <<
getInt();
427 OS <<
"LValue: <todo>";
445 for (
unsigned I = 1; I != N; ++I) {
453 for (
unsigned I = 1; I != N; ++I) {
464 OS <<
"MemberPointer: <todo>";
467 OS <<
"AddrLabelDiff: <todo>";
470 llvm_unreachable(
"Unknown APValue kind!");
477 Out <<
"<out of lifetime>";
480 Out <<
"<uninitialized>";
484 Out << (
getInt().getBoolValue() ?
"true" :
"false");
522 Out << (Ctx.
getLangOpts().CPlusPlus11 ?
"nullptr" :
"0");
523 }
else if (IsReference) {
545 }
else if (!IsReference) {
556 << DA.getIndex() <<
"}";
558 assert(Base.
get<
const Expr *>() !=
nullptr &&
559 "Expecting non-null Expr");
565 Out <<
" + " << (O / S);
581 ElemTy = VD->getType();
588 << DA.getIndex() <<
"}";
592 assert(E !=
nullptr &&
"Expecting non-null Expr");
601 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
605 const Decl *BaseOrMember = Path[I].getAsBaseOrMember().getPointer();
606 if (
const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
610 const ValueDecl *VD = cast<ValueDecl>(BaseOrMember);
613 Out << *CastToBase <<
"::";
615 ElemTy = VD->getType();
619 Out <<
'[' << Path[I].getAsArrayIndex() <<
']';
640 for (
unsigned I = 1; I != N; ++I) {
660 for (
unsigned I = 0; I != N; ++I, ++BI) {
668 for (
const auto *FI : RD->
fields()) {
671 if (FI->isUnnamedBitfield())
continue;
682 Out <<
"." << *FD <<
" = ";
691 Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) <<
"::" << *VD;
702 llvm_unreachable(
"Unknown APValue kind!");
707 llvm::raw_string_ostream Out(Result);
734 assert(
isLValue() &&
"Invalid accessor");
735 return ((
const LV*)(
const void*)Data.buffer)->Base;
739 assert(
isLValue() &&
"Invalid accessor");
740 return ((
const LV*)(
const void*)Data.buffer)->IsOnePastTheEnd;
744 assert(
isLValue() &&
"Invalid accessor");
745 return ((
LV*)(
void*)Data.buffer)->Offset;
749 assert(
isLValue() &&
"Invalid accessor");
750 return ((
const LV*)(
const char*)Data.buffer)->hasPath();
755 const LV &LVal = *((
const LV*)(
const char*)Data.buffer);
756 return llvm::makeArrayRef(LVal.
getPath(), LVal.PathLength);
760 assert(
isLValue() &&
"Invalid accessor");
761 return ((
const LV*)(
const char*)Data.buffer)->Base.getCallIndex();
765 assert(
isLValue() &&
"Invalid accessor");
766 return ((
const LV*)(
const char*)Data.buffer)->Base.getVersion();
770 assert(
isLValue() &&
"Invalid usage");
771 return ((
const LV*)(
const char*)Data.buffer)->IsNullPtr;
776 assert(
isLValue() &&
"Invalid accessor");
777 LV &LVal = *((
LV*)(
char*)Data.buffer);
779 LVal.IsOnePastTheEnd =
false;
782 LVal.IsNullPtr = IsNullPtr;
788 assert(
isLValue() &&
"Invalid accessor");
789 LV &LVal = *((
LV*)(
char*)Data.buffer);
791 LVal.IsOnePastTheEnd = IsOnePastTheEnd;
795 LVal.IsNullPtr = IsNullPtr;
802 return MPD.MemberAndIsDerivedMember.getPointer();
809 return MPD.MemberAndIsDerivedMember.getInt();
816 return llvm::makeArrayRef(MPD.
getPath(), MPD.PathLength);
819 void APValue::MakeLValue() {
820 assert(
isAbsent() &&
"Bad state change");
821 static_assert(
sizeof(
LV) <= DataSize,
"LV too big");
822 new ((
void*)(
char*)Data.buffer)
LV();
826 void APValue::MakeArray(
unsigned InitElts,
unsigned Size) {
827 assert(
isAbsent() &&
"Bad state change");
828 new ((
void*)(
char*)Data.buffer) Arr(InitElts, Size);
832 void APValue::MakeMemberPointer(
const ValueDecl *Member,
bool IsDerivedMember,
834 assert(
isAbsent() &&
"Bad state change");
837 MPD->MemberAndIsDerivedMember.setPointer(Member);
838 MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
unsigned getStructNumFields() const
Defines the clang::ASTContext interface.
void resizePath(unsigned Length)
friend llvm::hash_code hash_value(const LValueBase &Base)
friend bool operator==(const LValueBase &LHS, const LValueBase &RHS)
A (possibly-)qualified type.
llvm::APSInt getValue() const
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
unsigned getCallIndex() const
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...
The base class of the type hierarchy.
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)
QualType getTypeInfoType() const
Describes how types, statements, expressions, and declarations should be printed. ...
bool isLValueOnePastTheEnd() const
const ValueDecl * getMemberPointerDecl() const
Represents a struct/union/class.
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.
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
Symbolic representation of typeid(T) for some type T.
void * TypeInfoType
The type std::type_info, if this is a TypeInfoLValue.
llvm::hash_code hash_value(const APValue::LValueBase &Base)
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
const clang::PrintingPolicy & getPrintingPolicy() const
base_class_iterator bases_begin()
LValuePathEntry * PathPtr
bool needsCleanup() const
Returns whether the object performed allocations.
void * getAsOpaquePtr() const
APSInt & getComplexIntReal()
APValue & getVectorElt(unsigned I)
The APFixedPoint class works similarly to APInt/APSInt in that it is a functional replacement for a s...
unsigned getLValueVersion() const
static CharUnits One()
One - Construct a CharUnits quantity of one.
unsigned getVersion() const
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.
const Type * getType() const
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
A non-discriminated union of a base, field, or array index.
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
void * DynamicAllocType
The QualType, if this is a DynamicAllocLValue.
const T * castAs() const
Member-template castAs<specific type>.
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.
Symbolic representation of a dynamic allocation.
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)
This object has an indeterminate value (C++ [basic.indet]).
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()
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
static QualType getFromOpaquePtr(const void *Ptr)
bool isMemberPointerToDerivedMember() const
QualType getDynamicAllocType() 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.
There is no such object (it's outside its lifetime).
base_class_iterator bases_end()
void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const
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
APFixedPoint & getFixedPoint()
void setComplexFloat(APFloat R, APFloat I)
CharUnits & getLValueOffset()
unsigned getVectorLength() const