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