// BugReporterVisitors.cpp - Helpers for reporting bugs -----------*- C++ -*--////// The LLVM Compiler Infrastructure//// This file is distributed under the University of Illinois Open Source// License. See LICENSE.TXT for details.////===----------------------------------------------------------------------===////// This file defines a set of BugReporter "visitors" which can be used to// enhance the diagnostics reported for a bug.////===----------------------------------------------------------------------===//#include"clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h"#include"clang/AST/Expr.h"#include"clang/AST/ExprObjC.h"#include"clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"#include"clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"#include"clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"#include"clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"#include"clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"#include"clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"#include"llvm/ADT/SmallString.h"#include"llvm/ADT/StringExtras.h"#include"llvm/Support/raw_ostream.h"usingnamespaceclang;usingnamespaceento;//===----------------------------------------------------------------------===//// Utility functions.//===----------------------------------------------------------------------===//boolbugreporter::isDeclRefExprToReference(constExpr*E){if(constDeclRefExpr*DRE=dyn_cast<DeclRefExpr>(E)){returnDRE->getDecl()->getType()->isReferenceType();}returnfalse;}constExpr*bugreporter::getDerefExpr(constStmt*S){// Pattern match for a few useful cases (do something smarter later):// a[0], p->f, *pconstExpr*E=dyn_cast<Expr>(S);if(!E)return0;E=E->IgnoreParenCasts();while(true){if(constBinaryOperator*B=dyn_cast<BinaryOperator>(E)){assert(B->isAssignmentOp());E=B->getLHS()->IgnoreParenCasts();continue;}elseif(constUnaryOperator*U=dyn_cast<UnaryOperator>(E)){if(U->getOpcode()==UO_Deref)returnU->getSubExpr()->IgnoreParenCasts();}elseif(constMemberExpr*ME=dyn_cast<MemberExpr>(E)){if(ME->isArrow()||isDeclRefExprToReference(ME->getBase())){returnME->getBase()->IgnoreParenCasts();}}elseif(constObjCIvarRefExpr*IvarRef=dyn_cast<ObjCIvarRefExpr>(E)){returnIvarRef->getBase()->IgnoreParenCasts();}elseif(constArraySubscriptExpr*AE=dyn_cast<ArraySubscriptExpr>(E)){returnAE->getBase();}break;}returnNULL;}constStmt*bugreporter::GetDenomExpr(constExplodedNode*N){constStmt*S=N->