Index: lib/Basic/DiagnosticIDs.cpp
===================================================================
--- lib/Basic/DiagnosticIDs.cpp	(revision 186796)
+++ lib/Basic/DiagnosticIDs.cpp	(working copy)
@@ -507,8 +507,8 @@
   // shorter type anyway.
   size_t NameLen;
   const char *NameStr;
-  const short *Members;
-  const short *SubGroups;
+  uint16_t Members;
+  uint16_t SubGroups;
 
   StringRef getName() const {
     return StringRef(NameStr, NameLen);
@@ -545,16 +545,14 @@
     const WarningOption *Group,
     SmallVectorImpl<diag::kind> &Diags) const {
   // Add the members of the option diagnostic set.
-  if (const short *Member = Group->Members) {
-    for (; *Member != -1; ++Member)
-      Diags.push_back(*Member);
-  }
+  const int16_t *Member = DiagArrays + Group->Members;
+  for (; *Member != -1; ++Member)
+    Diags.push_back(*Member);
 
   // Add the members of the subgroups.
-  if (const short *SubGroups = Group->SubGroups) {
-    for (; *SubGroups != (short)-1; ++SubGroups)
-      getDiagnosticsInGroup(&OptionTable[(short)*SubGroups], Diags);
-  }
+  const int16_t *SubGroups = DiagSubGroups + Group->SubGroups;
+  for (; *SubGroups != (int16_t)-1; ++SubGroups)
+    getDiagnosticsInGroup(&OptionTable[(short)*SubGroups], Diags);
 }
 
 bool DiagnosticIDs::getDiagnosticsInGroup(
Index: tools/diagtool/DiagnosticNames.cpp
===================================================================
--- tools/diagtool/DiagnosticNames.cpp	(revision 186786)
+++ tools/diagtool/DiagnosticNames.cpp	(working copy)
@@ -73,6 +73,22 @@
 #undef GET_DIAG_TABLE
 };
 
+GroupRecord::subgroup_iterator GroupRecord::subgroup_begin() const {
+  return DiagSubGroups + SubGroups;
+}
+
+GroupRecord::subgroup_iterator GroupRecord::subgroup_end() const {
+  return 0;
+}
+
+GroupRecord::diagnostics_iterator GroupRecord::diagnostics_begin() const {
+  return DiagArrays + Members;
+}
+
+GroupRecord::diagnostics_iterator GroupRecord::diagnostics_end() const {
+  return 0;
+}
+
 llvm::ArrayRef<GroupRecord> diagtool::getDiagnosticGroups() {
   return llvm::makeArrayRef(OptionTable);
 }
Index: tools/diagtool/DiagnosticNames.h
===================================================================
--- tools/diagtool/DiagnosticNames.h	(revision 186786)
+++ tools/diagtool/DiagnosticNames.h	(working copy)
@@ -40,9 +40,9 @@
     // shorter type anyway.
     size_t NameLen;
     const char *NameStr;
-    const short *Members;
-    const short *SubGroups;
-    
+    uint16_t Members;
+    uint16_t SubGroups;
+
     llvm::StringRef getName() const {
       return llvm::StringRef(NameStr, NameLen);
     }
@@ -90,20 +90,12 @@
     };
 
     typedef group_iterator<GroupRecord> subgroup_iterator;
-    subgroup_iterator subgroup_begin() const {
-      return SubGroups;
-    }
-    subgroup_iterator subgroup_end() const {
-      return 0;
-    }
+    subgroup_iterator subgroup_begin() const;
+    subgroup_iterator subgroup_end() const;
 
     typedef group_iterator<DiagnosticRecord> diagnostics_iterator;
-    diagnostics_iterator diagnostics_begin() const {
-      return Members;
-    }
-    diagnostics_iterator diagnostics_end() const {
-      return 0;
-    }
+    diagnostics_iterator diagnostics_begin() const;
+    diagnostics_iterator diagnostics_end() const;
 
     bool operator<(const GroupRecord &Other) const {
       return getName() < Other.getName();
Index: utils/TableGen/ClangDiagnosticsEmitter.cpp
===================================================================
--- utils/TableGen/ClangDiagnosticsEmitter.cpp	(revision 186797)
+++ utils/TableGen/ClangDiagnosticsEmitter.cpp	(working copy)
@@ -619,6 +619,8 @@
   // that are mapped to.
   OS << "\n#ifdef GET_DIAG_ARRAYS\n";
   unsigned MaxLen = 0;
+  OS << "static const int16_t DiagArrays[] = {\n"
+     << "  /* Empty */ -1,\n";
   for (std::map<std::string, GroupInfo>::const_iterator
        I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) {
     MaxLen = std::max(MaxLen, (unsigned)I->first.size());
@@ -626,7 +628,7 @@
 
     const std::vector<const Record*> &V = I->second.DiagsInGroup;
     if (!V.empty() || (IsPedantic && !DiagsInPedantic.empty())) {
-      OS << "static const short DiagArray" << I->second.IDNo << "[] = { ";
+      OS << "  /* DiagArray" << I->second.IDNo << " */ ";
       for (unsigned i = 0, e = V.size(); i != e; ++i)
         OS << "diag::" << V[i]->getName() << ", ";
       // Emit the diagnostics implicitly in "pedantic".
@@ -634,12 +636,20 @@
         for (unsigned i = 0, e = DiagsInPedantic.size(); i != e; ++i)
           OS << "diag::" << DiagsInPedantic[i]->getName() << ", ";
       }
-      OS << "-1 };\n";
+      OS << "-1,\n";
     }
+  }
+  OS << "};\n\n";
 
+  OS << "static const int16_t DiagSubGroups[] = {\n"
+     << "  /* Empty */ -1,\n";
+  for (std::map<std::string, GroupInfo>::const_iterator
+       I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) {
+    const bool IsPedantic = I->first == "pedantic";
+
     const std::vector<std::string> &SubGroups = I->second.SubGroups;
     if (!SubGroups.empty() || (IsPedantic && !GroupsInPedantic.empty())) {
-      OS << "static const short DiagSubGroup" << I->second.IDNo << "[] = { ";
+      OS << "  /* DiagSubGroup" << I->second.IDNo << " */ ";
       for (unsigned i = 0, e = SubGroups.size(); i != e; ++i) {
         std::map<std::string, GroupInfo>::const_iterator RI =
           DiagsInGroup.find(SubGroups[i]);
@@ -658,13 +668,15 @@
         }
       }
 
-      OS << "-1 };\n";
+      OS << "-1,\n";
     }
   }
+  OS << "};\n";
   OS << "#endif // GET_DIAG_ARRAYS\n\n";
 
   // Emit the table now.
   OS << "\n#ifdef GET_DIAG_TABLE\n";
+  unsigned SubGroupIndex = 1, DiagArrayIndex = 1;
   for (std::map<std::string, GroupInfo>::const_iterator
        I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) {
     // Group option string.
@@ -683,20 +695,31 @@
     const bool IsPedantic = I->first == "pedantic";
 
     // Diagnostics in the group.
-    const bool hasDiags = !I->second.DiagsInGroup.empty() ||
+    const std::vector<const Record*> &V = I->second.DiagsInGroup;
+    const bool hasDiags = !V.empty() ||
                           (IsPedantic && !DiagsInPedantic.empty());
-    if (!hasDiags)
-      OS << "0, ";
-    else
-      OS << "DiagArray" << I->second.IDNo << ", ";
+    if (hasDiags) {
+      OS << "/* DiagArray" << I->second.IDNo << " */ "
+         << DiagArrayIndex << ", ";
+      if (IsPedantic)
+        DiagArrayIndex += DiagsInPedantic.size();
+      DiagArrayIndex += V.size() + 1;
+    } else {
+      OS << "/* Empty */ 0, ";
+    }
 
     // Subgroups.
-    const bool hasSubGroups = !I->second.SubGroups.empty() ||
+    const std::vector<std::string> &SubGroups = I->second.SubGroups;
+    const bool hasSubGroups = !SubGroups.empty() ||
                               (IsPedantic && !GroupsInPedantic.empty());
-    if (!hasSubGroups)
-      OS << 0;
-    else
-      OS << "DiagSubGroup" << I->second.IDNo;
+    if (hasSubGroups) {
+      OS << "/* DiagSubGroup" << I->second.IDNo << " */ " << SubGroupIndex;
+      if (IsPedantic)
+        SubGroupIndex += GroupsInPedantic.size();
+      SubGroupIndex += SubGroups.size() + 1;
+    } else {
+      OS << "/* Empty */ 0";
+    }
     OS << " },\n";
   }
   OS << "#endif // GET_DIAG_TABLE\n\n";
