Further refine the diagnostic categories for ARC diagnostics.  Addresses <rdar://problem/10245086>.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142571 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h
index 16d9b39..1ff6c11 100644
--- a/include/clang/Basic/DiagnosticIDs.h
+++ b/include/clang/Basic/DiagnosticIDs.h
@@ -182,6 +182,10 @@
   /// category.
   static StringRef getCategoryNameFromID(unsigned CategoryID);
   
+  /// isARCDiagnostic - Return true if a given diagnostic falls into an
+  /// ARC diagnostic category;
+  static bool isARCDiagnostic(unsigned DiagID);
+
   /// \brief Enumeration describing how the the emission of a diagnostic should
   /// be treated when it occurs during C++ template argument deduction.
   enum SFINAEResponse {
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index f2fb998..3267635 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2996,9 +2996,12 @@
 def ext_flexible_array_union_gnu : Extension<
   "flexible array member %0 in a union is a GNU extension">, InGroup<GNU>;
 
-let CategoryName = "Automatic Reference Counting Issue" in {
+let CategoryName = "ARC Issue" in {
 
 // ARC-mode diagnostics.
+
+let CategoryName = "ARC Weak References" in {
+
 def err_arc_weak_no_runtime : Error<
   "the current deployment target does not support automated __weak references">;
 def err_arc_unsupported_weak_class : Error<
@@ -3008,6 +3011,11 @@
 def err_arc_convesion_of_weak_unavailable : Error<
   "%select{implicit conversion|cast}0 of weak-unavailable object of type %1 to"
   " a __weak object of type %2">;
+
+} // end "ARC Weak References" category
+
+let CategoryName = "ARC Restrictions" in {
+
 def err_arc_illegal_explicit_message : Error<
   "ARC forbids explicit message send of %0">;
 def err_arc_unused_init_message : Error<
@@ -3027,6 +3035,9 @@
   "ARC forbids use of %0 in a @selector">;
 def err_arc_illegal_method_def : Error<
   "ARC forbids implementation of %0">;
+  
+} // end "ARC Restrictions" category
+  
 def err_arc_lost_method_convention : Error<
   "method was declared as %select{an 'alloc'|a 'copy'|an 'init'|a 'new'}0 "
   "method, but its implementation doesn't match because %select{"
@@ -3099,12 +3110,18 @@
 def err_arc_multiple_method_decl : Error< 
   "multiple methods named %0 found with mismatched result, "
   "parameter type or attributes">;
+
+let CategoryName = "ARC Retain Cycle" in {
+
 def warn_arc_retain_cycle : Warning<
   "capturing %0 strongly in this block is likely to lead to a retain cycle">,
   InGroup<ARCRetainCycles>;
 def note_arc_retain_cycle_owner : Note<
   "block will be retained by %select{the captured object|an object strongly "
   "retained by the captured object}0">;
+
+} // end "ARC Retain Cycle" category
+
 def note_nontrivial_objc_ownership : Note<
   "because type %0 has %select{no|no|__strong|__weak|__autoreleasing}1 "
   "ownership">;
@@ -3112,6 +3129,8 @@
   "%select{destination for|source of}0 this %1 call is a pointer to "
   "ownership-qualified type %2">, InGroup<ARCNonPodMemAccess>;
 
+let CategoryName = "ARC and @properties" in {
+
 def err_arc_strong_property_ownership : Error<
   "existing ivar %1 for strong property %0 may not be "
   "%select{|__unsafe_unretained||__weak}2">;
@@ -3121,10 +3140,15 @@
 def err_arc_inconsistent_property_ownership : Error<
   "%select{|unsafe_unretained|strong|weak}1 property %0 may not also be "
   "declared %select{|__unsafe_unretained|__strong|__weak|__autoreleasing}2">;
+
+} // end "ARC and @properties" category
+
 def err_arc_atomic_ownership : Error<
   "cannot perform atomic operation on a pointer to type %0: type has "
   "non-trivial ownership">;
 
+let CategoryName = "ARC Casting Rules" in {
+
 def err_arc_bridge_cast_incompatible : Error<
   "incompatible types casting %0 to %1 with a %select{__bridge|"
   "__bridge_transfer|__bridge_retained}2 cast">;
@@ -3143,6 +3167,8 @@
 def note_arc_bridge_retained : Note<
   "use __bridge_retained to make an ARC object available as a +1 %0">;
 
+} // ARC Casting category
+
 } // ARC category name
 
 def err_flexible_array_init_needs_braces : Error<
diff --git a/lib/ARCMigrate/ARCMT.cpp b/lib/ARCMigrate/ARCMT.cpp
index 6e1b0e5..a588d54 100644
--- a/lib/ARCMigrate/ARCMT.cpp
+++ b/lib/ARCMigrate/ARCMT.cpp
@@ -98,7 +98,7 @@
 
   virtual void HandleDiagnostic(DiagnosticsEngine::Level level,
                                 const Diagnostic &Info) {
-    if (arcmt::isARCDiagnostic(Info.getID(), Diags) ||
+    if (DiagnosticIDs::isARCDiagnostic(Info.getID()) ||
         level >= DiagnosticsEngine::Error || level == DiagnosticsEngine::Note) {
       CapturedDiags.push_back(StoredDiagnostic(level, Info));
       return;
@@ -572,12 +572,3 @@
 
   return false;
 }
-
-//===----------------------------------------------------------------------===//
-// isARCDiagnostic.
-//===----------------------------------------------------------------------===//
-
-bool arcmt::isARCDiagnostic(unsigned diagID, DiagnosticsEngine &Diag) {
-  return Diag.getDiagnosticIDs()->getCategoryNumberForDiag(diagID) ==
-           diag::DiagCat_Automatic_Reference_Counting_Issue;
-}
diff --git a/lib/ARCMigrate/Internals.h b/lib/ARCMigrate/Internals.h
index 46f3bb6..99b5f59 100644
--- a/lib/ARCMigrate/Internals.h
+++ b/lib/ARCMigrate/Internals.h
@@ -146,8 +146,6 @@
     : Ctx(Ctx), SemaRef(sema), TA(TA), ARCMTMacroLocs(ARCMTMacroLocs) { }
 };
 
-bool isARCDiagnostic(unsigned diagID, DiagnosticsEngine &Diag);
-
 static inline StringRef getARCMTMacroName() {
   return "__IMPL_ARCMT_REMOVED_EXPR__";
 }
diff --git a/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp
index 9481287..b14cdc9 100644
--- a/lib/Basic/DiagnosticIDs.cpp
+++ b/lib/Basic/DiagnosticIDs.cpp
@@ -806,9 +806,14 @@
     return false;
 
   // Currently we consider all ARC errors as recoverable.
-  if (getCategoryNumberForDiag(DiagID) ==
-        diag::DiagCat_Automatic_Reference_Counting_Issue)
+  if (isARCDiagnostic(DiagID))
     return false;
 
   return true;
 }
+
+bool DiagnosticIDs::isARCDiagnostic(unsigned DiagID) {
+  unsigned cat = getCategoryNumberForDiag(DiagID);
+  return DiagnosticIDs::getCategoryNameFromID(cat).startswith("ARC ");
+}
+
diff --git a/test/ARCMT/migrate-plist-output.m b/test/ARCMT/migrate-plist-output.m
index e5b74e9..d5cb9c1 100644
--- a/test/ARCMT/migrate-plist-output.m
+++ b/test/ARCMT/migrate-plist-output.m
@@ -21,7 +21,7 @@
 // CHECK:  <array>
 // CHECK:   <dict>
 // CHECK:    <key>description</key><string>ARC forbids explicit message send of &apos;release&apos;</string>
-// CHECK:    <key>category</key><string>Automatic Reference Counting Issue</string>
+// CHECK:    <key>category</key><string>ARC Restrictions</string>
 // CHECK:    <key>type</key><string>error</string>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>