AnalysisDeclContext.cpp revision 82cd37cf1cccde162d1f13eda6cdfe1398216f36
197ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu//== AnalysisContext.cpp - Analysis context for Path Sens analysis -*- C++ -*-// 297ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu// 397ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu// The LLVM Compiler Infrastructure 497ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu// 597ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu// This file is distributed under the University of Illinois Open Source 697ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu// License. See LICENSE.TXT for details. 797ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu// 897ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu//===----------------------------------------------------------------------===// 997ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu// 1097ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu// This file defines AnalysisContext, a class that manages the analysis context 1197ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu// data for path sensitive analysis. 1297ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu// 1397ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu//===----------------------------------------------------------------------===// 1497ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu 1597ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu#include "clang/Analysis/PathSensitive/AnalysisContext.h" 1697ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu#include "clang/Analysis/Analyses/LiveVariables.h" 1797ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu#include "clang/Analysis/CFG.h" 1897ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu#include "clang/AST/Decl.h" 1997ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu#include "clang/AST/DeclObjC.h" 2097ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu#include "clang/AST/ParentMap.h" 2187a05f1fe8ae14044f182b015b279e0a6f4cbdd1Mike Stump#include "llvm/Support/ErrorHandling.h" 2297ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu 2397ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xuusing namespace clang; 2497ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu 2597ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing XuAnalysisContext::~AnalysisContext() { 2697ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu delete cfg; 2797ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu delete liveness; 2897ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu delete PM; 2997ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu} 3097ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu 3197ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing XuStmt *AnalysisContext::getBody() { 3297ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 3397ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu return FD->getBody(); 3497ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 3597ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu return MD->getBody(); 3697ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu 3787a05f1fe8ae14044f182b015b279e0a6f4cbdd1Mike Stump llvm::llvm_unreachable("unknown code decl"); 3897ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu} 3997ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu 4082cd37cf1cccde162d1f13eda6cdfe1398216f36Ted Kremenekconst ImplicitParamDecl *AnalysisContext::getSelfDecl() const { 4182cd37cf1cccde162d1f13eda6cdfe1398216f36Ted Kremenek if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 4282cd37cf1cccde162d1f13eda6cdfe1398216f36Ted Kremenek return MD->getSelfDecl(); 4382cd37cf1cccde162d1f13eda6cdfe1398216f36Ted Kremenek 4482cd37cf1cccde162d1f13eda6cdfe1398216f36Ted Kremenek return NULL; 4582cd37cf1cccde162d1f13eda6cdfe1398216f36Ted Kremenek} 4682cd37cf1cccde162d1f13eda6cdfe1398216f36Ted Kremenek 4797ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing XuCFG *AnalysisContext::getCFG() { 4897ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu if (!cfg) 4997ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu cfg = CFG::buildCFG(getBody(), &D->getASTContext()); 5097ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu return cfg; 5197ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu} 5297ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu 5397ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing XuParentMap &AnalysisContext::getParentMap() { 5497ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu if (!PM) 5597ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu PM = new ParentMap(getBody()); 5697ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu return *PM; 5797ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu} 5897ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu 5997ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing XuLiveVariables *AnalysisContext::getLiveVariables() { 6097ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu if (!liveness) { 6197ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu CFG *c = getCFG(); 6297ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu if (!c) 6397ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu return 0; 6497ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu 6597ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu liveness = new LiveVariables(D->getASTContext(), *c); 6697ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu liveness->runOnCFG(*c); 6797ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu liveness->runOnAllBlocks(*c, 0, true); 6897ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu } 6997ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu 7097ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu return liveness; 7197ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu} 7297ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu 7397ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing XuAnalysisContext *AnalysisContextManager::getContext(Decl *D) { 7497ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu iterator I = Contexts.find(D); 7597ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu if (I != Contexts.end()) 7697ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu return &(I->second); 7797ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu 7897ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu AnalysisContext &Ctx = Contexts[D]; 7997ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu Ctx.setDecl(D); 8097ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu return &Ctx; 8197ab3941effe1f508c7113d9aa0c2887774f6fa8Zhongxing Xu} 8218c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu 8318c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xuvoid LocationContext::Profile(llvm::FoldingSetNodeID &ID, ContextKind k, 8418c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu AnalysisContext *ctx, LocationContext *parent) { 8518c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu ID.AddInteger(k); 8618c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu ID.AddPointer(ctx); 8718c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu ID.AddPointer(parent); 8818c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu} 8918c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu 9018c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xuvoid StackFrameContext::Profile(llvm::FoldingSetNodeID &ID,AnalysisContext *ctx, 9118c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu LocationContext *parent, Stmt *s) { 9218c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu LocationContext::Profile(ID, StackFrame, ctx, parent); 9318c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu ID.AddPointer(s); 9418c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu} 9518c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu 9618c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xuvoid ScopeContext::Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx, 9718c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu LocationContext *parent, Stmt *s) { 9818c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu LocationContext::Profile(ID, Scope, ctx, parent); 9918c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu ID.AddPointer(s); 10018c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu} 10118c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu 10218c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing XuStackFrameContext *LocationContextManager::getStackFrame(AnalysisContext *ctx, 10318c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu LocationContext *parent, Stmt *s) { 10418c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu llvm::FoldingSetNodeID ID; 10518c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu StackFrameContext::Profile(ID, ctx, parent, s); 10618c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu void *InsertPos; 10718c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu 10818c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu StackFrameContext *f = 10918c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos)); 11018c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu if (!f) { 11118c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu f = new StackFrameContext(ctx, parent, s); 11218c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu Contexts.InsertNode(f, InsertPos); 11318c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu } 11418c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu return f; 11518c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu} 11618c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu 11718c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing XuScopeContext *LocationContextManager::getScope(AnalysisContext *ctx, 11818c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu LocationContext *parent, Stmt *s) { 11918c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu llvm::FoldingSetNodeID ID; 12018c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu ScopeContext::Profile(ID, ctx, parent, s); 12118c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu void *InsertPos; 12218c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu 12318c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu ScopeContext *scope = 12418c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu cast_or_null<ScopeContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos)); 12518c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu 12618c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu if (!scope) { 12718c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu scope = new ScopeContext(ctx, parent, s); 12818c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu Contexts.InsertNode(scope, InsertPos); 12918c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu } 13018c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu return scope; 13118c7c06033cafe8c0cdcbe5759c802728688b49fZhongxing Xu} 132