AnalysisConsumer.cpp revision 43dee220252ef0b42c5f8a3bb1eca97f84f2565f
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
14e6348c336fecc8da9288ea367375a1b1cd2358d2Argyrios Kyrtzidis#include "AnalysisConsumer.h"
15f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "clang/AST/ASTConsumer.h"
16f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "clang/AST/Decl.h"
17802be99a6817aba6edb166b93c133da4358aa783Zhongxing Xu#include "clang/AST/DeclCXX.h"
18f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "clang/AST/DeclObjC.h"
19efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar#include "clang/AST/ParentMap.h"
20efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar#include "clang/Analysis/Analyses/LiveVariables.h"
211309f9a3b225ea846e5822691c39a77423125505Ted Kremenek#include "clang/Analysis/Analyses/UninitializedValues.h"
22efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar#include "clang/Analysis/CFG.h"
2343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/CheckerManager.h"
2421142581d55918beed544a757e4af3bb865b1812Ted Kremenek#include "clang/StaticAnalyzer/Checkers/LocalCheckers.h"
259b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
269b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
279b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
289b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
299b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/TransferFuncs.h"
309b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathDiagnosticClients.h"
31a7af5ea88a6c5bdf87497cca6c20831e8c546751Argyrios Kyrtzidis
32a7af5ea88a6c5bdf87497cca6c20831e8c546751Argyrios Kyrtzidis// FIXME: Restructure checker registration.
33e817771c57d0eacbe069a314ba619c43d0ac70abArgyrios Kyrtzidis#include "../Checkers/ExperimentalChecks.h"
34e817771c57d0eacbe069a314ba619c43d0ac70abArgyrios Kyrtzidis#include "../Checkers/InternalChecks.h"
35a7af5ea88a6c5bdf87497cca6c20831e8c546751Argyrios Kyrtzidis
36efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar#include "clang/Basic/FileManager.h"
37efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar#include "clang/Basic/SourceManager.h"
389b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#include "clang/Frontend/AnalyzerOptions.h"
39efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar#include "clang/Lex/Preprocessor.h"
40f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek#include "llvm/Support/raw_ostream.h"
4103013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Path.h"
4203013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Program.h"
436cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer#include "llvm/ADT/OwningPtr.h"
44db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek
45f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenekusing namespace clang;
469ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento;
47f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
48c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xustatic ExplodedNode::Auditor* CreateUbiViz();
49ff944a8c481d6c0f1ad2633e4be9bf8b1dd2a09fZhongxing Xu
50be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek//===----------------------------------------------------------------------===//
51f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek// Special PathDiagnosticClients.
52f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek//===----------------------------------------------------------------------===//
53f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek
54f75560670bcdd59b051149bdece3eac14e313853Ted Kremenekstatic PathDiagnosticClient*
55f928dca56542cf8f981a684f090d2c79bdcb2a10Argyrios KyrtzidiscreatePlistHTMLDiagnosticClient(const std::string& prefix,
56efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar                                const Preprocessor &PP) {
57d5b08bee799d4f77f1a25fa5977ca77b983ab031Michael J. Spencer  PathDiagnosticClient *PD =
58d5b08bee799d4f77f1a25fa5977ca77b983ab031Michael J. Spencer    createHTMLDiagnosticClient(llvm::sys::path::parent_path(prefix), PP);
59f928dca56542cf8f981a684f090d2c79bdcb2a10Argyrios Kyrtzidis  return createPlistDiagnosticClient(prefix, PP, PD);
60f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek}
61f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek
62f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek//===----------------------------------------------------------------------===//
63f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// AnalysisConsumer declaration.
64f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
65f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
66f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremeneknamespace {
67f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
68ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xuclass AnalysisConsumer : public ASTConsumer {
69ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xupublic:
706490ae5003226cae28f980648948bea8b21a8638Douglas Gregor  typedef void (*CodeAction)(AnalysisConsumer &C, AnalysisManager &M, Decl *D);
71f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek  typedef void (*TUAction)(AnalysisConsumer &C, AnalysisManager &M,
72f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek                           TranslationUnitDecl &TU);
73f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
74ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xuprivate:
751d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  typedef std::vector<CodeAction> Actions;
76f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek  typedef std::vector<TUAction> TUActions;
77f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
781d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  Actions FunctionActions;
791d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  Actions ObjCMethodActions;
801d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  Actions ObjCImplementationActions;
81ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu  Actions CXXMethodActions;
82ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu  TUActions TranslationUnitActions; // Remove this.
831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
841d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekpublic:
851d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  ASTContext* Ctx;
861d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  const Preprocessor &PP;
871d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  const std::string OutDir;
881d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  AnalyzerOptions Opts;
89d07a0d0279c09d1017f8450fce575a94dc9703c0Zhongxing Xu
901d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  // PD is owned by AnalysisManager.
911d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  PathDiagnosticClient *PD;
92d07a0d0279c09d1017f8450fce575a94dc9703c0Zhongxing Xu
931d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  StoreManagerCreator CreateStoreMgr;
941d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  ConstraintManagerCreator CreateConstraintMgr;
95f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
9643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis  llvm::OwningPtr<CheckerManager> checkerMgr;
971d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  llvm::OwningPtr<AnalysisManager> Mgr;
98c471e7b44e63ff1b46b480e723c4130aeaef5a8aZhongxing Xu
991d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  AnalysisConsumer(const Preprocessor& pp,
1001d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                   const std::string& outdir,
1011d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                   const AnalyzerOptions& opts)
1021d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    : Ctx(0), PP(pp), OutDir(outdir),
103c4a1437c15da43eb8d2601cdce13161ef41a4389Ted Kremenek      Opts(opts), PD(0) {
1041d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    DigestAnalyzerOptions();
1051d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  }
106fda7832b000ff8927386f093b52c067641679469Zhongxing Xu
1071d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  void DigestAnalyzerOptions() {
1081d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    // Create the PathDiagnosticClient.
1091d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    if (!OutDir.empty()) {
1101d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek      switch (Opts.AnalysisDiagOpt) {
1111d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek      default:
112fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE) \
1131d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek        case PD_##NAME: PD = CREATEFN(OutDir, PP); break;
114fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#include "clang/Frontend/Analyses.def"
115fda7832b000ff8927386f093b52c067641679469Zhongxing Xu      }
116a599ae8826b01c0160a519b0fc5a4871f599bf04Argyrios Kyrtzidis    } else if (Opts.AnalysisDiagOpt == PD_TEXT) {
117a599ae8826b01c0160a519b0fc5a4871f599bf04Argyrios Kyrtzidis      // Create the text client even without a specified output file since
118a599ae8826b01c0160a519b0fc5a4871f599bf04Argyrios Kyrtzidis      // it just uses diagnostic notes.
119a599ae8826b01c0160a519b0fc5a4871f599bf04Argyrios Kyrtzidis      PD = createTextPathDiagnosticClient("", PP);
1201d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    }
121fda7832b000ff8927386f093b52c067641679469Zhongxing Xu
1221d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    // Create the analyzer component creators.
1235f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis    switch (Opts.AnalysisStoreOpt) {
1245f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis    default:
1255f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis      assert(0 && "Unknown store manager.");
126fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATEFN)           \
1275f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis      case NAME##Model: CreateStoreMgr = CREATEFN; break;
128fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#include "clang/Frontend/Analyses.def"
1291d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    }
1301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1315f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis    switch (Opts.AnalysisConstraintsOpt) {
1325f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis    default:
1335f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis      assert(0 && "Unknown store manager.");
134fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATEFN)     \
1355f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis      case NAME##Model: CreateConstraintMgr = CREATEFN; break;
136fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#include "clang/Frontend/Analyses.def"
137fda7832b000ff8927386f093b52c067641679469Zhongxing Xu    }
1381d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  }
139f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
1401d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  void DisplayFunction(const Decl *D) {
141c4a1437c15da43eb8d2601cdce13161ef41a4389Ted Kremenek    if (!Opts.AnalyzerDisplayProgress)
1421d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek      return;
143f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
144fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek    SourceManager &SM = Mgr->getASTContext().getSourceManager();
145fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek    PresumedLoc Loc = SM.getPresumedLoc(D->getLocation());
146cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor    if (Loc.isValid()) {
147cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      llvm::errs() << "ANALYZE: " << Loc.getFilename();
148fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek
149cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
150cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor        const NamedDecl *ND = cast<NamedDecl>(D);
151cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor        llvm::errs() << ' ' << ND << '\n';
152cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      }
153cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      else if (isa<BlockDecl>(D)) {
154cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor        llvm::errs() << ' ' << "block(line:" << Loc.getLine() << ",col:"
155cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor                     << Loc.getColumn() << '\n';
156cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      }
157cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
158cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor        Selector S = MD->getSelector();
159cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor        llvm::errs() << ' ' << S.getAsString();
160cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      }
16135fa76d0bb6fb8c86159a7506efd094a4fe376d2Ted Kremenek    }
1621d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  }
1631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1641d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  void addCodeAction(CodeAction action) {
1651d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    FunctionActions.push_back(action);
1661d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    ObjCMethodActions.push_back(action);
167ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu    CXXMethodActions.push_back(action);
1681d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  }
1691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
170f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek  void addTranslationUnitAction(TUAction action) {
1711d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    TranslationUnitActions.push_back(action);
1721d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  }
1731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
174ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu  void addObjCImplementationAction(CodeAction action) {
175ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu    ObjCImplementationActions.push_back(action);
176ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu  }
177ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu
1781d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  virtual void Initialize(ASTContext &Context) {
1791d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    Ctx = &Context;
18043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis    checkerMgr.reset(registerCheckers(Opts, PP.getDiagnostics()));
1811d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    Mgr.reset(new AnalysisManager(*Ctx, PP.getDiagnostics(),
1821d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                  PP.getLangOptions(), PD,
1831d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                  CreateStoreMgr, CreateConstraintMgr,
18443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis                                  checkerMgr.get(),
185c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu                                  /* Indexer */ 0,
1866362b893731ccf4480a96527db9e55e04b801503Zhongxing Xu                                  Opts.MaxNodes, Opts.MaxLoop,
1871d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                  Opts.VisualizeEGDot, Opts.VisualizeEGUbi,
1881d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                  Opts.PurgeDead, Opts.EagerlyAssume,
1899b823e8e1ccb8a2cb49923bad22a80ca96f41f92Ted Kremenek                                  Opts.TrimGraph, Opts.InlineCall,
1909121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski                                  Opts.UnoptimizedCFG, Opts.CFGAddImplicitDtors,
191d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek                                  Opts.CFGAddInitializers,
192d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek                                  Opts.EagerlyTrimEGraph));
1931d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  }
1941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1951d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  virtual void HandleTranslationUnit(ASTContext &C);
19614cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek  void HandleDeclContext(ASTContext &C, DeclContext *dc);
19714cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek
19806a54a38be5054c910ffc92db60edab23f9ea105Argyrios Kyrtzidis  void HandleCode(Decl *D, Actions& actions);
1991d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek};
200f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek} // end anonymous namespace
201f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
202f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
203f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// AnalysisConsumer implementation.
204f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
205f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
20614cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenekvoid AnalysisConsumer::HandleDeclContext(ASTContext &C, DeclContext *dc) {
20714cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek  for (DeclContext::decl_iterator I = dc->decls_begin(), E = dc->decls_end();
208ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu       I != E; ++I) {
209ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu    Decl *D = *I;
21014cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek
211ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu    switch (D->getKind()) {
21214cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek      case Decl::Namespace: {
21314cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        HandleDeclContext(C, cast<NamespaceDecl>(D));
21414cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        break;
215ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu      }
21614cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek      case Decl::CXXConstructor:
21714cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek      case Decl::CXXDestructor:
21814cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek      case Decl::CXXConversion:
21914cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek      case Decl::CXXMethod:
22014cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek      case Decl::Function: {
22114cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        FunctionDecl* FD = cast<FunctionDecl>(D);
22214cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        // We skip function template definitions, as their semantics is
22314cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        // only determined when they are instantiated.
22414cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        if (FD->isThisDeclarationADefinition() &&
22514cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek            !FD->isDependentContext()) {
226ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu          if (!Opts.AnalyzeSpecificFunction.empty() &&
22714cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek              FD->getDeclName().getAsString() != Opts.AnalyzeSpecificFunction)
228ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu            break;
22914cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek          DisplayFunction(FD);
23014cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek          HandleCode(FD, FunctionActions);
231ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu        }
23214cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        break;
233ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu      }
23414cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek
23514cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek      case Decl::ObjCImplementation: {
23614cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        ObjCImplementationDecl* ID = cast<ObjCImplementationDecl>(*I);
23714cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        HandleCode(ID, ObjCImplementationActions);
23814cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek
23914cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        for (ObjCImplementationDecl::method_iterator MI = ID->meth_begin(),
24014cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek             ME = ID->meth_end(); MI != ME; ++MI) {
24114cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek          if ((*MI)->isThisDeclarationADefinition()) {
24214cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek            if (!Opts.AnalyzeSpecificFunction.empty() &&
24314cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek                Opts.AnalyzeSpecificFunction != (*MI)->getSelector().getAsString())
24414cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek              break;
24514cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek            DisplayFunction(*MI);
24614cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek            HandleCode(*MI, ObjCMethodActions);
24714cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek          }
24814cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        }
24914cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        break;
25014cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek      }
25114cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek
25214cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek      default:
25314cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        break;
254ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu    }
25514cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek  }
25614cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek}
257f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
25814cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenekvoid AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
25914cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek  TranslationUnitDecl *TU = C.getTranslationUnitDecl();
26014cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek  HandleDeclContext(C, TU);
261b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu
262f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek  for (TUActions::iterator I = TranslationUnitActions.begin(),
263f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek                           E = TranslationUnitActions.end(); I != E; ++I) {
264f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek    (*I)(*this, *Mgr, *TU);
265daac634c9744257d43ce892b973019b16468caf2Ted Kremenek  }
266daac634c9744257d43ce892b973019b16468caf2Ted Kremenek
267690a7f431d6863a101711e67636d51ddd13f35c5Ted Kremenek  // Explicitly destroy the PathDiagnosticClient.  This will flush its output.
268690a7f431d6863a101711e67636d51ddd13f35c5Ted Kremenek  // FIXME: This should be replaced with something that doesn't rely on
269da17fd50ad485fd2a1fc5c2f055caacf532992daZhongxing Xu  // side-effects in PathDiagnosticClient's destructor. This is required when
270da17fd50ad485fd2a1fc5c2f055caacf532992daZhongxing Xu  // used with option -disable-free.
271d07a0d0279c09d1017f8450fce575a94dc9703c0Zhongxing Xu  Mgr.reset(NULL);
272db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek}
273db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek
274fc576514d06c46a7cac49500169411d82f38d04bTed Kremenekstatic void FindBlocks(DeclContext *D, llvm::SmallVectorImpl<Decl*> &WL) {
275fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek  if (BlockDecl *BD = dyn_cast<BlockDecl>(D))
276fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek    WL.push_back(BD);
277f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
278fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek  for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
279fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek       I!=E; ++I)
280fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek    if (DeclContext *DC = dyn_cast<DeclContext>(*I))
281fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek      FindBlocks(DC, WL);
282fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek}
283fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek
28406a54a38be5054c910ffc92db60edab23f9ea105Argyrios Kyrtzidisvoid AnalysisConsumer::HandleCode(Decl *D, Actions& actions) {
2851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
286f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  // Don't run the actions if an error has occured with parsing the file.
28799e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek  Diagnostic &Diags = PP.getDiagnostics();
28899e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek  if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred())
289f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek    return;
29081922f01352aceeb923c0c3cc8c96b6527322384Ted Kremenek
291f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  // Don't run the actions on declarations in header files unless
292f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  // otherwise specified.
293fcd783d583d270b7ec1ec3e0fcf83cd93d30e381Ted Kremenek  SourceManager &SM = Ctx->getSourceManager();
294fcd783d583d270b7ec1ec3e0fcf83cd93d30e381Ted Kremenek  SourceLocation SL = SM.getInstantiationLoc(D->getLocation());
295fcd783d583d270b7ec1ec3e0fcf83cd93d30e381Ted Kremenek  if (!Opts.AnalyzeAll && !SM.isFromMainFile(SL))
2961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return;
297f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
29858f5ec7d56b1ebf5f90ee11226ebe7663f2821eaTed Kremenek  // Clear the AnalysisManager of old AnalysisContexts.
29958f5ec7d56b1ebf5f90ee11226ebe7663f2821eaTed Kremenek  Mgr->ClearContexts();
300f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
3011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Dispatch on the actions.
302fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek  llvm::SmallVector<Decl*, 10> WL;
303fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek  WL.push_back(D);
304f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
30506a54a38be5054c910ffc92db60edab23f9ea105Argyrios Kyrtzidis  if (D->hasBody() && Opts.AnalyzeNestedBlocks)
306fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek    FindBlocks(cast<DeclContext>(D), WL);
307f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
3083702af57e399448efa8e2bfd600f009945b5c936Zhongxing Xu  for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I)
309fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek    for (llvm::SmallVectorImpl<Decl*>::iterator WI=WL.begin(), WE=WL.end();
310fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek         WI != WE; ++WI)
311fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek      (*I)(*this, *Mgr, *WI);
312f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek}
313f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
314f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
315f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// Analyses
316f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
317f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
3181d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionWarnDeadStores(AnalysisConsumer &C, AnalysisManager& mgr,
3191d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                 Decl *D) {
320b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu  if (LiveVariables *L = mgr.getLiveVariables(D)) {
3217032f460fc9828f386056e75933da5af61e88638Ted Kremenek    BugReporter BR(mgr);
322b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu    CheckDeadStores(*mgr.getCFG(D), *L, mgr.getParentMap(D), BR);
3237032f460fc9828f386056e75933da5af61e88638Ted Kremenek  }
324f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek}
325f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
3261d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionWarnUninitVals(AnalysisConsumer &C, AnalysisManager& mgr,
3271d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                 Decl *D) {
3281d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  if (CFG* c = mgr.getCFG(D)) {
3295032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu    CheckUninitializedValues(*c, mgr.getASTContext(), mgr.getDiagnostic());
3301d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  }
331f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek}
332f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
333b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek
334d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisstatic void ActionExprEngine(AnalysisConsumer &C, AnalysisManager& mgr,
335f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek                               Decl *D,
336d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis                               TransferFuncs* tf) {
3371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
338d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  llvm::OwningPtr<TransferFuncs> TF(tf);
3397032f460fc9828f386056e75933da5af61e88638Ted Kremenek
34075d03cffe20b5c945ef04eba208efb0437339997Ted Kremenek  // Construct the analysis engine.  We first query for the LiveVariables
34175d03cffe20b5c945ef04eba208efb0437339997Ted Kremenek  // information to see if the CFG is valid.
34275d03cffe20b5c945ef04eba208efb0437339997Ted Kremenek  // FIXME: Inter-procedural analysis will need to handle invalid CFGs.
34375d03cffe20b5c945ef04eba208efb0437339997Ted Kremenek  if (!mgr.getLiveVariables(D))
344f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek    return;
345d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  ExprEngine Eng(mgr, TF.take());
346f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
3478382cf57b722f130f1a6b45380639871c07271c1Ted Kremenek  if (C.Opts.EnableExperimentalInternalChecks)
3488382cf57b722f130f1a6b45380639871c07271c1Ted Kremenek    RegisterExperimentalInternalChecks(Eng);
349f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
3506a19832d08f00ac78c0a69c4fbe38b04a55b75ccTed Kremenek  RegisterAppleChecks(Eng, *D);
351f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
352eb94113be0ee5f4d38408b413d92464a0bc16b55Ted Kremenek  if (C.Opts.EnableExperimentalChecks)
353eb94113be0ee5f4d38408b413d92464a0bc16b55Ted Kremenek    RegisterExperimentalChecks(Eng);
354f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
355bd5a94e263137dc3ce7c100485626bae025cf58eArgyrios Kyrtzidis  if (C.Opts.ObjCSelfInitCheck && isa<ObjCMethodDecl>(D))
356bd5a94e263137dc3ce7c100485626bae025cf58eArgyrios Kyrtzidis    registerObjCSelfInitChecker(Eng);
357bd5a94e263137dc3ce7c100485626bae025cf58eArgyrios Kyrtzidis
3581fafd1d96419f587763d1b81332d8f476aeace2eTom Care  // Enable idempotent operation checking if it was explicitly turned on, or if
3591fafd1d96419f587763d1b81332d8f476aeace2eTom Care  // we are running experimental checks (i.e. everything)
3601fafd1d96419f587763d1b81332d8f476aeace2eTom Care  if (C.Opts.IdempotentOps || C.Opts.EnableExperimentalChecks
3611fafd1d96419f587763d1b81332d8f476aeace2eTom Care      || C.Opts.EnableExperimentalInternalChecks)
3621fafd1d96419f587763d1b81332d8f476aeace2eTom Care    RegisterIdempotentOperationChecker(Eng);
363c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek
364c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  if (C.Opts.BufferOverflows)
365c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek    RegisterArrayBoundCheckerV2(Eng);
3661fafd1d96419f587763d1b81332d8f476aeace2eTom Care
36752d861ce41ce84d8389495ea78d97bcc962ac5baTom Care  // Enable AnalyzerStatsChecker if it was given as an argument
36852d861ce41ce84d8389495ea78d97bcc962ac5baTom Care  if (C.Opts.AnalyzerStats)
36952d861ce41ce84d8389495ea78d97bcc962ac5baTom Care    RegisterAnalyzerStatsChecker(Eng);
37052d861ce41ce84d8389495ea78d97bcc962ac5baTom Care
371f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  // Set the graph auditor.
372c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  llvm::OwningPtr<ExplodedNode::Auditor> Auditor;
373f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  if (mgr.shouldVisualizeUbigraph()) {
374f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    Auditor.reset(CreateUbiViz());
375c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    ExplodedNode::SetAuditor(Auditor.get());
376f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  }
3771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
378b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  // Execute the worklist algorithm.
379c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu  Eng.ExecuteWorkList(mgr.getStackFrame(D, 0), mgr.getMaxNodes());
3801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
381f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  // Release the auditor (if any) so that it doesn't monitor the graph
382f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  // created BugReporter.
383c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  ExplodedNode::SetAuditor(0);
3843df6421150271266b5a90fd4c6bfa6566c38c036Ted Kremenek
38534d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  // Visualize the exploded graph.
386f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  if (mgr.shouldVisualizeGraphviz())
38734d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek    Eng.ViewGraph(mgr.shouldTrimGraph());
3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3893df6421150271266b5a90fd4c6bfa6566c38c036Ted Kremenek  // Display warnings.
3903df6421150271266b5a90fd4c6bfa6566c38c036Ted Kremenek  Eng.getBugReporter().FlushReports();
391bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek}
392bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek
393565e465c6d0093f1bf8414b2cabdc842022385a9Ted Kremenekstatic void ActionObjCMemCheckerAux(AnalysisConsumer &C, AnalysisManager& mgr,
3941d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                  Decl *D, bool GCEnabled) {
3951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
396d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  TransferFuncs* TF = MakeCFRefCountTF(mgr.getASTContext(),
397bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek                                         GCEnabled,
398bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek                                         mgr.getLangOptions());
3991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
400d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  ActionExprEngine(C, mgr, D, TF);
401b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek}
402b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek
403565e465c6d0093f1bf8414b2cabdc842022385a9Ted Kremenekstatic void ActionObjCMemChecker(AnalysisConsumer &C, AnalysisManager& mgr,
4041d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                               Decl *D) {
4051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
406b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek switch (mgr.getLangOptions().getGCMode()) {
407b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump default:
408b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump   assert (false && "Invalid GC mode.");
409b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump case LangOptions::NonGC:
410565e465c6d0093f1bf8414b2cabdc842022385a9Ted Kremenek   ActionObjCMemCheckerAux(C, mgr, D, false);
411b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump   break;
412b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump
413b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump case LangOptions::GCOnly:
414565e465c6d0093f1bf8414b2cabdc842022385a9Ted Kremenek   ActionObjCMemCheckerAux(C, mgr, D, true);
415b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump   break;
416b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump
417b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump case LangOptions::HybridGC:
418565e465c6d0093f1bf8414b2cabdc842022385a9Ted Kremenek   ActionObjCMemCheckerAux(C, mgr, D, false);
419565e465c6d0093f1bf8414b2cabdc842022385a9Ted Kremenek   ActionObjCMemCheckerAux(C, mgr, D, true);
420b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump   break;
421b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek }
422b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek}
423b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek
4241d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionDisplayLiveVariables(AnalysisConsumer &C,
4251d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                       AnalysisManager& mgr, Decl *D) {
426b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu  if (LiveVariables* L = mgr.getLiveVariables(D)) {
4277032f460fc9828f386056e75933da5af61e88638Ted Kremenek    L->dumpBlockLiveness(mgr.getSourceManager());
4287032f460fc9828f386056e75933da5af61e88638Ted Kremenek  }
429235e031e84dd9d9aeee554db40e480f14650b527Ted Kremenek}
430235e031e84dd9d9aeee554db40e480f14650b527Ted Kremenek
4311d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionCFGDump(AnalysisConsumer &C, AnalysisManager& mgr, Decl *D) {
4321d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  if (CFG *cfg = mgr.getCFG(D)) {
4331d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    cfg->dump(mgr.getLangOptions());
4347032f460fc9828f386056e75933da5af61e88638Ted Kremenek  }
435902141f74ac3a2cd41966a98cd43e8702bc05ce9Ted Kremenek}
436902141f74ac3a2cd41966a98cd43e8702bc05ce9Ted Kremenek
4371d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionCFGView(AnalysisConsumer &C, AnalysisManager& mgr, Decl *D) {
4381d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  if (CFG *cfg = mgr.getCFG(D)) {
4391d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    cfg->viewCFG(mgr.getLangOptions());
4407032f460fc9828f386056e75933da5af61e88638Ted Kremenek  }
441902141f74ac3a2cd41966a98cd43e8702bc05ce9Ted Kremenek}
442902141f74ac3a2cd41966a98cd43e8702bc05ce9Ted Kremenek
4431d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionSecuritySyntacticChecks(AnalysisConsumer &C,
4441d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                          AnalysisManager &mgr, Decl *D) {
4451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  BugReporter BR(mgr);
446b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu  CheckSecuritySyntaxOnly(D, BR);
447dbfb5f853547c4cc2b4b39e90f01537dd317457aTed Kremenek}
448dbfb5f853547c4cc2b4b39e90f01537dd317457aTed Kremenek
4496dd66ed959b7f60749dd0040507b3f304183a1b6Ted Kremenekstatic void ActionLLVMConventionChecker(AnalysisConsumer &C,
4506dd66ed959b7f60749dd0040507b3f304183a1b6Ted Kremenek                                        AnalysisManager &mgr,
451676ca153e04b1c6be477bc8a10f1e06256850ceeTed Kremenek                                        TranslationUnitDecl &TU) {
4526dd66ed959b7f60749dd0040507b3f304183a1b6Ted Kremenek  BugReporter BR(mgr);
453676ca153e04b1c6be477bc8a10f1e06256850ceeTed Kremenek  CheckLLVMConventions(TU, BR);
4546dd66ed959b7f60749dd0040507b3f304183a1b6Ted Kremenek}
4556dd66ed959b7f60749dd0040507b3f304183a1b6Ted Kremenek
4561d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionWarnObjCDealloc(AnalysisConsumer &C, AnalysisManager& mgr,
4571d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                  Decl *D) {
4584f4e7e4610f7a6eb8923a3bf6f2951b2dca98608Ted Kremenek  if (mgr.getLangOptions().getGCMode() == LangOptions::GCOnly)
4594f4e7e4610f7a6eb8923a3bf6f2951b2dca98608Ted Kremenek    return;
460db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek  BugReporter BR(mgr);
4611d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  CheckObjCDealloc(cast<ObjCImplementationDecl>(D), mgr.getLangOptions(), BR);
462db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek}
463db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek
4641d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionWarnObjCUnusedIvars(AnalysisConsumer &C, AnalysisManager& mgr,
4651d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                      Decl *D) {
466395aaf20d6e1ab04741562dc6b7d47164bcbd87eTed Kremenek  BugReporter BR(mgr);
4671d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  CheckObjCUnusedIvar(cast<ObjCImplementationDecl>(D), BR);
468395aaf20d6e1ab04741562dc6b7d47164bcbd87eTed Kremenek}
469395aaf20d6e1ab04741562dc6b7d47164bcbd87eTed Kremenek
4701d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionWarnObjCMethSigs(AnalysisConsumer &C, AnalysisManager& mgr,
4711d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                   Decl *D) {
4720d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek  BugReporter BR(mgr);
473b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu  CheckObjCInstMethSignature(cast<ObjCImplementationDecl>(D), BR);
4740d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek}
4750d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek
4761d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionWarnSizeofPointer(AnalysisConsumer &C, AnalysisManager &mgr,
4771d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                    Decl *D) {
47828a109f63506d8c96e3fbf1b959b603ccec2f586Zhongxing Xu  BugReporter BR(mgr);
47928a109f63506d8c96e3fbf1b959b603ccec2f586Zhongxing Xu  CheckSizeofPointer(D, BR);
48028a109f63506d8c96e3fbf1b959b603ccec2f586Zhongxing Xu}
48128a109f63506d8c96e3fbf1b959b603ccec2f586Zhongxing Xu
482f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
483f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// AnalysisConsumer creation.
484f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
485f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
4869ef6537a894c33003359b1f9b9676e9178e028b7Ted KremenekASTConsumer* ento::CreateAnalysisConsumer(const Preprocessor& pp,
487e71b85feb0a2df9273b1b488f5b40279369a6255Eli Friedman                                           const std::string& OutDir,
488e71b85feb0a2df9273b1b488f5b40279369a6255Eli Friedman                                           const AnalyzerOptions& Opts) {
489efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar  llvm::OwningPtr<AnalysisConsumer> C(new AnalysisConsumer(pp, OutDir, Opts));
490be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek
491e71b85feb0a2df9273b1b488f5b40279369a6255Eli Friedman  for (unsigned i = 0; i < Opts.AnalysisList.size(); ++i)
492e71b85feb0a2df9273b1b488f5b40279369a6255Eli Friedman    switch (Opts.AnalysisList[i]) {
493f7f3c20a5d4c5bd1857a6cea1f001bb775401e96Ted Kremenek#define ANALYSIS(NAME, CMD, DESC, SCOPE)\
494b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump    case NAME:\
495b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump      C->add ## SCOPE ## Action(&Action ## NAME);\
496b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump      break;
4974df2c42581280bb1a02a5d034dbf657514cc56e8Eli Friedman#include "clang/Frontend/Analyses.def"
498b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump    default: break;
499f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek    }
5001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5012c4036eda90fad6d219d9f3fadbd9288fa197e89Ted Kremenek  // Last, disable the effects of '-Werror' when using the AnalysisConsumer.
502efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar  pp.getDiagnostics().setWarningsAsErrors(false);
503be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek
504f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  return C.take();
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 {
514f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  llvm::OwningPtr<llvm::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:
522710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  UbigraphViz(llvm::raw_ostream* out, llvm::sys::Path& dir,
52356b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek              llvm::sys::Path& filename);
5241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
525710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  ~UbigraphViz();
5261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  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
548f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  llvm::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
557c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xuvoid 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
59156b98719b0dbebb33cb228afa888c47156be2381Ted KremenekUbigraphViz::UbigraphViz(llvm::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