1 //=- ClangDiagnosticsEmitter.cpp - Generate Clang diagnostics tables -*- C++ -*-
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // These tablegen backends emit Clang diagnostics tables.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "TableGenBackends.h"
14 #include "llvm/ADT/DenseSet.h"
15 #include "llvm/ADT/Optional.h"
16 #include "llvm/ADT/PointerUnion.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallPtrSet.h"
19 #include "llvm/ADT/SmallString.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/StringMap.h"
22 #include "llvm/ADT/Twine.h"
23 #include "llvm/Support/Casting.h"
24 #include "llvm/TableGen/Error.h"
25 #include "llvm/TableGen/Record.h"
26 #include "llvm/TableGen/StringToOffsetTable.h"
27 #include "llvm/TableGen/TableGenBackend.h"
28 #include <algorithm>
29 #include <cctype>
30 #include <functional>
31 #include <map>
32 #include <set>
33 using namespace llvm;
34 
35 //===----------------------------------------------------------------------===//
36 // Diagnostic category computation code.
37 //===----------------------------------------------------------------------===//
38 
39 namespace {
40 class DiagGroupParentMap {
41   RecordKeeper &Records;
42   std::map<const Record*, std::vector<Record*> > Mapping;
43 public:
44   DiagGroupParentMap(RecordKeeper &records) : Records(records) {
45     std::vector<Record*> DiagGroups
46       = Records.getAllDerivedDefinitions("DiagGroup");
47     for (unsigned i = 0, e = DiagGroups.size(); i != e; ++i) {
48       std::vector<Record*> SubGroups =
49         DiagGroups[i]->getValueAsListOfDefs("SubGroups");
50       for (unsigned j = 0, e = SubGroups.size(); j != e; ++j)
51         Mapping[SubGroups[j]].push_back(DiagGroups[i]);
52     }
53   }
54 
55   const std::vector<Record*> &getParents(const Record *Group) {
56     return Mapping[Group];
57   }
58 };
59 } // end anonymous namespace.
60 
61 static std::string
62 getCategoryFromDiagGroup(const Record *Group,
63                          DiagGroupParentMap &DiagGroupParents) {
64   // If the DiagGroup has a category, return it.
65   std::string CatName = Group->getValueAsString("CategoryName");
66   if (!CatName.empty()) return CatName;
67 
68   // The diag group may the subgroup of one or more other diagnostic groups,
69   // check these for a category as well.
70   const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group);
71   for (unsigned i = 0, e = Parents.size(); i != e; ++i) {
72     CatName = getCategoryFromDiagGroup(Parents[i], DiagGroupParents);
73     if (!CatName.empty()) return CatName;
74   }
75   return "";
76 }
77 
78 /// getDiagnosticCategory - Return the category that the specified diagnostic
79 /// lives in.
80 static std::string getDiagnosticCategory(const Record *R,
81                                          DiagGroupParentMap &DiagGroupParents) {
82   // If the diagnostic is in a group, and that group has a category, use it.
83   if (DefInit *Group = dyn_cast<DefInit>(R->getValueInit("Group"))) {
84     // Check the diagnostic's diag group for a category.
85     std::string CatName = getCategoryFromDiagGroup(Group->getDef(),
86                                                    DiagGroupParents);
87     if (!CatName.empty()) return CatName;
88   }
89 
90   // If the diagnostic itself has a category, get it.
91   return R->getValueAsString("CategoryName");
92 }
93 
94 namespace {
95   class DiagCategoryIDMap {
96     RecordKeeper &Records;
97     StringMap<unsigned> CategoryIDs;
98     std::vector<std::string> CategoryStrings;
99   public:
100     DiagCategoryIDMap(RecordKeeper &records) : Records(records) {
101       DiagGroupParentMap ParentInfo(Records);
102 
103       // The zero'th category is "".
104       CategoryStrings.push_back("");
105       CategoryIDs[""] = 0;
106 
107       std::vector<Record*> Diags =
108       Records.getAllDerivedDefinitions("Diagnostic");
109       for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
110         std::string Category = getDiagnosticCategory(Diags[i], ParentInfo);
111         if (Category.empty()) continue;  // Skip diags with no category.
112 
113         unsigned &ID = CategoryIDs[Category];
114         if (ID != 0) continue;  // Already seen.
115 
116         ID = CategoryStrings.size();
117         CategoryStrings.push_back(Category);
118       }
119     }
120 
121     unsigned getID(StringRef CategoryString) {
122       return CategoryIDs[CategoryString];
123     }
124 
125     typedef std::vector<std::string>::const_iterator const_iterator;
126     const_iterator begin() const { return CategoryStrings.begin(); }
127     const_iterator end() const { return CategoryStrings.end(); }
128   };
129 
130   struct GroupInfo {
131     std::vector<const Record*> DiagsInGroup;
132     std::vector<std::string> SubGroups;
133     unsigned IDNo;
134 
135     const Record *ExplicitDef;
136 
137     GroupInfo() : IDNo(0), ExplicitDef(nullptr) {}
138   };
139 } // end anonymous namespace.
140 
141 static bool beforeThanCompare(const Record *LHS, const Record *RHS) {
142   assert(!LHS->getLoc().empty() && !RHS->getLoc().empty());
143   return
144     LHS->getLoc().front().getPointer() < RHS->getLoc().front().getPointer();
145 }
146 
147 static bool diagGroupBeforeByName(const Record *LHS, const Record *RHS) {
148   return LHS->getValueAsString("GroupName") <
149          RHS->getValueAsString("GroupName");
150 }
151 
152 static bool beforeThanCompareGroups(const GroupInfo *LHS, const GroupInfo *RHS){
153   assert(!LHS->DiagsInGroup.empty() && !RHS->DiagsInGroup.empty());
154   return beforeThanCompare(LHS->DiagsInGroup.front(),
155                            RHS->DiagsInGroup.front());
156 }
157 
158 /// Invert the 1-[0/1] mapping of diags to group into a one to many
159 /// mapping of groups to diags in the group.
160 static void groupDiagnostics(const std::vector<Record*> &Diags,
161                              const std::vector<Record*> &DiagGroups,
162                              std::map<std::string, GroupInfo> &DiagsInGroup) {
163 
164   for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
165     const Record *R = Diags[i];
166     DefInit *DI = dyn_cast<DefInit>(R->getValueInit("Group"));
167     if (!DI)
168       continue;
169     assert(R->getValueAsDef("Class")->getName() != "CLASS_NOTE" &&
170            "Note can't be in a DiagGroup");
171     std::string GroupName = DI->getDef()->getValueAsString("GroupName");
172     DiagsInGroup[GroupName].DiagsInGroup.push_back(R);
173   }
174 
175   typedef SmallPtrSet<GroupInfo *, 16> GroupSetTy;
176   GroupSetTy ImplicitGroups;
177 
178   // Add all DiagGroup's to the DiagsInGroup list to make sure we pick up empty
179   // groups (these are warnings that GCC supports that clang never produces).
180   for (unsigned i = 0, e = DiagGroups.size(); i != e; ++i) {
181     Record *Group = DiagGroups[i];
182     GroupInfo &GI = DiagsInGroup[Group->getValueAsString("GroupName")];
183     if (Group->isAnonymous()) {
184       if (GI.DiagsInGroup.size() > 1)
185         ImplicitGroups.insert(&GI);
186     } else {
187       if (GI.ExplicitDef)
188         assert(GI.ExplicitDef == Group);
189       else
190         GI.ExplicitDef = Group;
191     }
192 
193     std::vector<Record*> SubGroups = Group->getValueAsListOfDefs("SubGroups");
194     for (unsigned j = 0, e = SubGroups.size(); j != e; ++j)
195       GI.SubGroups.push_back(SubGroups[j]->getValueAsString("GroupName"));
196   }
197 
198   // Assign unique ID numbers to the groups.
199   unsigned IDNo = 0;
200   for (std::map<std::string, GroupInfo>::iterator
201        I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I, ++IDNo)
202     I->second.IDNo = IDNo;
203 
204   // Sort the implicit groups, so we can warn about them deterministically.
205   SmallVector<GroupInfo *, 16> SortedGroups(ImplicitGroups.begin(),
206                                             ImplicitGroups.end());
207   for (SmallVectorImpl<GroupInfo *>::iterator I = SortedGroups.begin(),
208                                               E = SortedGroups.end();
209        I != E; ++I) {
210     MutableArrayRef<const Record *> GroupDiags = (*I)->DiagsInGroup;
211     llvm::sort(GroupDiags, beforeThanCompare);
212   }
213   llvm::sort(SortedGroups, beforeThanCompareGroups);
214 
215   // Warn about the same group being used anonymously in multiple places.
216   for (SmallVectorImpl<GroupInfo *>::const_iterator I = SortedGroups.begin(),
217                                                     E = SortedGroups.end();
218        I != E; ++I) {
219     ArrayRef<const Record *> GroupDiags = (*I)->DiagsInGroup;
220 
221     if ((*I)->ExplicitDef) {
222       std::string Name = (*I)->ExplicitDef->getValueAsString("GroupName");
223       for (ArrayRef<const Record *>::const_iterator DI = GroupDiags.begin(),
224                                                     DE = GroupDiags.end();
225            DI != DE; ++DI) {
226         const DefInit *GroupInit = cast<DefInit>((*DI)->getValueInit("Group"));
227         const Record *NextDiagGroup = GroupInit->getDef();
228         if (NextDiagGroup == (*I)->ExplicitDef)
229           continue;
230 
231         SrcMgr.PrintMessage((*DI)->getLoc().front(),
232                             SourceMgr::DK_Error,
233                             Twine("group '") + Name +
234                               "' is referred to anonymously");
235         SrcMgr.PrintMessage((*I)->ExplicitDef->getLoc().front(),
236                             SourceMgr::DK_Note, "group defined here");
237       }
238     } else {
239       // If there's no existing named group, we should just warn once and use
240       // notes to list all the other cases.
241       ArrayRef<const Record *>::const_iterator DI = GroupDiags.begin(),
242                                                DE = GroupDiags.end();
243       assert(DI != DE && "We only care about groups with multiple uses!");
244 
245       const DefInit *GroupInit = cast<DefInit>((*DI)->getValueInit("Group"));
246       const Record *NextDiagGroup = GroupInit->getDef();
247       std::string Name = NextDiagGroup->getValueAsString("GroupName");
248 
249       SrcMgr.PrintMessage((*DI)->getLoc().front(),
250                           SourceMgr::DK_Error,
251                           Twine("group '") + Name +
252                             "' is referred to anonymously");
253 
254       for (++DI; DI != DE; ++DI) {
255         SrcMgr.PrintMessage((*DI)->getLoc().front(),
256                             SourceMgr::DK_Note, "also referenced here");
257       }
258     }
259   }
260 }
261 
262 //===----------------------------------------------------------------------===//
263 // Infer members of -Wpedantic.
264 //===----------------------------------------------------------------------===//
265 
266 typedef std::vector<const Record *> RecordVec;
267 typedef llvm::DenseSet<const Record *> RecordSet;
268 typedef llvm::PointerUnion<RecordVec*, RecordSet*> VecOrSet;
269 
270 namespace {
271 class InferPedantic {
272   typedef llvm::DenseMap<const Record*,
273                          std::pair<unsigned, Optional<unsigned> > > GMap;
274 
275   DiagGroupParentMap &DiagGroupParents;
276   const std::vector<Record*> &Diags;
277   const std::vector<Record*> DiagGroups;
278   std::map<std::string, GroupInfo> &DiagsInGroup;
279   llvm::DenseSet<const Record*> DiagsSet;
280   GMap GroupCount;
281 public:
282   InferPedantic(DiagGroupParentMap &DiagGroupParents,
283                 const std::vector<Record*> &Diags,
284                 const std::vector<Record*> &DiagGroups,
285                 std::map<std::string, GroupInfo> &DiagsInGroup)
286   : DiagGroupParents(DiagGroupParents),
287   Diags(Diags),
288   DiagGroups(DiagGroups),
289   DiagsInGroup(DiagsInGroup) {}
290 
291   /// Compute the set of diagnostics and groups that are immediately
292   /// in -Wpedantic.
293   void compute(VecOrSet DiagsInPedantic,
294                VecOrSet GroupsInPedantic);
295 
296 private:
297   /// Determine whether a group is a subgroup of another group.
298   bool isSubGroupOfGroup(const Record *Group,
299                          llvm::StringRef RootGroupName);
300 
301   /// Determine if the diagnostic is an extension.
302   bool isExtension(const Record *Diag);
303 
304   /// Determine if the diagnostic is off by default.
305   bool isOffByDefault(const Record *Diag);
306 
307   /// Increment the count for a group, and transitively marked
308   /// parent groups when appropriate.
309   void markGroup(const Record *Group);
310 
311   /// Return true if the diagnostic is in a pedantic group.
312   bool groupInPedantic(const Record *Group, bool increment = false);
313 };
314 } // end anonymous namespace
315 
316 bool InferPedantic::isSubGroupOfGroup(const Record *Group,
317                                       llvm::StringRef GName) {
318 
319   const std::string &GroupName = Group->getValueAsString("GroupName");
320   if (GName == GroupName)
321     return true;
322 
323   const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group);
324   for (unsigned i = 0, e = Parents.size(); i != e; ++i)
325     if (isSubGroupOfGroup(Parents[i], GName))
326       return true;
327 
328   return false;
329 }
330 
331 /// Determine if the diagnostic is an extension.
332 bool InferPedantic::isExtension(const Record *Diag) {
333   const std::string &ClsName = Diag->getValueAsDef("Class")->getName();
334   return ClsName == "CLASS_EXTENSION";
335 }
336 
337 bool InferPedantic::isOffByDefault(const Record *Diag) {
338   const std::string &DefSeverity =
339       Diag->getValueAsDef("DefaultSeverity")->getValueAsString("Name");
340   return DefSeverity == "Ignored";
341 }
342 
343 bool InferPedantic::groupInPedantic(const Record *Group, bool increment) {
344   GMap::mapped_type &V = GroupCount[Group];
345   // Lazily compute the threshold value for the group count.
346   if (!V.second.hasValue()) {
347     const GroupInfo &GI = DiagsInGroup[Group->getValueAsString("GroupName")];
348     V.second = GI.SubGroups.size() + GI.DiagsInGroup.size();
349   }
350 
351   if (increment)
352     ++V.first;
353 
354   // Consider a group in -Wpendatic IFF if has at least one diagnostic
355   // or subgroup AND all of those diagnostics and subgroups are covered
356   // by -Wpedantic via our computation.
357   return V.first != 0 && V.first == V.second.getValue();
358 }
359 
360 void InferPedantic::markGroup(const Record *Group) {
361   // If all the diagnostics and subgroups have been marked as being
362   // covered by -Wpedantic, increment the count of parent groups.  Once the
363   // group's count is equal to the number of subgroups and diagnostics in
364   // that group, we can safely add this group to -Wpedantic.
365   if (groupInPedantic(Group, /* increment */ true)) {
366     const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group);
367     for (unsigned i = 0, e = Parents.size(); i != e; ++i)
368       markGroup(Parents[i]);
369   }
370 }
371 
372 void InferPedantic::compute(VecOrSet DiagsInPedantic,
373                             VecOrSet GroupsInPedantic) {
374   // All extensions that are not on by default are implicitly in the
375   // "pedantic" group.  For those that aren't explicitly included in -Wpedantic,
376   // mark them for consideration to be included in -Wpedantic directly.
377   for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
378     Record *R = Diags[i];
379     if (isExtension(R) && isOffByDefault(R)) {
380       DiagsSet.insert(R);
381       if (DefInit *Group = dyn_cast<DefInit>(R->getValueInit("Group"))) {
382         const Record *GroupRec = Group->getDef();
383         if (!isSubGroupOfGroup(GroupRec, "pedantic")) {
384           markGroup(GroupRec);
385         }
386       }
387     }
388   }
389 
390   // Compute the set of diagnostics that are directly in -Wpedantic.  We
391   // march through Diags a second time to ensure the results are emitted
392   // in deterministic order.
393   for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
394     Record *R = Diags[i];
395     if (!DiagsSet.count(R))
396       continue;
397     // Check if the group is implicitly in -Wpedantic.  If so,
398     // the diagnostic should not be directly included in the -Wpedantic
399     // diagnostic group.
400     if (DefInit *Group = dyn_cast<DefInit>(R->getValueInit("Group")))
401       if (groupInPedantic(Group->getDef()))
402         continue;
403 
404     // The diagnostic is not included in a group that is (transitively) in
405     // -Wpedantic.  Include it in -Wpedantic directly.
406     if (RecordVec *V = DiagsInPedantic.dyn_cast<RecordVec*>())
407       V->push_back(R);
408     else {
409       DiagsInPedantic.get<RecordSet*>()->insert(R);
410     }
411   }
412 
413   if (!GroupsInPedantic)
414     return;
415 
416   // Compute the set of groups that are directly in -Wpedantic.  We
417   // march through the groups to ensure the results are emitted
418   /// in a deterministc order.
419   for (unsigned i = 0, ei = DiagGroups.size(); i != ei; ++i) {
420     Record *Group = DiagGroups[i];
421     if (!groupInPedantic(Group))
422       continue;
423 
424     unsigned ParentsInPedantic = 0;
425     const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group);
426     for (unsigned j = 0, ej = Parents.size(); j != ej; ++j) {
427       if (groupInPedantic(Parents[j]))
428         ++ParentsInPedantic;
429     }
430     // If all the parents are in -Wpedantic, this means that this diagnostic
431     // group will be indirectly included by -Wpedantic already.  In that
432     // case, do not add it directly to -Wpedantic.  If the group has no
433     // parents, obviously it should go into -Wpedantic.
434     if (Parents.size() > 0 && ParentsInPedantic == Parents.size())
435       continue;
436 
437     if (RecordVec *V = GroupsInPedantic.dyn_cast<RecordVec*>())
438       V->push_back(Group);
439     else {
440       GroupsInPedantic.get<RecordSet*>()->insert(Group);
441     }
442   }
443 }
444 
445 namespace {
446 enum PieceKind {
447   MultiPieceClass,
448   TextPieceClass,
449   PlaceholderPieceClass,
450   SelectPieceClass,
451   PluralPieceClass,
452   DiffPieceClass,
453   SubstitutionPieceClass,
454 };
455 
456 enum ModifierType {
457   MT_Unknown,
458   MT_Placeholder,
459   MT_Select,
460   MT_Sub,
461   MT_Plural,
462   MT_Diff,
463   MT_Ordinal,
464   MT_S,
465   MT_Q,
466   MT_ObjCClass,
467   MT_ObjCInstance,
468 };
469 
470 static StringRef getModifierName(ModifierType MT) {
471   switch (MT) {
472   case MT_Select:
473     return "select";
474   case MT_Sub:
475     return "sub";
476   case MT_Diff:
477     return "diff";
478   case MT_Plural:
479     return "plural";
480   case MT_Ordinal:
481     return "ordinal";
482   case MT_S:
483     return "s";
484   case MT_Q:
485     return "q";
486   case MT_Placeholder:
487     return "";
488   case MT_ObjCClass:
489     return "objcclass";
490   case MT_ObjCInstance:
491     return "objcinstance";
492   case MT_Unknown:
493     llvm_unreachable("invalid modifier type");
494   }
495   // Unhandled case
496   llvm_unreachable("invalid modifier type");
497 }
498 
499 struct Piece {
500   // This type and its derived classes are move-only.
501   Piece(PieceKind Kind) : ClassKind(Kind) {}
502   Piece(Piece const &O) = delete;
503   Piece &operator=(Piece const &) = delete;
504   virtual ~Piece() {}
505 
506   PieceKind getPieceClass() const { return ClassKind; }
507   static bool classof(const Piece *) { return true; }
508 
509 private:
510   PieceKind ClassKind;
511 };
512 
513 struct MultiPiece : Piece {
514   MultiPiece() : Piece(MultiPieceClass) {}
515   MultiPiece(std::vector<Piece *> Pieces)
516       : Piece(MultiPieceClass), Pieces(std::move(Pieces)) {}
517 
518   std::vector<Piece *> Pieces;
519 
520   static bool classof(const Piece *P) {
521     return P->getPieceClass() == MultiPieceClass;
522   }
523 };
524 
525 struct TextPiece : Piece {
526   StringRef Role;
527   std::string Text;
528   TextPiece(StringRef Text, StringRef Role = "")
529       : Piece(TextPieceClass), Role(Role), Text(Text.str()) {}
530 
531   static bool classof(const Piece *P) {
532     return P->getPieceClass() == TextPieceClass;
533   }
534 };
535 
536 struct PlaceholderPiece : Piece {
537   ModifierType Kind;
538   int Index;
539   PlaceholderPiece(ModifierType Kind, int Index)
540       : Piece(PlaceholderPieceClass), Kind(Kind), Index(Index) {}
541 
542   static bool classof(const Piece *P) {
543     return P->getPieceClass() == PlaceholderPieceClass;
544   }
545 };
546 
547 struct SelectPiece : Piece {
548 protected:
549   SelectPiece(PieceKind Kind, ModifierType ModKind)
550       : Piece(Kind), ModKind(ModKind) {}
551 
552 public:
553   SelectPiece(ModifierType ModKind) : SelectPiece(SelectPieceClass, ModKind) {}
554 
555   ModifierType ModKind;
556   std::vector<Piece *> Options;
557   int Index = 0;
558 
559   static bool classof(const Piece *P) {
560     return P->getPieceClass() == SelectPieceClass ||
561            P->getPieceClass() == PluralPieceClass;
562   }
563 };
564 
565 struct PluralPiece : SelectPiece {
566   PluralPiece() : SelectPiece(PluralPieceClass, MT_Plural) {}
567 
568   std::vector<Piece *> OptionPrefixes;
569   int Index = 0;
570 
571   static bool classof(const Piece *P) {
572     return P->getPieceClass() == PluralPieceClass;
573   }
574 };
575 
576 struct DiffPiece : Piece {
577   DiffPiece() : Piece(DiffPieceClass) {}
578 
579   Piece *Options[2] = {};
580   int Indexes[2] = {};
581 
582   static bool classof(const Piece *P) {
583     return P->getPieceClass() == DiffPieceClass;
584   }
585 };
586 
587 struct SubstitutionPiece : Piece {
588   SubstitutionPiece() : Piece(SubstitutionPieceClass) {}
589 
590   std::string Name;
591   std::vector<int> Modifiers;
592 
593   static bool classof(const Piece *P) {
594     return P->getPieceClass() == SubstitutionPieceClass;
595   }
596 };
597 
598 /// Diagnostic text, parsed into pieces.
599 
600 
601 struct DiagnosticTextBuilder {
602   DiagnosticTextBuilder(DiagnosticTextBuilder const &) = delete;
603   DiagnosticTextBuilder &operator=(DiagnosticTextBuilder const &) = delete;
604 
605   DiagnosticTextBuilder(RecordKeeper &Records) {
606     // Build up the list of substitution records.
607     for (auto *S : Records.getAllDerivedDefinitions("TextSubstitution")) {
608       EvaluatingRecordGuard Guard(&EvaluatingRecord, S);
609       Substitutions.try_emplace(
610           S->getName(), DiagText(*this, S->getValueAsString("Substitution")));
611     }
612 
613     // Check that no diagnostic definitions have the same name as a
614     // substitution.
615     for (Record *Diag : Records.getAllDerivedDefinitions("Diagnostic")) {
616       StringRef Name = Diag->getName();
617       if (Substitutions.count(Name))
618         llvm::PrintFatalError(
619             Diag->getLoc(),
620             "Diagnostic '" + Name +
621                 "' has same name as TextSubstitution definition");
622     }
623   }
624 
625   std::vector<std::string> buildForDocumentation(StringRef Role,
626                                                  const Record *R);
627   std::string buildForDefinition(const Record *R);
628 
629   Piece *getSubstitution(SubstitutionPiece *S) const {
630     auto It = Substitutions.find(S->Name);
631     if (It == Substitutions.end())
632       PrintFatalError("Failed to find substitution with name: " + S->Name);
633     return It->second.Root;
634   }
635 
636   LLVM_ATTRIBUTE_NORETURN void PrintFatalError(llvm::Twine const &Msg) const {
637     assert(EvaluatingRecord && "not evaluating a record?");
638     llvm::PrintFatalError(EvaluatingRecord->getLoc(), Msg);
639   }
640 
641 private:
642   struct DiagText {
643     DiagnosticTextBuilder &Builder;
644     std::vector<Piece *> AllocatedPieces;
645     Piece *Root = nullptr;
646 
647     template <class T, class... Args> T *New(Args &&... args) {
648       static_assert(std::is_base_of<Piece, T>::value, "must be piece");
649       T *Mem = new T(std::forward<Args>(args)...);
650       AllocatedPieces.push_back(Mem);
651       return Mem;
652     }
653 
654     DiagText(DiagnosticTextBuilder &Builder, StringRef Text)
655         : Builder(Builder), Root(parseDiagText(Text)) {}
656 
657     Piece *parseDiagText(StringRef &Text, bool Nested = false);
658     int parseModifier(StringRef &) const;
659 
660   public:
661     DiagText(DiagText &&O) noexcept
662         : Builder(O.Builder), AllocatedPieces(std::move(O.AllocatedPieces)),
663           Root(O.Root) {
664       O.Root = nullptr;
665     }
666 
667     ~DiagText() {
668       for (Piece *P : AllocatedPieces)
669         delete P;
670     }
671   };
672 
673 private:
674   const Record *EvaluatingRecord = nullptr;
675   struct EvaluatingRecordGuard {
676     EvaluatingRecordGuard(const Record **Dest, const Record *New)
677         : Dest(Dest), Old(*Dest) {
678       *Dest = New;
679     }
680     ~EvaluatingRecordGuard() { *Dest = Old; }
681     const Record **Dest;
682     const Record *Old;
683   };
684 
685   StringMap<DiagText> Substitutions;
686 };
687 
688 template <class Derived> struct DiagTextVisitor {
689   using ModifierMappingsType = Optional<std::vector<int>>;
690 
691 private:
692   Derived &getDerived() { return static_cast<Derived &>(*this); }
693 
694 public:
695   std::vector<int>
696   getSubstitutionMappings(SubstitutionPiece *P,
697                           const ModifierMappingsType &Mappings) const {
698     std::vector<int> NewMappings;
699     for (int Idx : P->Modifiers)
700       NewMappings.push_back(mapIndex(Idx, Mappings));
701     return NewMappings;
702   }
703 
704   struct SubstitutionContext {
705     SubstitutionContext(DiagTextVisitor &Visitor, SubstitutionPiece *P)
706         : Visitor(Visitor) {
707       Substitution = Visitor.Builder.getSubstitution(P);
708       OldMappings = std::move(Visitor.ModifierMappings);
709       std::vector<int> NewMappings =
710           Visitor.getSubstitutionMappings(P, OldMappings);
711       Visitor.ModifierMappings = std::move(NewMappings);
712     }
713 
714     ~SubstitutionContext() {
715       Visitor.ModifierMappings = std::move(OldMappings);
716     }
717 
718   private:
719     DiagTextVisitor &Visitor;
720     Optional<std::vector<int>> OldMappings;
721 
722   public:
723     Piece *Substitution;
724   };
725 
726 public:
727   DiagTextVisitor(DiagnosticTextBuilder &Builder) : Builder(Builder) {}
728 
729   void Visit(Piece *P) {
730     switch (P->getPieceClass()) {
731 #define CASE(T)                                                                \
732   case T##PieceClass:                                                          \
733     return getDerived().Visit##T(static_cast<T##Piece *>(P))
734       CASE(Multi);
735       CASE(Text);
736       CASE(Placeholder);
737       CASE(Select);
738       CASE(Plural);
739       CASE(Diff);
740       CASE(Substitution);
741 #undef CASE
742     }
743   }
744 
745   void VisitSubstitution(SubstitutionPiece *P) {
746     SubstitutionContext Guard(*this, P);
747     Visit(Guard.Substitution);
748   }
749 
750   int mapIndex(int Idx,
751                     ModifierMappingsType const &ModifierMappings) const {
752     if (!ModifierMappings)
753       return Idx;
754     if (ModifierMappings->size() <= static_cast<unsigned>(Idx))
755       Builder.PrintFatalError("Modifier value '" + std::to_string(Idx) +
756                               "' is not valid for this mapping (has " +
757                               std::to_string(ModifierMappings->size()) +
758                               " mappings)");
759     return (*ModifierMappings)[Idx];
760   }
761 
762   int mapIndex(int Idx) const {
763     return mapIndex(Idx, ModifierMappings);
764   }
765 
766 protected:
767   DiagnosticTextBuilder &Builder;
768   ModifierMappingsType ModifierMappings;
769 };
770 
771 void escapeRST(StringRef Str, std::string &Out) {
772   for (auto K : Str) {
773     if (StringRef("`*|_[]\\").count(K))
774       Out.push_back('\\');
775     Out.push_back(K);
776   }
777 }
778 
779 template <typename It> void padToSameLength(It Begin, It End) {
780   size_t Width = 0;
781   for (It I = Begin; I != End; ++I)
782     Width = std::max(Width, I->size());
783   for (It I = Begin; I != End; ++I)
784     (*I) += std::string(Width - I->size(), ' ');
785 }
786 
787 template <typename It> void makeTableRows(It Begin, It End) {
788   if (Begin == End)
789     return;
790   padToSameLength(Begin, End);
791   for (It I = Begin; I != End; ++I)
792     *I = "|" + *I + "|";
793 }
794 
795 void makeRowSeparator(std::string &Str) {
796   for (char &K : Str)
797     K = (K == '|' ? '+' : '-');
798 }
799 
800 struct DiagTextDocPrinter : DiagTextVisitor<DiagTextDocPrinter> {
801   using BaseTy = DiagTextVisitor<DiagTextDocPrinter>;
802   DiagTextDocPrinter(DiagnosticTextBuilder &Builder,
803                      std::vector<std::string> &RST)
804       : BaseTy(Builder), RST(RST) {}
805 
806   void gatherNodes(
807       Piece *OrigP, const ModifierMappingsType &CurrentMappings,
808       std::vector<std::pair<Piece *, ModifierMappingsType>> &Pieces) const {
809     if (auto *Sub = dyn_cast<SubstitutionPiece>(OrigP)) {
810       ModifierMappingsType NewMappings =
811           getSubstitutionMappings(Sub, CurrentMappings);
812       return gatherNodes(Builder.getSubstitution(Sub), NewMappings, Pieces);
813     }
814     if (auto *MD = dyn_cast<MultiPiece>(OrigP)) {
815       for (Piece *Node : MD->Pieces)
816         gatherNodes(Node, CurrentMappings, Pieces);
817       return;
818     }
819     Pieces.push_back(std::make_pair(OrigP, CurrentMappings));
820   }
821 
822   void VisitMulti(MultiPiece *P) {
823     if (P->Pieces.empty()) {
824       RST.push_back("");
825       return;
826     }
827 
828     if (P->Pieces.size() == 1)
829       return Visit(P->Pieces[0]);
830 
831     // Flatten the list of nodes, replacing any substitution pieces with the
832     // recursively flattened substituted node.
833     std::vector<std::pair<Piece *, ModifierMappingsType>> Pieces;
834     gatherNodes(P, ModifierMappings, Pieces);
835 
836     std::string EmptyLinePrefix;
837     size_t Start = RST.size();
838     bool HasMultipleLines = true;
839     for (const std::pair<Piece *, ModifierMappingsType> &NodePair : Pieces) {
840       std::vector<std::string> Lines;
841       DiagTextDocPrinter Visitor{Builder, Lines};
842       Visitor.ModifierMappings = NodePair.second;
843       Visitor.Visit(NodePair.first);
844 
845       if (Lines.empty())
846         continue;
847 
848       // We need a vertical separator if either this or the previous piece is a
849       // multi-line piece, or this is the last piece.
850       const char *Separator = (Lines.size() > 1 || HasMultipleLines) ? "|" : "";
851       HasMultipleLines = Lines.size() > 1;
852 
853       if (Start + Lines.size() > RST.size())
854         RST.resize(Start + Lines.size(), EmptyLinePrefix);
855 
856       padToSameLength(Lines.begin(), Lines.end());
857       for (size_t I = 0; I != Lines.size(); ++I)
858         RST[Start + I] += Separator + Lines[I];
859       std::string Empty(Lines[0].size(), ' ');
860       for (size_t I = Start + Lines.size(); I != RST.size(); ++I)
861         RST[I] += Separator + Empty;
862       EmptyLinePrefix += Separator + Empty;
863     }
864     for (size_t I = Start; I != RST.size(); ++I)
865       RST[I] += "|";
866     EmptyLinePrefix += "|";
867 
868     makeRowSeparator(EmptyLinePrefix);
869     RST.insert(RST.begin() + Start, EmptyLinePrefix);
870     RST.insert(RST.end(), EmptyLinePrefix);
871   }
872 
873   void VisitText(TextPiece *P) {
874     RST.push_back("");
875     auto &S = RST.back();
876 
877     StringRef T = P->Text;
878     while (!T.empty() && T.front() == ' ') {
879       RST.back() += " |nbsp| ";
880       T = T.drop_front();
881     }
882 
883     std::string Suffix;
884     while (!T.empty() && T.back() == ' ') {
885       Suffix += " |nbsp| ";
886       T = T.drop_back();
887     }
888 
889     if (!T.empty()) {
890       S += ':';
891       S += P->Role;
892       S += ":`";
893       escapeRST(T, S);
894       S += '`';
895     }
896 
897     S += Suffix;
898   }
899 
900   void VisitPlaceholder(PlaceholderPiece *P) {
901     RST.push_back(std::string(":placeholder:`") +
902                   char('A' + mapIndex(P->Index)) + "`");
903   }
904 
905   void VisitSelect(SelectPiece *P) {
906     std::vector<size_t> SeparatorIndexes;
907     SeparatorIndexes.push_back(RST.size());
908     RST.emplace_back();
909     for (auto *O : P->Options) {
910       Visit(O);
911       SeparatorIndexes.push_back(RST.size());
912       RST.emplace_back();
913     }
914 
915     makeTableRows(RST.begin() + SeparatorIndexes.front(),
916                   RST.begin() + SeparatorIndexes.back() + 1);
917     for (size_t I : SeparatorIndexes)
918       makeRowSeparator(RST[I]);
919   }
920 
921   void VisitPlural(PluralPiece *P) { VisitSelect(P); }
922 
923   void VisitDiff(DiffPiece *P) { Visit(P->Options[1]); }
924 
925   std::vector<std::string> &RST;
926 };
927 
928 struct DiagTextPrinter : DiagTextVisitor<DiagTextPrinter> {
929 public:
930   using BaseTy = DiagTextVisitor<DiagTextPrinter>;
931   DiagTextPrinter(DiagnosticTextBuilder &Builder, std::string &Result)
932       : BaseTy(Builder), Result(Result) {}
933 
934   void VisitMulti(MultiPiece *P) {
935     for (auto *Child : P->Pieces)
936       Visit(Child);
937   }
938   void VisitText(TextPiece *P) { Result += P->Text; }
939   void VisitPlaceholder(PlaceholderPiece *P) {
940     Result += "%";
941     Result += getModifierName(P->Kind);
942     addInt(mapIndex(P->Index));
943   }
944   void VisitSelect(SelectPiece *P) {
945     Result += "%";
946     Result += getModifierName(P->ModKind);
947     if (P->ModKind == MT_Select) {
948       Result += "{";
949       for (auto *D : P->Options) {
950         Visit(D);
951         Result += '|';
952       }
953       if (!P->Options.empty())
954         Result.erase(--Result.end());
955       Result += '}';
956     }
957     addInt(mapIndex(P->Index));
958   }
959 
960   void VisitPlural(PluralPiece *P) {
961     Result += "%plural{";
962     assert(P->Options.size() == P->OptionPrefixes.size());
963     for (unsigned I = 0, End = P->Options.size(); I < End; ++I) {
964       if (P->OptionPrefixes[I])
965         Visit(P->OptionPrefixes[I]);
966       Visit(P->Options[I]);
967       Result += "|";
968     }
969     if (!P->Options.empty())
970       Result.erase(--Result.end());
971     Result += '}';
972     addInt(mapIndex(P->Index));
973   }
974 
975   void VisitDiff(DiffPiece *P) {
976     Result += "%diff{";
977     Visit(P->Options[0]);
978     Result += "|";
979     Visit(P->Options[1]);
980     Result += "}";
981     addInt(mapIndex(P->Indexes[0]));
982     Result += ",";
983     addInt(mapIndex(P->Indexes[1]));
984   }
985 
986   void addInt(int Val) { Result += std::to_string(Val); }
987 
988   std::string &Result;
989 };
990 
991 int DiagnosticTextBuilder::DiagText::parseModifier(StringRef &Text) const {
992   if (Text.empty() || !isdigit(Text[0]))
993     Builder.PrintFatalError("expected modifier in diagnostic");
994   int Val = 0;
995   do {
996     Val *= 10;
997     Val += Text[0] - '0';
998     Text = Text.drop_front();
999   } while (!Text.empty() && isdigit(Text[0]));
1000   return Val;
1001 }
1002 
1003 Piece *DiagnosticTextBuilder::DiagText::parseDiagText(StringRef &Text,
1004                                                       bool Nested) {
1005   std::vector<Piece *> Parsed;
1006 
1007   while (!Text.empty()) {
1008     size_t End = (size_t)-2;
1009     do
1010       End = Nested ? Text.find_first_of("%|}", End + 2)
1011                    : Text.find_first_of('%', End + 2);
1012     while (End < Text.size() - 1 && Text[End] == '%' &&
1013            (Text[End + 1] == '%' || Text[End + 1] == '|'));
1014 
1015     if (End) {
1016       Parsed.push_back(New<TextPiece>(Text.slice(0, End), "diagtext"));
1017       Text = Text.slice(End, StringRef::npos);
1018       if (Text.empty())
1019         break;
1020     }
1021 
1022     if (Text[0] == '|' || Text[0] == '}')
1023       break;
1024 
1025     // Drop the '%'.
1026     Text = Text.drop_front();
1027 
1028     // Extract the (optional) modifier.
1029     size_t ModLength = Text.find_first_of("0123456789{");
1030     StringRef Modifier = Text.slice(0, ModLength);
1031     Text = Text.slice(ModLength, StringRef::npos);
1032     ModifierType ModType = llvm::StringSwitch<ModifierType>{Modifier}
1033                                .Case("select", MT_Select)
1034                                .Case("sub", MT_Sub)
1035                                .Case("diff", MT_Diff)
1036                                .Case("plural", MT_Plural)
1037                                .Case("s", MT_S)
1038                                .Case("ordinal", MT_Ordinal)
1039                                .Case("q", MT_Q)
1040                                .Case("objcclass", MT_ObjCClass)
1041                                .Case("objcinstance", MT_ObjCInstance)
1042                                .Case("", MT_Placeholder)
1043                                .Default(MT_Unknown);
1044 
1045     switch (ModType) {
1046     case MT_Unknown:
1047       Builder.PrintFatalError("Unknown modifier type: " + Modifier);
1048     case MT_Select: {
1049       SelectPiece *Select = New<SelectPiece>(MT_Select);
1050       do {
1051         Text = Text.drop_front(); // '{' or '|'
1052         Select->Options.push_back(parseDiagText(Text, true));
1053         assert(!Text.empty() && "malformed %select");
1054       } while (Text.front() == '|');
1055       // Drop the trailing '}'.
1056       Text = Text.drop_front(1);
1057       Select->Index = parseModifier(Text);
1058       Parsed.push_back(Select);
1059       continue;
1060     }
1061     case MT_Plural: {
1062       PluralPiece *Plural = New<PluralPiece>();
1063       do {
1064         Text = Text.drop_front(); // '{' or '|'
1065         size_t End = Text.find_first_of(":");
1066         if (End == StringRef::npos)
1067           Builder.PrintFatalError("expected ':' while parsing %plural");
1068         ++End;
1069         assert(!Text.empty());
1070         Plural->OptionPrefixes.push_back(
1071             New<TextPiece>(Text.slice(0, End), "diagtext"));
1072         Text = Text.slice(End, StringRef::npos);
1073         Plural->Options.push_back(parseDiagText(Text, true));
1074         assert(!Text.empty() && "malformed %select");
1075       } while (Text.front() == '|');
1076       // Drop the trailing '}'.
1077       Text = Text.drop_front(1);
1078       Plural->Index = parseModifier(Text);
1079       Parsed.push_back(Plural);
1080       continue;
1081     }
1082     case MT_Sub: {
1083       SubstitutionPiece *Sub = New<SubstitutionPiece>();
1084       Text = Text.drop_front(); // '{'
1085       size_t NameSize = Text.find_first_of('}');
1086       assert(NameSize != size_t(-1) && "failed to find the end of the name");
1087       assert(NameSize != 0 && "empty name?");
1088       Sub->Name = Text.substr(0, NameSize).str();
1089       Text = Text.drop_front(NameSize);
1090       Text = Text.drop_front(); // '}'
1091       if (!Text.empty()) {
1092         while (true) {
1093           if (!isdigit(Text[0]))
1094             break;
1095           Sub->Modifiers.push_back(parseModifier(Text));
1096           if (Text.empty() || Text[0] != ',')
1097             break;
1098           Text = Text.drop_front(); // ','
1099           assert(!Text.empty() && isdigit(Text[0]) &&
1100                  "expected another modifier");
1101         }
1102       }
1103       Parsed.push_back(Sub);
1104       continue;
1105     }
1106     case MT_Diff: {
1107       DiffPiece *Diff = New<DiffPiece>();
1108       Text = Text.drop_front(); // '{'
1109       Diff->Options[0] = parseDiagText(Text, true);
1110       Text = Text.drop_front(); // '|'
1111       Diff->Options[1] = parseDiagText(Text, true);
1112 
1113       Text = Text.drop_front(); // '}'
1114       Diff->Indexes[0] = parseModifier(Text);
1115       Text = Text.drop_front(); // ','
1116       Diff->Indexes[1] = parseModifier(Text);
1117       Parsed.push_back(Diff);
1118       continue;
1119     }
1120     case MT_S: {
1121       SelectPiece *Select = New<SelectPiece>(ModType);
1122       Select->Options.push_back(New<TextPiece>(""));
1123       Select->Options.push_back(New<TextPiece>("s", "diagtext"));
1124       Select->Index = parseModifier(Text);
1125       Parsed.push_back(Select);
1126       continue;
1127     }
1128     case MT_Q:
1129     case MT_Placeholder:
1130     case MT_ObjCClass:
1131     case MT_ObjCInstance:
1132     case MT_Ordinal: {
1133       Parsed.push_back(New<PlaceholderPiece>(ModType, parseModifier(Text)));
1134       continue;
1135     }
1136     }
1137   }
1138 
1139   return New<MultiPiece>(Parsed);
1140 }
1141 
1142 std::vector<std::string>
1143 DiagnosticTextBuilder::buildForDocumentation(StringRef Severity,
1144                                              const Record *R) {
1145   EvaluatingRecordGuard Guard(&EvaluatingRecord, R);
1146   StringRef Text = R->getValueAsString("Text");
1147 
1148   DiagText D(*this, Text);
1149   TextPiece *Prefix = D.New<TextPiece>(Severity, Severity);
1150   Prefix->Text += ": ";
1151   auto *MP = dyn_cast<MultiPiece>(D.Root);
1152   if (!MP) {
1153     MP = D.New<MultiPiece>();
1154     MP->Pieces.push_back(D.Root);
1155     D.Root = MP;
1156   }
1157   MP->Pieces.insert(MP->Pieces.begin(), Prefix);
1158   std::vector<std::string> Result;
1159   DiagTextDocPrinter{*this, Result}.Visit(D.Root);
1160   return Result;
1161 }
1162 
1163 std::string DiagnosticTextBuilder::buildForDefinition(const Record *R) {
1164   EvaluatingRecordGuard Guard(&EvaluatingRecord, R);
1165   StringRef Text = R->getValueAsString("Text");
1166   DiagText D(*this, Text);
1167   std::string Result;
1168   DiagTextPrinter{*this, Result}.Visit(D.Root);
1169   return Result;
1170 }
1171 
1172 } // namespace
1173 
1174 //===----------------------------------------------------------------------===//
1175 // Warning Tables (.inc file) generation.
1176 //===----------------------------------------------------------------------===//
1177 
1178 static bool isError(const Record &Diag) {
1179   const std::string &ClsName = Diag.getValueAsDef("Class")->getName();
1180   return ClsName == "CLASS_ERROR";
1181 }
1182 
1183 static bool isRemark(const Record &Diag) {
1184   const std::string &ClsName = Diag.getValueAsDef("Class")->getName();
1185   return ClsName == "CLASS_REMARK";
1186 }
1187 
1188 
1189 /// ClangDiagsDefsEmitter - The top-level class emits .def files containing
1190 /// declarations of Clang diagnostics.
1191 void clang::EmitClangDiagsDefs(RecordKeeper &Records, raw_ostream &OS,
1192                                const std::string &Component) {
1193   // Write the #if guard
1194   if (!Component.empty()) {
1195     std::string ComponentName = StringRef(Component).upper();
1196     OS << "#ifdef " << ComponentName << "START\n";
1197     OS << "__" << ComponentName << "START = DIAG_START_" << ComponentName
1198        << ",\n";
1199     OS << "#undef " << ComponentName << "START\n";
1200     OS << "#endif\n\n";
1201   }
1202 
1203   DiagnosticTextBuilder DiagTextBuilder(Records);
1204 
1205   std::vector<Record *> Diags = Records.getAllDerivedDefinitions("Diagnostic");
1206 
1207   std::vector<Record*> DiagGroups
1208     = Records.getAllDerivedDefinitions("DiagGroup");
1209 
1210   std::map<std::string, GroupInfo> DiagsInGroup;
1211   groupDiagnostics(Diags, DiagGroups, DiagsInGroup);
1212 
1213   DiagCategoryIDMap CategoryIDs(Records);
1214   DiagGroupParentMap DGParentMap(Records);
1215 
1216   // Compute the set of diagnostics that are in -Wpedantic.
1217   RecordSet DiagsInPedantic;
1218   InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup);
1219   inferPedantic.compute(&DiagsInPedantic, (RecordVec*)nullptr);
1220 
1221   for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
1222     const Record &R = *Diags[i];
1223 
1224     // Check if this is an error that is accidentally in a warning
1225     // group.
1226     if (isError(R)) {
1227       if (DefInit *Group = dyn_cast<DefInit>(R.getValueInit("Group"))) {
1228         const Record *GroupRec = Group->getDef();
1229         const std::string &GroupName = GroupRec->getValueAsString("GroupName");
1230         PrintFatalError(R.getLoc(), "Error " + R.getName() +
1231                       " cannot be in a warning group [" + GroupName + "]");
1232       }
1233     }
1234 
1235     // Check that all remarks have an associated diagnostic group.
1236     if (isRemark(R)) {
1237       if (!isa<DefInit>(R.getValueInit("Group"))) {
1238         PrintFatalError(R.getLoc(), "Error " + R.getName() +
1239                                         " not in any diagnostic group");
1240       }
1241     }
1242 
1243     // Filter by component.
1244     if (!Component.empty() && Component != R.getValueAsString("Component"))
1245       continue;
1246 
1247     OS << "DIAG(" << R.getName() << ", ";
1248     OS << R.getValueAsDef("Class")->getName();
1249     OS << ", (unsigned)diag::Severity::"
1250        << R.getValueAsDef("DefaultSeverity")->getValueAsString("Name");
1251 
1252     // Description string.
1253     OS << ", \"";
1254     OS.write_escaped(DiagTextBuilder.buildForDefinition(&R)) << '"';
1255 
1256     // Warning associated with the diagnostic. This is stored as an index into
1257     // the alphabetically sorted warning table.
1258     if (DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) {
1259       std::map<std::string, GroupInfo>::iterator I =
1260           DiagsInGroup.find(DI->getDef()->getValueAsString("GroupName"));
1261       assert(I != DiagsInGroup.end());
1262       OS << ", " << I->second.IDNo;
1263     } else if (DiagsInPedantic.count(&R)) {
1264       std::map<std::string, GroupInfo>::iterator I =
1265         DiagsInGroup.find("pedantic");
1266       assert(I != DiagsInGroup.end() && "pedantic group not defined");
1267       OS << ", " << I->second.IDNo;
1268     } else {
1269       OS << ", 0";
1270     }
1271 
1272     // SFINAE response.
1273     OS << ", " << R.getValueAsDef("SFINAE")->getName();
1274 
1275     // Default warning has no Werror bit.
1276     if (R.getValueAsBit("WarningNoWerror"))
1277       OS << ", true";
1278     else
1279       OS << ", false";
1280 
1281     if (R.getValueAsBit("ShowInSystemHeader"))
1282       OS << ", true";
1283     else
1284       OS << ", false";
1285 
1286     // Category number.
1287     OS << ", " << CategoryIDs.getID(getDiagnosticCategory(&R, DGParentMap));
1288     OS << ")\n";
1289   }
1290 }
1291 
1292 //===----------------------------------------------------------------------===//
1293 // Warning Group Tables generation
1294 //===----------------------------------------------------------------------===//
1295 
1296 static std::string getDiagCategoryEnum(llvm::StringRef name) {
1297   if (name.empty())
1298     return "DiagCat_None";
1299   SmallString<256> enumName = llvm::StringRef("DiagCat_");
1300   for (llvm::StringRef::iterator I = name.begin(), E = name.end(); I != E; ++I)
1301     enumName += isalnum(*I) ? *I : '_';
1302   return enumName.str();
1303 }
1304 
1305 /// Emit the array of diagnostic subgroups.
1306 ///
1307 /// The array of diagnostic subgroups contains for each group a list of its
1308 /// subgroups. The individual lists are separated by '-1'. Groups with no
1309 /// subgroups are skipped.
1310 ///
1311 /// \code
1312 ///   static const int16_t DiagSubGroups[] = {
1313 ///     /* Empty */ -1,
1314 ///     /* DiagSubGroup0 */ 142, -1,
1315 ///     /* DiagSubGroup13 */ 265, 322, 399, -1
1316 ///   }
1317 /// \endcode
1318 ///
1319 static void emitDiagSubGroups(std::map<std::string, GroupInfo> &DiagsInGroup,
1320                               RecordVec &GroupsInPedantic, raw_ostream &OS) {
1321   OS << "static const int16_t DiagSubGroups[] = {\n"
1322      << "  /* Empty */ -1,\n";
1323   for (auto const &I : DiagsInGroup) {
1324     const bool IsPedantic = I.first == "pedantic";
1325 
1326     const std::vector<std::string> &SubGroups = I.second.SubGroups;
1327     if (!SubGroups.empty() || (IsPedantic && !GroupsInPedantic.empty())) {
1328       OS << "  /* DiagSubGroup" << I.second.IDNo << " */ ";
1329       for (auto const &SubGroup : SubGroups) {
1330         std::map<std::string, GroupInfo>::const_iterator RI =
1331             DiagsInGroup.find(SubGroup);
1332         assert(RI != DiagsInGroup.end() && "Referenced without existing?");
1333         OS << RI->second.IDNo << ", ";
1334       }
1335       // Emit the groups implicitly in "pedantic".
1336       if (IsPedantic) {
1337         for (auto const &Group : GroupsInPedantic) {
1338           const std::string &GroupName = Group->getValueAsString("GroupName");
1339           std::map<std::string, GroupInfo>::const_iterator RI =
1340               DiagsInGroup.find(GroupName);
1341           assert(RI != DiagsInGroup.end() && "Referenced without existing?");
1342           OS << RI->second.IDNo << ", ";
1343         }
1344       }
1345 
1346       OS << "-1,\n";
1347     }
1348   }
1349   OS << "};\n\n";
1350 }
1351 
1352 /// Emit the list of diagnostic arrays.
1353 ///
1354 /// This data structure is a large array that contains itself arrays of varying
1355 /// size. Each array represents a list of diagnostics. The different arrays are
1356 /// separated by the value '-1'.
1357 ///
1358 /// \code
1359 ///   static const int16_t DiagArrays[] = {
1360 ///     /* Empty */ -1,
1361 ///     /* DiagArray1 */ diag::warn_pragma_message,
1362 ///                      -1,
1363 ///     /* DiagArray2 */ diag::warn_abs_too_small,
1364 ///                      diag::warn_unsigned_abs,
1365 ///                      diag::warn_wrong_absolute_value_type,
1366 ///                      -1
1367 ///   };
1368 /// \endcode
1369 ///
1370 static void emitDiagArrays(std::map<std::string, GroupInfo> &DiagsInGroup,
1371                            RecordVec &DiagsInPedantic, raw_ostream &OS) {
1372   OS << "static const int16_t DiagArrays[] = {\n"
1373      << "  /* Empty */ -1,\n";
1374   for (auto const &I : DiagsInGroup) {
1375     const bool IsPedantic = I.first == "pedantic";
1376 
1377     const std::vector<const Record *> &V = I.second.DiagsInGroup;
1378     if (!V.empty() || (IsPedantic && !DiagsInPedantic.empty())) {
1379       OS << "  /* DiagArray" << I.second.IDNo << " */ ";
1380       for (auto *Record : V)
1381         OS << "diag::" << Record->getName() << ", ";
1382       // Emit the diagnostics implicitly in "pedantic".
1383       if (IsPedantic) {
1384         for (auto const &Diag : DiagsInPedantic)
1385           OS << "diag::" << Diag->getName() << ", ";
1386       }
1387       OS << "-1,\n";
1388     }
1389   }
1390   OS << "};\n\n";
1391 }
1392 
1393 /// Emit a list of group names.
1394 ///
1395 /// This creates a long string which by itself contains a list of pascal style
1396 /// strings, which consist of a length byte directly followed by the string.
1397 ///
1398 /// \code
1399 ///   static const char DiagGroupNames[] = {
1400 ///     \000\020#pragma-messages\t#warnings\020CFString-literal"
1401 ///   };
1402 /// \endcode
1403 static void emitDiagGroupNames(StringToOffsetTable &GroupNames,
1404                                raw_ostream &OS) {
1405   OS << "static const char DiagGroupNames[] = {\n";
1406   GroupNames.EmitString(OS);
1407   OS << "};\n\n";
1408 }
1409 
1410 /// Emit diagnostic arrays and related data structures.
1411 ///
1412 /// This creates the actual diagnostic array, an array of diagnostic subgroups
1413 /// and an array of subgroup names.
1414 ///
1415 /// \code
1416 ///  #ifdef GET_DIAG_ARRAYS
1417 ///     static const int16_t DiagArrays[];
1418 ///     static const int16_t DiagSubGroups[];
1419 ///     static const char DiagGroupNames[];
1420 ///  #endif
1421 ///  \endcode
1422 static void emitAllDiagArrays(std::map<std::string, GroupInfo> &DiagsInGroup,
1423                               RecordVec &DiagsInPedantic,
1424                               RecordVec &GroupsInPedantic,
1425                               StringToOffsetTable &GroupNames,
1426                               raw_ostream &OS) {
1427   OS << "\n#ifdef GET_DIAG_ARRAYS\n";
1428   emitDiagArrays(DiagsInGroup, DiagsInPedantic, OS);
1429   emitDiagSubGroups(DiagsInGroup, GroupsInPedantic, OS);
1430   emitDiagGroupNames(GroupNames, OS);
1431   OS << "#endif // GET_DIAG_ARRAYS\n\n";
1432 }
1433 
1434 /// Emit diagnostic table.
1435 ///
1436 /// The table is sorted by the name of the diagnostic group. Each element
1437 /// consists of the name of the diagnostic group (given as offset in the
1438 /// group name table), a reference to a list of diagnostics (optional) and a
1439 /// reference to a set of subgroups (optional).
1440 ///
1441 /// \code
1442 /// #ifdef GET_DIAG_TABLE
1443 ///  {/* abi */              159, /* DiagArray11 */ 19, /* Empty */          0},
1444 ///  {/* aggregate-return */ 180, /* Empty */        0, /* Empty */          0},
1445 ///  {/* all */              197, /* Empty */        0, /* DiagSubGroup13 */ 3},
1446 ///  {/* deprecated */       1981,/* DiagArray1 */ 348, /* DiagSubGroup3 */  9},
1447 /// #endif
1448 /// \endcode
1449 static void emitDiagTable(std::map<std::string, GroupInfo> &DiagsInGroup,
1450                           RecordVec &DiagsInPedantic,
1451                           RecordVec &GroupsInPedantic,
1452                           StringToOffsetTable &GroupNames, raw_ostream &OS) {
1453   unsigned MaxLen = 0;
1454 
1455   for (auto const &I: DiagsInGroup)
1456     MaxLen = std::max(MaxLen, (unsigned)I.first.size());
1457 
1458   OS << "\n#ifdef GET_DIAG_TABLE\n";
1459   unsigned SubGroupIndex = 1, DiagArrayIndex = 1;
1460   for (auto const &I: DiagsInGroup) {
1461     // Group option string.
1462     OS << "  { /* ";
1463     if (I.first.find_first_not_of("abcdefghijklmnopqrstuvwxyz"
1464                                    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1465                                    "0123456789!@#$%^*-+=:?") !=
1466         std::string::npos)
1467       PrintFatalError("Invalid character in diagnostic group '" + I.first +
1468                       "'");
1469     OS << I.first << " */ " << std::string(MaxLen - I.first.size(), ' ');
1470     // Store a pascal-style length byte at the beginning of the string.
1471     std::string Name = char(I.first.size()) + I.first;
1472     OS << GroupNames.GetOrAddStringOffset(Name, false) << ", ";
1473 
1474     // Special handling for 'pedantic'.
1475     const bool IsPedantic = I.first == "pedantic";
1476 
1477     // Diagnostics in the group.
1478     const std::vector<const Record *> &V = I.second.DiagsInGroup;
1479     const bool hasDiags =
1480         !V.empty() || (IsPedantic && !DiagsInPedantic.empty());
1481     if (hasDiags) {
1482       OS << "/* DiagArray" << I.second.IDNo << " */ " << DiagArrayIndex
1483          << ", ";
1484       if (IsPedantic)
1485         DiagArrayIndex += DiagsInPedantic.size();
1486       DiagArrayIndex += V.size() + 1;
1487     } else {
1488       OS << "/* Empty */     0, ";
1489     }
1490 
1491     // Subgroups.
1492     const std::vector<std::string> &SubGroups = I.second.SubGroups;
1493     const bool hasSubGroups =
1494         !SubGroups.empty() || (IsPedantic && !GroupsInPedantic.empty());
1495     if (hasSubGroups) {
1496       OS << "/* DiagSubGroup" << I.second.IDNo << " */ " << SubGroupIndex;
1497       if (IsPedantic)
1498         SubGroupIndex += GroupsInPedantic.size();
1499       SubGroupIndex += SubGroups.size() + 1;
1500     } else {
1501       OS << "/* Empty */         0";
1502     }
1503 
1504     OS << " },\n";
1505   }
1506   OS << "#endif // GET_DIAG_TABLE\n\n";
1507 }
1508 
1509 /// Emit the table of diagnostic categories.
1510 ///
1511 /// The table has the form of macro calls that have two parameters. The
1512 /// category's name as well as an enum that represents the category. The
1513 /// table can be used by defining the macro 'CATEGORY' and including this
1514 /// table right after.
1515 ///
1516 /// \code
1517 /// #ifdef GET_CATEGORY_TABLE
1518 ///   CATEGORY("Semantic Issue", DiagCat_Semantic_Issue)
1519 ///   CATEGORY("Lambda Issue", DiagCat_Lambda_Issue)
1520 /// #endif
1521 /// \endcode
1522 static void emitCategoryTable(RecordKeeper &Records, raw_ostream &OS) {
1523   DiagCategoryIDMap CategoriesByID(Records);
1524   OS << "\n#ifdef GET_CATEGORY_TABLE\n";
1525   for (auto const &C : CategoriesByID)
1526     OS << "CATEGORY(\"" << C << "\", " << getDiagCategoryEnum(C) << ")\n";
1527   OS << "#endif // GET_CATEGORY_TABLE\n\n";
1528 }
1529 
1530 void clang::EmitClangDiagGroups(RecordKeeper &Records, raw_ostream &OS) {
1531   // Compute a mapping from a DiagGroup to all of its parents.
1532   DiagGroupParentMap DGParentMap(Records);
1533 
1534   std::vector<Record *> Diags = Records.getAllDerivedDefinitions("Diagnostic");
1535 
1536   std::vector<Record *> DiagGroups =
1537       Records.getAllDerivedDefinitions("DiagGroup");
1538 
1539   std::map<std::string, GroupInfo> DiagsInGroup;
1540   groupDiagnostics(Diags, DiagGroups, DiagsInGroup);
1541 
1542   // All extensions are implicitly in the "pedantic" group.  Record the
1543   // implicit set of groups in the "pedantic" group, and use this information
1544   // later when emitting the group information for Pedantic.
1545   RecordVec DiagsInPedantic;
1546   RecordVec GroupsInPedantic;
1547   InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup);
1548   inferPedantic.compute(&DiagsInPedantic, &GroupsInPedantic);
1549 
1550   StringToOffsetTable GroupNames;
1551   for (std::map<std::string, GroupInfo>::const_iterator
1552            I = DiagsInGroup.begin(),
1553            E = DiagsInGroup.end();
1554        I != E; ++I) {
1555     // Store a pascal-style length byte at the beginning of the string.
1556     std::string Name = char(I->first.size()) + I->first;
1557     GroupNames.GetOrAddStringOffset(Name, false);
1558   }
1559 
1560   emitAllDiagArrays(DiagsInGroup, DiagsInPedantic, GroupsInPedantic, GroupNames,
1561                     OS);
1562   emitDiagTable(DiagsInGroup, DiagsInPedantic, GroupsInPedantic, GroupNames,
1563                 OS);
1564   emitCategoryTable(Records, OS);
1565 }
1566 
1567 //===----------------------------------------------------------------------===//
1568 // Diagnostic name index generation
1569 //===----------------------------------------------------------------------===//
1570 
1571 namespace {
1572 struct RecordIndexElement
1573 {
1574   RecordIndexElement() {}
1575   explicit RecordIndexElement(Record const &R):
1576     Name(R.getName()) {}
1577 
1578   std::string Name;
1579 };
1580 } // end anonymous namespace.
1581 
1582 void clang::EmitClangDiagsIndexName(RecordKeeper &Records, raw_ostream &OS) {
1583   const std::vector<Record*> &Diags =
1584     Records.getAllDerivedDefinitions("Diagnostic");
1585 
1586   std::vector<RecordIndexElement> Index;
1587   Index.reserve(Diags.size());
1588   for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
1589     const Record &R = *(Diags[i]);
1590     Index.push_back(RecordIndexElement(R));
1591   }
1592 
1593   llvm::sort(Index,
1594              [](const RecordIndexElement &Lhs, const RecordIndexElement &Rhs) {
1595                return Lhs.Name < Rhs.Name;
1596              });
1597 
1598   for (unsigned i = 0, e = Index.size(); i != e; ++i) {
1599     const RecordIndexElement &R = Index[i];
1600 
1601     OS << "DIAG_NAME_INDEX(" << R.Name << ")\n";
1602   }
1603 }
1604 
1605 //===----------------------------------------------------------------------===//
1606 // Diagnostic documentation generation
1607 //===----------------------------------------------------------------------===//
1608 
1609 namespace docs {
1610 namespace {
1611 
1612 bool isRemarkGroup(const Record *DiagGroup,
1613                    const std::map<std::string, GroupInfo> &DiagsInGroup) {
1614   bool AnyRemarks = false, AnyNonRemarks = false;
1615 
1616   std::function<void(StringRef)> Visit = [&](StringRef GroupName) {
1617     auto &GroupInfo = DiagsInGroup.find(GroupName)->second;
1618     for (const Record *Diag : GroupInfo.DiagsInGroup)
1619       (isRemark(*Diag) ? AnyRemarks : AnyNonRemarks) = true;
1620     for (const auto &Name : GroupInfo.SubGroups)
1621       Visit(Name);
1622   };
1623   Visit(DiagGroup->getValueAsString("GroupName"));
1624 
1625   if (AnyRemarks && AnyNonRemarks)
1626     PrintFatalError(
1627         DiagGroup->getLoc(),
1628         "Diagnostic group contains both remark and non-remark diagnostics");
1629   return AnyRemarks;
1630 }
1631 
1632 std::string getDefaultSeverity(const Record *Diag) {
1633   return Diag->getValueAsDef("DefaultSeverity")->getValueAsString("Name");
1634 }
1635 
1636 std::set<std::string>
1637 getDefaultSeverities(const Record *DiagGroup,
1638                      const std::map<std::string, GroupInfo> &DiagsInGroup) {
1639   std::set<std::string> States;
1640 
1641   std::function<void(StringRef)> Visit = [&](StringRef GroupName) {
1642     auto &GroupInfo = DiagsInGroup.find(GroupName)->second;
1643     for (const Record *Diag : GroupInfo.DiagsInGroup)
1644       States.insert(getDefaultSeverity(Diag));
1645     for (const auto &Name : GroupInfo.SubGroups)
1646       Visit(Name);
1647   };
1648   Visit(DiagGroup->getValueAsString("GroupName"));
1649   return States;
1650 }
1651 
1652 void writeHeader(StringRef Str, raw_ostream &OS, char Kind = '-') {
1653   OS << Str << "\n" << std::string(Str.size(), Kind) << "\n";
1654 }
1655 
1656 void writeDiagnosticText(DiagnosticTextBuilder &Builder, const Record *R,
1657                          StringRef Role, raw_ostream &OS) {
1658   StringRef Text = R->getValueAsString("Text");
1659   if (Text == "%0")
1660     OS << "The text of this diagnostic is not controlled by Clang.\n\n";
1661   else {
1662     std::vector<std::string> Out = Builder.buildForDocumentation(Role, R);
1663     for (auto &Line : Out)
1664       OS << Line << "\n";
1665     OS << "\n";
1666   }
1667 }
1668 
1669 }  // namespace
1670 }  // namespace docs
1671 
1672 void clang::EmitClangDiagDocs(RecordKeeper &Records, raw_ostream &OS) {
1673   using namespace docs;
1674 
1675   // Get the documentation introduction paragraph.
1676   const Record *Documentation = Records.getDef("GlobalDocumentation");
1677   if (!Documentation) {
1678     PrintFatalError("The Documentation top-level definition is missing, "
1679                     "no documentation will be generated.");
1680     return;
1681   }
1682 
1683   OS << Documentation->getValueAsString("Intro") << "\n";
1684 
1685   DiagnosticTextBuilder Builder(Records);
1686 
1687   std::vector<Record*> Diags =
1688       Records.getAllDerivedDefinitions("Diagnostic");
1689 
1690   std::vector<Record*> DiagGroups =
1691       Records.getAllDerivedDefinitions("DiagGroup");
1692   llvm::sort(DiagGroups, diagGroupBeforeByName);
1693 
1694   DiagGroupParentMap DGParentMap(Records);
1695 
1696   std::map<std::string, GroupInfo> DiagsInGroup;
1697   groupDiagnostics(Diags, DiagGroups, DiagsInGroup);
1698 
1699   // Compute the set of diagnostics that are in -Wpedantic.
1700   {
1701     RecordSet DiagsInPedanticSet;
1702     RecordSet GroupsInPedanticSet;
1703     InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup);
1704     inferPedantic.compute(&DiagsInPedanticSet, &GroupsInPedanticSet);
1705     auto &PedDiags = DiagsInGroup["pedantic"];
1706     // Put the diagnostics into a deterministic order.
1707     RecordVec DiagsInPedantic(DiagsInPedanticSet.begin(),
1708                               DiagsInPedanticSet.end());
1709     RecordVec GroupsInPedantic(GroupsInPedanticSet.begin(),
1710                                GroupsInPedanticSet.end());
1711     llvm::sort(DiagsInPedantic, beforeThanCompare);
1712     llvm::sort(GroupsInPedantic, beforeThanCompare);
1713     PedDiags.DiagsInGroup.insert(PedDiags.DiagsInGroup.end(),
1714                                  DiagsInPedantic.begin(),
1715                                  DiagsInPedantic.end());
1716     for (auto *Group : GroupsInPedantic)
1717       PedDiags.SubGroups.push_back(Group->getValueAsString("GroupName"));
1718   }
1719 
1720   // FIXME: Write diagnostic categories and link to diagnostic groups in each.
1721 
1722   // Write out the diagnostic groups.
1723   for (const Record *G : DiagGroups) {
1724     bool IsRemarkGroup = isRemarkGroup(G, DiagsInGroup);
1725     auto &GroupInfo = DiagsInGroup[G->getValueAsString("GroupName")];
1726     bool IsSynonym = GroupInfo.DiagsInGroup.empty() &&
1727                      GroupInfo.SubGroups.size() == 1;
1728 
1729     writeHeader(((IsRemarkGroup ? "-R" : "-W") +
1730                     G->getValueAsString("GroupName")).str(),
1731                 OS);
1732 
1733     if (!IsSynonym) {
1734       // FIXME: Ideally, all the diagnostics in a group should have the same
1735       // default state, but that is not currently the case.
1736       auto DefaultSeverities = getDefaultSeverities(G, DiagsInGroup);
1737       if (!DefaultSeverities.empty() && !DefaultSeverities.count("Ignored")) {
1738         bool AnyNonErrors = DefaultSeverities.count("Warning") ||
1739                             DefaultSeverities.count("Remark");
1740         if (!AnyNonErrors)
1741           OS << "This diagnostic is an error by default, but the flag ``-Wno-"
1742              << G->getValueAsString("GroupName") << "`` can be used to disable "
1743              << "the error.\n\n";
1744         else
1745           OS << "This diagnostic is enabled by default.\n\n";
1746       } else if (DefaultSeverities.size() > 1) {
1747         OS << "Some of the diagnostics controlled by this flag are enabled "
1748            << "by default.\n\n";
1749       }
1750     }
1751 
1752     if (!GroupInfo.SubGroups.empty()) {
1753       if (IsSynonym)
1754         OS << "Synonym for ";
1755       else if (GroupInfo.DiagsInGroup.empty())
1756         OS << "Controls ";
1757       else
1758         OS << "Also controls ";
1759 
1760       bool First = true;
1761       llvm::sort(GroupInfo.SubGroups);
1762       for (const auto &Name : GroupInfo.SubGroups) {
1763         if (!First) OS << ", ";
1764         OS << "`" << (IsRemarkGroup ? "-R" : "-W") << Name << "`_";
1765         First = false;
1766       }
1767       OS << ".\n\n";
1768     }
1769 
1770     if (!GroupInfo.DiagsInGroup.empty()) {
1771       OS << "**Diagnostic text:**\n\n";
1772       for (const Record *D : GroupInfo.DiagsInGroup) {
1773         auto Severity = getDefaultSeverity(D);
1774         Severity[0] = tolower(Severity[0]);
1775         if (Severity == "ignored")
1776           Severity = IsRemarkGroup ? "remark" : "warning";
1777 
1778         writeDiagnosticText(Builder, D, Severity, OS);
1779       }
1780     }
1781 
1782     auto Doc = G->getValueAsString("Documentation");
1783     if (!Doc.empty())
1784       OS << Doc;
1785     else if (GroupInfo.SubGroups.empty() && GroupInfo.DiagsInGroup.empty())
1786       OS << "This diagnostic flag exists for GCC compatibility, and has no "
1787             "effect in Clang.\n";
1788     OS << "\n";
1789   }
1790 }
1791