diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index e07e84a..55bbfea 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -16,6 +16,9 @@
 
 #include "clang/AST/AttrIterator.h"
 #include "clang/AST/Type.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Stmt.h"
 #include "clang/Basic/AttrKinds.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/SourceLocation.h"
@@ -102,6 +105,9 @@ public:
   // Pretty print this attribute.
   virtual void printPretty(raw_ostream &OS,
                            const PrintingPolicy &Policy) const = 0;
+
+  virtual bool appertainsTo(const Decl *D) const = 0;
+  virtual bool appertainsTo(const Stmt *S) const = 0;
 };
 
 class InheritableAttr : public Attr {
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..cc5f023 100644
--- a/utils/TableGen/ClangAttrEmitter.cpp
+++ b/utils/TableGen/ClangAttrEmitter.cpp
@@ -750,6 +750,89 @@ static void writeAvailabilityValue(raw_ostream &OS) {
      << "  OS << \"";
 }
 
+static std::string getNodeName(const Record *R) {
+  // Decl nodes are always suffixed with Decl, but Stmt nodes are not.  See 
+  // ClangTableGenMain's entry for GenClangDeclNodes and GenClangStmtNodes.
+  if (R->isSubClassOf("Decl"))
+    return R->getName() + "Decl";
+  return R->getName();
+}
+
+/// Returns true if the subject appertains to a declaration, or false if it
+/// appertains to a statement.  The generated function name is returned by FN,
+/// and the generated parameter type is returned by TN.  This function will
+/// write the function definition into the ostream, so do not call this
+/// function while emitting other code.
+static bool writeAppertainsToSubjectSubsetDefinition(raw_ostream &OS,
+                                                     const Record *S,
+                                                     std::string &FN,
+                                                     std::string &TN) {
+  Record *B = S->getValueAsDef("Base");
+  FN = "appertainsTo" + S->getName();
+  TN = getNodeName(B);
+  OS << "private:\n  bool " + FN + "(const " + TN + " *S) const {\n";
+  std::string C = S->getValueAsString("CheckCode");
+  OS << "    return " + C + ";\n  }\n\n";
+  return B->isSubClassOf("Decl");
+}
+
+static void writeAppertainsToList(raw_ostream &OS,
+                                  const std::vector<std::string> &L) {
+  if (L.empty()) {
+    OS << "false";
+    return;
+  }
+
+  for (std::vector<std::string>::const_iterator I = L.begin(), E = L.end(),
+    F = L.begin(); I != E; ++I) {
+    if (I != F)
+      OS << " || ";
+    OS << (*I);
+  }
+}
+
+static void writeAppertainsToDefinitions(Record &R, raw_ostream &OS) {
+  // If there are subjects, we need to determine what those subjects are and
+  // how to write out the appertainsTo method pair.  If the function would not
+  // appertain to any of the given subjects (eg, there are Decls but not
+  // Stmts), then the empty function will return false (so it does not
+  // appertain to anything of the kind).  If there are subjects, then they are
+  // either simple subjects, or subset subjects.  Simple subjects are coded by
+  // using an isa check.  Subset subjects are coded using a helper function.
+  std::vector<std::string> Decls, Stmts;
+  bool HasSubjects = !R.isValueUnset("Subjects");
+  if (HasSubjects) {
+    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"))
+        Decls.push_back("isa<" + getNodeName(*I) + ">(*P)");
+      else if ((*I)->isSubClassOf("Stmt"))
+        Stmts.push_back("isa<" + getNodeName(*I) + ">(*P)");
+      else if ((*I)->isSubClassOf("SubsetSubject")) {
+        std::string FN, TN;
+        bool IsDecl = writeAppertainsToSubjectSubsetDefinition(OS, *I, FN, TN);
+        std::string C = FN + "(cast<" + TN + ">(P))";
+        if (IsDecl)
+          Decls.push_back(C);
+        else
+          Stmts.push_back(C);
+      }
+    }
+  }
+
+  // Write out the appertainsTo functions themselves.
+  OS << "public:\n  virtual bool appertainsTo(const Decl *P) const {\n";
+  OS << "    return ";
+  HasSubjects ? writeAppertainsToList(OS, Decls) : OS << "true";
+  OS << ";\n  }\n\n";
+
+  OS << "  virtual bool appertainsTo(const Stmt *P) const {\n";
+  OS << "    return ";
+  HasSubjects ? writeAppertainsToList(OS, Stmts) : OS << "true";
+  OS << ";\n  }\n\n";
+}
+
 static void writePrettyPrintFunction(Record &R, std::vector<Argument*> &Args,
                                      raw_ostream &OS) {
   std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings");
@@ -963,7 +1046,9 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) {
 
     bool LateParsed = R.getValueAsBit("LateParsed");
     OS << "  virtual bool isLateParsed() const { return "
-       << LateParsed << "; }\n";
+       << LateParsed << "; }\n\n";
+
+    writeAppertainsToDefinitions(R, OS);
 
     OS << "};\n\n";
   }
