AnalysisDeclContext.cpp revision 471c8b49982d1132f30b0b0da27fef94fd6e4f67
11d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek//== AnalysisDeclContext.cpp - Analysis context for Path Sens analysis -*- C++ -*-//
297ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu//
397ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu//                     The LLVM Compiler Infrastructure
497ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu//
597ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu// This file is distributed under the University of Illinois Open Source
697ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu// License. See LICENSE.TXT for details.
797ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu//
897ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu//===----------------------------------------------------------------------===//
997ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu//
101d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek// This file defines AnalysisDeclContext, a class that manages the analysis context
1197ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu// data for path sensitive analysis.
1297ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu//
1397ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu//===----------------------------------------------------------------------===//
1497ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu
15471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer#include "clang/AST/ASTContext.h"
1697ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu#include "clang/AST/Decl.h"
1797ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu#include "clang/AST/DeclObjC.h"
18fa6ef180c0d3609124217387618fbb51bbdd2e48Mike Stump#include "clang/AST/DeclTemplate.h"
1997ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu#include "clang/AST/ParentMap.h"
20b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek#include "clang/AST/StmtVisitor.h"
212cfe28b6a061e72c6c8726d7ecb879093a1ab7a3Ted Kremenek#include "clang/Analysis/Analyses/LiveVariables.h"
22db34ab70961ca4b24b600eb47053d7af304659f5Tom Care#include "clang/Analysis/Analyses/PseudoConstantAnalysis.h"
2342461eecee98fff3671b3c14ce10f1a9e18cc95cTed Kremenek#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
242cfe28b6a061e72c6c8726d7ecb879093a1ab7a3Ted Kremenek#include "clang/Analysis/AnalysisContext.h"
252cfe28b6a061e72c6c8726d7ecb879093a1ab7a3Ted Kremenek#include "clang/Analysis/CFG.h"
26283a358aecb75e30fcd486f2206f6c03c5e7f11dTed Kremenek#include "clang/Analysis/CFGStmtMap.h"
27b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek#include "clang/Analysis/Support/BumpVector.h"
28b2c60b04a597cc5ba4154837cf8e0a155a376fd7Argyrios Kyrtzidis#include "llvm/Support/SaveAndRestore.h"
299b20a90dff2ed605153c68a5c58b6aadcdb0952bBenjamin Kramer#include "llvm/ADT/SmallPtrSet.h"
3087a05f1fe8ae14044f182b015b279e0a6f4cbdd1Mike Stump#include "llvm/Support/ErrorHandling.h"
3197ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu
3297ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xuusing namespace clang;
3397ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu
34a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenektypedef llvm::DenseMap<const void *, ManagedAnalysis *> ManagedAnalysisMap;
35a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek
361d26f48dc2eea1c07431ca1519d7034a21b9bcffTed KremenekAnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
37b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek                                 const Decl *d,
38bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek                                 const CFG::BuildOptions &buildOptions)
39b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek  : Manager(Mgr),
40b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek    D(d),
41bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek    cfgBuildOptions(buildOptions),
42b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek    forcedBlkExprs(0),
43bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek    builtCFG(false),
44bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek    builtCompleteCFG(false),
45a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek    ReferencedBlockVars(0),
46a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek    ManagedAnalyses(0)
47bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek{
48b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek  cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
49bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek}
50bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek
511d26f48dc2eea1c07431ca1519d7034a21b9bcffTed KremenekAnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
52d200187bd27f9ad68699693a6e57f9ee3ff260faJordy Rose                                 const Decl *d)
53b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek: Manager(Mgr),
54b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek  D(d),
55bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek  forcedBlkExprs(0),
56bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek  builtCFG(false),
57bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek  builtCompleteCFG(false),
58a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek  ReferencedBlockVars(0),
59a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek  ManagedAnalyses(0)
60bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek{
61bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek  cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
62bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek}
63bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek
641d26f48dc2eea1c07431ca1519d7034a21b9bcffTed KremenekAnalysisDeclContextManager::AnalysisDeclContextManager(bool useUnoptimizedCFG,
65bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek                                               bool addImplicitDtors,
66bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek                                               bool addInitializers) {
67bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek  cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
68b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek  cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
69b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek  cfgBuildOptions.AddInitializers = addInitializers;
70b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek}
71b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek
721d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenekvoid AnalysisDeclContextManager::clear() {
7358f5ec7d56b1ebf5f90ee11226ebe7663f2821eaTed Kremenek  for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I)
7458f5ec7d56b1ebf5f90ee11226ebe7663f2821eaTed Kremenek    delete I->second;
7558f5ec7d56b1ebf5f90ee11226ebe7663f2821eaTed Kremenek  Contexts.clear();
7658f5ec7d56b1ebf5f90ee11226ebe7663f2821eaTed Kremenek}
7758f5ec7d56b1ebf5f90ee11226ebe7663f2821eaTed Kremenek
781d26f48dc2eea1c07431ca1519d7034a21b9bcffTed KremenekStmt *AnalysisDeclContext::getBody() const {
792376002038c8b904acd20be754aedd1a7471be71Ted Kremenek  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
8097ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu    return FD->getBody();
812376002038c8b904acd20be754aedd1a7471be71Ted Kremenek  else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8297ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu    return MD->getBody();
8330a45344c827a8346f6ecfda56b7811d1e031767Ted Kremenek  else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
8430a45344c827a8346f6ecfda56b7811d1e031767Ted Kremenek    return BD->getBody();
85fa6ef180c0d3609124217387618fbb51bbdd2e48Mike Stump  else if (const FunctionTemplateDecl *FunTmpl
86fa6ef180c0d3609124217387618fbb51bbdd2e48Mike Stump           = dyn_cast_or_null<FunctionTemplateDecl>(D))
87fa6ef180c0d3609124217387618fbb51bbdd2e48Mike Stump    return FunTmpl->getTemplatedDecl()->getBody();
8897ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu
899f61aa9e280adea9fbf3365f0e4f6ed568c9885aJeffrey Yasskin  llvm_unreachable("unknown code decl");
9097ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu}
9197ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu
921d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenekconst ImplicitParamDecl *AnalysisDeclContext::getSelfDecl() const {
9382cd37cf1cccde162d1f13eda6cdfe1398216f36Ted Kremenek  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
9482cd37cf1cccde162d1f13eda6cdfe1398216f36Ted Kremenek    return MD->getSelfDecl();
95ccf1bfde160c03c677ba530c9dcb77365a9c2d7bTed Kremenek  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
96ccf1bfde160c03c677ba530c9dcb77365a9c2d7bTed Kremenek    // See if 'self' was captured by the block.
97ccf1bfde160c03c677ba530c9dcb77365a9c2d7bTed Kremenek    for (BlockDecl::capture_const_iterator it = BD->capture_begin(),
98ccf1bfde160c03c677ba530c9dcb77365a9c2d7bTed Kremenek         et = BD->capture_end(); it != et; ++it) {
99ccf1bfde160c03c677ba530c9dcb77365a9c2d7bTed Kremenek      const VarDecl *VD = it->getVariable();
100ccf1bfde160c03c677ba530c9dcb77365a9c2d7bTed Kremenek      if (VD->getName() == "self")
101ccf1bfde160c03c677ba530c9dcb77365a9c2d7bTed Kremenek        return dyn_cast<ImplicitParamDecl>(VD);
102ccf1bfde160c03c677ba530c9dcb77365a9c2d7bTed Kremenek    }
103ccf1bfde160c03c677ba530c9dcb77365a9c2d7bTed Kremenek  }
1041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10582cd37cf1cccde162d1f13eda6cdfe1398216f36Ted Kremenek  return NULL;
10682cd37cf1cccde162d1f13eda6cdfe1398216f36Ted Kremenek}
10782cd37cf1cccde162d1f13eda6cdfe1398216f36Ted Kremenek
1081d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenekvoid AnalysisDeclContext::registerForcedBlockExpression(const Stmt *stmt) {
1090d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek  if (!forcedBlkExprs)
1100d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek    forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();
1110d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek  // Default construct an entry for 'stmt'.
112ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose  if (const Expr *e = dyn_cast<Expr>(stmt))
113ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose    stmt = e->IgnoreParens();
1140d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek  (void) (*forcedBlkExprs)[stmt];
1150d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek}
1160d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek
1170d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenekconst CFGBlock *
1181d26f48dc2eea1c07431ca1519d7034a21b9bcffTed KremenekAnalysisDeclContext::getBlockForRegisteredExpression(const Stmt *stmt) {
1190d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek  assert(forcedBlkExprs);
120ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose  if (const Expr *e = dyn_cast<Expr>(stmt))
121ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose    stmt = e->IgnoreParens();
1220d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek  CFG::BuildOptions::ForcedBlkExprs::const_iterator itr =
1230d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek    forcedBlkExprs->find(stmt);
1240d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek  assert(itr != forcedBlkExprs->end());
1250d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek  return itr->second;
1260d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek}
1270d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek
1281d26f48dc2eea1c07431ca1519d7034a21b9bcffTed KremenekCFG *AnalysisDeclContext::getCFG() {
129bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek  if (!cfgBuildOptions.PruneTriviallyFalseEdges)
1309b823e8e1ccb8a2cb49923bad22a80ca96f41f92Ted Kremenek    return getUnoptimizedCFG();
1319b823e8e1ccb8a2cb49923bad22a80ca96f41f92Ted Kremenek
132d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek  if (!builtCFG) {
133b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek    cfg.reset(CFG::buildCFG(D, getBody(),
134b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek                            &D->getASTContext(), cfgBuildOptions));
135d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek    // Even when the cfg is not successfully built, we don't
136d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek    // want to try building it again.
137d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek    builtCFG = true;
138d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek  }
139b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek  return cfg.get();
14097ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu}
14197ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu
1421d26f48dc2eea1c07431ca1519d7034a21b9bcffTed KremenekCFG *AnalysisDeclContext::getUnoptimizedCFG() {
143ad5a894df1841698c824381b414630799adc26caTed Kremenek  if (!builtCompleteCFG) {
144bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek    SaveAndRestore<bool> NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges,
145bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek                                  false);
146bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek    completeCFG.reset(CFG::buildCFG(D, getBody(), &D->getASTContext(),
147bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek                                    cfgBuildOptions));
148ad5a894df1841698c824381b414630799adc26caTed Kremenek    // Even when the cfg is not successfully built, we don't
149ad5a894df1841698c824381b414630799adc26caTed Kremenek    // want to try building it again.
150ad5a894df1841698c824381b414630799adc26caTed Kremenek    builtCompleteCFG = true;
151ad5a894df1841698c824381b414630799adc26caTed Kremenek  }
152b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek  return completeCFG.get();
153ad5a894df1841698c824381b414630799adc26caTed Kremenek}
154ad5a894df1841698c824381b414630799adc26caTed Kremenek
1551d26f48dc2eea1c07431ca1519d7034a21b9bcffTed KremenekCFGStmtMap *AnalysisDeclContext::getCFGStmtMap() {
156283a358aecb75e30fcd486f2206f6c03c5e7f11dTed Kremenek  if (cfgStmtMap)
157b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek    return cfgStmtMap.get();
158283a358aecb75e30fcd486f2206f6c03c5e7f11dTed Kremenek
159283a358aecb75e30fcd486f2206f6c03c5e7f11dTed Kremenek  if (CFG *c = getCFG()) {
160b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek    cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
161b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek    return cfgStmtMap.get();
162283a358aecb75e30fcd486f2206f6c03c5e7f11dTed Kremenek  }
163283a358aecb75e30fcd486f2206f6c03c5e7f11dTed Kremenek
164283a358aecb75e30fcd486f2206f6c03c5e7f11dTed Kremenek  return 0;
165283a358aecb75e30fcd486f2206f6c03c5e7f11dTed Kremenek}
16642461eecee98fff3671b3c14ce10f1a9e18cc95cTed Kremenek
1671d26f48dc2eea1c07431ca1519d7034a21b9bcffTed KremenekCFGReverseBlockReachabilityAnalysis *AnalysisDeclContext::getCFGReachablityAnalysis() {
16842461eecee98fff3671b3c14ce10f1a9e18cc95cTed Kremenek  if (CFA)
169b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek    return CFA.get();
17042461eecee98fff3671b3c14ce10f1a9e18cc95cTed Kremenek
17142461eecee98fff3671b3c14ce10f1a9e18cc95cTed Kremenek  if (CFG *c = getCFG()) {
172af13d5b25b360e698cc1cf1055ad7d14e008e505Ted Kremenek    CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
173b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek    return CFA.get();
17442461eecee98fff3671b3c14ce10f1a9e18cc95cTed Kremenek  }
175283a358aecb75e30fcd486f2206f6c03c5e7f11dTed Kremenek
17642461eecee98fff3671b3c14ce10f1a9e18cc95cTed Kremenek  return 0;
17742461eecee98fff3671b3c14ce10f1a9e18cc95cTed Kremenek}
178283a358aecb75e30fcd486f2206f6c03c5e7f11dTed Kremenek
179682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenekvoid AnalysisDeclContext::dumpCFG(bool ShowColors) {
1804e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
18104eeba43040969c05cfcb563195ef5b199297b62Anders Carlsson}
18204eeba43040969c05cfcb563195ef5b199297b62Anders Carlsson
1831d26f48dc2eea1c07431ca1519d7034a21b9bcffTed KremenekParentMap &AnalysisDeclContext::getParentMap() {
1841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (!PM)
185b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek    PM.reset(new ParentMap(getBody()));
18697ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu  return *PM;
18797ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu}
18897ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu
1891d26f48dc2eea1c07431ca1519d7034a21b9bcffTed KremenekPseudoConstantAnalysis *AnalysisDeclContext::getPseudoConstantAnalysis() {
190245adabd97c8c770c13935a9075f2243cc6f1d57Tom Care  if (!PCA)
191b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek    PCA.reset(new PseudoConstantAnalysis(getBody()));
192b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek  return PCA.get();
193245adabd97c8c770c13935a9075f2243cc6f1d57Tom Care}
194245adabd97c8c770c13935a9075f2243cc6f1d57Tom Care
195d200187bd27f9ad68699693a6e57f9ee3ff260faJordy RoseAnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) {
1961d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek  AnalysisDeclContext *&AC = Contexts[D];
1972376002038c8b904acd20be754aedd1a7471be71Ted Kremenek  if (!AC)
198d200187bd27f9ad68699693a6e57f9ee3ff260faJordy Rose    AC = new AnalysisDeclContext(this, D, cfgBuildOptions);
1992376002038c8b904acd20be754aedd1a7471be71Ted Kremenek  return AC;
20097ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu}
20118c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu
202b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenekconst StackFrameContext *
2031d26f48dc2eea1c07431ca1519d7034a21b9bcffTed KremenekAnalysisDeclContext::getStackFrame(LocationContext const *Parent, const Stmt *S,
204b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek                               const CFGBlock *Blk, unsigned Idx) {
205b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek  return getLocationContextManager().getStackFrame(this, Parent, S, Blk, Idx);
206b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek}
207b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek
2087fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenekconst BlockInvocationContext *
2097fa9b4f258636d89342eda28f21a986c8ac353b1Ted KremenekAnalysisDeclContext::getBlockInvocationContext(const LocationContext *parent,
2107fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek                                               const clang::BlockDecl *BD,
2117fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek                                               const void *ContextData) {
2127fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek  return getLocationContextManager().getBlockInvocationContext(this, parent,
2137fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek                                                               BD, ContextData);
2147fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek}
2157fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek
2161d26f48dc2eea1c07431ca1519d7034a21b9bcffTed KremenekLocationContextManager & AnalysisDeclContext::getLocationContextManager() {
217b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek  assert(Manager &&
2181d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek         "Cannot create LocationContexts without an AnalysisDeclContextManager!");
219b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek  return Manager->getLocationContextManager();
220b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek}
221b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek
222dc0d909f0f6684159c8475db1a15967e5613cb27Ted Kremenek//===----------------------------------------------------------------------===//
223dc0d909f0f6684159c8475db1a15967e5613cb27Ted Kremenek// FoldingSet profiling.
224dc0d909f0f6684159c8475db1a15967e5613cb27Ted Kremenek//===----------------------------------------------------------------------===//
225dc0d909f0f6684159c8475db1a15967e5613cb27Ted Kremenek
226dc0d909f0f6684159c8475db1a15967e5613cb27Ted Kremenekvoid LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
227dc0d909f0f6684159c8475db1a15967e5613cb27Ted Kremenek                                    ContextKind ck,
2281d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek                                    AnalysisDeclContext *ctx,
229dc0d909f0f6684159c8475db1a15967e5613cb27Ted Kremenek                                    const LocationContext *parent,
2309c378f705405d37f49795d5e915989de774fe11fTed Kremenek                                    const void *data) {
2310ee4124012950d7bb853438629b8e7652febf183Ted Kremenek  ID.AddInteger(ck);
2320ee4124012950d7bb853438629b8e7652febf183Ted Kremenek  ID.AddPointer(ctx);
2330ee4124012950d7bb853438629b8e7652febf183Ted Kremenek  ID.AddPointer(parent);
234dc0d909f0f6684159c8475db1a15967e5613cb27Ted Kremenek  ID.AddPointer(data);
235dc0d909f0f6684159c8475db1a15967e5613cb27Ted Kremenek}
236dc0d909f0f6684159c8475db1a15967e5613cb27Ted Kremenek
237dc0d909f0f6684159c8475db1a15967e5613cb27Ted Kremenekvoid StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
2381d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek  Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block, Index);
23918c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu}
24018c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu
241dc0d909f0f6684159c8475db1a15967e5613cb27Ted Kremenekvoid ScopeContext::Profile(llvm::FoldingSetNodeID &ID) {
2421d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek  Profile(ID, getAnalysisDeclContext(), getParent(), Enter);
24318c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu}
24418c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu
245dc0d909f0f6684159c8475db1a15967e5613cb27Ted Kremenekvoid BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
2467fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek  Profile(ID, getAnalysisDeclContext(), getParent(), BD, ContextData);
247dc0d909f0f6684159c8475db1a15967e5613cb27Ted Kremenek}
248dc0d909f0f6684159c8475db1a15967e5613cb27Ted Kremenek
249dc0d909f0f6684159c8475db1a15967e5613cb27Ted Kremenek//===----------------------------------------------------------------------===//
2500ee4124012950d7bb853438629b8e7652febf183Ted Kremenek// LocationContext creation.
251dc0d909f0f6684159c8475db1a15967e5613cb27Ted Kremenek//===----------------------------------------------------------------------===//
252dc0d909f0f6684159c8475db1a15967e5613cb27Ted Kremenek
2530ee4124012950d7bb853438629b8e7652febf183Ted Kremenektemplate <typename LOC, typename DATA>
2540ee4124012950d7bb853438629b8e7652febf183Ted Kremenekconst LOC*
2551d26f48dc2eea1c07431ca1519d7034a21b9bcffTed KremenekLocationContextManager::getLocationContext(AnalysisDeclContext *ctx,
2560ee4124012950d7bb853438629b8e7652febf183Ted Kremenek                                           const LocationContext *parent,
2570ee4124012950d7bb853438629b8e7652febf183Ted Kremenek                                           const DATA *d) {
2580ee4124012950d7bb853438629b8e7652febf183Ted Kremenek  llvm::FoldingSetNodeID ID;
2590ee4124012950d7bb853438629b8e7652febf183Ted Kremenek  LOC::Profile(ID, ctx, parent, d);
2600ee4124012950d7bb853438629b8e7652febf183Ted Kremenek  void *InsertPos;
261d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
2620ee4124012950d7bb853438629b8e7652febf183Ted Kremenek  LOC *L = cast_or_null<LOC>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
263d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
2640ee4124012950d7bb853438629b8e7652febf183Ted Kremenek  if (!L) {
2650ee4124012950d7bb853438629b8e7652febf183Ted Kremenek    L = new LOC(ctx, parent, d);
2660ee4124012950d7bb853438629b8e7652febf183Ted Kremenek    Contexts.InsertNode(L, InsertPos);
2670ee4124012950d7bb853438629b8e7652febf183Ted Kremenek  }
2680ee4124012950d7bb853438629b8e7652febf183Ted Kremenek  return L;
26958f5ec7d56b1ebf5f90ee11226ebe7663f2821eaTed Kremenek}
27058f5ec7d56b1ebf5f90ee11226ebe7663f2821eaTed Kremenek
2710ee4124012950d7bb853438629b8e7652febf183Ted Kremenekconst StackFrameContext*
2721d26f48dc2eea1c07431ca1519d7034a21b9bcffTed KremenekLocationContextManager::getStackFrame(AnalysisDeclContext *ctx,
27354c809b19444a01444f36e93d1d28c9a5668484cTed Kremenek                                      const LocationContext *parent,
274892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek                                      const Stmt *s,
275d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu                                      const CFGBlock *blk, unsigned idx) {
27662d399e1880aacd9dc494fce374245b0da915adaZhongxing Xu  llvm::FoldingSetNodeID ID;
277892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek  StackFrameContext::Profile(ID, ctx, parent, s, blk, idx);
27862d399e1880aacd9dc494fce374245b0da915adaZhongxing Xu  void *InsertPos;
279d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek  StackFrameContext *L =
28062d399e1880aacd9dc494fce374245b0da915adaZhongxing Xu   cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
28162d399e1880aacd9dc494fce374245b0da915adaZhongxing Xu  if (!L) {
282892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    L = new StackFrameContext(ctx, parent, s, blk, idx);
28362d399e1880aacd9dc494fce374245b0da915adaZhongxing Xu    Contexts.InsertNode(L, InsertPos);
28462d399e1880aacd9dc494fce374245b0da915adaZhongxing Xu  }
28562d399e1880aacd9dc494fce374245b0da915adaZhongxing Xu  return L;
28618c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu}
28718c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu
2880ee4124012950d7bb853438629b8e7652febf183Ted Kremenekconst ScopeContext *
2891d26f48dc2eea1c07431ca1519d7034a21b9bcffTed KremenekLocationContextManager::getScope(AnalysisDeclContext *ctx,
2900ee4124012950d7bb853438629b8e7652febf183Ted Kremenek                                 const LocationContext *parent,
2910ee4124012950d7bb853438629b8e7652febf183Ted Kremenek                                 const Stmt *s) {
2920ee4124012950d7bb853438629b8e7652febf183Ted Kremenek  return getLocationContext<ScopeContext, Stmt>(ctx, parent, s);
2930ee4124012950d7bb853438629b8e7652febf183Ted Kremenek}
29418c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu
2957fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenekconst BlockInvocationContext *
2967fa9b4f258636d89342eda28f21a986c8ac353b1Ted KremenekLocationContextManager::getBlockInvocationContext(AnalysisDeclContext *ctx,
2977fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek                                                  const LocationContext *parent,
2987fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek                                                  const BlockDecl *BD,
2997fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek                                                  const void *ContextData) {
3007fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek  llvm::FoldingSetNodeID ID;
3017fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek  BlockInvocationContext::Profile(ID, ctx, parent, BD, ContextData);
3027fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek  void *InsertPos;
3037fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek  BlockInvocationContext *L =
3047fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek    cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,
3057fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek                                                                    InsertPos));
3067fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek  if (!L) {
3077fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek    L = new BlockInvocationContext(ctx, parent, BD, ContextData);
3087fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek    Contexts.InsertNode(L, InsertPos);
3097fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek  }
3107fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek  return L;
3117fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek}
3127fa9b4f258636d89342eda28f21a986c8ac353b1Ted Kremenek
313b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek//===----------------------------------------------------------------------===//
31467d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek// LocationContext methods.
31567d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek//===----------------------------------------------------------------------===//
31667d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek
31767d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenekconst StackFrameContext *LocationContext::getCurrentStackFrame() const {
31867d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek  const LocationContext *LC = this;
31967d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek  while (LC) {
32067d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek    if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC))
32167d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek      return SFC;
32267d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek    LC = LC->getParent();
32367d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek  }
32467d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek  return NULL;
32567d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek}
32667d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek
3278ddf7cead8a67342a4584a203e0bf736b7efedbeZhongxing Xubool LocationContext::isParentOf(const LocationContext *LC) const {
3288ddf7cead8a67342a4584a203e0bf736b7efedbeZhongxing Xu  do {
3298ddf7cead8a67342a4584a203e0bf736b7efedbeZhongxing Xu    const LocationContext *Parent = LC->getParent();
3308ddf7cead8a67342a4584a203e0bf736b7efedbeZhongxing Xu    if (Parent == this)
3318ddf7cead8a67342a4584a203e0bf736b7efedbeZhongxing Xu      return true;
3328ddf7cead8a67342a4584a203e0bf736b7efedbeZhongxing Xu    else
3338ddf7cead8a67342a4584a203e0bf736b7efedbeZhongxing Xu      LC = Parent;
3348ddf7cead8a67342a4584a203e0bf736b7efedbeZhongxing Xu  } while (LC);
3358ddf7cead8a67342a4584a203e0bf736b7efedbeZhongxing Xu
3368ddf7cead8a67342a4584a203e0bf736b7efedbeZhongxing Xu  return false;
3378ddf7cead8a67342a4584a203e0bf736b7efedbeZhongxing Xu}
3388ddf7cead8a67342a4584a203e0bf736b7efedbeZhongxing Xu
33967d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek//===----------------------------------------------------------------------===//
340b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek// Lazily generated map to query the external variables referenced by a Block.
341b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek//===----------------------------------------------------------------------===//
342b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek
343b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremeneknamespace {
344b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenekclass FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
345b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek  BumpVector<const VarDecl*> &BEVals;
346b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek  BumpVectorContext &BC;
3479b20a90dff2ed605153c68a5c58b6aadcdb0952bBenjamin Kramer  llvm::SmallPtrSet<const VarDecl*, 4> Visited;
3489b20a90dff2ed605153c68a5c58b6aadcdb0952bBenjamin Kramer  llvm::SmallPtrSet<const DeclContext*, 4> IgnoredContexts;
349b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenekpublic:
350b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek  FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
351b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek                            BumpVectorContext &bc)
352b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek  : BEVals(bevals), BC(bc) {}
3532cfe28b6a061e72c6c8726d7ecb879093a1ab7a3Ted Kremenek
3542cfe28b6a061e72c6c8726d7ecb879093a1ab7a3Ted Kremenek  bool IsTrackedDecl(const VarDecl *VD) {
3552cfe28b6a061e72c6c8726d7ecb879093a1ab7a3Ted Kremenek    const DeclContext *DC = VD->getDeclContext();
3562cfe28b6a061e72c6c8726d7ecb879093a1ab7a3Ted Kremenek    return IgnoredContexts.count(DC) == 0;
3572cfe28b6a061e72c6c8726d7ecb879093a1ab7a3Ted Kremenek  }
3582cfe28b6a061e72c6c8726d7ecb879093a1ab7a3Ted Kremenek
359b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek  void VisitStmt(Stmt *S) {
3607502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    for (Stmt::child_range I = S->children(); I; ++I)
361b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek      if (Stmt *child = *I)
362b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek        Visit(child);
363b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek  }
36485248734f404fbb9b2f88ecd5296761a8578def6Ted Kremenek
36515ce164836472bfba88b30e53aa3f6ac0fb8a95dTed Kremenek  void VisitDeclRefExpr(DeclRefExpr *DR) {
36685248734f404fbb9b2f88ecd5296761a8578def6Ted Kremenek    // Non-local variables are also directly modified.
3679b20a90dff2ed605153c68a5c58b6aadcdb0952bBenjamin Kramer    if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
36885248734f404fbb9b2f88ecd5296761a8578def6Ted Kremenek      if (!VD->hasLocalStorage()) {
3699b20a90dff2ed605153c68a5c58b6aadcdb0952bBenjamin Kramer        if (Visited.insert(VD))
37085248734f404fbb9b2f88ecd5296761a8578def6Ted Kremenek          BEVals.push_back(VD, BC);
371f4b88a45902af1802a1cb42ba48b1c474474f228John McCall      } else if (DR->refersToEnclosingLocal()) {
3729b20a90dff2ed605153c68a5c58b6aadcdb0952bBenjamin Kramer        if (Visited.insert(VD) && IsTrackedDecl(VD))
3739b20a90dff2ed605153c68a5c58b6aadcdb0952bBenjamin Kramer          BEVals.push_back(VD, BC);
37485248734f404fbb9b2f88ecd5296761a8578def6Ted Kremenek      }
3759b20a90dff2ed605153c68a5c58b6aadcdb0952bBenjamin Kramer    }
37685248734f404fbb9b2f88ecd5296761a8578def6Ted Kremenek  }
3772cfe28b6a061e72c6c8726d7ecb879093a1ab7a3Ted Kremenek
3782cfe28b6a061e72c6c8726d7ecb879093a1ab7a3Ted Kremenek  void VisitBlockExpr(BlockExpr *BR) {
3792cfe28b6a061e72c6c8726d7ecb879093a1ab7a3Ted Kremenek    // Blocks containing blocks can transitively capture more variables.
3802cfe28b6a061e72c6c8726d7ecb879093a1ab7a3Ted Kremenek    IgnoredContexts.insert(BR->getBlockDecl());
3812cfe28b6a061e72c6c8726d7ecb879093a1ab7a3Ted Kremenek    Visit(BR->getBlockDecl()->getBody());
3822cfe28b6a061e72c6c8726d7ecb879093a1ab7a3Ted Kremenek  }
38315ce164836472bfba88b30e53aa3f6ac0fb8a95dTed Kremenek
38415ce164836472bfba88b30e53aa3f6ac0fb8a95dTed Kremenek  void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {
38515ce164836472bfba88b30e53aa3f6ac0fb8a95dTed Kremenek    for (PseudoObjectExpr::semantics_iterator it = PE->semantics_begin(),
38615ce164836472bfba88b30e53aa3f6ac0fb8a95dTed Kremenek         et = PE->semantics_end(); it != et; ++it) {
38715ce164836472bfba88b30e53aa3f6ac0fb8a95dTed Kremenek      Expr *Semantic = *it;
38815ce164836472bfba88b30e53aa3f6ac0fb8a95dTed Kremenek      if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
38915ce164836472bfba88b30e53aa3f6ac0fb8a95dTed Kremenek        Semantic = OVE->getSourceExpr();
39015ce164836472bfba88b30e53aa3f6ac0fb8a95dTed Kremenek      Visit(Semantic);
39115ce164836472bfba88b30e53aa3f6ac0fb8a95dTed Kremenek    }
39215ce164836472bfba88b30e53aa3f6ac0fb8a95dTed Kremenek  }
393d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek};
394b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek} // end anonymous namespace
395b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek
396b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenektypedef BumpVector<const VarDecl*> DeclVec;
397b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek
398b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenekstatic DeclVec* LazyInitializeReferencedDecls(const BlockDecl *BD,
399b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek                                              void *&Vec,
400b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek                                              llvm::BumpPtrAllocator &A) {
401b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek  if (Vec)
402b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek    return (DeclVec*) Vec;
403d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
404b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek  BumpVectorContext BC(A);
405b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek  DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
406b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek  new (BV) DeclVec(BC, 10);
407d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
408b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek  // Find the referenced variables.
409b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek  FindBlockDeclRefExprsVals F(*BV, BC);
410b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek  F.Visit(BD->getBody());
411d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
412d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek  Vec = BV;
413b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek  return BV;
414b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek}
415b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek
4161d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenekstd::pair<AnalysisDeclContext::referenced_decls_iterator,
4171d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek          AnalysisDeclContext::referenced_decls_iterator>
4181d26f48dc2eea1c07431ca1519d7034a21b9bcffTed KremenekAnalysisDeclContext::getReferencedBlockVars(const BlockDecl *BD) {
419b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek  if (!ReferencedBlockVars)
420b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek    ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
421d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
422b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek  DeclVec *V = LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
423b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek  return std::make_pair(V->begin(), V->end());
424b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek}
425b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek
4261d26f48dc2eea1c07431ca1519d7034a21b9bcffTed KremenekManagedAnalysis *&AnalysisDeclContext::getAnalysisImpl(const void *tag) {
427a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek  if (!ManagedAnalyses)
428a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek    ManagedAnalyses = new ManagedAnalysisMap();
429a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek  ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
430a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek  return (*M)[tag];
431a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek}
432a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek
433b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek//===----------------------------------------------------------------------===//
434b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek// Cleanup.
435b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek//===----------------------------------------------------------------------===//
436b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek
437a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted KremenekManagedAnalysis::~ManagedAnalysis() {}
438a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek
4391d26f48dc2eea1c07431ca1519d7034a21b9bcffTed KremenekAnalysisDeclContext::~AnalysisDeclContext() {
440b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek  delete forcedBlkExprs;
441b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek  delete ReferencedBlockVars;
442a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek  // Release the managed analyses.
443a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek  if (ManagedAnalyses) {
444a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek    ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
445a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek    for (ManagedAnalysisMap::iterator I = M->begin(), E = M->end(); I!=E; ++I)
446a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek      delete I->second;
447a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek    delete M;
448a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek  }
449b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek}
450b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek
4511d26f48dc2eea1c07431ca1519d7034a21b9bcffTed KremenekAnalysisDeclContextManager::~AnalysisDeclContextManager() {
452b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek  for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I)
453b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek    delete I->second;
454b1a7b65231e86f7da6aacbf00bcdc16c56350e65Ted Kremenek}
4550ee4124012950d7bb853438629b8e7652febf183Ted Kremenek
4560ee4124012950d7bb853438629b8e7652febf183Ted KremenekLocationContext::~LocationContext() {}
4570ee4124012950d7bb853438629b8e7652febf183Ted Kremenek
4580ee4124012950d7bb853438629b8e7652febf183Ted KremenekLocationContextManager::~LocationContextManager() {
4590ee4124012950d7bb853438629b8e7652febf183Ted Kremenek  clear();
4600ee4124012950d7bb853438629b8e7652febf183Ted Kremenek}
4610ee4124012950d7bb853438629b8e7652febf183Ted Kremenek
4620ee4124012950d7bb853438629b8e7652febf183Ted Kremenekvoid LocationContextManager::clear() {
4630ee4124012950d7bb853438629b8e7652febf183Ted Kremenek  for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
464d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek       E = Contexts.end(); I != E; ) {
4650ee4124012950d7bb853438629b8e7652febf183Ted Kremenek    LocationContext *LC = &*I;
4660ee4124012950d7bb853438629b8e7652febf183Ted Kremenek    ++I;
4670ee4124012950d7bb853438629b8e7652febf183Ted Kremenek    delete LC;
4680ee4124012950d7bb853438629b8e7652febf183Ted Kremenek  }
469d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek
4700ee4124012950d7bb853438629b8e7652febf183Ted Kremenek  Contexts.clear();
4710ee4124012950d7bb853438629b8e7652febf183Ted Kremenek}
4720ee4124012950d7bb853438629b8e7652febf183Ted Kremenek
473