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