xref: /freebsd/contrib/llvm-project/clang/lib/Analysis/PathDiagnostic.cpp (revision 6be3386466ab79a84b48429ae66244f21526d3df)
1 //===- PathDiagnostic.cpp - Path-Specific 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 defines the PathDiagnostic-related interfaces.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "clang/Analysis/PathDiagnostic.h"
14 #include "clang/AST/Decl.h"
15 #include "clang/AST/DeclBase.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/DeclObjC.h"
18 #include "clang/AST/DeclTemplate.h"
19 #include "clang/AST/Expr.h"
20 #include "clang/AST/ExprCXX.h"
21 #include "clang/AST/OperationKinds.h"
22 #include "clang/AST/ParentMap.h"
23 #include "clang/AST/PrettyPrinter.h"
24 #include "clang/AST/Stmt.h"
25 #include "clang/AST/Type.h"
26 #include "clang/Analysis/AnalysisDeclContext.h"
27 #include "clang/Analysis/CFG.h"
28 #include "clang/Analysis/ProgramPoint.h"
29 #include "clang/Basic/FileManager.h"
30 #include "clang/Basic/LLVM.h"
31 #include "clang/Basic/SourceLocation.h"
32 #include "clang/Basic/SourceManager.h"
33 #include "llvm/ADT/ArrayRef.h"
34 #include "llvm/ADT/FoldingSet.h"
35 #include "llvm/ADT/None.h"
36 #include "llvm/ADT/Optional.h"
37 #include "llvm/ADT/STLExtras.h"
38 #include "llvm/ADT/SmallString.h"
39 #include "llvm/ADT/SmallVector.h"
40 #include "llvm/ADT/StringExtras.h"
41 #include "llvm/ADT/StringRef.h"
42 #include "llvm/Support/Casting.h"
43 #include "llvm/Support/ErrorHandling.h"
44 #include "llvm/Support/raw_ostream.h"
45 #include <cassert>
46 #include <cstring>
47 #include <memory>
48 #include <utility>
49 #include <vector>
50 
51 using namespace clang;
52 using namespace ento;
53 
54 static StringRef StripTrailingDots(StringRef s) {
55   for (StringRef::size_type i = s.size(); i != 0; --i)
56     if (s[i - 1] != '.')
57       return s.substr(0, i);
58   return {};
59 }
60 
61 PathDiagnosticPiece::PathDiagnosticPiece(StringRef s,
62                                          Kind k, DisplayHint hint)
63     : str(StripTrailingDots(s)), kind(k), Hint(hint) {}
64 
65 PathDiagnosticPiece::PathDiagnosticPiece(Kind k, DisplayHint hint)
66     : kind(k), Hint(hint) {}
67 
68 PathDiagnosticPiece::~PathDiagnosticPiece() = default;
69 
70 PathDiagnosticEventPiece::~PathDiagnosticEventPiece() = default;
71 
72 PathDiagnosticCallPiece::~PathDiagnosticCallPiece() = default;
73 
74 PathDiagnosticControlFlowPiece::~PathDiagnosticControlFlowPiece() = default;
75 
76 PathDiagnosticMacroPiece::~PathDiagnosticMacroPiece() = default;
77 
78 PathDiagnosticNotePiece::~PathDiagnosticNotePiece() = default;
79 
80 PathDiagnosticPopUpPiece::~PathDiagnosticPopUpPiece() = default;
81 
82 void PathPieces::flattenTo(PathPieces &Primary, PathPieces &Current,
83                            bool ShouldFlattenMacros) const {
84   for (auto &Piece : *this) {
85     switch (Piece->getKind()) {
86     case PathDiagnosticPiece::Call: {
87       auto &Call = cast<PathDiagnosticCallPiece>(*Piece);
88       if (auto CallEnter = Call.getCallEnterEvent())
89         Current.push_back(std::move(CallEnter));
90       Call.path.flattenTo(Primary, Primary, ShouldFlattenMacros);
91       if (auto callExit = Call.getCallExitEvent())
92         Current.push_back(std::move(callExit));
93       break;
94     }
95     case PathDiagnosticPiece::Macro: {
96       auto &Macro = cast<PathDiagnosticMacroPiece>(*Piece);
97       if (ShouldFlattenMacros) {
98         Macro.subPieces.flattenTo(Primary, Primary, ShouldFlattenMacros);
99       } else {
100         Current.push_back(Piece);
101         PathPieces NewPath;
102         Macro.subPieces.flattenTo(Primary, NewPath, ShouldFlattenMacros);
103         // FIXME: This probably shouldn't mutate the original path piece.
104         Macro.subPieces = NewPath;
105       }
106       break;
107     }
108     case PathDiagnosticPiece::Event:
109     case PathDiagnosticPiece::ControlFlow:
110     case PathDiagnosticPiece::Note:
111     case PathDiagnosticPiece::PopUp:
112       Current.push_back(Piece);
113       break;
114     }
115   }
116 }
117 
118 PathDiagnostic::~PathDiagnostic() = default;
119 
120 PathDiagnostic::PathDiagnostic(
121     StringRef CheckerName, const Decl *declWithIssue, StringRef bugtype,
122     StringRef verboseDesc, StringRef shortDesc, StringRef category,
123     PathDiagnosticLocation LocationToUnique, const Decl *DeclToUnique,
124     std::unique_ptr<FilesToLineNumsMap> ExecutedLines)
125     : CheckerName(CheckerName), DeclWithIssue(declWithIssue),
126       BugType(StripTrailingDots(bugtype)),
127       VerboseDesc(StripTrailingDots(verboseDesc)),
128       ShortDesc(StripTrailingDots(shortDesc)),
129       Category(StripTrailingDots(category)), UniqueingLoc(LocationToUnique),
130       UniqueingDecl(DeclToUnique), ExecutedLines(std::move(ExecutedLines)),
131       path(pathImpl) {}
132 
133 void PathDiagnosticConsumer::anchor() {}
134 
135 PathDiagnosticConsumer::~PathDiagnosticConsumer() {
136   // Delete the contents of the FoldingSet if it isn't empty already.
137   for (auto &Diag : Diags)
138     delete &Diag;
139 }
140 
141 void PathDiagnosticConsumer::HandlePathDiagnostic(
142     std::unique_ptr<PathDiagnostic> D) {
143   if (!D || D->path.empty())
144     return;
145 
146   // We need to flatten the locations (convert Stmt* to locations) because
147   // the referenced statements may be freed by the time the diagnostics
148   // are emitted.
149   D->flattenLocations();
150 
151   // If the PathDiagnosticConsumer does not support diagnostics that
152   // cross file boundaries, prune out such diagnostics now.
153   if (!supportsCrossFileDiagnostics()) {
154     // Verify that the entire path is from the same FileID.
155     FileID FID;
156     const SourceManager &SMgr = D->path.front()->getLocation().getManager();
157     SmallVector<const PathPieces *, 5> WorkList;
158     WorkList.push_back(&D->path);
159     SmallString<128> buf;
160     llvm::raw_svector_ostream warning(buf);
161     warning << "warning: Path diagnostic report is not generated. Current "
162             << "output format does not support diagnostics that cross file "
163             << "boundaries. Refer to --analyzer-output for valid output "
164             << "formats\n";
165 
166     while (!WorkList.empty()) {
167       const PathPieces &path = *WorkList.pop_back_val();
168 
169       for (const auto &I : path) {
170         const PathDiagnosticPiece *piece = I.get();
171         FullSourceLoc L = piece->getLocation().asLocation().getExpansionLoc();
172 
173         if (FID.isInvalid()) {
174           FID = SMgr.getFileID(L);
175         } else if (SMgr.getFileID(L) != FID) {
176           llvm::errs() << warning.str();
177           return;
178         }
179 
180         // Check the source ranges.
181         ArrayRef<SourceRange> Ranges = piece->getRanges();
182         for (const auto &I : Ranges) {
183           SourceLocation L = SMgr.getExpansionLoc(I.getBegin());
184           if (!L.isFileID() || SMgr.getFileID(L) != FID) {
185             llvm::errs() << warning.str();
186             return;
187           }
188           L = SMgr.getExpansionLoc(I.getEnd());
189           if (!L.isFileID() || SMgr.getFileID(L) != FID) {
190             llvm::errs() << warning.str();
191             return;
192           }
193         }
194 
195         if (const auto *call = dyn_cast<PathDiagnosticCallPiece>(piece))
196           WorkList.push_back(&call->path);
197         else if (const auto *macro = dyn_cast<PathDiagnosticMacroPiece>(piece))
198           WorkList.push_back(&macro->subPieces);
199       }
200     }
201 
202     if (FID.isInvalid())
203       return; // FIXME: Emit a warning?
204   }
205 
206   // Profile the node to see if we already have something matching it
207   llvm::FoldingSetNodeID profile;
208   D->Profile(profile);
209   void *InsertPos = nullptr;
210 
211   if (PathDiagnostic *orig = Diags.FindNodeOrInsertPos(profile, InsertPos)) {
212     // Keep the PathDiagnostic with the shorter path.
213     // Note, the enclosing routine is called in deterministic order, so the
214     // results will be consistent between runs (no reason to break ties if the
215     // size is the same).
216     const unsigned orig_size = orig->full_size();
217     const unsigned new_size = D->full_size();
218     if (orig_size <= new_size)
219       return;
220 
221     assert(orig != D.get());
222     Diags.RemoveNode(orig);
223     delete orig;
224   }
225 
226   Diags.InsertNode(D.release());
227 }
228 
229 static Optional<bool> comparePath(const PathPieces &X, const PathPieces &Y);
230 
231 static Optional<bool>
232 compareControlFlow(const PathDiagnosticControlFlowPiece &X,
233                    const PathDiagnosticControlFlowPiece &Y) {
234   FullSourceLoc XSL = X.getStartLocation().asLocation();
235   FullSourceLoc YSL = Y.getStartLocation().asLocation();
236   if (XSL != YSL)
237     return XSL.isBeforeInTranslationUnitThan(YSL);
238   FullSourceLoc XEL = X.getEndLocation().asLocation();
239   FullSourceLoc YEL = Y.getEndLocation().asLocation();
240   if (XEL != YEL)
241     return XEL.isBeforeInTranslationUnitThan(YEL);
242   return None;
243 }
244 
245 static Optional<bool> compareMacro(const PathDiagnosticMacroPiece &X,
246                                    const PathDiagnosticMacroPiece &Y) {
247   return comparePath(X.subPieces, Y.subPieces);
248 }
249 
250 static Optional<bool> compareCall(const PathDiagnosticCallPiece &X,
251                                   const PathDiagnosticCallPiece &Y) {
252   FullSourceLoc X_CEL = X.callEnter.asLocation();
253   FullSourceLoc Y_CEL = Y.callEnter.asLocation();
254   if (X_CEL != Y_CEL)
255     return X_CEL.isBeforeInTranslationUnitThan(Y_CEL);
256   FullSourceLoc X_CEWL = X.callEnterWithin.asLocation();
257   FullSourceLoc Y_CEWL = Y.callEnterWithin.asLocation();
258   if (X_CEWL != Y_CEWL)
259     return X_CEWL.isBeforeInTranslationUnitThan(Y_CEWL);
260   FullSourceLoc X_CRL = X.callReturn.asLocation();
261   FullSourceLoc Y_CRL = Y.callReturn.asLocation();
262   if (X_CRL != Y_CRL)
263     return X_CRL.isBeforeInTranslationUnitThan(Y_CRL);
264   return comparePath(X.path, Y.path);
265 }
266 
267 static Optional<bool> comparePiece(const PathDiagnosticPiece &X,
268                                    const PathDiagnosticPiece &Y) {
269   if (X.getKind() != Y.getKind())
270     return X.getKind() < Y.getKind();
271 
272   FullSourceLoc XL = X.getLocation().asLocation();
273   FullSourceLoc YL = Y.getLocation().asLocation();
274   if (XL != YL)
275     return XL.isBeforeInTranslationUnitThan(YL);
276 
277   if (X.getString() != Y.getString())
278     return X.getString() < Y.getString();
279 
280   if (X.getRanges().size() != Y.getRanges().size())
281     return X.getRanges().size() < Y.getRanges().size();
282 
283   const SourceManager &SM = XL.getManager();
284 
285   for (unsigned i = 0, n = X.getRanges().size(); i < n; ++i) {
286     SourceRange XR = X.getRanges()[i];
287     SourceRange YR = Y.getRanges()[i];
288     if (XR != YR) {
289       if (XR.getBegin() != YR.getBegin())
290         return SM.isBeforeInTranslationUnit(XR.getBegin(), YR.getBegin());
291       return SM.isBeforeInTranslationUnit(XR.getEnd(), YR.getEnd());
292     }
293   }
294 
295   switch (X.getKind()) {
296     case PathDiagnosticPiece::ControlFlow:
297       return compareControlFlow(cast<PathDiagnosticControlFlowPiece>(X),
298                                 cast<PathDiagnosticControlFlowPiece>(Y));
299     case PathDiagnosticPiece::Macro:
300       return compareMacro(cast<PathDiagnosticMacroPiece>(X),
301                           cast<PathDiagnosticMacroPiece>(Y));
302     case PathDiagnosticPiece::Call:
303       return compareCall(cast<PathDiagnosticCallPiece>(X),
304                          cast<PathDiagnosticCallPiece>(Y));
305     case PathDiagnosticPiece::Event:
306     case PathDiagnosticPiece::Note:
307     case PathDiagnosticPiece::PopUp:
308       return None;
309   }
310   llvm_unreachable("all cases handled");
311 }
312 
313 static Optional<bool> comparePath(const PathPieces &X, const PathPieces &Y) {
314   if (X.size() != Y.size())
315     return X.size() < Y.size();
316 
317   PathPieces::const_iterator X_I = X.begin(), X_end = X.end();
318   PathPieces::const_iterator Y_I = Y.begin(), Y_end = Y.end();
319 
320   for ( ; X_I != X_end && Y_I != Y_end; ++X_I, ++Y_I) {
321     Optional<bool> b = comparePiece(**X_I, **Y_I);
322     if (b.hasValue())
323       return b.getValue();
324   }
325 
326   return None;
327 }
328 
329 static bool compareCrossTUSourceLocs(FullSourceLoc XL, FullSourceLoc YL) {
330   std::pair<FileID, unsigned> XOffs = XL.getDecomposedLoc();
331   std::pair<FileID, unsigned> YOffs = YL.getDecomposedLoc();
332   const SourceManager &SM = XL.getManager();
333   std::pair<bool, bool> InSameTU = SM.isInTheSameTranslationUnit(XOffs, YOffs);
334   if (InSameTU.first)
335     return XL.isBeforeInTranslationUnitThan(YL);
336   const FileEntry *XFE = SM.getFileEntryForID(XL.getSpellingLoc().getFileID());
337   const FileEntry *YFE = SM.getFileEntryForID(YL.getSpellingLoc().getFileID());
338   if (!XFE || !YFE)
339     return XFE && !YFE;
340   int NameCmp = XFE->getName().compare(YFE->getName());
341   if (NameCmp != 0)
342     return NameCmp == -1;
343   // Last resort: Compare raw file IDs that are possibly expansions.
344   return XL.getFileID() < YL.getFileID();
345 }
346 
347 static bool compare(const PathDiagnostic &X, const PathDiagnostic &Y) {
348   FullSourceLoc XL = X.getLocation().asLocation();
349   FullSourceLoc YL = Y.getLocation().asLocation();
350   if (XL != YL)
351     return compareCrossTUSourceLocs(XL, YL);
352   if (X.getBugType() != Y.getBugType())
353     return X.getBugType() < Y.getBugType();
354   if (X.getCategory() != Y.getCategory())
355     return X.getCategory() < Y.getCategory();
356   if (X.getVerboseDescription() != Y.getVerboseDescription())
357     return X.getVerboseDescription() < Y.getVerboseDescription();
358   if (X.getShortDescription() != Y.getShortDescription())
359     return X.getShortDescription() < Y.getShortDescription();
360   if (X.getDeclWithIssue() != Y.getDeclWithIssue()) {
361     const Decl *XD = X.getDeclWithIssue();
362     if (!XD)
363       return true;
364     const Decl *YD = Y.getDeclWithIssue();
365     if (!YD)
366       return false;
367     SourceLocation XDL = XD->getLocation();
368     SourceLocation YDL = YD->getLocation();
369     if (XDL != YDL) {
370       const SourceManager &SM = XL.getManager();
371       return compareCrossTUSourceLocs(FullSourceLoc(XDL, SM),
372                                       FullSourceLoc(YDL, SM));
373     }
374   }
375   PathDiagnostic::meta_iterator XI = X.meta_begin(), XE = X.meta_end();
376   PathDiagnostic::meta_iterator YI = Y.meta_begin(), YE = Y.meta_end();
377   if (XE - XI != YE - YI)
378     return (XE - XI) < (YE - YI);
379   for ( ; XI != XE ; ++XI, ++YI) {
380     if (*XI != *YI)
381       return (*XI) < (*YI);
382   }
383   Optional<bool> b = comparePath(X.path, Y.path);
384   assert(b.hasValue());
385   return b.getValue();
386 }
387 
388 void PathDiagnosticConsumer::FlushDiagnostics(
389                                      PathDiagnosticConsumer::FilesMade *Files) {
390   if (flushed)
391     return;
392 
393   flushed = true;
394 
395   std::vector<const PathDiagnostic *> BatchDiags;
396   for (const auto &D : Diags)
397     BatchDiags.push_back(&D);
398 
399   // Sort the diagnostics so that they are always emitted in a deterministic
400   // order.
401   int (*Comp)(const PathDiagnostic *const *, const PathDiagnostic *const *) =
402       [](const PathDiagnostic *const *X, const PathDiagnostic *const *Y) {
403         assert(*X != *Y && "PathDiagnostics not uniqued!");
404         if (compare(**X, **Y))
405           return -1;
406         assert(compare(**Y, **X) && "Not a total order!");
407         return 1;
408       };
409   array_pod_sort(BatchDiags.begin(), BatchDiags.end(), Comp);
410 
411   FlushDiagnosticsImpl(BatchDiags, Files);
412 
413   // Delete the flushed diagnostics.
414   for (const auto D : BatchDiags)
415     delete D;
416 
417   // Clear out the FoldingSet.
418   Diags.clear();
419 }
420 
421 PathDiagnosticConsumer::FilesMade::~FilesMade() {
422   for (PDFileEntry &Entry : Set)
423     Entry.~PDFileEntry();
424 }
425 
426 void PathDiagnosticConsumer::FilesMade::addDiagnostic(const PathDiagnostic &PD,
427                                                       StringRef ConsumerName,
428                                                       StringRef FileName) {
429   llvm::FoldingSetNodeID NodeID;
430   NodeID.Add(PD);
431   void *InsertPos;
432   PDFileEntry *Entry = Set.FindNodeOrInsertPos(NodeID, InsertPos);
433   if (!Entry) {
434     Entry = Alloc.Allocate<PDFileEntry>();
435     Entry = new (Entry) PDFileEntry(NodeID);
436     Set.InsertNode(Entry, InsertPos);
437   }
438 
439   // Allocate persistent storage for the file name.
440   char *FileName_cstr = (char*) Alloc.Allocate(FileName.size(), 1);
441   memcpy(FileName_cstr, FileName.data(), FileName.size());
442 
443   Entry->files.push_back(std::make_pair(ConsumerName,
444                                         StringRef(FileName_cstr,
445                                                   FileName.size())));
446 }
447 
448 PathDiagnosticConsumer::PDFileEntry::ConsumerFiles *
449 PathDiagnosticConsumer::FilesMade::getFiles(const PathDiagnostic &PD) {
450   llvm::FoldingSetNodeID NodeID;
451   NodeID.Add(PD);
452   void *InsertPos;
453   PDFileEntry *Entry = Set.FindNodeOrInsertPos(NodeID, InsertPos);
454   if (!Entry)
455     return nullptr;
456   return &Entry->files;
457 }
458 
459 //===----------------------------------------------------------------------===//
460 // PathDiagnosticLocation methods.
461 //===----------------------------------------------------------------------===//
462 
463 SourceLocation PathDiagnosticLocation::getValidSourceLocation(
464     const Stmt *S, LocationOrAnalysisDeclContext LAC, bool UseEndOfStatement) {
465   SourceLocation L = UseEndOfStatement ? S->getEndLoc() : S->getBeginLoc();
466   assert(!LAC.isNull() &&
467          "A valid LocationContext or AnalysisDeclContext should be passed to "
468          "PathDiagnosticLocation upon creation.");
469 
470   // S might be a temporary statement that does not have a location in the
471   // source code, so find an enclosing statement and use its location.
472   if (!L.isValid()) {
473     AnalysisDeclContext *ADC;
474     if (LAC.is<const LocationContext*>())
475       ADC = LAC.get<const LocationContext*>()->getAnalysisDeclContext();
476     else
477       ADC = LAC.get<AnalysisDeclContext*>();
478 
479     ParentMap &PM = ADC->getParentMap();
480 
481     const Stmt *Parent = S;
482     do {
483       Parent = PM.getParent(Parent);
484 
485       // In rare cases, we have implicit top-level expressions,
486       // such as arguments for implicit member initializers.
487       // In this case, fall back to the start of the body (even if we were
488       // asked for the statement end location).
489       if (!Parent) {
490         const Stmt *Body = ADC->getBody();
491         if (Body)
492           L = Body->getBeginLoc();
493         else
494           L = ADC->getDecl()->getEndLoc();
495         break;
496       }
497 
498       L = UseEndOfStatement ? Parent->getEndLoc() : Parent->getBeginLoc();
499     } while (!L.isValid());
500   }
501 
502   // FIXME: Ironically, this assert actually fails in some cases.
503   //assert(L.isValid());
504   return L;
505 }
506 
507 static PathDiagnosticLocation
508 getLocationForCaller(const StackFrameContext *SFC,
509                      const LocationContext *CallerCtx,
510                      const SourceManager &SM) {
511   const CFGBlock &Block = *SFC->getCallSiteBlock();
512   CFGElement Source = Block[SFC->getIndex()];
513 
514   switch (Source.getKind()) {
515   case CFGElement::Statement:
516   case CFGElement::Constructor:
517   case CFGElement::CXXRecordTypedCall:
518     return PathDiagnosticLocation(Source.castAs<CFGStmt>().getStmt(),
519                                   SM, CallerCtx);
520   case CFGElement::Initializer: {
521     const CFGInitializer &Init = Source.castAs<CFGInitializer>();
522     return PathDiagnosticLocation(Init.getInitializer()->getInit(),
523                                   SM, CallerCtx);
524   }
525   case CFGElement::AutomaticObjectDtor: {
526     const CFGAutomaticObjDtor &Dtor = Source.castAs<CFGAutomaticObjDtor>();
527     return PathDiagnosticLocation::createEnd(Dtor.getTriggerStmt(),
528                                              SM, CallerCtx);
529   }
530   case CFGElement::DeleteDtor: {
531     const CFGDeleteDtor &Dtor = Source.castAs<CFGDeleteDtor>();
532     return PathDiagnosticLocation(Dtor.getDeleteExpr(), SM, CallerCtx);
533   }
534   case CFGElement::BaseDtor:
535   case CFGElement::MemberDtor: {
536     const AnalysisDeclContext *CallerInfo = CallerCtx->getAnalysisDeclContext();
537     if (const Stmt *CallerBody = CallerInfo->getBody())
538       return PathDiagnosticLocation::createEnd(CallerBody, SM, CallerCtx);
539     return PathDiagnosticLocation::create(CallerInfo->getDecl(), SM);
540   }
541   case CFGElement::NewAllocator: {
542     const CFGNewAllocator &Alloc = Source.castAs<CFGNewAllocator>();
543     return PathDiagnosticLocation(Alloc.getAllocatorExpr(), SM, CallerCtx);
544   }
545   case CFGElement::TemporaryDtor: {
546     // Temporary destructors are for temporaries. They die immediately at around
547     // the location of CXXBindTemporaryExpr. If they are lifetime-extended,
548     // they'd be dealt with via an AutomaticObjectDtor instead.
549     const auto &Dtor = Source.castAs<CFGTemporaryDtor>();
550     return PathDiagnosticLocation::createEnd(Dtor.getBindTemporaryExpr(), SM,
551                                              CallerCtx);
552   }
553   case CFGElement::ScopeBegin:
554   case CFGElement::ScopeEnd:
555     llvm_unreachable("not yet implemented!");
556   case CFGElement::LifetimeEnds:
557   case CFGElement::LoopExit:
558     llvm_unreachable("CFGElement kind should not be on callsite!");
559   }
560 
561   llvm_unreachable("Unknown CFGElement kind");
562 }
563 
564 PathDiagnosticLocation
565 PathDiagnosticLocation::createBegin(const Decl *D,
566                                     const SourceManager &SM) {
567   return PathDiagnosticLocation(D->getBeginLoc(), SM, SingleLocK);
568 }
569 
570 PathDiagnosticLocation
571 PathDiagnosticLocation::createBegin(const Stmt *S,
572                                     const SourceManager &SM,
573                                     LocationOrAnalysisDeclContext LAC) {
574   return PathDiagnosticLocation(getValidSourceLocation(S, LAC),
575                                 SM, SingleLocK);
576 }
577 
578 PathDiagnosticLocation
579 PathDiagnosticLocation::createEnd(const Stmt *S,
580                                   const SourceManager &SM,
581                                   LocationOrAnalysisDeclContext LAC) {
582   if (const auto *CS = dyn_cast<CompoundStmt>(S))
583     return createEndBrace(CS, SM);
584   return PathDiagnosticLocation(getValidSourceLocation(S, LAC, /*End=*/true),
585                                 SM, SingleLocK);
586 }
587 
588 PathDiagnosticLocation
589 PathDiagnosticLocation::createOperatorLoc(const BinaryOperator *BO,
590                                           const SourceManager &SM) {
591   return PathDiagnosticLocation(BO->getOperatorLoc(), SM, SingleLocK);
592 }
593 
594 PathDiagnosticLocation
595 PathDiagnosticLocation::createConditionalColonLoc(
596                                             const ConditionalOperator *CO,
597                                             const SourceManager &SM) {
598   return PathDiagnosticLocation(CO->getColonLoc(), SM, SingleLocK);
599 }
600 
601 PathDiagnosticLocation
602 PathDiagnosticLocation::createMemberLoc(const MemberExpr *ME,
603                                         const SourceManager &SM) {
604 
605   assert(ME->getMemberLoc().isValid() || ME->getBeginLoc().isValid());
606 
607   // In some cases, getMemberLoc isn't valid -- in this case we'll return with
608   // some other related valid SourceLocation.
609   if (ME->getMemberLoc().isValid())
610     return PathDiagnosticLocation(ME->getMemberLoc(), SM, SingleLocK);
611 
612   return PathDiagnosticLocation(ME->getBeginLoc(), SM, SingleLocK);
613 }
614 
615 PathDiagnosticLocation
616 PathDiagnosticLocation::createBeginBrace(const CompoundStmt *CS,
617                                          const SourceManager &SM) {
618   SourceLocation L = CS->getLBracLoc();
619   return PathDiagnosticLocation(L, SM, SingleLocK);
620 }
621 
622 PathDiagnosticLocation
623 PathDiagnosticLocation::createEndBrace(const CompoundStmt *CS,
624                                        const SourceManager &SM) {
625   SourceLocation L = CS->getRBracLoc();
626   return PathDiagnosticLocation(L, SM, SingleLocK);
627 }
628 
629 PathDiagnosticLocation
630 PathDiagnosticLocation::createDeclBegin(const LocationContext *LC,
631                                         const SourceManager &SM) {
632   // FIXME: Should handle CXXTryStmt if analyser starts supporting C++.
633   if (const auto *CS = dyn_cast_or_null<CompoundStmt>(LC->getDecl()->getBody()))
634     if (!CS->body_empty()) {
635       SourceLocation Loc = (*CS->body_begin())->getBeginLoc();
636       return PathDiagnosticLocation(Loc, SM, SingleLocK);
637     }
638 
639   return PathDiagnosticLocation();
640 }
641 
642 PathDiagnosticLocation
643 PathDiagnosticLocation::createDeclEnd(const LocationContext *LC,
644                                       const SourceManager &SM) {
645   SourceLocation L = LC->getDecl()->getBodyRBrace();
646   return PathDiagnosticLocation(L, SM, SingleLocK);
647 }
648 
649 PathDiagnosticLocation
650 PathDiagnosticLocation::create(const ProgramPoint& P,
651                                const SourceManager &SMng) {
652   const Stmt* S = nullptr;
653   if (Optional<BlockEdge> BE = P.getAs<BlockEdge>()) {
654     const CFGBlock *BSrc = BE->getSrc();
655     if (BSrc->getTerminator().isVirtualBaseBranch()) {
656       // TODO: VirtualBaseBranches should also appear for destructors.
657       // In this case we should put the diagnostic at the end of decl.
658       return PathDiagnosticLocation::createBegin(
659           P.getLocationContext()->getDecl(), SMng);
660 
661     } else {
662       S = BSrc->getTerminatorCondition();
663       if (!S) {
664         // If the BlockEdge has no terminator condition statement but its
665         // source is the entry of the CFG (e.g. a checker crated the branch at
666         // the beginning of a function), use the function's declaration instead.
667         assert(BSrc == &BSrc->getParent()->getEntry() && "CFGBlock has no "
668                "TerminatorCondition and is not the enrty block of the CFG");
669         return PathDiagnosticLocation::createBegin(
670             P.getLocationContext()->getDecl(), SMng);
671       }
672     }
673   } else if (Optional<StmtPoint> SP = P.getAs<StmtPoint>()) {
674     S = SP->getStmt();
675     if (P.getAs<PostStmtPurgeDeadSymbols>())
676       return PathDiagnosticLocation::createEnd(S, SMng, P.getLocationContext());
677   } else if (Optional<PostInitializer> PIP = P.getAs<PostInitializer>()) {
678     return PathDiagnosticLocation(PIP->getInitializer()->getSourceLocation(),
679                                   SMng);
680   } else if (Optional<PreImplicitCall> PIC = P.getAs<PreImplicitCall>()) {
681     return PathDiagnosticLocation(PIC->getLocation(), SMng);
682   } else if (Optional<PostImplicitCall> PIE = P.getAs<PostImplicitCall>()) {
683     return PathDiagnosticLocation(PIE->getLocation(), SMng);
684   } else if (Optional<CallEnter> CE = P.getAs<CallEnter>()) {
685     return getLocationForCaller(CE->getCalleeContext(),
686                                 CE->getLocationContext(),
687                                 SMng);
688   } else if (Optional<CallExitEnd> CEE = P.getAs<CallExitEnd>()) {
689     return getLocationForCaller(CEE->getCalleeContext(),
690                                 CEE->getLocationContext(),
691                                 SMng);
692   } else if (auto CEB = P.getAs<CallExitBegin>()) {
693     if (const ReturnStmt *RS = CEB->getReturnStmt())
694       return PathDiagnosticLocation::createBegin(RS, SMng,
695                                                  CEB->getLocationContext());
696     return PathDiagnosticLocation(
697         CEB->getLocationContext()->getDecl()->getSourceRange().getEnd(), SMng);
698   } else if (Optional<BlockEntrance> BE = P.getAs<BlockEntrance>()) {
699     if (Optional<CFGElement> BlockFront = BE->getFirstElement()) {
700       if (auto StmtElt = BlockFront->getAs<CFGStmt>()) {
701         return PathDiagnosticLocation(StmtElt->getStmt()->getBeginLoc(), SMng);
702       } else if (auto NewAllocElt = BlockFront->getAs<CFGNewAllocator>()) {
703         return PathDiagnosticLocation(
704             NewAllocElt->getAllocatorExpr()->getBeginLoc(), SMng);
705       }
706       llvm_unreachable("Unexpected CFG element at front of block");
707     }
708 
709     return PathDiagnosticLocation(
710         BE->getBlock()->getTerminatorStmt()->getBeginLoc(), SMng);
711   } else if (Optional<FunctionExitPoint> FE = P.getAs<FunctionExitPoint>()) {
712     return PathDiagnosticLocation(FE->getStmt(), SMng,
713                                   FE->getLocationContext());
714   } else {
715     llvm_unreachable("Unexpected ProgramPoint");
716   }
717 
718   return PathDiagnosticLocation(S, SMng, P.getLocationContext());
719 }
720 
721 PathDiagnosticLocation PathDiagnosticLocation::createSingleLocation(
722                                            const PathDiagnosticLocation &PDL) {
723   FullSourceLoc L = PDL.asLocation();
724   return PathDiagnosticLocation(L, L.getManager(), SingleLocK);
725 }
726 
727 FullSourceLoc
728   PathDiagnosticLocation::genLocation(SourceLocation L,
729                                       LocationOrAnalysisDeclContext LAC) const {
730   assert(isValid());
731   // Note that we want a 'switch' here so that the compiler can warn us in
732   // case we add more cases.
733   switch (K) {
734     case SingleLocK:
735     case RangeK:
736       break;
737     case StmtK:
738       // Defensive checking.
739       if (!S)
740         break;
741       return FullSourceLoc(getValidSourceLocation(S, LAC),
742                            const_cast<SourceManager&>(*SM));
743     case DeclK:
744       // Defensive checking.
745       if (!D)
746         break;
747       return FullSourceLoc(D->getLocation(), const_cast<SourceManager&>(*SM));
748   }
749 
750   return FullSourceLoc(L, const_cast<SourceManager&>(*SM));
751 }
752 
753 PathDiagnosticRange
754   PathDiagnosticLocation::genRange(LocationOrAnalysisDeclContext LAC) const {
755   assert(isValid());
756   // Note that we want a 'switch' here so that the compiler can warn us in
757   // case we add more cases.
758   switch (K) {
759     case SingleLocK:
760       return PathDiagnosticRange(SourceRange(Loc,Loc), true);
761     case RangeK:
762       break;
763     case StmtK: {
764       const Stmt *S = asStmt();
765       switch (S->getStmtClass()) {
766         default:
767           break;
768         case Stmt::DeclStmtClass: {
769           const auto *DS = cast<DeclStmt>(S);
770           if (DS->isSingleDecl()) {
771             // Should always be the case, but we'll be defensive.
772             return SourceRange(DS->getBeginLoc(),
773                                DS->getSingleDecl()->getLocation());
774           }
775           break;
776         }
777           // FIXME: Provide better range information for different
778           //  terminators.
779         case Stmt::IfStmtClass:
780         case Stmt::WhileStmtClass:
781         case Stmt::DoStmtClass:
782         case Stmt::ForStmtClass:
783         case Stmt::ChooseExprClass:
784         case Stmt::IndirectGotoStmtClass:
785         case Stmt::SwitchStmtClass:
786         case Stmt::BinaryConditionalOperatorClass:
787         case Stmt::ConditionalOperatorClass:
788         case Stmt::ObjCForCollectionStmtClass: {
789           SourceLocation L = getValidSourceLocation(S, LAC);
790           return SourceRange(L, L);
791         }
792       }
793       SourceRange R = S->getSourceRange();
794       if (R.isValid())
795         return R;
796       break;
797     }
798     case DeclK:
799       if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
800         return MD->getSourceRange();
801       if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
802         if (Stmt *Body = FD->getBody())
803           return Body->getSourceRange();
804       }
805       else {
806         SourceLocation L = D->getLocation();
807         return PathDiagnosticRange(SourceRange(L, L), true);
808       }
809   }
810 
811   return SourceRange(Loc, Loc);
812 }
813 
814 void PathDiagnosticLocation::flatten() {
815   if (K == StmtK) {
816     K = RangeK;
817     S = nullptr;
818     D = nullptr;
819   }
820   else if (K == DeclK) {
821     K = SingleLocK;
822     S = nullptr;
823     D = nullptr;
824   }
825 }
826 
827 //===----------------------------------------------------------------------===//
828 // Manipulation of PathDiagnosticCallPieces.
829 //===----------------------------------------------------------------------===//
830 
831 std::shared_ptr<PathDiagnosticCallPiece>
832 PathDiagnosticCallPiece::construct(const CallExitEnd &CE,
833                                    const SourceManager &SM) {
834   const Decl *caller = CE.getLocationContext()->getDecl();
835   PathDiagnosticLocation pos = getLocationForCaller(CE.getCalleeContext(),
836                                                     CE.getLocationContext(),
837                                                     SM);
838   return std::shared_ptr<PathDiagnosticCallPiece>(
839       new PathDiagnosticCallPiece(caller, pos));
840 }
841 
842 PathDiagnosticCallPiece *
843 PathDiagnosticCallPiece::construct(PathPieces &path,
844                                    const Decl *caller) {
845   std::shared_ptr<PathDiagnosticCallPiece> C(
846       new PathDiagnosticCallPiece(path, caller));
847   path.clear();
848   auto *R = C.get();
849   path.push_front(std::move(C));
850   return R;
851 }
852 
853 void PathDiagnosticCallPiece::setCallee(const CallEnter &CE,
854                                         const SourceManager &SM) {
855   const StackFrameContext *CalleeCtx = CE.getCalleeContext();
856   Callee = CalleeCtx->getDecl();
857 
858   callEnterWithin = PathDiagnosticLocation::createBegin(Callee, SM);
859   callEnter = getLocationForCaller(CalleeCtx, CE.getLocationContext(), SM);
860 
861   // Autosynthesized property accessors are special because we'd never
862   // pop back up to non-autosynthesized code until we leave them.
863   // This is not generally true for autosynthesized callees, which may call
864   // non-autosynthesized callbacks.
865   // Unless set here, the IsCalleeAnAutosynthesizedPropertyAccessor flag
866   // defaults to false.
867   if (const auto *MD = dyn_cast<ObjCMethodDecl>(Callee))
868     IsCalleeAnAutosynthesizedPropertyAccessor = (
869         MD->isPropertyAccessor() &&
870         CalleeCtx->getAnalysisDeclContext()->isBodyAutosynthesized());
871 }
872 
873 static void describeTemplateParameters(raw_ostream &Out,
874                                        const ArrayRef<TemplateArgument> TAList,
875                                        const LangOptions &LO,
876                                        StringRef Prefix = StringRef(),
877                                        StringRef Postfix = StringRef());
878 
879 static void describeTemplateParameter(raw_ostream &Out,
880                                       const TemplateArgument &TArg,
881                                       const LangOptions &LO) {
882 
883   if (TArg.getKind() == TemplateArgument::ArgKind::Pack) {
884     describeTemplateParameters(Out, TArg.getPackAsArray(), LO);
885   } else {
886     TArg.print(PrintingPolicy(LO), Out);
887   }
888 }
889 
890 static void describeTemplateParameters(raw_ostream &Out,
891                                        const ArrayRef<TemplateArgument> TAList,
892                                        const LangOptions &LO,
893                                        StringRef Prefix, StringRef Postfix) {
894   if (TAList.empty())
895     return;
896 
897   Out << Prefix;
898   for (int I = 0, Last = TAList.size() - 1; I != Last; ++I) {
899     describeTemplateParameter(Out, TAList[I], LO);
900     Out << ", ";
901   }
902   describeTemplateParameter(Out, TAList[TAList.size() - 1], LO);
903   Out << Postfix;
904 }
905 
906 static void describeClass(raw_ostream &Out, const CXXRecordDecl *D,
907                           StringRef Prefix = StringRef()) {
908   if (!D->getIdentifier())
909     return;
910   Out << Prefix << '\'' << *D;
911   if (const auto T = dyn_cast<ClassTemplateSpecializationDecl>(D))
912     describeTemplateParameters(Out, T->getTemplateArgs().asArray(),
913                                D->getLangOpts(), "<", ">");
914 
915   Out << '\'';
916 }
917 
918 static bool describeCodeDecl(raw_ostream &Out, const Decl *D,
919                              bool ExtendedDescription,
920                              StringRef Prefix = StringRef()) {
921   if (!D)
922     return false;
923 
924   if (isa<BlockDecl>(D)) {
925     if (ExtendedDescription)
926       Out << Prefix << "anonymous block";
927     return ExtendedDescription;
928   }
929 
930   if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
931     Out << Prefix;
932     if (ExtendedDescription && !MD->isUserProvided()) {
933       if (MD->isExplicitlyDefaulted())
934         Out << "defaulted ";
935       else
936         Out << "implicit ";
937     }
938 
939     if (const auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
940       if (CD->isDefaultConstructor())
941         Out << "default ";
942       else if (CD->isCopyConstructor())
943         Out << "copy ";
944       else if (CD->isMoveConstructor())
945         Out << "move ";
946 
947       Out << "constructor";
948       describeClass(Out, MD->getParent(), " for ");
949     } else if (isa<CXXDestructorDecl>(MD)) {
950       if (!MD->isUserProvided()) {
951         Out << "destructor";
952         describeClass(Out, MD->getParent(), " for ");
953       } else {
954         // Use ~Foo for explicitly-written destructors.
955         Out << "'" << *MD << "'";
956       }
957     } else if (MD->isCopyAssignmentOperator()) {
958         Out << "copy assignment operator";
959         describeClass(Out, MD->getParent(), " for ");
960     } else if (MD->isMoveAssignmentOperator()) {
961         Out << "move assignment operator";
962         describeClass(Out, MD->getParent(), " for ");
963     } else {
964       if (MD->getParent()->getIdentifier())
965         Out << "'" << *MD->getParent() << "::" << *MD << "'";
966       else
967         Out << "'" << *MD << "'";
968     }
969 
970     return true;
971   }
972 
973   Out << Prefix << '\'' << cast<NamedDecl>(*D);
974 
975   // Adding template parameters.
976   if (const auto FD = dyn_cast<FunctionDecl>(D))
977     if (const TemplateArgumentList *TAList =
978                                     FD->getTemplateSpecializationArgs())
979       describeTemplateParameters(Out, TAList->asArray(), FD->getLangOpts(), "<",
980                                  ">");
981 
982   Out << '\'';
983   return true;
984 }
985 
986 std::shared_ptr<PathDiagnosticEventPiece>
987 PathDiagnosticCallPiece::getCallEnterEvent() const {
988   // We do not produce call enters and call exits for autosynthesized property
989   // accessors. We do generally produce them for other functions coming from
990   // the body farm because they may call callbacks that bring us back into
991   // visible code.
992   if (!Callee || IsCalleeAnAutosynthesizedPropertyAccessor)
993     return nullptr;
994 
995   SmallString<256> buf;
996   llvm::raw_svector_ostream Out(buf);
997 
998   Out << "Calling ";
999   describeCodeDecl(Out, Callee, /*ExtendedDescription=*/true);
1000 
1001   assert(callEnter.asLocation().isValid());
1002   return std::make_shared<PathDiagnosticEventPiece>(callEnter, Out.str());
1003 }
1004 
1005 std::shared_ptr<PathDiagnosticEventPiece>
1006 PathDiagnosticCallPiece::getCallEnterWithinCallerEvent() const {
1007   if (!callEnterWithin.asLocation().isValid())
1008     return nullptr;
1009   if (Callee->isImplicit() || !Callee->hasBody())
1010     return nullptr;
1011   if (const auto *MD = dyn_cast<CXXMethodDecl>(Callee))
1012     if (MD->isDefaulted())
1013       return nullptr;
1014 
1015   SmallString<256> buf;
1016   llvm::raw_svector_ostream Out(buf);
1017 
1018   Out << "Entered call";
1019   describeCodeDecl(Out, Caller, /*ExtendedDescription=*/false, " from ");
1020 
1021   return std::make_shared<PathDiagnosticEventPiece>(callEnterWithin, Out.str());
1022 }
1023 
1024 std::shared_ptr<PathDiagnosticEventPiece>
1025 PathDiagnosticCallPiece::getCallExitEvent() const {
1026   // We do not produce call enters and call exits for autosynthesized property
1027   // accessors. We do generally produce them for other functions coming from
1028   // the body farm because they may call callbacks that bring us back into
1029   // visible code.
1030   if (NoExit || IsCalleeAnAutosynthesizedPropertyAccessor)
1031     return nullptr;
1032 
1033   SmallString<256> buf;
1034   llvm::raw_svector_ostream Out(buf);
1035 
1036   if (!CallStackMessage.empty()) {
1037     Out << CallStackMessage;
1038   } else {
1039     bool DidDescribe = describeCodeDecl(Out, Callee,
1040                                         /*ExtendedDescription=*/false,
1041                                         "Returning from ");
1042     if (!DidDescribe)
1043       Out << "Returning to caller";
1044   }
1045 
1046   assert(callReturn.asLocation().isValid());
1047   return std::make_shared<PathDiagnosticEventPiece>(callReturn, Out.str());
1048 }
1049 
1050 static void compute_path_size(const PathPieces &pieces, unsigned &size) {
1051   for (const auto &I : pieces) {
1052     const PathDiagnosticPiece *piece = I.get();
1053     if (const auto *cp = dyn_cast<PathDiagnosticCallPiece>(piece))
1054       compute_path_size(cp->path, size);
1055     else
1056       ++size;
1057   }
1058 }
1059 
1060 unsigned PathDiagnostic::full_size() {
1061   unsigned size = 0;
1062   compute_path_size(path, size);
1063   return size;
1064 }
1065 
1066 //===----------------------------------------------------------------------===//
1067 // FoldingSet profiling methods.
1068 //===----------------------------------------------------------------------===//
1069 
1070 void PathDiagnosticLocation::Profile(llvm::FoldingSetNodeID &ID) const {
1071   ID.AddInteger(Range.getBegin().getRawEncoding());
1072   ID.AddInteger(Range.getEnd().getRawEncoding());
1073   ID.AddInteger(Loc.getRawEncoding());
1074 }
1075 
1076 void PathDiagnosticPiece::Profile(llvm::FoldingSetNodeID &ID) const {
1077   ID.AddInteger((unsigned) getKind());
1078   ID.AddString(str);
1079   // FIXME: Add profiling support for code hints.
1080   ID.AddInteger((unsigned) getDisplayHint());
1081   ArrayRef<SourceRange> Ranges = getRanges();
1082   for (const auto &I : Ranges) {
1083     ID.AddInteger(I.getBegin().getRawEncoding());
1084     ID.AddInteger(I.getEnd().getRawEncoding());
1085   }
1086 }
1087 
1088 void PathDiagnosticCallPiece::Profile(llvm::FoldingSetNodeID &ID) const {
1089   PathDiagnosticPiece::Profile(ID);
1090   for (const auto &I : path)
1091     ID.Add(*I);
1092 }
1093 
1094 void PathDiagnosticSpotPiece::Profile(llvm::FoldingSetNodeID &ID) const {
1095   PathDiagnosticPiece::Profile(ID);
1096   ID.Add(Pos);
1097 }
1098 
1099 void PathDiagnosticControlFlowPiece::Profile(llvm::FoldingSetNodeID &ID) const {
1100   PathDiagnosticPiece::Profile(ID);
1101   for (const auto &I : *this)
1102     ID.Add(I);
1103 }
1104 
1105 void PathDiagnosticMacroPiece::Profile(llvm::FoldingSetNodeID &ID) const {
1106   PathDiagnosticSpotPiece::Profile(ID);
1107   for (const auto &I : subPieces)
1108     ID.Add(*I);
1109 }
1110 
1111 void PathDiagnosticNotePiece::Profile(llvm::FoldingSetNodeID &ID) const {
1112   PathDiagnosticSpotPiece::Profile(ID);
1113 }
1114 
1115 void PathDiagnosticPopUpPiece::Profile(llvm::FoldingSetNodeID &ID) const {
1116   PathDiagnosticSpotPiece::Profile(ID);
1117 }
1118 
1119 void PathDiagnostic::Profile(llvm::FoldingSetNodeID &ID) const {
1120   ID.Add(getLocation());
1121   ID.AddString(BugType);
1122   ID.AddString(VerboseDesc);
1123   ID.AddString(Category);
1124 }
1125 
1126 void PathDiagnostic::FullProfile(llvm::FoldingSetNodeID &ID) const {
1127   Profile(ID);
1128   for (const auto &I : path)
1129     ID.Add(*I);
1130   for (meta_iterator I = meta_begin(), E = meta_end(); I != E; ++I)
1131     ID.AddString(*I);
1132 }
1133 
1134 LLVM_DUMP_METHOD void PathPieces::dump() const {
1135   unsigned index = 0;
1136   for (PathPieces::const_iterator I = begin(), E = end(); I != E; ++I) {
1137     llvm::errs() << "[" << index++ << "]  ";
1138     (*I)->dump();
1139     llvm::errs() << "\n";
1140   }
1141 }
1142 
1143 LLVM_DUMP_METHOD void PathDiagnosticCallPiece::dump() const {
1144   llvm::errs() << "CALL\n--------------\n";
1145 
1146   if (const Stmt *SLoc = getLocation().getStmtOrNull())
1147     SLoc->dump();
1148   else if (const auto *ND = dyn_cast_or_null<NamedDecl>(getCallee()))
1149     llvm::errs() << *ND << "\n";
1150   else
1151     getLocation().dump();
1152 }
1153 
1154 LLVM_DUMP_METHOD void PathDiagnosticEventPiece::dump() const {
1155   llvm::errs() << "EVENT\n--------------\n";
1156   llvm::errs() << getString() << "\n";
1157   llvm::errs() << " ---- at ----\n";
1158   getLocation().dump();
1159 }
1160 
1161 LLVM_DUMP_METHOD void PathDiagnosticControlFlowPiece::dump() const {
1162   llvm::errs() << "CONTROL\n--------------\n";
1163   getStartLocation().dump();
1164   llvm::errs() << " ---- to ----\n";
1165   getEndLocation().dump();
1166 }
1167 
1168 LLVM_DUMP_METHOD void PathDiagnosticMacroPiece::dump() const {
1169   llvm::errs() << "MACRO\n--------------\n";
1170   // FIXME: Print which macro is being invoked.
1171 }
1172 
1173 LLVM_DUMP_METHOD void PathDiagnosticNotePiece::dump() const {
1174   llvm::errs() << "NOTE\n--------------\n";
1175   llvm::errs() << getString() << "\n";
1176   llvm::errs() << " ---- at ----\n";
1177   getLocation().dump();
1178 }
1179 
1180 LLVM_DUMP_METHOD void PathDiagnosticPopUpPiece::dump() const {
1181   llvm::errs() << "POP-UP\n--------------\n";
1182   llvm::errs() << getString() << "\n";
1183   llvm::errs() << " ---- at ----\n";
1184   getLocation().dump();
1185 }
1186 
1187 LLVM_DUMP_METHOD void PathDiagnosticLocation::dump() const {
1188   if (!isValid()) {
1189     llvm::errs() << "<INVALID>\n";
1190     return;
1191   }
1192 
1193   switch (K) {
1194   case RangeK:
1195     // FIXME: actually print the range.
1196     llvm::errs() << "<range>\n";
1197     break;
1198   case SingleLocK:
1199     asLocation().dump();
1200     llvm::errs() << "\n";
1201     break;
1202   case StmtK:
1203     if (S)
1204       S->dump();
1205     else
1206       llvm::errs() << "<NULL STMT>\n";
1207     break;
1208   case DeclK:
1209     if (const auto *ND = dyn_cast_or_null<NamedDecl>(D))
1210       llvm::errs() << *ND << "\n";
1211     else if (isa<BlockDecl>(D))
1212       // FIXME: Make this nicer.
1213       llvm::errs() << "<block>\n";
1214     else if (D)
1215       llvm::errs() << "<unknown decl>\n";
1216     else
1217       llvm::errs() << "<NULL DECL>\n";
1218     break;
1219   }
1220 }
1221