aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/include/clang/AST/APValue.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/include/clang/AST/APValue.h')
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/APValue.h163
1 files changed, 103 insertions, 60 deletions
diff --git a/contrib/llvm-project/clang/include/clang/AST/APValue.h b/contrib/llvm-project/clang/include/clang/AST/APValue.h
index cca92b5f8235..5f4ac02f53c9 100644
--- a/contrib/llvm-project/clang/include/clang/AST/APValue.h
+++ b/contrib/llvm-project/clang/include/clang/AST/APValue.h
@@ -13,14 +13,20 @@
#ifndef LLVM_CLANG_AST_APVALUE_H
#define LLVM_CLANG_AST_APVALUE_H
-#include "clang/Basic/FixedPoint.h"
#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/APFixedPoint.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/Support/AlignOf.h"
namespace clang {
+namespace serialization {
+template <typename T> class BasicReaderBase;
+} // end namespace serialization
+
class AddrLabelExpr;
class ASTContext;
class CharUnits;
@@ -32,6 +38,7 @@ namespace clang {
struct PrintingPolicy;
class Type;
class ValueDecl;
+ class QualType;
/// Symbolic representation of typeid(T) for some type T.
class TypeInfoLValue {
@@ -113,6 +120,7 @@ namespace clang {
/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
/// [Vector: N * APValue], [Array: N * APValue]
class APValue {
+ typedef llvm::APFixedPoint APFixedPoint;
typedef llvm::APSInt APSInt;
typedef llvm::APFloat APFloat;
public:
@@ -147,6 +155,8 @@ public:
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type);
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo);
+ void Profile(llvm::FoldingSetNodeID &ID) const;
+
template <class T>
bool is() const { return Ptr.is<T>(); }
@@ -167,11 +177,14 @@ public:
QualType getTypeInfoType() const;
QualType getDynamicAllocType() const;
+ QualType getType() const;
+
friend bool operator==(const LValueBase &LHS, const LValueBase &RHS);
friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) {
return !(LHS == RHS);
}
friend llvm::hash_code hash_value(const LValueBase &Base);
+ friend struct llvm::DenseMapInfo<LValueBase>;
private:
PtrTy Ptr;
@@ -199,8 +212,7 @@ public:
public:
LValuePathEntry() : Value() {}
- LValuePathEntry(BaseOrMemberType BaseOrMember)
- : Value{reinterpret_cast<uintptr_t>(BaseOrMember.getOpaqueValue())} {}
+ LValuePathEntry(BaseOrMemberType BaseOrMember);
static LValuePathEntry ArrayIndex(uint64_t Index) {
LValuePathEntry Result;
Result.Value = Index;
@@ -213,6 +225,8 @@ public:
}
uint64_t getAsArrayIndex() const { return Value; }
+ void Profile(llvm::FoldingSetNodeID &ID) const;
+
friend bool operator==(LValuePathEntry A, LValuePathEntry B) {
return A.Value == B.Value;
}
@@ -223,12 +237,22 @@ public:
return llvm::hash_value(A.Value);
}
};
+ class LValuePathSerializationHelper {
+ const void *ElemTy;
+
+ public:
+ ArrayRef<LValuePathEntry> Path;
+
+ LValuePathSerializationHelper(ArrayRef<LValuePathEntry>, QualType);
+ QualType getType();
+ };
struct NoLValuePath {};
struct UninitArray {};
struct UninitStruct {};
- friend class ASTReader;
- friend class ASTWriter;
+ template <typename Impl> friend class clang::serialization::BasicReaderBase;
+ friend class ASTImporter;
+ friend class ASTNodeImporter;
private:
ValueKind Kind;
@@ -302,7 +326,7 @@ public:
MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
}
APValue(const APValue &RHS);
- APValue(APValue &&RHS) : Kind(None) { swap(RHS); }
+ APValue(APValue &&RHS);
APValue(LValueBase B, const CharUnits &O, NoLValuePath N,
bool IsNullPtr = false)
: Kind(None) {
@@ -337,6 +361,9 @@ public:
return Result;
}
+ APValue &operator=(const APValue &RHS);
+ APValue &operator=(APValue &&RHS);
+
~APValue() {
if (Kind != None && Kind != Indeterminate)
DestroyDataAndMakeUninit();
@@ -352,6 +379,11 @@ public:
/// Swaps the contents of this and the given APValue.
void swap(APValue &RHS);
+ /// profile this value. There is no guarantee that values of different
+ /// types will not produce the same profiled value, so the type should
+ /// typically also be profiled if it's not implied by the context.
+ void Profile(llvm::FoldingSetNodeID &ID) const;
+
ValueKind getKind() const { return Kind; }
bool isAbsent() const { return Kind == None; }
@@ -375,11 +407,14 @@ public:
void dump(raw_ostream &OS, const ASTContext &Context) const;
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const;
+ void printPretty(raw_ostream &OS, const PrintingPolicy &Policy, QualType Ty,
+ const ASTContext *Ctx = nullptr) const;
+
std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
APSInt &getInt() {
assert(isInt() && "Invalid accessor");
- return *(APSInt*)(char*)Data.buffer;
+ return *(APSInt *)(char *)&Data;
}
const APSInt &getInt() const {
return const_cast<APValue*>(this)->getInt();
@@ -393,7 +428,7 @@ public:
APFloat &getFloat() {
assert(isFloat() && "Invalid accessor");
- return *(APFloat*)(char*)Data.buffer;
+ return *(APFloat *)(char *)&Data;
}
const APFloat &getFloat() const {
return const_cast<APValue*>(this)->getFloat();
@@ -401,7 +436,7 @@ public:
APFixedPoint &getFixedPoint() {
assert(isFixedPoint() && "Invalid accessor");
- return *(APFixedPoint *)(char *)Data.buffer;
+ return *(APFixedPoint *)(char *)&Data;
}
const APFixedPoint &getFixedPoint() const {
return const_cast<APValue *>(this)->getFixedPoint();
@@ -409,7 +444,7 @@ public:
APSInt &getComplexIntReal() {
assert(isComplexInt() && "Invalid accessor");
- return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
+ return ((ComplexAPSInt *)(char *)&Data)->Real;
}
const APSInt &getComplexIntReal() const {
return const_cast<APValue*>(this)->getComplexIntReal();
@@ -417,7 +452,7 @@ public:
APSInt &getComplexIntImag() {
assert(isComplexInt() && "Invalid accessor");
- return ((ComplexAPSInt*)(char*)Data.buffer)->Imag;
+ return ((ComplexAPSInt *)(char *)&Data)->Imag;
}
const APSInt &getComplexIntImag() const {
return const_cast<APValue*>(this)->getComplexIntImag();
@@ -425,7 +460,7 @@ public:
APFloat &getComplexFloatReal() {
assert(isComplexFloat() && "Invalid accessor");
- return ((ComplexAPFloat*)(char*)Data.buffer)->Real;
+ return ((ComplexAPFloat *)(char *)&Data)->Real;
}
const APFloat &getComplexFloatReal() const {
return const_cast<APValue*>(this)->getComplexFloatReal();
@@ -433,7 +468,7 @@ public:
APFloat &getComplexFloatImag() {
assert(isComplexFloat() && "Invalid accessor");
- return ((ComplexAPFloat*)(char*)Data.buffer)->Imag;
+ return ((ComplexAPFloat *)(char *)&Data)->Imag;
}
const APFloat &getComplexFloatImag() const {
return const_cast<APValue*>(this)->getComplexFloatImag();
@@ -454,20 +489,20 @@ public:
APValue &getVectorElt(unsigned I) {
assert(isVector() && "Invalid accessor");
assert(I < getVectorLength() && "Index out of range");
- return ((Vec*)(char*)Data.buffer)->Elts[I];
+ return ((Vec *)(char *)&Data)->Elts[I];
}
const APValue &getVectorElt(unsigned I) const {
return const_cast<APValue*>(this)->getVectorElt(I);
}
unsigned getVectorLength() const {
assert(isVector() && "Invalid accessor");
- return ((const Vec*)(const void *)Data.buffer)->NumElts;
+ return ((const Vec *)(const void *)&Data)->NumElts;
}
APValue &getArrayInitializedElt(unsigned I) {
assert(isArray() && "Invalid accessor");
assert(I < getArrayInitializedElts() && "Index out of range");
- return ((Arr*)(char*)Data.buffer)->Elts[I];
+ return ((Arr *)(char *)&Data)->Elts[I];
}
const APValue &getArrayInitializedElt(unsigned I) const {
return const_cast<APValue*>(this)->getArrayInitializedElt(I);
@@ -478,35 +513,37 @@ public:
APValue &getArrayFiller() {
assert(isArray() && "Invalid accessor");
assert(hasArrayFiller() && "No array filler");
- return ((Arr*)(char*)Data.buffer)->Elts[getArrayInitializedElts()];
+ return ((Arr *)(char *)&Data)->Elts[getArrayInitializedElts()];
}
const APValue &getArrayFiller() const {
return const_cast<APValue*>(this)->getArrayFiller();
}
unsigned getArrayInitializedElts() const {
assert(isArray() && "Invalid accessor");
- return ((const Arr*)(const void *)Data.buffer)->NumElts;
+ return ((const Arr *)(const void *)&Data)->NumElts;
}
unsigned getArraySize() const {
assert(isArray() && "Invalid accessor");
- return ((const Arr*)(const void *)Data.buffer)->ArrSize;
+ return ((const Arr *)(const void *)&Data)->ArrSize;
}
unsigned getStructNumBases() const {
assert(isStruct() && "Invalid accessor");
- return ((const StructData*)(const char*)Data.buffer)->NumBases;
+ return ((const StructData *)(const char *)&Data)->NumBases;
}
unsigned getStructNumFields() const {
assert(isStruct() && "Invalid accessor");
- return ((const StructData*)(const char*)Data.buffer)->NumFields;
+ return ((const StructData *)(const char *)&Data)->NumFields;
}
APValue &getStructBase(unsigned i) {
assert(isStruct() && "Invalid accessor");
- return ((StructData*)(char*)Data.buffer)->Elts[i];
+ assert(i < getStructNumBases() && "base class index OOB");
+ return ((StructData *)(char *)&Data)->Elts[i];
}
APValue &getStructField(unsigned i) {
assert(isStruct() && "Invalid accessor");
- return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i];
+ assert(i < getStructNumFields() && "field index OOB");
+ return ((StructData *)(char *)&Data)->Elts[getStructNumBases() + i];
}
const APValue &getStructBase(unsigned i) const {
return const_cast<APValue*>(this)->getStructBase(i);
@@ -517,11 +554,11 @@ public:
const FieldDecl *getUnionField() const {
assert(isUnion() && "Invalid accessor");
- return ((const UnionData*)(const char*)Data.buffer)->Field;
+ return ((const UnionData *)(const char *)&Data)->Field;
}
APValue &getUnionValue() {
assert(isUnion() && "Invalid accessor");
- return *((UnionData*)(char*)Data.buffer)->Value;
+ return *((UnionData *)(char *)&Data)->Value;
}
const APValue &getUnionValue() const {
return const_cast<APValue*>(this)->getUnionValue();
@@ -533,119 +570,125 @@ public:
const AddrLabelExpr* getAddrLabelDiffLHS() const {
assert(isAddrLabelDiff() && "Invalid accessor");
- return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr;
+ return ((const AddrLabelDiffData *)(const char *)&Data)->LHSExpr;
}
const AddrLabelExpr* getAddrLabelDiffRHS() const {
assert(isAddrLabelDiff() && "Invalid accessor");
- return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr;
+ return ((const AddrLabelDiffData *)(const char *)&Data)->RHSExpr;
}
void setInt(APSInt I) {
assert(isInt() && "Invalid accessor");
- *(APSInt *)(char *)Data.buffer = std::move(I);
+ *(APSInt *)(char *)&Data = std::move(I);
}
void setFloat(APFloat F) {
assert(isFloat() && "Invalid accessor");
- *(APFloat *)(char *)Data.buffer = std::move(F);
+ *(APFloat *)(char *)&Data = std::move(F);
}
void setFixedPoint(APFixedPoint FX) {
assert(isFixedPoint() && "Invalid accessor");
- *(APFixedPoint *)(char *)Data.buffer = std::move(FX);
+ *(APFixedPoint *)(char *)&Data = std::move(FX);
}
void setVector(const APValue *E, unsigned N) {
- assert(isVector() && "Invalid accessor");
- ((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
- ((Vec*)(char*)Data.buffer)->NumElts = N;
+ MutableArrayRef<APValue> InternalElts = setVectorUninit(N);
for (unsigned i = 0; i != N; ++i)
- ((Vec*)(char*)Data.buffer)->Elts[i] = E[i];
+ InternalElts[i] = E[i];
}
void setComplexInt(APSInt R, APSInt I) {
assert(R.getBitWidth() == I.getBitWidth() &&
"Invalid complex int (type mismatch).");
assert(isComplexInt() && "Invalid accessor");
- ((ComplexAPSInt *)(char *)Data.buffer)->Real = std::move(R);
- ((ComplexAPSInt *)(char *)Data.buffer)->Imag = std::move(I);
+ ((ComplexAPSInt *)(char *)&Data)->Real = std::move(R);
+ ((ComplexAPSInt *)(char *)&Data)->Imag = std::move(I);
}
void setComplexFloat(APFloat R, APFloat I) {
assert(&R.getSemantics() == &I.getSemantics() &&
"Invalid complex float (type mismatch).");
assert(isComplexFloat() && "Invalid accessor");
- ((ComplexAPFloat *)(char *)Data.buffer)->Real = std::move(R);
- ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
+ ((ComplexAPFloat *)(char *)&Data)->Real = std::move(R);
+ ((ComplexAPFloat *)(char *)&Data)->Imag = std::move(I);
}
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
bool IsNullPtr);
void setLValue(LValueBase B, const CharUnits &O,
ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
bool IsNullPtr);
- void setUnion(const FieldDecl *Field, const APValue &Value) {
- assert(isUnion() && "Invalid accessor");
- ((UnionData*)(char*)Data.buffer)->Field = Field;
- *((UnionData*)(char*)Data.buffer)->Value = Value;
- }
+ void setUnion(const FieldDecl *Field, const APValue &Value);
void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
const AddrLabelExpr* RHSExpr) {
- ((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr;
- ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr;
- }
-
- /// Assign by swapping from a copy of the RHS.
- APValue &operator=(APValue RHS) {
- swap(RHS);
- return *this;
+ ((AddrLabelDiffData *)(char *)&Data)->LHSExpr = LHSExpr;
+ ((AddrLabelDiffData *)(char *)&Data)->RHSExpr = RHSExpr;
}
private:
void DestroyDataAndMakeUninit();
void MakeInt() {
assert(isAbsent() && "Bad state change");
- new ((void*)Data.buffer) APSInt(1);
+ new ((void *)&Data) APSInt(1);
Kind = Int;
}
void MakeFloat() {
assert(isAbsent() && "Bad state change");
- new ((void*)(char*)Data.buffer) APFloat(0.0);
+ new ((void *)(char *)&Data) APFloat(0.0);
Kind = Float;
}
void MakeFixedPoint(APFixedPoint &&FX) {
assert(isAbsent() && "Bad state change");
- new ((void *)(char *)Data.buffer) APFixedPoint(std::move(FX));
+ new ((void *)(char *)&Data) APFixedPoint(std::move(FX));
Kind = FixedPoint;
}
void MakeVector() {
assert(isAbsent() && "Bad state change");
- new ((void*)(char*)Data.buffer) Vec();
+ new ((void *)(char *)&Data) Vec();
Kind = Vector;
}
void MakeComplexInt() {
assert(isAbsent() && "Bad state change");
- new ((void*)(char*)Data.buffer) ComplexAPSInt();
+ new ((void *)(char *)&Data) ComplexAPSInt();
Kind = ComplexInt;
}
void MakeComplexFloat() {
assert(isAbsent() && "Bad state change");
- new ((void*)(char*)Data.buffer) ComplexAPFloat();
+ new ((void *)(char *)&Data) ComplexAPFloat();
Kind = ComplexFloat;
}
void MakeLValue();
void MakeArray(unsigned InitElts, unsigned Size);
void MakeStruct(unsigned B, unsigned M) {
assert(isAbsent() && "Bad state change");
- new ((void*)(char*)Data.buffer) StructData(B, M);
+ new ((void *)(char *)&Data) StructData(B, M);
Kind = Struct;
}
void MakeUnion() {
assert(isAbsent() && "Bad state change");
- new ((void*)(char*)Data.buffer) UnionData();
+ new ((void *)(char *)&Data) UnionData();
Kind = Union;
}
void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
ArrayRef<const CXXRecordDecl*> Path);
void MakeAddrLabelDiff() {
assert(isAbsent() && "Bad state change");
- new ((void*)(char*)Data.buffer) AddrLabelDiffData();
+ new ((void *)(char *)&Data) AddrLabelDiffData();
Kind = AddrLabelDiff;
}
+
+private:
+ /// The following functions are used as part of initialization, during
+ /// deserialization and importing. Reserve the space so that it can be
+ /// filled in by those steps.
+ MutableArrayRef<APValue> setVectorUninit(unsigned N) {
+ assert(isVector() && "Invalid accessor");
+ Vec *V = ((Vec *)(char *)&Data);
+ V->Elts = new APValue[N];
+ V->NumElts = N;
+ return {V->Elts, V->NumElts};
+ }
+ MutableArrayRef<LValuePathEntry>
+ setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size,
+ bool OnePastTheEnd, bool IsNullPtr);
+ MutableArrayRef<const CXXRecordDecl *>
+ setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember,
+ unsigned Size);
};
} // end namespace clang.