diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-09-27 01:26:47 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-09-27 01:26:47 +0000 |
commit | e9401b10f5a8f2d6e40aba10304a66daafa2e610 (patch) | |
tree | 7a995ddd61c8c4e2faddf5aea609765895ec5490 /include/clang/AST | |
parent | 3c5620725db305fc19506ccc2bce66f9a8b7b319 (diff) | |
download | clang-e9401b10f5a8f2d6e40aba10304a66daafa2e610.tar.gz |
For P0784R7: Add support for dynamic allocation with new / delete during
constant evaluation.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@373036 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/AST')
-rw-r--r-- | include/clang/AST/APValue.h | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h index 6943479831..63359294ef 100644 --- a/include/clang/AST/APValue.h +++ b/include/clang/AST/APValue.h @@ -53,6 +53,34 @@ public: void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const; }; + +/// Symbolic representation of a dynamic allocation. +class DynamicAllocLValue { + unsigned Index; + +public: + DynamicAllocLValue() : Index(0) {} + explicit DynamicAllocLValue(unsigned Index) : Index(Index + 1) {} + unsigned getIndex() { return Index - 1; } + + explicit operator bool() const { return Index != 0; } + + void *getOpaqueValue() { + return reinterpret_cast<void *>(static_cast<uintptr_t>(Index) + << NumLowBitsAvailable); + } + static DynamicAllocLValue getFromOpaqueValue(void *Value) { + DynamicAllocLValue V; + V.Index = reinterpret_cast<uintptr_t>(Value) >> NumLowBitsAvailable; + return V; + } + + static unsigned getMaxIndex() { + return (std::numeric_limits<unsigned>::max() >> NumLowBitsAvailable) - 1; + } + + static constexpr int NumLowBitsAvailable = 3; +}; } namespace llvm { @@ -67,6 +95,17 @@ template<> struct PointerLikeTypeTraits<clang::TypeInfoLValue> { // to include Type.h. static constexpr int NumLowBitsAvailable = 3; }; + +template<> struct PointerLikeTypeTraits<clang::DynamicAllocLValue> { + static void *getAsVoidPointer(clang::DynamicAllocLValue V) { + return V.getOpaqueValue(); + } + static clang::DynamicAllocLValue getFromVoidPointer(void *P) { + return clang::DynamicAllocLValue::getFromOpaqueValue(P); + } + static constexpr int NumLowBitsAvailable = + clang::DynamicAllocLValue::NumLowBitsAvailable; +}; } namespace clang { @@ -97,13 +136,15 @@ public: }; class LValueBase { - typedef llvm::PointerUnion<const ValueDecl *, const Expr *, TypeInfoLValue> + typedef llvm::PointerUnion<const ValueDecl *, const Expr *, TypeInfoLValue, + DynamicAllocLValue> PtrTy; public: LValueBase() : Local{} {} LValueBase(const ValueDecl *P, unsigned I = 0, unsigned V = 0); LValueBase(const Expr *P, unsigned I = 0, unsigned V = 0); + static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type); static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo); template <class T> @@ -124,6 +165,7 @@ public: unsigned getCallIndex() const; unsigned getVersion() const; QualType getTypeInfoType() const; + QualType getDynamicAllocType() const; friend bool operator==(const LValueBase &LHS, const LValueBase &RHS); friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) { @@ -140,6 +182,8 @@ public: LocalState Local; /// The type std::type_info, if this is a TypeInfoLValue. void *TypeInfoType; + /// The QualType, if this is a DynamicAllocLValue. + void *DynamicAllocType; }; }; |