aboutsummaryrefslogtreecommitdiff
path: root/Driver/AnalysisConsumer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Driver/AnalysisConsumer.cpp')
-rw-r--r--Driver/AnalysisConsumer.cpp58
1 files changed, 58 insertions, 0 deletions
diff --git a/Driver/AnalysisConsumer.cpp b/Driver/AnalysisConsumer.cpp
index 11fb4a95c1..57be0ff55d 100644
--- a/Driver/AnalysisConsumer.cpp
+++ b/Driver/AnalysisConsumer.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "ASTConsumers.h"
+#include "HTMLDiagnostics.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
@@ -104,6 +105,7 @@ namespace {
llvm::OwningPtr<CFG> cfg;
llvm::OwningPtr<LiveVariables> liveness;
llvm::OwningPtr<ParentMap> PM;
+ llvm::OwningPtr<PathDiagnosticClient> PD;
public:
AnalysisManager(AnalysisConsumer& c, Decl* d, Stmt* b)
@@ -130,6 +132,17 @@ namespace {
Diagnostic& getDiagnostic() {
return C.Diags;
}
+
+ const LangOptions& getLangOptions() const {
+ return C.LOpts;
+ }
+
+ PathDiagnosticClient* getPathDiagnosticClient() {
+ if (PD.get() == 0 && !C.HTMLDir.empty())
+ PD.reset(CreateHTMLDiagnosticClient(C.HTMLDir, C.PP, C.PPF));
+
+ return PD.get();
+ }
LiveVariables* getLiveVariables() {
if (!liveness) liveness.reset(new LiveVariables(*getCFG()));
@@ -213,6 +226,47 @@ static void ActionUninitVals(AnalysisManager& mgr) {
mgr.getDiagnostic());
}
+
+static void ActionRefLeakCheckerAux(AnalysisManager& mgr, bool GCEnabled,
+ bool StandardWarnings) {
+
+ // Construct the analysis engine.
+ GRExprEngine Eng(*mgr.getCFG(), *mgr.getCodeDecl(), mgr.getContext());
+
+ // Construct the transfer function object.
+ llvm::OwningPtr<GRTransferFuncs>
+ TF(MakeCFRefCountTF(mgr.getContext(), GCEnabled, StandardWarnings,
+ mgr.getLangOptions()));
+
+ Eng.setTransferFunctions(TF.get());
+
+ // Execute the worklist algorithm.
+ Eng.ExecuteWorkList();
+
+ // Display warnings.
+ Eng.EmitWarnings(mgr.getDiagnostic(), mgr.getPathDiagnosticClient());
+}
+
+static void ActionRefLeakChecker(AnalysisManager& mgr) {
+
+ switch (mgr.getLangOptions().getGCMode()) {
+ default:
+ assert (false && "Invalid GC mode.");
+ case LangOptions::NonGC:
+ ActionRefLeakCheckerAux(mgr, false, true);
+ break;
+
+ case LangOptions::GCOnly:
+ ActionRefLeakCheckerAux(mgr, true, true);
+ break;
+
+ case LangOptions::HybridGC:
+ ActionRefLeakCheckerAux(mgr, false, true);
+ ActionRefLeakCheckerAux(mgr, true, false);
+ break;
+ }
+}
+
//===----------------------------------------------------------------------===//
// AnalysisConsumer creation.
//===----------------------------------------------------------------------===//
@@ -240,6 +294,10 @@ ASTConsumer* clang::CreateAnalysisConsumer(Analyses* Beg, Analyses* End,
C->addCodeAction(&ActionUninitVals);
break;
+ case CheckerCFRef:
+ C->addCodeAction(&ActionRefLeakChecker);
+ break;
+
default: break;
}