Merge remote-tracking branch 'origin/swift-4.1-branch' into stable
diff --git a/test/Misc/warning-flags-tree.c b/test/Misc/warning-flags-tree.c
index d71c9f6..01ba497 100644
--- a/test/Misc/warning-flags-tree.c
+++ b/test/Misc/warning-flags-tree.c
@@ -1,6 +1,6 @@
-// RUN: diagtool tree | FileCheck -strict-whitespace %s
-// RUN: diagtool tree -Weverything | FileCheck -strict-whitespace %s
-// RUN: diagtool tree everything | FileCheck -strict-whitespace %s
+// RUN: diagtool tree --internal | FileCheck -strict-whitespace %s
+// RUN: diagtool tree --internal -Weverything | FileCheck -strict-whitespace %s
+// RUN: diagtool tree --internal everything | FileCheck -strict-whitespace %s
 //
 // These three ways of running diagtool tree are the same:
 // they produce a tree for every top-level diagnostic flag.
@@ -29,8 +29,7 @@
 
 // RUN: not diagtool tree -Wthis-is-not-a-valid-flag
 
-
-// RUN: diagtool tree -Wgnu | FileCheck -strict-whitespace -check-prefix CHECK-GNU %s
+// RUN: diagtool tree --internal -Wgnu | FileCheck -strict-whitespace -check-prefix CHECK-GNU %s
 // CHECK-GNU: -Wgnu
 // CHECK-GNU:   -Wgnu-designator
 // CHECK-GNU:     ext_gnu_array_range
@@ -40,7 +39,7 @@
 // CHECK-GNU:     ext_vla
 // There are more GNU extensions but we don't need to check them all.
 
-// RUN: diagtool tree --flags-only -Wgnu | FileCheck -check-prefix CHECK-FLAGS-ONLY %s
+// RUN: diagtool tree -Wgnu | FileCheck -check-prefix CHECK-FLAGS-ONLY %s
 // CHECK-FLAGS-ONLY: -Wgnu
 // CHECK-FLAGS-ONLY:   -Wgnu-designator
 // CHECK-FLAGS-ONLY-NOT:     ext_gnu_array_range
diff --git a/tools/diagtool/DiagnosticNames.cpp b/tools/diagtool/DiagnosticNames.cpp
index 1f89489..00af854 100644
--- a/tools/diagtool/DiagnosticNames.cpp
+++ b/tools/diagtool/DiagnosticNames.cpp
@@ -85,6 +85,11 @@
   return nullptr;
 }
 
+llvm::iterator_range<diagtool::GroupRecord::subgroup_iterator>
+GroupRecord::subgroups() const {
+  return llvm::make_range(subgroup_begin(), subgroup_end());
+}
+
 GroupRecord::diagnostics_iterator GroupRecord::diagnostics_begin() const {
   return DiagArrays + Members;
 }
@@ -93,6 +98,11 @@
   return nullptr;
 }
 
+llvm::iterator_range<diagtool::GroupRecord::diagnostics_iterator>
+GroupRecord::diagnostics() const {
+  return llvm::make_range(diagnostics_begin(), diagnostics_end());
+}
+
 llvm::ArrayRef<GroupRecord> diagtool::getDiagnosticGroups() {
   return llvm::makeArrayRef(OptionTable);
 }
diff --git a/tools/diagtool/DiagnosticNames.h b/tools/diagtool/DiagnosticNames.h
index ac1a098..598ae6a 100644
--- a/tools/diagtool/DiagnosticNames.h
+++ b/tools/diagtool/DiagnosticNames.h
@@ -20,7 +20,7 @@
     const char *NameStr;
     short DiagID;
     uint8_t NameLen;
-    
+
     llvm::StringRef getName() const {
       return llvm::StringRef(NameStr, NameLen);
     }
@@ -80,7 +80,7 @@
       bool operator==(group_iterator &Other) const {
         return CurrentID == Other.CurrentID;
       }
-      
+
       bool operator!=(group_iterator &Other) const {
         return CurrentID != Other.CurrentID;
       }
@@ -89,10 +89,12 @@
     typedef group_iterator<GroupRecord> subgroup_iterator;
     subgroup_iterator subgroup_begin() const;
     subgroup_iterator subgroup_end() const;
+    llvm::iterator_range<subgroup_iterator> subgroups() const;
 
     typedef group_iterator<DiagnosticRecord> diagnostics_iterator;
     diagnostics_iterator diagnostics_begin() const;
     diagnostics_iterator diagnostics_end() const;
+    llvm::iterator_range<diagnostics_iterator> diagnostics() const;
 
     bool operator<(llvm::StringRef Other) const {
       return getName() < Other;
diff --git a/tools/diagtool/ListWarnings.cpp b/tools/diagtool/ListWarnings.cpp
index 3e6e883..8bf9df9 100644
--- a/tools/diagtool/ListWarnings.cpp
+++ b/tools/diagtool/ListWarnings.cpp
@@ -23,7 +23,7 @@
 DEF_DIAGTOOL("list-warnings",
              "List warnings and their corresponding flags",
              ListWarnings)
-  
+
 using namespace clang;
 using namespace diagtool;
 
@@ -31,20 +31,19 @@
 struct Entry {
   llvm::StringRef DiagName;
   llvm::StringRef Flag;
-  
+
   Entry(llvm::StringRef diagN, llvm::StringRef flag)
     : DiagName(diagN), Flag(flag) {}
-  
+
   bool operator<(const Entry &x) const { return DiagName < x.DiagName; }
 };
 }
 
 static void printEntries(std::vector<Entry> &entries, llvm::raw_ostream &out) {
-  for (std::vector<Entry>::iterator it = entries.begin(), ei = entries.end();
-       it != ei; ++it) {
-    out << "  " << it->DiagName;
-    if (!it->Flag.empty())
-      out << " [-W" << it->Flag << "]";
+  for (const Entry &E : entries) {
+    out << "  " << E.DiagName;
+    if (!E.Flag.empty())
+      out << " [-W" << E.Flag << "]";
     out << '\n';
   }
 }
@@ -52,23 +51,18 @@
 int ListWarnings::run(unsigned int argc, char **argv, llvm::raw_ostream &out) {
   std::vector<Entry> Flagged, Unflagged;
   llvm::StringMap<std::vector<unsigned> > flagHistogram;
-  
-  ArrayRef<DiagnosticRecord> AllDiagnostics = getBuiltinDiagnosticsByName();
 
-  for (ArrayRef<DiagnosticRecord>::iterator di = AllDiagnostics.begin(),
-                                            de = AllDiagnostics.end();
-       di != de; ++di) {
-    unsigned diagID = di->DiagID;
-    
+  for (const DiagnosticRecord &DR : getBuiltinDiagnosticsByName()) {
+    const unsigned diagID = DR.DiagID;
+
     if (DiagnosticIDs::isBuiltinNote(diagID))
       continue;
-        
+
     if (!DiagnosticIDs::isBuiltinWarningOrExtension(diagID))
       continue;
-  
-    Entry entry(di->getName(),
-                DiagnosticIDs::getWarningOptionForDiag(diagID));
-    
+
+    Entry entry(DR.getName(), DiagnosticIDs::getWarningOptionForDiag(diagID));
+
     if (entry.Flag.empty())
       Unflagged.push_back(entry);
     else {
@@ -76,24 +70,24 @@
       flagHistogram[entry.Flag].push_back(diagID);
     }
   }
-  
+
   out << "Warnings with flags (" << Flagged.size() << "):\n";
   printEntries(Flagged, out);
-  
+
   out << "Warnings without flags (" << Unflagged.size() << "):\n";
   printEntries(Unflagged, out);
 
   out << "\nSTATISTICS:\n\n";
 
-  double percentFlagged = ((double) Flagged.size()) 
-    / (Flagged.size() + Unflagged.size()) * 100.0;
-  
-  out << "  Percentage of warnings with flags: " 
-      << llvm::format("%.4g",percentFlagged) << "%\n";
-  
+  double percentFlagged =
+      ((double)Flagged.size()) / (Flagged.size() + Unflagged.size()) * 100.0;
+
+  out << "  Percentage of warnings with flags: "
+      << llvm::format("%.4g", percentFlagged) << "%\n";
+
   out << "  Number of unique flags: "
       << flagHistogram.size() << '\n';
-  
+
   double avgDiagsPerFlag = (double) Flagged.size() / flagHistogram.size();
   out << "  Average number of diagnostics per flag: "
       << llvm::format("%.4g", avgDiagsPerFlag) << '\n';
@@ -102,7 +96,7 @@
       << flagHistogram["pedantic"].size() << '\n';
 
   out << '\n';
-  
+
   return 0;
 }
 
diff --git a/tools/diagtool/ShowEnabledWarnings.cpp b/tools/diagtool/ShowEnabledWarnings.cpp
index e6ea786..513abc1 100644
--- a/tools/diagtool/ShowEnabledWarnings.cpp
+++ b/tools/diagtool/ShowEnabledWarnings.cpp
@@ -112,17 +112,14 @@
   // which ones are turned on.
   // FIXME: It would be very nice to print which flags are turning on which
   // diagnostics, but this can be done with a diff.
-  ArrayRef<DiagnosticRecord> AllDiagnostics = getBuiltinDiagnosticsByName();
   std::vector<PrettyDiag> Active;
 
-  for (ArrayRef<DiagnosticRecord>::iterator I = AllDiagnostics.begin(),
-                                            E = AllDiagnostics.end();
-       I != E; ++I) {
-    unsigned DiagID = I->DiagID;
-    
+  for (const DiagnosticRecord &DR : getBuiltinDiagnosticsByName()) {
+    unsigned DiagID = DR.DiagID;
+
     if (DiagnosticIDs::isBuiltinNote(DiagID))
       continue;
-    
+
     if (!DiagnosticIDs::isBuiltinWarningOrExtension(DiagID))
       continue;
 
@@ -132,17 +129,16 @@
       continue;
 
     StringRef WarningOpt = DiagnosticIDs::getWarningOptionForDiag(DiagID);
-    Active.push_back(PrettyDiag(I->getName(), WarningOpt, DiagLevel));
+    Active.push_back(PrettyDiag(DR.getName(), WarningOpt, DiagLevel));
   }
 
   // Print them all out.
-  for (std::vector<PrettyDiag>::const_iterator I = Active.begin(),
-       E = Active.end(); I != E; ++I) {
+  for (const PrettyDiag &PD : Active) {
     if (ShouldShowLevels)
-      Out << getCharForLevel(I->Level) << "  ";
-    Out << I->Name;
-    if (!I->Flag.empty())
-      Out << " [-W" << I->Flag << "]";
+      Out << getCharForLevel(PD.Level) << "  ";
+    Out << PD.Name;
+    if (!PD.Flag.empty())
+      Out << " [-W" << PD.Flag << "]";
     Out << '\n';
   }
 
diff --git a/tools/diagtool/TreeView.cpp b/tools/diagtool/TreeView.cpp
index 07af944..b4846b5 100644
--- a/tools/diagtool/TreeView.cpp
+++ b/tools/diagtool/TreeView.cpp
@@ -32,10 +32,10 @@
 public:
   llvm::raw_ostream &out;
   const bool ShowColors;
-  bool FlagsOnly;
+  bool Internal;
 
   TreePrinter(llvm::raw_ostream &out)
-      : out(out), ShowColors(hasColors(out)), FlagsOnly(false) {}
+      : out(out), ShowColors(hasColors(out)), Internal(false) {}
 
   void setColor(llvm::raw_ostream::Colors Color) {
     if (ShowColors)
@@ -54,28 +54,42 @@
     return Diags.isIgnored(DiagID, SourceLocation());
   }
 
+  static bool enabledByDefault(const GroupRecord &Group) {
+    for (const DiagnosticRecord &DR : Group.diagnostics()) {
+      if (isIgnored(DR.DiagID))
+        return false;
+    }
+
+    for (const GroupRecord &GR : Group.subgroups()) {
+      if (!enabledByDefault(GR))
+        return false;
+    }
+
+    return true;
+  }
+
   void printGroup(const GroupRecord &Group, unsigned Indent = 0) {
     out.indent(Indent * 2);
 
-    setColor(llvm::raw_ostream::YELLOW);
+    if (enabledByDefault(Group))
+      setColor(llvm::raw_ostream::GREEN);
+    else
+      setColor(llvm::raw_ostream::YELLOW);
+
     out << "-W" << Group.getName() << "\n";
     resetColor();
 
     ++Indent;
-    for (GroupRecord::subgroup_iterator I = Group.subgroup_begin(),
-                                        E = Group.subgroup_end();
-         I != E; ++I) {
-      printGroup(*I, Indent);
+    for (const GroupRecord &GR : Group.subgroups()) {
+      printGroup(GR, Indent);
     }
 
-    if (!FlagsOnly) {
-      for (GroupRecord::diagnostics_iterator I = Group.diagnostics_begin(),
-                                             E = Group.diagnostics_end();
-           I != E; ++I) {
-        if (ShowColors && !isIgnored(I->DiagID))
+    if (Internal) {
+      for (const DiagnosticRecord &DR : Group.diagnostics()) {
+        if (ShowColors && !isIgnored(DR.DiagID))
           setColor(llvm::raw_ostream::GREEN);
         out.indent(Indent * 2);
-        out << I->getName();
+        out << DR.getName();
         resetColor();
         out << "\n";
       }
@@ -107,12 +121,9 @@
     ArrayRef<GroupRecord> AllGroups = getDiagnosticGroups();
     llvm::DenseSet<unsigned> NonRootGroupIDs;
 
-    for (ArrayRef<GroupRecord>::iterator I = AllGroups.begin(),
-                                         E = AllGroups.end();
-         I != E; ++I) {
-      for (GroupRecord::subgroup_iterator SI = I->subgroup_begin(),
-                                          SE = I->subgroup_end();
-           SI != SE; ++SI) {
+    for (const GroupRecord &GR : AllGroups) {
+      for (auto SI = GR.subgroup_begin(), SE = GR.subgroup_end(); SI != SE;
+           ++SI) {
         NonRootGroupIDs.insert((unsigned)SI.getID());
       }
     }
@@ -139,16 +150,16 @@
 };
 
 static void printUsage() {
-  llvm::errs() << "Usage: diagtool tree [--flags-only] [<diagnostic-group>]\n";
+  llvm::errs() << "Usage: diagtool tree [--internal] [<diagnostic-group>]\n";
 }
 
 int TreeView::run(unsigned int argc, char **argv, llvm::raw_ostream &out) {
   // First check our one flag (--flags-only).
-  bool FlagsOnly = false;
+  bool Internal = false;
   if (argc > 0) {
     StringRef FirstArg(*argv);
-    if (FirstArg.equals("--flags-only")) {
-      FlagsOnly = true;
+    if (FirstArg.equals("--internal")) {
+      Internal = true;
       --argc;
       ++argv;
     }
@@ -175,7 +186,7 @@
   }
 
   TreePrinter TP(out);
-  TP.FlagsOnly = FlagsOnly;
+  TP.Internal = Internal;
   TP.showKey();
   return ShowAll ? TP.showAll() : TP.showGroup(RootGroup);
 }