summaryrefslogtreecommitdiff
path: root/include/llvm/IR/Value.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/IR/Value.h')
-rw-r--r--include/llvm/IR/Value.h21
1 files changed, 20 insertions, 1 deletions
diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h
index 96a370dcc35f..d669b1544070 100644
--- a/include/llvm/IR/Value.h
+++ b/include/llvm/IR/Value.h
@@ -21,6 +21,7 @@
#include "llvm-c/Types.h"
#include <cassert>
#include <iterator>
+#include <memory>
namespace llvm {
@@ -69,6 +70,8 @@ using ValueName = StringMapEntry<Value*>;
/// objects that watch it and listen to RAUW and Destroy events. See
/// llvm/IR/ValueHandle.h for details.
class Value {
+ // The least-significant bit of the first word of Value *must* be zero:
+ // http://www.llvm.org/docs/ProgrammersManual.html#the-waymarking-algorithm
Type *VTy;
Use *UseList;
@@ -200,10 +203,19 @@ private:
protected:
Value(Type *Ty, unsigned scid);
+ /// Value's destructor should be virtual by design, but that would require
+ /// that Value and all of its subclasses have a vtable that effectively
+ /// duplicates the information in the value ID. As a size optimization, the
+ /// destructor has been protected, and the caller should manually call
+ /// deleteValue.
+ ~Value(); // Use deleteValue() to delete a generic Value.
+
public:
Value(const Value &) = delete;
void operator=(const Value &) = delete;
- virtual ~Value();
+
+ /// Delete a pointer to a generic Value.
+ void deleteValue();
/// \brief Support for debugging, callable in GDB: V->dump()
void dump() const;
@@ -643,6 +655,13 @@ protected:
void setValueSubclassData(unsigned short D) { SubclassData = D; }
};
+struct ValueDeleter { void operator()(Value *V) { V->deleteValue(); } };
+
+/// Use this instead of std::unique_ptr<Value> or std::unique_ptr<Instruction>.
+/// Those don't work because Value and Instruction's destructors are protected,
+/// aren't virtual, and won't destroy the complete object.
+typedef std::unique_ptr<Value, ValueDeleter> unique_value;
+
inline raw_ostream &operator<<(raw_ostream &OS, const Value &V) {
V.print(OS);
return OS;