//== 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 CallGraphNode classes.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_ANALYSIS_CALLGRAPH
#define LLVM_CLANG_ANALYSIS_CALLGRAPH

#include "clang/Index/ASTLocation.h"
#include "clang/Index/Entity.h"
#include "clang/Index/Program.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/STLExtras.h"
#include <vector>
#include <map>

namespace clang {

class CallGraphNode {
  idx::Entity F;
  typedef std::pair<idx::ASTLocation, CallGraphNode*> CallRecord;
  std::vector<CallRecord> CalledFunctions;

public:
  CallGraphNode(idx::Entity f) : F(f) {}

  typedef std::vector<CallRecord>::iterator iterator;
  typedef std::vector<CallRecord>::const_iterator const_iterator;

  iterator begin() { return CalledFunctions.begin(); }
  iterator end()   { return CalledFunctions.end(); }
  const_iterator begin() const { return CalledFunctions.begin(); }
  const_iterator end()   const { return CalledFunctions.end();   }

  void addCallee(idx::ASTLocation L, CallGraphNode *Node) {
    CalledFunctions.push_back(std::make_pair(L, Node));
  }

  bool hasCallee() const { return begin() != end(); }

  std::string getName() const { return F.getPrintableName(); }

  Decl *getDecl(ASTContext &Ctx) const { return F.getDecl(Ctx); }
};

class CallGraph {
  /// Program manages all Entities.
  idx::Program &Prog;

  typedef std::map<idx::Entity, CallGraphNode *> FunctionMapTy;

  /// FunctionMap owns all CallGraphNodes.
  FunctionMapTy FunctionMap;

  /// CallerCtx maps a caller to its ASTContext.
  llvm::DenseMap<CallGraphNode *, ASTContext *> CallerCtx;

  /// Root node is the 'main' function or 0.
  CallGraphNode *Root;

  /// ExternalCallingNode has edges to all external functions.
  CallGraphNode *ExternalCallingNode;

public:
  CallGraph(idx::Program &P);
  ~CallGraph();

  typedef FunctionMapTy::iterator iterator;
  typedef FunctionMapTy::const_iterator const_iterator;

  iterator begin() { return FunctionMap.begin(); }
  iterator end()   { return FunctionMap.end();   }
  const_iterator begin() const { return FunctionMap.begin(); }
  const_iterator end()   const { return FunctionMap.end();   }

  CallGraphNode *getRoot() { return Root; }

  CallGraphNode *getExternalCallingNode() { return ExternalCallingNode; }

  void addTU(ASTContext &AST);

  idx::Program &getProgram() { return Prog; }

  CallGraphNode *getOrInsertFunction(idx::Entity F);

  Decl *getDecl(CallGraphNode *Node);

  void print(llvm::raw_ostream &os);
  void dump();

  void ViewCallGraph() const;
};

} // end clang namespace

namespace llvm {

template <> struct GraphTraits<clang::CallGraph> {
  typedef clang::CallGraph GraphType;
  typedef clang::CallGraphNode NodeType;

  typedef std::pair<clang::idx::ASTLocation, NodeType*> CGNPairTy;
  typedef std::pointer_to_unary_function<CGNPairTy, NodeType*> CGNDerefFun;

  typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType;

  static NodeType *getEntryNode(GraphType *CG) {
    return CG->getExternalCallingNode();
  }

  static ChildIteratorType child_begin(NodeType *N) {
    return map_iterator(N->begin(), CGNDerefFun(CGNDeref));
  }
  static ChildIteratorType child_end(NodeType *N) {
    return map_iterator(N->end(), CGNDerefFun(CGNDeref));
  }

  typedef std::pair<clang::idx::Entity, NodeType*> PairTy;
  typedef std::pointer_to_unary_function<PairTy, NodeType*> DerefFun;

  typedef mapped_iterator<GraphType::const_iterator, DerefFun> nodes_iterator;

  static nodes_iterator nodes_begin(const GraphType &CG) {
    return map_iterator(CG.begin(), DerefFun(CGDeref));
  }
  static nodes_iterator nodes_end(const GraphType &CG) {
    return map_iterator(CG.end(), DerefFun(CGDeref));
  }

  static NodeType *CGNDeref(CGNPairTy P) { return P.second; }

  static NodeType *CGDeref(PairTy P) { return P.second; }
};

} // end llvm namespace

#endif
