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