diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 6b3d472066117ed564c692adb0036e6470647668..93c64805aa9f96065dbe1b681466d202f7d70444 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -1600,8 +1600,6 @@ public:
 
   /// \brief Returns the inheritance model used for this record.
   MSInheritanceAttr::Spelling getMSInheritanceModel() const;
-  /// \brief Locks-in the inheritance model for this class.
-  void setMSInheritanceModel();
   /// \brief Calculate what the inheritance model would be for this class.
   MSInheritanceAttr::Spelling calculateInheritanceModel() const;
 
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index d2c80b113d44b7735406367b204072d6ae508720..b263c1bc1d6171344731e0e5158310847c5b2bb4 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -99,6 +99,11 @@ class VersionArgument<string name, bit opt = 0> : Argument<name, opt>;
 // be dependent.
 class AlignedArgument<string name, bit opt = 0> : Argument<name, opt>;
 
+// A bool argument with a default value
+class DefaultBoolArgument<string name, bit default> : BoolArgument<name, 1> {
+  bit Default = default;
+}
+
 // An integer argument with a default value
 class DefaultIntArgument<string name, int default> : IntArgument<name, 1> {
   int Default = default;
@@ -1397,6 +1402,7 @@ def UPtr : TypeAttr {
 
 def MSInheritance : InheritableAttr {
   let LangOpts = [MicrosoftExt];
+  let Args = [DefaultBoolArgument<"BestCase", 1>];
   let Spellings = [Keyword<"__single_inheritance">,
                    Keyword<"__multiple_inheritance">,
                    Keyword<"__virtual_inheritance">,
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index b269313fce8958d199612ac7138b1d6fdbe946ea..de07ee8d8fc9fec79a7d333ed50a4c34e08ea074 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -177,6 +177,8 @@ def err_invalid_token_after_declarator_suggest_equal : Error<
   "invalid %0 at end of declaration; did you mean '='?">;
 def err_expected_statement : Error<"expected statement">;
 def err_expected_lparen_after : Error<"expected '(' after '%0'">;
+def err_expected_rparen_after : Error<"expected ')' after '%0'">;
+def err_expected_punc : Error<"expected ')' or ',' after '%0'">;
 def err_expected_less_after : Error<"expected '<' after '%0'">;
 def err_expected_lbrace_in_compound_literal : Error<
   "expected '{' in compound literal">;
@@ -809,6 +811,10 @@ def err_pragma_comment_unknown_kind : Error<"unknown kind of pragma comment">;
 def err_pragma_detect_mismatch_malformed : Error<
   "pragma detect_mismatch is malformed; it requires two comma-separated "
   "string literals">;
+// - #pragma pointers_to_members
+def err_pragma_pointers_to_members_unknown_kind : Error<
+  "unexpected %0, expected to see one of %select{|'best_case', 'full_generality', }1"
+  "'single_inheritance', 'multiple_inheritance', or 'virtual_inheritance'">;
 
 // OpenCL Section 6.8.g
 def err_not_opencl_storage_class_specifier : Error<
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index a7e27d5e29bad4aa2861db37e7c33e7efd83a257..05c2fa2b27c76996d08fee75ee765903c666cd0c 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -673,6 +673,11 @@ ANNOTATION(pragma_redefine_extname)
 // handles them.
 ANNOTATION(pragma_fp_contract)
 
+// Annotation for #pragma pointers_to_members...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_ms_pointers_to_members)
+
 // Annotation for #pragma OPENCL EXTENSION...
 // The lexer produces these so that they only take effect when the parser
 // handles them.
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index baa890a5408f45f9e3b9498bc8f9fb669b55d7cf..8b9053fa09808a2ef85493cef9c2685c8156f66f 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -155,6 +155,7 @@ class Parser : public CodeCompletionHandler {
   OwningPtr<PragmaHandler> OpenMPHandler;
   OwningPtr<PragmaHandler> MSCommentHandler;
   OwningPtr<PragmaHandler> MSDetectMismatchHandler;
+  OwningPtr<PragmaHandler> MSPointersToMembers;
 
   /// Whether the '>' token acts as an operator or not. This will be
   /// true except when we are parsing an expression within a C++
@@ -457,6 +458,8 @@ private:
   /// #pragma comment...
   void HandlePragmaMSComment();
 
+  void HandlePragmaMSPointersToMembers();
+
   /// \brief Handle the annotation token produced for
   /// #pragma align...
   void HandlePragmaAlign();
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index aa6d2246aedde256fd6da2e9398cc0c658eaed5b..85d29da35a36e846e06d4f9d4c872a83781e5e8b 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -262,6 +262,19 @@ public:
 
   bool MSStructPragmaOn; // True when \#pragma ms_struct on
 
+  enum PragmaMSPointersToMembersKind {
+    PPTMK_BestCase,
+    PPTMK_FullGeneralitySingleInheritance,
+    PPTMK_FullGeneralityMultipleInheritance,
+    PPTMK_FullGeneralityVirtualInheritance,
+  };
+
+  /// \brief Controls member pointer representation format under the MS ABI.
+  PragmaMSPointersToMembersKind MSPointerToMemberRepresentationMethod;
+
+  /// \brief Source location for newly created implicit MSInheritanceAttrs
+  SourceLocation ImplicitMSInheritanceAttrLoc;
+
   /// VisContext - Manages the stack for \#pragma GCC visibility.
   void *VisContext; // Really a "PragmaVisStack*"
 
@@ -1864,7 +1877,7 @@ public:
   DLLExportAttr *mergeDLLExportAttr(Decl *D, SourceRange Range,
                                     unsigned AttrSpellingListIndex);
   MSInheritanceAttr *
-  mergeMSInheritanceAttr(Decl *D, SourceRange Range,
+  mergeMSInheritanceAttr(Decl *D, SourceRange Range, bool BestCase,
                          unsigned AttrSpellingListIndex,
                          MSInheritanceAttr::Spelling SemanticSpelling);
   FormatAttr *mergeFormatAttr(Decl *D, SourceRange Range,
@@ -2577,7 +2590,7 @@ public:
                                       unsigned ArgNum, StringRef &Str,
                                       SourceLocation *ArgLocation = 0);
   bool checkMSInheritanceAttrOnDefinition(
-      CXXRecordDecl *RD, SourceRange Range,
+      CXXRecordDecl *RD, SourceRange Range, bool BestCase,
       MSInheritanceAttr::Spelling SemanticSpelling);
 
   void CheckAlignasUnderalignment(Decl *D);
@@ -6970,6 +6983,12 @@ public:
   /// \#pragma comment(kind, "arg").
   void ActOnPragmaMSComment(PragmaMSCommentKind Kind, StringRef Arg);
 
+  /// ActOnPragmaMSPointersToMembers - called on well formed \#pragma
+  /// pointers_to_members(representation method[, general purpose
+  /// representation]).
+  void ActOnPragmaMSPointersToMembers(PragmaMSPointersToMembersKind Kind,
+                                      SourceLocation PragmaLoc);
+
   /// ActOnPragmaDetectMismatch - Call on well-formed \#pragma detect_mismatch
   void ActOnPragmaDetectMismatch(StringRef Name, StringRef Value);
 
diff --git a/lib/AST/MicrosoftCXXABI.cpp b/lib/AST/MicrosoftCXXABI.cpp
index 03d0d505514eabf77fbd28b35bbbd72009ef1517..91ffc63b770972573fd2f9d1eced774764a65fe6 100644
--- a/lib/AST/MicrosoftCXXABI.cpp
+++ b/lib/AST/MicrosoftCXXABI.cpp
@@ -109,14 +109,6 @@ CXXRecordDecl::getMSInheritanceModel() const {
   return IA->getSemanticSpelling();
 }
 
-void CXXRecordDecl::setMSInheritanceModel() {
-  if (hasAttr<MSInheritanceAttr>())
-    return;
-
-  addAttr(MSInheritanceAttr::CreateImplicit(
-      getASTContext(), calculateInheritanceModel(), getSourceRange()));
-}
-
 // Returns the number of pointer and integer slots used to represent a member
 // pointer in the MS C++ ABI.
 //
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 083d682428ec53ab20bc4823766eb7bdf5c5d815..5d68453e3fb9e9ffde03ffeb48999aff27c35eb4 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -2620,6 +2620,11 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
         continue;
       }
 
+      if (Tok.is(tok::annot_pragma_ms_pointers_to_members)) {
+        HandlePragmaMSPointersToMembers();
+        continue;
+      }
+
       // If we see a namespace here, a close brace was missing somewhere.
       if (Tok.is(tok::kw_namespace)) {
         DiagnoseUnexpectedNamespace(cast<NamedDecl>(TagDecl));
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
index 41562a44e962791d1137926a464165b0c2b47187..2655996a1fff2d9af1e05f1442755b957823f0f6 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -180,6 +180,14 @@ void Parser::HandlePragmaOpenCLExtension() {
   }
 }
 
+void Parser::HandlePragmaMSPointersToMembers() {
+  assert(Tok.is(tok::annot_pragma_ms_pointers_to_members));
+  Sema::PragmaMSPointersToMembersKind RepresentationMethod =
+      static_cast<Sema::PragmaMSPointersToMembersKind>(
+          reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
+  SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
+  Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
+}
 
 
 // #pragma GCC visibility comes in two variants:
@@ -799,6 +807,99 @@ PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
                       /*DisableMacroExpansion=*/true, /*OwnsTokens=*/true);
 }
 
+/// \brief Handle '#pragma pointers_to_members'
+// The grammar for this pragma is as follows:
+//
+// <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance'
+//
+// #pragma pointers_to_members '(' 'best_case' ')'
+// #pragma pointers_to_members '(' 'full_generality' [',' inheritance-model] ')'
+// #pragma pointers_to_members '(' inheritance-model ')'
+void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP,
+                                             PragmaIntroducerKind Introducer,
+                                             Token &Tok) {
+  SourceLocation PointersToMembersLoc = Tok.getLocation();
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::l_paren)) {
+    PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
+      << "pointers_to_members";
+    return;
+  }
+  PP.Lex(Tok);
+  const IdentifierInfo *Arg = Tok.getIdentifierInfo();
+  if (!Arg) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
+      << "pointers_to_members";
+    return;
+  }
+  PP.Lex(Tok);
+
+  Sema::PragmaMSPointersToMembersKind RepresentationMethod;
+  if (Arg->isStr("best_case")) {
+    RepresentationMethod = Sema::PPTMK_BestCase;
+  } else {
+    if (Arg->isStr("full_generality")) {
+      if (Tok.is(tok::comma)) {
+        PP.Lex(Tok);
+
+        Arg = Tok.getIdentifierInfo();
+        if (!Arg) {
+          PP.Diag(Tok.getLocation(),
+                  diag::err_pragma_pointers_to_members_unknown_kind)
+              << Tok.getKind() << /*OnlyInheritanceModels*/ 0;
+          return;
+        }
+        PP.Lex(Tok);
+      } else if (Tok.is(tok::r_paren)) {
+        // #pragma pointers_to_members(full_generality) implicitly specifies
+        // virtual_inheritance.
+        Arg = 0;
+        RepresentationMethod = Sema::PPTMK_FullGeneralityVirtualInheritance;
+      } else {
+        PP.Diag(Tok.getLocation(), diag::err_expected_punc)
+            << "full_generality";
+        return;
+      }
+    }
+
+    if (Arg) {
+      if (Arg->isStr("single_inheritance")) {
+        RepresentationMethod = Sema::PPTMK_FullGeneralitySingleInheritance;
+      } else if (Arg->isStr("multiple_inheritance")) {
+        RepresentationMethod = Sema::PPTMK_FullGeneralityMultipleInheritance;
+      } else if (Arg->isStr("virtual_inheritance")) {
+        RepresentationMethod = Sema::PPTMK_FullGeneralityVirtualInheritance;
+      } else {
+        PP.Diag(Tok.getLocation(),
+                diag::err_pragma_pointers_to_members_unknown_kind)
+            << Arg << /*HasPointerDeclaration*/ 1;
+        return;
+      }
+    }
+  }
+
+  if (Tok.isNot(tok::r_paren)) {
+    PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after)
+        << (Arg ? Arg->getName() : "full_generality");
+    return;
+  }
+
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::eod)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
+      << "pointers_to_members";
+    return;
+  }
+
+  Token AnnotTok;
+  AnnotTok.startToken();
+  AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members);
+  AnnotTok.setLocation(PointersToMembersLoc);
+  AnnotTok.setAnnotationValue(
+      reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
+  PP.EnterToken(AnnotTok);
+}
+
 /// \brief Handle the Microsoft \#pragma detect_mismatch extension.
 ///
 /// The syntax is:
diff --git a/lib/Parse/ParsePragma.h b/lib/Parse/ParsePragma.h
index b41450f4eadfc98c931dabca85db15006c311c82..734bc8d6349263f8a602c1cf3e007ae1bf18450b 100644
--- a/lib/Parse/ParsePragma.h
+++ b/lib/Parse/ParsePragma.h
@@ -134,6 +134,13 @@ private:
   Sema &Actions;
 };
 
+class PragmaMSPointersToMembers : public PragmaHandler {
+public:
+  explicit PragmaMSPointersToMembers() : PragmaHandler("pointers_to_members") {}
+  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                            Token &FirstToken);
+};
+
 }  // end namespace clang
 
 #endif
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index f2e4ad9f7b12f7620ccecc29dee0db889191a1e7..0be14f07ae858047bc8d7baa37376d7025d4fbcb 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -345,6 +345,11 @@ Retry:
     ProhibitAttributes(Attrs);
     return ParseOpenMPDeclarativeOrExecutableDirective();
 
+  case tok::annot_pragma_ms_pointers_to_members:
+    ProhibitAttributes(Attrs);
+    HandlePragmaMSPointersToMembers();
+    return StmtEmpty();
+
   }
 
   // If we reached this code, the statement must end in a semicolon.
@@ -820,6 +825,9 @@ void Parser::ParseCompoundStatementLeadingPragmas() {
     case tok::annot_pragma_fp_contract:
       HandlePragmaFPContract();
       break;
+    case tok::annot_pragma_ms_pointers_to_members:
+      HandlePragmaMSPointersToMembers();
+      break;
     default:
       checkForPragmas = false;
       break;
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index efa6a1bb592da2ffde684a2db91e6a812901c2f1..a52248f2f9159a2497811b025672560e831f1bc0 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -108,6 +108,8 @@ Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies)
     PP.AddPragmaHandler(MSCommentHandler.get());
     MSDetectMismatchHandler.reset(new PragmaDetectMismatchHandler(actions));
     PP.AddPragmaHandler(MSDetectMismatchHandler.get());
+    MSPointersToMembers.reset(new PragmaMSPointersToMembers());
+    PP.AddPragmaHandler(MSPointersToMembers.get());
   }
 
   CommentSemaHandler.reset(new ActionCommentHandler(actions));
@@ -483,6 +485,8 @@ Parser::~Parser() {
     MSCommentHandler.reset();
     PP.RemovePragmaHandler(MSDetectMismatchHandler.get());
     MSDetectMismatchHandler.reset();
+    PP.RemovePragmaHandler(MSPointersToMembers.get());
+    MSPointersToMembers.reset();
   }
 
   PP.RemovePragmaHandler("STDC", FPContractHandler.get());
@@ -702,6 +706,9 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
   case tok::annot_pragma_openmp:
     ParseOpenMPDeclarativeDirective();
     return DeclGroupPtrTy();
+  case tok::annot_pragma_ms_pointers_to_members:
+    HandlePragmaMSPointersToMembers();
+    return DeclGroupPtrTy();
   case tok::semi:
     // Either a C++11 empty-declaration or attribute-declaration.
     SingleDecl = Actions.ActOnEmptyDeclaration(getCurScope(),
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 494fe73ed3f84ec8fb22e16ff34bcf4a20712257..b2cf59b1c8470bf2805071907397407d946c5627 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -75,7 +75,8 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
     Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
     CollectStats(false), CodeCompleter(CodeCompleter),
     CurContext(0), OriginalLexicalContext(0),
-    PackContext(0), MSStructPragmaOn(false), VisContext(0),
+    PackContext(0), MSStructPragmaOn(false),
+    MSPointerToMemberRepresentationMethod(PPTMK_BestCase), VisContext(0),
     IsBuildingRecoveryCallExpr(false),
     ExprNeedsCleanups(false), LateTemplateParser(0), OpaqueParser(0),
     IdResolver(pp), StdInitializerList(0), CXXTypeInfoDecl(0), MSVCGuidDecl(0),
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index 499f958744741d2995a6b85ff332177c4183c6fd..9f0eb91d2e40684d03cefe96ebd5a1307a61d87f 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -287,6 +287,13 @@ void Sema::ActOnPragmaDetectMismatch(StringRef Name, StringRef Value) {
   Consumer.HandleDetectMismatch(Name, Value);
 }
 
+void Sema::ActOnPragmaMSPointersToMembers(
+    PragmaMSPointersToMembersKind RepresentationMethod,
+    SourceLocation PragmaLoc) {
+  MSPointerToMemberRepresentationMethod = RepresentationMethod;
+  ImplicitMSInheritanceAttrLoc = PragmaLoc;
+}
+
 void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope,
                              SourceLocation PragmaLoc) {
 
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index b42b502b097da6d3495dab78910f4a04b0235593..17e0f38e07de3af55f01dd357a7191b62bc9708c 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1963,7 +1963,8 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D, InheritableAttr *Attr,
     NewAttr = S.mergeSectionAttr(D, SA->getRange(), SA->getName(),
                                  AttrSpellingListIndex);
   else if (MSInheritanceAttr *IA = dyn_cast<MSInheritanceAttr>(Attr))
-    NewAttr = S.mergeMSInheritanceAttr(D, IA->getRange(), AttrSpellingListIndex,
+    NewAttr = S.mergeMSInheritanceAttr(D, IA->getRange(), IA->getBestCase(),
+                                       AttrSpellingListIndex,
                                        IA->getSemanticSpelling());
   else if (isa<AlignedAttr>(Attr))
     // AlignedAttrs are handled separately, because we need to handle all
@@ -12152,7 +12153,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
 
       if (const MSInheritanceAttr *IA = Record->getAttr<MSInheritanceAttr>())
         checkMSInheritanceAttrOnDefinition(cast<CXXRecordDecl>(Record),
-                                           IA->getRange(),
+                                           IA->getRange(), IA->getBestCase(),
                                            IA->getSemanticSpelling());
     }
 
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 66591e4bf36035177f9b9cc9a923bde65bbd7538..65fb7266dbf01e68b320a87155ce3c97124f2f6b 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -2873,7 +2873,7 @@ void Sema::CheckAlignasUnderalignment(Decl *D) {
 }
 
 bool Sema::checkMSInheritanceAttrOnDefinition(
-    CXXRecordDecl *RD, SourceRange Range,
+    CXXRecordDecl *RD, SourceRange Range, bool BestCase,
     MSInheritanceAttr::Spelling SemanticSpelling) {
   assert(RD->hasDefinition() && "RD has no definition!");
 
@@ -2886,8 +2886,13 @@ bool Sema::checkMSInheritanceAttrOnDefinition(
   if (SemanticSpelling == MSInheritanceAttr::Keyword_unspecified_inheritance)
     return false;
 
-  if (RD->calculateInheritanceModel() == SemanticSpelling)
-    return false;
+  if (BestCase) {
+    if (RD->calculateInheritanceModel() == SemanticSpelling)
+      return false;
+  } else {
+    if (RD->calculateInheritanceModel() <= SemanticSpelling)
+      return false;
+  }
 
   Diag(Range.getBegin(), diag::err_mismatched_ms_inheritance)
       << 0 /*definition*/;
@@ -3705,7 +3710,8 @@ static void handleMSInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr)
     return;
   }
   MSInheritanceAttr *IA = S.mergeMSInheritanceAttr(
-      D, Attr.getRange(), Attr.getAttributeSpellingListIndex(),
+      D, Attr.getRange(), /*BestCase=*/true,
+      Attr.getAttributeSpellingListIndex(),
       (MSInheritanceAttr::Spelling)Attr.getSemanticSpelling());
   if (IA)
     D->addAttr(IA);
@@ -3886,7 +3892,7 @@ static void handleDLLExportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
 }
 
 MSInheritanceAttr *
-Sema::mergeMSInheritanceAttr(Decl *D, SourceRange Range,
+Sema::mergeMSInheritanceAttr(Decl *D, SourceRange Range, bool BestCase,
                              unsigned AttrSpellingListIndex,
                              MSInheritanceAttr::Spelling SemanticSpelling) {
   if (MSInheritanceAttr *IA = D->getAttr<MSInheritanceAttr>()) {
@@ -3900,7 +3906,8 @@ Sema::mergeMSInheritanceAttr(Decl *D, SourceRange Range,
 
   CXXRecordDecl *RD = cast<CXXRecordDecl>(D);
   if (RD->hasDefinition()) {
-    if (checkMSInheritanceAttrOnDefinition(RD, Range, SemanticSpelling)) {
+    if (checkMSInheritanceAttrOnDefinition(RD, Range, BestCase,
+                                           SemanticSpelling)) {
       return 0;
     }
   } else {
@@ -3917,7 +3924,7 @@ Sema::mergeMSInheritanceAttr(Decl *D, SourceRange Range,
   }
 
   return ::new (Context)
-      MSInheritanceAttr(Range, Context, AttrSpellingListIndex);
+      MSInheritanceAttr(Range, Context, BestCase, AttrSpellingListIndex);
 }
 
 /// Handles semantic checking for features that are common to all attributes,
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index f9f6cee994ecfa3fb16636f7cacb5526ff33900d..606a4c090783d1fdb3832703dc9835599e482acc 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -5082,7 +5082,35 @@ bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
         if (!MPTy->getClass()->isDependentType()) {
           RequireCompleteType(Loc, QualType(MPTy->getClass(), 0), 0);
 
-          MPTy->getMostRecentCXXRecordDecl()->setMSInheritanceModel();
+          CXXRecordDecl *RD = MPTy->getMostRecentCXXRecordDecl();
+          if (!RD->hasAttr<MSInheritanceAttr>()) {
+            MSInheritanceAttr::Spelling InheritanceModel;
+
+            switch (MSPointerToMemberRepresentationMethod) {
+            case PPTMK_BestCase:
+              InheritanceModel = RD->calculateInheritanceModel();
+              break;
+            case PPTMK_FullGeneralitySingleInheritance:
+              InheritanceModel = MSInheritanceAttr::Keyword_single_inheritance;
+              break;
+            case PPTMK_FullGeneralityMultipleInheritance:
+              InheritanceModel =
+                  MSInheritanceAttr::Keyword_multiple_inheritance;
+              break;
+            case PPTMK_FullGeneralityVirtualInheritance:
+              InheritanceModel =
+                  MSInheritanceAttr::Keyword_unspecified_inheritance;
+              break;
+            }
+
+            RD->addAttr(MSInheritanceAttr::CreateImplicit(
+                getASTContext(), InheritanceModel,
+                /*BestCase=*/MSPointerToMemberRepresentationMethod ==
+                    PPTMK_BestCase,
+                ImplicitMSInheritanceAttrLoc.isValid()
+                    ? ImplicitMSInheritanceAttrLoc
+                    : RD->getSourceRange()));
+          }
         }
       }
     }
diff --git a/test/SemaCXX/member-pointer-ms.cpp b/test/SemaCXX/member-pointer-ms.cpp
index 8e8094004f6fcfc7b630d1adc55cc3404976c7da..422b7cfbd18d3393a4c5770c620a49a4f4d81f7e 100644
--- a/test/SemaCXX/member-pointer-ms.cpp
+++ b/test/SemaCXX/member-pointer-ms.cpp
@@ -202,3 +202,26 @@ struct __multiple_inheritance C {}; // expected-error{{inheritance model does no
 struct __virtual_inheritance D;
 struct D : virtual B {};
 }
+
+#pragma pointers_to_members(full_generality, multiple_inheritance)
+struct TrulySingleInheritance;
+static_assert(sizeof(int TrulySingleInheritance::*) == kMultipleDataSize, "");
+#pragma pointers_to_members(best_case)
+// This definition shouldn't conflict with the increased generality that the
+// multiple_inheritance model gave to TrulySingleInheritance.
+struct TrulySingleInheritance {};
+
+// Even if a definition proceeds the first mention of a pointer to member, we
+// still give the record the fully general representation.
+#pragma pointers_to_members(full_generality, virtual_inheritance)
+struct SingleInheritanceAsVirtualAfterPragma {};
+static_assert(sizeof(int SingleInheritanceAsVirtualAfterPragma::*) == 12, "");
+
+#pragma pointers_to_members(best_case)
+
+// The above holds even if the pragma comes after the definition.
+struct SingleInheritanceAsVirtualBeforePragma {};
+#pragma pointers_to_members(virtual_inheritance)
+static_assert(sizeof(int SingleInheritanceAsVirtualBeforePragma::*) == 12, "");
+
+#pragma pointers_to_members(single) // expected-error{{unexpected 'single'}}
diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp
index 0d1df4f8ad4a2db7744ae82ebdbe5fb0e6c3317e..26c5faf5932cc63f7baca6783aef08fa39f18427 100644
--- a/utils/TableGen/ClangAttrEmitter.cpp
+++ b/utils/TableGen/ClangAttrEmitter.cpp
@@ -982,6 +982,9 @@ static Argument *createArgument(Record &Arg, StringRef Attr,
     Ptr = new SimpleArgument(Arg, Attr, "FunctionDecl *");
   else if (ArgName == "IdentifierArgument")
     Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *");
+  else if (ArgName == "DefaultBoolArgument")
+    Ptr = new DefaultSimpleArgument(Arg, Attr, "bool",
+                                    Arg.getValueAsBit("Default"));
   else if (ArgName == "BoolArgument") Ptr = new SimpleArgument(Arg, Attr, 
                                                                "bool");
   else if (ArgName == "DefaultIntArgument")