AnalysisConsumer.cpp revision b990d039c7e01ad0055dcbd1e13a691813397b96
1f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===--- AnalysisConsumer.cpp - ASTConsumer for running Analyses ----------===//
2f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//
3f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//                     The LLVM Compiler Infrastructure
4f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//
5f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// This file is distributed under the University of Illinois Open Source
6f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// License. See LICENSE.TXT for details.
7f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//
8f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
9f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//
10f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// "Meta" ASTConsumer for running different source analyses.
11f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//
12f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
13f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
14d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks#define DEBUG_TYPE "AnalysisConsumer"
15d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks
16e6348c336fecc8da9288ea367375a1b1cd2358d2Argyrios Kyrtzidis#include "AnalysisConsumer.h"
17f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "clang/AST/ASTConsumer.h"
18f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "clang/AST/Decl.h"
19802be99a6817aba6edb166b93c133da4358aa783Zhongxing Xu#include "clang/AST/DeclCXX.h"
20f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "clang/AST/DeclObjC.h"
21efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar#include "clang/AST/ParentMap.h"
22aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks#include "clang/AST/RecursiveASTVisitor.h"
23efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar#include "clang/Analysis/CFG.h"
24d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks#include "clang/Analysis/CallGraph.h"
2527af04bcca46f8a3374586be1301477f9123f5e1Argyrios Kyrtzidis#include "clang/StaticAnalyzer/Frontend/CheckerRegistration.h"
2643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/CheckerManager.h"
2721142581d55918beed544a757e4af3bb865b1812Ted Kremenek#include "clang/StaticAnalyzer/Checkers/LocalCheckers.h"
289b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
299b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
309b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
319b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
32f39d962cf84f46d2c0512157259ae1d41a1a5173David Blaikie#include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
33a7af5ea88a6c5bdf87497cca6c20831e8c546751Argyrios Kyrtzidis
34efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar#include "clang/Basic/FileManager.h"
35efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar#include "clang/Basic/SourceManager.h"
369b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#include "clang/Frontend/AnalyzerOptions.h"
37efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar#include "clang/Lex/Preprocessor.h"
38f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek#include "llvm/Support/raw_ostream.h"
3903013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Path.h"
4003013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Program.h"
41d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks#include "llvm/Support/Timer.h"
42d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks#include "llvm/ADT/DepthFirstIterator.h"
436cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer#include "llvm/ADT/OwningPtr.h"
4481fb169f42769e02c7425b23885a261c025fd5e6Anna Zaks#include "llvm/ADT/Statistic.h"
45db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek
467fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks#include <queue>
477fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks
48f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenekusing namespace clang;
499ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento;
50d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaksusing llvm::SmallPtrSet;
51f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
52c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xustatic ExplodedNode::Auditor* CreateUbiViz();
53ff944a8c481d6c0f1ad2633e4be9bf8b1dd2a09fZhongxing Xu
543fd5f370a28552976c52e76c3035d79012d78ddaAnna ZaksSTATISTIC(NumFunctionTopLevel, "The # of functions at top level.");
55d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna ZaksSTATISTIC(NumFunctionsAnalyzed, "The # of functions analysed (as top level).");
56d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks
57be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek//===----------------------------------------------------------------------===//
58f39d962cf84f46d2c0512157259ae1d41a1a5173David Blaikie// Special PathDiagnosticConsumers.
59f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek//===----------------------------------------------------------------------===//
60f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek
61ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikiestatic PathDiagnosticConsumer*
62ef3643fbbbf66247c5e205497fae0f46e240c143David BlaikiecreatePlistHTMLDiagnosticConsumer(const std::string& prefix,
63efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar                                const Preprocessor &PP) {
64ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie  PathDiagnosticConsumer *PD =
65ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie    createHTMLDiagnosticConsumer(llvm::sys::path::parent_path(prefix), PP);
66ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie  return createPlistDiagnosticConsumer(prefix, PP, PD);
67f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek}
68f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek
69f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek//===----------------------------------------------------------------------===//
70f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// AnalysisConsumer declaration.
71f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
72f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
73f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremeneknamespace {
74f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
75aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaksclass AnalysisConsumer : public ASTConsumer,
76aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks                         public RecursiveASTVisitor<AnalysisConsumer> {
77aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  enum AnalysisMode {
78aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    ANALYSIS_SYNTAX,
79aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    ANALYSIS_PATH,
80aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    ANALYSIS_ALL
81aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  };
82aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks
83aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  /// Mode of the analyzes while recursively visiting Decls.
84aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  AnalysisMode RecVisitorMode;
85aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  /// Bug Reporter to use while recursively visiting Decls.
86aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  BugReporter *RecVisitorBR;
87aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks
88ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xupublic:
899c378f705405d37f49795d5e915989de774fe11fTed Kremenek  ASTContext *Ctx;
901d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  const Preprocessor &PP;
911d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  const std::string OutDir;
921d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  AnalyzerOptions Opts;
9308b86531ade68727c56918f162816075b87c864aJordy Rose  ArrayRef<std::string> Plugins;
94d07a0d0279c09d1017f8450fce575a94dc9703c0Zhongxing Xu
951d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  // PD is owned by AnalysisManager.
96ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie  PathDiagnosticConsumer *PD;
97d07a0d0279c09d1017f8450fce575a94dc9703c0Zhongxing Xu
981d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  StoreManagerCreator CreateStoreMgr;
991d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  ConstraintManagerCreator CreateConstraintMgr;
100f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
1016f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<CheckerManager> checkerMgr;
1026f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<AnalysisManager> Mgr;
103c471e7b44e63ff1b46b480e723c4130aeaef5a8aZhongxing Xu
104d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks  /// Time the analyzes time of each translation unit.
105d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks  static llvm::Timer* TUTotalTimer;
106d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks
1071d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  AnalysisConsumer(const Preprocessor& pp,
1081d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                   const std::string& outdir,
10908b86531ade68727c56918f162816075b87c864aJordy Rose                   const AnalyzerOptions& opts,
11008b86531ade68727c56918f162816075b87c864aJordy Rose                   ArrayRef<std::string> plugins)
111aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    : RecVisitorMode(ANALYSIS_ALL), RecVisitorBR(0),
112aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks      Ctx(0), PP(pp), OutDir(outdir), Opts(opts), Plugins(plugins), PD(0) {
1131d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    DigestAnalyzerOptions();
114d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks    if (Opts.PrintStats) {
115d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks      llvm::EnableStatistics();
116d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks      TUTotalTimer = new llvm::Timer("Analyzer Total Time");
117d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks    }
118d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks  }
119d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks
120d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks  ~AnalysisConsumer() {
121d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks    if (Opts.PrintStats)
122d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks      delete TUTotalTimer;
1231d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  }
124fda7832b000ff8927386f093b52c067641679469Zhongxing Xu
1251d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  void DigestAnalyzerOptions() {
126ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie    // Create the PathDiagnosticConsumer.
1271d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    if (!OutDir.empty()) {
1281d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek      switch (Opts.AnalysisDiagOpt) {
1291d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek      default:
130fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE) \
1311d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek        case PD_##NAME: PD = CREATEFN(OutDir, PP); break;
132fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#include "clang/Frontend/Analyses.def"
133fda7832b000ff8927386f093b52c067641679469Zhongxing Xu      }
134a599ae8826b01c0160a519b0fc5a4871f599bf04Argyrios Kyrtzidis    } else if (Opts.AnalysisDiagOpt == PD_TEXT) {
135a599ae8826b01c0160a519b0fc5a4871f599bf04Argyrios Kyrtzidis      // Create the text client even without a specified output file since
136a599ae8826b01c0160a519b0fc5a4871f599bf04Argyrios Kyrtzidis      // it just uses diagnostic notes.
137ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie      PD = createTextPathDiagnosticConsumer("", PP);
1381d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    }
139fda7832b000ff8927386f093b52c067641679469Zhongxing Xu
1401d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    // Create the analyzer component creators.
1415f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis    switch (Opts.AnalysisStoreOpt) {
1425f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis    default:
143b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("Unknown store manager.");
144fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATEFN)           \
1455f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis      case NAME##Model: CreateStoreMgr = CREATEFN; break;
146fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#include "clang/Frontend/Analyses.def"
1471d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    }
1481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1495f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis    switch (Opts.AnalysisConstraintsOpt) {
1505f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis    default:
151b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("Unknown store manager.");
152fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATEFN)     \
1535f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis      case NAME##Model: CreateConstraintMgr = CREATEFN; break;
154fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#include "clang/Frontend/Analyses.def"
155fda7832b000ff8927386f093b52c067641679469Zhongxing Xu    }
1561d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  }
157f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
158aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  void DisplayFunction(const Decl *D, AnalysisMode Mode) {
159c4a1437c15da43eb8d2601cdce13161ef41a4389Ted Kremenek    if (!Opts.AnalyzerDisplayProgress)
1601d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek      return;
161f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
162fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek    SourceManager &SM = Mgr->getASTContext().getSourceManager();
163fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek    PresumedLoc Loc = SM.getPresumedLoc(D->getLocation());
164cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor    if (Loc.isValid()) {
165aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks      llvm::errs() << "ANALYZE";
166aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks      switch (Mode) {
167aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks        case ANALYSIS_SYNTAX: llvm::errs() << "(Syntax)"; break;
168aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks        case ANALYSIS_PATH: llvm::errs() << "(Path Sensitive)"; break;
169aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks        case ANALYSIS_ALL: break;
170aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks      };
171aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks      llvm::errs() << ": " << Loc.getFilename();
172cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
173cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor        const NamedDecl *ND = cast<NamedDecl>(D);
174b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer        llvm::errs() << ' ' << *ND << '\n';
175cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      }
176cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      else if (isa<BlockDecl>(D)) {
177cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor        llvm::errs() << ' ' << "block(line:" << Loc.getLine() << ",col:"
178cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor                     << Loc.getColumn() << '\n';
179cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      }
180cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
181cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor        Selector S = MD->getSelector();
182cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor        llvm::errs() << ' ' << S.getAsString();
183cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      }
18435fa76d0bb6fb8c86159a7506efd094a4fe376d2Ted Kremenek    }
1851d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  }
1861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1871d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  virtual void Initialize(ASTContext &Context) {
1881d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    Ctx = &Context;
1894e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    checkerMgr.reset(createCheckerManager(Opts, PP.getLangOpts(), Plugins,
19008b86531ade68727c56918f162816075b87c864aJordy Rose                                          PP.getDiagnostics()));
1911d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    Mgr.reset(new AnalysisManager(*Ctx, PP.getDiagnostics(),
1924e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie                                  PP.getLangOpts(), PD,
1931d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                  CreateStoreMgr, CreateConstraintMgr,
19443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis                                  checkerMgr.get(),
195c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu                                  /* Indexer */ 0,
1966362b893731ccf4480a96527db9e55e04b801503Zhongxing Xu                                  Opts.MaxNodes, Opts.MaxLoop,
1971d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                  Opts.VisualizeEGDot, Opts.VisualizeEGUbi,
198d30952838421ddfb9f7e346b2ba8213889a5f789Anna Zaks                                  Opts.AnalysisPurgeOpt, Opts.EagerlyAssume,
19966253352131e3e7a22b3bfd0e180607aa2bfb988Anna Zaks                                  Opts.TrimGraph,
2009121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski                                  Opts.UnoptimizedCFG, Opts.CFGAddImplicitDtors,
201d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek                                  Opts.CFGAddInitializers,
2028235f9c9c8b3d1737d1c6bd57f7ba3f616b92392Anna Zaks                                  Opts.EagerlyTrimEGraph,
20366253352131e3e7a22b3bfd0e180607aa2bfb988Anna Zaks                                  Opts.IPAMode,
2048235f9c9c8b3d1737d1c6bd57f7ba3f616b92392Anna Zaks                                  Opts.InlineMaxStackDepth,
20566253352131e3e7a22b3bfd0e180607aa2bfb988Anna Zaks                                  Opts.InlineMaxFunctionSize,
20666253352131e3e7a22b3bfd0e180607aa2bfb988Anna Zaks                                  Opts.InliningMode));
2071d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  }
2081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2091d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  virtual void HandleTranslationUnit(ASTContext &C);
21014cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek
211a2e589e60d147f4f04cee5682b8389b55c410244Anna Zaks  /// \brief Build the call graph for the TU and use it to define the order
212aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  /// in which the functions should be visited.
213a2e589e60d147f4f04cee5682b8389b55c410244Anna Zaks  void HandleDeclsGallGraph(TranslationUnitDecl *TU);
214aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks
215aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  /// \brief Run analyzes(syntax or path sensitive) on the given function.
216aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  /// \param Mode - determines if we are requesting syntax only or path
217aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  /// sensitive only analysis.
218aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  /// \param VisitedCallees - The output parameter, which is populated with the
219aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  /// set of functions which should be considered analyzed after analyzing the
220aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  /// given root function.
221aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  void HandleCode(Decl *D, AnalysisMode Mode, SetOfDecls *VisitedCallees = 0);
222aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks
223aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  /// \brief Check if we should skip (not analyze) the given function.
22498520835eb1aa091429afa06e9f4f7ebe3864d34Anna Zaks  bool skipFunction(Decl *D);
225aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks
2263fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks  void RunPathSensitiveChecks(Decl *D, SetOfDecls *VisitedCallees);
2273fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks  void ActionExprEngine(Decl *D, bool ObjCGCEnabled, SetOfDecls *VisitedCallees);
228aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks
229aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  /// Visitors for the RecursiveASTVisitor.
230aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks
231aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  /// Handle callbacks for arbitrary Decls.
232aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  bool VisitDecl(Decl *D) {
233aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    checkerMgr->runCheckersOnASTDecl(D, *Mgr, *RecVisitorBR);
234aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    return true;
235aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  }
236aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks
237aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  bool VisitFunctionDecl(FunctionDecl *FD) {
238aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    IdentifierInfo *II = FD->getIdentifier();
239aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    if (II && II->getName().startswith("__inline"))
240aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks      return true;
241aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks
242aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    // We skip function template definitions, as their semantics is
243aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    // only determined when they are instantiated.
244aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    if (FD->isThisDeclarationADefinition() &&
245aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks        !FD->isDependentContext()) {
246aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks      HandleCode(FD, RecVisitorMode);
247aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    }
248aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    return true;
249aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  }
250aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks
251aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  bool VisitObjCMethodDecl(ObjCMethodDecl *MD) {
252aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    checkerMgr->runCheckersOnASTDecl(MD, *Mgr, *RecVisitorBR);
253aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    if (MD->isThisDeclarationADefinition())
254aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks      HandleCode(MD, RecVisitorMode);
255aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    return true;
256aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  }
2571d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek};
258f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek} // end anonymous namespace
259f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
260aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks
261f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
262f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// AnalysisConsumer implementation.
263f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
264d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaksllvm::Timer* AnalysisConsumer::TUTotalTimer = 0;
265f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
266a2e589e60d147f4f04cee5682b8389b55c410244Anna Zaksvoid AnalysisConsumer::HandleDeclsGallGraph(TranslationUnitDecl *TU) {
267d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks  // Otherwise, use the Callgraph to derive the order.
268d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks  // Build the Call Graph.
269d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks  CallGraph CG;
270a2e589e60d147f4f04cee5682b8389b55c410244Anna Zaks  CG.addToCallGraph(TU);
271d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks
272d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks  // Find the top level nodes - children of root + the unreachable (parentless)
273d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks  // nodes.
2743fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks  llvm::SmallVector<CallGraphNode*, 24> TopLevelFunctions;
275b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks  for (CallGraph::nodes_iterator TI = CG.parentless_begin(),
276b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks                                 TE = CG.parentless_end(); TI != TE; ++TI) {
277b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks    TopLevelFunctions.push_back(*TI);
278b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks    NumFunctionTopLevel++;
279b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks  }
280d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks  CallGraphNode *Entry = CG.getRoot();
281d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks  for (CallGraphNode::iterator I = Entry->begin(),
2823fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks                               E = Entry->end(); I != E; ++I) {
283d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks    TopLevelFunctions.push_back(*I);
2843fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks    NumFunctionTopLevel++;
2853fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks  }
286d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks
287b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks  // Make sure the nodes are sorted in order reverse of their definition in the
288b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks  // translation unit. This step is very important for performance. It ensures
289b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks  // that we analyze the root functions before the externally available
290b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks  // subroutines.
2917fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks  std::queue<CallGraphNode*> BFSQueue;
292b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks  for (llvm::SmallVector<CallGraphNode*, 24>::reverse_iterator
293b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks         TI = TopLevelFunctions.rbegin(), TE = TopLevelFunctions.rend();
2947fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks         TI != TE; ++TI)
2957fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks    BFSQueue.push(*TI);
296d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks
2977fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks  // BFS over all of the functions, while skipping the ones inlined into
2987fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks  // the previously processed functions. Use external Visited set, which is
299d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks  // also modified when we inline a function.
300d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks  SmallPtrSet<CallGraphNode*,24> Visited;
3017fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks  while(!BFSQueue.empty()) {
3027fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks    CallGraphNode *N = BFSQueue.front();
3037fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks    BFSQueue.pop();
3047fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks
3057fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks    // Skip the functions which have been processed already or previously
3067fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks    // inlined.
3077fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks    if (Visited.count(N))
3087fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks      continue;
3097fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks
3107fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks    // Analyze the function.
3117fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks    SetOfDecls VisitedCallees;
3127fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks    Decl *D = N->getDecl();
3137fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks    assert(D);
3147fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks    HandleCode(D, ANALYSIS_PATH,
3157fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks               (Mgr->InliningMode == All ? 0 : &VisitedCallees));
3167fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks
3177fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks    // Add the visited callees to the global visited set.
3187fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks    for (SetOfDecls::const_iterator I = VisitedCallees.begin(),
3197fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks                                    E = VisitedCallees.end(); I != E; ++I) {
3207fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks      CallGraphNode *VN = CG.getNode(*I);
3217fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks      if (VN)
3227fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks        Visited.insert(VN);
3237fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks    }
3247fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks    Visited.insert(N);
3257fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks
3267fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks    // Push the children into the queue.
3277fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks    for (CallGraphNode::const_iterator CI = N->begin(),
3287fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks                                       CE = N->end(); CI != CE; ++CI) {
3297fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks      BFSQueue.push(*CI);
330d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks    }
331d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks  }
332fee618af5dd7dee2caaa7347b372eb3dc5fdeffcTed Kremenek}
333fee618af5dd7dee2caaa7347b372eb3dc5fdeffcTed Kremenek
33414cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenekvoid AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
335aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  // Don't run the actions if an error has occurred with parsing the file.
336aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  DiagnosticsEngine &Diags = PP.getDiagnostics();
337aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred())
338aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    return;
339aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks
340c5bdc556f6a65c677e0ed73f918c3000ecad33afAnna Zaks  {
341d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks    if (TUTotalTimer) TUTotalTimer->startTimer();
342d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks
343c5bdc556f6a65c677e0ed73f918c3000ecad33afAnna Zaks    // Introduce a scope to destroy BR before Mgr.
344c5bdc556f6a65c677e0ed73f918c3000ecad33afAnna Zaks    BugReporter BR(*Mgr);
345c5bdc556f6a65c677e0ed73f918c3000ecad33afAnna Zaks    TranslationUnitDecl *TU = C.getTranslationUnitDecl();
346c5bdc556f6a65c677e0ed73f918c3000ecad33afAnna Zaks    checkerMgr->runCheckersOnASTDecl(TU, *Mgr, BR);
347aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks
348aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    // Run the AST-only checks using the order in which functions are defined.
349aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    // If inlining is not turned on, use the simplest function order for path
350aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    // sensitive analyzes as well.
351aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    RecVisitorMode = (Mgr->shouldInlineCall() ? ANALYSIS_SYNTAX : ANALYSIS_ALL);
352aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    RecVisitorBR = &BR;
353aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    TraverseDecl(TU);
354aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks
355aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    if (Mgr->shouldInlineCall())
356a2e589e60d147f4f04cee5682b8389b55c410244Anna Zaks      HandleDeclsGallGraph(TU);
357b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu
358c5bdc556f6a65c677e0ed73f918c3000ecad33afAnna Zaks    // After all decls handled, run checkers on the entire TranslationUnit.
359c5bdc556f6a65c677e0ed73f918c3000ecad33afAnna Zaks    checkerMgr->runCheckersOnEndOfTranslationUnit(TU, *Mgr, BR);
360aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks
361aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks    RecVisitorBR = 0;
362c5bdc556f6a65c677e0ed73f918c3000ecad33afAnna Zaks  }
3639be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
364ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie  // Explicitly destroy the PathDiagnosticConsumer.  This will flush its output.
365690a7f431d6863a101711e67636d51ddd13f35c5Ted Kremenek  // FIXME: This should be replaced with something that doesn't rely on
366ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie  // side-effects in PathDiagnosticConsumer's destructor. This is required when
367da17fd50ad485fd2a1fc5c2f055caacf532992daZhongxing Xu  // used with option -disable-free.
368d07a0d0279c09d1017f8450fce575a94dc9703c0Zhongxing Xu  Mgr.reset(NULL);
369d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks
370d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks  if (TUTotalTimer) TUTotalTimer->stopTimer();
371db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek}
372db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek
3735f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic void FindBlocks(DeclContext *D, SmallVectorImpl<Decl*> &WL) {
374fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek  if (BlockDecl *BD = dyn_cast<BlockDecl>(D))
375fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek    WL.push_back(BD);
376f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
377fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek  for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
378fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek       I!=E; ++I)
379fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek    if (DeclContext *DC = dyn_cast<DeclContext>(*I))
380fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek      FindBlocks(DC, WL);
381fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek}
382fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek
383d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaksstatic std::string getFunctionName(const Decl *D) {
384d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks  if (const ObjCMethodDecl *ID = dyn_cast<ObjCMethodDecl>(D)) {
385d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks    return ID->getSelector().getAsString();
386d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks  }
387d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks  if (const FunctionDecl *ND = dyn_cast<FunctionDecl>(D)) {
388d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks    IdentifierInfo *II = ND->getIdentifier();
389d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks    if (II)
390d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks      return II->getName();
391d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks  }
392d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks  return "";
393d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks}
394d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks
39598520835eb1aa091429afa06e9f4f7ebe3864d34Anna Zaksbool AnalysisConsumer::skipFunction(Decl *D) {
396d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks  if (!Opts.AnalyzeSpecificFunction.empty() &&
397d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks      getFunctionName(D) != Opts.AnalyzeSpecificFunction)
39898520835eb1aa091429afa06e9f4f7ebe3864d34Anna Zaks    return true;
3991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
400f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  // Don't run the actions on declarations in header files unless
401f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  // otherwise specified.
402fcd783d583d270b7ec1ec3e0fcf83cd93d30e381Ted Kremenek  SourceManager &SM = Ctx->getSourceManager();
403402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth  SourceLocation SL = SM.getExpansionLoc(D->getLocation());
404fcd783d583d270b7ec1ec3e0fcf83cd93d30e381Ted Kremenek  if (!Opts.AnalyzeAll && !SM.isFromMainFile(SL))
40598520835eb1aa091429afa06e9f4f7ebe3864d34Anna Zaks    return true;
40698520835eb1aa091429afa06e9f4f7ebe3864d34Anna Zaks
40798520835eb1aa091429afa06e9f4f7ebe3864d34Anna Zaks  return false;
40898520835eb1aa091429afa06e9f4f7ebe3864d34Anna Zaks}
40998520835eb1aa091429afa06e9f4f7ebe3864d34Anna Zaks
410aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaksvoid AnalysisConsumer::HandleCode(Decl *D, AnalysisMode Mode,
411aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks                                  SetOfDecls *VisitedCallees) {
41298520835eb1aa091429afa06e9f4f7ebe3864d34Anna Zaks  if (skipFunction(D))
4131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return;
414f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
415aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks  DisplayFunction(D, Mode);
41698520835eb1aa091429afa06e9f4f7ebe3864d34Anna Zaks
4171d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek  // Clear the AnalysisManager of old AnalysisDeclContexts.
41858f5ec7d56b1ebf5f90ee11226ebe7663f2821eaTed Kremenek  Mgr->ClearContexts();
419f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
4201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Dispatch on the actions.
4215f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<Decl*, 10> WL;
422fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek  WL.push_back(D);
423f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
42406a54a38be5054c910ffc92db60edab23f9ea105Argyrios Kyrtzidis  if (D->hasBody() && Opts.AnalyzeNestedBlocks)
425fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek    FindBlocks(cast<DeclContext>(D), WL);
426f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
4279fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  BugReporter BR(*Mgr);
4285f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  for (SmallVectorImpl<Decl*>::iterator WI=WL.begin(), WE=WL.end();
4299fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis       WI != WE; ++WI)
430d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis    if ((*WI)->hasBody()) {
431aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks      if (Mode != ANALYSIS_PATH)
432aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks        checkerMgr->runCheckersOnASTBody(*WI, *Mgr, BR);
433aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks      if (Mode != ANALYSIS_SYNTAX && checkerMgr->hasPathSensitiveCheckers())
4343fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks        RunPathSensitiveChecks(*WI, VisitedCallees);
435d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis    }
436d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks  NumFunctionsAnalyzed++;
437f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek}
438f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
439f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
440d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis// Path-sensitive checking.
441f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
442f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
4433fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaksvoid AnalysisConsumer::ActionExprEngine(Decl *D, bool ObjCGCEnabled,
4443fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks                                        SetOfDecls *VisitedCallees) {
445a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek  // Construct the analysis engine.  First check if the CFG is valid.
44675d03cffe20b5c945ef04eba208efb0437339997Ted Kremenek  // FIXME: Inter-procedural analysis will need to handle invalid CFGs.
4473fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks  if (!Mgr->getCFG(D))
448f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek    return;
4493fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks
4503fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks  ExprEngine Eng(*Mgr, ObjCGCEnabled, VisitedCallees);
451f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
452f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  // Set the graph auditor.
4536f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<ExplodedNode::Auditor> Auditor;
4543fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks  if (Mgr->shouldVisualizeUbigraph()) {
455f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    Auditor.reset(CreateUbiViz());
456c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    ExplodedNode::SetAuditor(Auditor.get());
457f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  }
4581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
459b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  // Execute the worklist algorithm.
4603fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks  Eng.ExecuteWorkList(Mgr->getAnalysisDeclContextManager().getStackFrame(D, 0),
4613fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks                      Mgr->getMaxNodes());
4621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
463f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  // Release the auditor (if any) so that it doesn't monitor the graph
464f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  // created BugReporter.
465c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  ExplodedNode::SetAuditor(0);
4663df6421150271266b5a90fd4c6bfa6566c38c036Ted Kremenek
46734d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  // Visualize the exploded graph.
4683fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks  if (Mgr->shouldVisualizeGraphviz())
4693fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks    Eng.ViewGraph(Mgr->shouldTrimGraph());
4701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4713df6421150271266b5a90fd4c6bfa6566c38c036Ted Kremenek  // Display warnings.
4723df6421150271266b5a90fd4c6bfa6566c38c036Ted Kremenek  Eng.getBugReporter().FlushReports();
473bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek}
474bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek
4753fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaksvoid AnalysisConsumer::RunPathSensitiveChecks(Decl *D, SetOfDecls *Visited) {
47617a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose
4774e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  switch (Mgr->getLangOpts().getGC()) {
47817a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose  case LangOptions::NonGC:
4793fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks    ActionExprEngine(D, false, Visited);
48017a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose    break;
48117a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose
48217a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose  case LangOptions::GCOnly:
4833fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks    ActionExprEngine(D, true, Visited);
48417a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose    break;
48517a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose
48617a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose  case LangOptions::HybridGC:
4873fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks    ActionExprEngine(D, false, Visited);
4883fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks    ActionExprEngine(D, true, Visited);
48917a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose    break;
49017a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose  }
491b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek}
492b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek
493f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
494f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// AnalysisConsumer creation.
495f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
496f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
4979ef6537a894c33003359b1f9b9676e9178e028b7Ted KremenekASTConsumer* ento::CreateAnalysisConsumer(const Preprocessor& pp,
49808b86531ade68727c56918f162816075b87c864aJordy Rose                                          const std::string& outDir,
49908b86531ade68727c56918f162816075b87c864aJordy Rose                                          const AnalyzerOptions& opts,
50008b86531ade68727c56918f162816075b87c864aJordy Rose                                          ArrayRef<std::string> plugins) {
50108b86531ade68727c56918f162816075b87c864aJordy Rose  // Disable the effects of '-Werror' when using the AnalysisConsumer.
502efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar  pp.getDiagnostics().setWarningsAsErrors(false);
503be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek
50408b86531ade68727c56918f162816075b87c864aJordy Rose  return new AnalysisConsumer(pp, outDir, opts, plugins);
505f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek}
506f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
507f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek//===----------------------------------------------------------------------===//
508f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek// Ubigraph Visualization.  FIXME: Move to separate file.
509f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek//===----------------------------------------------------------------------===//
510f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
511f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremeneknamespace {
5121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
513c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xuclass UbigraphViz : public ExplodedNode::Auditor {
5146f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<raw_ostream> Out;
515710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  llvm::sys::Path Dir, Filename;
516f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  unsigned Cntr;
517f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
518f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  typedef llvm::DenseMap<void*,unsigned> VMap;
519f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  VMap M;
5201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
521f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenekpublic:
5229c378f705405d37f49795d5e915989de774fe11fTed Kremenek  UbigraphViz(raw_ostream *out, llvm::sys::Path& dir,
52356b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek              llvm::sys::Path& filename);
5241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
525710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  ~UbigraphViz();
5261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5279c378f705405d37f49795d5e915989de774fe11fTed Kremenek  virtual void AddEdge(ExplodedNode *Src, ExplodedNode *Dst);
528f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek};
5291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
530f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek} // end anonymous namespace
531f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
532c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xustatic ExplodedNode::Auditor* CreateUbiViz() {
533f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  std::string ErrMsg;
5341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
535710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  llvm::sys::Path Dir = llvm::sys::Path::GetTemporaryDirectory(&ErrMsg);
536f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  if (!ErrMsg.empty())
537f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    return 0;
538f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
539710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  llvm::sys::Path Filename = Dir;
540f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  Filename.appendComponent("llvm_ubi");
541f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  Filename.makeUnique(true,&ErrMsg);
542f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
543f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  if (!ErrMsg.empty())
544f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    return 0;
545f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
546d57a7ef9252964bc6c8471451d7bd395b0520cb8Chris Lattner  llvm::errs() << "Writing '" << Filename.str() << "'.\n";
5471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5486f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<llvm::raw_fd_ostream> Stream;
549b044c473a155b7e827680635c1699cb2b5b6c0eeDan Gohman  Stream.reset(new llvm::raw_fd_ostream(Filename.c_str(), ErrMsg));
550f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
551f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  if (!ErrMsg.empty())
552f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    return 0;
5531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
554710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  return new UbigraphViz(Stream.take(), Dir, Filename);
555f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek}
556f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
5579c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid UbigraphViz::AddEdge(ExplodedNode *Src, ExplodedNode *Dst) {
5581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
55945479c88c8a44c55d27c3bd855273bb318082f37Ted Kremenek  assert (Src != Dst && "Self-edges are not allowed.");
5601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
561f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  // Lookup the Src.  If it is a new node, it's a root.
562f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  VMap::iterator SrcI= M.find(Src);
563f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  unsigned SrcID;
5641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
565f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  if (SrcI == M.end()) {
566f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    M[Src] = SrcID = Cntr++;
567f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    *Out << "('vertex', " << SrcID << ", ('color','#00ff00'))\n";
568f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  }
569f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  else
570f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    SrcID = SrcI->second;
5711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
572f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  // Lookup the Dst.
573f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  VMap::iterator DstI= M.find(Dst);
574f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  unsigned DstID;
575f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
576f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  if (DstI == M.end()) {
577f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    M[Dst] = DstID = Cntr++;
578f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    *Out << "('vertex', " << DstID << ")\n";
579f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  }
58056b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek  else {
58156b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek    // We have hit DstID before.  Change its style to reflect a cache hit.
582f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    DstID = DstI->second;
58356b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek    *Out << "('change_vertex_style', " << DstID << ", 1)\n";
58456b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek  }
585f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
586f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  // Add the edge.
5871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  *Out << "('edge', " << SrcID << ", " << DstID
588d1289327f7d2126d732e23cc189ecd0aa5d07cbbTed Kremenek       << ", ('arrow','true'), ('oriented', 'true'))\n";
589f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek}
590f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
5919c378f705405d37f49795d5e915989de774fe11fTed KremenekUbigraphViz::UbigraphViz(raw_ostream *out, llvm::sys::Path& dir,
59256b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek                         llvm::sys::Path& filename)
59356b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek  : Out(out), Dir(dir), Filename(filename), Cntr(0) {
59456b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek
59556b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek  *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n";
59656b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek  *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66'),"
59756b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek          " ('size', '1.5'))\n";
59856b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek}
59956b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek
600710ad9343f32b33b336369b20edad1a21a0b3299Ted KremenekUbigraphViz::~UbigraphViz() {
601710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  Out.reset(0);
6026cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer  llvm::errs() << "Running 'ubiviz' program... ";
603710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  std::string ErrMsg;
604710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  llvm::sys::Path Ubiviz = llvm::sys::Program::FindProgramByName("ubiviz");
605710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  std::vector<const char*> args;
606710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  args.push_back(Ubiviz.c_str());
607710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  args.push_back(Filename.c_str());
608710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  args.push_back(0);
6091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
610710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  if (llvm::sys::Program::ExecuteAndWait(Ubiviz, &args[0],0,0,0,0,&ErrMsg)) {
6116cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer    llvm::errs() << "Error viewing graph: " << ErrMsg << "\n";
612710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  }
6131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
614710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  // Delete the directory.
6151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Dir.eraseFromDisk(true);
616932680ecdeab4c216ce7c0736093d3dcd2f60f6dDaniel Dunbar}
617