//== 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;
}

Stmt *AnalysisContext::getBody() {
  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
    return FD->getBody();
  else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
    return MD->getBody();

  llvm::llvm_unreachable("unknown code decl");
}

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(Decl *D) {
  iterator I = Contexts.find(D);
  if (I != Contexts.end())
    return &(I->second);

  AnalysisContext &Ctx = Contexts[D];
  Ctx.setDecl(D);
  return &Ctx;
}

void LocationContext::Profile(llvm::FoldingSetNodeID &ID, ContextKind k,
                              AnalysisContext *ctx, LocationContext *parent) {
  ID.AddInteger(k);
  ID.AddPointer(ctx);
  ID.AddPointer(parent);
}

void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID,AnalysisContext *ctx,
                                LocationContext *parent, Stmt *s) {
  LocationContext::Profile(ID, StackFrame, ctx, parent);
  ID.AddPointer(s);
}

void ScopeContext::Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
                           LocationContext *parent, Stmt *s) {
  LocationContext::Profile(ID, Scope, ctx, parent);
  ID.AddPointer(s);
}

StackFrameContext *LocationContextManager::getStackFrame(AnalysisContext *ctx, 
                                             LocationContext *parent, 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,
                                             LocationContext *parent, 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;
}
