AnalysisConsumer.cpp revision e62f048960645b79363408fdead53fec2a063c52
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)."); 56e62f048960645b79363408fdead53fec2a063c52Anna ZaksSTATISTIC(NumBlocksInAnalyzedFunctions, 57e62f048960645b79363408fdead53fec2a063c52Anna Zaks "The # of basic blocks in the analyzed functions."); 58e62f048960645b79363408fdead53fec2a063c52Anna ZaksSTATISTIC(PercentReachableBlocks, "The % of reachable basic blocks."); 59d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks 60be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek//===----------------------------------------------------------------------===// 61f39d962cf84f46d2c0512157259ae1d41a1a5173David Blaikie// Special PathDiagnosticConsumers. 62f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek//===----------------------------------------------------------------------===// 63f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek 64ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikiestatic PathDiagnosticConsumer* 65ef3643fbbbf66247c5e205497fae0f46e240c143David BlaikiecreatePlistHTMLDiagnosticConsumer(const std::string& prefix, 66efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar const Preprocessor &PP) { 67ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie PathDiagnosticConsumer *PD = 68ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie createHTMLDiagnosticConsumer(llvm::sys::path::parent_path(prefix), PP); 69ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie return createPlistDiagnosticConsumer(prefix, PP, PD); 70f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek} 71f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek 72f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek//===----------------------------------------------------------------------===// 73f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// AnalysisConsumer declaration. 74f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===// 75f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 76f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremeneknamespace { 77f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 78aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaksclass AnalysisConsumer : public ASTConsumer, 79aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks public RecursiveASTVisitor<AnalysisConsumer> { 80aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks enum AnalysisMode { 81aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks ANALYSIS_SYNTAX, 82aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks ANALYSIS_PATH, 83aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks ANALYSIS_ALL 84aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks }; 85aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks 86aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks /// Mode of the analyzes while recursively visiting Decls. 87aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks AnalysisMode RecVisitorMode; 88aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks /// Bug Reporter to use while recursively visiting Decls. 89aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks BugReporter *RecVisitorBR; 90aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks 91ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xupublic: 929c378f705405d37f49795d5e915989de774fe11fTed Kremenek ASTContext *Ctx; 931d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek const Preprocessor &PP; 941d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek const std::string OutDir; 951d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek AnalyzerOptions Opts; 9608b86531ade68727c56918f162816075b87c864aJordy Rose ArrayRef<std::string> Plugins; 97d07a0d0279c09d1017f8450fce575a94dc9703c0Zhongxing Xu 981d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek // PD is owned by AnalysisManager. 99ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie PathDiagnosticConsumer *PD; 100d07a0d0279c09d1017f8450fce575a94dc9703c0Zhongxing Xu 1011d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek StoreManagerCreator CreateStoreMgr; 1021d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek ConstraintManagerCreator CreateConstraintMgr; 103f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 1046f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<CheckerManager> checkerMgr; 1056f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<AnalysisManager> Mgr; 106c471e7b44e63ff1b46b480e723c4130aeaef5a8aZhongxing Xu 107d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks /// Time the analyzes time of each translation unit. 108d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks static llvm::Timer* TUTotalTimer; 109d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks 1103bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks /// The information about analyzed functions shared throughout the 1113bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks /// translation unit. 1123bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks FunctionSummariesTy FunctionSummaries; 1133bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks 1141d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek AnalysisConsumer(const Preprocessor& pp, 1151d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek const std::string& outdir, 11608b86531ade68727c56918f162816075b87c864aJordy Rose const AnalyzerOptions& opts, 11708b86531ade68727c56918f162816075b87c864aJordy Rose ArrayRef<std::string> plugins) 118aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks : RecVisitorMode(ANALYSIS_ALL), RecVisitorBR(0), 119aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks Ctx(0), PP(pp), OutDir(outdir), Opts(opts), Plugins(plugins), PD(0) { 1201d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek DigestAnalyzerOptions(); 121d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks if (Opts.PrintStats) { 122d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks llvm::EnableStatistics(); 123d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks TUTotalTimer = new llvm::Timer("Analyzer Total Time"); 124d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks } 125d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks } 126d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks 127d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks ~AnalysisConsumer() { 128e62f048960645b79363408fdead53fec2a063c52Anna Zaks // Count how many basic blocks we have not covered. 129e62f048960645b79363408fdead53fec2a063c52Anna Zaks NumBlocksInAnalyzedFunctions = FunctionSummaries.getTotalNumBasicBlocks(); 130e62f048960645b79363408fdead53fec2a063c52Anna Zaks if (NumBlocksInAnalyzedFunctions > 0) 131e62f048960645b79363408fdead53fec2a063c52Anna Zaks PercentReachableBlocks = 132e62f048960645b79363408fdead53fec2a063c52Anna Zaks (FunctionSummaries.getTotalNumVisitedBasicBlocks() * 100) / 133e62f048960645b79363408fdead53fec2a063c52Anna Zaks NumBlocksInAnalyzedFunctions; 134e62f048960645b79363408fdead53fec2a063c52Anna Zaks 135d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks if (Opts.PrintStats) 136d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks delete TUTotalTimer; 1371d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek } 138fda7832b000ff8927386f093b52c067641679469Zhongxing Xu 1391d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek void DigestAnalyzerOptions() { 140ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie // Create the PathDiagnosticConsumer. 1411d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek if (!OutDir.empty()) { 1421d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek switch (Opts.AnalysisDiagOpt) { 1431d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek default: 144fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE) \ 1451d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek case PD_##NAME: PD = CREATEFN(OutDir, PP); break; 146fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#include "clang/Frontend/Analyses.def" 147fda7832b000ff8927386f093b52c067641679469Zhongxing Xu } 148a599ae8826b01c0160a519b0fc5a4871f599bf04Argyrios Kyrtzidis } else if (Opts.AnalysisDiagOpt == PD_TEXT) { 149a599ae8826b01c0160a519b0fc5a4871f599bf04Argyrios Kyrtzidis // Create the text client even without a specified output file since 150a599ae8826b01c0160a519b0fc5a4871f599bf04Argyrios Kyrtzidis // it just uses diagnostic notes. 151ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie PD = createTextPathDiagnosticConsumer("", PP); 1521d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek } 153fda7832b000ff8927386f093b52c067641679469Zhongxing Xu 1541d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek // Create the analyzer component creators. 1555f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis switch (Opts.AnalysisStoreOpt) { 1565f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis default: 157b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Unknown store manager."); 158fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATEFN) \ 1595f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis case NAME##Model: CreateStoreMgr = CREATEFN; break; 160fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#include "clang/Frontend/Analyses.def" 1611d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek } 1621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1635f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis switch (Opts.AnalysisConstraintsOpt) { 1645f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis default: 165b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Unknown store manager."); 166fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATEFN) \ 1675f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis case NAME##Model: CreateConstraintMgr = CREATEFN; break; 168fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#include "clang/Frontend/Analyses.def" 169fda7832b000ff8927386f093b52c067641679469Zhongxing Xu } 1701d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek } 171f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek 172aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks void DisplayFunction(const Decl *D, AnalysisMode Mode) { 173c4a1437c15da43eb8d2601cdce13161ef41a4389Ted Kremenek if (!Opts.AnalyzerDisplayProgress) 1741d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek return; 175f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek 176fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek SourceManager &SM = Mgr->getASTContext().getSourceManager(); 177fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek PresumedLoc Loc = SM.getPresumedLoc(D->getLocation()); 178cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor if (Loc.isValid()) { 179aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks llvm::errs() << "ANALYZE"; 180aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks switch (Mode) { 181aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks case ANALYSIS_SYNTAX: llvm::errs() << "(Syntax)"; break; 182aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks case ANALYSIS_PATH: llvm::errs() << "(Path Sensitive)"; break; 183aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks case ANALYSIS_ALL: break; 184aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks }; 185aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks llvm::errs() << ": " << Loc.getFilename(); 186cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) { 187cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor const NamedDecl *ND = cast<NamedDecl>(D); 188b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer llvm::errs() << ' ' << *ND << '\n'; 189cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor } 190cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor else if (isa<BlockDecl>(D)) { 191cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor llvm::errs() << ' ' << "block(line:" << Loc.getLine() << ",col:" 192cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor << Loc.getColumn() << '\n'; 193cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor } 194cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 195cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor Selector S = MD->getSelector(); 196cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor llvm::errs() << ' ' << S.getAsString(); 197cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor } 19835fa76d0bb6fb8c86159a7506efd094a4fe376d2Ted Kremenek } 1991d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek } 2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2011d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek virtual void Initialize(ASTContext &Context) { 2021d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek Ctx = &Context; 2034e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie checkerMgr.reset(createCheckerManager(Opts, PP.getLangOpts(), Plugins, 20408b86531ade68727c56918f162816075b87c864aJordy Rose PP.getDiagnostics())); 2051d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek Mgr.reset(new AnalysisManager(*Ctx, PP.getDiagnostics(), 2064e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie PP.getLangOpts(), PD, 2071d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek CreateStoreMgr, CreateConstraintMgr, 20843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis checkerMgr.get(), 209c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu /* Indexer */ 0, 2106362b893731ccf4480a96527db9e55e04b801503Zhongxing Xu Opts.MaxNodes, Opts.MaxLoop, 2111d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek Opts.VisualizeEGDot, Opts.VisualizeEGUbi, 212d30952838421ddfb9f7e346b2ba8213889a5f789Anna Zaks Opts.AnalysisPurgeOpt, Opts.EagerlyAssume, 21366253352131e3e7a22b3bfd0e180607aa2bfb988Anna Zaks Opts.TrimGraph, 2149121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski Opts.UnoptimizedCFG, Opts.CFGAddImplicitDtors, 215d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek Opts.CFGAddInitializers, 2168235f9c9c8b3d1737d1c6bd57f7ba3f616b92392Anna Zaks Opts.EagerlyTrimEGraph, 21766253352131e3e7a22b3bfd0e180607aa2bfb988Anna Zaks Opts.IPAMode, 2188235f9c9c8b3d1737d1c6bd57f7ba3f616b92392Anna Zaks Opts.InlineMaxStackDepth, 21966253352131e3e7a22b3bfd0e180607aa2bfb988Anna Zaks Opts.InlineMaxFunctionSize, 2205903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks Opts.InliningMode, 221b47dbcbc12430fdf3e5a5b9f59cdec5480e89e75Anna Zaks Opts.NoRetryExhausted)); 2221d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek } 2231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2241d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek virtual void HandleTranslationUnit(ASTContext &C); 22514cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek 226a2e589e60d147f4f04cee5682b8389b55c410244Anna Zaks /// \brief Build the call graph for the TU and use it to define the order 227aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks /// in which the functions should be visited. 228a2e589e60d147f4f04cee5682b8389b55c410244Anna Zaks void HandleDeclsGallGraph(TranslationUnitDecl *TU); 229aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks 230aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks /// \brief Run analyzes(syntax or path sensitive) on the given function. 231aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks /// \param Mode - determines if we are requesting syntax only or path 232aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks /// sensitive only analysis. 233aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks /// \param VisitedCallees - The output parameter, which is populated with the 234aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks /// set of functions which should be considered analyzed after analyzing the 235aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks /// given root function. 236aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks void HandleCode(Decl *D, AnalysisMode Mode, SetOfDecls *VisitedCallees = 0); 237aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks 238aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks /// \brief Check if we should skip (not analyze) the given function. 23998520835eb1aa091429afa06e9f4f7ebe3864d34Anna Zaks bool skipFunction(Decl *D); 240aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks 2413fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks void RunPathSensitiveChecks(Decl *D, SetOfDecls *VisitedCallees); 2423fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks void ActionExprEngine(Decl *D, bool ObjCGCEnabled, SetOfDecls *VisitedCallees); 243aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks 244aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks /// Visitors for the RecursiveASTVisitor. 245aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks 246aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks /// Handle callbacks for arbitrary Decls. 247aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks bool VisitDecl(Decl *D) { 248aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks checkerMgr->runCheckersOnASTDecl(D, *Mgr, *RecVisitorBR); 249aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks return true; 250aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks } 251aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks 252aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks bool VisitFunctionDecl(FunctionDecl *FD) { 253aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks IdentifierInfo *II = FD->getIdentifier(); 254aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks if (II && II->getName().startswith("__inline")) 255aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks return true; 256aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks 257aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks // We skip function template definitions, as their semantics is 258aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks // only determined when they are instantiated. 259aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks if (FD->isThisDeclarationADefinition() && 260aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks !FD->isDependentContext()) { 261aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks HandleCode(FD, RecVisitorMode); 262aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks } 263aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks return true; 264aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks } 265aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks 266aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks bool VisitObjCMethodDecl(ObjCMethodDecl *MD) { 267aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks checkerMgr->runCheckersOnASTDecl(MD, *Mgr, *RecVisitorBR); 268aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks if (MD->isThisDeclarationADefinition()) 269aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks HandleCode(MD, RecVisitorMode); 270aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks return true; 271aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks } 2721d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek}; 273f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek} // end anonymous namespace 274f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 275aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks 276f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===// 277f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// AnalysisConsumer implementation. 278f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===// 279d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaksllvm::Timer* AnalysisConsumer::TUTotalTimer = 0; 280f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 281a2e589e60d147f4f04cee5682b8389b55c410244Anna Zaksvoid AnalysisConsumer::HandleDeclsGallGraph(TranslationUnitDecl *TU) { 282d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks // Otherwise, use the Callgraph to derive the order. 283d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks // Build the Call Graph. 284d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks CallGraph CG; 285a2e589e60d147f4f04cee5682b8389b55c410244Anna Zaks CG.addToCallGraph(TU); 286d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks 287d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks // Find the top level nodes - children of root + the unreachable (parentless) 288d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks // nodes. 2893fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks llvm::SmallVector<CallGraphNode*, 24> TopLevelFunctions; 290b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks for (CallGraph::nodes_iterator TI = CG.parentless_begin(), 291b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks TE = CG.parentless_end(); TI != TE; ++TI) { 292b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks TopLevelFunctions.push_back(*TI); 293b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks NumFunctionTopLevel++; 294b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks } 295d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks CallGraphNode *Entry = CG.getRoot(); 296d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks for (CallGraphNode::iterator I = Entry->begin(), 2973fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks E = Entry->end(); I != E; ++I) { 298d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks TopLevelFunctions.push_back(*I); 2993fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks NumFunctionTopLevel++; 3003fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks } 301d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks 302b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks // Make sure the nodes are sorted in order reverse of their definition in the 303b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks // translation unit. This step is very important for performance. It ensures 304b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks // that we analyze the root functions before the externally available 305b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks // subroutines. 3067fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks std::queue<CallGraphNode*> BFSQueue; 307b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks for (llvm::SmallVector<CallGraphNode*, 24>::reverse_iterator 308b990d039c7e01ad0055dcbd1e13a691813397b96Anna Zaks TI = TopLevelFunctions.rbegin(), TE = TopLevelFunctions.rend(); 3097fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks TI != TE; ++TI) 3107fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks BFSQueue.push(*TI); 311d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks 3127fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks // BFS over all of the functions, while skipping the ones inlined into 3137fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks // the previously processed functions. Use external Visited set, which is 314d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks // also modified when we inline a function. 315d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks SmallPtrSet<CallGraphNode*,24> Visited; 3167fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks while(!BFSQueue.empty()) { 3177fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks CallGraphNode *N = BFSQueue.front(); 3187fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks BFSQueue.pop(); 3197fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks 3207fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks // Skip the functions which have been processed already or previously 3217fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks // inlined. 3227fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks if (Visited.count(N)) 3237fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks continue; 3247fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks 3257fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks // Analyze the function. 3267fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks SetOfDecls VisitedCallees; 3277fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks Decl *D = N->getDecl(); 3287fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks assert(D); 3297fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks HandleCode(D, ANALYSIS_PATH, 3307fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks (Mgr->InliningMode == All ? 0 : &VisitedCallees)); 3317fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks 3327fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks // Add the visited callees to the global visited set. 3337fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks for (SetOfDecls::const_iterator I = VisitedCallees.begin(), 3347fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks E = VisitedCallees.end(); I != E; ++I) { 3357fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks CallGraphNode *VN = CG.getNode(*I); 3367fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks if (VN) 3377fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks Visited.insert(VN); 3387fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks } 3397fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks Visited.insert(N); 3407fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks 3417fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks // Push the children into the queue. 3427fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks for (CallGraphNode::const_iterator CI = N->begin(), 3437fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks CE = N->end(); CI != CE; ++CI) { 3447fe8dcef71ae56e43fd7df345db2895f84f2d0caAnna Zaks BFSQueue.push(*CI); 345d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks } 346d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks } 347fee618af5dd7dee2caaa7347b372eb3dc5fdeffcTed Kremenek} 348fee618af5dd7dee2caaa7347b372eb3dc5fdeffcTed Kremenek 34914cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenekvoid AnalysisConsumer::HandleTranslationUnit(ASTContext &C) { 350aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks // Don't run the actions if an error has occurred with parsing the file. 351aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks DiagnosticsEngine &Diags = PP.getDiagnostics(); 352aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred()) 353aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks return; 354aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks 355c5bdc556f6a65c677e0ed73f918c3000ecad33afAnna Zaks { 356d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks if (TUTotalTimer) TUTotalTimer->startTimer(); 357d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks 358c5bdc556f6a65c677e0ed73f918c3000ecad33afAnna Zaks // Introduce a scope to destroy BR before Mgr. 359c5bdc556f6a65c677e0ed73f918c3000ecad33afAnna Zaks BugReporter BR(*Mgr); 360c5bdc556f6a65c677e0ed73f918c3000ecad33afAnna Zaks TranslationUnitDecl *TU = C.getTranslationUnitDecl(); 361c5bdc556f6a65c677e0ed73f918c3000ecad33afAnna Zaks checkerMgr->runCheckersOnASTDecl(TU, *Mgr, BR); 362aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks 363aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks // Run the AST-only checks using the order in which functions are defined. 364aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks // If inlining is not turned on, use the simplest function order for path 365aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks // sensitive analyzes as well. 366aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks RecVisitorMode = (Mgr->shouldInlineCall() ? ANALYSIS_SYNTAX : ANALYSIS_ALL); 367aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks RecVisitorBR = &BR; 368aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks TraverseDecl(TU); 369aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks 370aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks if (Mgr->shouldInlineCall()) 371a2e589e60d147f4f04cee5682b8389b55c410244Anna Zaks HandleDeclsGallGraph(TU); 372b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu 373c5bdc556f6a65c677e0ed73f918c3000ecad33afAnna Zaks // After all decls handled, run checkers on the entire TranslationUnit. 374c5bdc556f6a65c677e0ed73f918c3000ecad33afAnna Zaks checkerMgr->runCheckersOnEndOfTranslationUnit(TU, *Mgr, BR); 375aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks 376aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks RecVisitorBR = 0; 377c5bdc556f6a65c677e0ed73f918c3000ecad33afAnna Zaks } 3789be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek 379ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie // Explicitly destroy the PathDiagnosticConsumer. This will flush its output. 380690a7f431d6863a101711e67636d51ddd13f35c5Ted Kremenek // FIXME: This should be replaced with something that doesn't rely on 381ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie // side-effects in PathDiagnosticConsumer's destructor. This is required when 382da17fd50ad485fd2a1fc5c2f055caacf532992daZhongxing Xu // used with option -disable-free. 383d07a0d0279c09d1017f8450fce575a94dc9703c0Zhongxing Xu Mgr.reset(NULL); 384d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks 385d38f79543136ba68cd14b1dab0856474df1fbfd5Anna Zaks if (TUTotalTimer) TUTotalTimer->stopTimer(); 386db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek} 387db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek 3885f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic void FindBlocks(DeclContext *D, SmallVectorImpl<Decl*> &WL) { 389fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) 390fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek WL.push_back(BD); 391f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek 392fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end(); 393fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek I!=E; ++I) 394fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek if (DeclContext *DC = dyn_cast<DeclContext>(*I)) 395fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek FindBlocks(DC, WL); 396fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek} 397fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek 398d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaksstatic std::string getFunctionName(const Decl *D) { 399d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks if (const ObjCMethodDecl *ID = dyn_cast<ObjCMethodDecl>(D)) { 400d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks return ID->getSelector().getAsString(); 401d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks } 402d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks if (const FunctionDecl *ND = dyn_cast<FunctionDecl>(D)) { 403d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks IdentifierInfo *II = ND->getIdentifier(); 404d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks if (II) 405d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks return II->getName(); 406d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks } 407d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks return ""; 408d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks} 409d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks 41098520835eb1aa091429afa06e9f4f7ebe3864d34Anna Zaksbool AnalysisConsumer::skipFunction(Decl *D) { 411d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks if (!Opts.AnalyzeSpecificFunction.empty() && 412d95e0b830ed031f2ea0e15e3679cd51b9bf23a9cAnna Zaks getFunctionName(D) != Opts.AnalyzeSpecificFunction) 41398520835eb1aa091429afa06e9f4f7ebe3864d34Anna Zaks return true; 4141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 415f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek // Don't run the actions on declarations in header files unless 416f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek // otherwise specified. 417fcd783d583d270b7ec1ec3e0fcf83cd93d30e381Ted Kremenek SourceManager &SM = Ctx->getSourceManager(); 418402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth SourceLocation SL = SM.getExpansionLoc(D->getLocation()); 419fcd783d583d270b7ec1ec3e0fcf83cd93d30e381Ted Kremenek if (!Opts.AnalyzeAll && !SM.isFromMainFile(SL)) 42098520835eb1aa091429afa06e9f4f7ebe3864d34Anna Zaks return true; 42198520835eb1aa091429afa06e9f4f7ebe3864d34Anna Zaks 42298520835eb1aa091429afa06e9f4f7ebe3864d34Anna Zaks return false; 42398520835eb1aa091429afa06e9f4f7ebe3864d34Anna Zaks} 42498520835eb1aa091429afa06e9f4f7ebe3864d34Anna Zaks 425aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaksvoid AnalysisConsumer::HandleCode(Decl *D, AnalysisMode Mode, 426aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks SetOfDecls *VisitedCallees) { 42798520835eb1aa091429afa06e9f4f7ebe3864d34Anna Zaks if (skipFunction(D)) 4281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return; 429f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 430aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks DisplayFunction(D, Mode); 43198520835eb1aa091429afa06e9f4f7ebe3864d34Anna Zaks 4321d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek // Clear the AnalysisManager of old AnalysisDeclContexts. 43358f5ec7d56b1ebf5f90ee11226ebe7663f2821eaTed Kremenek Mgr->ClearContexts(); 434f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek 4351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Dispatch on the actions. 4365f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Decl*, 10> WL; 437fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek WL.push_back(D); 438f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek 43906a54a38be5054c910ffc92db60edab23f9ea105Argyrios Kyrtzidis if (D->hasBody() && Opts.AnalyzeNestedBlocks) 440fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek FindBlocks(cast<DeclContext>(D), WL); 441f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek 4429fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis BugReporter BR(*Mgr); 4435f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner for (SmallVectorImpl<Decl*>::iterator WI=WL.begin(), WE=WL.end(); 4449fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis WI != WE; ++WI) 445d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis if ((*WI)->hasBody()) { 446aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks if (Mode != ANALYSIS_PATH) 447aa5609891df937291bf962dd2fc7deb2ceae292fAnna Zaks checkerMgr->runCheckersOnASTBody(*WI, *Mgr, BR); 4481f5171edc9fb9b0698a75fa981c29a750b0a6082Anna Zaks if (Mode != ANALYSIS_SYNTAX && checkerMgr->hasPathSensitiveCheckers()) { 4493fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks RunPathSensitiveChecks(*WI, VisitedCallees); 4501f5171edc9fb9b0698a75fa981c29a750b0a6082Anna Zaks NumFunctionsAnalyzed++; 4511f5171edc9fb9b0698a75fa981c29a750b0a6082Anna Zaks } 452d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis } 453f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek} 454f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 455f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===// 456d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis// Path-sensitive checking. 457f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===// 458f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 4593fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaksvoid AnalysisConsumer::ActionExprEngine(Decl *D, bool ObjCGCEnabled, 4603fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks SetOfDecls *VisitedCallees) { 461a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek // Construct the analysis engine. First check if the CFG is valid. 46275d03cffe20b5c945ef04eba208efb0437339997Ted Kremenek // FIXME: Inter-procedural analysis will need to handle invalid CFGs. 4633fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks if (!Mgr->getCFG(D)) 464f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek return; 4653fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks 4663bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks ExprEngine Eng(*Mgr, ObjCGCEnabled, VisitedCallees, &FunctionSummaries); 467f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek 468f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek // Set the graph auditor. 4696f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<ExplodedNode::Auditor> Auditor; 4703fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks if (Mgr->shouldVisualizeUbigraph()) { 471f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek Auditor.reset(CreateUbiViz()); 472c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu ExplodedNode::SetAuditor(Auditor.get()); 473f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek } 4741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 475b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek // Execute the worklist algorithm. 4763fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks Eng.ExecuteWorkList(Mgr->getAnalysisDeclContextManager().getStackFrame(D, 0), 4773fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks Mgr->getMaxNodes()); 4781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 479f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek // Release the auditor (if any) so that it doesn't monitor the graph 480f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek // created BugReporter. 481c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu ExplodedNode::SetAuditor(0); 4823df6421150271266b5a90fd4c6bfa6566c38c036Ted Kremenek 48334d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek // Visualize the exploded graph. 4843fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks if (Mgr->shouldVisualizeGraphviz()) 4853fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks Eng.ViewGraph(Mgr->shouldTrimGraph()); 4861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4873df6421150271266b5a90fd4c6bfa6566c38c036Ted Kremenek // Display warnings. 4883df6421150271266b5a90fd4c6bfa6566c38c036Ted Kremenek Eng.getBugReporter().FlushReports(); 489bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek} 490bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek 4913fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaksvoid AnalysisConsumer::RunPathSensitiveChecks(Decl *D, SetOfDecls *Visited) { 49217a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose 4934e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie switch (Mgr->getLangOpts().getGC()) { 49417a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose case LangOptions::NonGC: 4953fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks ActionExprEngine(D, false, Visited); 49617a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose break; 49717a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose 49817a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose case LangOptions::GCOnly: 4993fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks ActionExprEngine(D, true, Visited); 50017a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose break; 50117a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose 50217a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose case LangOptions::HybridGC: 5033fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks ActionExprEngine(D, false, Visited); 5043fd5f370a28552976c52e76c3035d79012d78ddaAnna Zaks ActionExprEngine(D, true, Visited); 50517a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose break; 50617a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose } 507b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek} 508b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek 509f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===// 510f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// AnalysisConsumer creation. 511f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===// 512f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 5139ef6537a894c33003359b1f9b9676e9178e028b7Ted KremenekASTConsumer* ento::CreateAnalysisConsumer(const Preprocessor& pp, 51408b86531ade68727c56918f162816075b87c864aJordy Rose const std::string& outDir, 51508b86531ade68727c56918f162816075b87c864aJordy Rose const AnalyzerOptions& opts, 51608b86531ade68727c56918f162816075b87c864aJordy Rose ArrayRef<std::string> plugins) { 51708b86531ade68727c56918f162816075b87c864aJordy Rose // Disable the effects of '-Werror' when using the AnalysisConsumer. 518efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar pp.getDiagnostics().setWarningsAsErrors(false); 519be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek 52008b86531ade68727c56918f162816075b87c864aJordy Rose return new AnalysisConsumer(pp, outDir, opts, plugins); 521f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek} 522f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek 523f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek//===----------------------------------------------------------------------===// 524f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek// Ubigraph Visualization. FIXME: Move to separate file. 525f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek//===----------------------------------------------------------------------===// 526f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 527f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremeneknamespace { 5281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 529c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xuclass UbigraphViz : public ExplodedNode::Auditor { 5306f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<raw_ostream> Out; 531710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek llvm::sys::Path Dir, Filename; 532f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek unsigned Cntr; 533f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 534f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek typedef llvm::DenseMap<void*,unsigned> VMap; 535f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek VMap M; 5361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 537f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenekpublic: 5389c378f705405d37f49795d5e915989de774fe11fTed Kremenek UbigraphViz(raw_ostream *out, llvm::sys::Path& dir, 53956b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek llvm::sys::Path& filename); 5401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 541710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek ~UbigraphViz(); 5421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5439c378f705405d37f49795d5e915989de774fe11fTed Kremenek virtual void AddEdge(ExplodedNode *Src, ExplodedNode *Dst); 544f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek}; 5451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 546f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek} // end anonymous namespace 547f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 548c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xustatic ExplodedNode::Auditor* CreateUbiViz() { 549f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek std::string ErrMsg; 5501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 551710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek llvm::sys::Path Dir = llvm::sys::Path::GetTemporaryDirectory(&ErrMsg); 552f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek if (!ErrMsg.empty()) 553f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek return 0; 554f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 555710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek llvm::sys::Path Filename = Dir; 556f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek Filename.appendComponent("llvm_ubi"); 557f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek Filename.makeUnique(true,&ErrMsg); 558f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 559f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek if (!ErrMsg.empty()) 560f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek return 0; 561f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 562d57a7ef9252964bc6c8471451d7bd395b0520cb8Chris Lattner llvm::errs() << "Writing '" << Filename.str() << "'.\n"; 5631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5646f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith OwningPtr<llvm::raw_fd_ostream> Stream; 565b044c473a155b7e827680635c1699cb2b5b6c0eeDan Gohman Stream.reset(new llvm::raw_fd_ostream(Filename.c_str(), ErrMsg)); 566f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 567f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek if (!ErrMsg.empty()) 568f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek return 0; 5691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 570710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek return new UbigraphViz(Stream.take(), Dir, Filename); 571f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek} 572f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 5739c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid UbigraphViz::AddEdge(ExplodedNode *Src, ExplodedNode *Dst) { 5741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 57545479c88c8a44c55d27c3bd855273bb318082f37Ted Kremenek assert (Src != Dst && "Self-edges are not allowed."); 5761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 577f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek // Lookup the Src. If it is a new node, it's a root. 578f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek VMap::iterator SrcI= M.find(Src); 579f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek unsigned SrcID; 5801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 581f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek if (SrcI == M.end()) { 582f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek M[Src] = SrcID = Cntr++; 583f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek *Out << "('vertex', " << SrcID << ", ('color','#00ff00'))\n"; 584f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek } 585f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek else 586f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek SrcID = SrcI->second; 5871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 588f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek // Lookup the Dst. 589f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek VMap::iterator DstI= M.find(Dst); 590f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek unsigned DstID; 591f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 592f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek if (DstI == M.end()) { 593f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek M[Dst] = DstID = Cntr++; 594f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek *Out << "('vertex', " << DstID << ")\n"; 595f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek } 59656b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek else { 59756b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek // We have hit DstID before. Change its style to reflect a cache hit. 598f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek DstID = DstI->second; 59956b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek *Out << "('change_vertex_style', " << DstID << ", 1)\n"; 60056b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek } 601f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 602f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek // Add the edge. 6031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump *Out << "('edge', " << SrcID << ", " << DstID 604d1289327f7d2126d732e23cc189ecd0aa5d07cbbTed Kremenek << ", ('arrow','true'), ('oriented', 'true'))\n"; 605f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek} 606f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek 6079c378f705405d37f49795d5e915989de774fe11fTed KremenekUbigraphViz::UbigraphViz(raw_ostream *out, llvm::sys::Path& dir, 60856b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek llvm::sys::Path& filename) 60956b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek : Out(out), Dir(dir), Filename(filename), Cntr(0) { 61056b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek 61156b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n"; 61256b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66')," 61356b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek " ('size', '1.5'))\n"; 61456b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek} 61556b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek 616710ad9343f32b33b336369b20edad1a21a0b3299Ted KremenekUbigraphViz::~UbigraphViz() { 617710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek Out.reset(0); 6186cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer llvm::errs() << "Running 'ubiviz' program... "; 619710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek std::string ErrMsg; 620710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek llvm::sys::Path Ubiviz = llvm::sys::Program::FindProgramByName("ubiviz"); 621710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek std::vector<const char*> args; 622710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek args.push_back(Ubiviz.c_str()); 623710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek args.push_back(Filename.c_str()); 624710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek args.push_back(0); 6251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 626710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek if (llvm::sys::Program::ExecuteAndWait(Ubiviz, &args[0],0,0,0,0,&ErrMsg)) { 6276cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer llvm::errs() << "Error viewing graph: " << ErrMsg << "\n"; 628710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek } 6291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 630710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek // Delete the directory. 6311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Dir.eraseFromDisk(true); 632932680ecdeab4c216ce7c0736093d3dcd2f60f6dDaniel Dunbar} 633