xref: /llvm-project/clang/lib/Basic/Diagnostic.cpp (revision 0865ecc5150b9a55ba1f9e30b6d463a66ac362a6)
1 //===- Diagnostic.cpp - C Language Family Diagnostic Handling -------------===//
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 //  This file implements the Diagnostic-related interfaces.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "clang/Basic/Diagnostic.h"
14 #include "clang/Basic/CharInfo.h"
15 #include "clang/Basic/DiagnosticDriver.h"
16 #include "clang/Basic/DiagnosticError.h"
17 #include "clang/Basic/DiagnosticFrontend.h"
18 #include "clang/Basic/DiagnosticIDs.h"
19 #include "clang/Basic/DiagnosticOptions.h"
20 #include "clang/Basic/IdentifierTable.h"
21 #include "clang/Basic/PartialDiagnostic.h"
22 #include "clang/Basic/SourceLocation.h"
23 #include "clang/Basic/SourceManager.h"
24 #include "clang/Basic/Specifiers.h"
25 #include "clang/Basic/TokenKinds.h"
26 #include "llvm/ADT/IntrusiveRefCntPtr.h"
27 #include "llvm/ADT/SmallString.h"
28 #include "llvm/ADT/SmallVector.h"
29 #include "llvm/ADT/StringExtras.h"
30 #include "llvm/ADT/StringMap.h"
31 #include "llvm/ADT/StringRef.h"
32 #include "llvm/Support/ConvertUTF.h"
33 #include "llvm/Support/CrashRecoveryContext.h"
34 #include "llvm/Support/Error.h"
35 #include "llvm/Support/MemoryBuffer.h"
36 #include "llvm/Support/SpecialCaseList.h"
37 #include "llvm/Support/Unicode.h"
38 #include "llvm/Support/VirtualFileSystem.h"
39 #include "llvm/Support/raw_ostream.h"
40 #include <algorithm>
41 #include <cassert>
42 #include <cstddef>
43 #include <cstdint>
44 #include <cstring>
45 #include <limits>
46 #include <memory>
47 #include <string>
48 #include <utility>
49 #include <vector>
50 
51 using namespace clang;
52 
53 const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
54                                              DiagNullabilityKind nullability) {
55   DB.AddString(
56       ("'" +
57        getNullabilitySpelling(nullability.first,
58                               /*isContextSensitive=*/nullability.second) +
59        "'")
60           .str());
61   return DB;
62 }
63 
64 const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
65                                              llvm::Error &&E) {
66   DB.AddString(toString(std::move(E)));
67   return DB;
68 }
69 
70 static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT,
71                             StringRef Modifier, StringRef Argument,
72                             ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
73                             SmallVectorImpl<char> &Output,
74                             void *Cookie,
75                             ArrayRef<intptr_t> QualTypeVals) {
76   StringRef Str = "<can't format argument>";
77   Output.append(Str.begin(), Str.end());
78 }
79 
80 DiagnosticsEngine::DiagnosticsEngine(
81     IntrusiveRefCntPtr<DiagnosticIDs> diags,
82     IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, DiagnosticConsumer *client,
83     bool ShouldOwnClient)
84     : Diags(std::move(diags)), DiagOpts(std::move(DiagOpts)) {
85   setClient(client, ShouldOwnClient);
86   ArgToStringFn = DummyArgToStringFn;
87 
88   Reset();
89 }
90 
91 DiagnosticsEngine::~DiagnosticsEngine() {
92   // If we own the diagnostic client, destroy it first so that it can access the
93   // engine from its destructor.
94   setClient(nullptr);
95 }
96 
97 void DiagnosticsEngine::dump() const {
98   DiagStatesByLoc.dump(*SourceMgr);
99 }
100 
101 void DiagnosticsEngine::dump(StringRef DiagName) const {
102   DiagStatesByLoc.dump(*SourceMgr, DiagName);
103 }
104 
105 void DiagnosticsEngine::setClient(DiagnosticConsumer *client,
106                                   bool ShouldOwnClient) {
107   Owner.reset(ShouldOwnClient ? client : nullptr);
108   Client = client;
109 }
110 
111 void DiagnosticsEngine::pushMappings(SourceLocation Loc) {
112   DiagStateOnPushStack.push_back(GetCurDiagState());
113 }
114 
115 bool DiagnosticsEngine::popMappings(SourceLocation Loc) {
116   if (DiagStateOnPushStack.empty())
117     return false;
118 
119   if (DiagStateOnPushStack.back() != GetCurDiagState()) {
120     // State changed at some point between push/pop.
121     PushDiagStatePoint(DiagStateOnPushStack.back(), Loc);
122   }
123   DiagStateOnPushStack.pop_back();
124   return true;
125 }
126 
127 void DiagnosticsEngine::Reset(bool soft /*=false*/) {
128   ErrorOccurred = false;
129   UncompilableErrorOccurred = false;
130   FatalErrorOccurred = false;
131   UnrecoverableErrorOccurred = false;
132 
133   NumWarnings = 0;
134   NumErrors = 0;
135   TrapNumErrorsOccurred = 0;
136   TrapNumUnrecoverableErrorsOccurred = 0;
137 
138   LastDiagLevel = DiagnosticIDs::Ignored;
139 
140   if (!soft) {
141     // Clear state related to #pragma diagnostic.
142     DiagStates.clear();
143     DiagStatesByLoc.clear();
144     DiagStateOnPushStack.clear();
145 
146     // Create a DiagState and DiagStatePoint representing diagnostic changes
147     // through command-line.
148     DiagStates.emplace_back(*Diags);
149     DiagStatesByLoc.appendFirst(&DiagStates.back());
150   }
151 }
152 
153 DiagnosticMapping &
154 DiagnosticsEngine::DiagState::getOrAddMapping(diag::kind Diag) {
155   std::pair<iterator, bool> Result =
156       DiagMap.insert(std::make_pair(Diag, DiagnosticMapping()));
157 
158   // Initialize the entry if we added it.
159   if (Result.second) {
160     Result.first->second = DiagIDs.getDefaultMapping(Diag);
161     if (DiagnosticIDs::IsCustomDiag(Diag))
162       DiagIDs.initCustomDiagMapping(Result.first->second, Diag);
163   }
164 
165   return Result.first->second;
166 }
167 
168 void DiagnosticsEngine::DiagStateMap::appendFirst(DiagState *State) {
169   assert(Files.empty() && "not first");
170   FirstDiagState = CurDiagState = State;
171   CurDiagStateLoc = SourceLocation();
172 }
173 
174 void DiagnosticsEngine::DiagStateMap::append(SourceManager &SrcMgr,
175                                              SourceLocation Loc,
176                                              DiagState *State) {
177   CurDiagState = State;
178   CurDiagStateLoc = Loc;
179 
180   std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedLoc(Loc);
181   unsigned Offset = Decomp.second;
182   for (File *F = getFile(SrcMgr, Decomp.first); F;
183        Offset = F->ParentOffset, F = F->Parent) {
184     F->HasLocalTransitions = true;
185     auto &Last = F->StateTransitions.back();
186     assert(Last.Offset <= Offset && "state transitions added out of order");
187 
188     if (Last.Offset == Offset) {
189       if (Last.State == State)
190         break;
191       Last.State = State;
192       continue;
193     }
194 
195     F->StateTransitions.push_back({State, Offset});
196   }
197 }
198 
199 DiagnosticsEngine::DiagState *
200 DiagnosticsEngine::DiagStateMap::lookup(SourceManager &SrcMgr,
201                                         SourceLocation Loc) const {
202   // Common case: we have not seen any diagnostic pragmas.
203   if (Files.empty())
204     return FirstDiagState;
205 
206   std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedLoc(Loc);
207   const File *F = getFile(SrcMgr, Decomp.first);
208   return F->lookup(Decomp.second);
209 }
210 
211 DiagnosticsEngine::DiagState *
212 DiagnosticsEngine::DiagStateMap::File::lookup(unsigned Offset) const {
213   auto OnePastIt =
214       llvm::partition_point(StateTransitions, [=](const DiagStatePoint &P) {
215         return P.Offset <= Offset;
216       });
217   assert(OnePastIt != StateTransitions.begin() && "missing initial state");
218   return OnePastIt[-1].State;
219 }
220 
221 DiagnosticsEngine::DiagStateMap::File *
222 DiagnosticsEngine::DiagStateMap::getFile(SourceManager &SrcMgr,
223                                          FileID ID) const {
224   // Get or insert the File for this ID.
225   auto Range = Files.equal_range(ID);
226   if (Range.first != Range.second)
227     return &Range.first->second;
228   auto &F = Files.insert(Range.first, std::make_pair(ID, File()))->second;
229 
230   // We created a new File; look up the diagnostic state at the start of it and
231   // initialize it.
232   if (ID.isValid()) {
233     std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedIncludedLoc(ID);
234     F.Parent = getFile(SrcMgr, Decomp.first);
235     F.ParentOffset = Decomp.second;
236     F.StateTransitions.push_back({F.Parent->lookup(Decomp.second), 0});
237   } else {
238     // This is the (imaginary) root file into which we pretend all top-level
239     // files are included; it descends from the initial state.
240     //
241     // FIXME: This doesn't guarantee that we use the same ordering as
242     // isBeforeInTranslationUnit in the cases where someone invented another
243     // top-level file and added diagnostic pragmas to it. See the code at the
244     // end of isBeforeInTranslationUnit for the quirks it deals with.
245     F.StateTransitions.push_back({FirstDiagState, 0});
246   }
247   return &F;
248 }
249 
250 void DiagnosticsEngine::DiagStateMap::dump(SourceManager &SrcMgr,
251                                            StringRef DiagName) const {
252   llvm::errs() << "diagnostic state at ";
253   CurDiagStateLoc.print(llvm::errs(), SrcMgr);
254   llvm::errs() << ": " << CurDiagState << "\n";
255 
256   for (auto &F : Files) {
257     FileID ID = F.first;
258     File &File = F.second;
259 
260     bool PrintedOuterHeading = false;
261     auto PrintOuterHeading = [&] {
262       if (PrintedOuterHeading) return;
263       PrintedOuterHeading = true;
264 
265       llvm::errs() << "File " << &File << " <FileID " << ID.getHashValue()
266                    << ">: " << SrcMgr.getBufferOrFake(ID).getBufferIdentifier();
267 
268       if (F.second.Parent) {
269         std::pair<FileID, unsigned> Decomp =
270             SrcMgr.getDecomposedIncludedLoc(ID);
271         assert(File.ParentOffset == Decomp.second);
272         llvm::errs() << " parent " << File.Parent << " <FileID "
273                      << Decomp.first.getHashValue() << "> ";
274         SrcMgr.getLocForStartOfFile(Decomp.first)
275               .getLocWithOffset(Decomp.second)
276               .print(llvm::errs(), SrcMgr);
277       }
278       if (File.HasLocalTransitions)
279         llvm::errs() << " has_local_transitions";
280       llvm::errs() << "\n";
281     };
282 
283     if (DiagName.empty())
284       PrintOuterHeading();
285 
286     for (DiagStatePoint &Transition : File.StateTransitions) {
287       bool PrintedInnerHeading = false;
288       auto PrintInnerHeading = [&] {
289         if (PrintedInnerHeading) return;
290         PrintedInnerHeading = true;
291 
292         PrintOuterHeading();
293         llvm::errs() << "  ";
294         SrcMgr.getLocForStartOfFile(ID)
295               .getLocWithOffset(Transition.Offset)
296               .print(llvm::errs(), SrcMgr);
297         llvm::errs() << ": state " << Transition.State << ":\n";
298       };
299 
300       if (DiagName.empty())
301         PrintInnerHeading();
302 
303       for (auto &Mapping : *Transition.State) {
304         StringRef Option =
305             SrcMgr.getDiagnostics().Diags->getWarningOptionForDiag(
306                 Mapping.first);
307         if (!DiagName.empty() && DiagName != Option)
308           continue;
309 
310         PrintInnerHeading();
311         llvm::errs() << "    ";
312         if (Option.empty())
313           llvm::errs() << "<unknown " << Mapping.first << ">";
314         else
315           llvm::errs() << Option;
316         llvm::errs() << ": ";
317 
318         switch (Mapping.second.getSeverity()) {
319         case diag::Severity::Ignored: llvm::errs() << "ignored"; break;
320         case diag::Severity::Remark: llvm::errs() << "remark"; break;
321         case diag::Severity::Warning: llvm::errs() << "warning"; break;
322         case diag::Severity::Error: llvm::errs() << "error"; break;
323         case diag::Severity::Fatal: llvm::errs() << "fatal"; break;
324         }
325 
326         if (!Mapping.second.isUser())
327           llvm::errs() << " default";
328         if (Mapping.second.isPragma())
329           llvm::errs() << " pragma";
330         if (Mapping.second.hasNoWarningAsError())
331           llvm::errs() << " no-error";
332         if (Mapping.second.hasNoErrorAsFatal())
333           llvm::errs() << " no-fatal";
334         if (Mapping.second.wasUpgradedFromWarning())
335           llvm::errs() << " overruled";
336         llvm::errs() << "\n";
337       }
338     }
339   }
340 }
341 
342 void DiagnosticsEngine::PushDiagStatePoint(DiagState *State,
343                                            SourceLocation Loc) {
344   assert(Loc.isValid() && "Adding invalid loc point");
345   DiagStatesByLoc.append(*SourceMgr, Loc, State);
346 }
347 
348 void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map,
349                                     SourceLocation L) {
350   assert((Diags->isWarningOrExtension(Diag) ||
351           (Map == diag::Severity::Fatal || Map == diag::Severity::Error)) &&
352          "Cannot map errors into warnings!");
353   assert((L.isInvalid() || SourceMgr) && "No SourceMgr for valid location");
354 
355   // A command line -Wfoo has an invalid L and cannot override error/fatal
356   // mapping, while a warning pragma can.
357   bool WasUpgradedFromWarning = false;
358   if (Map == diag::Severity::Warning && L.isInvalid()) {
359     DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag);
360     if (Info.getSeverity() == diag::Severity::Error ||
361         Info.getSeverity() == diag::Severity::Fatal) {
362       Map = Info.getSeverity();
363       WasUpgradedFromWarning = true;
364     }
365   }
366   DiagnosticMapping Mapping = makeUserMapping(Map, L);
367   Mapping.setUpgradedFromWarning(WasUpgradedFromWarning);
368 
369   // Make sure we propagate the NoWarningAsError flag from an existing
370   // mapping (which may be the default mapping).
371   DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag);
372   Mapping.setNoWarningAsError(Info.hasNoWarningAsError() ||
373                               Mapping.hasNoWarningAsError());
374 
375   // Common case; setting all the diagnostics of a group in one place.
376   if ((L.isInvalid() || L == DiagStatesByLoc.getCurDiagStateLoc()) &&
377       DiagStatesByLoc.getCurDiagState()) {
378     // FIXME: This is theoretically wrong: if the current state is shared with
379     // some other location (via push/pop) we will change the state for that
380     // other location as well. This cannot currently happen, as we can't update
381     // the diagnostic state at the same location at which we pop.
382     DiagStatesByLoc.getCurDiagState()->setMapping(Diag, Mapping);
383     return;
384   }
385 
386   // A diagnostic pragma occurred, create a new DiagState initialized with
387   // the current one and a new DiagStatePoint to record at which location
388   // the new state became active.
389   DiagStates.push_back(*GetCurDiagState());
390   DiagStates.back().setMapping(Diag, Mapping);
391   PushDiagStatePoint(&DiagStates.back(), L);
392 }
393 
394 bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor,
395                                             StringRef Group, diag::Severity Map,
396                                             SourceLocation Loc) {
397   // Get the diagnostics in this group.
398   SmallVector<diag::kind, 256> GroupDiags;
399   if (Diags->getDiagnosticsInGroup(Flavor, Group, GroupDiags))
400     return true;
401 
402   Diags->setGroupSeverity(Group, Map);
403 
404   // Set the mapping.
405   for (diag::kind Diag : GroupDiags)
406     setSeverity(Diag, Map, Loc);
407 
408   return false;
409 }
410 
411 bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor,
412                                             diag::Group Group,
413                                             diag::Severity Map,
414                                             SourceLocation Loc) {
415   return setSeverityForGroup(Flavor, Diags->getWarningOptionForGroup(Group),
416                              Map, Loc);
417 }
418 
419 bool DiagnosticsEngine::setDiagnosticGroupWarningAsError(StringRef Group,
420                                                          bool Enabled) {
421   // If we are enabling this feature, just set the diagnostic mappings to map to
422   // errors.
423   if (Enabled)
424     return setSeverityForGroup(diag::Flavor::WarningOrError, Group,
425                                diag::Severity::Error);
426   Diags->setGroupSeverity(Group, diag::Severity::Warning);
427 
428   // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and
429   // potentially downgrade anything already mapped to be a warning.
430 
431   // Get the diagnostics in this group.
432   SmallVector<diag::kind, 8> GroupDiags;
433   if (Diags->getDiagnosticsInGroup(diag::Flavor::WarningOrError, Group,
434                                    GroupDiags))
435     return true;
436 
437   // Perform the mapping change.
438   for (diag::kind Diag : GroupDiags) {
439     DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag);
440 
441     if (Info.getSeverity() == diag::Severity::Error ||
442         Info.getSeverity() == diag::Severity::Fatal)
443       Info.setSeverity(diag::Severity::Warning);
444 
445     Info.setNoWarningAsError(true);
446   }
447 
448   return false;
449 }
450 
451 bool DiagnosticsEngine::setDiagnosticGroupErrorAsFatal(StringRef Group,
452                                                        bool Enabled) {
453   // If we are enabling this feature, just set the diagnostic mappings to map to
454   // fatal errors.
455   if (Enabled)
456     return setSeverityForGroup(diag::Flavor::WarningOrError, Group,
457                                diag::Severity::Fatal);
458   Diags->setGroupSeverity(Group, diag::Severity::Error);
459 
460   // Otherwise, we want to set the diagnostic mapping's "no Wfatal-errors" bit,
461   // and potentially downgrade anything already mapped to be a fatal error.
462 
463   // Get the diagnostics in this group.
464   SmallVector<diag::kind, 8> GroupDiags;
465   if (Diags->getDiagnosticsInGroup(diag::Flavor::WarningOrError, Group,
466                                    GroupDiags))
467     return true;
468 
469   // Perform the mapping change.
470   for (diag::kind Diag : GroupDiags) {
471     DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag);
472 
473     if (Info.getSeverity() == diag::Severity::Fatal)
474       Info.setSeverity(diag::Severity::Error);
475 
476     Info.setNoErrorAsFatal(true);
477   }
478 
479   return false;
480 }
481 
482 void DiagnosticsEngine::setSeverityForAll(diag::Flavor Flavor,
483                                           diag::Severity Map,
484                                           SourceLocation Loc) {
485   // Get all the diagnostics.
486   std::vector<diag::kind> AllDiags;
487   DiagnosticIDs::getAllDiagnostics(Flavor, AllDiags);
488 
489   // Set the mapping.
490   for (diag::kind Diag : AllDiags)
491     if (Diags->isWarningOrExtension(Diag))
492       setSeverity(Diag, Map, Loc);
493 }
494 
495 namespace {
496 // FIXME: We should isolate the parser from SpecialCaseList and just use it
497 // here.
498 class WarningsSpecialCaseList : public llvm::SpecialCaseList {
499 public:
500   static std::unique_ptr<WarningsSpecialCaseList>
501   create(const llvm::MemoryBuffer &Input, std::string &Err);
502 
503   // Section names refer to diagnostic groups, which cover multiple individual
504   // diagnostics. Expand diagnostic groups here to individual diagnostics.
505   // A diagnostic can have multiple diagnostic groups associated with it, we let
506   // the last section take precedence in such cases.
507   void processSections(DiagnosticsEngine &Diags);
508 
509   bool isDiagSuppressed(diag::kind DiagId, SourceLocation DiagLoc,
510                         const SourceManager &SM) const;
511 
512 private:
513   // Find the longest glob pattern that matches FilePath amongst
514   // CategoriesToMatchers, return true iff the match exists and belongs to a
515   // positive category.
516   bool globsMatches(const llvm::StringMap<Matcher> &CategoriesToMatchers,
517                     StringRef FilePath) const;
518 
519   llvm::DenseMap<diag::kind, const Section *> DiagToSection;
520 };
521 } // namespace
522 
523 std::unique_ptr<WarningsSpecialCaseList>
524 WarningsSpecialCaseList::create(const llvm::MemoryBuffer &Input,
525                                 std::string &Err) {
526   auto WarningSuppressionList = std::make_unique<WarningsSpecialCaseList>();
527   if (!WarningSuppressionList->createInternal(&Input, Err))
528     return nullptr;
529   return WarningSuppressionList;
530 }
531 
532 void WarningsSpecialCaseList::processSections(DiagnosticsEngine &Diags) {
533   // Drop the default section introduced by special case list, we only support
534   // exact diagnostic group names.
535   // FIXME: We should make this configurable in the parser instead.
536   Sections.erase("*");
537   // Make sure we iterate sections by their line numbers.
538   std::vector<std::pair<unsigned, const llvm::StringMapEntry<Section> *>>
539       LineAndSectionEntry;
540   LineAndSectionEntry.reserve(Sections.size());
541   for (const auto &Entry : Sections) {
542     StringRef DiagName = Entry.getKey();
543     // Each section has a matcher with that section's name, attached to that
544     // line.
545     const auto &DiagSectionMatcher = Entry.getValue().SectionMatcher;
546     unsigned DiagLine = DiagSectionMatcher->Globs.at(DiagName).second;
547     LineAndSectionEntry.emplace_back(DiagLine, &Entry);
548   }
549   llvm::sort(LineAndSectionEntry);
550   static constexpr auto WarningFlavor = clang::diag::Flavor::WarningOrError;
551   for (const auto &[_, SectionEntry] : LineAndSectionEntry) {
552     SmallVector<diag::kind> GroupDiags;
553     StringRef DiagGroup = SectionEntry->getKey();
554     if (Diags.getDiagnosticIDs()->getDiagnosticsInGroup(
555             WarningFlavor, DiagGroup, GroupDiags)) {
556       StringRef Suggestion =
557           DiagnosticIDs::getNearestOption(WarningFlavor, DiagGroup);
558       Diags.Report(diag::warn_unknown_diag_option)
559           << static_cast<unsigned>(WarningFlavor) << DiagGroup
560           << !Suggestion.empty() << Suggestion;
561       continue;
562     }
563     for (diag::kind Diag : GroupDiags)
564       // We're intentionally overwriting any previous mappings here to make sure
565       // latest one takes precedence.
566       DiagToSection[Diag] = &SectionEntry->getValue();
567   }
568 }
569 
570 void DiagnosticsEngine::setDiagSuppressionMapping(llvm::MemoryBuffer &Input) {
571   std::string Error;
572   auto WarningSuppressionList = WarningsSpecialCaseList::create(Input, Error);
573   if (!WarningSuppressionList) {
574     // FIXME: Use a `%select` statement instead of printing `Error` as-is. This
575     // should help localization.
576     Report(diag::err_drv_malformed_warning_suppression_mapping)
577         << Input.getBufferIdentifier() << Error;
578     return;
579   }
580   WarningSuppressionList->processSections(*this);
581   DiagSuppressionMapping =
582       [WarningSuppressionList(std::move(WarningSuppressionList))](
583           diag::kind DiagId, SourceLocation DiagLoc, const SourceManager &SM) {
584         return WarningSuppressionList->isDiagSuppressed(DiagId, DiagLoc, SM);
585       };
586 }
587 
588 bool WarningsSpecialCaseList::isDiagSuppressed(diag::kind DiagId,
589                                                SourceLocation DiagLoc,
590                                                const SourceManager &SM) const {
591   const Section *DiagSection = DiagToSection.lookup(DiagId);
592   if (!DiagSection)
593     return false;
594   const SectionEntries &EntityTypeToCategories = DiagSection->Entries;
595   auto SrcEntriesIt = EntityTypeToCategories.find("src");
596   if (SrcEntriesIt == EntityTypeToCategories.end())
597     return false;
598   const llvm::StringMap<llvm::SpecialCaseList::Matcher> &CategoriesToMatchers =
599       SrcEntriesIt->getValue();
600   // We also use presumed locations here to improve reproducibility for
601   // preprocessed inputs.
602   if (PresumedLoc PLoc = SM.getPresumedLoc(DiagLoc); PLoc.isValid())
603     return globsMatches(
604         CategoriesToMatchers,
605         llvm::sys::path::remove_leading_dotslash(PLoc.getFilename()));
606   return false;
607 }
608 
609 bool WarningsSpecialCaseList::globsMatches(
610     const llvm::StringMap<Matcher> &CategoriesToMatchers,
611     StringRef FilePath) const {
612   StringRef LongestMatch;
613   bool LongestIsPositive = false;
614   for (const auto &Entry : CategoriesToMatchers) {
615     StringRef Category = Entry.getKey();
616     const llvm::SpecialCaseList::Matcher &Matcher = Entry.getValue();
617     bool IsPositive = Category != "emit";
618     for (const auto &[Pattern, Glob] : Matcher.Globs) {
619       if (Pattern.size() < LongestMatch.size())
620         continue;
621       if (!Glob.first.match(FilePath))
622         continue;
623       LongestMatch = Pattern;
624       LongestIsPositive = IsPositive;
625     }
626   }
627   return LongestIsPositive;
628 }
629 
630 bool DiagnosticsEngine::isSuppressedViaMapping(diag::kind DiagId,
631                                                SourceLocation DiagLoc) const {
632   if (!hasSourceManager() || !DiagSuppressionMapping)
633     return false;
634   return DiagSuppressionMapping(DiagId, DiagLoc, getSourceManager());
635 }
636 
637 void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) {
638   DiagnosticStorage DiagStorage;
639   DiagStorage.DiagRanges.append(storedDiag.range_begin(),
640                                 storedDiag.range_end());
641 
642   DiagStorage.FixItHints.append(storedDiag.fixit_begin(),
643                                 storedDiag.fixit_end());
644 
645   assert(Client && "DiagnosticConsumer not set!");
646   Level DiagLevel = storedDiag.getLevel();
647   Diagnostic Info(this, storedDiag.getLocation(), storedDiag.getID(),
648                   DiagStorage, storedDiag.getMessage());
649   Client->HandleDiagnostic(DiagLevel, Info);
650   if (Client->IncludeInDiagnosticCounts()) {
651     if (DiagLevel == DiagnosticsEngine::Warning)
652       ++NumWarnings;
653   }
654 }
655 
656 bool DiagnosticsEngine::EmitDiagnostic(const DiagnosticBuilder &DB,
657                                        bool Force) {
658   assert(getClient() && "DiagnosticClient not set!");
659 
660   bool Emitted;
661   if (Force) {
662     Diagnostic Info(this, DB);
663 
664     // Figure out the diagnostic level of this message.
665     DiagnosticIDs::Level DiagLevel
666       = Diags->getDiagnosticLevel(Info.getID(), Info.getLocation(), *this);
667 
668     Emitted = (DiagLevel != DiagnosticIDs::Ignored);
669     if (Emitted) {
670       // Emit the diagnostic regardless of suppression level.
671       Diags->EmitDiag(*this, DB, DiagLevel);
672     }
673   } else {
674     // Process the diagnostic, sending the accumulated information to the
675     // DiagnosticConsumer.
676     Emitted = ProcessDiag(DB);
677   }
678 
679   return Emitted;
680 }
681 
682 DiagnosticBuilder::DiagnosticBuilder(DiagnosticsEngine *DiagObj,
683                                      SourceLocation DiagLoc, unsigned DiagID)
684     : StreamingDiagnostic(DiagObj->DiagAllocator), DiagObj(DiagObj),
685       DiagLoc(DiagLoc), DiagID(DiagID), IsActive(true) {
686   assert(DiagObj && "DiagnosticBuilder requires a valid DiagnosticsEngine!");
687 }
688 
689 DiagnosticBuilder::DiagnosticBuilder(const DiagnosticBuilder &D)
690     : StreamingDiagnostic() {
691   DiagLoc = D.DiagLoc;
692   DiagID = D.DiagID;
693   FlagValue = D.FlagValue;
694   DiagObj = D.DiagObj;
695   DiagStorage = D.DiagStorage;
696   D.DiagStorage = nullptr;
697   Allocator = D.Allocator;
698   IsActive = D.IsActive;
699   IsForceEmit = D.IsForceEmit;
700   D.Clear();
701 }
702 
703 Diagnostic::Diagnostic(const DiagnosticsEngine *DO,
704                        const DiagnosticBuilder &DiagBuilder)
705     : DiagObj(DO), DiagLoc(DiagBuilder.DiagLoc), DiagID(DiagBuilder.DiagID),
706       FlagValue(DiagBuilder.FlagValue), DiagStorage(*DiagBuilder.getStorage()) {
707 }
708 
709 Diagnostic::Diagnostic(const DiagnosticsEngine *DO, SourceLocation DiagLoc,
710                        unsigned DiagID, const DiagnosticStorage &DiagStorage,
711                        StringRef StoredDiagMessage)
712     : DiagObj(DO), DiagLoc(DiagLoc), DiagID(DiagID), DiagStorage(DiagStorage),
713       StoredDiagMessage(StoredDiagMessage) {}
714 
715 DiagnosticConsumer::~DiagnosticConsumer() = default;
716 
717 void DiagnosticConsumer::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
718                                         const Diagnostic &Info) {
719   if (!IncludeInDiagnosticCounts())
720     return;
721 
722   if (DiagLevel == DiagnosticsEngine::Warning)
723     ++NumWarnings;
724   else if (DiagLevel >= DiagnosticsEngine::Error)
725     ++NumErrors;
726 }
727 
728 /// ModifierIs - Return true if the specified modifier matches specified string.
729 template <std::size_t StrLen>
730 static bool ModifierIs(const char *Modifier, unsigned ModifierLen,
731                        const char (&Str)[StrLen]) {
732   return StrLen-1 == ModifierLen && memcmp(Modifier, Str, StrLen-1) == 0;
733 }
734 
735 /// ScanForward - Scans forward, looking for the given character, skipping
736 /// nested clauses and escaped characters.
737 static const char *ScanFormat(const char *I, const char *E, char Target) {
738   unsigned Depth = 0;
739 
740   for ( ; I != E; ++I) {
741     if (Depth == 0 && *I == Target) return I;
742     if (Depth != 0 && *I == '}') Depth--;
743 
744     if (*I == '%') {
745       I++;
746       if (I == E) break;
747 
748       // Escaped characters get implicitly skipped here.
749 
750       // Format specifier.
751       if (!isDigit(*I) && !isPunctuation(*I)) {
752         for (I++; I != E && !isDigit(*I) && *I != '{'; I++) ;
753         if (I == E) break;
754         if (*I == '{')
755           Depth++;
756       }
757     }
758   }
759   return E;
760 }
761 
762 /// HandleSelectModifier - Handle the integer 'select' modifier.  This is used
763 /// like this:  %select{foo|bar|baz}2.  This means that the integer argument
764 /// "%2" has a value from 0-2.  If the value is 0, the diagnostic prints 'foo'.
765 /// If the value is 1, it prints 'bar'.  If it has the value 2, it prints 'baz'.
766 /// This is very useful for certain classes of variant diagnostics.
767 static void HandleSelectModifier(const Diagnostic &DInfo, unsigned ValNo,
768                                  const char *Argument, unsigned ArgumentLen,
769                                  SmallVectorImpl<char> &OutStr) {
770   const char *ArgumentEnd = Argument+ArgumentLen;
771 
772   // Skip over 'ValNo' |'s.
773   while (ValNo) {
774     const char *NextVal = ScanFormat(Argument, ArgumentEnd, '|');
775     assert(NextVal != ArgumentEnd && "Value for integer select modifier was"
776            " larger than the number of options in the diagnostic string!");
777     Argument = NextVal+1;  // Skip this string.
778     --ValNo;
779   }
780 
781   // Get the end of the value.  This is either the } or the |.
782   const char *EndPtr = ScanFormat(Argument, ArgumentEnd, '|');
783 
784   // Recursively format the result of the select clause into the output string.
785   DInfo.FormatDiagnostic(Argument, EndPtr, OutStr);
786 }
787 
788 /// HandleIntegerSModifier - Handle the integer 's' modifier.  This adds the
789 /// letter 's' to the string if the value is not 1.  This is used in cases like
790 /// this:  "you idiot, you have %4 parameter%s4!".
791 static void HandleIntegerSModifier(unsigned ValNo,
792                                    SmallVectorImpl<char> &OutStr) {
793   if (ValNo != 1)
794     OutStr.push_back('s');
795 }
796 
797 /// HandleOrdinalModifier - Handle the integer 'ord' modifier.  This
798 /// prints the ordinal form of the given integer, with 1 corresponding
799 /// to the first ordinal.  Currently this is hard-coded to use the
800 /// English form.
801 static void HandleOrdinalModifier(unsigned ValNo,
802                                   SmallVectorImpl<char> &OutStr) {
803   assert(ValNo != 0 && "ValNo must be strictly positive!");
804 
805   llvm::raw_svector_ostream Out(OutStr);
806 
807   // We could use text forms for the first N ordinals, but the numeric
808   // forms are actually nicer in diagnostics because they stand out.
809   Out << ValNo << llvm::getOrdinalSuffix(ValNo);
810 }
811 
812 // 123 -> "123".
813 // 1234 -> "1.23k".
814 // 123456 -> "123.46k".
815 // 1234567 -> "1.23M".
816 // 1234567890 -> "1.23G".
817 // 1234567890123 -> "1.23T".
818 static void HandleIntegerHumanModifier(int64_t ValNo,
819                                        SmallVectorImpl<char> &OutStr) {
820   static constexpr std::array<std::pair<int64_t, char>, 4> Units = {
821       {{1'000'000'000'000L, 'T'},
822        {1'000'000'000L, 'G'},
823        {1'000'000L, 'M'},
824        {1'000L, 'k'}}};
825 
826   llvm::raw_svector_ostream Out(OutStr);
827   if (ValNo < 0) {
828     Out << "-";
829     ValNo = -ValNo;
830   }
831   for (const auto &[UnitSize, UnitSign] : Units) {
832     if (ValNo >= UnitSize) {
833       Out << llvm::format("%0.2f%c", ValNo / static_cast<double>(UnitSize),
834                           UnitSign);
835       return;
836     }
837   }
838   Out << ValNo;
839 }
840 
841 /// PluralNumber - Parse an unsigned integer and advance Start.
842 static unsigned PluralNumber(const char *&Start, const char *End) {
843   // Programming 101: Parse a decimal number :-)
844   unsigned Val = 0;
845   while (Start != End && *Start >= '0' && *Start <= '9') {
846     Val *= 10;
847     Val += *Start - '0';
848     ++Start;
849   }
850   return Val;
851 }
852 
853 /// TestPluralRange - Test if Val is in the parsed range. Modifies Start.
854 static bool TestPluralRange(unsigned Val, const char *&Start, const char *End) {
855   if (*Start != '[') {
856     unsigned Ref = PluralNumber(Start, End);
857     return Ref == Val;
858   }
859 
860   ++Start;
861   unsigned Low = PluralNumber(Start, End);
862   assert(*Start == ',' && "Bad plural expression syntax: expected ,");
863   ++Start;
864   unsigned High = PluralNumber(Start, End);
865   assert(*Start == ']' && "Bad plural expression syntax: expected )");
866   ++Start;
867   return Low <= Val && Val <= High;
868 }
869 
870 /// EvalPluralExpr - Actual expression evaluator for HandlePluralModifier.
871 static bool EvalPluralExpr(unsigned ValNo, const char *Start, const char *End) {
872   // Empty condition?
873   if (*Start == ':')
874     return true;
875 
876   while (true) {
877     char C = *Start;
878     if (C == '%') {
879       // Modulo expression
880       ++Start;
881       unsigned Arg = PluralNumber(Start, End);
882       assert(*Start == '=' && "Bad plural expression syntax: expected =");
883       ++Start;
884       unsigned ValMod = ValNo % Arg;
885       if (TestPluralRange(ValMod, Start, End))
886         return true;
887     } else {
888       assert((C == '[' || (C >= '0' && C <= '9')) &&
889              "Bad plural expression syntax: unexpected character");
890       // Range expression
891       if (TestPluralRange(ValNo, Start, End))
892         return true;
893     }
894 
895     // Scan for next or-expr part.
896     Start = std::find(Start, End, ',');
897     if (Start == End)
898       break;
899     ++Start;
900   }
901   return false;
902 }
903 
904 /// HandlePluralModifier - Handle the integer 'plural' modifier. This is used
905 /// for complex plural forms, or in languages where all plurals are complex.
906 /// The syntax is: %plural{cond1:form1|cond2:form2|:form3}, where condn are
907 /// conditions that are tested in order, the form corresponding to the first
908 /// that applies being emitted. The empty condition is always true, making the
909 /// last form a default case.
910 /// Conditions are simple boolean expressions, where n is the number argument.
911 /// Here are the rules.
912 /// condition  := expression | empty
913 /// empty      :=                             -> always true
914 /// expression := numeric [',' expression]    -> logical or
915 /// numeric    := range                       -> true if n in range
916 ///             | '%' number '=' range        -> true if n % number in range
917 /// range      := number
918 ///             | '[' number ',' number ']'   -> ranges are inclusive both ends
919 ///
920 /// Here are some examples from the GNU gettext manual written in this form:
921 /// English:
922 /// {1:form0|:form1}
923 /// Latvian:
924 /// {0:form2|%100=11,%10=0,%10=[2,9]:form1|:form0}
925 /// Gaeilge:
926 /// {1:form0|2:form1|:form2}
927 /// Romanian:
928 /// {1:form0|0,%100=[1,19]:form1|:form2}
929 /// Lithuanian:
930 /// {%10=0,%100=[10,19]:form2|%10=1:form0|:form1}
931 /// Russian (requires repeated form):
932 /// {%100=[11,14]:form2|%10=1:form0|%10=[2,4]:form1|:form2}
933 /// Slovak
934 /// {1:form0|[2,4]:form1|:form2}
935 /// Polish (requires repeated form):
936 /// {1:form0|%100=[10,20]:form2|%10=[2,4]:form1|:form2}
937 static void HandlePluralModifier(const Diagnostic &DInfo, unsigned ValNo,
938                                  const char *Argument, unsigned ArgumentLen,
939                                  SmallVectorImpl<char> &OutStr) {
940   const char *ArgumentEnd = Argument + ArgumentLen;
941   while (true) {
942     assert(Argument < ArgumentEnd && "Plural expression didn't match.");
943     const char *ExprEnd = Argument;
944     while (*ExprEnd != ':') {
945       assert(ExprEnd != ArgumentEnd && "Plural missing expression end");
946       ++ExprEnd;
947     }
948     if (EvalPluralExpr(ValNo, Argument, ExprEnd)) {
949       Argument = ExprEnd + 1;
950       ExprEnd = ScanFormat(Argument, ArgumentEnd, '|');
951 
952       // Recursively format the result of the plural clause into the
953       // output string.
954       DInfo.FormatDiagnostic(Argument, ExprEnd, OutStr);
955       return;
956     }
957     Argument = ScanFormat(Argument, ArgumentEnd - 1, '|') + 1;
958   }
959 }
960 
961 /// Returns the friendly description for a token kind that will appear
962 /// without quotes in diagnostic messages. These strings may be translatable in
963 /// future.
964 static const char *getTokenDescForDiagnostic(tok::TokenKind Kind) {
965   switch (Kind) {
966   case tok::identifier:
967     return "identifier";
968   default:
969     return nullptr;
970   }
971 }
972 
973 /// FormatDiagnostic - Format this diagnostic into a string, substituting the
974 /// formal arguments into the %0 slots.  The result is appended onto the Str
975 /// array.
976 void Diagnostic::
977 FormatDiagnostic(SmallVectorImpl<char> &OutStr) const {
978   if (StoredDiagMessage.has_value()) {
979     OutStr.append(StoredDiagMessage->begin(), StoredDiagMessage->end());
980     return;
981   }
982 
983   StringRef Diag =
984     getDiags()->getDiagnosticIDs()->getDescription(getID());
985 
986   FormatDiagnostic(Diag.begin(), Diag.end(), OutStr);
987 }
988 
989 /// EscapeStringForDiagnostic - Append Str to the diagnostic buffer,
990 /// escaping non-printable characters and ill-formed code unit sequences.
991 void clang::EscapeStringForDiagnostic(StringRef Str,
992                                       SmallVectorImpl<char> &OutStr) {
993   OutStr.reserve(OutStr.size() + Str.size());
994   auto *Begin = reinterpret_cast<const unsigned char *>(Str.data());
995   llvm::raw_svector_ostream OutStream(OutStr);
996   const unsigned char *End = Begin + Str.size();
997   while (Begin != End) {
998     // ASCII case
999     if (isPrintable(*Begin) || isWhitespace(*Begin)) {
1000       OutStream << *Begin;
1001       ++Begin;
1002       continue;
1003     }
1004     if (llvm::isLegalUTF8Sequence(Begin, End)) {
1005       llvm::UTF32 CodepointValue;
1006       llvm::UTF32 *CpPtr = &CodepointValue;
1007       const unsigned char *CodepointBegin = Begin;
1008       const unsigned char *CodepointEnd =
1009           Begin + llvm::getNumBytesForUTF8(*Begin);
1010       llvm::ConversionResult Res = llvm::ConvertUTF8toUTF32(
1011           &Begin, CodepointEnd, &CpPtr, CpPtr + 1, llvm::strictConversion);
1012       (void)Res;
1013       assert(
1014           llvm::conversionOK == Res &&
1015           "the sequence is legal UTF-8 but we couldn't convert it to UTF-32");
1016       assert(Begin == CodepointEnd &&
1017              "we must be further along in the string now");
1018       if (llvm::sys::unicode::isPrintable(CodepointValue) ||
1019           llvm::sys::unicode::isFormatting(CodepointValue)) {
1020         OutStr.append(CodepointBegin, CodepointEnd);
1021         continue;
1022       }
1023       // Unprintable code point.
1024       OutStream << "<U+" << llvm::format_hex_no_prefix(CodepointValue, 4, true)
1025                 << ">";
1026       continue;
1027     }
1028     // Invalid code unit.
1029     OutStream << "<" << llvm::format_hex_no_prefix(*Begin, 2, true) << ">";
1030     ++Begin;
1031   }
1032 }
1033 
1034 void Diagnostic::
1035 FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
1036                  SmallVectorImpl<char> &OutStr) const {
1037   // When the diagnostic string is only "%0", the entire string is being given
1038   // by an outside source.  Remove unprintable characters from this string
1039   // and skip all the other string processing.
1040   if (DiagEnd - DiagStr == 2 && StringRef(DiagStr, DiagEnd - DiagStr) == "%0" &&
1041       getArgKind(0) == DiagnosticsEngine::ak_std_string) {
1042     const std::string &S = getArgStdStr(0);
1043     EscapeStringForDiagnostic(S, OutStr);
1044     return;
1045   }
1046 
1047   /// FormattedArgs - Keep track of all of the arguments formatted by
1048   /// ConvertArgToString and pass them into subsequent calls to
1049   /// ConvertArgToString, allowing the implementation to avoid redundancies in
1050   /// obvious cases.
1051   SmallVector<DiagnosticsEngine::ArgumentValue, 8> FormattedArgs;
1052 
1053   /// QualTypeVals - Pass a vector of arrays so that QualType names can be
1054   /// compared to see if more information is needed to be printed.
1055   SmallVector<intptr_t, 2> QualTypeVals;
1056   SmallString<64> Tree;
1057 
1058   for (unsigned i = 0, e = getNumArgs(); i < e; ++i)
1059     if (getArgKind(i) == DiagnosticsEngine::ak_qualtype)
1060       QualTypeVals.push_back(getRawArg(i));
1061 
1062   while (DiagStr != DiagEnd) {
1063     if (DiagStr[0] != '%') {
1064       // Append non-%0 substrings to Str if we have one.
1065       const char *StrEnd = std::find(DiagStr, DiagEnd, '%');
1066       OutStr.append(DiagStr, StrEnd);
1067       DiagStr = StrEnd;
1068       continue;
1069     } else if (isPunctuation(DiagStr[1])) {
1070       OutStr.push_back(DiagStr[1]);  // %% -> %.
1071       DiagStr += 2;
1072       continue;
1073     }
1074 
1075     // Skip the %.
1076     ++DiagStr;
1077 
1078     // This must be a placeholder for a diagnostic argument.  The format for a
1079     // placeholder is one of "%0", "%modifier0", or "%modifier{arguments}0".
1080     // The digit is a number from 0-9 indicating which argument this comes from.
1081     // The modifier is a string of digits from the set [-a-z]+, arguments is a
1082     // brace enclosed string.
1083     const char *Modifier = nullptr, *Argument = nullptr;
1084     unsigned ModifierLen = 0, ArgumentLen = 0;
1085 
1086     // Check to see if we have a modifier.  If so eat it.
1087     if (!isDigit(DiagStr[0])) {
1088       Modifier = DiagStr;
1089       while (DiagStr[0] == '-' ||
1090              (DiagStr[0] >= 'a' && DiagStr[0] <= 'z'))
1091         ++DiagStr;
1092       ModifierLen = DiagStr-Modifier;
1093 
1094       // If we have an argument, get it next.
1095       if (DiagStr[0] == '{') {
1096         ++DiagStr; // Skip {.
1097         Argument = DiagStr;
1098 
1099         DiagStr = ScanFormat(DiagStr, DiagEnd, '}');
1100         assert(DiagStr != DiagEnd && "Mismatched {}'s in diagnostic string!");
1101         ArgumentLen = DiagStr-Argument;
1102         ++DiagStr;  // Skip }.
1103       }
1104     }
1105 
1106     assert(isDigit(*DiagStr) && "Invalid format for argument in diagnostic");
1107     unsigned ArgNo = *DiagStr++ - '0';
1108 
1109     // Only used for type diffing.
1110     unsigned ArgNo2 = ArgNo;
1111 
1112     DiagnosticsEngine::ArgumentKind Kind = getArgKind(ArgNo);
1113     if (ModifierIs(Modifier, ModifierLen, "diff")) {
1114       assert(*DiagStr == ',' && isDigit(*(DiagStr + 1)) &&
1115              "Invalid format for diff modifier");
1116       ++DiagStr;  // Comma.
1117       ArgNo2 = *DiagStr++ - '0';
1118       DiagnosticsEngine::ArgumentKind Kind2 = getArgKind(ArgNo2);
1119       if (Kind == DiagnosticsEngine::ak_qualtype &&
1120           Kind2 == DiagnosticsEngine::ak_qualtype)
1121         Kind = DiagnosticsEngine::ak_qualtype_pair;
1122       else {
1123         // %diff only supports QualTypes.  For other kinds of arguments,
1124         // use the default printing.  For example, if the modifier is:
1125         //   "%diff{compare $ to $|other text}1,2"
1126         // treat it as:
1127         //   "compare %1 to %2"
1128         const char *ArgumentEnd = Argument + ArgumentLen;
1129         const char *Pipe = ScanFormat(Argument, ArgumentEnd, '|');
1130         assert(ScanFormat(Pipe + 1, ArgumentEnd, '|') == ArgumentEnd &&
1131                "Found too many '|'s in a %diff modifier!");
1132         const char *FirstDollar = ScanFormat(Argument, Pipe, '$');
1133         const char *SecondDollar = ScanFormat(FirstDollar + 1, Pipe, '$');
1134         const char ArgStr1[] = { '%', static_cast<char>('0' + ArgNo) };
1135         const char ArgStr2[] = { '%', static_cast<char>('0' + ArgNo2) };
1136         FormatDiagnostic(Argument, FirstDollar, OutStr);
1137         FormatDiagnostic(ArgStr1, ArgStr1 + 2, OutStr);
1138         FormatDiagnostic(FirstDollar + 1, SecondDollar, OutStr);
1139         FormatDiagnostic(ArgStr2, ArgStr2 + 2, OutStr);
1140         FormatDiagnostic(SecondDollar + 1, Pipe, OutStr);
1141         continue;
1142       }
1143     }
1144 
1145     switch (Kind) {
1146     // ---- STRINGS ----
1147     case DiagnosticsEngine::ak_std_string: {
1148       const std::string &S = getArgStdStr(ArgNo);
1149       assert(ModifierLen == 0 && "No modifiers for strings yet");
1150       EscapeStringForDiagnostic(S, OutStr);
1151       break;
1152     }
1153     case DiagnosticsEngine::ak_c_string: {
1154       const char *S = getArgCStr(ArgNo);
1155       assert(ModifierLen == 0 && "No modifiers for strings yet");
1156 
1157       // Don't crash if get passed a null pointer by accident.
1158       if (!S)
1159         S = "(null)";
1160       EscapeStringForDiagnostic(S, OutStr);
1161       break;
1162     }
1163     // ---- INTEGERS ----
1164     case DiagnosticsEngine::ak_sint: {
1165       int64_t Val = getArgSInt(ArgNo);
1166 
1167       if (ModifierIs(Modifier, ModifierLen, "select")) {
1168         HandleSelectModifier(*this, (unsigned)Val, Argument, ArgumentLen,
1169                              OutStr);
1170       } else if (ModifierIs(Modifier, ModifierLen, "s")) {
1171         HandleIntegerSModifier(Val, OutStr);
1172       } else if (ModifierIs(Modifier, ModifierLen, "plural")) {
1173         HandlePluralModifier(*this, (unsigned)Val, Argument, ArgumentLen,
1174                              OutStr);
1175       } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) {
1176         HandleOrdinalModifier((unsigned)Val, OutStr);
1177       } else if (ModifierIs(Modifier, ModifierLen, "human")) {
1178         HandleIntegerHumanModifier(Val, OutStr);
1179       } else {
1180         assert(ModifierLen == 0 && "Unknown integer modifier");
1181         llvm::raw_svector_ostream(OutStr) << Val;
1182       }
1183       break;
1184     }
1185     case DiagnosticsEngine::ak_uint: {
1186       uint64_t Val = getArgUInt(ArgNo);
1187 
1188       if (ModifierIs(Modifier, ModifierLen, "select")) {
1189         HandleSelectModifier(*this, Val, Argument, ArgumentLen, OutStr);
1190       } else if (ModifierIs(Modifier, ModifierLen, "s")) {
1191         HandleIntegerSModifier(Val, OutStr);
1192       } else if (ModifierIs(Modifier, ModifierLen, "plural")) {
1193         HandlePluralModifier(*this, (unsigned)Val, Argument, ArgumentLen,
1194                              OutStr);
1195       } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) {
1196         HandleOrdinalModifier(Val, OutStr);
1197       } else if (ModifierIs(Modifier, ModifierLen, "human")) {
1198         HandleIntegerHumanModifier(Val, OutStr);
1199       } else {
1200         assert(ModifierLen == 0 && "Unknown integer modifier");
1201         llvm::raw_svector_ostream(OutStr) << Val;
1202       }
1203       break;
1204     }
1205     // ---- TOKEN SPELLINGS ----
1206     case DiagnosticsEngine::ak_tokenkind: {
1207       tok::TokenKind Kind = static_cast<tok::TokenKind>(getRawArg(ArgNo));
1208       assert(ModifierLen == 0 && "No modifiers for token kinds yet");
1209 
1210       llvm::raw_svector_ostream Out(OutStr);
1211       if (const char *S = tok::getPunctuatorSpelling(Kind))
1212         // Quoted token spelling for punctuators.
1213         Out << '\'' << S << '\'';
1214       else if ((S = tok::getKeywordSpelling(Kind)))
1215         // Unquoted token spelling for keywords.
1216         Out << S;
1217       else if ((S = getTokenDescForDiagnostic(Kind)))
1218         // Unquoted translatable token name.
1219         Out << S;
1220       else if ((S = tok::getTokenName(Kind)))
1221         // Debug name, shouldn't appear in user-facing diagnostics.
1222         Out << '<' << S << '>';
1223       else
1224         Out << "(null)";
1225       break;
1226     }
1227     // ---- NAMES and TYPES ----
1228     case DiagnosticsEngine::ak_identifierinfo: {
1229       const IdentifierInfo *II = getArgIdentifier(ArgNo);
1230       assert(ModifierLen == 0 && "No modifiers for strings yet");
1231 
1232       // Don't crash if get passed a null pointer by accident.
1233       if (!II) {
1234         const char *S = "(null)";
1235         OutStr.append(S, S + strlen(S));
1236         continue;
1237       }
1238 
1239       llvm::raw_svector_ostream(OutStr) << '\'' << II->getName() << '\'';
1240       break;
1241     }
1242     case DiagnosticsEngine::ak_addrspace:
1243     case DiagnosticsEngine::ak_qual:
1244     case DiagnosticsEngine::ak_qualtype:
1245     case DiagnosticsEngine::ak_declarationname:
1246     case DiagnosticsEngine::ak_nameddecl:
1247     case DiagnosticsEngine::ak_nestednamespec:
1248     case DiagnosticsEngine::ak_declcontext:
1249     case DiagnosticsEngine::ak_attr:
1250       getDiags()->ConvertArgToString(Kind, getRawArg(ArgNo),
1251                                      StringRef(Modifier, ModifierLen),
1252                                      StringRef(Argument, ArgumentLen),
1253                                      FormattedArgs,
1254                                      OutStr, QualTypeVals);
1255       break;
1256     case DiagnosticsEngine::ak_qualtype_pair: {
1257       // Create a struct with all the info needed for printing.
1258       TemplateDiffTypes TDT;
1259       TDT.FromType = getRawArg(ArgNo);
1260       TDT.ToType = getRawArg(ArgNo2);
1261       TDT.ElideType = getDiags()->ElideType;
1262       TDT.ShowColors = getDiags()->ShowColors;
1263       TDT.TemplateDiffUsed = false;
1264       intptr_t val = reinterpret_cast<intptr_t>(&TDT);
1265 
1266       const char *ArgumentEnd = Argument + ArgumentLen;
1267       const char *Pipe = ScanFormat(Argument, ArgumentEnd, '|');
1268 
1269       // Print the tree.  If this diagnostic already has a tree, skip the
1270       // second tree.
1271       if (getDiags()->PrintTemplateTree && Tree.empty()) {
1272         TDT.PrintFromType = true;
1273         TDT.PrintTree = true;
1274         getDiags()->ConvertArgToString(Kind, val,
1275                                        StringRef(Modifier, ModifierLen),
1276                                        StringRef(Argument, ArgumentLen),
1277                                        FormattedArgs,
1278                                        Tree, QualTypeVals);
1279         // If there is no tree information, fall back to regular printing.
1280         if (!Tree.empty()) {
1281           FormatDiagnostic(Pipe + 1, ArgumentEnd, OutStr);
1282           break;
1283         }
1284       }
1285 
1286       // Non-tree printing, also the fall-back when tree printing fails.
1287       // The fall-back is triggered when the types compared are not templates.
1288       const char *FirstDollar = ScanFormat(Argument, ArgumentEnd, '$');
1289       const char *SecondDollar = ScanFormat(FirstDollar + 1, ArgumentEnd, '$');
1290 
1291       // Append before text
1292       FormatDiagnostic(Argument, FirstDollar, OutStr);
1293 
1294       // Append first type
1295       TDT.PrintTree = false;
1296       TDT.PrintFromType = true;
1297       getDiags()->ConvertArgToString(Kind, val,
1298                                      StringRef(Modifier, ModifierLen),
1299                                      StringRef(Argument, ArgumentLen),
1300                                      FormattedArgs,
1301                                      OutStr, QualTypeVals);
1302       if (!TDT.TemplateDiffUsed)
1303         FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype,
1304                                                TDT.FromType));
1305 
1306       // Append middle text
1307       FormatDiagnostic(FirstDollar + 1, SecondDollar, OutStr);
1308 
1309       // Append second type
1310       TDT.PrintFromType = false;
1311       getDiags()->ConvertArgToString(Kind, val,
1312                                      StringRef(Modifier, ModifierLen),
1313                                      StringRef(Argument, ArgumentLen),
1314                                      FormattedArgs,
1315                                      OutStr, QualTypeVals);
1316       if (!TDT.TemplateDiffUsed)
1317         FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype,
1318                                                TDT.ToType));
1319 
1320       // Append end text
1321       FormatDiagnostic(SecondDollar + 1, Pipe, OutStr);
1322       break;
1323     }
1324     }
1325 
1326     // Remember this argument info for subsequent formatting operations.  Turn
1327     // std::strings into a null terminated string to make it be the same case as
1328     // all the other ones.
1329     if (Kind == DiagnosticsEngine::ak_qualtype_pair)
1330       continue;
1331     else if (Kind != DiagnosticsEngine::ak_std_string)
1332       FormattedArgs.push_back(std::make_pair(Kind, getRawArg(ArgNo)));
1333     else
1334       FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_c_string,
1335                                         (intptr_t)getArgStdStr(ArgNo).c_str()));
1336   }
1337 
1338   // Append the type tree to the end of the diagnostics.
1339   OutStr.append(Tree.begin(), Tree.end());
1340 }
1341 
1342 StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
1343                                    StringRef Message)
1344     : ID(ID), Level(Level), Message(Message) {}
1345 
1346 StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level,
1347                                    const Diagnostic &Info)
1348     : ID(Info.getID()), Level(Level) {
1349   assert((Info.getLocation().isInvalid() || Info.hasSourceManager()) &&
1350        "Valid source location without setting a source manager for diagnostic");
1351   if (Info.getLocation().isValid())
1352     Loc = FullSourceLoc(Info.getLocation(), Info.getSourceManager());
1353   SmallString<64> Message;
1354   Info.FormatDiagnostic(Message);
1355   this->Message.assign(Message.begin(), Message.end());
1356   this->Ranges.assign(Info.getRanges().begin(), Info.getRanges().end());
1357   this->FixIts.assign(Info.getFixItHints().begin(), Info.getFixItHints().end());
1358 }
1359 
1360 StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
1361                                    StringRef Message, FullSourceLoc Loc,
1362                                    ArrayRef<CharSourceRange> Ranges,
1363                                    ArrayRef<FixItHint> FixIts)
1364     : ID(ID), Level(Level), Loc(Loc), Message(Message),
1365       Ranges(Ranges.begin(), Ranges.end()), FixIts(FixIts.begin(), FixIts.end())
1366 {
1367 }
1368 
1369 llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
1370                                      const StoredDiagnostic &SD) {
1371   if (SD.getLocation().hasManager())
1372     OS << SD.getLocation().printToString(SD.getLocation().getManager()) << ": ";
1373   OS << SD.getMessage();
1374   return OS;
1375 }
1376 
1377 /// IncludeInDiagnosticCounts - This method (whose default implementation
1378 ///  returns true) indicates whether the diagnostics handled by this
1379 ///  DiagnosticConsumer should be included in the number of diagnostics
1380 ///  reported by DiagnosticsEngine.
1381 bool DiagnosticConsumer::IncludeInDiagnosticCounts() const { return true; }
1382 
1383 void IgnoringDiagConsumer::anchor() {}
1384 
1385 ForwardingDiagnosticConsumer::~ForwardingDiagnosticConsumer() = default;
1386 
1387 void ForwardingDiagnosticConsumer::HandleDiagnostic(
1388        DiagnosticsEngine::Level DiagLevel,
1389        const Diagnostic &Info) {
1390   Target.HandleDiagnostic(DiagLevel, Info);
1391 }
1392 
1393 void ForwardingDiagnosticConsumer::clear() {
1394   DiagnosticConsumer::clear();
1395   Target.clear();
1396 }
1397 
1398 bool ForwardingDiagnosticConsumer::IncludeInDiagnosticCounts() const {
1399   return Target.IncludeInDiagnosticCounts();
1400 }
1401 
1402 DiagStorageAllocator::DiagStorageAllocator() {
1403   for (unsigned I = 0; I != NumCached; ++I)
1404     FreeList[I] = Cached + I;
1405   NumFreeListEntries = NumCached;
1406 }
1407 
1408 DiagStorageAllocator::~DiagStorageAllocator() {
1409   // Don't assert if we are in a CrashRecovery context, as this invariant may
1410   // be invalidated during a crash.
1411   assert((NumFreeListEntries == NumCached ||
1412           llvm::CrashRecoveryContext::isRecoveringFromCrash()) &&
1413          "A partial is on the lam");
1414 }
1415 
1416 char DiagnosticError::ID;
1417