diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 18:03:49 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 18:03:49 +0000 |
commit | 9092c3e0fa01f3139b016d05d267a89e3b07747a (patch) | |
tree | 137ebebcae16fb0ce7ab4af456992bbd8d22fced /lib/Analysis/AnalysisContext.cpp | |
parent | 4981926bf654fe5a2c3893f24ca44106b217e71e (diff) | |
download | FreeBSD-src-9092c3e0fa01f3139b016d05d267a89e3b07747a.zip FreeBSD-src-9092c3e0fa01f3139b016d05d267a89e3b07747a.tar.gz |
Update clang to r84119.
Diffstat (limited to 'lib/Analysis/AnalysisContext.cpp')
-rw-r--r-- | lib/Analysis/AnalysisContext.cpp | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/lib/Analysis/AnalysisContext.cpp b/lib/Analysis/AnalysisContext.cpp new file mode 100644 index 0000000..a4cb66b --- /dev/null +++ b/lib/Analysis/AnalysisContext.cpp @@ -0,0 +1,138 @@ +//== AnalysisContext.cpp - Analysis context for Path Sens analysis -*- C++ -*-// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines AnalysisContext, a class that manages the analysis context +// data for path sensitive analysis. +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/PathSensitive/AnalysisContext.h" +#include "clang/Analysis/Analyses/LiveVariables.h" +#include "clang/Analysis/CFG.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/ParentMap.h" +#include "llvm/Support/ErrorHandling.h" + +using namespace clang; + +AnalysisContext::~AnalysisContext() { + delete cfg; + delete liveness; + delete PM; +} + +AnalysisContextManager::~AnalysisContextManager() { + for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I) + delete I->second; +} + +Stmt *AnalysisContext::getBody() { + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) + return FD->getBody(); + else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) + return MD->getBody(); + + llvm::llvm_unreachable("unknown code decl"); +} + +const ImplicitParamDecl *AnalysisContext::getSelfDecl() const { + if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) + return MD->getSelfDecl(); + + return NULL; +} + +CFG *AnalysisContext::getCFG() { + if (!cfg) + cfg = CFG::buildCFG(getBody(), &D->getASTContext()); + return cfg; +} + +ParentMap &AnalysisContext::getParentMap() { + if (!PM) + PM = new ParentMap(getBody()); + return *PM; +} + +LiveVariables *AnalysisContext::getLiveVariables() { + if (!liveness) { + CFG *c = getCFG(); + if (!c) + return 0; + + liveness = new LiveVariables(D->getASTContext(), *c); + liveness->runOnCFG(*c); + liveness->runOnAllBlocks(*c, 0, true); + } + + return liveness; +} + +AnalysisContext *AnalysisContextManager::getContext(const Decl *D) { + AnalysisContext *&AC = Contexts[D]; + if (!AC) + AC = new AnalysisContext(D); + + return AC; +} + +void LocationContext::Profile(llvm::FoldingSetNodeID &ID, ContextKind k, + AnalysisContext *ctx, + const LocationContext *parent) { + ID.AddInteger(k); + ID.AddPointer(ctx); + ID.AddPointer(parent); +} + +void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID,AnalysisContext *ctx, + const LocationContext *parent, const Stmt *s) { + LocationContext::Profile(ID, StackFrame, ctx, parent); + ID.AddPointer(s); +} + +void ScopeContext::Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx, + const LocationContext *parent, const Stmt *s) { + LocationContext::Profile(ID, Scope, ctx, parent); + ID.AddPointer(s); +} + +StackFrameContext* +LocationContextManager::getStackFrame(AnalysisContext *ctx, + const LocationContext *parent, + const Stmt *s) { + llvm::FoldingSetNodeID ID; + StackFrameContext::Profile(ID, ctx, parent, s); + void *InsertPos; + + StackFrameContext *f = + cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos)); + if (!f) { + f = new StackFrameContext(ctx, parent, s); + Contexts.InsertNode(f, InsertPos); + } + return f; +} + +ScopeContext *LocationContextManager::getScope(AnalysisContext *ctx, + const LocationContext *parent, + const Stmt *s) { + llvm::FoldingSetNodeID ID; + ScopeContext::Profile(ID, ctx, parent, s); + void *InsertPos; + + ScopeContext *scope = + cast_or_null<ScopeContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos)); + + if (!scope) { + scope = new ScopeContext(ctx, parent, s); + Contexts.InsertNode(scope, InsertPos); + } + return scope; +} |