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