From 5c32dfc5fb1cfcff8ae3671284e17daa8da3a188 Mon Sep 17 00:00:00 2001 From: Anna Zaks Date: Fri, 21 Dec 2012 01:19:15 +0000 Subject: [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). llvm-svn: 170825 --- .../StaticAnalyzer/Frontend/AnalysisConsumer.cpp | 48 ++++++++-------------- 1 file changed, 18 insertions(+), 30 deletions(-) (limited to 'clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp') diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index 47ca9b7ba40..025891adf8e 100644 --- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/clang/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 &WL) { - if (BlockDecl *BD = dyn_cast(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(*I)) - FindBlocks(DC, WL); -} - static std::string getFunctionName(const Decl *D) { if (const ObjCMethodDecl *ID = dyn_cast(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 WL; - WL.push_back(D); - - if (D->hasBody() && Opts->AnalyzeNestedBlocks) - FindBlocks(cast(D), WL); - BugReporter BR(*Mgr); - for (SmallVectorImpl::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++; + } } //===----------------------------------------------------------------------===// -- cgit v1.2.3