BugReporter.h revision 686775deca8b8685eb90801495880e3abdd844c2
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===--- BugReporter.h - Generate PathDiagnostics --------------*- C++ -*-===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This file defines BugReporter, a utility class for generating 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// PathDiagnostics for analyses based on GRState. 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef LLVM_CLANG_GR_BUGREPORTER 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define LLVM_CLANG_GR_BUGREPORTER 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/Basic/SourceLocation.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/GRState.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/ADT/FoldingSet.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/ADT/ImmutableList.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/ADT/ImmutableSet.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/ADT/SmallSet.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list> 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace clang { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ASTContext; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Diagnostic; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Stmt; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ParentMap; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ento { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PathDiagnostic; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PathDiagnosticPiece; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PathDiagnosticClient; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExplodedNode; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExplodedGraph; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BugReporter; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BugReporterContext; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExprEngine; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GRState; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BugType; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Interface for individual bug reports. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BugReporterVisitor : public llvm::FoldingSetNode { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~BugReporterVisitor(); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual PathDiagnosticPiece* VisitNode(const ExplodedNode* N, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExplodedNode* PrevN, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BugReporterContext& BRC) = 0; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool isOwnedByReporterContext() { return true; } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FIXME: Combine this with RangedBugReport and remove RangedBugReport. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BugReport : public BugReporterVisitor { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)protected: 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BugType& BT; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string ShortDescription; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string Description; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExplodedNode *ErrorNode; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable SourceRange R; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)protected: 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class BugReporter; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class BugReportEquivClass; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Profile(llvm::FoldingSetNodeID& hash) const { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash.AddPointer(&BT); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash.AddInteger(getLocation().getRawEncoding()); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash.AddString(Description); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class NodeResolver { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~NodeResolver() {} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual const ExplodedNode* 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getOriginalNode(const ExplodedNode* N) = 0; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : BT(bt), Description(desc), ErrorNode(errornode) {} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BugReport(BugType& bt, StringRef shortDesc, StringRef desc, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExplodedNode *errornode) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : BT(bt), ShortDescription(shortDesc), Description(desc), 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorNode(errornode) {} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~BugReport(); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool isOwnedByReporterContext() { return false; } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BugType& getBugType() const { return BT; } 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BugType& getBugType() { return BT; } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FIXME: Perhaps this should be moved into a subclass? 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExplodedNode* getErrorNode() const { return ErrorNode; } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FIXME: Do we need this? Maybe getLocation() should return a ProgramPoint 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // object. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FIXME: If we do need it, we can probably just make it private to 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // BugReporter. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Stmt* getStmt() const; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const StringRef getDescription() const { return Description; } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const StringRef getShortDescription() const { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ShortDescription.empty() ? Description : ShortDescription; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FIXME: Is this needed? 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual std::pair<const char**,const char**> getExtraDescriptiveText() { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::make_pair((const char**)0,(const char**)0); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FIXME: Perhaps move this into a subclass. 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual PathDiagnosticPiece* getEndPath(BugReporterContext& BRC, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExplodedNode* N); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// getLocation - Return the "definitive" location of the reported bug. 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// While a bug can span an entire path, usually there is a specific 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// location that can be used to identify where the key issue occurred. 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// This location is used by clients rendering diagnostics. 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual SourceLocation getLocation() const; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef const SourceRange *ranges_iterator; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// getRanges - Returns the source ranges associated with this bug. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual std::pair<ranges_iterator, ranges_iterator> getRanges() const; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual PathDiagnosticPiece* VisitNode(const ExplodedNode* N, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExplodedNode* PrevN, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BugReporterContext& BR); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void registerInitialVisitors(BugReporterContext& BRC, 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExplodedNode* N) {} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BugTypes (collections of related reports). 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BugReportEquivClass : public llvm::FoldingSetNode { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // List of *owned* BugReport objects. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::list<BugReport*> Reports; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class BugReporter; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddReport(BugReport* R) { Reports.push_back(R); } 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BugReportEquivClass(BugReport* R) { Reports.push_back(R); } 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~BugReportEquivClass(); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Profile(llvm::FoldingSetNodeID& ID) const { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(!Reports.empty()); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*Reports.begin())->Profile(ID); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class iterator { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::list<BugReport*>::iterator impl; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iterator(std::list<BugReport*>::iterator i) : impl(i) {} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iterator& operator++() { ++impl; return *this; } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator==(const iterator& I) const { return I.impl == impl; } 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator!=(const iterator& I) const { return I.impl != impl; } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BugReport* operator*() const { return *impl; } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BugReport* operator->() const { return *impl; } 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class const_iterator { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::list<BugReport*>::const_iterator impl; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_iterator(std::list<BugReport*>::const_iterator i) : impl(i) {} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_iterator& operator++() { ++impl; return *this; } 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator==(const const_iterator& I) const { return I.impl == impl; } 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator!=(const const_iterator& I) const { return I.impl != impl; } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BugReport* operator*() const { return *impl; } 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BugReport* operator->() const { return *impl; } 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iterator begin() { return iterator(Reports.begin()); } 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iterator end() { return iterator(Reports.end()); } 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_iterator begin() const { return const_iterator(Reports.begin()); } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_iterator end() const { return const_iterator(Reports.end()); } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Specialized subclasses of BugReport. 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FIXME: Collapse this with the default BugReport class. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RangedBugReport : public BugReport { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SmallVector<SourceRange, 4> Ranges; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RangedBugReport(BugType& D, StringRef description, 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExplodedNode *errornode) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : BugReport(D, description, errornode) {} 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RangedBugReport(BugType& D, StringRef shortDescription, 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringRef description, ExplodedNode *errornode) 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : BugReport(D, shortDescription, description, errornode) {} 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ~RangedBugReport(); 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // FIXME: Move this out of line. 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void addRange(SourceRange R) { 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) assert(R.isValid()); 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Ranges.push_back(R); 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual std::pair<ranges_iterator, ranges_iterator> getRanges() const { 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::make_pair(Ranges.begin(), Ranges.end()); 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void Profile(llvm::FoldingSetNodeID& hash) const { 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BugReport::Profile(hash); 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (SmallVectorImpl<SourceRange>::const_iterator I = 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Ranges.begin(), E = Ranges.end(); I != E; ++I) { 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const SourceRange range = *I; 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!range.isValid()) 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue; 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hash.AddInteger(range.getBegin().getRawEncoding()); 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hash.AddInteger(range.getEnd().getRawEncoding()); 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class EnhancedBugReport : public RangedBugReport { 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)public: 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef void (*VisitorCreator)(BugReporterContext &BRcC, const void *data, 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ExplodedNode *N); 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)private: 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::vector<std::pair<VisitorCreator, const void*> > Creators; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Creators creators; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnhancedBugReport(BugType& D, StringRef description, 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExplodedNode *errornode) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : RangedBugReport(D, description, errornode) {} 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnhancedBugReport(BugType& D, StringRef shortDescription, 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringRef description, ExplodedNode *errornode) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : RangedBugReport(D, shortDescription, description, errornode) {} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ~EnhancedBugReport() {} 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void registerInitialVisitors(BugReporterContext& BRC, const ExplodedNode* N) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Creators::iterator I = creators.begin(), E = creators.end(); I!=E; ++I) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) I->first(BRC, I->second, N); 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void addVisitorCreator(VisitorCreator creator, const void *data) { 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) creators.push_back(std::make_pair(creator, data)); 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BugReporter and friends. 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class BugReporterData { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~BugReporterData(); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual Diagnostic& getDiagnostic() = 0; 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual PathDiagnosticClient* getPathDiagnosticClient() = 0; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ASTContext& getASTContext() = 0; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual SourceManager& getSourceManager() = 0; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BugReporter { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum Kind { BaseBRKind, GRBugReporterKind }; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)private: 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef llvm::ImmutableSet<BugType*> BugTypesTy; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BugTypesTy::Factory F; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BugTypesTy BugTypes; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Kind kind; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BugReporterData& D; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void FlushReport(BugReportEquivClass& EQ); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) llvm::FoldingSet<BugReportEquivClass> EQClasses; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)protected: 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BugReporter(BugReporterData& d, Kind k) : BugTypes(F.getEmptySet()), kind(k), 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) D(d) {} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)public: 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BugReporter(BugReporterData& d) : BugTypes(F.getEmptySet()), kind(BaseBRKind), 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) D(d) {} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~BugReporter(); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void FlushReports(); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Kind getKind() const { return kind; } 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Diagnostic& getDiagnostic() { 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return D.getDiagnostic(); 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PathDiagnosticClient* getPathDiagnosticClient() { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return D.getPathDiagnosticClient(); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) typedef BugTypesTy::iterator iterator; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iterator begin() { return BugTypes.begin(); } 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iterator end() { return BugTypes.end(); } 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef llvm::FoldingSet<BugReportEquivClass>::iterator EQClasses_iterator; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EQClasses_iterator EQClasses_begin() { return EQClasses.begin(); } 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EQClasses_iterator EQClasses_end() { return EQClasses.end(); } 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASTContext& getContext() { return D.getASTContext(); } 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SourceManager& getSourceManager() { return D.getSourceManager(); } 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void GeneratePathDiagnostic(PathDiagnostic& pathDiagnostic, 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SmallVectorImpl<BugReport *> &bugReports) {} 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void Register(BugType *BT); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void EmitReport(BugReport *R); 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void EmitBasicReport(StringRef BugName, StringRef BugStr, 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SourceLocation Loc, 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SourceRange* RangeBeg, unsigned NumRanges); 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void EmitBasicReport(StringRef BugName, StringRef BugCategory, 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringRef BugStr, SourceLocation Loc, 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SourceRange* RangeBeg, unsigned NumRanges); 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void EmitBasicReport(StringRef BugName, StringRef BugStr, 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SourceLocation Loc) { 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EmitBasicReport(BugName, BugStr, Loc, 0, 0); 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void EmitBasicReport(StringRef BugName, StringRef BugCategory, 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringRef BugStr, SourceLocation Loc) { 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EmitBasicReport(BugName, BugCategory, BugStr, Loc, 0, 0); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void EmitBasicReport(StringRef BugName, StringRef BugStr, 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SourceLocation Loc, SourceRange R) { 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EmitBasicReport(BugName, BugStr, Loc, &R, 1); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void EmitBasicReport(StringRef BugName, StringRef Category, 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringRef BugStr, SourceLocation Loc, 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SourceRange R) { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EmitBasicReport(BugName, Category, BugStr, Loc, &R, 1); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool classof(const BugReporter* R) { return true; } 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)private: 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) llvm::StringMap<BugType *> StrBugTypes; 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// \brief Returns a BugType that is associated with the given name and 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// category. 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BugType *getBugTypeForName(StringRef name, StringRef category); 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// FIXME: Get rid of GRBugReporter. It's the wrong abstraction. 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class GRBugReporter : public BugReporter { 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExprEngine& Eng; 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) llvm::SmallSet<SymbolRef, 10> NotableSymbols; 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public: 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GRBugReporter(BugReporterData& d, ExprEngine& eng) 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : BugReporter(d, GRBugReporterKind), Eng(eng) {} 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~GRBugReporter(); 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// getEngine - Return the analysis engine used to analyze a given 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// function or method. 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExprEngine &getEngine() { return Eng; } 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// getGraph - Get the exploded graph created by the analysis engine 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// for the analyzed method or function. 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExplodedGraph &getGraph(); 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// getStateManager - Return the state manager used by the analysis 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// engine. 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GRStateManager &getStateManager(); 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void GeneratePathDiagnostic(PathDiagnostic &pathDiagnostic, 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SmallVectorImpl<BugReport*> &bugReports); 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void addNotableSymbol(SymbolRef Sym) { 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotableSymbols.insert(Sym); 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool isNotable(SymbolRef Sym) const { 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (bool) NotableSymbols.count(Sym); 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// classof - Used by isa<>, cast<>, and dyn_cast<>. 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static bool classof(const BugReporter* R) { 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return R->getKind() == GRBugReporterKind; 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class BugReporterContext { 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GRBugReporter &BR; 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Not the most efficient data structure, but we use an ImmutableList for the 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Callbacks because it is safe to make additions to list during iteration. 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) llvm::ImmutableList<BugReporterVisitor*>::Factory F; 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) llvm::ImmutableList<BugReporterVisitor*> Callbacks; 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) llvm::FoldingSet<BugReporterVisitor> CallbacksSet; 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public: 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BugReporterContext(GRBugReporter& br) : BR(br), Callbacks(F.getEmptyList()) {} 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~BugReporterContext(); 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void addVisitor(BugReporterVisitor* visitor); 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef llvm::ImmutableList<BugReporterVisitor*>::iterator visitor_iterator; 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) visitor_iterator visitor_begin() { return Callbacks.begin(); } 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) visitor_iterator visitor_end() { return Callbacks.end(); } 430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GRBugReporter& getBugReporter() { return BR; } 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExplodedGraph &getGraph() { return BR.getGraph(); } 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void addNotableSymbol(SymbolRef Sym) { 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // FIXME: For now forward to GRBugReporter. 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BR.addNotableSymbol(Sym); 438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool isNotable(SymbolRef Sym) const { 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // FIXME: For now forward to GRBugReporter. 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return BR.isNotable(Sym); 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GRStateManager& getStateManager() { 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return BR.getStateManager(); 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SValBuilder& getSValBuilder() { 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return getStateManager().getSValBuilder(); 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASTContext& getASTContext() { 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return BR.getContext(); 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SourceManager& getSourceManager() { 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return BR.getSourceManager(); 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual BugReport::NodeResolver& getNodeResolver() = 0; 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class DiagBugReport : public RangedBugReport { 465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::list<std::string> Strs; 466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FullSourceLoc L; 467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)public: 468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DiagBugReport(BugType& D, StringRef desc, FullSourceLoc l) : 469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RangedBugReport(D, desc, 0), L(l) {} 470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~DiagBugReport() {} 472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // FIXME: Move out-of-line (virtual function). 474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SourceLocation getLocation() const { return L; } 475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void addString(StringRef s) { Strs.push_back(s); } 477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) typedef std::list<std::string>::const_iterator str_iterator; 479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) str_iterator str_begin() const { return Strs.begin(); } 480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) str_iterator str_end() const { return Strs.end(); } 481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//===----------------------------------------------------------------------===// 484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//===----------------------------------------------------------------------===// 485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace bugreporter { 487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const Stmt *GetDerefExpr(const ExplodedNode *N); 489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const Stmt *GetDenomExpr(const ExplodedNode *N); 490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const Stmt *GetCalleeExpr(const ExplodedNode *N); 491const Stmt *GetRetValExpr(const ExplodedNode *N); 492 493void registerTrackNullOrUndefValue(BugReporterContext& BRC, const void *stmt, 494 const ExplodedNode* N); 495 496void registerFindLastStore(BugReporterContext& BRC, const void *memregion, 497 const ExplodedNode *N); 498 499void registerNilReceiverVisitor(BugReporterContext &BRC); 500 501void registerVarDeclsLastStore(BugReporterContext &BRC, const void *stmt, 502 const ExplodedNode *N); 503 504} // end namespace clang::bugreporter 505 506//===----------------------------------------------------------------------===// 507 508} // end GR namespace 509 510} // end clang namespace 511 512#endif 513