xref: /freebsd/contrib/llvm-project/clang/lib/Analysis/PathDiagnostic.cpp (revision e17f5b1d307b7b8910d67883e57a9604305906d5)
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 CheckerName, 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     : CheckerName(CheckerName), 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     if (Optional<CFGElement> BlockFront = BE->getFirstElement()) {
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     }
707 
708     return PathDiagnosticLocation(
709         BE->getBlock()->getTerminatorStmt()->getBeginLoc(), SMng);
710   } else if (Optional<FunctionExitPoint> FE = P.getAs<FunctionExitPoint>()) {
711     return PathDiagnosticLocation(FE->getStmt(), SMng,
712                                   FE->getLocationContext());
713   } else {
714     llvm_unreachable("Unexpected ProgramPoint");
715   }
716 
717   return PathDiagnosticLocation(S, SMng, P.getLocationContext());
718 }
719 
720 PathDiagnosticLocation PathDiagnosticLocation::createSingleLocation(
721                                            const PathDiagnosticLocation &PDL) {
722   FullSourceLoc L = PDL.asLocation();
723   return PathDiagnosticLocation(L, L.getManager(), SingleLocK);
724 }
725 
726 FullSourceLoc
727   PathDiagnosticLocation::genLocation(SourceLocation L,
728                                       LocationOrAnalysisDeclContext LAC) const {
729   assert(isValid());
730   // Note that we want a 'switch' here so that the compiler can warn us in
731   // case we add more cases.
732   switch (K) {
733     case SingleLocK:
734     case RangeK:
735       break;
736     case StmtK:
737       // Defensive checking.
738       if (!S)
739         break;
740       return FullSourceLoc(getValidSourceLocation(S, LAC),
741                            const_cast<SourceManager&>(*SM));
742     case DeclK:
743       // Defensive checking.
744       if (!D)
745         break;
746       return FullSourceLoc(D->getLocation(), const_cast<SourceManager&>(*SM));
747   }
748 
749   return FullSourceLoc(L, const_cast<SourceManager&>(*SM));
750 }
751 
752 PathDiagnosticRange
753   PathDiagnosticLocation::genRange(LocationOrAnalysisDeclContext LAC) const {
754   assert(isValid());
755   // Note that we want a 'switch' here so that the compiler can warn us in
756   // case we add more cases.
757   switch (K) {
758     case SingleLocK:
759       return PathDiagnosticRange(SourceRange(Loc,Loc), true);
760     case RangeK:
761       break;
762     case StmtK: {
763       const Stmt *S = asStmt();
764       switch (S->getStmtClass()) {
765         default:
766           break;
767         case Stmt::DeclStmtClass: {
768           const auto *DS = cast<DeclStmt>(S);
769           if (DS->isSingleDecl()) {
770             // Should always be the case, but we'll be defensive.
771             return SourceRange(DS->getBeginLoc(),
772                                DS->getSingleDecl()->getLocation());
773           }
774           break;
775         }
776           // FIXME: Provide better range information for different
777           //  terminators.
778         case Stmt::IfStmtClass:
779         case Stmt::WhileStmtClass:
780         case Stmt::DoStmtClass:
781         case Stmt::ForStmtClass:
782         case Stmt::ChooseExprClass:
783         case Stmt::IndirectGotoStmtClass:
784         case Stmt::SwitchStmtClass:
785         case Stmt::BinaryConditionalOperatorClass:
786         case Stmt::ConditionalOperatorClass:
787         case Stmt::ObjCForCollectionStmtClass: {
788           SourceLocation L = getValidSourceLocation(S, LAC);
789           return SourceRange(L, L);
790         }
791       }
792       SourceRange R = S->getSourceRange();
793       if (R.isValid())
794         return R;
795       break;
796     }
797     case DeclK:
798       if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
799         return MD->getSourceRange();
800       if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
801         if (Stmt *Body = FD->getBody())
802           return Body->getSourceRange();
803       }
804       else {
805         SourceLocation L = D->getLocation();
806         return PathDiagnosticRange(SourceRange(L, L), true);
807       }
808   }
809 
810   return SourceRange(Loc, Loc);
811 }
812 
813 void PathDiagnosticLocation::flatten() {
814   if (K == StmtK) {
815     K = RangeK;
816     S = nullptr;
817     D = nullptr;
818   }
819   else if (K == DeclK) {
820     K = SingleLocK;
821     S = nullptr;
822     D = nullptr;
823   }
824 }
825 
826 //===----------------------------------------------------------------------===//
827 // Manipulation of PathDiagnosticCallPieces.
828 //===----------------------------------------------------------------------===//
829 
830 std::shared_ptr<PathDiagnosticCallPiece>
831 PathDiagnosticCallPiece::construct(const CallExitEnd &CE,
832                                    const SourceManager &SM) {
833   const Decl *caller = CE.getLocationContext()->getDecl();
834   PathDiagnosticLocation pos = getLocationForCaller(CE.getCalleeContext(),
835                                                     CE.getLocationContext(),
836                                                     SM);
837   return std::shared_ptr<PathDiagnosticCallPiece>(
838       new PathDiagnosticCallPiece(caller, pos));
839 }
840 
841 PathDiagnosticCallPiece *
842 PathDiagnosticCallPiece::construct(PathPieces &path,
843                                    const Decl *caller) {
844   std::shared_ptr<PathDiagnosticCallPiece> C(
845       new PathDiagnosticCallPiece(path, caller));
846   path.clear();
847   auto *R = C.get();
848   path.push_front(std::move(C));
849   return R;
850 }
851 
852 void PathDiagnosticCallPiece::setCallee(const CallEnter &CE,
853                                         const SourceManager &SM) {
854   const StackFrameContext *CalleeCtx = CE.getCalleeContext();
855   Callee = CalleeCtx->getDecl();
856 
857   callEnterWithin = PathDiagnosticLocation::createBegin(Callee, SM);
858   callEnter = getLocationForCaller(CalleeCtx, CE.getLocationContext(), SM);
859 
860   // Autosynthesized property accessors are special because we'd never
861   // pop back up to non-autosynthesized code until we leave them.
862   // This is not generally true for autosynthesized callees, which may call
863   // non-autosynthesized callbacks.
864   // Unless set here, the IsCalleeAnAutosynthesizedPropertyAccessor flag
865   // defaults to false.
866   if (const auto *MD = dyn_cast<ObjCMethodDecl>(Callee))
867     IsCalleeAnAutosynthesizedPropertyAccessor = (
868         MD->isPropertyAccessor() &&
869         CalleeCtx->getAnalysisDeclContext()->isBodyAutosynthesized());
870 }
871 
872 static void describeTemplateParameters(raw_ostream &Out,
873                                        const ArrayRef<TemplateArgument> TAList,
874                                        const LangOptions &LO,
875                                        StringRef Prefix = StringRef(),
876                                        StringRef Postfix = StringRef());
877 
878 static void describeTemplateParameter(raw_ostream &Out,
879                                       const TemplateArgument &TArg,
880                                       const LangOptions &LO) {
881 
882   if (TArg.getKind() == TemplateArgument::ArgKind::Pack) {
883     describeTemplateParameters(Out, TArg.getPackAsArray(), LO);
884   } else {
885     TArg.print(PrintingPolicy(LO), Out);
886   }
887 }
888 
889 static void describeTemplateParameters(raw_ostream &Out,
890                                        const ArrayRef<TemplateArgument> TAList,
891                                        const LangOptions &LO,
892                                        StringRef Prefix, StringRef Postfix) {
893   if (TAList.empty())
894     return;
895 
896   Out << Prefix;
897   for (int I = 0, Last = TAList.size() - 1; I != Last; ++I) {
898     describeTemplateParameter(Out, TAList[I], LO);
899     Out << ", ";
900   }
901   describeTemplateParameter(Out, TAList[TAList.size() - 1], LO);
902   Out << Postfix;
903 }
904 
905 static void describeClass(raw_ostream &Out, const CXXRecordDecl *D,
906                           StringRef Prefix = StringRef()) {
907   if (!D->getIdentifier())
908     return;
909   Out << Prefix << '\'' << *D;
910   if (const auto T = dyn_cast<ClassTemplateSpecializationDecl>(D))
911     describeTemplateParameters(Out, T->getTemplateArgs().asArray(),
912                                D->getASTContext().getLangOpts(), "<", ">");
913 
914   Out << '\'';
915 }
916 
917 static bool describeCodeDecl(raw_ostream &Out, const Decl *D,
918                              bool ExtendedDescription,
919                              StringRef Prefix = StringRef()) {
920   if (!D)
921     return false;
922 
923   if (isa<BlockDecl>(D)) {
924     if (ExtendedDescription)
925       Out << Prefix << "anonymous block";
926     return ExtendedDescription;
927   }
928 
929   if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
930     Out << Prefix;
931     if (ExtendedDescription && !MD->isUserProvided()) {
932       if (MD->isExplicitlyDefaulted())
933         Out << "defaulted ";
934       else
935         Out << "implicit ";
936     }
937 
938     if (const auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
939       if (CD->isDefaultConstructor())
940         Out << "default ";
941       else if (CD->isCopyConstructor())
942         Out << "copy ";
943       else if (CD->isMoveConstructor())
944         Out << "move ";
945 
946       Out << "constructor";
947       describeClass(Out, MD->getParent(), " for ");
948     } else if (isa<CXXDestructorDecl>(MD)) {
949       if (!MD->isUserProvided()) {
950         Out << "destructor";
951         describeClass(Out, MD->getParent(), " for ");
952       } else {
953         // Use ~Foo for explicitly-written destructors.
954         Out << "'" << *MD << "'";
955       }
956     } else if (MD->isCopyAssignmentOperator()) {
957         Out << "copy assignment operator";
958         describeClass(Out, MD->getParent(), " for ");
959     } else if (MD->isMoveAssignmentOperator()) {
960         Out << "move assignment operator";
961         describeClass(Out, MD->getParent(), " for ");
962     } else {
963       if (MD->getParent()->getIdentifier())
964         Out << "'" << *MD->getParent() << "::" << *MD << "'";
965       else
966         Out << "'" << *MD << "'";
967     }
968 
969     return true;
970   }
971 
972   Out << Prefix << '\'' << cast<NamedDecl>(*D);
973 
974   // Adding template parameters.
975   if (const auto FD = dyn_cast<FunctionDecl>(D))
976     if (const TemplateArgumentList *TAList =
977                                     FD->getTemplateSpecializationArgs())
978       describeTemplateParameters(Out, TAList->asArray(),
979                                  FD->getASTContext().getLangOpts(), "<", ">");
980 
981   Out << '\'';
982   return true;
983 }
984 
985 std::shared_ptr<PathDiagnosticEventPiece>
986 PathDiagnosticCallPiece::getCallEnterEvent() const {
987   // We do not produce call enters and call exits for autosynthesized property
988   // accessors. We do generally produce them for other functions coming from
989   // the body farm because they may call callbacks that bring us back into
990   // visible code.
991   if (!Callee || IsCalleeAnAutosynthesizedPropertyAccessor)
992     return nullptr;
993 
994   SmallString<256> buf;
995   llvm::raw_svector_ostream Out(buf);
996 
997   Out << "Calling ";
998   describeCodeDecl(Out, Callee, /*ExtendedDescription=*/true);
999 
1000   assert(callEnter.asLocation().isValid());
1001   return std::make_shared<PathDiagnosticEventPiece>(callEnter, Out.str());
1002 }
1003 
1004 std::shared_ptr<PathDiagnosticEventPiece>
1005 PathDiagnosticCallPiece::getCallEnterWithinCallerEvent() const {
1006   if (!callEnterWithin.asLocation().isValid())
1007     return nullptr;
1008   if (Callee->isImplicit() || !Callee->hasBody())
1009     return nullptr;
1010   if (const auto *MD = dyn_cast<CXXMethodDecl>(Callee))
1011     if (MD->isDefaulted())
1012       return nullptr;
1013 
1014   SmallString<256> buf;
1015   llvm::raw_svector_ostream Out(buf);
1016 
1017   Out << "Entered call";
1018   describeCodeDecl(Out, Caller, /*ExtendedDescription=*/false, " from ");
1019 
1020   return std::make_shared<PathDiagnosticEventPiece>(callEnterWithin, Out.str());
1021 }
1022 
1023 std::shared_ptr<PathDiagnosticEventPiece>
1024 PathDiagnosticCallPiece::getCallExitEvent() const {
1025   // We do not produce call enters and call exits for autosynthesized property
1026   // accessors. We do generally produce them for other functions coming from
1027   // the body farm because they may call callbacks that bring us back into
1028   // visible code.
1029   if (NoExit || IsCalleeAnAutosynthesizedPropertyAccessor)
1030     return nullptr;
1031 
1032   SmallString<256> buf;
1033   llvm::raw_svector_ostream Out(buf);
1034 
1035   if (!CallStackMessage.empty()) {
1036     Out << CallStackMessage;
1037   } else {
1038     bool DidDescribe = describeCodeDecl(Out, Callee,
1039                                         /*ExtendedDescription=*/false,
1040                                         "Returning from ");
1041     if (!DidDescribe)
1042       Out << "Returning to caller";
1043   }
1044 
1045   assert(callReturn.asLocation().isValid());
1046   return std::make_shared<PathDiagnosticEventPiece>(callReturn, Out.str());
1047 }
1048 
1049 static void compute_path_size(const PathPieces &pieces, unsigned &size) {
1050   for (const auto &I : pieces) {
1051     const PathDiagnosticPiece *piece = I.get();
1052     if (const auto *cp = dyn_cast<PathDiagnosticCallPiece>(piece))
1053       compute_path_size(cp->path, size);
1054     else
1055       ++size;
1056   }
1057 }
1058 
1059 unsigned PathDiagnostic::full_size() {
1060   unsigned size = 0;
1061   compute_path_size(path, size);
1062   return size;
1063 }
1064 
1065 //===----------------------------------------------------------------------===//
1066 // FoldingSet profiling methods.
1067 //===----------------------------------------------------------------------===//
1068 
1069 void PathDiagnosticLocation::Profile(llvm::FoldingSetNodeID &ID) const {
1070   ID.AddInteger(Range.getBegin().getRawEncoding());
1071   ID.AddInteger(Range.getEnd().getRawEncoding());
1072   ID.AddInteger(Loc.getRawEncoding());
1073 }
1074 
1075 void PathDiagnosticPiece::Profile(llvm::FoldingSetNodeID &ID) const {
1076   ID.AddInteger((unsigned) getKind());
1077   ID.AddString(str);
1078   // FIXME: Add profiling support for code hints.
1079   ID.AddInteger((unsigned) getDisplayHint());
1080   ArrayRef<SourceRange> Ranges = getRanges();
1081   for (const auto &I : Ranges) {
1082     ID.AddInteger(I.getBegin().getRawEncoding());
1083     ID.AddInteger(I.getEnd().getRawEncoding());
1084   }
1085 }
1086 
1087 void PathDiagnosticCallPiece::Profile(llvm::FoldingSetNodeID &ID) const {
1088   PathDiagnosticPiece::Profile(ID);
1089   for (const auto &I : path)
1090     ID.Add(*I);
1091 }
1092 
1093 void PathDiagnosticSpotPiece::Profile(llvm::FoldingSetNodeID &ID) const {
1094   PathDiagnosticPiece::Profile(ID);
1095   ID.Add(Pos);
1096 }
1097 
1098 void PathDiagnosticControlFlowPiece::Profile(llvm::FoldingSetNodeID &ID) const {
1099   PathDiagnosticPiece::Profile(ID);
1100   for (const auto &I : *this)
1101     ID.Add(I);
1102 }
1103 
1104 void PathDiagnosticMacroPiece::Profile(llvm::FoldingSetNodeID &ID) const {
1105   PathDiagnosticSpotPiece::Profile(ID);
1106   for (const auto &I : subPieces)
1107     ID.Add(*I);
1108 }
1109 
1110 void PathDiagnosticNotePiece::Profile(llvm::FoldingSetNodeID &ID) const {
1111   PathDiagnosticSpotPiece::Profile(ID);
1112 }
1113 
1114 void PathDiagnosticPopUpPiece::Profile(llvm::FoldingSetNodeID &ID) const {
1115   PathDiagnosticSpotPiece::Profile(ID);
1116 }
1117 
1118 void PathDiagnostic::Profile(llvm::FoldingSetNodeID &ID) const {
1119   ID.Add(getLocation());
1120   ID.AddString(BugType);
1121   ID.AddString(VerboseDesc);
1122   ID.AddString(Category);
1123 }
1124 
1125 void PathDiagnostic::FullProfile(llvm::FoldingSetNodeID &ID) const {
1126   Profile(ID);
1127   for (const auto &I : path)
1128     ID.Add(*I);
1129   for (meta_iterator I = meta_begin(), E = meta_end(); I != E; ++I)
1130     ID.AddString(*I);
1131 }
1132 
1133 LLVM_DUMP_METHOD void PathPieces::dump() const {
1134   unsigned index = 0;
1135   for (PathPieces::const_iterator I = begin(), E = end(); I != E; ++I) {
1136     llvm::errs() << "[" << index++ << "]  ";
1137     (*I)->dump();
1138     llvm::errs() << "\n";
1139   }
1140 }
1141 
1142 LLVM_DUMP_METHOD void PathDiagnosticCallPiece::dump() const {
1143   llvm::errs() << "CALL\n--------------\n";
1144 
1145   if (const Stmt *SLoc = getLocation().getStmtOrNull())
1146     SLoc->dump();
1147   else if (const auto *ND = dyn_cast_or_null<NamedDecl>(getCallee()))
1148     llvm::errs() << *ND << "\n";
1149   else
1150     getLocation().dump();
1151 }
1152 
1153 LLVM_DUMP_METHOD void PathDiagnosticEventPiece::dump() const {
1154   llvm::errs() << "EVENT\n--------------\n";
1155   llvm::errs() << getString() << "\n";
1156   llvm::errs() << " ---- at ----\n";
1157   getLocation().dump();
1158 }
1159 
1160 LLVM_DUMP_METHOD void PathDiagnosticControlFlowPiece::dump() const {
1161   llvm::errs() << "CONTROL\n--------------\n";
1162   getStartLocation().dump();
1163   llvm::errs() << " ---- to ----\n";
1164   getEndLocation().dump();
1165 }
1166 
1167 LLVM_DUMP_METHOD void PathDiagnosticMacroPiece::dump() const {
1168   llvm::errs() << "MACRO\n--------------\n";
1169   // FIXME: Print which macro is being invoked.
1170 }
1171 
1172 LLVM_DUMP_METHOD void PathDiagnosticNotePiece::dump() const {
1173   llvm::errs() << "NOTE\n--------------\n";
1174   llvm::errs() << getString() << "\n";
1175   llvm::errs() << " ---- at ----\n";
1176   getLocation().dump();
1177 }
1178 
1179 LLVM_DUMP_METHOD void PathDiagnosticPopUpPiece::dump() const {
1180   llvm::errs() << "POP-UP\n--------------\n";
1181   llvm::errs() << getString() << "\n";
1182   llvm::errs() << " ---- at ----\n";
1183   getLocation().dump();
1184 }
1185 
1186 LLVM_DUMP_METHOD void PathDiagnosticLocation::dump() const {
1187   if (!isValid()) {
1188     llvm::errs() << "<INVALID>\n";
1189     return;
1190   }
1191 
1192   switch (K) {
1193   case RangeK:
1194     // FIXME: actually print the range.
1195     llvm::errs() << "<range>\n";
1196     break;
1197   case SingleLocK:
1198     asLocation().dump();
1199     llvm::errs() << "\n";
1200     break;
1201   case StmtK:
1202     if (S)
1203       S->dump();
1204     else
1205       llvm::errs() << "<NULL STMT>\n";
1206     break;
1207   case DeclK:
1208     if (const auto *ND = dyn_cast_or_null<NamedDecl>(D))
1209       llvm::errs() << *ND << "\n";
1210     else if (isa<BlockDecl>(D))
1211       // FIXME: Make this nicer.
1212       llvm::errs() << "<block>\n";
1213     else if (D)
1214       llvm::errs() << "<unknown decl>\n";
1215     else
1216       llvm::errs() << "<NULL DECL>\n";
1217     break;
1218   }
1219 }
1220