//== CallGraph.cpp - Call graph building ------------------------*- C++ -*--==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defined the CallGraph and CGBuilder classes.
//
//===----------------------------------------------------------------------===//

#include "clang/Index/CallGraph.h"

#include "clang/AST/ASTContext.h"
#include "clang/AST/StmtVisitor.h"

#include "llvm/Support/GraphWriter.h"

using namespace clang;
using namespace idx;

namespace {
class CGBuilder : public StmtVisitor<CGBuilder> {

  CallGraph &G;
  FunctionDecl *FD;

  Entity CallerEnt;

  CallGraphNode *CallerNode;

public:
  CGBuilder(CallGraph &g, FunctionDecl *fd, Entity E, CallGraphNode *N)
    : G(g), FD(fd), CallerEnt(E), CallerNode(N) {}

  void VisitStmt(Stmt *S) { VisitChildren(S); }

  void VisitCallExpr(CallExpr *CE);

  void VisitChildren(Stmt *S) {
    for (Stmt::child_range I = S->children(); I; ++I)
      if (*I)
        static_cast<CGBuilder*>(this)->Visit(*I);
  }
};
}

void CGBuilder::VisitCallExpr(CallExpr *CE) {
  if (FunctionDecl *CalleeDecl = CE->getDirectCallee()) {
    Entity Ent = Entity::get(CalleeDecl, G.getProgram());
    CallGraphNode *CalleeNode = G.getOrInsertFunction(Ent);
    CallerNode->addCallee(ASTLocation(FD, CE), CalleeNode);
  }
}

CallGraph::CallGraph(Program &P) : Prog(P), Root(0) {
  ExternalCallingNode = getOrInsertFunction(Entity());
}

CallGraph::~CallGraph() {
  if (!FunctionMap.empty()) {
    for (FunctionMapTy::iterator I = FunctionMap.begin(), E = FunctionMap.end();
        I != E; ++I)
      delete I->second;
    FunctionMap.clear();
  }
}

void CallGraph::addTU(ASTContext& Ctx) {
  DeclContext *DC = Ctx.getTranslationUnitDecl();
  for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
       I != E; ++I) {

    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
      if (FD->doesThisDeclarationHaveABody()) {
        // Set caller's ASTContext.
        Entity Ent = Entity::get(FD, Prog);
        CallGraphNode *Node = getOrInsertFunction(Ent);
        CallerCtx[Node] = &Ctx;

        // If this function has external linkage, anything could call it.
        if (FD->isGlobal())
          ExternalCallingNode->addCallee(idx::ASTLocation(), Node);

        // Set root node to 'main' function.
        if (FD->getNameAsString() == "main")
          Root = Node;

        CGBuilder builder(*this, FD, Ent, Node);
        builder.Visit(FD->getBody());
      }
    }
  }
}

CallGraphNode *CallGraph::getOrInsertFunction(Entity F) {
  CallGraphNode *&Node = FunctionMap[F];
  if (Node)
    return Node;

  return Node = new CallGraphNode(F);
}

Decl *CallGraph::getDecl(CallGraphNode *Node) {
  // Get the function's context.
  ASTContext *Ctx = CallerCtx[Node];

  return Node->getDecl(*Ctx);
}

void CallGraph::print(raw_ostream &os) {
  for (iterator I = begin(), E = end(); I != E; ++I) {
    if (I->second->hasCallee()) {
      os << "function: " << I->first.getPrintableName()
         << " calls:\n";
      for (CallGraphNode::iterator CI = I->second->begin(),
             CE = I->second->end(); CI != CE; ++CI) {
        os << "    " << CI->second->getName();
      }
      os << '\n';
    }
  }
}

void CallGraph::dump() {
  print(llvm::errs());
}

void CallGraph::ViewCallGraph() const {
  llvm::ViewGraph(*this, "CallGraph");
}

namespace llvm {

template <>
struct DOTGraphTraits<CallGraph> : public DefaultDOTGraphTraits {

  DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}

  static std::string getNodeLabel(const CallGraphNode *Node,
                                  const CallGraph &CG) {
    return Node->getName();

  }

};

}
