summaryrefslogtreecommitdiff
path: root/include/clang/AST
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2019-09-27 01:26:47 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2019-09-27 01:26:47 +0000
commite9401b10f5a8f2d6e40aba10304a66daafa2e610 (patch)
tree7a995ddd61c8c4e2faddf5aea609765895ec5490 /include/clang/AST
parent3c5620725db305fc19506ccc2bce66f9a8b7b319 (diff)
downloadclang-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.h46
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;
};
};