diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index e07e84a..5f137b7 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -16,6 +16,8 @@
 
 #include "clang/AST/AttrIterator.h"
 #include "clang/AST/Type.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Stmt.h"
 #include "clang/Basic/AttrKinds.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/SourceLocation.h"
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 7b6e978..318c669 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -32,7 +32,7 @@ class SubsetSubject<AttrSubject base, string description, code check>
 // This is the type of a variable which C++11 allows alignas(...) to appertain
 // to.
 def NormalVar : SubsetSubject<Var, "non-register, non-parameter variable",
-                              [{S->getStorageClass() != VarDecl::Register &&
+                              [{S->getStorageClass() != clang::SC_Register &&
                                 S->getKind() != Decl::ImplicitParam &&
                                 S->getKind() != Decl::ParmVar &&
                                 S->getKind() != Decl::NonTypeTemplateParm}]>;
diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp
index 3982fc3..b23300b 100644
--- a/utils/TableGen/ClangAttrEmitter.cpp
+++ b/utils/TableGen/ClangAttrEmitter.cpp
@@ -750,6 +750,54 @@ static void writeAvailabilityValue(raw_ostream &OS) {
      << "  OS << \"";
 }
 
+static void writeAppertainsToDeclaration(raw_ostream &OS) {
+  OS << "  template <typename Subject>\n";
+  OS << "  inline bool appertainsTo(const Subject *) const;\n";
+}
+
+static std::string getNodeName(const Record *R) {
+  if (R->isSubClassOf("Decl"))
+    return R->getName() + "Decl";
+  return R->getName();
+}
+
+static void writeAppertainsToSpecializationDefinitions(Record &R,
+                                                       raw_ostream &OS) {
+  // If there are no subjects for the attribute, we assume the attribute
+  // appertains to all subjects (this is the most backwards-compatible way to
+  // implement appertainsTo).
+  bool HasSubjects = !R.isValueUnset("Subjects");
+
+  OS << "template <typename Subject>\n";
+  OS << "inline bool " + R.getName();
+  OS << "Attr::appertainsTo(const Subject *) const { return ";
+  OS << std::string((HasSubjects ? "false" : "true")) + "; }\n\n";
+
+  if (!HasSubjects)
+    return;
+
+  std::vector<Record *> Subjects = R.getValueAsListOfDefs("Subjects");
+
+  for (std::vector<Record *>::const_iterator I = Subjects.begin(),
+       E = Subjects.end(); I != E; ++I) {
+    if ((*I)->isSubClassOf("Decl") || (*I)->isSubClassOf("Stmt")) {
+      OS << "template <>\n";
+      OS << "inline bool " + R.getName() + "Attr::appertainsTo<";
+      OS << getNodeName(*I) + ">( const " + getNodeName(*I);
+      OS << "*) const { return true; }\n\n";
+    } else if ((*I)->isSubClassOf("SubsetSubject")) {
+      // Subset subjects have a base associated with them that we will use for
+      // the template parameter.  But the contents of the function are pulled
+      // directly from the CheckCode parameter.
+      Record *Base = (*I)->getValueAsDef("Base");
+      std::string Check = (*I)->getValueAsString("CheckCode");
+      OS << "template <>\n";
+      OS << "inline bool " + R.getName() + "Attr::appertainsTo<";
+      OS << getNodeName(Base) + ">(const " + getNodeName(Base);
+      OS << " *S) const { return " + Check + "; }\n\n";
+    }
+  }
+}
 static void writePrettyPrintFunction(Record &R, std::vector<Argument*> &Args,
                                      raw_ostream &OS) {
   std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings");
@@ -963,9 +1011,13 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) {
 
     bool LateParsed = R.getValueAsBit("LateParsed");
     OS << "  virtual bool isLateParsed() const { return "
-       << LateParsed << "; }\n";
+       << LateParsed << "; }\n\n";
+
+    writeAppertainsToDeclaration(OS);
 
     OS << "};\n\n";
+
+    writeAppertainsToSpecializationDefinitions(R, OS);
   }
 
   OS << "#endif\n";
