aboutsummaryrefslogtreecommitdiff
path: root/Driver/AnalysisConsumer.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-07-03 04:29:21 +0000
committerTed Kremenek <kremenek@apple.com>2008-07-03 04:29:21 +0000
commitdb09a4dee28a4515438af60f2d2b4a83e4965c31 (patch)
tree548432954c9240c789b3809f0321c9ed571c4e59 /Driver/AnalysisConsumer.cpp
parentc44eec6dd29ee9415cbd38a35deff4c8b67abb6a (diff)
Added static analysis check to see if a subclass of NSObject implements -dealloc, and whether or not that implementation calls [super dealloc].
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53075 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'Driver/AnalysisConsumer.cpp')
-rw-r--r--Driver/AnalysisConsumer.cpp44
1 files changed, 35 insertions, 9 deletions
diff --git a/Driver/AnalysisConsumer.cpp b/Driver/AnalysisConsumer.cpp
index f14fd1dd66..c557b80c7e 100644
--- a/Driver/AnalysisConsumer.cpp
+++ b/Driver/AnalysisConsumer.cpp
@@ -17,7 +17,6 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/ADT/ImmutableList.h"
#include "llvm/ADT/OwningPtr.h"
#include "clang/AST/CFG.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
@@ -25,6 +24,7 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/FileManager.h"
#include "clang/AST/ParentMap.h"
+#include "clang/AST/TranslationUnit.h"
#include "clang/Analysis/PathSensitive/BugReporter.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Analysis/LocalCheckers.h"
@@ -32,6 +32,8 @@
#include "clang/Analysis/PathSensitive/GRExprEngine.h"
#include "llvm/Support/Streams.h"
+#include <vector>
+
using namespace clang;
@@ -53,11 +55,10 @@ namespace {
namespace {
class VISIBILITY_HIDDEN AnalysisConsumer : public ASTConsumer {
- typedef llvm::ImmutableList<CodeAction> Actions;
+ typedef std::vector<CodeAction> Actions;
Actions FunctionActions;
Actions ObjCMethodActions;
-
- Actions::Factory F;
+ Actions ObjCImplementationActions;
public:
const bool Visualize;
@@ -78,16 +79,19 @@ namespace {
const std::string& fname,
const std::string& htmldir,
bool visualize, bool trim, bool analyzeAll)
- : FunctionActions(F.GetEmptyList()), ObjCMethodActions(F.GetEmptyList()),
- Visualize(visualize), TrimGraph(trim), LOpts(lopts), Diags(diags),
+ : Visualize(visualize), TrimGraph(trim), LOpts(lopts), Diags(diags),
Ctx(0), PP(pp), PPF(ppf),
HTMLDir(htmldir),
FName(fname),
AnalyzeAll(analyzeAll) {}
void addCodeAction(CodeAction action) {
- FunctionActions = F.Concat(action, FunctionActions);
- ObjCMethodActions = F.Concat(action, ObjCMethodActions);
+ FunctionActions.push_back(action);
+ ObjCMethodActions.push_back(action);
+ }
+
+ void addObjCImplementationAction(CodeAction action) {
+ ObjCImplementationActions.push_back(action);
}
virtual void Initialize(ASTContext &Context) {
@@ -95,6 +99,8 @@ namespace {
}
virtual void HandleTopLevelDecl(Decl *D);
+ virtual void HandleTranslationUnit(TranslationUnit &TU);
+
void HandleCode(Decl* D, Stmt* Body, Actions actions);
};
@@ -235,6 +241,18 @@ void AnalysisConsumer::HandleTopLevelDecl(Decl *D) {
}
}
+void AnalysisConsumer::HandleTranslationUnit(TranslationUnit& TU) {
+
+ if (ObjCImplementationActions.empty())
+ return;
+
+ for (TranslationUnit::iterator I = TU.begin(), E = TU.end(); I!=E; ++I) {
+
+ if (ObjCImplementationDecl* ID = dyn_cast<ObjCImplementationDecl>(*I))
+ HandleCode(ID, 0, ObjCImplementationActions);
+ }
+}
+
void AnalysisConsumer::HandleCode(Decl* D, Stmt* Body, Actions actions) {
// Don't run the actions if an error has occured with parsing the file.
@@ -259,7 +277,7 @@ void AnalysisConsumer::HandleCode(Decl* D, Stmt* Body, Actions actions) {
// Dispatch on the actions.
for (Actions::iterator I = actions.begin(),
E = actions.end(); I != E; ++I)
- ((*I).getHead())(mgr);
+ (*I)(mgr);
}
//===----------------------------------------------------------------------===//
@@ -351,6 +369,11 @@ static void ActionCFGView(AnalysisManager& mgr) {
mgr.getCFG().viewCFG();
}
+static void ActionCheckObjCDealloc(AnalysisManager& mgr) {
+ BugReporter BR(mgr);
+ CheckObjCDealloc(cast<ObjCImplementationDecl>(mgr.getCodeDecl()), BR);
+}
+
//===----------------------------------------------------------------------===//
// AnalysisConsumer creation.
//===----------------------------------------------------------------------===//
@@ -401,6 +424,9 @@ ASTConsumer* clang::CreateAnalysisConsumer(Analyses* Beg, Analyses* End,
default: break;
}
+ // Checks we always perform:
+ C->addObjCImplementationAction(&ActionCheckObjCDealloc);
+
return C.take();
}