1 //=- ClangDiagnosticsEmitter.cpp - Generate Clang diagnostics tables -*- C++ -*-
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // These tablegen backends emit Clang diagnostics tables.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/ADT/DenseSet.h"
15 #include "llvm/ADT/Optional.h"
16 #include "llvm/ADT/PointerUnion.h"
17 #include "llvm/ADT/SmallPtrSet.h"
18 #include "llvm/ADT/SmallString.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringMap.h"
21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/ADT/Twine.h"
23 #include "llvm/TableGen/Error.h"
24 #include "llvm/TableGen/Record.h"
25 #include "llvm/TableGen/StringToOffsetTable.h"
26 #include "llvm/TableGen/TableGenBackend.h"
27 #include <algorithm>
28 #include <cctype>
29 #include <functional>
30 #include <map>
31 #include <set>
32 using namespace llvm;
33 
34 //===----------------------------------------------------------------------===//
35 // Diagnostic category computation code.
36 //===----------------------------------------------------------------------===//
37 
38 namespace {
39 class DiagGroupParentMap {
40   RecordKeeper &Records;
41   std::map<const Record*, std::vector<Record*> > Mapping;
42 public:
43   DiagGroupParentMap(RecordKeeper &records) : Records(records) {
44     std::vector<Record*> DiagGroups
45       = Records.getAllDerivedDefinitions("DiagGroup");
46     for (unsigned i = 0, e = DiagGroups.size(); i != e; ++i) {
47       std::vector<Record*> SubGroups =
48         DiagGroups[i]->getValueAsListOfDefs("SubGroups");
49       for (unsigned j = 0, e = SubGroups.size(); j != e; ++j)
50         Mapping[SubGroups[j]].push_back(DiagGroups[i]);
51     }
52   }
53 
54   const std::vector<Record*> &getParents(const Record *Group) {
55     return Mapping[Group];
56   }
57 };
58 } // end anonymous namespace.
59 
60 static std::string
61 getCategoryFromDiagGroup(const Record *Group,
62                          DiagGroupParentMap &DiagGroupParents) {
63   // If the DiagGroup has a category, return it.
64   std::string CatName = Group->getValueAsString("CategoryName");
65   if (!CatName.empty()) return CatName;
66 
67   // The diag group may the subgroup of one or more other diagnostic groups,
68   // check these for a category as well.
69   const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group);
70   for (unsigned i = 0, e = Parents.size(); i != e; ++i) {
71     CatName = getCategoryFromDiagGroup(Parents[i], DiagGroupParents);
72     if (!CatName.empty()) return CatName;
73   }
74   return "";
75 }
76 
77 /// getDiagnosticCategory - Return the category that the specified diagnostic
78 /// lives in.
79 static std::string getDiagnosticCategory(const Record *R,
80                                          DiagGroupParentMap &DiagGroupParents) {
81   // If the diagnostic is in a group, and that group has a category, use it.
82   if (DefInit *Group = dyn_cast<DefInit>(R->getValueInit("Group"))) {
83     // Check the diagnostic's diag group for a category.
84     std::string CatName = getCategoryFromDiagGroup(Group->getDef(),
85                                                    DiagGroupParents);
86     if (!CatName.empty()) return CatName;
87   }
88 
89   // If the diagnostic itself has a category, get it.
90   return R->getValueAsString("CategoryName");
91 }
92 
93 namespace {
94   class DiagCategoryIDMap {
95     RecordKeeper &Records;
96     StringMap<unsigned> CategoryIDs;
97     std::vector<std::string> CategoryStrings;
98   public:
99     DiagCategoryIDMap(RecordKeeper &records) : Records(records) {
100       DiagGroupParentMap ParentInfo(Records);
101 
102       // The zero'th category is "".
103       CategoryStrings.push_back("");
104       CategoryIDs[""] = 0;
105 
106       std::vector<Record*> Diags =
107       Records.getAllDerivedDefinitions("Diagnostic");
108       for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
109         std::string Category = getDiagnosticCategory(Diags[i], ParentInfo);
110         if (Category.empty()) continue;  // Skip diags with no category.
111 
112         unsigned &ID = CategoryIDs[Category];
113         if (ID != 0) continue;  // Already seen.
114 
115         ID = CategoryStrings.size();
116         CategoryStrings.push_back(Category);
117       }
118     }
119 
120     unsigned getID(StringRef CategoryString) {
121       return CategoryIDs[CategoryString];
122     }
123 
124     typedef std::vector<std::string>::const_iterator const_iterator;
125     const_iterator begin() const { return CategoryStrings.begin(); }
126     const_iterator end() const { return CategoryStrings.end(); }
127   };
128 
129   struct GroupInfo {
130     std::vector<const Record*> DiagsInGroup;
131     std::vector<std::string> SubGroups;
132     unsigned IDNo;
133 
134     const Record *ExplicitDef;
135 
136     GroupInfo() : ExplicitDef(nullptr) {}
137   };
138 } // end anonymous namespace.
139 
140 static bool beforeThanCompare(const Record *LHS, const Record *RHS) {
141   assert(!LHS->getLoc().empty() && !RHS->getLoc().empty());
142   return
143     LHS->getLoc().front().getPointer() < RHS->getLoc().front().getPointer();
144 }
145 
146 static bool diagGroupBeforeByName(const Record *LHS, const Record *RHS) {
147   return LHS->getValueAsString("GroupName") <
148          RHS->getValueAsString("GroupName");
149 }
150 
151 static bool beforeThanCompareGroups(const GroupInfo *LHS, const GroupInfo *RHS){
152   assert(!LHS->DiagsInGroup.empty() && !RHS->DiagsInGroup.empty());
153   return beforeThanCompare(LHS->DiagsInGroup.front(),
154                            RHS->DiagsInGroup.front());
155 }
156 
157 /// \brief Invert the 1-[0/1] mapping of diags to group into a one to many
158 /// mapping of groups to diags in the group.
159 static void groupDiagnostics(const std::vector<Record*> &Diags,
160                              const std::vector<Record*> &DiagGroups,
161                              std::map<std::string, GroupInfo> &DiagsInGroup) {
162 
163   for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
164     const Record *R = Diags[i];
165     DefInit *DI = dyn_cast<DefInit>(R->getValueInit("Group"));
166     if (!DI)
167       continue;
168     assert(R->getValueAsDef("Class")->getName() != "CLASS_NOTE" &&
169            "Note can't be in a DiagGroup");
170     std::string GroupName = DI->getDef()->getValueAsString("GroupName");
171     DiagsInGroup[GroupName].DiagsInGroup.push_back(R);
172   }
173 
174   typedef SmallPtrSet<GroupInfo *, 16> GroupSetTy;
175   GroupSetTy ImplicitGroups;
176 
177   // Add all DiagGroup's to the DiagsInGroup list to make sure we pick up empty
178   // groups (these are warnings that GCC supports that clang never produces).
179   for (unsigned i = 0, e = DiagGroups.size(); i != e; ++i) {
180     Record *Group = DiagGroups[i];
181     GroupInfo &GI = DiagsInGroup[Group->getValueAsString("GroupName")];
182     if (Group->isAnonymous()) {
183       if (GI.DiagsInGroup.size() > 1)
184         ImplicitGroups.insert(&GI);
185     } else {
186       if (GI.ExplicitDef)
187         assert(GI.ExplicitDef == Group);
188       else
189         GI.ExplicitDef = Group;
190     }
191 
192     std::vector<Record*> SubGroups = Group->getValueAsListOfDefs("SubGroups");
193     for (unsigned j = 0, e = SubGroups.size(); j != e; ++j)
194       GI.SubGroups.push_back(SubGroups[j]->getValueAsString("GroupName"));
195   }
196 
197   // Assign unique ID numbers to the groups.
198   unsigned IDNo = 0;
199   for (std::map<std::string, GroupInfo>::iterator
200        I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I, ++IDNo)
201     I->second.IDNo = IDNo;
202 
203   // Sort the implicit groups, so we can warn about them deterministically.
204   SmallVector<GroupInfo *, 16> SortedGroups(ImplicitGroups.begin(),
205                                             ImplicitGroups.end());
206   for (SmallVectorImpl<GroupInfo *>::iterator I = SortedGroups.begin(),
207                                               E = SortedGroups.end();
208        I != E; ++I) {
209     MutableArrayRef<const Record *> GroupDiags = (*I)->DiagsInGroup;
210     llvm::sort(GroupDiags.begin(), GroupDiags.end(), beforeThanCompare);
211   }
212   llvm::sort(SortedGroups.begin(), SortedGroups.end(), beforeThanCompareGroups);
213 
214   // Warn about the same group being used anonymously in multiple places.
215   for (SmallVectorImpl<GroupInfo *>::const_iterator I = SortedGroups.begin(),
216                                                     E = SortedGroups.end();
217        I != E; ++I) {
218     ArrayRef<const Record *> GroupDiags = (*I)->DiagsInGroup;
219 
220     if ((*I)->ExplicitDef) {
221       std::string Name = (*I)->ExplicitDef->getValueAsString("GroupName");
222       for (ArrayRef<const Record *>::const_iterator DI = GroupDiags.begin(),
223                                                     DE = GroupDiags.end();
224            DI != DE; ++DI) {
225         const DefInit *GroupInit = cast<DefInit>((*DI)->getValueInit("Group"));
226         const Record *NextDiagGroup = GroupInit->getDef();
227         if (NextDiagGroup == (*I)->ExplicitDef)
228           continue;
229 
230         SrcMgr.PrintMessage((*DI)->getLoc().front(),
231                             SourceMgr::DK_Error,
232                             Twine("group '") + Name +
233                               "' is referred to anonymously");
234         SrcMgr.PrintMessage((*I)->ExplicitDef->getLoc().front(),
235                             SourceMgr::DK_Note, "group defined here");
236       }
237     } else {
238       // If there's no existing named group, we should just warn once and use
239       // notes to list all the other cases.
240       ArrayRef<const Record *>::const_iterator DI = GroupDiags.begin(),
241                                                DE = GroupDiags.end();
242       assert(DI != DE && "We only care about groups with multiple uses!");
243 
244       const DefInit *GroupInit = cast<DefInit>((*DI)->getValueInit("Group"));
245       const Record *NextDiagGroup = GroupInit->getDef();
246       std::string Name = NextDiagGroup->getValueAsString("GroupName");
247 
248       SrcMgr.PrintMessage((*DI)->getLoc().front(),
249                           SourceMgr::DK_Error,
250                           Twine("group '") + Name +
251                             "' is referred to anonymously");
252 
253       for (++DI; DI != DE; ++DI) {
254         SrcMgr.PrintMessage((*DI)->getLoc().front(),
255                             SourceMgr::DK_Note, "also referenced here");
256       }
257     }
258   }
259 }
260 
261 //===----------------------------------------------------------------------===//
262 // Infer members of -Wpedantic.
263 //===----------------------------------------------------------------------===//
264 
265 typedef std::vector<const Record *> RecordVec;
266 typedef llvm::DenseSet<const Record *> RecordSet;
267 typedef llvm::PointerUnion<RecordVec*, RecordSet*> VecOrSet;
268 
269 namespace {
270 class InferPedantic {
271   typedef llvm::DenseMap<const Record*,
272                          std::pair<unsigned, Optional<unsigned> > > GMap;
273 
274   DiagGroupParentMap &DiagGroupParents;
275   const std::vector<Record*> &Diags;
276   const std::vector<Record*> DiagGroups;
277   std::map<std::string, GroupInfo> &DiagsInGroup;
278   llvm::DenseSet<const Record*> DiagsSet;
279   GMap GroupCount;
280 public:
281   InferPedantic(DiagGroupParentMap &DiagGroupParents,
282                 const std::vector<Record*> &Diags,
283                 const std::vector<Record*> &DiagGroups,
284                 std::map<std::string, GroupInfo> &DiagsInGroup)
285   : DiagGroupParents(DiagGroupParents),
286   Diags(Diags),
287   DiagGroups(DiagGroups),
288   DiagsInGroup(DiagsInGroup) {}
289 
290   /// Compute the set of diagnostics and groups that are immediately
291   /// in -Wpedantic.
292   void compute(VecOrSet DiagsInPedantic,
293                VecOrSet GroupsInPedantic);
294 
295 private:
296   /// Determine whether a group is a subgroup of another group.
297   bool isSubGroupOfGroup(const Record *Group,
298                          llvm::StringRef RootGroupName);
299 
300   /// Determine if the diagnostic is an extension.
301   bool isExtension(const Record *Diag);
302 
303   /// Determine if the diagnostic is off by default.
304   bool isOffByDefault(const Record *Diag);
305 
306   /// Increment the count for a group, and transitively marked
307   /// parent groups when appropriate.
308   void markGroup(const Record *Group);
309 
310   /// Return true if the diagnostic is in a pedantic group.
311   bool groupInPedantic(const Record *Group, bool increment = false);
312 };
313 } // end anonymous namespace
314 
315 bool InferPedantic::isSubGroupOfGroup(const Record *Group,
316                                       llvm::StringRef GName) {
317 
318   const std::string &GroupName = Group->getValueAsString("GroupName");
319   if (GName == GroupName)
320     return true;
321 
322   const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group);
323   for (unsigned i = 0, e = Parents.size(); i != e; ++i)
324     if (isSubGroupOfGroup(Parents[i], GName))
325       return true;
326 
327   return false;
328 }
329 
330 /// Determine if the diagnostic is an extension.
331 bool InferPedantic::isExtension(const Record *Diag) {
332   const std::string &ClsName = Diag->getValueAsDef("Class")->getName();
333   return ClsName == "CLASS_EXTENSION";
334 }
335 
336 bool InferPedantic::isOffByDefault(const Record *Diag) {
337   const std::string &DefSeverity =
338       Diag->getValueAsDef("DefaultSeverity")->getValueAsString("Name");
339   return DefSeverity == "Ignored";
340 }
341 
342 bool InferPedantic::groupInPedantic(const Record *Group, bool increment) {
343   GMap::mapped_type &V = GroupCount[Group];
344   // Lazily compute the threshold value for the group count.
345   if (!V.second.hasValue()) {
346     const GroupInfo &GI = DiagsInGroup[Group->getValueAsString("GroupName")];
347     V.second = GI.SubGroups.size() + GI.DiagsInGroup.size();
348   }
349 
350   if (increment)
351     ++V.first;
352 
353   // Consider a group in -Wpendatic IFF if has at least one diagnostic
354   // or subgroup AND all of those diagnostics and subgroups are covered
355   // by -Wpedantic via our computation.
356   return V.first != 0 && V.first == V.second.getValue();
357 }
358 
359 void InferPedantic::markGroup(const Record *Group) {
360   // If all the diagnostics and subgroups have been marked as being
361   // covered by -Wpedantic, increment the count of parent groups.  Once the
362   // group's count is equal to the number of subgroups and diagnostics in
363   // that group, we can safely add this group to -Wpedantic.
364   if (groupInPedantic(Group, /* increment */ true)) {
365     const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group);
366     for (unsigned i = 0, e = Parents.size(); i != e; ++i)
367       markGroup(Parents[i]);
368   }
369 }
370 
371 void InferPedantic::compute(VecOrSet DiagsInPedantic,
372                             VecOrSet GroupsInPedantic) {
373   // All extensions that are not on by default are implicitly in the
374   // "pedantic" group.  For those that aren't explicitly included in -Wpedantic,
375   // mark them for consideration to be included in -Wpedantic directly.
376   for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
377     Record *R = Diags[i];
378     if (isExtension(R) && isOffByDefault(R)) {
379       DiagsSet.insert(R);
380       if (DefInit *Group = dyn_cast<DefInit>(R->getValueInit("Group"))) {
381         const Record *GroupRec = Group->getDef();
382         if (!isSubGroupOfGroup(GroupRec, "pedantic")) {
383           markGroup(GroupRec);
384         }
385       }
386     }
387   }
388 
389   // Compute the set of diagnostics that are directly in -Wpedantic.  We
390   // march through Diags a second time to ensure the results are emitted
391   // in deterministic order.
392   for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
393     Record *R = Diags[i];
394     if (!DiagsSet.count(R))
395       continue;
396     // Check if the group is implicitly in -Wpedantic.  If so,
397     // the diagnostic should not be directly included in the -Wpedantic
398     // diagnostic group.
399     if (DefInit *Group = dyn_cast<DefInit>(R->getValueInit("Group")))
400       if (groupInPedantic(Group->getDef()))
401         continue;
402 
403     // The diagnostic is not included in a group that is (transitively) in
404     // -Wpedantic.  Include it in -Wpedantic directly.
405     if (RecordVec *V = DiagsInPedantic.dyn_cast<RecordVec*>())
406       V->push_back(R);
407     else {
408       DiagsInPedantic.get<RecordSet*>()->insert(R);
409     }
410   }
411 
412   if (!GroupsInPedantic)
413     return;
414 
415   // Compute the set of groups that are directly in -Wpedantic.  We
416   // march through the groups to ensure the results are emitted
417   /// in a deterministc order.
418   for (unsigned i = 0, ei = DiagGroups.size(); i != ei; ++i) {
419     Record *Group = DiagGroups[i];
420     if (!groupInPedantic(Group))
421       continue;
422 
423     unsigned ParentsInPedantic = 0;
424     const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group);
425     for (unsigned j = 0, ej = Parents.size(); j != ej; ++j) {
426       if (groupInPedantic(Parents[j]))
427         ++ParentsInPedantic;
428     }
429     // If all the parents are in -Wpedantic, this means that this diagnostic
430     // group will be indirectly included by -Wpedantic already.  In that
431     // case, do not add it directly to -Wpedantic.  If the group has no
432     // parents, obviously it should go into -Wpedantic.
433     if (Parents.size() > 0 && ParentsInPedantic == Parents.size())
434       continue;
435 
436     if (RecordVec *V = GroupsInPedantic.dyn_cast<RecordVec*>())
437       V->push_back(Group);
438     else {
439       GroupsInPedantic.get<RecordSet*>()->insert(Group);
440     }
441   }
442 }
443 
444 //===----------------------------------------------------------------------===//
445 // Warning Tables (.inc file) generation.
446 //===----------------------------------------------------------------------===//
447 
448 static bool isError(const Record &Diag) {
449   const std::string &ClsName = Diag.getValueAsDef("Class")->getName();
450   return ClsName == "CLASS_ERROR";
451 }
452 
453 static bool isRemark(const Record &Diag) {
454   const std::string &ClsName = Diag.getValueAsDef("Class")->getName();
455   return ClsName == "CLASS_REMARK";
456 }
457 
458 /// ClangDiagsDefsEmitter - The top-level class emits .def files containing
459 /// declarations of Clang diagnostics.
460 namespace clang {
461 void EmitClangDiagsDefs(RecordKeeper &Records, raw_ostream &OS,
462                         const std::string &Component) {
463   // Write the #if guard
464   if (!Component.empty()) {
465     std::string ComponentName = StringRef(Component).upper();
466     OS << "#ifdef " << ComponentName << "START\n";
467     OS << "__" << ComponentName << "START = DIAG_START_" << ComponentName
468        << ",\n";
469     OS << "#undef " << ComponentName << "START\n";
470     OS << "#endif\n\n";
471   }
472 
473   const std::vector<Record*> &Diags =
474     Records.getAllDerivedDefinitions("Diagnostic");
475 
476   std::vector<Record*> DiagGroups
477     = Records.getAllDerivedDefinitions("DiagGroup");
478 
479   std::map<std::string, GroupInfo> DiagsInGroup;
480   groupDiagnostics(Diags, DiagGroups, DiagsInGroup);
481 
482   DiagCategoryIDMap CategoryIDs(Records);
483   DiagGroupParentMap DGParentMap(Records);
484 
485   // Compute the set of diagnostics that are in -Wpedantic.
486   RecordSet DiagsInPedantic;
487   InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup);
488   inferPedantic.compute(&DiagsInPedantic, (RecordVec*)nullptr);
489 
490   for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
491     const Record &R = *Diags[i];
492 
493     // Check if this is an error that is accidentally in a warning
494     // group.
495     if (isError(R)) {
496       if (DefInit *Group = dyn_cast<DefInit>(R.getValueInit("Group"))) {
497         const Record *GroupRec = Group->getDef();
498         const std::string &GroupName = GroupRec->getValueAsString("GroupName");
499         PrintFatalError(R.getLoc(), "Error " + R.getName() +
500                       " cannot be in a warning group [" + GroupName + "]");
501       }
502     }
503 
504     // Check that all remarks have an associated diagnostic group.
505     if (isRemark(R)) {
506       if (!isa<DefInit>(R.getValueInit("Group"))) {
507         PrintFatalError(R.getLoc(), "Error " + R.getName() +
508                                         " not in any diagnostic group");
509       }
510     }
511 
512     // Filter by component.
513     if (!Component.empty() && Component != R.getValueAsString("Component"))
514       continue;
515 
516     OS << "DIAG(" << R.getName() << ", ";
517     OS << R.getValueAsDef("Class")->getName();
518     OS << ", (unsigned)diag::Severity::"
519        << R.getValueAsDef("DefaultSeverity")->getValueAsString("Name");
520 
521     // Description string.
522     OS << ", \"";
523     OS.write_escaped(R.getValueAsString("Text")) << '"';
524 
525     // Warning associated with the diagnostic. This is stored as an index into
526     // the alphabetically sorted warning table.
527     if (DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) {
528       std::map<std::string, GroupInfo>::iterator I =
529           DiagsInGroup.find(DI->getDef()->getValueAsString("GroupName"));
530       assert(I != DiagsInGroup.end());
531       OS << ", " << I->second.IDNo;
532     } else if (DiagsInPedantic.count(&R)) {
533       std::map<std::string, GroupInfo>::iterator I =
534         DiagsInGroup.find("pedantic");
535       assert(I != DiagsInGroup.end() && "pedantic group not defined");
536       OS << ", " << I->second.IDNo;
537     } else {
538       OS << ", 0";
539     }
540 
541     // SFINAE response.
542     OS << ", " << R.getValueAsDef("SFINAE")->getName();
543 
544     // Default warning has no Werror bit.
545     if (R.getValueAsBit("WarningNoWerror"))
546       OS << ", true";
547     else
548       OS << ", false";
549 
550     if (R.getValueAsBit("ShowInSystemHeader"))
551       OS << ", true";
552     else
553       OS << ", false";
554 
555     // Category number.
556     OS << ", " << CategoryIDs.getID(getDiagnosticCategory(&R, DGParentMap));
557     OS << ")\n";
558   }
559 }
560 } // end namespace clang
561 
562 //===----------------------------------------------------------------------===//
563 // Warning Group Tables generation
564 //===----------------------------------------------------------------------===//
565 
566 static std::string getDiagCategoryEnum(llvm::StringRef name) {
567   if (name.empty())
568     return "DiagCat_None";
569   SmallString<256> enumName = llvm::StringRef("DiagCat_");
570   for (llvm::StringRef::iterator I = name.begin(), E = name.end(); I != E; ++I)
571     enumName += isalnum(*I) ? *I : '_';
572   return enumName.str();
573 }
574 
575 /// \brief Emit the array of diagnostic subgroups.
576 ///
577 /// The array of diagnostic subgroups contains for each group a list of its
578 /// subgroups. The individual lists are separated by '-1'. Groups with no
579 /// subgroups are skipped.
580 ///
581 /// \code
582 ///   static const int16_t DiagSubGroups[] = {
583 ///     /* Empty */ -1,
584 ///     /* DiagSubGroup0 */ 142, -1,
585 ///     /* DiagSubGroup13 */ 265, 322, 399, -1
586 ///   }
587 /// \endcode
588 ///
589 static void emitDiagSubGroups(std::map<std::string, GroupInfo> &DiagsInGroup,
590                               RecordVec &GroupsInPedantic, raw_ostream &OS) {
591   OS << "static const int16_t DiagSubGroups[] = {\n"
592      << "  /* Empty */ -1,\n";
593   for (auto const &I : DiagsInGroup) {
594     const bool IsPedantic = I.first == "pedantic";
595 
596     const std::vector<std::string> &SubGroups = I.second.SubGroups;
597     if (!SubGroups.empty() || (IsPedantic && !GroupsInPedantic.empty())) {
598       OS << "  /* DiagSubGroup" << I.second.IDNo << " */ ";
599       for (auto const &SubGroup : SubGroups) {
600         std::map<std::string, GroupInfo>::const_iterator RI =
601             DiagsInGroup.find(SubGroup);
602         assert(RI != DiagsInGroup.end() && "Referenced without existing?");
603         OS << RI->second.IDNo << ", ";
604       }
605       // Emit the groups implicitly in "pedantic".
606       if (IsPedantic) {
607         for (auto const &Group : GroupsInPedantic) {
608           const std::string &GroupName = Group->getValueAsString("GroupName");
609           std::map<std::string, GroupInfo>::const_iterator RI =
610               DiagsInGroup.find(GroupName);
611           assert(RI != DiagsInGroup.end() && "Referenced without existing?");
612           OS << RI->second.IDNo << ", ";
613         }
614       }
615 
616       OS << "-1,\n";
617     }
618   }
619   OS << "};\n\n";
620 }
621 
622 /// \brief Emit the list of diagnostic arrays.
623 ///
624 /// This data structure is a large array that contains itself arrays of varying
625 /// size. Each array represents a list of diagnostics. The different arrays are
626 /// separated by the value '-1'.
627 ///
628 /// \code
629 ///   static const int16_t DiagArrays[] = {
630 ///     /* Empty */ -1,
631 ///     /* DiagArray1 */ diag::warn_pragma_message,
632 ///                      -1,
633 ///     /* DiagArray2 */ diag::warn_abs_too_small,
634 ///                      diag::warn_unsigned_abs,
635 ///                      diag::warn_wrong_absolute_value_type,
636 ///                      -1
637 ///   };
638 /// \endcode
639 ///
640 static void emitDiagArrays(std::map<std::string, GroupInfo> &DiagsInGroup,
641                            RecordVec &DiagsInPedantic, raw_ostream &OS) {
642   OS << "static const int16_t DiagArrays[] = {\n"
643      << "  /* Empty */ -1,\n";
644   for (auto const &I : DiagsInGroup) {
645     const bool IsPedantic = I.first == "pedantic";
646 
647     const std::vector<const Record *> &V = I.second.DiagsInGroup;
648     if (!V.empty() || (IsPedantic && !DiagsInPedantic.empty())) {
649       OS << "  /* DiagArray" << I.second.IDNo << " */ ";
650       for (auto *Record : V)
651         OS << "diag::" << Record->getName() << ", ";
652       // Emit the diagnostics implicitly in "pedantic".
653       if (IsPedantic) {
654         for (auto const &Diag : DiagsInPedantic)
655           OS << "diag::" << Diag->getName() << ", ";
656       }
657       OS << "-1,\n";
658     }
659   }
660   OS << "};\n\n";
661 }
662 
663 /// \brief Emit a list of group names.
664 ///
665 /// This creates a long string which by itself contains a list of pascal style
666 /// strings, which consist of a length byte directly followed by the string.
667 ///
668 /// \code
669 ///   static const char DiagGroupNames[] = {
670 ///     \000\020#pragma-messages\t#warnings\020CFString-literal"
671 ///   };
672 /// \endcode
673 static void emitDiagGroupNames(StringToOffsetTable &GroupNames,
674                                raw_ostream &OS) {
675   OS << "static const char DiagGroupNames[] = {\n";
676   GroupNames.EmitString(OS);
677   OS << "};\n\n";
678 }
679 
680 /// \brief Emit diagnostic arrays and related data structures.
681 ///
682 /// This creates the actual diagnostic array, an array of diagnostic subgroups
683 /// and an array of subgroup names.
684 ///
685 /// \code
686 ///  #ifdef GET_DIAG_ARRAYS
687 ///     static const int16_t DiagArrays[];
688 ///     static const int16_t DiagSubGroups[];
689 ///     static const char DiagGroupNames[];
690 ///  #endif
691 ///  \endcode
692 static void emitAllDiagArrays(std::map<std::string, GroupInfo> &DiagsInGroup,
693                               RecordVec &DiagsInPedantic,
694                               RecordVec &GroupsInPedantic,
695                               StringToOffsetTable &GroupNames,
696                               raw_ostream &OS) {
697   OS << "\n#ifdef GET_DIAG_ARRAYS\n";
698   emitDiagArrays(DiagsInGroup, DiagsInPedantic, OS);
699   emitDiagSubGroups(DiagsInGroup, GroupsInPedantic, OS);
700   emitDiagGroupNames(GroupNames, OS);
701   OS << "#endif // GET_DIAG_ARRAYS\n\n";
702 }
703 
704 /// \brief Emit diagnostic table.
705 ///
706 /// The table is sorted by the name of the diagnostic group. Each element
707 /// consists of the name of the diagnostic group (given as offset in the
708 /// group name table), a reference to a list of diagnostics (optional) and a
709 /// reference to a set of subgroups (optional).
710 ///
711 /// \code
712 /// #ifdef GET_DIAG_TABLE
713 ///  {/* abi */              159, /* DiagArray11 */ 19, /* Empty */          0},
714 ///  {/* aggregate-return */ 180, /* Empty */        0, /* Empty */          0},
715 ///  {/* all */              197, /* Empty */        0, /* DiagSubGroup13 */ 3},
716 ///  {/* deprecated */       1981,/* DiagArray1 */ 348, /* DiagSubGroup3 */  9},
717 /// #endif
718 /// \endcode
719 static void emitDiagTable(std::map<std::string, GroupInfo> &DiagsInGroup,
720                           RecordVec &DiagsInPedantic,
721                           RecordVec &GroupsInPedantic,
722                           StringToOffsetTable &GroupNames, raw_ostream &OS) {
723   unsigned MaxLen = 0;
724 
725   for (auto const &I: DiagsInGroup)
726     MaxLen = std::max(MaxLen, (unsigned)I.first.size());
727 
728   OS << "\n#ifdef GET_DIAG_TABLE\n";
729   unsigned SubGroupIndex = 1, DiagArrayIndex = 1;
730   for (auto const &I: DiagsInGroup) {
731     // Group option string.
732     OS << "  { /* ";
733     if (I.first.find_first_not_of("abcdefghijklmnopqrstuvwxyz"
734                                    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
735                                    "0123456789!@#$%^*-+=:?") !=
736         std::string::npos)
737       PrintFatalError("Invalid character in diagnostic group '" + I.first +
738                       "'");
739     OS << I.first << " */ " << std::string(MaxLen - I.first.size(), ' ');
740     // Store a pascal-style length byte at the beginning of the string.
741     std::string Name = char(I.first.size()) + I.first;
742     OS << GroupNames.GetOrAddStringOffset(Name, false) << ", ";
743 
744     // Special handling for 'pedantic'.
745     const bool IsPedantic = I.first == "pedantic";
746 
747     // Diagnostics in the group.
748     const std::vector<const Record *> &V = I.second.DiagsInGroup;
749     const bool hasDiags =
750         !V.empty() || (IsPedantic && !DiagsInPedantic.empty());
751     if (hasDiags) {
752       OS << "/* DiagArray" << I.second.IDNo << " */ " << DiagArrayIndex
753          << ", ";
754       if (IsPedantic)
755         DiagArrayIndex += DiagsInPedantic.size();
756       DiagArrayIndex += V.size() + 1;
757     } else {
758       OS << "/* Empty */     0, ";
759     }
760 
761     // Subgroups.
762     const std::vector<std::string> &SubGroups = I.second.SubGroups;
763     const bool hasSubGroups =
764         !SubGroups.empty() || (IsPedantic && !GroupsInPedantic.empty());
765     if (hasSubGroups) {
766       OS << "/* DiagSubGroup" << I.second.IDNo << " */ " << SubGroupIndex;
767       if (IsPedantic)
768         SubGroupIndex += GroupsInPedantic.size();
769       SubGroupIndex += SubGroups.size() + 1;
770     } else {
771       OS << "/* Empty */         0";
772     }
773 
774     OS << " },\n";
775   }
776   OS << "#endif // GET_DIAG_TABLE\n\n";
777 }
778 
779 /// \brief Emit the table of diagnostic categories.
780 ///
781 /// The table has the form of macro calls that have two parameters. The
782 /// category's name as well as an enum that represents the category. The
783 /// table can be used by defining the macro 'CATEGORY' and including this
784 /// table right after.
785 ///
786 /// \code
787 /// #ifdef GET_CATEGORY_TABLE
788 ///   CATEGORY("Semantic Issue", DiagCat_Semantic_Issue)
789 ///   CATEGORY("Lambda Issue", DiagCat_Lambda_Issue)
790 /// #endif
791 /// \endcode
792 static void emitCategoryTable(RecordKeeper &Records, raw_ostream &OS) {
793   DiagCategoryIDMap CategoriesByID(Records);
794   OS << "\n#ifdef GET_CATEGORY_TABLE\n";
795   for (auto const &C : CategoriesByID)
796     OS << "CATEGORY(\"" << C << "\", " << getDiagCategoryEnum(C) << ")\n";
797   OS << "#endif // GET_CATEGORY_TABLE\n\n";
798 }
799 
800 namespace clang {
801 void EmitClangDiagGroups(RecordKeeper &Records, raw_ostream &OS) {
802   // Compute a mapping from a DiagGroup to all of its parents.
803   DiagGroupParentMap DGParentMap(Records);
804 
805   std::vector<Record *> Diags = Records.getAllDerivedDefinitions("Diagnostic");
806 
807   std::vector<Record *> DiagGroups =
808       Records.getAllDerivedDefinitions("DiagGroup");
809 
810   std::map<std::string, GroupInfo> DiagsInGroup;
811   groupDiagnostics(Diags, DiagGroups, DiagsInGroup);
812 
813   // All extensions are implicitly in the "pedantic" group.  Record the
814   // implicit set of groups in the "pedantic" group, and use this information
815   // later when emitting the group information for Pedantic.
816   RecordVec DiagsInPedantic;
817   RecordVec GroupsInPedantic;
818   InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup);
819   inferPedantic.compute(&DiagsInPedantic, &GroupsInPedantic);
820 
821   StringToOffsetTable GroupNames;
822   for (std::map<std::string, GroupInfo>::const_iterator
823            I = DiagsInGroup.begin(),
824            E = DiagsInGroup.end();
825        I != E; ++I) {
826     // Store a pascal-style length byte at the beginning of the string.
827     std::string Name = char(I->first.size()) + I->first;
828     GroupNames.GetOrAddStringOffset(Name, false);
829   }
830 
831   emitAllDiagArrays(DiagsInGroup, DiagsInPedantic, GroupsInPedantic, GroupNames,
832                     OS);
833   emitDiagTable(DiagsInGroup, DiagsInPedantic, GroupsInPedantic, GroupNames,
834                 OS);
835   emitCategoryTable(Records, OS);
836 }
837 } // end namespace clang
838 
839 //===----------------------------------------------------------------------===//
840 // Diagnostic name index generation
841 //===----------------------------------------------------------------------===//
842 
843 namespace {
844 struct RecordIndexElement
845 {
846   RecordIndexElement() {}
847   explicit RecordIndexElement(Record const &R):
848     Name(R.getName()) {}
849 
850   std::string Name;
851 };
852 } // end anonymous namespace.
853 
854 namespace clang {
855 void EmitClangDiagsIndexName(RecordKeeper &Records, raw_ostream &OS) {
856   const std::vector<Record*> &Diags =
857     Records.getAllDerivedDefinitions("Diagnostic");
858 
859   std::vector<RecordIndexElement> Index;
860   Index.reserve(Diags.size());
861   for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
862     const Record &R = *(Diags[i]);
863     Index.push_back(RecordIndexElement(R));
864   }
865 
866   llvm::sort(Index.begin(), Index.end(),
867              [](const RecordIndexElement &Lhs, const RecordIndexElement &Rhs) {
868                return Lhs.Name < Rhs.Name;
869             });
870 
871   for (unsigned i = 0, e = Index.size(); i != e; ++i) {
872     const RecordIndexElement &R = Index[i];
873 
874     OS << "DIAG_NAME_INDEX(" << R.Name << ")\n";
875   }
876 }
877 
878 //===----------------------------------------------------------------------===//
879 // Diagnostic documentation generation
880 //===----------------------------------------------------------------------===//
881 
882 namespace docs {
883 namespace {
884 
885 /// Diagnostic text, parsed into pieces.
886 struct DiagText {
887   struct Piece {
888     // This type and its derived classes are move-only.
889     Piece() {}
890     Piece(Piece &&O) {}
891     Piece &operator=(Piece &&O) { return *this; }
892 
893     virtual void print(std::vector<std::string> &RST) = 0;
894     virtual ~Piece() {}
895   };
896   struct TextPiece : Piece {
897     StringRef Role;
898     std::string Text;
899     void print(std::vector<std::string> &RST) override;
900   };
901   struct PlaceholderPiece : Piece {
902     int Index;
903     void print(std::vector<std::string> &RST) override;
904   };
905   struct SelectPiece : Piece {
906     SelectPiece() {}
907     SelectPiece(SelectPiece &&O) noexcept : Options(std::move(O.Options)) {}
908     std::vector<DiagText> Options;
909     void print(std::vector<std::string> &RST) override;
910   };
911 
912   std::vector<std::unique_ptr<Piece>> Pieces;
913 
914   DiagText();
915   DiagText(DiagText &&O) noexcept : Pieces(std::move(O.Pieces)) {}
916 
917   DiagText(StringRef Text);
918   DiagText(StringRef Kind, StringRef Text);
919 
920   template<typename P> void add(P Piece) {
921     Pieces.push_back(llvm::make_unique<P>(std::move(Piece)));
922   }
923   void print(std::vector<std::string> &RST);
924 };
925 
926 DiagText parseDiagText(StringRef &Text, bool Nested = false) {
927   DiagText Parsed;
928 
929   while (!Text.empty()) {
930     size_t End = (size_t)-2;
931     do
932       End = Nested ? Text.find_first_of("%|}", End + 2)
933                    : Text.find_first_of('%', End + 2);
934     while (End < Text.size() - 1 && Text[End] == '%' && Text[End + 1] == '%');
935 
936     if (End) {
937       DiagText::TextPiece Piece;
938       Piece.Role = "diagtext";
939       Piece.Text = Text.slice(0, End);
940       Parsed.add(std::move(Piece));
941       Text = Text.slice(End, StringRef::npos);
942       if (Text.empty()) break;
943     }
944 
945     if (Text[0] == '|' || Text[0] == '}')
946       break;
947 
948     // Drop the '%'.
949     Text = Text.drop_front();
950 
951     // Extract the (optional) modifier.
952     size_t ModLength = Text.find_first_of("0123456789{");
953     StringRef Modifier = Text.slice(0, ModLength);
954     Text = Text.slice(ModLength, StringRef::npos);
955 
956     // FIXME: Handle %ordinal here.
957     if (Modifier == "select" || Modifier == "plural") {
958       DiagText::SelectPiece Select;
959       do {
960         Text = Text.drop_front();
961         if (Modifier == "plural")
962           while (Text[0] != ':')
963             Text = Text.drop_front();
964         Select.Options.push_back(parseDiagText(Text, true));
965         assert(!Text.empty() && "malformed %select");
966       } while (Text.front() == '|');
967       Parsed.add(std::move(Select));
968 
969       // Drop the trailing '}n'.
970       Text = Text.drop_front(2);
971       continue;
972     }
973 
974     // For %diff, just take the second alternative (tree diagnostic). It would
975     // be preferable to take the first one, and replace the $ with the suitable
976     // placeholders.
977     if (Modifier == "diff") {
978       Text = Text.drop_front(); // '{'
979       parseDiagText(Text, true);
980       Text = Text.drop_front(); // '|'
981 
982       DiagText D = parseDiagText(Text, true);
983       for (auto &P : D.Pieces)
984         Parsed.Pieces.push_back(std::move(P));
985 
986       Text = Text.drop_front(4); // '}n,m'
987       continue;
988     }
989 
990     if (Modifier == "s") {
991       Text = Text.drop_front();
992       DiagText::SelectPiece Select;
993       Select.Options.push_back(DiagText(""));
994       Select.Options.push_back(DiagText("s"));
995       Parsed.add(std::move(Select));
996       continue;
997     }
998 
999     assert(!Text.empty() && isdigit(Text[0]) && "malformed placeholder");
1000     DiagText::PlaceholderPiece Placeholder;
1001     Placeholder.Index = Text[0] - '0';
1002     Parsed.add(std::move(Placeholder));
1003     Text = Text.drop_front();
1004     continue;
1005   }
1006   return Parsed;
1007 }
1008 
1009 DiagText::DiagText() {}
1010 
1011 DiagText::DiagText(StringRef Text) : DiagText(parseDiagText(Text, false)) {}
1012 
1013 DiagText::DiagText(StringRef Kind, StringRef Text) : DiagText(parseDiagText(Text, false)) {
1014   TextPiece Prefix;
1015   Prefix.Role = Kind;
1016   Prefix.Text = Kind;
1017   Prefix.Text += ": ";
1018   Pieces.insert(Pieces.begin(),
1019                 llvm::make_unique<TextPiece>(std::move(Prefix)));
1020 }
1021 
1022 void escapeRST(StringRef Str, std::string &Out) {
1023   for (auto K : Str) {
1024     if (StringRef("`*|_[]\\").count(K))
1025       Out.push_back('\\');
1026     Out.push_back(K);
1027   }
1028 }
1029 
1030 template<typename It> void padToSameLength(It Begin, It End) {
1031   size_t Width = 0;
1032   for (It I = Begin; I != End; ++I)
1033     Width = std::max(Width, I->size());
1034   for (It I = Begin; I != End; ++I)
1035     (*I) += std::string(Width - I->size(), ' ');
1036 }
1037 
1038 template<typename It> void makeTableRows(It Begin, It End) {
1039   if (Begin == End) return;
1040   padToSameLength(Begin, End);
1041   for (It I = Begin; I != End; ++I)
1042     *I = "|" + *I + "|";
1043 }
1044 
1045 void makeRowSeparator(std::string &Str) {
1046   for (char &K : Str)
1047     K = (K == '|' ? '+' : '-');
1048 }
1049 
1050 void DiagText::print(std::vector<std::string> &RST) {
1051   if (Pieces.empty()) {
1052     RST.push_back("");
1053     return;
1054   }
1055 
1056   if (Pieces.size() == 1)
1057     return Pieces[0]->print(RST);
1058 
1059   std::string EmptyLinePrefix;
1060   size_t Start = RST.size();
1061   bool HasMultipleLines = true;
1062   for (auto &P : Pieces) {
1063     std::vector<std::string> Lines;
1064     P->print(Lines);
1065     if (Lines.empty())
1066       continue;
1067 
1068     // We need a vertical separator if either this or the previous piece is a
1069     // multi-line piece, or this is the last piece.
1070     const char *Separator = (Lines.size() > 1 || HasMultipleLines) ? "|" : "";
1071     HasMultipleLines = Lines.size() > 1;
1072 
1073     if (Start + Lines.size() > RST.size())
1074       RST.resize(Start + Lines.size(), EmptyLinePrefix);
1075 
1076     padToSameLength(Lines.begin(), Lines.end());
1077     for (size_t I = 0; I != Lines.size(); ++I)
1078       RST[Start + I] += Separator + Lines[I];
1079     std::string Empty(Lines[0].size(), ' ');
1080     for (size_t I = Start + Lines.size(); I != RST.size(); ++I)
1081       RST[I] += Separator + Empty;
1082     EmptyLinePrefix += Separator + Empty;
1083   }
1084   for (size_t I = Start; I != RST.size(); ++I)
1085     RST[I] += "|";
1086   EmptyLinePrefix += "|";
1087 
1088   makeRowSeparator(EmptyLinePrefix);
1089   RST.insert(RST.begin() + Start, EmptyLinePrefix);
1090   RST.insert(RST.end(), EmptyLinePrefix);
1091 }
1092 
1093 void DiagText::TextPiece::print(std::vector<std::string> &RST) {
1094   RST.push_back("");
1095   auto &S = RST.back();
1096 
1097   StringRef T = Text;
1098   while (!T.empty() && T.front() == ' ') {
1099     RST.back() += " |nbsp| ";
1100     T = T.drop_front();
1101   }
1102 
1103   std::string Suffix;
1104   while (!T.empty() && T.back() == ' ') {
1105     Suffix += " |nbsp| ";
1106     T = T.drop_back();
1107   }
1108 
1109   if (!T.empty()) {
1110     S += ':';
1111     S += Role;
1112     S += ":`";
1113     escapeRST(T, S);
1114     S += '`';
1115   }
1116 
1117   S += Suffix;
1118 }
1119 
1120 void DiagText::PlaceholderPiece::print(std::vector<std::string> &RST) {
1121   RST.push_back(std::string(":placeholder:`") + char('A' + Index) + "`");
1122 }
1123 
1124 void DiagText::SelectPiece::print(std::vector<std::string> &RST) {
1125   std::vector<size_t> SeparatorIndexes;
1126   SeparatorIndexes.push_back(RST.size());
1127   RST.emplace_back();
1128   for (auto &O : Options) {
1129     O.print(RST);
1130     SeparatorIndexes.push_back(RST.size());
1131     RST.emplace_back();
1132   }
1133 
1134   makeTableRows(RST.begin() + SeparatorIndexes.front(),
1135                 RST.begin() + SeparatorIndexes.back() + 1);
1136   for (size_t I : SeparatorIndexes)
1137     makeRowSeparator(RST[I]);
1138 }
1139 
1140 bool isRemarkGroup(const Record *DiagGroup,
1141                    const std::map<std::string, GroupInfo> &DiagsInGroup) {
1142   bool AnyRemarks = false, AnyNonRemarks = false;
1143 
1144   std::function<void(StringRef)> Visit = [&](StringRef GroupName) {
1145     auto &GroupInfo = DiagsInGroup.find(GroupName)->second;
1146     for (const Record *Diag : GroupInfo.DiagsInGroup)
1147       (isRemark(*Diag) ? AnyRemarks : AnyNonRemarks) = true;
1148     for (const auto &Name : GroupInfo.SubGroups)
1149       Visit(Name);
1150   };
1151   Visit(DiagGroup->getValueAsString("GroupName"));
1152 
1153   if (AnyRemarks && AnyNonRemarks)
1154     PrintFatalError(
1155         DiagGroup->getLoc(),
1156         "Diagnostic group contains both remark and non-remark diagnostics");
1157   return AnyRemarks;
1158 }
1159 
1160 std::string getDefaultSeverity(const Record *Diag) {
1161   return Diag->getValueAsDef("DefaultSeverity")->getValueAsString("Name");
1162 }
1163 
1164 std::set<std::string>
1165 getDefaultSeverities(const Record *DiagGroup,
1166                      const std::map<std::string, GroupInfo> &DiagsInGroup) {
1167   std::set<std::string> States;
1168 
1169   std::function<void(StringRef)> Visit = [&](StringRef GroupName) {
1170     auto &GroupInfo = DiagsInGroup.find(GroupName)->second;
1171     for (const Record *Diag : GroupInfo.DiagsInGroup)
1172       States.insert(getDefaultSeverity(Diag));
1173     for (const auto &Name : GroupInfo.SubGroups)
1174       Visit(Name);
1175   };
1176   Visit(DiagGroup->getValueAsString("GroupName"));
1177   return States;
1178 }
1179 
1180 void writeHeader(StringRef Str, raw_ostream &OS, char Kind = '-') {
1181   OS << Str << "\n" << std::string(Str.size(), Kind) << "\n";
1182 }
1183 
1184 void writeDiagnosticText(StringRef Role, StringRef Text, raw_ostream &OS) {
1185   if (Text == "%0")
1186     OS << "The text of this diagnostic is not controlled by Clang.\n\n";
1187   else {
1188     std::vector<std::string> Out;
1189     DiagText(Role, Text).print(Out);
1190     for (auto &Line : Out)
1191       OS << Line << "\n";
1192     OS << "\n";
1193   }
1194 }
1195 
1196 }  // namespace
1197 }  // namespace docs
1198 
1199 void EmitClangDiagDocs(RecordKeeper &Records, raw_ostream &OS) {
1200   using namespace docs;
1201 
1202   // Get the documentation introduction paragraph.
1203   const Record *Documentation = Records.getDef("GlobalDocumentation");
1204   if (!Documentation) {
1205     PrintFatalError("The Documentation top-level definition is missing, "
1206                     "no documentation will be generated.");
1207     return;
1208   }
1209 
1210   OS << Documentation->getValueAsString("Intro") << "\n";
1211 
1212   std::vector<Record*> Diags =
1213       Records.getAllDerivedDefinitions("Diagnostic");
1214   std::vector<Record*> DiagGroups =
1215       Records.getAllDerivedDefinitions("DiagGroup");
1216   llvm::sort(DiagGroups.begin(), DiagGroups.end(), diagGroupBeforeByName);
1217 
1218   DiagGroupParentMap DGParentMap(Records);
1219 
1220   std::map<std::string, GroupInfo> DiagsInGroup;
1221   groupDiagnostics(Diags, DiagGroups, DiagsInGroup);
1222 
1223   // Compute the set of diagnostics that are in -Wpedantic.
1224   {
1225     RecordSet DiagsInPedanticSet;
1226     RecordSet GroupsInPedanticSet;
1227     InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup);
1228     inferPedantic.compute(&DiagsInPedanticSet, &GroupsInPedanticSet);
1229     auto &PedDiags = DiagsInGroup["pedantic"];
1230     // Put the diagnostics into a deterministic order.
1231     RecordVec DiagsInPedantic(DiagsInPedanticSet.begin(),
1232                               DiagsInPedanticSet.end());
1233     RecordVec GroupsInPedantic(GroupsInPedanticSet.begin(),
1234                                GroupsInPedanticSet.end());
1235     llvm::sort(DiagsInPedantic.begin(), DiagsInPedantic.end(),
1236                beforeThanCompare);
1237     llvm::sort(GroupsInPedantic.begin(), GroupsInPedantic.end(),
1238                beforeThanCompare);
1239     PedDiags.DiagsInGroup.insert(PedDiags.DiagsInGroup.end(),
1240                                  DiagsInPedantic.begin(),
1241                                  DiagsInPedantic.end());
1242     for (auto *Group : GroupsInPedantic)
1243       PedDiags.SubGroups.push_back(Group->getValueAsString("GroupName"));
1244   }
1245 
1246   // FIXME: Write diagnostic categories and link to diagnostic groups in each.
1247 
1248   // Write out the diagnostic groups.
1249   for (const Record *G : DiagGroups) {
1250     bool IsRemarkGroup = isRemarkGroup(G, DiagsInGroup);
1251     auto &GroupInfo = DiagsInGroup[G->getValueAsString("GroupName")];
1252     bool IsSynonym = GroupInfo.DiagsInGroup.empty() &&
1253                      GroupInfo.SubGroups.size() == 1;
1254 
1255     writeHeader(((IsRemarkGroup ? "-R" : "-W") +
1256                     G->getValueAsString("GroupName")).str(),
1257                 OS);
1258 
1259     if (!IsSynonym) {
1260       // FIXME: Ideally, all the diagnostics in a group should have the same
1261       // default state, but that is not currently the case.
1262       auto DefaultSeverities = getDefaultSeverities(G, DiagsInGroup);
1263       if (!DefaultSeverities.empty() && !DefaultSeverities.count("Ignored")) {
1264         bool AnyNonErrors = DefaultSeverities.count("Warning") ||
1265                             DefaultSeverities.count("Remark");
1266         if (!AnyNonErrors)
1267           OS << "This diagnostic is an error by default, but the flag ``-Wno-"
1268              << G->getValueAsString("GroupName") << "`` can be used to disable "
1269              << "the error.\n\n";
1270         else
1271           OS << "This diagnostic is enabled by default.\n\n";
1272       } else if (DefaultSeverities.size() > 1) {
1273         OS << "Some of the diagnostics controlled by this flag are enabled "
1274            << "by default.\n\n";
1275       }
1276     }
1277 
1278     if (!GroupInfo.SubGroups.empty()) {
1279       if (IsSynonym)
1280         OS << "Synonym for ";
1281       else if (GroupInfo.DiagsInGroup.empty())
1282         OS << "Controls ";
1283       else
1284         OS << "Also controls ";
1285 
1286       bool First = true;
1287       llvm::sort(GroupInfo.SubGroups.begin(), GroupInfo.SubGroups.end());
1288       for (const auto &Name : GroupInfo.SubGroups) {
1289         if (!First) OS << ", ";
1290         OS << "`" << (IsRemarkGroup ? "-R" : "-W") << Name << "`_";
1291         First = false;
1292       }
1293       OS << ".\n\n";
1294     }
1295 
1296     if (!GroupInfo.DiagsInGroup.empty()) {
1297       OS << "**Diagnostic text:**\n\n";
1298       for (const Record *D : GroupInfo.DiagsInGroup) {
1299         auto Severity = getDefaultSeverity(D);
1300         Severity[0] = tolower(Severity[0]);
1301         if (Severity == "ignored")
1302           Severity = IsRemarkGroup ? "remark" : "warning";
1303         writeDiagnosticText(Severity, D->getValueAsString("Text"), OS);
1304       }
1305     }
1306 
1307     auto Doc = G->getValueAsString("Documentation");
1308     if (!Doc.empty())
1309       OS << Doc;
1310     else if (GroupInfo.SubGroups.empty() && GroupInfo.DiagsInGroup.empty())
1311       OS << "This diagnostic flag exists for GCC compatibility, and has no "
1312             "effect in Clang.\n";
1313     OS << "\n";
1314   }
1315 }
1316 
1317 } // end namespace clang
1318