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