Index: tools/clang/include/clang/AST/APValue.h
==================================================================
--- tools/clang/include/clang/AST/APValue.h
+++ tools/clang/include/clang/AST/APValue.h
@@ -386,10 +386,14 @@
   /// Assign by swapping from a copy of the RHS.
   APValue &operator=(APValue RHS) {
     swap(RHS);
     return *this;
   }
+
+  /// \brief Get memory directly consumed by APValue instance not
+  /// including memory held through non-owned pointers.
+  size_t getMemorySize() const;
 
 private:
   void DestroyDataAndMakeUninit();
   void MakeUninit() {
     if (Kind != Uninitialized)

Index: tools/clang/lib/AST/APValue.cpp
==================================================================
--- tools/clang/lib/AST/APValue.cpp
+++ tools/clang/lib/AST/APValue.cpp
@@ -62,10 +62,15 @@
 
   LValuePathEntry *getPath() { return hasPathPtr() ? PathPtr : Path; }
   const LValuePathEntry *getPath() const {
     return hasPathPtr() ? PathPtr : Path;
   }
+
+  size_t getMemorySize() const {
+    return sizeof(LV) + (hasPathPtr() ? (PathLength * sizeof(LValuePathEntry))
+                                      : 0);
+  }
 };
 
 namespace {
   struct MemberPointerBase {
     llvm::PointerIntPair<const ValueDecl*, 1, bool> MemberAndIsDerivedMember;
@@ -99,10 +104,15 @@
 
   PathElem *getPath() { return hasPathPtr() ? PathPtr : Path; }
   const PathElem *getPath() const {
     return hasPathPtr() ? PathPtr : Path;
   }
+
+  size_t getMemorySize() const {
+    return sizeof(MemberPointerData) +
+             (hasPathPtr() ? (PathLength * sizeof(PathElem)) : 0);
+  }
 };
 
 // FIXME: Reduce the malloc traffic here.
 
 APValue::Arr::Arr(unsigned NumElts, unsigned Size) :
@@ -602,5 +612,57 @@
   MPD->MemberAndIsDerivedMember.setPointer(Member);
   MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
   MPD->resizePath(Path.size());
   memcpy(MPD->getPath(), Path.data(), Path.size()*sizeof(const CXXRecordDecl*));
 }
+
+size_t APValue::getMemorySize() const {
+  // Only returns the memory actually held by the APValue, not that
+  // held through non-owned pointers.
+  switch (getKind()) {
+    case Uninitialized:
+    case Int:
+    case Float:
+    case ComplexInt:
+    case ComplexFloat:
+    case AddrLabelDiff:
+      return sizeof(APValue);
+
+    case Vector: {
+      size_t Total = sizeof(APValue);
+      for (unsigned I = 0, N = getVectorLength(); I != N; ++I)
+        Total += getVectorElt(I).getMemorySize();
+      return Total;
+    }
+
+    case Array: {
+      size_t Total = sizeof(APValue);
+      for (unsigned I = 0, N = getArrayInitializedElts(); I != N; ++I)
+        Total += getArrayInitializedElt(I).getMemorySize();
+      if (hasArrayFiller())
+        Total += getArrayFiller().getMemorySize();
+      return Total;
+    }
+
+    case Struct: {
+      size_t Total = sizeof(APValue);
+      for (unsigned I = 0, N = getStructNumBases(); I != N; ++I)
+        Total += getStructBase(I).getMemorySize();
+      for (unsigned I = 0, N = getStructNumFields(); I != N; ++I)
+        Total += getStructField(I).getMemorySize();
+      return Total;
+    }
+
+    case Union:
+      return sizeof(APValue) + getUnionValue().getMemorySize();
+
+    case LValue:
+      return sizeof(APValue) + ((const LV*)(const void*)Data)->getMemorySize();
+
+    case MemberPointer:
+      return sizeof(APValue) +
+             ((const MemberPointerData*)(const char*)Data)->getMemorySize();
+    }
+
+  llvm_unreachable("Unknown APValue kind!");
+  return 0;
+}

