Index: include/clang/AST/Attr.h
===================================================================
--- include/clang/AST/Attr.h	(revision 197567)
+++ include/clang/AST/Attr.h	(working copy)
@@ -136,21 +136,6 @@
   }
 };
 
-class MSInheritanceAttr : public InheritableAttr {
-  virtual void anchor();
-protected:
-  MSInheritanceAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
-    : InheritableAttr(AK, R, SpellingListIndex) {}
-
-public:
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    // Relies on relative order of enum emission with respect to param attrs.
-    return (A->getKind() <= attr::LAST_MS_INHERITANCE &&
-            A->getKind() > attr::LAST_INHERITABLE_PARAM);
-  }
-};
-
 #include "clang/AST/Attrs.inc"
 
 }  // end namespace clang
Index: include/clang/Basic/Attr.td
===================================================================
--- include/clang/Basic/Attr.td	(revision 197582)
+++ include/clang/Basic/Attr.td	(working copy)
@@ -1270,28 +1270,23 @@
   let ASTNode = 0;
 }
 
-class MSInheritanceAttr : InheritableAttr {
+def MSInheritance : InheritableAttr {
   let LangOpts = [MicrosoftExt];
+  let Spellings = [Keyword<"__single_inheritance">,
+                   Keyword<"__multiple_inheritance">,
+                   Keyword<"__virtual_inheritance">,
+                   // We use an empty string to denote an unspecified
+                   // inheritance attribute.
+                   Keyword<"">];
+  let Accessors = [Accessor<"IsSingle", [Keyword<"__single_inheritance">]>,
+                   Accessor<"IsMultiple", [Keyword<"__multiple_inheritance">]>,
+                   Accessor<"IsVirtual", [Keyword<"__virtual_inheritance">]>,
+                   Accessor<"IsUnspecified", [Keyword<"">]>];
+  // This index is based off the Spellings list and corresponds to the empty
+  // keyword "spelling."
+  let AdditionalMembers = [{static const int UnspecifiedSpellingIndex = 3;}];
 }
 
-def SingleInheritance : MSInheritanceAttr {
-  let Spellings = [Keyword<"__single_inheritance">];
-}
-
-def MultipleInheritance : MSInheritanceAttr {
-  let Spellings = [Keyword<"__multiple_inheritance">];
-}
-
-def VirtualInheritance : MSInheritanceAttr {
-  let Spellings = [Keyword<"__virtual_inheritance">];
-}
-
-// This attribute doesn't have any spellings, but we can apply it implicitly to
-// incomplete types that lack any of the other attributes.
-def UnspecifiedInheritance : MSInheritanceAttr {
-  let Spellings = [];
-}
-
 def Unaligned : IgnoredAttr {
   let Spellings = [Keyword<"__unaligned">];
 }
Index: include/clang/Basic/AttrKinds.h
===================================================================
--- include/clang/Basic/AttrKinds.h	(revision 197567)
+++ include/clang/Basic/AttrKinds.h	(working copy)
@@ -24,7 +24,6 @@
 #define ATTR(X) X,
 #define LAST_INHERITABLE_ATTR(X) X, LAST_INHERITABLE = X,
 #define LAST_INHERITABLE_PARAM_ATTR(X) X, LAST_INHERITABLE_PARAM = X,
-#define LAST_MS_INHERITANCE_ATTR(X) X, LAST_MS_INHERITANCE = X,
 #include "clang/Basic/AttrList.inc"
   NUM_ATTRS
 };
Index: lib/AST/AttrImpl.cpp
===================================================================
--- lib/AST/AttrImpl.cpp	(revision 197567)
+++ lib/AST/AttrImpl.cpp	(working copy)
@@ -24,6 +24,4 @@
 
 void InheritableParamAttr::anchor() { }
 
-void MSInheritanceAttr::anchor() { }
-
 #include "clang/AST/AttrImpl.inc"
Index: lib/AST/MicrosoftCXXABI.cpp
===================================================================
--- lib/AST/MicrosoftCXXABI.cpp	(revision 197567)
+++ lib/AST/MicrosoftCXXABI.cpp	(working copy)
@@ -92,19 +92,21 @@
   return false;
 }
 
-static MSInheritanceModel MSInheritanceAttrToModel(attr::Kind Kind) {
-  switch (Kind) {
-  default: llvm_unreachable("expected MS inheritance attribute");
-  case attr::SingleInheritance:      return MSIM_Single;
-  case attr::MultipleInheritance:    return MSIM_Multiple;
-  case attr::VirtualInheritance:     return MSIM_Virtual;
-  case attr::UnspecifiedInheritance: return MSIM_Unspecified;
-  }
+static MSInheritanceModel MSInheritanceAttrToModel(MSInheritanceAttr *Attr) {
+  if (Attr->IsSingle())
+    return MSIM_Single;
+  else if (Attr->IsMultiple())
+    return MSIM_Multiple;
+  else if (Attr->IsVirtual())
+    return MSIM_Virtual;
+  
+  assert(Attr->IsUnspecified() && "Expected unspecified inheritance attr");
+  return MSIM_Unspecified;
 }
 
 MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const {
-  if (Attr *IA = this->getAttr<MSInheritanceAttr>())
-    return MSInheritanceAttrToModel(IA->getKind());
+  if (MSInheritanceAttr *IA = this->getAttr<MSInheritanceAttr>())
+    return MSInheritanceAttrToModel(IA);
   // If there was no explicit attribute, the record must be defined already, and
   // we can figure out the inheritance model from its other properties.
   if (this->getNumVBases() > 0)
Index: lib/Parse/ParseDeclCXX.cpp
===================================================================
--- lib/Parse/ParseDeclCXX.cpp	(revision 197567)
+++ lib/Parse/ParseDeclCXX.cpp	(working copy)
@@ -998,7 +998,7 @@
     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
     SourceLocation AttrNameLoc = ConsumeToken();
     attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
-                 AttributeList::AS_GNU);
+                 AttributeList::AS_Keyword);
   }
 }
 
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp	(revision 197567)
+++ lib/Sema/SemaDeclAttr.cpp	(working copy)
@@ -4091,12 +4091,8 @@
   case AttributeList::AT_Uuid:
     handleUuidAttr(S, D, Attr);
     break;
-  case AttributeList::AT_SingleInheritance:
-    handleSimpleAttribute<SingleInheritanceAttr>(S, D, Attr); break;
-  case AttributeList::AT_MultipleInheritance:
-    handleSimpleAttribute<MultipleInheritanceAttr>(S, D, Attr); break;
-  case AttributeList::AT_VirtualInheritance:
-    handleSimpleAttribute<VirtualInheritanceAttr>(S, D, Attr); break;
+  case AttributeList::AT_MSInheritance:
+    handleSimpleAttribute<MSInheritanceAttr>(S, D, Attr); break;
   case AttributeList::AT_ForceInline:
     handleSimpleAttribute<ForceInlineAttr>(S, D, Attr); break;
   case AttributeList::AT_SelectAny:
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp	(revision 197567)
+++ lib/Sema/SemaType.cpp	(working copy)
@@ -1805,8 +1805,9 @@
         // figure out the inheritance model.
         for (CXXRecordDecl::redecl_iterator I = RD->redecls_begin(),
              E = RD->redecls_end(); I != E; ++I) {
-          I->addAttr(::new (Context) UnspecifiedInheritanceAttr(
-              RD->getSourceRange(), Context));
+          I->addAttr(::new (Context) MSInheritanceAttr(RD->getSourceRange(),
+                                                       Context,
+                                 MSInheritanceAttr::UnspecifiedSpellingIndex));
         }
       }
     }
Index: utils/TableGen/ClangAttrEmitter.cpp
===================================================================
--- utils/TableGen/ClangAttrEmitter.cpp	(revision 197567)
+++ utils/TableGen/ClangAttrEmitter.cpp	(working copy)
@@ -1387,20 +1387,10 @@
         " INHERITABLE_PARAM_ATTR(NAME)\n";
   OS << "#endif\n\n";
 
-  OS << "#ifndef MS_INHERITANCE_ATTR\n";
-  OS << "#define MS_INHERITANCE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n";
-  OS << "#endif\n\n";
-
-  OS << "#ifndef LAST_MS_INHERITANCE_ATTR\n";
-  OS << "#define LAST_MS_INHERITANCE_ATTR(NAME)"
-        " MS_INHERITANCE_ATTR(NAME)\n";
-  OS << "#endif\n\n";
-
   Record *InhClass = Records.getClass("InheritableAttr");
   Record *InhParamClass = Records.getClass("InheritableParamAttr");
-  Record *MSInheritanceClass = Records.getClass("MSInheritanceAttr");
   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
-                       NonInhAttrs, InhAttrs, InhParamAttrs, MSInhAttrs;
+                       NonInhAttrs, InhAttrs, InhParamAttrs;
   for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
        i != e; ++i) {
     if (!(*i)->getValueAsBit("ASTNode"))
@@ -1408,8 +1398,6 @@
     
     if ((*i)->isSubClassOf(InhParamClass))
       InhParamAttrs.push_back(*i);
-    else if ((*i)->isSubClassOf(MSInheritanceClass))
-      MSInhAttrs.push_back(*i);
     else if ((*i)->isSubClassOf(InhClass))
       InhAttrs.push_back(*i);
     else
@@ -1417,16 +1405,13 @@
   }
 
   EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs);
-  EmitAttrList(OS, "MS_INHERITANCE_ATTR", MSInhAttrs);
   EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs);
   EmitAttrList(OS, "ATTR", NonInhAttrs);
 
   OS << "#undef LAST_ATTR\n";
   OS << "#undef INHERITABLE_ATTR\n";
-  OS << "#undef MS_INHERITANCE_ATTR\n";
   OS << "#undef LAST_INHERITABLE_ATTR\n";
   OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n";
-  OS << "#undef LAST_MS_INHERITANCE_ATTR\n";
   OS << "#undef ATTR\n";
 }
 
