aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-12-21 01:19:15 +0000
committerAnna Zaks <ganna@apple.com>2012-12-21 01:19:15 +0000
commit4f858dfd42c89b67200dac0afc228a0baa323691 (patch)
treead4d008b16fb3bc5ff7f057897561388d715d154 /lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
parentcd0fd18909e3b89ed6f2cc1118809003db64e67a (diff)
[analyzer] Add blocks and ObjC messages to the call graph.
This paves the road for constructing a better function dependency graph. If we analyze a function before the functions it calls and inlines, there is more opportunity for optimization. Note, we add call edges to the called methods that correspond to function definitions (declarations with bodies). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@170825 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp')
-rw-r--r--lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp48
1 files changed, 18 insertions, 30 deletions
diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 47ca9b7ba4..025891adf8 100644
--- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -330,6 +330,14 @@ public:
}
return true;
}
+
+ bool VisitBlockDecl(BlockDecl *BD) {
+ if (BD->hasBody()) {
+ assert(RecVisitorMode == AM_Syntax || Mgr->shouldInlineCall() == false);
+ HandleCode(BD, RecVisitorMode);
+ }
+ return true;
+ }
private:
void storeTopLevelDecls(DeclGroupRef DG);
@@ -544,16 +552,6 @@ void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
}
-static void FindBlocks(DeclContext *D, SmallVectorImpl<Decl*> &WL) {
- if (BlockDecl *BD = dyn_cast<BlockDecl>(D))
- WL.push_back(BD);
-
- for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
- I!=E; ++I)
- if (DeclContext *DC = dyn_cast<DeclContext>(*I))
- FindBlocks(DC, WL);
-}
-
static std::string getFunctionName(const Decl *D) {
if (const ObjCMethodDecl *ID = dyn_cast<ObjCMethodDecl>(D)) {
return ID->getSelector().getAsString();
@@ -591,6 +589,8 @@ AnalysisConsumer::getModeForDecl(Decl *D, AnalysisMode Mode) {
void AnalysisConsumer::HandleCode(Decl *D, AnalysisMode Mode,
ExprEngine::InliningModes IMode,
SetOfConstDecls *VisitedCallees) {
+ if (!D->hasBody())
+ return;
Mode = getModeForDecl(D, Mode);
if (Mode == AM_None)
return;
@@ -602,29 +602,17 @@ void AnalysisConsumer::HandleCode(Decl *D, AnalysisMode Mode,
MaxCFGSize = MaxCFGSize < CFGSize ? CFGSize : MaxCFGSize;
}
-
// Clear the AnalysisManager of old AnalysisDeclContexts.
Mgr->ClearContexts();
-
- // Dispatch on the actions.
- SmallVector<Decl*, 10> WL;
- WL.push_back(D);
-
- if (D->hasBody() && Opts->AnalyzeNestedBlocks)
- FindBlocks(cast<DeclContext>(D), WL);
-
BugReporter BR(*Mgr);
- for (SmallVectorImpl<Decl*>::iterator WI=WL.begin(), WE=WL.end();
- WI != WE; ++WI)
- if ((*WI)->hasBody()) {
- if (Mode & AM_Syntax)
- checkerMgr->runCheckersOnASTBody(*WI, *Mgr, BR);
- if ((Mode & AM_Path) && checkerMgr->hasPathSensitiveCheckers()) {
- RunPathSensitiveChecks(*WI, IMode, VisitedCallees);
- if (IMode != ExprEngine::Inline_None)
- NumFunctionsAnalyzed++;
- }
- }
+
+ if (Mode & AM_Syntax)
+ checkerMgr->runCheckersOnASTBody(D, *Mgr, BR);
+ if ((Mode & AM_Path) && checkerMgr->hasPathSensitiveCheckers()) {
+ RunPathSensitiveChecks(D, IMode, VisitedCallees);
+ if (IMode != ExprEngine::Inline_None)
+ NumFunctionsAnalyzed++;
+ }
}
//===----------------------------------------------------------------------===//