BugReporter.h revision dd986cc9989f665370cef0917ba8ba3b4871e3e6
1db0e15ae3e2b5e180541eec35e2bce54359ca7d8Zhongxing Xu//===---  BugReporter.h - Generate PathDiagnostics --------------*- C++ -*-===//
261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//
361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//                     The LLVM Compiler Infrastructure
461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//
561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek// This file is distributed under the University of Illinois Open Source
661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek// License. See LICENSE.TXT for details.
761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//
861f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//===----------------------------------------------------------------------===//
961f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//
1061f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//  This file defines BugReporter, a utility class for generating
114adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek//  PathDiagnostics for analyses based on GRState.
1261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//
1361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//===----------------------------------------------------------------------===//
1461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
1561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek#ifndef LLVM_CLANG_ANALYSIS_BUGREPORTER
1661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek#define LLVM_CLANG_ANALYSIS_BUGREPORTER
1761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
18e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek#include "clang/Basic/Diagnostic.h"
19d2f642b56e87493edfc3b0dab359b5e32d5f8a5eTed Kremenek#include "clang/Basic/SourceLocation.h"
204adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek#include "clang/Analysis/PathSensitive/GRState.h"
2161f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
2261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek#include "llvm/ADT/SmallPtrSet.h"
23f377fc85488f4799ced714ac60e65a0e3f8f69cbTed Kremenek#include "llvm/ADT/SmallSet.h"
2422caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner#include "llvm/ADT/SmallString.h"
2530bc96544346bea42921cf6837e66cef80d664b4Chris Lattner#include "llvm/ADT/StringExtras.h"
26cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek#include "llvm/ADT/ImmutableSet.h"
27e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek#include <list>
28e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek
2961f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremeneknamespace clang {
3061f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
3161f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekclass PathDiagnostic;
3261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekclass PathDiagnosticPiece;
3361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekclass PathDiagnosticClient;
3461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekclass ASTContext;
3561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekclass Diagnostic;
3650a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenekclass BugReporter;
378966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenekclass BugReporterContext;
3850a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenekclass GRExprEngine;
394adc81e540b874bafa15715fd2c5cb662463debdTed Kremenekclass GRState;
40d2f642b56e87493edfc3b0dab359b5e32d5f8a5eTed Kremenekclass Stmt;
41cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekclass BugType;
421a654b60ef40e84f3943cdb581795c4d4dae1e45Ted Kremenekclass ParentMap;
4350a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek
44cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===//
45cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek// Interface for individual bug reports.
46cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===//
478966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
488966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenekclass BugReporterVisitor {
498966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenekpublic:
508966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  virtual ~BugReporterVisitor();
518966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  virtual PathDiagnosticPiece* VisitNode(const ExplodedNode<GRState>* N,
528966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek                                         const ExplodedNode<GRState>* PrevN,
53dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek                                         BugReporterContext& BRC) = 0;
548966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
558966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  virtual bool isOwnedByReporterContext() { return true; }
568966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek};
5761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
58cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek// FIXME: Combine this with RangedBugReport and remove RangedBugReport.
598966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenekclass BugReport : public BugReporterVisitor {
607a9bb52171f962d51ab13c1e012d2236feb9558dTed Kremenekprotected:
61cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  BugType& BT;
62d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek  std::string ShortDescription;
63cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  std::string Description;
64cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  const ExplodedNode<GRState> *EndNode;
65cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  SourceRange R;
66072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek
67cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekprotected:
68cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  friend class BugReporter;
69cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  friend class BugReportEquivClass;
70cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
71cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  virtual void Profile(llvm::FoldingSetNodeID& hash) const {
72cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    hash.AddInteger(getLocation().getRawEncoding());
73072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek  }
7495cc1bae89ac68626d6f4d389e189ce1ef3aa7f6Ted Kremenek
7550a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenekpublic:
76fe9e543a2a363df7fcaa899367d3b2580b63b27cTed Kremenek  class NodeResolver {
77fe9e543a2a363df7fcaa899367d3b2580b63b27cTed Kremenek  public:
78fe9e543a2a363df7fcaa899367d3b2580b63b27cTed Kremenek    virtual ~NodeResolver() {}
79fe9e543a2a363df7fcaa899367d3b2580b63b27cTed Kremenek    virtual const ExplodedNode<GRState>*
80fe9e543a2a363df7fcaa899367d3b2580b63b27cTed Kremenek            getOriginalNode(const ExplodedNode<GRState>* N) = 0;
81fe9e543a2a363df7fcaa899367d3b2580b63b27cTed Kremenek  };
82fe9e543a2a363df7fcaa899367d3b2580b63b27cTed Kremenek
83cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  BugReport(BugType& bt, const char* desc, const ExplodedNode<GRState> *n)
84cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    : BT(bt), Description(desc), EndNode(n) {}
85d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek
86d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek  BugReport(BugType& bt, const char* shortDesc, const char* desc,
87d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek            const ExplodedNode<GRState> *n)
88d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek  : BT(bt), ShortDescription(shortDesc), Description(desc), EndNode(n) {}
89d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek
9050a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek  virtual ~BugReport();
918966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
928966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  virtual bool isOwnedByReporterContext() { return false; }
93cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
94cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  const BugType& getBugType() const { return BT; }
95cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  BugType& getBugType() { return BT; }
9650a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek
97cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  // FIXME: Perhaps this should be moved into a subclass?
983148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek  const ExplodedNode<GRState>* getEndNode() const { return EndNode; }
99d2f642b56e87493edfc3b0dab359b5e32d5f8a5eTed Kremenek
100cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  // FIXME: Do we need this?  Maybe getLocation() should return a ProgramPoint
101cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  // object.
1028966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  // FIXME: If we do need it, we can probably just make it private to
1038966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  // BugReporter.
104bb77e9b908658b354b058509d3801f3aed052becTed Kremenek  Stmt* getStmt(BugReporter& BR) const;
10561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
106cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  const std::string& getDescription() const { return Description; }
107d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek
108d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek  const std::string& getShortDescription() const {
109d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek    return ShortDescription.empty() ? Description : ShortDescription;
110d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek  }
1118c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek
112cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  // FIXME: Is this needed?
113072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek  virtual std::pair<const char**,const char**> getExtraDescriptiveText() {
114cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    return std::make_pair((const char**)0,(const char**)0);
115072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek  }
116072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek
117cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  // FIXME: Perhaps move this into a subclass.
118dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek  virtual PathDiagnosticPiece* getEndPath(BugReporterContext& BRC,
1193148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek                                          const ExplodedNode<GRState>* N);
120d2f642b56e87493edfc3b0dab359b5e32d5f8a5eTed Kremenek
121cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  /// getLocation - Return the "definitive" location of the reported bug.
122cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  ///  While a bug can span an entire path, usually there is a specific
123cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  ///  location that can be used to identify where the key issue occured.
124cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  ///  This location is used by clients rendering diagnostics.
125cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  virtual SourceLocation getLocation() const;
126f1ae705460552655fe7275327804444c62e86baeTed Kremenek
127cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  /// getRanges - Returns the source ranges associated with this bug.
128bb77e9b908658b354b058509d3801f3aed052becTed Kremenek  virtual void getRanges(BugReporter& BR,const SourceRange*& beg,
129bb77e9b908658b354b058509d3801f3aed052becTed Kremenek                         const SourceRange*& end);
130cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
1318966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  virtual PathDiagnosticPiece* VisitNode(const ExplodedNode<GRState>* N,
1328966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek                                         const ExplodedNode<GRState>* PrevN,
133dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek                                         BugReporterContext& BR);
134dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek
135dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek  virtual void registerInitialVisitors(BugReporterContext& BRC,
136dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek                                       const ExplodedNode<GRState>* N) {}
1376837faa083bebad39aa342f84c2b450fb6410eafTed Kremenek};
138cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
139cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===//
140cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek// BugTypes (collections of related reports).
141cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===//
142cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
143cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekclass BugReportEquivClass : public llvm::FoldingSetNode {
144cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  // List of *owned* BugReport objects.
145cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  std::list<BugReport*> Reports;
146cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
147cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  friend class BugReporter;
148cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  void AddReport(BugReport* R) { Reports.push_back(R); }
149cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekpublic:
150cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  BugReportEquivClass(BugReport* R) { Reports.push_back(R); }
151cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  ~BugReportEquivClass();
152cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
153cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  void Profile(llvm::FoldingSetNodeID& ID) const {
154cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    assert(!Reports.empty());
155cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    (*Reports.begin())->Profile(ID);
156cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  }
157cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
158cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  class iterator {
159cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    std::list<BugReport*>::iterator impl;
160cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  public:
161cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    iterator(std::list<BugReport*>::iterator i) : impl(i) {}
162cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    iterator& operator++() { ++impl; return *this; }
163cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    bool operator==(const iterator& I) const { return I.impl == impl; }
164cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    bool operator!=(const iterator& I) const { return I.impl != impl; }
165cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    BugReport* operator*() const { return *impl; }
166cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    BugReport* operator->() const { return *impl; }
167cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  };
1683aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek
1693aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek  class const_iterator {
1703aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek    std::list<BugReport*>::const_iterator impl;
1713aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek  public:
1723aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek    const_iterator(std::list<BugReport*>::const_iterator i) : impl(i) {}
1733aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek    const_iterator& operator++() { ++impl; return *this; }
1743aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek    bool operator==(const const_iterator& I) const { return I.impl == impl; }
1753aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek    bool operator!=(const const_iterator& I) const { return I.impl != impl; }
1763aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek    const BugReport* operator*() const { return *impl; }
1773aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek    const BugReport* operator->() const { return *impl; }
1783aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek  };
179cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
180cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  iterator begin() { return iterator(Reports.begin()); }
181cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  iterator end() { return iterator(Reports.end()); }
1823aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek
1833aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek  const_iterator begin() const { return const_iterator(Reports.begin()); }
1843aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek  const_iterator end() const { return const_iterator(Reports.end()); }
185cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek};
186cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
187cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekclass BugType {
188cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekprivate:
189cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  const std::string Name;
190cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  const std::string Category;
191cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  llvm::FoldingSet<BugReportEquivClass> EQClasses;
192cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  friend class BugReporter;
193cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekpublic:
194cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  BugType(const char *name, const char* cat) : Name(name), Category(cat) {}
195cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  virtual ~BugType();
1966837faa083bebad39aa342f84c2b450fb6410eafTed Kremenek
197cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  // FIXME: Should these be made strings as well?
198cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  const std::string& getName() const { return Name; }
199cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  const std::string& getCategory() const { return Category; }
200cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
201cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  virtual void FlushReports(BugReporter& BR);
202cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  void AddReport(BugReport* BR);
2033aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek
2043aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek  typedef llvm::FoldingSet<BugReportEquivClass>::iterator iterator;
2053aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek  iterator begin() { return EQClasses.begin(); }
2063aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek  iterator end() { return EQClasses.end(); }
2073aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek
2083aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek  typedef llvm::FoldingSet<BugReportEquivClass>::const_iterator const_iterator;
2093aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek  const_iterator begin() const { return EQClasses.begin(); }
2103aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek  const_iterator end() const { return EQClasses.end(); }
211cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek};
212cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
213cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===//
214cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek// Specialized subclasses of BugReport.
215cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===//
216cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
217cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek// FIXME: Collapse this with the default BugReport class.
218d2f642b56e87493edfc3b0dab359b5e32d5f8a5eTed Kremenekclass RangedBugReport : public BugReport {
2195e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek  std::vector<SourceRange> Ranges;
2205e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenekpublic:
221cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  RangedBugReport(BugType& D, const char* description, ExplodedNode<GRState> *n)
222cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    : BugReport(D, description, n) {}
223d2f642b56e87493edfc3b0dab359b5e32d5f8a5eTed Kremenek
224d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek  RangedBugReport(BugType& D, const char *shortDescription,
225d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek                  const char *description, ExplodedNode<GRState> *n)
226d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek  : BugReport(D, shortDescription, description, n) {}
227d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek
228cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  ~RangedBugReport();
22922bda887aacd0e591978541a799aa43835652ec9Ted Kremenek
230cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  // FIXME: Move this out of line.
2315e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek  void addRange(SourceRange R) { Ranges.push_back(R); }
2325e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek
233cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  // FIXME: Move this out of line.
234cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  void getRanges(BugReporter& BR,const SourceRange*& beg,
235cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek                 const SourceRange*& end) {
2365e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek
2375e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek    if (Ranges.empty()) {
2385e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek      beg = NULL;
2395e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek      end = NULL;
2405e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek    }
2415e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek    else {
2425e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek      beg = &Ranges[0];
2435e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek      end = beg + Ranges.size();
2445e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek    }
2455e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek  }
2465e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek};
2475e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek
248cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===//
249cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek// BugReporter and friends.
250cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===//
251cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
252c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenekclass BugReporterData {
253c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenekpublic:
254c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  virtual ~BugReporterData();
255c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  virtual Diagnostic& getDiagnostic() = 0;
256c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  virtual PathDiagnosticClient* getPathDiagnosticClient() = 0;
257c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  virtual ASTContext& getContext() = 0;
258c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  virtual SourceManager& getSourceManager() = 0;
2597032f460fc9828f386056e75933da5af61e88638Ted Kremenek  virtual CFG* getCFG() = 0;
260c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  virtual ParentMap& getParentMap() = 0;
2617032f460fc9828f386056e75933da5af61e88638Ted Kremenek  virtual LiveVariables* getLiveVariables() = 0;
262c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek};
263c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek
26461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekclass BugReporter {
265c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenekpublic:
266c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  enum Kind { BaseBRKind, GRBugReporterKind };
267c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek
268cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekprivate:
269cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  typedef llvm::ImmutableSet<BugType*> BugTypesTy;
270cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  BugTypesTy::Factory F;
271cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  BugTypesTy BugTypes;
272cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
273cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  const Kind kind;
274c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  BugReporterData& D;
275c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek
276cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  void FlushReport(BugReportEquivClass& EQ);
277cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
278cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekprotected:
279cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  BugReporter(BugReporterData& d, Kind k) : BugTypes(F.GetEmptySet()), kind(k), D(d) {}
280cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
28161f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekpublic:
282cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  BugReporter(BugReporterData& d) : BugTypes(F.GetEmptySet()), kind(BaseBRKind), D(d) {}
283c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  virtual ~BugReporter();
28450a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek
285cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  void FlushReports();
286cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
287c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  Kind getKind() const { return kind; }
28861f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
289c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  Diagnostic& getDiagnostic() {
290c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek    return D.getDiagnostic();
291c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  }
29250a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek
293c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  PathDiagnosticClient* getPathDiagnosticClient() {
294c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek    return D.getPathDiagnosticClient();
295c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  }
29661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
2973aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek  typedef BugTypesTy::iterator iterator;
2983aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek  iterator begin() { return BugTypes.begin(); }
2993aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek  iterator end() { return BugTypes.end(); }
3003aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek
301cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  ASTContext& getContext() { return D.getContext(); }
30261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
303cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  SourceManager& getSourceManager() { return D.getSourceManager(); }
304c9fa2f7bcc3061aa8bcdbe0df26d2c7cf7281539Ted Kremenek
305cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  CFG* getCFG() { return D.getCFG(); }
306c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek
307cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  ParentMap& getParentMap() { return D.getParentMap(); }
308c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek
309cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  LiveVariables* getLiveVariables() { return D.getLiveVariables(); }
310c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek
311cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  virtual void GeneratePathDiagnostic(PathDiagnostic& PD,
312cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek                                      BugReportEquivClass& EQ) {}
31361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
314cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  void Register(BugType *BT);
315cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
316cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  void EmitReport(BugReport *R);
31750a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek
31857202071e477530e9348bc76671ee369b2399b92Ted Kremenek  void EmitBasicReport(const char* BugName, const char* BugStr,
3198f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek                       SourceLocation Loc,
3208f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek                       SourceRange* RangeBeg, unsigned NumRanges);
3218f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek
3228c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek  void EmitBasicReport(const char* BugName, const char* BugCategory,
3238c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek                       const char* BugStr, SourceLocation Loc,
3248c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek                       SourceRange* RangeBeg, unsigned NumRanges);
3258c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek
3268c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek
3278f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek  void EmitBasicReport(const char* BugName, const char* BugStr,
3288f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek                       SourceLocation Loc) {
3298f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek    EmitBasicReport(BugName, BugStr, Loc, 0, 0);
3308f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek  }
3318f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek
33262059e809596a419e6fc3e751b2f0b57b7cc51e7Ted Kremenek  void EmitBasicReport(const char* BugName, const char* BugCategory,
33362059e809596a419e6fc3e751b2f0b57b7cc51e7Ted Kremenek                       const char* BugStr, SourceLocation Loc) {
33462059e809596a419e6fc3e751b2f0b57b7cc51e7Ted Kremenek    EmitBasicReport(BugName, BugCategory, BugStr, Loc, 0, 0);
33562059e809596a419e6fc3e751b2f0b57b7cc51e7Ted Kremenek  }
33662059e809596a419e6fc3e751b2f0b57b7cc51e7Ted Kremenek
3378f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek  void EmitBasicReport(const char* BugName, const char* BugStr,
3388f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek                       SourceLocation Loc, SourceRange R) {
3398f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek    EmitBasicReport(BugName, BugStr, Loc, &R, 1);
3408f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek  }
34157202071e477530e9348bc76671ee369b2399b92Ted Kremenek
3428c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek  void EmitBasicReport(const char* BugName, const char* Category,
3438c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek                       const char* BugStr, SourceLocation Loc, SourceRange R) {
3448c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek    EmitBasicReport(BugName, Category, BugStr, Loc, &R, 1);
3458c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek  }
3468c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek
347c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  static bool classof(const BugReporter* R) { return true; }
348c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek};
3498966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
350cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek// FIXME: Get rid of GRBugReporter.  It's the wrong abstraction.
351c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenekclass GRBugReporter : public BugReporter {
352c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  GRExprEngine& Eng;
3532dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek  llvm::SmallSet<SymbolRef, 10> NotableSymbols;
354cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekpublic:
355c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  GRBugReporter(BugReporterData& d, GRExprEngine& eng)
356c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek    : BugReporter(d, GRBugReporterKind), Eng(eng) {}
3571a654b60ef40e84f3943cdb581795c4d4dae1e45Ted Kremenek
358c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  virtual ~GRBugReporter();
359c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek
360cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek  /// getEngine - Return the analysis engine used to analyze a given
361cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek  ///  function or method.
362cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  GRExprEngine& getEngine() { return Eng; }
363c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek
364cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek  /// getGraph - Get the exploded graph created by the analysis engine
365cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek  ///  for the analyzed method or function.
3664adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek  ExplodedGraph<GRState>& getGraph();
36761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
368cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek  /// getStateManager - Return the state manager used by the analysis
369cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek  ///  engine.
3704adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek  GRStateManager& getStateManager();
371f377fc85488f4799ced714ac60e65a0e3f8f69cbTed Kremenek
372cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  virtual void GeneratePathDiagnostic(PathDiagnostic& PD,
373cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek                                      BugReportEquivClass& R);
374c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek
3752dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek  void addNotableSymbol(SymbolRef Sym) {
376c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek    NotableSymbols.insert(Sym);
377c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  }
378c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek
3792dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek  bool isNotable(SymbolRef Sym) const {
380c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek    return (bool) NotableSymbols.count(Sym);
381c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  }
382cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek
383cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek  /// classof - Used by isa<>, cast<>, and dyn_cast<>.
384c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  static bool classof(const BugReporter* R) {
385c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek    return R->getKind() == GRBugReporterKind;
386c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek  }
38761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek};
3888966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
3898966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenekclass BugReporterContext {
3908966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  GRBugReporter &BR;
3918966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  std::vector<BugReporterVisitor*> Callbacks;
3928966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenekpublic:
3938966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  BugReporterContext(GRBugReporter& br) : BR(br) {}
3948966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  virtual ~BugReporterContext();
3958966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
3968966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  void addVisitor(BugReporterVisitor* visitor) {
3978966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    if (visitor) Callbacks.push_back(visitor);
3988966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  }
3998966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
4008966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  typedef std::vector<BugReporterVisitor*>::iterator visitor_iterator;
4018966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  visitor_iterator visitor_begin() { return Callbacks.begin(); }
4028966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  visitor_iterator visitor_end() { return Callbacks.end(); }
4038966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
4048966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  GRBugReporter& getBugReporter() { return BR; }
4058966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
4068966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  ExplodedGraph<GRState>& getGraph() { return BR.getGraph(); }
4078966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
4088966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  void addNotableSymbol(SymbolRef Sym) {
4098966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    // FIXME: For now forward to GRBugReporter.
4108966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    BR.addNotableSymbol(Sym);
4118966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  }
4128966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
4138966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  bool isNotable(SymbolRef Sym) const {
4148966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    // FIXME: For now forward to GRBugReporter.
4158966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    return BR.isNotable(Sym);
4168966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  }
4178966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
4188966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  GRStateManager& getStateManager() {
4198966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    return BR.getStateManager();
4208966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  }
4218966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
422dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek  ValueManager& getValueManager() {
423dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek    return getStateManager().getValueManager();
424dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek  }
425dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek
4268966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  ASTContext& getASTContext() {
4278966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    return BR.getContext();
4288966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  }
4298966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
4308966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  SourceManager& getSourceManager() {
4318966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    return BR.getSourceManager();
4328966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  }
4338966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
4348966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  const Decl& getCodeDecl() {
4358966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    return getStateManager().getCodeDecl();
4368966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  }
4378966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
4388966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  const CFG& getCFG() {
4398966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    return *BR.getCFG();
4408966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  }
4418966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
4428966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  virtual BugReport::NodeResolver& getNodeResolver() = 0;
4438966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek};
444e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek
445e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenekclass DiagBugReport : public RangedBugReport {
446e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek  std::list<std::string> Strs;
447e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek  FullSourceLoc L;
448e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenekpublic:
449cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  DiagBugReport(BugType& D, const char* desc, FullSourceLoc l) :
450cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  RangedBugReport(D, desc, 0), L(l) {}
451e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek
452e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek  virtual ~DiagBugReport() {}
453e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek
454cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  // FIXME: Move out-of-line (virtual function).
455cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  SourceLocation getLocation() const { return L; }
456e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek
457e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek  void addString(const std::string& s) { Strs.push_back(s); }
458e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek
459e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek  typedef std::list<std::string>::const_iterator str_iterator;
460e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek  str_iterator str_begin() const { return Strs.begin(); }
461e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek  str_iterator str_end() const { return Strs.end(); }
462e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek};
463e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek
46461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek} // end clang namespace
46561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
46661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek#endif
467