AnalysisConsumer.cpp revision 5f83d6f36a7308eef21d87104fd70c421e854448
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"
2321142581d55918beed544a757e4af3bb865b1812Ted Kremenek#include "clang/StaticAnalyzer/Checkers/LocalCheckers.h"
249b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
259b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
269b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
279b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
289b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/TransferFuncs.h"
299b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathDiagnosticClients.h"
30a7af5ea88a6c5bdf87497cca6c20831e8c546751Argyrios Kyrtzidis
31a7af5ea88a6c5bdf87497cca6c20831e8c546751Argyrios Kyrtzidis// FIXME: Restructure checker registration.
32e817771c57d0eacbe069a314ba619c43d0ac70abArgyrios Kyrtzidis#include "../Checkers/ExperimentalChecks.h"
33e817771c57d0eacbe069a314ba619c43d0ac70abArgyrios Kyrtzidis#include "../Checkers/InternalChecks.h"
34a7af5ea88a6c5bdf87497cca6c20831e8c546751Argyrios Kyrtzidis
35efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar#include "clang/Basic/FileManager.h"
36efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar#include "clang/Basic/SourceManager.h"
379b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#include "clang/Frontend/AnalyzerOptions.h"
38efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar#include "clang/Lex/Preprocessor.h"
39f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek#include "llvm/Support/raw_ostream.h"
4003013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Path.h"
4103013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Program.h"
426cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer#include "llvm/ADT/OwningPtr.h"
43db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek
44f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenekusing namespace clang;
459ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento;
46f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
47c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xustatic ExplodedNode::Auditor* CreateUbiViz();
48ff944a8c481d6c0f1ad2633e4be9bf8b1dd2a09fZhongxing Xu
49be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek//===----------------------------------------------------------------------===//
50f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek// Special PathDiagnosticClients.
51f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek//===----------------------------------------------------------------------===//
52f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek
53f75560670bcdd59b051149bdece3eac14e313853Ted Kremenekstatic PathDiagnosticClient*
54f928dca56542cf8f981a684f090d2c79bdcb2a10Argyrios KyrtzidiscreatePlistHTMLDiagnosticClient(const std::string& prefix,
55efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar                                const Preprocessor &PP) {
56d5b08bee799d4f77f1a25fa5977ca77b983ab031Michael J. Spencer  PathDiagnosticClient *PD =
57d5b08bee799d4f77f1a25fa5977ca77b983ab031Michael J. Spencer    createHTMLDiagnosticClient(llvm::sys::path::parent_path(prefix), PP);
58f928dca56542cf8f981a684f090d2c79bdcb2a10Argyrios Kyrtzidis  return createPlistDiagnosticClient(prefix, PP, PD);
59f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek}
60f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek
61f75560670bcdd59b051149bdece3eac14e313853Ted Kremenek//===----------------------------------------------------------------------===//
62f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// AnalysisConsumer declaration.
63f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
64f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
65f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremeneknamespace {
66f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
67ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xuclass AnalysisConsumer : public ASTConsumer {
68ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xupublic:
696490ae5003226cae28f980648948bea8b21a8638Douglas Gregor  typedef void (*CodeAction)(AnalysisConsumer &C, AnalysisManager &M, Decl *D);
70f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek  typedef void (*TUAction)(AnalysisConsumer &C, AnalysisManager &M,
71f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek                           TranslationUnitDecl &TU);
72f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
73ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xuprivate:
741d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  typedef std::vector<CodeAction> Actions;
75f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek  typedef std::vector<TUAction> TUActions;
76f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
771d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  Actions FunctionActions;
781d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  Actions ObjCMethodActions;
791d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  Actions ObjCImplementationActions;
80ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu  Actions CXXMethodActions;
81ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu  TUActions TranslationUnitActions; // Remove this.
821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
831d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekpublic:
841d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  ASTContext* Ctx;
851d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  const Preprocessor &PP;
861d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  const std::string OutDir;
871d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  AnalyzerOptions Opts;
88d07a0d0279c09d1017f8450fce575a94dc9703c0Zhongxing Xu
891d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  // PD is owned by AnalysisManager.
901d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  PathDiagnosticClient *PD;
91d07a0d0279c09d1017f8450fce575a94dc9703c0Zhongxing Xu
921d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  StoreManagerCreator CreateStoreMgr;
931d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  ConstraintManagerCreator CreateConstraintMgr;
94f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
951d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  llvm::OwningPtr<AnalysisManager> Mgr;
96c471e7b44e63ff1b46b480e723c4130aeaef5a8aZhongxing Xu
971d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  AnalysisConsumer(const Preprocessor& pp,
981d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                   const std::string& outdir,
991d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                   const AnalyzerOptions& opts)
1001d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    : Ctx(0), PP(pp), OutDir(outdir),
101c4a1437c15da43eb8d2601cdce13161ef41a4389Ted Kremenek      Opts(opts), PD(0) {
1021d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    DigestAnalyzerOptions();
1031d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  }
104fda7832b000ff8927386f093b52c067641679469Zhongxing Xu
1051d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  void DigestAnalyzerOptions() {
1061d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    // Create the PathDiagnosticClient.
1071d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    if (!OutDir.empty()) {
1081d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek      switch (Opts.AnalysisDiagOpt) {
1091d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek      default:
110fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE) \
1111d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek        case PD_##NAME: PD = CREATEFN(OutDir, PP); break;
112fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#include "clang/Frontend/Analyses.def"
113fda7832b000ff8927386f093b52c067641679469Zhongxing Xu      }
114a599ae8826b01c0160a519b0fc5a4871f599bf04Argyrios Kyrtzidis    } else if (Opts.AnalysisDiagOpt == PD_TEXT) {
115a599ae8826b01c0160a519b0fc5a4871f599bf04Argyrios Kyrtzidis      // Create the text client even without a specified output file since
116a599ae8826b01c0160a519b0fc5a4871f599bf04Argyrios Kyrtzidis      // it just uses diagnostic notes.
117a599ae8826b01c0160a519b0fc5a4871f599bf04Argyrios Kyrtzidis      PD = createTextPathDiagnosticClient("", PP);
1181d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    }
119fda7832b000ff8927386f093b52c067641679469Zhongxing Xu
1201d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    // Create the analyzer component creators.
1215f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis    switch (Opts.AnalysisStoreOpt) {
1225f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis    default:
1235f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis      assert(0 && "Unknown store manager.");
124fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATEFN)           \
1255f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis      case NAME##Model: CreateStoreMgr = CREATEFN; break;
126fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#include "clang/Frontend/Analyses.def"
1271d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    }
1281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1295f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis    switch (Opts.AnalysisConstraintsOpt) {
1305f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis    default:
1315f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis      assert(0 && "Unknown store manager.");
132fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATEFN)     \
1335f83d6f36a7308eef21d87104fd70c421e854448Argyrios Kyrtzidis      case NAME##Model: CreateConstraintMgr = CREATEFN; break;
134fda7832b000ff8927386f093b52c067641679469Zhongxing Xu#include "clang/Frontend/Analyses.def"
135fda7832b000ff8927386f093b52c067641679469Zhongxing Xu    }
1361d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  }
137f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
1381d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  void DisplayFunction(const Decl *D) {
139c4a1437c15da43eb8d2601cdce13161ef41a4389Ted Kremenek    if (!Opts.AnalyzerDisplayProgress)
1401d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek      return;
141f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
142fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek    SourceManager &SM = Mgr->getASTContext().getSourceManager();
143fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek    PresumedLoc Loc = SM.getPresumedLoc(D->getLocation());
144cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor    if (Loc.isValid()) {
145cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      llvm::errs() << "ANALYZE: " << Loc.getFilename();
146fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek
147cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
148cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor        const NamedDecl *ND = cast<NamedDecl>(D);
149cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor        llvm::errs() << ' ' << ND << '\n';
150cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      }
151cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      else if (isa<BlockDecl>(D)) {
152cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor        llvm::errs() << ' ' << "block(line:" << Loc.getLine() << ",col:"
153cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor                     << Loc.getColumn() << '\n';
154cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      }
155cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
156cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor        Selector S = MD->getSelector();
157cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor        llvm::errs() << ' ' << S.getAsString();
158cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      }
15935fa76d0bb6fb8c86159a7506efd094a4fe376d2Ted Kremenek    }
1601d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  }
1611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1621d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  void addCodeAction(CodeAction action) {
1631d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    FunctionActions.push_back(action);
1641d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    ObjCMethodActions.push_back(action);
165ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu    CXXMethodActions.push_back(action);
1661d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  }
1671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
168f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek  void addTranslationUnitAction(TUAction action) {
1691d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    TranslationUnitActions.push_back(action);
1701d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  }
1711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
172ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu  void addObjCImplementationAction(CodeAction action) {
173ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu    ObjCImplementationActions.push_back(action);
174ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu  }
175ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu
1761d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  virtual void Initialize(ASTContext &Context) {
1771d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    Ctx = &Context;
1781d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    Mgr.reset(new AnalysisManager(*Ctx, PP.getDiagnostics(),
1791d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                  PP.getLangOptions(), PD,
1801d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                  CreateStoreMgr, CreateConstraintMgr,
181c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu                                  /* Indexer */ 0,
1826362b893731ccf4480a96527db9e55e04b801503Zhongxing Xu                                  Opts.MaxNodes, Opts.MaxLoop,
1831d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                  Opts.VisualizeEGDot, Opts.VisualizeEGUbi,
1841d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                  Opts.PurgeDead, Opts.EagerlyAssume,
1859b823e8e1ccb8a2cb49923bad22a80ca96f41f92Ted Kremenek                                  Opts.TrimGraph, Opts.InlineCall,
1869121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski                                  Opts.UnoptimizedCFG, Opts.CFGAddImplicitDtors,
187d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek                                  Opts.CFGAddInitializers,
188d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek                                  Opts.EagerlyTrimEGraph));
1891d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  }
1901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1911d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  virtual void HandleTranslationUnit(ASTContext &C);
19214cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek  void HandleDeclContext(ASTContext &C, DeclContext *dc);
19314cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek
19406a54a38be5054c910ffc92db60edab23f9ea105Argyrios Kyrtzidis  void HandleCode(Decl *D, Actions& actions);
1951d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek};
196f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek} // end anonymous namespace
197f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
198f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
199f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// AnalysisConsumer implementation.
200f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
201f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
20214cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenekvoid AnalysisConsumer::HandleDeclContext(ASTContext &C, DeclContext *dc) {
20314cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek  for (DeclContext::decl_iterator I = dc->decls_begin(), E = dc->decls_end();
204ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu       I != E; ++I) {
205ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu    Decl *D = *I;
20614cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek
207ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu    switch (D->getKind()) {
20814cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek      case Decl::Namespace: {
20914cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        HandleDeclContext(C, cast<NamespaceDecl>(D));
21014cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        break;
211ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu      }
21214cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek      case Decl::CXXConstructor:
21314cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek      case Decl::CXXDestructor:
21414cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek      case Decl::CXXConversion:
21514cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek      case Decl::CXXMethod:
21614cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek      case Decl::Function: {
21714cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        FunctionDecl* FD = cast<FunctionDecl>(D);
21814cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        // We skip function template definitions, as their semantics is
21914cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        // only determined when they are instantiated.
22014cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        if (FD->isThisDeclarationADefinition() &&
22114cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek            !FD->isDependentContext()) {
222ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu          if (!Opts.AnalyzeSpecificFunction.empty() &&
22314cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek              FD->getDeclName().getAsString() != Opts.AnalyzeSpecificFunction)
224ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu            break;
22514cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek          DisplayFunction(FD);
22614cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek          HandleCode(FD, FunctionActions);
227ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu        }
22814cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        break;
229ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu      }
23014cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek
23114cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek      case Decl::ObjCImplementation: {
23214cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        ObjCImplementationDecl* ID = cast<ObjCImplementationDecl>(*I);
23314cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        HandleCode(ID, ObjCImplementationActions);
23414cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek
23514cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        for (ObjCImplementationDecl::method_iterator MI = ID->meth_begin(),
23614cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek             ME = ID->meth_end(); MI != ME; ++MI) {
23714cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek          if ((*MI)->isThisDeclarationADefinition()) {
23814cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek            if (!Opts.AnalyzeSpecificFunction.empty() &&
23914cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek                Opts.AnalyzeSpecificFunction != (*MI)->getSelector().getAsString())
24014cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek              break;
24114cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek            DisplayFunction(*MI);
24214cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek            HandleCode(*MI, ObjCMethodActions);
24314cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek          }
24414cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        }
24514cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        break;
24614cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek      }
24714cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek
24814cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek      default:
24914cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek        break;
250ed8afacb8118b71bcfa8017059e51da325e7691bZhongxing Xu    }
25114cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek  }
25214cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek}
253f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
25414cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenekvoid AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
25514cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek  TranslationUnitDecl *TU = C.getTranslationUnitDecl();
25614cc9451de4a9539bf79e4e5d63248c2377426dbTed Kremenek  HandleDeclContext(C, TU);
257b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu
258f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek  for (TUActions::iterator I = TranslationUnitActions.begin(),
259f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek                           E = TranslationUnitActions.end(); I != E; ++I) {
260f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek    (*I)(*this, *Mgr, *TU);
261daac634c9744257d43ce892b973019b16468caf2Ted Kremenek  }
262daac634c9744257d43ce892b973019b16468caf2Ted Kremenek
263690a7f431d6863a101711e67636d51ddd13f35c5Ted Kremenek  // Explicitly destroy the PathDiagnosticClient.  This will flush its output.
264690a7f431d6863a101711e67636d51ddd13f35c5Ted Kremenek  // FIXME: This should be replaced with something that doesn't rely on
265da17fd50ad485fd2a1fc5c2f055caacf532992daZhongxing Xu  // side-effects in PathDiagnosticClient's destructor. This is required when
266da17fd50ad485fd2a1fc5c2f055caacf532992daZhongxing Xu  // used with option -disable-free.
267d07a0d0279c09d1017f8450fce575a94dc9703c0Zhongxing Xu  Mgr.reset(NULL);
268db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek}
269db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek
270fc576514d06c46a7cac49500169411d82f38d04bTed Kremenekstatic void FindBlocks(DeclContext *D, llvm::SmallVectorImpl<Decl*> &WL) {
271fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek  if (BlockDecl *BD = dyn_cast<BlockDecl>(D))
272fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek    WL.push_back(BD);
273f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
274fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek  for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
275fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek       I!=E; ++I)
276fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek    if (DeclContext *DC = dyn_cast<DeclContext>(*I))
277fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek      FindBlocks(DC, WL);
278fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek}
279fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek
28006a54a38be5054c910ffc92db60edab23f9ea105Argyrios Kyrtzidisvoid AnalysisConsumer::HandleCode(Decl *D, Actions& actions) {
2811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
282f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  // Don't run the actions if an error has occured with parsing the file.
28399e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek  Diagnostic &Diags = PP.getDiagnostics();
28499e8192c4c8f1f596f9969e5f2cdafcee64ddaacTed Kremenek  if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred())
285f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek    return;
28681922f01352aceeb923c0c3cc8c96b6527322384Ted Kremenek
287f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  // Don't run the actions on declarations in header files unless
288f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  // otherwise specified.
289fcd783d583d270b7ec1ec3e0fcf83cd93d30e381Ted Kremenek  SourceManager &SM = Ctx->getSourceManager();
290fcd783d583d270b7ec1ec3e0fcf83cd93d30e381Ted Kremenek  SourceLocation SL = SM.getInstantiationLoc(D->getLocation());
291fcd783d583d270b7ec1ec3e0fcf83cd93d30e381Ted Kremenek  if (!Opts.AnalyzeAll && !SM.isFromMainFile(SL))
2921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return;
293f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
29458f5ec7d56b1ebf5f90ee11226ebe7663f2821eaTed Kremenek  // Clear the AnalysisManager of old AnalysisContexts.
29558f5ec7d56b1ebf5f90ee11226ebe7663f2821eaTed Kremenek  Mgr->ClearContexts();
296f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
2971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Dispatch on the actions.
298fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek  llvm::SmallVector<Decl*, 10> WL;
299fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek  WL.push_back(D);
300f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
30106a54a38be5054c910ffc92db60edab23f9ea105Argyrios Kyrtzidis  if (D->hasBody() && Opts.AnalyzeNestedBlocks)
302fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek    FindBlocks(cast<DeclContext>(D), WL);
303f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
3043702af57e399448efa8e2bfd600f009945b5c936Zhongxing Xu  for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I)
305fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek    for (llvm::SmallVectorImpl<Decl*>::iterator WI=WL.begin(), WE=WL.end();
306fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek         WI != WE; ++WI)
307fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek      (*I)(*this, *Mgr, *WI);
308f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek}
309f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
310f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
311f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// Analyses
312f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
313f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
3141d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionWarnDeadStores(AnalysisConsumer &C, AnalysisManager& mgr,
3151d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                 Decl *D) {
316b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu  if (LiveVariables *L = mgr.getLiveVariables(D)) {
3177032f460fc9828f386056e75933da5af61e88638Ted Kremenek    BugReporter BR(mgr);
318b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu    CheckDeadStores(*mgr.getCFG(D), *L, mgr.getParentMap(D), BR);
3197032f460fc9828f386056e75933da5af61e88638Ted Kremenek  }
320f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek}
321f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
3221d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionWarnUninitVals(AnalysisConsumer &C, AnalysisManager& mgr,
3231d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                 Decl *D) {
3241d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  if (CFG* c = mgr.getCFG(D)) {
3255032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu    CheckUninitializedValues(*c, mgr.getASTContext(), mgr.getDiagnostic());
3261d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  }
327f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek}
328f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
329b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek
330d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisstatic void ActionExprEngine(AnalysisConsumer &C, AnalysisManager& mgr,
331f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek                               Decl *D,
332d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis                               TransferFuncs* tf) {
3331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
334d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  llvm::OwningPtr<TransferFuncs> TF(tf);
3357032f460fc9828f386056e75933da5af61e88638Ted Kremenek
33675d03cffe20b5c945ef04eba208efb0437339997Ted Kremenek  // Construct the analysis engine.  We first query for the LiveVariables
33775d03cffe20b5c945ef04eba208efb0437339997Ted Kremenek  // information to see if the CFG is valid.
33875d03cffe20b5c945ef04eba208efb0437339997Ted Kremenek  // FIXME: Inter-procedural analysis will need to handle invalid CFGs.
33975d03cffe20b5c945ef04eba208efb0437339997Ted Kremenek  if (!mgr.getLiveVariables(D))
340f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek    return;
341d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  ExprEngine Eng(mgr, TF.take());
342f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
3438382cf57b722f130f1a6b45380639871c07271c1Ted Kremenek  if (C.Opts.EnableExperimentalInternalChecks)
3448382cf57b722f130f1a6b45380639871c07271c1Ted Kremenek    RegisterExperimentalInternalChecks(Eng);
345f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
3466a19832d08f00ac78c0a69c4fbe38b04a55b75ccTed Kremenek  RegisterAppleChecks(Eng, *D);
347f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
348eb94113be0ee5f4d38408b413d92464a0bc16b55Ted Kremenek  if (C.Opts.EnableExperimentalChecks)
349eb94113be0ee5f4d38408b413d92464a0bc16b55Ted Kremenek    RegisterExperimentalChecks(Eng);
350f6eafcca7734274d277afa121f2c4fb025a54218Ted Kremenek
351bd5a94e263137dc3ce7c100485626bae025cf58eArgyrios Kyrtzidis  if (C.Opts.ObjCSelfInitCheck && isa<ObjCMethodDecl>(D))
352bd5a94e263137dc3ce7c100485626bae025cf58eArgyrios Kyrtzidis    registerObjCSelfInitChecker(Eng);
353bd5a94e263137dc3ce7c100485626bae025cf58eArgyrios Kyrtzidis
3541fafd1d96419f587763d1b81332d8f476aeace2eTom Care  // Enable idempotent operation checking if it was explicitly turned on, or if
3551fafd1d96419f587763d1b81332d8f476aeace2eTom Care  // we are running experimental checks (i.e. everything)
3561fafd1d96419f587763d1b81332d8f476aeace2eTom Care  if (C.Opts.IdempotentOps || C.Opts.EnableExperimentalChecks
3571fafd1d96419f587763d1b81332d8f476aeace2eTom Care      || C.Opts.EnableExperimentalInternalChecks)
3581fafd1d96419f587763d1b81332d8f476aeace2eTom Care    RegisterIdempotentOperationChecker(Eng);
359c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek
360c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  if (C.Opts.BufferOverflows)
361c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek    RegisterArrayBoundCheckerV2(Eng);
3621fafd1d96419f587763d1b81332d8f476aeace2eTom Care
36352d861ce41ce84d8389495ea78d97bcc962ac5baTom Care  // Enable AnalyzerStatsChecker if it was given as an argument
36452d861ce41ce84d8389495ea78d97bcc962ac5baTom Care  if (C.Opts.AnalyzerStats)
36552d861ce41ce84d8389495ea78d97bcc962ac5baTom Care    RegisterAnalyzerStatsChecker(Eng);
36652d861ce41ce84d8389495ea78d97bcc962ac5baTom Care
367f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  // Set the graph auditor.
368c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  llvm::OwningPtr<ExplodedNode::Auditor> Auditor;
369f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  if (mgr.shouldVisualizeUbigraph()) {
370f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    Auditor.reset(CreateUbiViz());
371c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    ExplodedNode::SetAuditor(Auditor.get());
372f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  }
3731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
374b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  // Execute the worklist algorithm.
375c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu  Eng.ExecuteWorkList(mgr.getStackFrame(D, 0), mgr.getMaxNodes());
3761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
377f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  // Release the auditor (if any) so that it doesn't monitor the graph
378f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  // created BugReporter.
379c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  ExplodedNode::SetAuditor(0);
3803df6421150271266b5a90fd4c6bfa6566c38c036Ted Kremenek
38134d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  // Visualize the exploded graph.
382f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  if (mgr.shouldVisualizeGraphviz())
38334d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek    Eng.ViewGraph(mgr.shouldTrimGraph());
3841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3853df6421150271266b5a90fd4c6bfa6566c38c036Ted Kremenek  // Display warnings.
3863df6421150271266b5a90fd4c6bfa6566c38c036Ted Kremenek  Eng.getBugReporter().FlushReports();
387bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek}
388bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek
389565e465c6d0093f1bf8414b2cabdc842022385a9Ted Kremenekstatic void ActionObjCMemCheckerAux(AnalysisConsumer &C, AnalysisManager& mgr,
3901d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                  Decl *D, bool GCEnabled) {
3911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
392d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  TransferFuncs* TF = MakeCFRefCountTF(mgr.getASTContext(),
393bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek                                         GCEnabled,
394bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek                                         mgr.getLangOptions());
3951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
396d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  ActionExprEngine(C, mgr, D, TF);
397b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek}
398b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek
399565e465c6d0093f1bf8414b2cabdc842022385a9Ted Kremenekstatic void ActionObjCMemChecker(AnalysisConsumer &C, AnalysisManager& mgr,
4001d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                               Decl *D) {
4011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
402b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek switch (mgr.getLangOptions().getGCMode()) {
403b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump default:
404b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump   assert (false && "Invalid GC mode.");
405b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump case LangOptions::NonGC:
406565e465c6d0093f1bf8414b2cabdc842022385a9Ted Kremenek   ActionObjCMemCheckerAux(C, mgr, D, false);
407b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump   break;
408b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump
409b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump case LangOptions::GCOnly:
410565e465c6d0093f1bf8414b2cabdc842022385a9Ted Kremenek   ActionObjCMemCheckerAux(C, mgr, D, true);
411b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump   break;
412b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump
413b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump case LangOptions::HybridGC:
414565e465c6d0093f1bf8414b2cabdc842022385a9Ted Kremenek   ActionObjCMemCheckerAux(C, mgr, D, false);
415565e465c6d0093f1bf8414b2cabdc842022385a9Ted Kremenek   ActionObjCMemCheckerAux(C, mgr, D, true);
416b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump   break;
417b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek }
418b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek}
419b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek
4201d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionDisplayLiveVariables(AnalysisConsumer &C,
4211d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                       AnalysisManager& mgr, Decl *D) {
422b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu  if (LiveVariables* L = mgr.getLiveVariables(D)) {
4237032f460fc9828f386056e75933da5af61e88638Ted Kremenek    L->dumpBlockLiveness(mgr.getSourceManager());
4247032f460fc9828f386056e75933da5af61e88638Ted Kremenek  }
425235e031e84dd9d9aeee554db40e480f14650b527Ted Kremenek}
426235e031e84dd9d9aeee554db40e480f14650b527Ted Kremenek
4271d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionCFGDump(AnalysisConsumer &C, AnalysisManager& mgr, Decl *D) {
4281d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  if (CFG *cfg = mgr.getCFG(D)) {
4291d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    cfg->dump(mgr.getLangOptions());
4307032f460fc9828f386056e75933da5af61e88638Ted Kremenek  }
431902141f74ac3a2cd41966a98cd43e8702bc05ce9Ted Kremenek}
432902141f74ac3a2cd41966a98cd43e8702bc05ce9Ted Kremenek
4331d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionCFGView(AnalysisConsumer &C, AnalysisManager& mgr, Decl *D) {
4341d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  if (CFG *cfg = mgr.getCFG(D)) {
4351d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek    cfg->viewCFG(mgr.getLangOptions());
4367032f460fc9828f386056e75933da5af61e88638Ted Kremenek  }
437902141f74ac3a2cd41966a98cd43e8702bc05ce9Ted Kremenek}
438902141f74ac3a2cd41966a98cd43e8702bc05ce9Ted Kremenek
4391d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionSecuritySyntacticChecks(AnalysisConsumer &C,
4401d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                          AnalysisManager &mgr, Decl *D) {
4411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  BugReporter BR(mgr);
442b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu  CheckSecuritySyntaxOnly(D, BR);
443dbfb5f853547c4cc2b4b39e90f01537dd317457aTed Kremenek}
444dbfb5f853547c4cc2b4b39e90f01537dd317457aTed Kremenek
4456dd66ed959b7f60749dd0040507b3f304183a1b6Ted Kremenekstatic void ActionLLVMConventionChecker(AnalysisConsumer &C,
4466dd66ed959b7f60749dd0040507b3f304183a1b6Ted Kremenek                                        AnalysisManager &mgr,
447676ca153e04b1c6be477bc8a10f1e06256850ceeTed Kremenek                                        TranslationUnitDecl &TU) {
4486dd66ed959b7f60749dd0040507b3f304183a1b6Ted Kremenek  BugReporter BR(mgr);
449676ca153e04b1c6be477bc8a10f1e06256850ceeTed Kremenek  CheckLLVMConventions(TU, BR);
4506dd66ed959b7f60749dd0040507b3f304183a1b6Ted Kremenek}
4516dd66ed959b7f60749dd0040507b3f304183a1b6Ted Kremenek
4521d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionWarnObjCDealloc(AnalysisConsumer &C, AnalysisManager& mgr,
4531d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                  Decl *D) {
4544f4e7e4610f7a6eb8923a3bf6f2951b2dca98608Ted Kremenek  if (mgr.getLangOptions().getGCMode() == LangOptions::GCOnly)
4554f4e7e4610f7a6eb8923a3bf6f2951b2dca98608Ted Kremenek    return;
456db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek  BugReporter BR(mgr);
4571d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  CheckObjCDealloc(cast<ObjCImplementationDecl>(D), mgr.getLangOptions(), BR);
458db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek}
459db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek
4601d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionWarnObjCUnusedIvars(AnalysisConsumer &C, AnalysisManager& mgr,
4611d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                      Decl *D) {
462395aaf20d6e1ab04741562dc6b7d47164bcbd87eTed Kremenek  BugReporter BR(mgr);
4631d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek  CheckObjCUnusedIvar(cast<ObjCImplementationDecl>(D), BR);
464395aaf20d6e1ab04741562dc6b7d47164bcbd87eTed Kremenek}
465395aaf20d6e1ab04741562dc6b7d47164bcbd87eTed Kremenek
4661d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionWarnObjCMethSigs(AnalysisConsumer &C, AnalysisManager& mgr,
4671d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                   Decl *D) {
4680d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek  BugReporter BR(mgr);
469b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu  CheckObjCInstMethSignature(cast<ObjCImplementationDecl>(D), BR);
4700d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek}
4710d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek
4721d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenekstatic void ActionWarnSizeofPointer(AnalysisConsumer &C, AnalysisManager &mgr,
4731d9cbeb76cf4c36acf5545028e2b2ac207086442Ted Kremenek                                    Decl *D) {
47428a109f63506d8c96e3fbf1b959b603ccec2f586Zhongxing Xu  BugReporter BR(mgr);
47528a109f63506d8c96e3fbf1b959b603ccec2f586Zhongxing Xu  CheckSizeofPointer(D, BR);
47628a109f63506d8c96e3fbf1b959b603ccec2f586Zhongxing Xu}
47728a109f63506d8c96e3fbf1b959b603ccec2f586Zhongxing Xu
478f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
479f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// AnalysisConsumer creation.
480f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek//===----------------------------------------------------------------------===//
481f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
4829ef6537a894c33003359b1f9b9676e9178e028b7Ted KremenekASTConsumer* ento::CreateAnalysisConsumer(const Preprocessor& pp,
483e71b85feb0a2df9273b1b488f5b40279369a6255Eli Friedman                                           const std::string& OutDir,
484e71b85feb0a2df9273b1b488f5b40279369a6255Eli Friedman                                           const AnalyzerOptions& Opts) {
485efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar  llvm::OwningPtr<AnalysisConsumer> C(new AnalysisConsumer(pp, OutDir, Opts));
486be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek
487e71b85feb0a2df9273b1b488f5b40279369a6255Eli Friedman  for (unsigned i = 0; i < Opts.AnalysisList.size(); ++i)
488e71b85feb0a2df9273b1b488f5b40279369a6255Eli Friedman    switch (Opts.AnalysisList[i]) {
489f7f3c20a5d4c5bd1857a6cea1f001bb775401e96Ted Kremenek#define ANALYSIS(NAME, CMD, DESC, SCOPE)\
490b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump    case NAME:\
491b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump      C->add ## SCOPE ## Action(&Action ## NAME);\
492b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump      break;
4934df2c42581280bb1a02a5d034dbf657514cc56e8Eli Friedman#include "clang/Frontend/Analyses.def"
494b7166334d897e1e4e6a5b428fe2d0ec752ef187fMike Stump    default: break;
495f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek    }
4961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4972c4036eda90fad6d219d9f3fadbd9288fa197e89Ted Kremenek  // Last, disable the effects of '-Werror' when using the AnalysisConsumer.
498efceabd2380f49306bc0229583458e93b062094bDaniel Dunbar  pp.getDiagnostics().setWarningsAsErrors(false);
499be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek
500f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  return C.take();
501f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek}
502f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
503f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek//===----------------------------------------------------------------------===//
504f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek// Ubigraph Visualization.  FIXME: Move to separate file.
505f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek//===----------------------------------------------------------------------===//
506f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
507f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremeneknamespace {
5081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
509c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xuclass UbigraphViz : public ExplodedNode::Auditor {
510f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  llvm::OwningPtr<llvm::raw_ostream> Out;
511710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  llvm::sys::Path Dir, Filename;
512f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  unsigned Cntr;
513f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
514f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  typedef llvm::DenseMap<void*,unsigned> VMap;
515f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  VMap M;
5161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
517f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenekpublic:
518710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  UbigraphViz(llvm::raw_ostream* out, llvm::sys::Path& dir,
51956b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek              llvm::sys::Path& filename);
5201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
521710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  ~UbigraphViz();
5221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual void AddEdge(ExplodedNode* Src, ExplodedNode* Dst);
524f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek};
5251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
526f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek} // end anonymous namespace
527f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
528c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xustatic ExplodedNode::Auditor* CreateUbiViz() {
529f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  std::string ErrMsg;
5301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
531710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  llvm::sys::Path Dir = llvm::sys::Path::GetTemporaryDirectory(&ErrMsg);
532f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  if (!ErrMsg.empty())
533f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    return 0;
534f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
535710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  llvm::sys::Path Filename = Dir;
536f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  Filename.appendComponent("llvm_ubi");
537f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  Filename.makeUnique(true,&ErrMsg);
538f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
539f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  if (!ErrMsg.empty())
540f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    return 0;
541f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
542d57a7ef9252964bc6c8471451d7bd395b0520cb8Chris Lattner  llvm::errs() << "Writing '" << Filename.str() << "'.\n";
5431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
544f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  llvm::OwningPtr<llvm::raw_fd_ostream> Stream;
545b044c473a155b7e827680635c1699cb2b5b6c0eeDan Gohman  Stream.reset(new llvm::raw_fd_ostream(Filename.c_str(), ErrMsg));
546f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
547f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  if (!ErrMsg.empty())
548f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    return 0;
5491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
550710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  return new UbigraphViz(Stream.take(), Dir, Filename);
551f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek}
552f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
553c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xuvoid UbigraphViz::AddEdge(ExplodedNode* Src, ExplodedNode* Dst) {
5541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
55545479c88c8a44c55d27c3bd855273bb318082f37Ted Kremenek  assert (Src != Dst && "Self-edges are not allowed.");
5561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
557f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  // Lookup the Src.  If it is a new node, it's a root.
558f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  VMap::iterator SrcI= M.find(Src);
559f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  unsigned SrcID;
5601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
561f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  if (SrcI == M.end()) {
562f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    M[Src] = SrcID = Cntr++;
563f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    *Out << "('vertex', " << SrcID << ", ('color','#00ff00'))\n";
564f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  }
565f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  else
566f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    SrcID = SrcI->second;
5671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
568f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  // Lookup the Dst.
569f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  VMap::iterator DstI= M.find(Dst);
570f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  unsigned DstID;
571f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
572f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  if (DstI == M.end()) {
573f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    M[Dst] = DstID = Cntr++;
574f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    *Out << "('vertex', " << DstID << ")\n";
575f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  }
57656b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek  else {
57756b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek    // We have hit DstID before.  Change its style to reflect a cache hit.
578f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek    DstID = DstI->second;
57956b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek    *Out << "('change_vertex_style', " << DstID << ", 1)\n";
58056b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek  }
581f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
582f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek  // Add the edge.
5831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  *Out << "('edge', " << SrcID << ", " << DstID
584d1289327f7d2126d732e23cc189ecd0aa5d07cbbTed Kremenek       << ", ('arrow','true'), ('oriented', 'true'))\n";
585f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek}
586f8ce6991f41d55b6e8526b7a7919771428e2b181Ted Kremenek
58756b98719b0dbebb33cb228afa888c47156be2381Ted KremenekUbigraphViz::UbigraphViz(llvm::raw_ostream* out, llvm::sys::Path& dir,
58856b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek                         llvm::sys::Path& filename)
58956b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek  : Out(out), Dir(dir), Filename(filename), Cntr(0) {
59056b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek
59156b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek  *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n";
59256b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek  *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66'),"
59356b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek          " ('size', '1.5'))\n";
59456b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek}
59556b98719b0dbebb33cb228afa888c47156be2381Ted Kremenek
596710ad9343f32b33b336369b20edad1a21a0b3299Ted KremenekUbigraphViz::~UbigraphViz() {
597710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  Out.reset(0);
5986cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer  llvm::errs() << "Running 'ubiviz' program... ";
599710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  std::string ErrMsg;
600710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  llvm::sys::Path Ubiviz = llvm::sys::Program::FindProgramByName("ubiviz");
601710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  std::vector<const char*> args;
602710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  args.push_back(Ubiviz.c_str());
603710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  args.push_back(Filename.c_str());
604710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  args.push_back(0);
6051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
606710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  if (llvm::sys::Program::ExecuteAndWait(Ubiviz, &args[0],0,0,0,0,&ErrMsg)) {
6076cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer    llvm::errs() << "Error viewing graph: " << ErrMsg << "\n";
608710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  }
6091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
610710ad9343f32b33b336369b20edad1a21a0b3299Ted Kremenek  // Delete the directory.
6111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Dir.eraseFromDisk(true);
612932680ecdeab4c216ce7c0736093d3dcd2f60f6dDaniel Dunbar}
613