Introduce another Reset() method in BumpPtrAllocator that calls a destructor
[oota-llvm.git] / include / llvm / Support / Allocator.h
index 4c848788c73dd2abae3f2f3275938a36251a5006..a58b9db27faafc3b4aa58adb3c5ae9f75eb17ee7 100644 (file)
 #define LLVM_SUPPORT_ALLOCATOR_H
 
 #include "llvm/Support/AlignOf.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/System/DataTypes.h"
+#include <algorithm>
 #include <cassert>
 #include <cstdlib>
+#include <cstddef>
 
 namespace llvm {
 
@@ -131,6 +134,7 @@ class BumpPtrAllocator {
   static MallocSlabAllocator DefaultSlabAllocator;
 
 public:
+  typedef void (*DTorFunction)(void*);
   BumpPtrAllocator(size_t size = 4096, size_t threshold = 4096,
                    SlabAllocator &allocator = DefaultSlabAllocator);
   ~BumpPtrAllocator();
@@ -139,6 +143,11 @@ public:
   /// to the beginning of it, freeing all memory allocated so far.
   void Reset();
 
+  /// Reset - like Reset(), but call DTorFunction for each allocated
+  /// object. This assumes that all objects allocated with this allocator
+  /// had the same size and alignment specified here.
+  void Reset(size_t Size, size_t Alignment, DTorFunction DTor);
+
   /// Allocate - Allocate space at the specified alignment.
   ///
   void *Allocate(size_t Size, size_t Alignment);
@@ -175,4 +184,22 @@ public:
 
 }  // end namespace llvm
 
+inline void *operator new(size_t Size, llvm::BumpPtrAllocator &Allocator) {
+  struct S {
+    char c;
+#ifdef __GNUC__
+    char x __attribute__((aligned));
+#else
+    union {
+      double D;
+      long double LD;
+      long long L;
+      void *P;
+    } x;
+#endif
+  };
+  return Allocator.Allocate(Size, std::min((size_t)llvm::NextPowerOf2(Size),
+                                           offsetof(S, x)));
+}
+
 #endif // LLVM_SUPPORT_ALLOCATOR_H