diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 05ff49c..7afb45c 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -254,6 +254,16 @@
   TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
 };
 
+/// The inheritance model to use for member pointers of a given CXXRecordDecl.
+enum MSInheritanceModel {
+  MSIM_Single,
+  MSIM_SinglePolymorphic,
+  MSIM_Multiple,
+  MSIM_MultiplePolymorphic,
+  MSIM_Virtual,
+  MSIM_Unspecified
+};
+
 /// CXXRecordDecl - Represents a C++ struct/union/class.
 /// FIXME: This class will disappear once we've properly taught RecordDecl
 /// to deal with C++-specific things.
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 23fa3e8..e040214 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -2092,14 +2092,6 @@
   }
 };
 
-/// The inheritance model to use for this member pointer.
-enum MSInheritanceModel {
-  MSIM_Single,
-  MSIM_Multiple,
-  MSIM_Virtual,
-  MSIM_Unspecified
-};
-
 /// MemberPointerType - C++ 8.3.3 - Pointers to members
 ///
 class MemberPointerType : public Type, public llvm::FoldingSetNode {
@@ -2135,10 +2127,6 @@
     return !PointeeType->isFunctionProtoType();
   }
 
-  /// Returns the number of pointer and integer slots used to represent this
-  /// member pointer in the MS C++ ABI.
-  std::pair<unsigned, unsigned> getMSMemberPointerSlots() const;
-
   const Type *getClass() const { return Class; }
 
   bool isSugared() const { return false; }
diff --git a/lib/AST/MicrosoftCXXABI.cpp b/lib/AST/MicrosoftCXXABI.cpp
index 6553e9d..fd932f7 100644
--- a/lib/AST/MicrosoftCXXABI.cpp
+++ b/lib/AST/MicrosoftCXXABI.cpp
@@ -89,8 +89,8 @@
   if (this->getNumVBases() > 0)
     return MSIM_Virtual;
   if (usesMultipleInheritanceModel(this))
-    return MSIM_Multiple;
-  return MSIM_Single;
+    return this->isPolymorphic() ? MSIM_MultiplePolymorphic : MSIM_Multiple;
+  return this->isPolymorphic() ? MSIM_SinglePolymorphic : MSIM_Single;
 }
 
 // Returns the number of pointer and integer slots used to represent a member
@@ -119,15 +119,15 @@
 //
 //     // The offset of the vb-table pointer within the object.  Only needed for
 //     // incomplete types.
-//     int VBTableOffset;
+//     int VBPtrOffset;
 //   };
-std::pair<unsigned, unsigned>
-MemberPointerType::getMSMemberPointerSlots() const {
-  const CXXRecordDecl *RD = this->getClass()->getAsCXXRecordDecl();
+static std::pair<unsigned, unsigned>
+getMSMemberPointerSlots(const MemberPointerType *MPT) {
+  const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
   MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
   unsigned Ptrs;
   unsigned Ints = 0;
-  if (this->isMemberFunctionPointer()) {
+  if (MPT->isMemberFunctionPointer()) {
     // Member function pointers are a struct of a function pointer followed by a
     // variable number of ints depending on the inheritance model used.  The
     // function pointer is a real function if it is non-virtual and a vftable
@@ -137,7 +137,9 @@
     switch (Inheritance) {
     case MSIM_Unspecified: ++Ints;  // VBTableOffset
     case MSIM_Virtual:     ++Ints;  // VirtualBaseAdjustmentOffset
+    case MSIM_MultiplePolymorphic:
     case MSIM_Multiple:    ++Ints;  // NonVirtualBaseAdjustment
+    case MSIM_SinglePolymorphic:
     case MSIM_Single:      break;   // Nothing
     }
   } else {
@@ -147,7 +149,9 @@
     switch (Inheritance) {
     case MSIM_Unspecified: ++Ints;  // VBTableOffset
     case MSIM_Virtual:     ++Ints;  // VirtualBaseAdjustmentOffset
+    case MSIM_MultiplePolymorphic:
     case MSIM_Multiple:             // Nothing
+    case MSIM_SinglePolymorphic:
     case MSIM_Single:      ++Ints;  // Field offset
     }
   }
@@ -160,7 +164,7 @@
   assert(Target.getTriple().getArch() == llvm::Triple::x86 ||
          Target.getTriple().getArch() == llvm::Triple::x86_64);
   unsigned Ptrs, Ints;
-  llvm::tie(Ptrs, Ints) = MPT->getMSMemberPointerSlots();
+  llvm::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
   // The nominal struct is laid out with pointers followed by ints and aligned
   // to a pointer width if any are present and an int width otherwise.
   unsigned PtrSize = Target.getPointerWidth(0);
diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp
index 00b15c9..2c7f89a 100644
--- a/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -111,17 +111,28 @@
   static bool needThisReturn(GlobalDecl GD);
 
 private:
-  llvm::Constant *getSimpleNullMemberPointer(const MemberPointerType *MPT);
-
-  llvm::Constant *getZeroPtrDiff() {
-    return llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
+  llvm::Constant *getZeroInt() {
+    return llvm::ConstantInt::get(CGM.IntTy, 0);
   }
 
-  llvm::Constant *getAllOnesPtrDiff() {
-    return  llvm::Constant::getAllOnesValue(CGM.PtrDiffTy);
+  llvm::Constant *getAllOnesInt() {
+    return  llvm::Constant::getAllOnesValue(CGM.IntTy);
   }
 
+  void
+  GetNullMemberPointerFields(const MemberPointerType *MPT,
+                             llvm::SmallVectorImpl<llvm::Constant *> &fields);
+
+  llvm::Value *AdjustVirtualBase(CodeGenFunction &CGF, const CXXRecordDecl *RD,
+                                 llvm::Value *Base,
+                                 llvm::Value *VirtualBaseAdjustmentOffset,
+                                 llvm::Value *VBPtrOffset /* optional */);
+
 public:
+  virtual llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT);
+
+  virtual bool isZeroInitializable(const MemberPointerType *MPT);
+
   virtual llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
 
   virtual llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
@@ -136,6 +147,12 @@
                                                     llvm::Value *MemPtr,
                                                   const MemberPointerType *MPT);
 
+  virtual llvm::Value *
+  EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
+                                  llvm::Value *&This,
+                                  llvm::Value *MemPtr,
+                                  const MemberPointerType *MPT);
+
 };
 
 }
@@ -379,45 +396,125 @@
   CGF.EmitCXXGlobalVarDeclInit(D, DeclPtr, PerformInit);
 }
 
-// Returns true for member pointer types that we know how to represent with a
-// simple ptrdiff_t.  Currently we only know how to emit, test, and load member
-// data pointers for complete single inheritance classes.
-static bool isSimpleMemberPointer(const MemberPointerType *MPT) {
-  const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
-  return (MPT->isMemberDataPointer() &&
-          !MPT->getClass()->isIncompleteType() &&
-          RD->getNumVBases() == 0);
+// Member pointer helpers.
+static bool hasVBPtrOffsetField(MSInheritanceModel Inheritance) {
+  return Inheritance == MSIM_Unspecified;
 }
 
-llvm::Constant *
-MicrosoftCXXABI::getSimpleNullMemberPointer(const MemberPointerType *MPT) {
-  if (isSimpleMemberPointer(MPT)) {
-    const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
-    // A null member data pointer is represented as -1 if the class is not
-    // polymorphic, and 0 otherwise.
-    if (RD->isPolymorphic())
-      return getZeroPtrDiff();
-    return getAllOnesPtrDiff();
+// Only member pointers to functions need a this adjustment, since it can be
+// combined with the field offset for data pointers.
+static bool hasNonVirtualBaseAdjustmentField(const MemberPointerType *MPT,
+                                             MSInheritanceModel Inheritance) {
+  return (MPT->isMemberFunctionPointer() &&
+          Inheritance >= MSIM_Multiple);
+}
+
+static bool hasVirtualBaseAdjustmentField(MSInheritanceModel Inheritance) {
+  return Inheritance >= MSIM_Virtual;
+}
+
+// Use zero for the field offset of a null data member pointer if we can
+// guarantee that zero is not a valid field offset, or if the member pointer has
+// multiple fields.  Polymorphic classes have a vfptr at offset zero, so we can
+// use zero for null.  If there are multiple fields, we can use zero even if it
+// is a valid field offset because null-ness testing will check the other
+// fields.
+static bool nullFieldOffsetIsZero(MSInheritanceModel Inheritance) {
+  return Inheritance != MSIM_Multiple && Inheritance != MSIM_Single;
+}
+
+bool MicrosoftCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
+  // Null-ness for function memptrs only depends on the first field, which is
+  // the function pointer.  The rest don't matter, so we can zero initialize.
+  if (MPT->isMemberFunctionPointer())
+    return true;
+
+  // The virtual base adjustment field is always -1 for null, so if we have one
+  // we can't zero initialize.  The field offset is sometimes also -1 if 0 is a
+  // valid field offset.
+  const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
+  MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
+  return (!hasVirtualBaseAdjustmentField(Inheritance) &&
+          nullFieldOffsetIsZero(Inheritance));
+}
+
+llvm::Type *
+MicrosoftCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
+  const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
+  MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
+  llvm::SmallVector<llvm::Type *, 4> fields;
+  if (MPT->isMemberFunctionPointer())
+    fields.push_back(CGM.VoidPtrTy);  // FunctionPointerOrVirtualThunk
+  else
+    fields.push_back(CGM.IntTy);  // FieldOffset
+
+  if (hasVBPtrOffsetField(Inheritance))
+    fields.push_back(CGM.IntTy);
+  if (hasNonVirtualBaseAdjustmentField(MPT, Inheritance))
+    fields.push_back(CGM.IntTy);
+  if (hasVirtualBaseAdjustmentField(Inheritance))
+    fields.push_back(CGM.IntTy);  // VirtualBaseAdjustmentOffset
+
+  if (fields.size() == 1)
+    return fields[0];
+  return llvm::StructType::get(CGM.getLLVMContext(), fields);
+}
+
+void MicrosoftCXXABI::
+GetNullMemberPointerFields(const MemberPointerType *MPT,
+                           llvm::SmallVectorImpl<llvm::Constant *> &fields) {
+  assert(fields.empty());
+  const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
+  MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
+  if (MPT->isMemberFunctionPointer()) {
+    // FunctionPointerOrVirtualThunk
+    fields.push_back(llvm::Constant::getNullValue(CGM.VoidPtrTy));
+  } else {
+    if (nullFieldOffsetIsZero(Inheritance))
+      fields.push_back(getZeroInt());  // FieldOffset
+    else
+      fields.push_back(getAllOnesInt());  // FieldOffset
   }
-  return GetBogusMemberPointer(QualType(MPT, 0));
+
+  if (hasVBPtrOffsetField(Inheritance))
+    fields.push_back(getZeroInt());
+  if (hasNonVirtualBaseAdjustmentField(MPT, Inheritance))
+    fields.push_back(getZeroInt());
+  if (hasVirtualBaseAdjustmentField(Inheritance))
+    fields.push_back(getAllOnesInt());
 }
 
 llvm::Constant *
 MicrosoftCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
-  if (isSimpleMemberPointer(MPT))
-    return getSimpleNullMemberPointer(MPT);
-  // FIXME: Implement function member pointers.
-  return GetBogusMemberPointer(QualType(MPT, 0));
+  llvm::SmallVector<llvm::Constant *, 4> fields;
+  GetNullMemberPointerFields(MPT, fields);
+  if (fields.size() == 1)
+    return fields[0];
+  llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
+  assert(Res->getType() == ConvertMemberPointerType(MPT));
+  return Res;
 }
 
 llvm::Constant *
 MicrosoftCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
                                        CharUnits offset) {
-  // Member data pointers are plain offsets when no virtual bases are involved.
-  if (isSimpleMemberPointer(MPT))
-    return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.getQuantity());
-  // FIXME: Implement member pointers other inheritance models.
-  return GetBogusMemberPointer(QualType(MPT, 0));
+  const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
+  MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
+  llvm::SmallVector<llvm::Constant *, 4> fields;
+  fields.push_back(llvm::ConstantInt::get(CGM.IntTy, offset.getQuantity()));
+  if (hasVBPtrOffsetField(Inheritance)) {
+    int64_t VBPtrOffset =
+      getContext().getASTRecordLayout(RD).getVBPtrOffset().getQuantity();
+    fields.push_back(llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset));
+  }
+  assert(!hasNonVirtualBaseAdjustmentField(MPT, Inheritance));
+  // The virtual base field starts out zero.  It is adjusted by conversions to
+  // member pointer types of a more derived class.  See http://llvm.org/PR15713
+  if (hasVirtualBaseAdjustmentField(Inheritance))
+    fields.push_back(getZeroInt());
+  if (fields.size() == 1)
+    return fields[0];
+  return llvm::ConstantStruct::getAnon(fields);
 }
 
 llvm::Value *
@@ -425,16 +522,90 @@
                                             llvm::Value *MemPtr,
                                             const MemberPointerType *MPT) {
   CGBuilderTy &Builder = CGF.Builder;
+  llvm::SmallVector<llvm::Constant *, 4> fields;
+  // We only need one field for member functions.
+  if (MPT->isMemberFunctionPointer())
+    fields.push_back(llvm::Constant::getNullValue(CGM.VoidPtrTy));
+  else
+    GetNullMemberPointerFields(MPT, fields);
+  assert(!fields.empty());
+  llvm::Value *FirstField = MemPtr;
+  if (MemPtr->getType()->isStructTy())
+    FirstField = Builder.CreateExtractValue(MemPtr, 0);
+  llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0], "memptr.cmp0");
 
-  // For member data pointers, this is just a check against -1 or 0.
-  if (isSimpleMemberPointer(MPT)) {
-    llvm::Constant *Val = getSimpleNullMemberPointer(MPT);
-    return Builder.CreateICmpNE(MemPtr, Val, "memptr.tobool");
+  // For function member pointers, we only need to test the function pointer
+  // field.  The other fields if any can be garbage.
+  if (MPT->isMemberFunctionPointer())
+    return Res;
+
+  // Otherwise, emit a series of compares and combine the results.
+  for (int I = 1, E = fields.size(); I < E; ++I) {
+    llvm::Value *Field = Builder.CreateExtractValue(MemPtr, I);
+    llvm::Value *Next = Builder.CreateICmpNE(Field, fields[I], "memptr.cmp");
+    Res = Builder.CreateAnd(Res, Next, "memptr.tobool");
+  }
+  return Res;
+}
+
+// Returns an adjusted base cast to i8*, since we do more address arithmetic on
+// it.
+llvm::Value *
+MicrosoftCXXABI::AdjustVirtualBase(CodeGenFunction &CGF,
+                                   const CXXRecordDecl *RD, llvm::Value *Base,
+                                   llvm::Value *VirtualBaseAdjustmentOffset,
+                                   llvm::Value *VBPtrOffset) {
+  CGBuilderTy &Builder = CGF.Builder;
+  Base = Builder.CreateBitCast(Base, CGM.Int8PtrTy);
+  llvm::BasicBlock *OriginalBB = 0;
+  llvm::BasicBlock *SkipAdjustBB = 0;
+  llvm::BasicBlock *VBaseAdjustBB = 0;
+
+  // In the unspecified inheritance model, there might not be a vbtable at all,
+  // in which case we need to skip the virtual base lookup.  If there is a
+  // vbtable, the first entry is a no-op entry that gives back the original
+  // base, so look for a virtual base adjustment offset of zero.
+  if (VBPtrOffset) {
+    OriginalBB = Builder.GetInsertBlock();
+    VBaseAdjustBB = CGF.createBasicBlock("memptr.vadjust");
+    SkipAdjustBB = CGF.createBasicBlock("memptr.skip_vadjust");
+    llvm::Value *IsVirtual =
+      Builder.CreateICmpNE(VirtualBaseAdjustmentOffset, getZeroInt(),
+                           "memptr.is_vbase");
+    Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
+    CGF.EmitBlock(VBaseAdjustBB);
   }
 
-  // FIXME: Implement member pointers other inheritance models.
-  ErrorUnsupportedABI(CGF, "function member pointer tests");
-  return GetBogusMemberPointer(QualType(MPT, 0));
+  // If we weren't given a dynamic vbptr offset, RD should be complete and we'll
+  // know the vbptr offset.
+  if (!VBPtrOffset) {
+    CharUnits offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
+    VBPtrOffset = llvm::ConstantInt::get(CGM.IntTy, offs.getQuantity());
+  }
+  // Load the vbtable pointer from the vbtable offset in the instance.
+  llvm::Value *VBPtr =
+    Builder.CreateInBoundsGEP(Base, VBPtrOffset, "memptr.vbptr");
+  llvm::Value *VBTable =
+    Builder.CreateBitCast(VBPtr, CGM.Int8PtrTy->getPointerTo(0));
+  VBTable = Builder.CreateLoad(VBTable, "memptr.vbtable");
+  // Load an i32 offset from the vb-table.
+  llvm::Value *VBaseOffs =
+    Builder.CreateInBoundsGEP(VBTable, VirtualBaseAdjustmentOffset);
+  VBaseOffs = Builder.CreateBitCast(VBaseOffs, CGM.Int32Ty->getPointerTo(0));
+  VBaseOffs = Builder.CreateLoad(VBaseOffs, "memptr.vbase_offs");
+  // Add it to VBPtr.  GEP will sign extend the i32 value for us.
+  llvm::Value *AdjustedBase = Builder.CreateInBoundsGEP(VBPtr, VBaseOffs);
+
+  // Merge control flow with the case where we didn't have to adjust.
+  if (VBaseAdjustBB) {
+    Builder.CreateBr(SkipAdjustBB);
+    CGF.EmitBlock(SkipAdjustBB);
+    llvm::PHINode *Phi = Builder.CreatePHI(CGM.Int8PtrTy, 2, "memptr.base");
+    Phi->addIncoming(Base, OriginalBB);
+    Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
+    return Phi;
+  }
+  return AdjustedBase;
 }
 
 llvm::Value *
@@ -442,32 +613,90 @@
                                               llvm::Value *Base,
                                               llvm::Value *MemPtr,
                                               const MemberPointerType *MPT) {
+  assert(MPT->isMemberDataPointer());
   unsigned AS = Base->getType()->getPointerAddressSpace();
   llvm::Type *PType =
       CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS);
   CGBuilderTy &Builder = CGF.Builder;
+  const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
+  MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
 
-  if (MPT->isMemberFunctionPointer()) {
-    ErrorUnsupportedABI(CGF, "function member pointer address");
-    return llvm::Constant::getNullValue(PType);
+  // Extract the fields we need, regardless of model.  We'll apply them if we
+  // have them.
+  llvm::Value *FieldOffset = MemPtr;
+  llvm::Value *VirtualBaseAdjustmentOffset = 0;
+  llvm::Value *VBPtrOffset = 0;
+  if (MemPtr->getType()->isStructTy()) {
+    // We need to extract values.
+    unsigned I = 0;
+    FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
+    if (hasVBPtrOffsetField(Inheritance))
+      VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
+    if (hasVirtualBaseAdjustmentField(Inheritance))
+      VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
   }
 
-  llvm::Value *Addr;
-  if (isSimpleMemberPointer(MPT)) {
-    // Add the offset with GEP and i8*.
-    assert(MemPtr->getType() == CGM.PtrDiffTy);
-    Base = Builder.CreateBitCast(Base, Builder.getInt8Ty()->getPointerTo(AS));
-    Addr = Builder.CreateInBoundsGEP(Base, MemPtr, "memptr.offset");
-  } else {
-    ErrorUnsupportedABI(CGF, "non-scalar member pointers");
-    return llvm::Constant::getNullValue(PType);
+  if (VirtualBaseAdjustmentOffset) {
+    Base = AdjustVirtualBase(CGF, RD, Base, VirtualBaseAdjustmentOffset,
+                             VBPtrOffset);
   }
+  llvm::Value *Addr =
+    Builder.CreateInBoundsGEP(Base, FieldOffset, "memptr.offset");
 
   // Cast the address to the appropriate pointer type, adopting the address
   // space of the base pointer.
   return Builder.CreateBitCast(Addr, PType);
 }
 
+llvm::Value *
+MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
+                                                 llvm::Value *&This,
+                                                 llvm::Value *MemPtr,
+                                                 const MemberPointerType *MPT) {
+  assert(MPT->isMemberFunctionPointer());
+  const FunctionProtoType *FPT =
+    MPT->getPointeeType()->castAs<FunctionProtoType>();
+  const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
+  llvm::FunctionType *FTy =
+    CGM.getTypes().GetFunctionType(
+      CGM.getTypes().arrangeCXXMethodType(RD, FPT));
+  CGBuilderTy &Builder = CGF.Builder;
+
+  MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
+
+  // Extract the fields we need, regardless of model.  We'll apply them if we
+  // have them.
+  llvm::Value *FunctionPointer = MemPtr;
+  llvm::Value *NonVirtualBaseAdjustment = NULL;
+  llvm::Value *VirtualBaseAdjustmentOffset = NULL;
+  llvm::Value *VBPtrOffset = NULL;
+  if (MemPtr->getType()->isStructTy()) {
+    // We need to extract values.
+    unsigned I = 0;
+    FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
+    if (hasVBPtrOffsetField(Inheritance))
+      VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
+    if (hasNonVirtualBaseAdjustmentField(MPT, Inheritance))
+      NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
+    if (hasVirtualBaseAdjustmentField(Inheritance))
+      VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
+  }
+
+  if (VirtualBaseAdjustmentOffset) {
+    This = AdjustVirtualBase(CGF, RD, This, VirtualBaseAdjustmentOffset,
+                             VBPtrOffset);
+  }
+
+  if (NonVirtualBaseAdjustment) {
+    // Apply the adjustment and cast back to the original struct type.
+    llvm::Value *Ptr = Builder.CreateBitCast(This, Builder.getInt8PtrTy());
+    Ptr = Builder.CreateInBoundsGEP(Ptr, NonVirtualBaseAdjustment);
+    This = Builder.CreateBitCast(Ptr, This->getType(), "this.adjusted");
+  }
+
+  return Builder.CreateBitCast(FunctionPointer, FTy->getPointerTo());
+}
+
 CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
   return new MicrosoftCXXABI(CGM);
 }
diff --git a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
index 997e007..1206463 100755
--- a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
+++ b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
@@ -1,10 +1,59 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+
+struct B1 {
+  int b;
+};
+struct B2 { };
+struct Single : B1 { };
+struct Multiple : B1, B2 { };
+struct Virtual : virtual B1 {
+  int v;
+};
 
 struct POD {
   int a;
   int b;
 };
 
+struct Polymorphic {
+  virtual void myVirtual();
+  int a;
+  int b;
+};
+
+// This class uses the virtual inheritance model, yet its vbptr offset is not 0.
+// We still use zero for the null field offset, despite it being a valid field
+// offset.
+struct NonZeroVBPtr : POD, Virtual {
+  int n;
+};
+
+struct Unspecified;
+
+// Check that we can lower the LLVM types and get the initializers right.
+int Single     ::*s_d_memptr;
+int Polymorphic::*p_d_memptr;
+int Multiple   ::*m_d_memptr;
+int Virtual    ::*v_d_memptr;
+int NonZeroVBPtr::*n_d_memptr;
+int Unspecified::*u_d_memptr;
+// CHECK: @"\01?s_d_memptr@@3PQSingle@@HA" = global i32 -1, align 4
+// CHECK: @"\01?p_d_memptr@@3PQPolymorphic@@HA" = global i32 0, align 4
+// CHECK: @"\01?m_d_memptr@@3PQMultiple@@HA" = global i32 -1, align 4
+// CHECK: @"\01?v_d_memptr@@3PQVirtual@@HA" = global { i32, i32 }
+// CHECK:   { i32 0, i32 -1 }, align 4
+// CHECK: @"\01?n_d_memptr@@3PQNonZeroVBPtr@@HA" = global { i32, i32 }
+// CHECK:   { i32 0, i32 -1 }, align 4
+// CHECK: @"\01?u_d_memptr@@3PQUnspecified@@HA" = global { i32, i32, i32 }
+// CHECK:   { i32 0, i32 0, i32 -1 }, align 4
+
+void (Single  ::*s_f_memptr)();
+void (Multiple::*m_f_memptr)();
+void (Virtual ::*v_f_memptr)();
+// CHECK: @"\01?s_f_memptr@@3P8Single@@AEXXZA" = global i8* null, align 4
+// CHECK: @"\01?m_f_memptr@@3P8Multiple@@AEXXZA" = global { i8*, i32 } zeroinitializer, align 4
+// CHECK: @"\01?v_f_memptr@@3P8Virtual@@AEXXZA" = global { i8*, i32, i32 } zeroinitializer, align 4
+
 void podMemPtrs() {
   int POD::*memptr;
   memptr = &POD::a;
@@ -24,12 +73,6 @@
 // CHECK:      }
 }
 
-struct Polymorphic {
-  virtual void myVirtual();
-  int a;
-  int b;
-};
-
 void polymorphicMemPtrs() {
   int Polymorphic::*memptr;
   memptr = &Polymorphic::a;
@@ -49,3 +92,133 @@
 // CHECK:        ret void
 // CHECK:      }
 }
+
+bool nullTestDataUnspecified(int Unspecified::*mp) {
+  return mp;
+// CHECK: define zeroext i1 @"\01?nullTestDataUnspecified@@YA_NPQUnspecified@@H@Z"{{.*}} {
+// CHECK:   %{{.*}} = load { i32, i32, i32 }* %{{.*}}, align 4
+// CHECK:   store { i32, i32, i32 } {{.*}} align 4
+// CHECK:   %[[mp:.*]] = load { i32, i32, i32 }* %{{.*}}, align 4
+// CHECK:   %[[mp0:.*]] = extractvalue { i32, i32, i32 } %[[mp]], 0
+// CHECK:   %[[cmp0:.*]] = icmp ne i32 %[[mp0]], 0
+// CHECK:   %[[mp1:.*]] = extractvalue { i32, i32, i32 } %[[mp]], 1
+// CHECK:   %[[cmp1:.*]] = icmp ne i32 %[[mp1]], 0
+// CHECK:   %[[and0:.*]] = and i1 %[[cmp0]], %[[cmp1]]
+// CHECK:   %[[mp2:.*]] = extractvalue { i32, i32, i32 } %[[mp]], 2
+// CHECK:   %[[cmp2:.*]] = icmp ne i32 %[[mp2]], -1
+// CHECK:   %[[and1:.*]] = and i1 %[[and0]], %[[cmp2]]
+// CHECK:   ret i1 %[[and1]]
+// CHECK: }
+}
+
+bool nullTestFunctionUnspecified(void (Unspecified::*mp)()) {
+  return mp;
+// CHECK: define zeroext i1 @"\01?nullTestFunctionUnspecified@@YA_NP8Unspecified@@AEXXZ@Z"{{.*}} {
+// CHECK:   %{{.*}} = load { i8*, i32, i32, i32 }* %{{.*}}, align 4
+// CHECK:   store { i8*, i32, i32, i32 } {{.*}} align 4
+// CHECK:   %[[mp:.*]] = load { i8*, i32, i32, i32 }* %{{.*}}, align 4
+// CHECK:   %[[mp0:.*]] = extractvalue { i8*, i32, i32, i32 } %[[mp]], 0
+// CHECK:   %[[cmp0:.*]] = icmp ne i8* %[[mp0]], null
+// CHECK:   ret i1 %[[cmp0]]
+// CHECK: }
+}
+
+int loadDataMemberPointerVirtual(Virtual *o, int Virtual::*memptr) {
+  return o->*memptr;
+// Test that we can unpack this aggregate member pointer and load the member
+// data pointer.
+// CHECK: define i32 @"\01?loadDataMemberPointerVirtual@@YAHPAUVirtual@@PQ1@H@Z"{{.*}} {
+// CHECK:   %[[o:.*]] = load %{{.*}}** %{{.*}}, align 4
+// CHECK:   %[[memptr:.*]] = load { i32, i32 }* %memptr.addr, align 4
+// CHECK:   %[[memptr0:.*]] = extractvalue { i32, i32 } %[[memptr:.*]], 0
+// CHECK:   %[[memptr1:.*]] = extractvalue { i32, i32 } %[[memptr:.*]], 1
+// CHECK:   %[[v6:.*]] = bitcast %{{.*}}* %[[o]] to i8*
+// CHECK:   %[[vbptr:.*]] = getelementptr inbounds i8* %[[v6]], i32 0
+// CHECK:   %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i8**
+// CHECK:   %[[vbtable:.*]] = load i8** %[[vbptr_a:.*]]
+// CHECK:   %[[v7:.*]] = getelementptr inbounds i8* %[[vbtable]], i32 %[[memptr1]]
+// CHECK:   %[[v8:.*]] = bitcast i8* %[[v7]] to i32*
+// CHECK:   %[[vbase_offs:.*]] = load i32* %[[v8]]
+// CHECK:   %[[v10:.*]] = getelementptr inbounds i8* %[[vbptr]], i32 %[[vbase_offs]]
+// CHECK:   %[[offset:.*]] = getelementptr inbounds i8* %[[v10]], i32 %[[memptr0]]
+// CHECK:   %[[v11:.*]] = bitcast i8* %[[offset]] to i32*
+// CHECK:   %[[v12:.*]] = load i32* %[[v11]]
+// CHECK:   ret i32 %[[v12]]
+// CHECK: }
+}
+
+int loadDataMemberPointerUnspecified(Unspecified *o, int Unspecified::*memptr) {
+  return o->*memptr;
+// Test that we can unpack this aggregate member pointer and load the member
+// data pointer.
+// CHECK: define i32 @"\01?loadDataMemberPointerUnspecified@@YAHPAUUnspecified@@PQ1@H@Z"{{.*}} {
+// CHECK:   %[[o:.*]] = load %{{.*}}** %{{.*}}, align 4
+// CHECK:   %[[memptr:.*]] = load { i32, i32, i32 }* %memptr.addr, align 4
+// CHECK:   %[[memptr0:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 0
+// CHECK:   %[[memptr1:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 1
+// CHECK:   %[[memptr2:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 2
+// CHECK:   %[[base:.*]] = bitcast %{{.*}}* %[[o]] to i8*
+// CHECK:   %[[is_vbase:.*]] = icmp ne i32 %[[memptr2]], 0
+// CHECK:   br i1 %[[is_vbase]], label %[[vadjust:.*]], label %[[skip:.*]]
+//
+// CHECK: [[vadjust]]:
+// CHECK:   %[[vbptr:.*]] = getelementptr inbounds i8* %[[base]], i32 %[[memptr1]]
+// CHECK:   %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i8**
+// CHECK:   %[[vbtable:.*]] = load i8** %[[vbptr_a:.*]]
+// CHECK:   %[[v7:.*]] = getelementptr inbounds i8* %[[vbtable]], i32 %[[memptr2]]
+// CHECK:   %[[v8:.*]] = bitcast i8* %[[v7]] to i32*
+// CHECK:   %[[vbase_offs:.*]] = load i32* %[[v8]]
+// CHECK:   %[[base_adj:.*]] = getelementptr inbounds i8* %[[vbptr]], i32 %[[vbase_offs]]
+//
+// CHECK: [[skip]]:
+// CHECK:   %[[new_base:.*]] = phi i8* [ %[[base]], %entry ], [ %[[base_adj]], %[[vadjust]] ]
+// CHECK:   %[[offset:.*]] = getelementptr inbounds i8* %[[new_base]], i32 %[[memptr0]]
+// CHECK:   %[[v11:.*]] = bitcast i8* %[[offset]] to i32*
+// CHECK:   %[[v12:.*]] = load i32* %[[v11]]
+// CHECK:   ret i32 %[[v12]]
+// CHECK: }
+}
+
+void callMemberPointerSingle(Single *o, void (Single::*memptr)()) {
+  (o->*memptr)();
+// Just look for an indirect thiscall.
+// CHECK: define void @"\01?callMemberPointerSingle@@{{.*}} #0 {
+// CHECK:   call x86_thiscallcc void %{{.*}}(%{{.*}} %{{.*}})
+// CHECK:   ret void
+// CHECK: }
+}
+
+void callMemberPointerMultiple(Multiple *o, void (Multiple::*memptr)()) {
+  (o->*memptr)();
+// CHECK: define void @"\01?callMemberPointerMultiple@@{{.*}} #0 {
+// CHECK:   %[[memptr0:.*]] = extractvalue { i8*, i32 } %{{.*}}, 0
+// CHECK:   %[[memptr1:.*]] = extractvalue { i8*, i32 } %{{.*}}, 1
+// CHECK:   %[[this_adjusted:.*]] = getelementptr inbounds i8* %{{.*}}, i32 %[[memptr1]]
+// CHECK:   %[[this:.*]] = bitcast i8* %[[this_adjusted]] to {{.*}}
+// CHECK:   %[[fptr:.*]] = bitcast i8* %[[memptr0]] to {{.*}}
+// CHECK:   call x86_thiscallcc void %[[fptr]](%{{.*}} %[[this]])
+// CHECK:   ret void
+// CHECK: }
+}
+
+void callMemberPointerVirtualBase(Virtual *o, void (Virtual::*memptr)()) {
+  (o->*memptr)();
+// This shares a lot with virtual data member pointers.
+// CHECK: define void @"\01?callMemberPointerVirtualBase@@{{.*}} #0 {
+// CHECK:   %[[memptr0:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 0
+// CHECK:   %[[memptr1:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 1
+// CHECK:   %[[memptr2:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 2
+// CHECK:   %[[vbptr:.*]] = getelementptr inbounds i8* %{{.*}}, i32 0
+// CHECK:   %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i8**
+// CHECK:   %[[vbtable:.*]] = load i8** %[[vbptr_a:.*]]
+// CHECK:   %[[v7:.*]] = getelementptr inbounds i8* %[[vbtable]], i32 %[[memptr2]]
+// CHECK:   %[[v8:.*]] = bitcast i8* %[[v7]] to i32*
+// CHECK:   %[[vbase_offs:.*]] = load i32* %[[v8]]
+// CHECK:   %[[v10:.*]] = getelementptr inbounds i8* %[[vbptr]], i32 %[[vbase_offs]]
+// CHECK:   %[[this_adjusted:.*]] = getelementptr inbounds i8* %[[v10]], i32 %[[memptr1]]
+// CHECK:   %[[fptr:.*]] = bitcast i8* %[[memptr0]] to void ({{.*}})
+// CHECK:   %[[this:.*]] = bitcast i8* %[[this_adjusted]] to {{.*}}
+// CHECK:   call x86_thiscallcc void %[[fptr]](%{{.*}} %[[this]])
+// CHECK:   ret void
+// CHECK: }
+}
