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