Check in LLVM r95781.
diff --git a/lib/Index/ASTLocation.cpp b/lib/Index/ASTLocation.cpp
new file mode 100644
index 0000000..c24f3bf
--- /dev/null
+++ b/lib/Index/ASTLocation.cpp
@@ -0,0 +1,117 @@
+//===--- ASTLocation.cpp - A <Decl, Stmt> pair ------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  ASTLocation is Decl or a Stmt and its immediate Decl parent.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/ASTLocation.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprObjC.h"
+using namespace clang;
+using namespace idx;
+
+static Decl *getDeclFromExpr(Stmt *E) {
+  if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
+    return RefExpr->getDecl();
+  if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
+    return ME->getMemberDecl();
+  if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
+    return RE->getDecl();
+
+  if (CallExpr *CE = dyn_cast<CallExpr>(E))
+    return getDeclFromExpr(CE->getCallee());
+  if (CastExpr *CE = dyn_cast<CastExpr>(E))
+    return getDeclFromExpr(CE->getSubExpr());
+
+  return 0;
+}
+
+Decl *ASTLocation::getReferencedDecl() {
+  if (isInvalid())
+    return 0;
+
+  switch (getKind()) {
+  default: assert(0 && "Invalid Kind");
+  case N_Type:
+    return 0;
+  case N_Decl:
+    return D;
+  case N_NamedRef:
+    return NDRef.ND;
+  case N_Stmt:
+    return getDeclFromExpr(Stm);
+  }
+  
+  return 0;
+}
+
+SourceRange ASTLocation::getSourceRange() const {
+  if (isInvalid())
+    return SourceRange();
+
+  switch (getKind()) {
+  default: assert(0 && "Invalid Kind");
+    return SourceRange();
+  case N_Decl:
+    return D->getSourceRange();
+  case N_Stmt:
+    return Stm->getSourceRange();
+  case N_NamedRef:
+    return SourceRange(AsNamedRef().Loc, AsNamedRef().Loc);
+  case N_Type:
+    return AsTypeLoc().getSourceRange();
+  }
+  
+  return SourceRange();
+}
+
+void ASTLocation::print(llvm::raw_ostream &OS) const {
+  if (isInvalid()) {
+    OS << "<< Invalid ASTLocation >>\n";
+    return;
+  }
+  
+  ASTContext &Ctx = getParentDecl()->getASTContext();
+
+  switch (getKind()) {
+  case N_Decl:
+    OS << "[Decl: " << AsDecl()->getDeclKindName() << " ";
+    if (const NamedDecl *ND = dyn_cast<NamedDecl>(AsDecl()))
+      OS << ND->getNameAsString();
+    break;
+
+  case N_Stmt:
+    OS << "[Stmt: " << AsStmt()->getStmtClassName() << " ";
+    AsStmt()->printPretty(OS, Ctx, 0, PrintingPolicy(Ctx.getLangOptions()));
+    break;
+    
+  case N_NamedRef:
+    OS << "[NamedRef: " << AsNamedRef().ND->getDeclKindName() << " ";
+    OS << AsNamedRef().ND->getNameAsString();
+    break;
+    
+  case N_Type: {
+    QualType T = AsTypeLoc().getType();
+    OS << "[Type: " << T->getTypeClassName() << " " << T.getAsString();
+  }
+  }
+
+  OS << "] <";
+
+  SourceRange Range = getSourceRange();
+  SourceManager &SourceMgr = Ctx.getSourceManager();
+  Range.getBegin().print(OS, SourceMgr);
+  OS << ", ";
+  Range.getEnd().print(OS, SourceMgr);
+  OS << ">\n";
+}
diff --git a/lib/Index/ASTVisitor.h b/lib/Index/ASTVisitor.h
new file mode 100644
index 0000000..943c720
--- /dev/null
+++ b/lib/Index/ASTVisitor.h
@@ -0,0 +1,144 @@
+//===--- ASTVisitor.h - Visitor for an ASTContext ---------------*- 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 the ASTVisitor interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_ASTVISITOR_H
+#define LLVM_CLANG_INDEX_ASTVISITOR_H
+
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/TypeLocVisitor.h"
+
+namespace clang {
+
+namespace idx {
+
+/// \brief Traverses the full AST, both Decls and Stmts.
+template<typename ImplClass>
+class ASTVisitor : public DeclVisitor<ImplClass>,
+                   public StmtVisitor<ImplClass>,
+                   public TypeLocVisitor<ImplClass> {
+public:
+  ASTVisitor() : CurrentDecl(0) { }
+
+  Decl *CurrentDecl;
+
+  typedef ASTVisitor<ImplClass>  Base;
+  typedef DeclVisitor<ImplClass> BaseDeclVisitor;
+  typedef StmtVisitor<ImplClass> BaseStmtVisitor;
+  typedef TypeLocVisitor<ImplClass> BaseTypeLocVisitor;
+
+  using BaseStmtVisitor::Visit;
+
+  //===--------------------------------------------------------------------===//
+  // DeclVisitor
+  //===--------------------------------------------------------------------===//
+
+  void Visit(Decl *D) {
+    Decl *PrevDecl = CurrentDecl;
+    CurrentDecl = D;
+    BaseDeclVisitor::Visit(D);
+    CurrentDecl = PrevDecl;
+  }
+  
+  void VisitDeclaratorDecl(DeclaratorDecl *D) {
+    BaseDeclVisitor::VisitDeclaratorDecl(D);
+    if (TypeSourceInfo *TInfo = D->getTypeSourceInfo())
+      Visit(TInfo->getTypeLoc());
+  }
+
+  void VisitFunctionDecl(FunctionDecl *D) {
+    BaseDeclVisitor::VisitFunctionDecl(D);
+    if (D->isThisDeclarationADefinition())
+      Visit(D->getBody());
+  }
+
+  void VisitObjCMethodDecl(ObjCMethodDecl *D) {
+    BaseDeclVisitor::VisitObjCMethodDecl(D);
+    if (D->getBody())
+      Visit(D->getBody());
+  }
+
+  void VisitBlockDecl(BlockDecl *D) {
+    BaseDeclVisitor::VisitBlockDecl(D);
+    Visit(D->getBody());
+  }
+
+  void VisitVarDecl(VarDecl *D) {
+    BaseDeclVisitor::VisitVarDecl(D);
+    if (Expr *Init = D->getInit())
+      Visit(Init);
+  }
+
+  void VisitDecl(Decl *D) {
+    if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D))
+      return;
+
+    if (DeclContext *DC = dyn_cast<DeclContext>(D))
+      static_cast<ImplClass*>(this)->VisitDeclContext(DC);
+  }
+
+  void VisitDeclContext(DeclContext *DC) {
+    for (DeclContext::decl_iterator
+           I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I)
+      Visit(*I);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // StmtVisitor
+  //===--------------------------------------------------------------------===//
+
+  void VisitDeclStmt(DeclStmt *Node) {
+    for (DeclStmt::decl_iterator
+           I = Node->decl_begin(), E = Node->decl_end(); I != E; ++I)
+      Visit(*I);
+  }
+
+  void VisitBlockExpr(BlockExpr *Node) {
+    // The BlockDecl is also visited by 'VisitDeclContext()'.  No need to visit it twice.
+  }
+
+  void VisitStmt(Stmt *Node) {
+    for (Stmt::child_iterator
+           I = Node->child_begin(), E = Node->child_end(); I != E; ++I)
+      if (*I)
+        Visit(*I);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // TypeLocVisitor
+  //===--------------------------------------------------------------------===//
+  
+  void Visit(TypeLoc TL) {
+    for (; TL; TL = TL.getNextTypeLoc())
+      BaseTypeLocVisitor::Visit(TL);
+  }
+  
+  void VisitArrayLoc(ArrayTypeLoc TL) {
+    BaseTypeLocVisitor::VisitArrayTypeLoc(TL);
+    if (TL.getSizeExpr())
+      Visit(TL.getSizeExpr());
+  }
+  
+  void VisitFunctionTypeLoc(FunctionTypeLoc TL) {
+    BaseTypeLocVisitor::VisitFunctionTypeLoc(TL);
+    for (unsigned i = 0; i != TL.getNumArgs(); ++i)
+      Visit(TL.getArg(i));
+  }
+
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/lib/Index/Analyzer.cpp b/lib/Index/Analyzer.cpp
new file mode 100644
index 0000000..fb3529d
--- /dev/null
+++ b/lib/Index/Analyzer.cpp
@@ -0,0 +1,437 @@
+//===--- Analyzer.cpp - Analysis for indexing information -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Analyzer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/Analyzer.h"
+#include "clang/Index/Entity.h"
+#include "clang/Index/TranslationUnit.h"
+#include "clang/Index/Handlers.h"
+#include "clang/Index/ASTLocation.h"
+#include "clang/Index/GlobalSelector.h"
+#include "clang/Index/DeclReferenceMap.h"
+#include "clang/Index/SelectorMap.h"
+#include "clang/Index/IndexProvider.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/ExprObjC.h"
+#include "llvm/ADT/SmallSet.h"
+using namespace clang;
+using namespace idx;
+
+namespace  {
+
+//===----------------------------------------------------------------------===//
+// DeclEntityAnalyzer Implementation
+//===----------------------------------------------------------------------===//
+
+class DeclEntityAnalyzer : public TranslationUnitHandler {
+  Entity Ent;
+  TULocationHandler &TULocHandler;
+
+public:
+  DeclEntityAnalyzer(Entity ent, TULocationHandler &handler)
+    : Ent(ent), TULocHandler(handler) { }
+
+  virtual void Handle(TranslationUnit *TU) {
+    assert(TU && "Passed null translation unit");
+
+    Decl *D = Ent.getDecl(TU->getASTContext());
+    assert(D && "Couldn't resolve Entity");
+
+    for (Decl::redecl_iterator I = D->redecls_begin(),
+                               E = D->redecls_end(); I != E; ++I)
+      TULocHandler.Handle(TULocation(TU, ASTLocation(*I)));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// RefEntityAnalyzer Implementation
+//===----------------------------------------------------------------------===//
+
+class RefEntityAnalyzer : public TranslationUnitHandler {
+  Entity Ent;
+  TULocationHandler &TULocHandler;
+
+public:
+  RefEntityAnalyzer(Entity ent, TULocationHandler &handler)
+    : Ent(ent), TULocHandler(handler) { }
+
+  virtual void Handle(TranslationUnit *TU) {
+    assert(TU && "Passed null translation unit");
+
+    Decl *D = Ent.getDecl(TU->getASTContext());
+    assert(D && "Couldn't resolve Entity");
+    NamedDecl *ND = dyn_cast<NamedDecl>(D);
+    if (!ND)
+      return;
+
+    DeclReferenceMap &RefMap = TU->getDeclReferenceMap();
+    for (DeclReferenceMap::astlocation_iterator
+           I = RefMap.refs_begin(ND), E = RefMap.refs_end(ND); I != E; ++I)
+      TULocHandler.Handle(TULocation(TU, *I));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// RefSelectorAnalyzer Implementation
+//===----------------------------------------------------------------------===//
+
+/// \brief Accepts an ObjC method and finds all message expressions that this
+/// method may respond to.
+class RefSelectorAnalyzer : public TranslationUnitHandler {
+  Program &Prog;
+  TULocationHandler &TULocHandler;
+
+  // The original ObjCInterface associated with the method.
+  Entity IFaceEnt;
+  GlobalSelector GlobSel;
+  bool IsInstanceMethod;
+
+  /// \brief Super classes of the ObjCInterface.
+  typedef llvm::SmallSet<Entity, 16> EntitiesSetTy;
+  EntitiesSetTy HierarchyEntities;
+
+public:
+  RefSelectorAnalyzer(ObjCMethodDecl *MD,
+                      Program &prog, TULocationHandler &handler)
+    : Prog(prog), TULocHandler(handler) {
+    assert(MD);
+
+    // FIXME: Protocol methods.
+    assert(!isa<ObjCProtocolDecl>(MD->getDeclContext()) &&
+           "Protocol methods not supported yet");
+
+    ObjCInterfaceDecl *IFD = MD->getClassInterface();
+    assert(IFD);
+    IFaceEnt = Entity::get(IFD, Prog);
+    GlobSel = GlobalSelector::get(MD->getSelector(), Prog);
+    IsInstanceMethod = MD->isInstanceMethod();
+
+    for (ObjCInterfaceDecl *Cls = IFD->getSuperClass();
+           Cls; Cls = Cls->getSuperClass())
+      HierarchyEntities.insert(Entity::get(Cls, Prog));
+  }
+
+  virtual void Handle(TranslationUnit *TU) {
+    assert(TU && "Passed null translation unit");
+
+    ASTContext &Ctx = TU->getASTContext();
+    // Null means it doesn't exist in this translation unit.
+    ObjCInterfaceDecl *IFace =
+        cast_or_null<ObjCInterfaceDecl>(IFaceEnt.getDecl(Ctx));
+    Selector Sel = GlobSel.getSelector(Ctx);
+
+    SelectorMap &SelMap = TU->getSelectorMap();
+    for (SelectorMap::astlocation_iterator
+           I = SelMap.refs_begin(Sel), E = SelMap.refs_end(Sel); I != E; ++I) {
+      if (ValidReference(*I, IFace))
+        TULocHandler.Handle(TULocation(TU, *I));
+    }
+  }
+
+  /// \brief Determines whether the given message expression is likely to end
+  /// up at the given interface decl.
+  ///
+  /// It returns true "eagerly", meaning it will return false only if it can
+  /// "prove" statically that the interface cannot accept this message.
+  bool ValidReference(ASTLocation ASTLoc, ObjCInterfaceDecl *IFace) {
+    assert(ASTLoc.isStmt());
+
+    // FIXME: Finding @selector references should be through another Analyzer
+    // method, like FindSelectors.
+    if (isa<ObjCSelectorExpr>(ASTLoc.AsStmt()))
+      return false;
+
+    ObjCInterfaceDecl *MsgD = 0;
+    ObjCMessageExpr *Msg = cast<ObjCMessageExpr>(ASTLoc.AsStmt());
+
+    if (Msg->getReceiver()) {
+      const ObjCObjectPointerType *OPT =
+          Msg->getReceiver()->getType()->getAsObjCInterfacePointerType();
+
+      // Can be anything! Accept it as a possibility..
+      if (!OPT || OPT->isObjCIdType() || OPT->isObjCQualifiedIdType())
+        return true;
+
+      // Expecting class method.
+      if (OPT->isObjCClassType() || OPT->isObjCQualifiedClassType())
+        return !IsInstanceMethod;
+
+      MsgD = OPT->getInterfaceDecl();
+      assert(MsgD);
+
+      // Should be an instance method.
+      if (!IsInstanceMethod)
+        return false;
+
+    } else {
+      // Expecting class method.
+      if (IsInstanceMethod)
+        return false;
+
+      MsgD = Msg->getClassInfo().first;
+      // FIXME: Case when we only have an identifier.
+      assert(MsgD && "Identifier only");
+    }
+
+    assert(MsgD);
+
+    // Same interface ? We have a winner!
+    if (MsgD == IFace)
+      return true;
+
+    // If the message interface is a superclass of the original interface,
+    // accept this message as a possibility.
+    if (HierarchyEntities.count(Entity::get(MsgD, Prog)))
+      return true;
+
+    // If the message interface is a subclass of the original interface, accept
+    // the message unless there is a subclass in the hierarchy that will
+    // "steal" the message (thus the message "will go" to the subclass and not
+    /// the original interface).
+    if (IFace) {
+      Selector Sel = Msg->getSelector();
+      for (ObjCInterfaceDecl *Cls = MsgD; Cls; Cls = Cls->getSuperClass()) {
+        if (Cls == IFace)
+          return true;
+        if (Cls->getMethod(Sel, IsInstanceMethod))
+          return false;
+      }
+    }
+
+    // The interfaces are unrelated, don't accept the message.
+    return false;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// MessageAnalyzer Implementation
+//===----------------------------------------------------------------------===//
+
+/// \brief Accepts an ObjC message expression and finds all methods that may
+/// respond to it.
+class MessageAnalyzer : public TranslationUnitHandler {
+  Program &Prog;
+  TULocationHandler &TULocHandler;
+
+  // The ObjCInterface associated with the message. Can be null/invalid.
+  Entity MsgIFaceEnt;
+  GlobalSelector GlobSel;
+  bool CanBeInstanceMethod;
+  bool CanBeClassMethod;
+
+  /// \brief Super classes of the ObjCInterface.
+  typedef llvm::SmallSet<Entity, 16> EntitiesSetTy;
+  EntitiesSetTy HierarchyEntities;
+
+  /// \brief The interface in the message interface hierarchy that "intercepts"
+  /// the selector.
+  Entity ReceiverIFaceEnt;
+
+public:
+  MessageAnalyzer(ObjCMessageExpr *Msg,
+                  Program &prog, TULocationHandler &handler)
+    : Prog(prog), TULocHandler(handler),
+      CanBeInstanceMethod(false),
+      CanBeClassMethod(false) {
+
+    assert(Msg);
+
+    ObjCInterfaceDecl *MsgD = 0;
+
+    while (true) {
+      if (Msg->getReceiver() == 0) {
+        CanBeClassMethod = true;
+        MsgD = Msg->getClassInfo().first;
+        // FIXME: Case when we only have an identifier.
+        assert(MsgD && "Identifier only");
+        break;
+      }
+
+      const ObjCObjectPointerType *OPT =
+          Msg->getReceiver()->getType()->getAsObjCInterfacePointerType();
+
+      if (!OPT || OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()) {
+        CanBeInstanceMethod = CanBeClassMethod = true;
+        break;
+      }
+
+      if (OPT->isObjCClassType() || OPT->isObjCQualifiedClassType()) {
+        CanBeClassMethod = true;
+        break;
+      }
+
+      MsgD = OPT->getInterfaceDecl();
+      assert(MsgD);
+      CanBeInstanceMethod = true;
+      break;
+    }
+
+    assert(CanBeInstanceMethod || CanBeClassMethod);
+
+    Selector sel = Msg->getSelector();
+    assert(!sel.isNull());
+
+    MsgIFaceEnt = Entity::get(MsgD, Prog);
+    GlobSel = GlobalSelector::get(sel, Prog);
+
+    if (MsgD) {
+      for (ObjCInterfaceDecl *Cls = MsgD->getSuperClass();
+             Cls; Cls = Cls->getSuperClass())
+        HierarchyEntities.insert(Entity::get(Cls, Prog));
+
+      // Find the interface in the hierarchy that "receives" the message.
+      for (ObjCInterfaceDecl *Cls = MsgD; Cls; Cls = Cls->getSuperClass()) {
+        bool isReceiver = false;
+
+        ObjCInterfaceDecl::lookup_const_iterator Meth, MethEnd;
+        for (llvm::tie(Meth, MethEnd) = Cls->lookup(sel);
+               Meth != MethEnd; ++Meth) {
+          if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth))
+            if ((MD->isInstanceMethod() && CanBeInstanceMethod) ||
+                (MD->isClassMethod()    && CanBeClassMethod)) {
+              isReceiver = true;
+              break;
+            }
+        }
+
+        if (isReceiver) {
+          ReceiverIFaceEnt = Entity::get(Cls, Prog);
+          break;
+        }
+      }
+    }
+  }
+
+  virtual void Handle(TranslationUnit *TU) {
+    assert(TU && "Passed null translation unit");
+    ASTContext &Ctx = TU->getASTContext();
+
+    // Null means it doesn't exist in this translation unit or there was no
+    // interface that was determined to receive the original message.
+    ObjCInterfaceDecl *ReceiverIFace =
+        cast_or_null<ObjCInterfaceDecl>(ReceiverIFaceEnt.getDecl(Ctx));
+
+    // No subclass for the original receiver interface, so it remains the
+    // receiver.
+    if (ReceiverIFaceEnt.isValid() && ReceiverIFace == 0)
+      return;
+
+    // Null means it doesn't exist in this translation unit or there was no
+    // interface associated with the message in the first place.
+    ObjCInterfaceDecl *MsgIFace =
+        cast_or_null<ObjCInterfaceDecl>(MsgIFaceEnt.getDecl(Ctx));
+
+    Selector Sel = GlobSel.getSelector(Ctx);
+    SelectorMap &SelMap = TU->getSelectorMap();
+    for (SelectorMap::method_iterator
+           I = SelMap.methods_begin(Sel), E = SelMap.methods_end(Sel);
+           I != E; ++I) {
+      ObjCMethodDecl *D = *I;
+      if (ValidMethod(D, MsgIFace, ReceiverIFace)) {
+        for (ObjCMethodDecl::redecl_iterator
+               RI = D->redecls_begin(), RE = D->redecls_end(); RI != RE; ++RI)
+          TULocHandler.Handle(TULocation(TU, ASTLocation(*RI)));
+      }
+    }
+  }
+
+  /// \brief Determines whether the given method is likely to accept the
+  /// original message.
+  ///
+  /// It returns true "eagerly", meaning it will return false only if it can
+  /// "prove" statically that the method cannot accept the original message.
+  bool ValidMethod(ObjCMethodDecl *D, ObjCInterfaceDecl *MsgIFace,
+                   ObjCInterfaceDecl *ReceiverIFace) {
+    assert(D);
+
+    // FIXME: Protocol methods ?
+    if (isa<ObjCProtocolDecl>(D->getDeclContext()))
+      return false;
+
+    // No specific interface associated with the message. Can be anything.
+    if (MsgIFaceEnt.isInvalid())
+      return true;
+
+    if ((!CanBeInstanceMethod && D->isInstanceMethod()) ||
+        (!CanBeClassMethod    && D->isClassMethod()))
+      return false;
+
+    ObjCInterfaceDecl *IFace = D->getClassInterface();
+    assert(IFace);
+
+    // If the original message interface is the same or a superclass of the
+    // given interface, accept the method as a possibility.
+    if (MsgIFace && MsgIFace->isSuperClassOf(IFace))
+      return true;
+
+    if (ReceiverIFace) {
+      // The given interface, "overrides" the receiver.
+      if (ReceiverIFace->isSuperClassOf(IFace))
+        return true;
+    } else {
+      // No receiver was found for the original message.
+      assert(ReceiverIFaceEnt.isInvalid());
+
+      // If the original message interface is a subclass of the given interface,
+      // accept the message.
+      if (HierarchyEntities.count(Entity::get(IFace, Prog)))
+        return true;
+    }
+
+    // The interfaces are unrelated, or the receiver interface wasn't
+    // "overriden".
+    return false;
+  }
+};
+
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Analyzer Implementation
+//===----------------------------------------------------------------------===//
+
+void Analyzer::FindDeclarations(Decl *D, TULocationHandler &Handler) {
+  assert(D && "Passed null declaration");
+  Entity Ent = Entity::get(D, Prog);
+  if (Ent.isInvalid())
+    return;
+
+  DeclEntityAnalyzer DEA(Ent, Handler);
+  Idxer.GetTranslationUnitsFor(Ent, DEA);
+}
+
+void Analyzer::FindReferences(Decl *D, TULocationHandler &Handler) {
+  assert(D && "Passed null declaration");
+  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+    RefSelectorAnalyzer RSA(MD, Prog, Handler);
+    GlobalSelector Sel = GlobalSelector::get(MD->getSelector(), Prog);
+    Idxer.GetTranslationUnitsFor(Sel, RSA);
+    return;
+  }
+
+  Entity Ent = Entity::get(D, Prog);
+  if (Ent.isInvalid())
+    return;
+
+  RefEntityAnalyzer REA(Ent, Handler);
+  Idxer.GetTranslationUnitsFor(Ent, REA);
+}
+
+/// \brief Find methods that may respond to the given message and pass them
+/// to Handler.
+void Analyzer::FindObjCMethods(ObjCMessageExpr *Msg,
+                               TULocationHandler &Handler) {
+  assert(Msg);
+  MessageAnalyzer MsgAnalyz(Msg, Prog, Handler);
+  GlobalSelector GlobSel = GlobalSelector::get(Msg->getSelector(), Prog);
+  Idxer.GetTranslationUnitsFor(GlobSel, MsgAnalyz);
+}
diff --git a/lib/Index/CMakeLists.txt b/lib/Index/CMakeLists.txt
new file mode 100644
index 0000000..4d67035
--- /dev/null
+++ b/lib/Index/CMakeLists.txt
@@ -0,0 +1,16 @@
+set(LLVM_NO_RTTI 1)
+
+add_clang_library(clangIndex
+  ASTLocation.cpp
+  Analyzer.cpp
+  CallGraph.cpp
+  DeclReferenceMap.cpp
+  Entity.cpp
+  GlobalSelector.cpp
+  Handlers.cpp
+  IndexProvider.cpp
+  Indexer.cpp
+  Program.cpp
+  ResolveLocation.cpp
+  SelectorMap.cpp
+  )
diff --git a/lib/Index/CallGraph.cpp b/lib/Index/CallGraph.cpp
new file mode 100644
index 0000000..6403319
--- /dev/null
+++ b/lib/Index/CallGraph.cpp
@@ -0,0 +1,150 @@
+//== 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_iterator I=S->child_begin(), E=S->child_end(); I != E;++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() : 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->isThisDeclarationADefinition()) {
+        // 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(llvm::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();
+
+  }
+
+};
+
+}
diff --git a/lib/Index/DeclReferenceMap.cpp b/lib/Index/DeclReferenceMap.cpp
new file mode 100644
index 0000000..d6e30ab
--- /dev/null
+++ b/lib/Index/DeclReferenceMap.cpp
@@ -0,0 +1,90 @@
+//===--- DeclReferenceMap.cpp - Map Decls to their references -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  DeclReferenceMap creates a mapping from Decls to the ASTLocations that
+//  reference them.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/DeclReferenceMap.h"
+#include "clang/Index/ASTLocation.h"
+#include "ASTVisitor.h"
+using namespace clang;
+using namespace idx;
+
+namespace {
+
+class RefMapper : public ASTVisitor<RefMapper> {
+  DeclReferenceMap::MapTy &Map;
+
+public:
+  RefMapper(DeclReferenceMap::MapTy &map) : Map(map) { }
+
+  void VisitDeclRefExpr(DeclRefExpr *Node);
+  void VisitMemberExpr(MemberExpr *Node);
+  void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
+  
+  void VisitTypedefTypeLoc(TypedefTypeLoc TL);
+  void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
+};
+
+} // anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// RefMapper Implementation
+//===----------------------------------------------------------------------===//
+
+void RefMapper::VisitDeclRefExpr(DeclRefExpr *Node) {
+  NamedDecl *PrimD = cast<NamedDecl>(Node->getDecl()->getCanonicalDecl());
+  Map.insert(std::make_pair(PrimD, ASTLocation(CurrentDecl, Node)));
+}
+
+void RefMapper::VisitMemberExpr(MemberExpr *Node) {
+  NamedDecl *PrimD = cast<NamedDecl>(Node->getMemberDecl()->getCanonicalDecl());
+  Map.insert(std::make_pair(PrimD, ASTLocation(CurrentDecl, Node)));
+}
+
+void RefMapper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
+  Map.insert(std::make_pair(Node->getDecl(), ASTLocation(CurrentDecl, Node)));
+}
+
+void RefMapper::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+  NamedDecl *ND = TL.getTypedefDecl();
+  Map.insert(std::make_pair(ND, ASTLocation(CurrentDecl, ND, TL.getNameLoc())));
+}
+
+void RefMapper::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
+  NamedDecl *ND = TL.getIFaceDecl();
+  Map.insert(std::make_pair(ND, ASTLocation(CurrentDecl, ND, TL.getNameLoc())));
+}
+
+//===----------------------------------------------------------------------===//
+// DeclReferenceMap Implementation
+//===----------------------------------------------------------------------===//
+
+DeclReferenceMap::DeclReferenceMap(ASTContext &Ctx) {
+  RefMapper(Map).Visit(Ctx.getTranslationUnitDecl());
+}
+
+DeclReferenceMap::astlocation_iterator
+DeclReferenceMap::refs_begin(NamedDecl *D) const {
+  NamedDecl *Prim = cast<NamedDecl>(D->getCanonicalDecl());
+  return astlocation_iterator(Map.lower_bound(Prim));
+}
+
+DeclReferenceMap::astlocation_iterator
+DeclReferenceMap::refs_end(NamedDecl *D) const {
+  NamedDecl *Prim = cast<NamedDecl>(D->getCanonicalDecl());
+  return astlocation_iterator(Map.upper_bound(Prim));
+}
+
+bool DeclReferenceMap::refs_empty(NamedDecl *D) const {
+  NamedDecl *Prim = cast<NamedDecl>(D->getCanonicalDecl());
+  return refs_begin(Prim) == refs_end(Prim);
+}
diff --git a/lib/Index/Entity.cpp b/lib/Index/Entity.cpp
new file mode 100644
index 0000000..03fe9f7
--- /dev/null
+++ b/lib/Index/Entity.cpp
@@ -0,0 +1,227 @@
+//===--- Entity.cpp - Cross-translation-unit "token" for decls ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Entity is a ASTContext-independent way to refer to declarations that are
+//  visible across translation units.
+//
+//===----------------------------------------------------------------------===//
+
+#include "EntityImpl.h"
+#include "ProgramImpl.h"
+#include "clang/Index/Program.h"
+#include "clang/Index/GlobalSelector.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclVisitor.h"
+using namespace clang;
+using namespace idx;
+
+// FIXME: Entity is really really basic currently, mostly written to work
+// on variables and functions. Should support types and other decls eventually..
+
+
+//===----------------------------------------------------------------------===//
+// EntityGetter
+//===----------------------------------------------------------------------===//
+
+namespace clang {
+namespace idx {
+
+/// \brief Gets the Entity associated with a Decl.
+class EntityGetter : public DeclVisitor<EntityGetter, Entity> {
+  Program &Prog;
+  ProgramImpl &ProgImpl;
+
+public:
+  EntityGetter(Program &prog, ProgramImpl &progImpl)
+    : Prog(prog), ProgImpl(progImpl) { }
+
+  Entity VisitNamedDecl(NamedDecl *D);
+  Entity VisitVarDecl(VarDecl *D);
+  Entity VisitFunctionDecl(FunctionDecl *D);
+};
+
+}
+}
+
+Entity EntityGetter::VisitNamedDecl(NamedDecl *D) {
+  Entity Parent;
+  if (!D->getDeclContext()->isTranslationUnit()) {
+    Parent = Visit(cast<Decl>(D->getDeclContext()));
+    // FIXME: Anonymous structs ?
+    if (Parent.isInvalid())
+      return Entity();
+  }
+  if (Parent.isValid() && Parent.isInternalToTU())
+    return Entity(D);
+
+  // FIXME: Only works for DeclarationNames that are identifiers and selectors.
+  // Treats other DeclarationNames as internal Decls for now..
+
+  DeclarationName LocalName = D->getDeclName();
+  if (!LocalName)
+    return Entity(D);
+
+  DeclarationName GlobName;
+
+  if (IdentifierInfo *II = LocalName.getAsIdentifierInfo()) {
+    IdentifierInfo *GlobII =
+      &ProgImpl.getIdents().get(II->getNameStart(),
+                                II->getNameStart() + II->getLength());
+    GlobName = DeclarationName(GlobII);
+  } else {
+    Selector LocalSel = LocalName.getObjCSelector();
+
+    // Treats other DeclarationNames as internal Decls for now..
+    if (LocalSel.isNull())
+      return Entity(D);
+
+    Selector GlobSel =
+        (uintptr_t)GlobalSelector::get(LocalSel, Prog).getAsOpaquePtr();
+    GlobName = DeclarationName(GlobSel);
+  }
+
+  assert(GlobName);
+
+  unsigned IdNS = D->getIdentifierNamespace();
+
+  ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D);
+  bool isObjCInstanceMethod = MD && MD->isInstanceMethod();
+
+  llvm::FoldingSetNodeID ID;
+  EntityImpl::Profile(ID, Parent, GlobName, IdNS, isObjCInstanceMethod);
+
+  ProgramImpl::EntitySetTy &Entities = ProgImpl.getEntities();
+  void *InsertPos = 0;
+  if (EntityImpl *Ent = Entities.FindNodeOrInsertPos(ID, InsertPos))
+    return Entity(Ent);
+
+  void *Buf = ProgImpl.Allocate(sizeof(EntityImpl));
+  EntityImpl *New =
+      new (Buf) EntityImpl(Parent, GlobName, IdNS, isObjCInstanceMethod);
+  Entities.InsertNode(New, InsertPos);
+
+  return Entity(New);
+}
+
+Entity EntityGetter::VisitVarDecl(VarDecl *D) {
+  // If it's static it cannot be referred to by another translation unit.
+  if (D->getStorageClass() == VarDecl::Static)
+    return Entity(D);
+
+  return VisitNamedDecl(D);
+}
+
+Entity EntityGetter::VisitFunctionDecl(FunctionDecl *D) {
+  // If it's static it cannot be refered to by another translation unit.
+  if (D->getStorageClass() == FunctionDecl::Static)
+    return Entity(D);
+
+  return VisitNamedDecl(D);
+}
+
+//===----------------------------------------------------------------------===//
+// EntityImpl Implementation
+//===----------------------------------------------------------------------===//
+
+Decl *EntityImpl::getDecl(ASTContext &AST) {
+  DeclContext *DC =
+    Parent.isInvalid() ? AST.getTranslationUnitDecl()
+                       : cast<DeclContext>(Parent.getDecl(AST));
+  if (!DC)
+    return 0; // Couldn't get the parent context.
+
+  DeclarationName LocalName;
+
+  if (IdentifierInfo *GlobII = Name.getAsIdentifierInfo()) {
+    IdentifierInfo &II =
+      AST.Idents.get(GlobII->getNameStart(),
+                     GlobII->getNameStart() + GlobII->getLength());
+    LocalName = DeclarationName(&II);
+  } else {
+    Selector GlobSel = Name.getObjCSelector();
+    assert(!GlobSel.isNull() && "A not handled yet declaration name");
+    GlobalSelector GSel =
+        GlobalSelector::getFromOpaquePtr(GlobSel.getAsOpaquePtr());
+    LocalName = GSel.getSelector(AST);
+  }
+
+  assert(LocalName);
+
+  DeclContext::lookup_result Res = DC->lookup(LocalName);
+  for (DeclContext::lookup_iterator I = Res.first, E = Res.second; I!=E; ++I) {
+    Decl *D = *I;
+    if (D->getIdentifierNamespace() == IdNS) {
+      if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+        if (MD->isInstanceMethod() == IsObjCInstanceMethod)
+          return MD;
+      } else
+        return D;
+    }
+  }
+
+  return 0; // Failed to find a decl using this Entity.
+}
+
+/// \brief Get an Entity associated with the given Decl.
+/// \returns Null if an Entity cannot refer to this Decl.
+Entity EntityImpl::get(Decl *D, Program &Prog, ProgramImpl &ProgImpl) {
+  assert(D && "Passed null Decl");
+  return EntityGetter(Prog, ProgImpl).Visit(D);
+}
+
+std::string EntityImpl::getPrintableName() {
+  return Name.getAsString();
+}
+
+//===----------------------------------------------------------------------===//
+// Entity Implementation
+//===----------------------------------------------------------------------===//
+
+Entity::Entity(Decl *D) : Val(D->getCanonicalDecl()) { }
+
+/// \brief Find the Decl that can be referred to by this entity.
+Decl *Entity::getDecl(ASTContext &AST) const {
+  if (isInvalid())
+    return 0;
+
+  if (Decl *D = Val.dyn_cast<Decl *>())
+    // Check that the passed AST is actually the one that this Decl belongs to.
+    return (&D->getASTContext() == &AST) ? D : 0;
+
+  return Val.get<EntityImpl *>()->getDecl(AST);
+}
+
+std::string Entity::getPrintableName() const {
+  if (isInvalid())
+    return "<< Invalid >>";
+
+  if (Decl *D = Val.dyn_cast<Decl *>()) {
+    if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
+      return ND->getNameAsString();
+    else
+      return std::string();
+  }
+
+  return Val.get<EntityImpl *>()->getPrintableName();
+}
+
+/// \brief Get an Entity associated with the given Decl.
+/// \returns Null if an Entity cannot refer to this Decl.
+Entity Entity::get(Decl *D, Program &Prog) {
+  if (D == 0)
+    return Entity();
+  ProgramImpl &ProgImpl = *static_cast<ProgramImpl*>(Prog.Impl);
+  return EntityImpl::get(D, Prog, ProgImpl);
+}
+
+unsigned
+llvm::DenseMapInfo<Entity>::getHashValue(Entity E) {
+  return DenseMapInfo<void*>::getHashValue(E.getAsOpaquePtr());
+}
diff --git a/lib/Index/EntityImpl.h b/lib/Index/EntityImpl.h
new file mode 100644
index 0000000..cbce934
--- /dev/null
+++ b/lib/Index/EntityImpl.h
@@ -0,0 +1,70 @@
+//===--- EntityImpl.h - Internal Entity implementation---------*- C++ -*-=====//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Internal implementation for the Entity class
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_ENTITYIMPL_H
+#define LLVM_CLANG_INDEX_ENTITYIMPL_H
+
+#include "clang/Index/Entity.h"
+#include "clang/AST/DeclarationName.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/StringSet.h"
+
+namespace clang {
+
+namespace idx {
+  class ProgramImpl;
+
+class EntityImpl : public llvm::FoldingSetNode {
+  Entity Parent;
+  DeclarationName Name;
+
+  /// \brief Identifier namespace.
+  unsigned IdNS;
+
+  /// \brief If Name is a selector, this keeps track whether it's for an
+  /// instance method.
+  bool IsObjCInstanceMethod;
+
+public:
+  EntityImpl(Entity parent, DeclarationName name, unsigned idNS,
+             bool isObjCInstanceMethod)
+    : Parent(parent), Name(name), IdNS(idNS),
+      IsObjCInstanceMethod(isObjCInstanceMethod) { }
+
+  /// \brief Find the Decl that can be referred to by this entity.
+  Decl *getDecl(ASTContext &AST);
+
+  /// \brief Get an Entity associated with the given Decl.
+  /// \returns Null if an Entity cannot refer to this Decl.
+  static Entity get(Decl *D, Program &Prog, ProgramImpl &ProgImpl);
+
+  std::string getPrintableName();
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    Profile(ID, Parent, Name, IdNS, IsObjCInstanceMethod);
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, Entity Parent,
+                      DeclarationName Name, unsigned IdNS,
+                      bool isObjCInstanceMethod) {
+    ID.AddPointer(Parent.getAsOpaquePtr());
+    ID.AddPointer(Name.getAsOpaquePtr());
+    ID.AddInteger(IdNS);
+    ID.AddBoolean(isObjCInstanceMethod);
+  }
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/lib/Index/GlobalSelector.cpp b/lib/Index/GlobalSelector.cpp
new file mode 100644
index 0000000..2b2ca6d
--- /dev/null
+++ b/lib/Index/GlobalSelector.cpp
@@ -0,0 +1,75 @@
+//===-- GlobalSelector.cpp - Cross-translation-unit "token" for selectors -===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  GlobalSelector is a ASTContext-independent way to refer to selectors.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/GlobalSelector.h"
+#include "ProgramImpl.h"
+#include "clang/Index/Program.h"
+#include "clang/AST/ASTContext.h"
+using namespace clang;
+using namespace idx;
+
+/// \brief Get the ASTContext-specific selector.
+Selector GlobalSelector::getSelector(ASTContext &AST) const {
+  if (isInvalid())
+    return Selector();
+
+  Selector GlobSel = Selector(reinterpret_cast<uintptr_t>(Val));
+
+  llvm::SmallVector<IdentifierInfo *, 8> Ids;
+  for (unsigned i = 0, e = GlobSel.isUnarySelector() ? 1 : GlobSel.getNumArgs();
+         i != e; ++i) {
+    IdentifierInfo *GlobII = GlobSel.getIdentifierInfoForSlot(i);
+    IdentifierInfo *II =
+      &AST.Idents.get(GlobII->getNameStart(),
+                      GlobII->getNameStart() + GlobII->getLength());
+    Ids.push_back(II);
+  }
+
+  return AST.Selectors.getSelector(GlobSel.getNumArgs(), Ids.data());
+}
+
+/// \brief Get a printable name for debugging purpose.
+std::string GlobalSelector::getPrintableName() const {
+  if (isInvalid())
+    return "<< Invalid >>";
+
+  Selector GlobSel = Selector(reinterpret_cast<uintptr_t>(Val));
+  return GlobSel.getAsString();
+}
+
+/// \brief Get a GlobalSelector for the ASTContext-specific selector.
+GlobalSelector GlobalSelector::get(Selector Sel, Program &Prog) {
+  if (Sel.isNull())
+    return GlobalSelector();
+
+  ProgramImpl &ProgImpl = *static_cast<ProgramImpl*>(Prog.Impl);
+
+  llvm::SmallVector<IdentifierInfo *, 8> Ids;
+  for (unsigned i = 0, e = Sel.isUnarySelector() ? 1 : Sel.getNumArgs();
+         i != e; ++i) {
+    IdentifierInfo *II = Sel.getIdentifierInfoForSlot(i);
+    IdentifierInfo *GlobII =
+      &ProgImpl.getIdents().get(II->getNameStart(),
+                                II->getNameStart() + II->getLength());
+    Ids.push_back(GlobII);
+  }
+
+  Selector GlobSel = ProgImpl.getSelectors().getSelector(Sel.getNumArgs(),
+                                                         Ids.data());
+  return GlobalSelector(GlobSel.getAsOpaquePtr());
+}
+
+unsigned
+llvm::DenseMapInfo<GlobalSelector>::getHashValue(GlobalSelector Sel) {
+  return DenseMapInfo<void*>::getHashValue(Sel.getAsOpaquePtr());
+}
diff --git a/lib/Index/Handlers.cpp b/lib/Index/Handlers.cpp
new file mode 100644
index 0000000..1e9a27d
--- /dev/null
+++ b/lib/Index/Handlers.cpp
@@ -0,0 +1,22 @@
+//===--- Handlers.cpp - Interfaces for receiving information ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Abstract interfaces for receiving information.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/Handlers.h"
+#include "clang/Index/Entity.h"
+using namespace clang;
+using namespace idx;
+
+// Out-of-line to give the virtual tables a home.
+EntityHandler::~EntityHandler() { }
+TranslationUnitHandler::~TranslationUnitHandler() { }
+TULocationHandler::~TULocationHandler() { }
diff --git a/lib/Index/IndexProvider.cpp b/lib/Index/IndexProvider.cpp
new file mode 100644
index 0000000..eea0988
--- /dev/null
+++ b/lib/Index/IndexProvider.cpp
@@ -0,0 +1,20 @@
+//===- IndexProvider.cpp - Maps information to translation units -*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Maps information to TranslationUnits.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/IndexProvider.h"
+#include "clang/Index/Entity.h"
+using namespace clang;
+using namespace idx;
+
+// Out-of-line to give the virtual table a home.
+IndexProvider::~IndexProvider() { }
diff --git a/lib/Index/Indexer.cpp b/lib/Index/Indexer.cpp
new file mode 100644
index 0000000..57bfc5b
--- /dev/null
+++ b/lib/Index/Indexer.cpp
@@ -0,0 +1,104 @@
+//===--- Indexer.cpp - IndexProvider implementation -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  IndexProvider implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/Indexer.h"
+#include "clang/Index/Program.h"
+#include "clang/Index/Handlers.h"
+#include "clang/Index/TranslationUnit.h"
+#include "ASTVisitor.h"
+#include "clang/AST/DeclBase.h"
+using namespace clang;
+using namespace idx;
+
+namespace {
+
+class EntityIndexer : public EntityHandler {
+  TranslationUnit *TU;
+  Indexer::MapTy &Map;
+
+public:
+  EntityIndexer(TranslationUnit *tu, Indexer::MapTy &map) : TU(tu), Map(map) { }
+
+  virtual void Handle(Entity Ent) {
+    if (Ent.isInternalToTU())
+      return;
+    Map[Ent].insert(TU);
+  }
+};
+
+class SelectorIndexer : public ASTVisitor<SelectorIndexer> {
+  Program &Prog;
+  TranslationUnit *TU;
+  Indexer::SelMapTy &Map;
+
+public:
+  SelectorIndexer(Program &prog, TranslationUnit *tu, Indexer::SelMapTy &map)
+    : Prog(prog), TU(tu), Map(map) { }
+
+  void VisitObjCMethodDecl(ObjCMethodDecl *D) {
+    Map[GlobalSelector::get(D->getSelector(), Prog)].insert(TU);
+    Base::VisitObjCMethodDecl(D);
+  }
+
+  void VisitObjCMessageExpr(ObjCMessageExpr *Node) {
+    Map[GlobalSelector::get(Node->getSelector(), Prog)].insert(TU);
+    Base::VisitObjCMessageExpr(Node);
+  }
+};
+
+} // anonymous namespace
+
+void Indexer::IndexAST(TranslationUnit *TU) {
+  assert(TU && "Passed null TranslationUnit");
+  ASTContext &Ctx = TU->getASTContext();
+  CtxTUMap[&Ctx] = TU;
+  EntityIndexer Idx(TU, Map);
+  Prog.FindEntities(Ctx, Idx);
+
+  SelectorIndexer SelIdx(Prog, TU, SelMap);
+  SelIdx.Visit(Ctx.getTranslationUnitDecl());
+}
+
+void Indexer::GetTranslationUnitsFor(Entity Ent,
+                                     TranslationUnitHandler &Handler) {
+  assert(Ent.isValid() && "Expected valid Entity");
+
+  if (Ent.isInternalToTU()) {
+    Decl *D = Ent.getInternalDecl();
+    CtxTUMapTy::iterator I = CtxTUMap.find(&D->getASTContext());
+    if (I != CtxTUMap.end())
+      Handler.Handle(I->second);
+    return;
+  }
+
+  MapTy::iterator I = Map.find(Ent);
+  if (I == Map.end())
+    return;
+
+  TUSetTy &Set = I->second;
+  for (TUSetTy::iterator I = Set.begin(), E = Set.end(); I != E; ++I)
+    Handler.Handle(*I);
+}
+
+void Indexer::GetTranslationUnitsFor(GlobalSelector Sel,
+                                    TranslationUnitHandler &Handler) {
+  assert(Sel.isValid() && "Expected valid GlobalSelector");
+
+  SelMapTy::iterator I = SelMap.find(Sel);
+  if (I == SelMap.end())
+    return;
+
+  TUSetTy &Set = I->second;
+  for (TUSetTy::iterator I = Set.begin(), E = Set.end(); I != E; ++I)
+    Handler.Handle(*I);
+}
diff --git a/lib/Index/Makefile b/lib/Index/Makefile
new file mode 100644
index 0000000..9d33a2d
--- /dev/null
+++ b/lib/Index/Makefile
@@ -0,0 +1,27 @@
+##===- clang/lib/Index/Makefile ----------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+#
+#  This implements the Indexer library for the C-Language front-end.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+include $(LEVEL)/Makefile.config
+
+LIBRARYNAME := clangIndex
+BUILD_ARCHIVE = 1
+
+ifeq ($(ARCH),PowerPC)
+CXXFLAGS += -maltivec
+endif
+
+CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Index/Program.cpp b/lib/Index/Program.cpp
new file mode 100644
index 0000000..4efad2c
--- /dev/null
+++ b/lib/Index/Program.cpp
@@ -0,0 +1,50 @@
+//===--- Program.cpp - Entity originator and misc -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Storage for Entities and utility functions
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/Program.h"
+#include "ProgramImpl.h"
+#include "clang/Index/Handlers.h"
+#include "clang/Index/TranslationUnit.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/ASTContext.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+using namespace idx;
+
+// Out-of-line to give the virtual tables a home.
+TranslationUnit::~TranslationUnit() { }
+
+Program::Program() : Impl(new ProgramImpl()) { }
+
+Program::~Program() {
+  delete static_cast<ProgramImpl *>(Impl);
+}
+
+static void FindEntitiesInDC(DeclContext *DC, Program &Prog,
+                             EntityHandler &Handler) {
+  for (DeclContext::decl_iterator
+         I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
+    if (I->getLocation().isInvalid())
+      continue;
+    Entity Ent = Entity::get(*I, Prog);
+    if (Ent.isValid())
+      Handler.Handle(Ent);
+    if (DeclContext *SubDC = dyn_cast<DeclContext>(*I))
+      FindEntitiesInDC(SubDC, Prog, Handler);
+  }
+}
+
+/// \brief Traverses the AST and passes all the entities to the Handler.
+void Program::FindEntities(ASTContext &Ctx, EntityHandler &Handler) {
+  FindEntitiesInDC(Ctx.getTranslationUnitDecl(), *this, Handler);
+}
diff --git a/lib/Index/ProgramImpl.h b/lib/Index/ProgramImpl.h
new file mode 100644
index 0000000..57b9ce3
--- /dev/null
+++ b/lib/Index/ProgramImpl.h
@@ -0,0 +1,56 @@
+//===--- ProgramImpl.h - Internal Program implementation---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Internal implementation for the Program class
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_PROGRAMIMPL_H
+#define LLVM_CLANG_INDEX_PROGRAMIMPL_H
+
+#include "EntityImpl.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LangOptions.h"
+
+namespace clang {
+
+namespace idx {
+  class EntityListener;
+
+class ProgramImpl {
+public:
+  typedef llvm::FoldingSet<EntityImpl> EntitySetTy;
+
+private:
+  EntitySetTy Entities;
+  llvm::BumpPtrAllocator BumpAlloc;
+
+  IdentifierTable Identifiers;
+  SelectorTable Selectors;
+
+  ProgramImpl(const ProgramImpl&); // do not implement
+  ProgramImpl &operator=(const ProgramImpl &); // do not implement
+
+public:
+  ProgramImpl() : Identifiers(LangOptions()) { }
+
+  EntitySetTy &getEntities() { return Entities; }
+  IdentifierTable &getIdents() { return Identifiers; }
+  SelectorTable &getSelectors() { return Selectors; }
+
+  void *Allocate(unsigned Size, unsigned Align = 8) {
+    return BumpAlloc.Allocate(Size, Align);
+  }
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/lib/Index/ResolveLocation.cpp b/lib/Index/ResolveLocation.cpp
new file mode 100644
index 0000000..4bb1594
--- /dev/null
+++ b/lib/Index/ResolveLocation.cpp
@@ -0,0 +1,613 @@
+//===--- ResolveLocation.cpp - Source location resolver ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This defines the ResolveLocationInAST function, which resolves a
+//  source location into a ASTLocation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/Utils.h"
+#include "clang/Index/ASTLocation.h"
+#include "clang/AST/TypeLocVisitor.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Basic/SourceManager.h"
+using namespace clang;
+using namespace idx;
+
+namespace {
+
+/// \brief Base for the LocResolver classes. Mostly does source range checking.
+class LocResolverBase {
+protected:
+  ASTContext &Ctx;
+  SourceLocation Loc;
+  
+  ASTLocation ResolveInDeclarator(Decl *D, Stmt *Stm, TypeSourceInfo *TInfo);
+
+  enum RangePos {
+    BeforeLoc,
+    ContainsLoc,
+    AfterLoc
+  };
+
+  RangePos CheckRange(SourceRange Range);
+  RangePos CheckRange(TypeSourceInfo *TInfo);
+  RangePos CheckRange(Decl *D) {
+    if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
+      if (ContainsLocation(DD->getTypeSourceInfo()))
+        return ContainsLoc;
+    if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
+      if (ContainsLocation(TD->getTypeSourceInfo()))
+        return ContainsLoc;
+
+    return CheckRange(D->getSourceRange());
+  }
+  RangePos CheckRange(Stmt *Node) { return CheckRange(Node->getSourceRange()); }
+  RangePos CheckRange(TypeLoc TL) { return CheckRange(TL.getSourceRange()); }
+
+  template <typename T>
+  bool isBeforeLocation(T Node) {
+    return CheckRange(Node) == BeforeLoc;
+  }
+
+  template <typename T>
+  bool isAfterLocation(T Node) {
+    return CheckRange(Node) == AfterLoc;
+  }
+
+public:
+  LocResolverBase(ASTContext &ctx, SourceLocation loc)
+    : Ctx(ctx), Loc(loc) {}
+    
+  template <typename T>
+  bool ContainsLocation(T Node) {
+    return CheckRange(Node) == ContainsLoc;
+  }
+
+#ifndef NDEBUG
+  /// \brief Debugging output.
+  void print(Decl *D);
+  /// \brief Debugging output.
+  void print(Stmt *Node);
+#endif
+};
+
+/// \brief Searches a statement for the ASTLocation that corresponds to a source
+/// location.
+class StmtLocResolver : public LocResolverBase,
+                                          public StmtVisitor<StmtLocResolver,
+                                                             ASTLocation     > {
+  Decl * const Parent;
+
+public:
+  StmtLocResolver(ASTContext &ctx, SourceLocation loc, Decl *parent)
+    : LocResolverBase(ctx, loc), Parent(parent) {}
+
+  ASTLocation VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node);
+  ASTLocation VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node);
+  ASTLocation VisitDeclStmt(DeclStmt *Node);
+  ASTLocation VisitStmt(Stmt *Node);
+};
+
+/// \brief Searches a declaration for the ASTLocation that corresponds to a
+/// source location.
+class DeclLocResolver : public LocResolverBase,
+                                          public DeclVisitor<DeclLocResolver,
+                                                             ASTLocation     > {
+public:
+  DeclLocResolver(ASTContext &ctx, SourceLocation loc)
+    : LocResolverBase(ctx, loc) {}
+
+  ASTLocation VisitDeclContext(DeclContext *DC);
+  ASTLocation VisitTranslationUnitDecl(TranslationUnitDecl *TU);
+  ASTLocation VisitDeclaratorDecl(DeclaratorDecl *D);
+  ASTLocation VisitVarDecl(VarDecl *D);
+  ASTLocation VisitFunctionDecl(FunctionDecl *D);
+  ASTLocation VisitObjCClassDecl(ObjCClassDecl *D);                                                             
+  ASTLocation VisitObjCMethodDecl(ObjCMethodDecl *D);
+  ASTLocation VisitTypedefDecl(TypedefDecl *D);
+  ASTLocation VisitDecl(Decl *D);
+};
+
+class TypeLocResolver : public LocResolverBase,
+                        public TypeLocVisitor<TypeLocResolver, ASTLocation> {
+  Decl * const ParentDecl;
+
+public:
+  TypeLocResolver(ASTContext &ctx, SourceLocation loc, Decl *pd)
+    : LocResolverBase(ctx, loc), ParentDecl(pd) { }
+
+  ASTLocation VisitBuiltinTypeLoc(BuiltinTypeLoc TL);
+  ASTLocation VisitTypedefTypeLoc(TypedefTypeLoc TL);
+  ASTLocation VisitFunctionTypeLoc(FunctionTypeLoc TL);
+  ASTLocation VisitArrayTypeLoc(ArrayTypeLoc TL);
+  ASTLocation VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
+  ASTLocation VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
+  ASTLocation VisitTypeLoc(TypeLoc TL);
+};
+
+} // anonymous namespace
+
+ASTLocation
+StmtLocResolver::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
+  assert(ContainsLocation(Node) &&
+         "Should visit only after verifying that loc is in range");
+
+  if (Node->isArgumentType()) {
+    TypeSourceInfo *TInfo = Node->getArgumentTypeInfo();
+    if (ContainsLocation(TInfo))
+      return ResolveInDeclarator(Parent, Node, TInfo);
+  } else {
+    Expr *SubNode = Node->getArgumentExpr();
+    if (ContainsLocation(SubNode))
+      return Visit(SubNode);
+  }
+
+  return ASTLocation(Parent, Node);
+}
+
+
+ASTLocation
+StmtLocResolver::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
+  assert(ContainsLocation(Node) &&
+         "Should visit only after verifying that loc is in range");
+
+  if (Node->getNumArgs() == 1)
+    // Unary operator. Let normal child traversal handle it.
+    return VisitCallExpr(Node);
+
+  assert(Node->getNumArgs() == 2 &&
+         "Wrong args for the C++ operator call expr ?");
+
+  llvm::SmallVector<Expr *, 3> Nodes;
+  // Binary operator. Check in order of 1-left arg, 2-callee, 3-right arg.
+  Nodes.push_back(Node->getArg(0));
+  Nodes.push_back(Node->getCallee());
+  Nodes.push_back(Node->getArg(1));
+
+  for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
+    RangePos RP = CheckRange(Nodes[i]);
+    if (RP == AfterLoc)
+      break;
+    if (RP == ContainsLoc)
+      return Visit(Nodes[i]);
+  }
+
+  return ASTLocation(Parent, Node);
+}
+
+ASTLocation StmtLocResolver::VisitDeclStmt(DeclStmt *Node) {
+  assert(ContainsLocation(Node) &&
+         "Should visit only after verifying that loc is in range");
+
+  // Search all declarations of this DeclStmt.
+  for (DeclStmt::decl_iterator
+         I = Node->decl_begin(), E = Node->decl_end(); I != E; ++I) {
+    RangePos RP = CheckRange(*I);
+    if (RP == AfterLoc)
+      break;
+    if (RP == ContainsLoc)
+      return DeclLocResolver(Ctx, Loc).Visit(*I);
+  }
+
+  return ASTLocation(Parent, Node);
+}
+
+ASTLocation StmtLocResolver::VisitStmt(Stmt *Node) {
+  assert(ContainsLocation(Node) &&
+         "Should visit only after verifying that loc is in range");
+
+  // Search the child statements.
+  for (Stmt::child_iterator
+         I = Node->child_begin(), E = Node->child_end(); I != E; ++I) {
+    if (*I == NULL)
+      continue;
+
+    RangePos RP = CheckRange(*I);
+    if (RP == AfterLoc)
+      break;
+    if (RP == ContainsLoc)
+      return Visit(*I);
+  }
+
+  return ASTLocation(Parent, Node);
+}
+
+ASTLocation DeclLocResolver::VisitDeclContext(DeclContext *DC) {
+  for (DeclContext::decl_iterator
+         I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
+    RangePos RP = CheckRange(*I);
+    if (RP == AfterLoc)
+      break;
+    if (RP == ContainsLoc)
+      return Visit(*I);
+  }
+
+  return ASTLocation(cast<Decl>(DC));
+}
+
+ASTLocation DeclLocResolver::VisitTranslationUnitDecl(TranslationUnitDecl *TU) {
+  ASTLocation ASTLoc = VisitDeclContext(TU);
+  if (ASTLoc.getParentDecl() == TU)
+    return ASTLocation();
+  return ASTLoc;
+}
+
+ASTLocation DeclLocResolver::VisitFunctionDecl(FunctionDecl *D) {
+  assert(ContainsLocation(D) &&
+         "Should visit only after verifying that loc is in range");
+
+  if (ContainsLocation(D->getTypeSourceInfo()))
+    return ResolveInDeclarator(D, 0, D->getTypeSourceInfo());
+
+  // First, search through the parameters of the function.
+  for (FunctionDecl::param_iterator
+         I = D->param_begin(), E = D->param_end(); I != E; ++I) {
+    RangePos RP = CheckRange(*I);
+    if (RP == AfterLoc)
+      return ASTLocation(D);
+    if (RP == ContainsLoc)
+      return Visit(*I);
+  }
+
+  // We didn't find the location in the parameters and we didn't get passed it.
+
+  if (!D->isThisDeclarationADefinition())
+    return ASTLocation(D);
+
+  // Second, search through the declarations that are part of the function.
+  // If we find the location there, we won't have to search through its body.
+
+  for (DeclContext::decl_iterator
+         I = D->decls_begin(), E = D->decls_end(); I != E; ++I) {
+    if (isa<ParmVarDecl>(*I))
+      continue; // We already searched through the parameters.
+
+    RangePos RP = CheckRange(*I);
+    if (RP == AfterLoc)
+      break;
+    if (RP == ContainsLoc)
+      return Visit(*I);
+  }
+
+  // We didn't find a declaration that corresponds to the source location.
+
+  // Finally, search through the body of the function.
+  Stmt *Body = D->getBody();
+  assert(Body && "Expected definition");
+  assert(!isBeforeLocation(Body) &&
+         "This function is supposed to contain the loc");
+  if (isAfterLocation(Body))
+    return ASTLocation(D);
+
+  // The body contains the location.
+  assert(ContainsLocation(Body));
+  return StmtLocResolver(Ctx, Loc, D).Visit(Body);
+}
+
+ASTLocation DeclLocResolver::VisitDeclaratorDecl(DeclaratorDecl *D) {
+  assert(ContainsLocation(D) &&
+         "Should visit only after verifying that loc is in range");
+  if (ContainsLocation(D->getTypeSourceInfo()))
+    return ResolveInDeclarator(D, /*Stmt=*/0, D->getTypeSourceInfo());
+
+  return ASTLocation(D);
+}
+
+ASTLocation DeclLocResolver::VisitTypedefDecl(TypedefDecl *D) {
+  assert(ContainsLocation(D) &&
+         "Should visit only after verifying that loc is in range");
+
+  if (ContainsLocation(D->getTypeSourceInfo()))
+    return ResolveInDeclarator(D, /*Stmt=*/0, D->getTypeSourceInfo());
+
+  return ASTLocation(D);
+}
+
+ASTLocation DeclLocResolver::VisitVarDecl(VarDecl *D) {
+  assert(ContainsLocation(D) &&
+         "Should visit only after verifying that loc is in range");
+
+  // Check whether the location points to the init expression.
+  Expr *Init = D->getInit();
+  if (Init && ContainsLocation(Init))
+    return StmtLocResolver(Ctx, Loc, D).Visit(Init);
+  
+  if (ContainsLocation(D->getTypeSourceInfo()))
+    return ResolveInDeclarator(D, 0, D->getTypeSourceInfo());
+
+  return ASTLocation(D);
+}
+
+ASTLocation DeclLocResolver::VisitObjCClassDecl(ObjCClassDecl *D) {
+  assert(ContainsLocation(D) &&
+         "Should visit only after verifying that loc is in range");
+         
+  for (ObjCClassDecl::iterator I = D->begin(), E = D->end() ; I != E; ++I) {
+    if (CheckRange(I->getLocation()) == ContainsLoc)
+      return ASTLocation(D, I->getInterface(), I->getLocation());
+  }
+  return ASTLocation(D);
+}
+
+ASTLocation DeclLocResolver::VisitObjCMethodDecl(ObjCMethodDecl *D) {
+  assert(ContainsLocation(D) &&
+         "Should visit only after verifying that loc is in range");
+
+  // First, search through the parameters of the method.
+  for (ObjCMethodDecl::param_iterator
+         I = D->param_begin(), E = D->param_end(); I != E; ++I) {
+    RangePos RP = CheckRange(*I);
+    if (RP == AfterLoc)
+      return ASTLocation(D);
+    if (RP == ContainsLoc)
+      return Visit(*I);
+  }
+
+  // We didn't find the location in the parameters and we didn't get passed it.
+
+  if (!D->getBody())
+    return ASTLocation(D);
+
+  // Second, search through the declarations that are part of the method.
+  // If we find he location there, we won't have to search through its body.
+
+  for (DeclContext::decl_iterator
+         I = D->decls_begin(), E = D->decls_end(); I != E; ++I) {
+    if (isa<ParmVarDecl>(*I))
+      continue; // We already searched through the parameters.
+
+    RangePos RP = CheckRange(*I);
+    if (RP == AfterLoc)
+      break;
+    if (RP == ContainsLoc)
+      return Visit(*I);
+  }
+
+  // We didn't find a declaration that corresponds to the source location.
+
+  // Finally, search through the body of the method.
+  Stmt *Body = D->getBody();
+  assert(Body && "Expected definition");
+  assert(!isBeforeLocation(Body) &&
+         "This method is supposed to contain the loc");
+  if (isAfterLocation(Body))
+    return ASTLocation(D);
+
+  // The body contains the location.
+  assert(ContainsLocation(Body));
+  return StmtLocResolver(Ctx, Loc, D).Visit(Body);
+}
+
+ASTLocation DeclLocResolver::VisitDecl(Decl *D) {
+  assert(ContainsLocation(D) &&
+         "Should visit only after verifying that loc is in range");
+  if (DeclContext *DC = dyn_cast<DeclContext>(D))
+    return VisitDeclContext(DC);
+  return ASTLocation(D);
+}
+
+ASTLocation TypeLocResolver::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
+  // Continue the 'id' magic by making the builtin type (which cannot
+  // actually be spelled) map to the typedef.
+  BuiltinType *T = TL.getTypePtr();
+  if (T->getKind() == BuiltinType::ObjCId) {
+    TypedefDecl *D = Ctx.getObjCIdType()->getAs<TypedefType>()->getDecl();
+    return ASTLocation(ParentDecl, D, TL.getNameLoc());
+  }
+
+  // Same thing with 'Class'.
+  if (T->getKind() == BuiltinType::ObjCClass) {
+    TypedefDecl *D = Ctx.getObjCClassType()->getAs<TypedefType>()->getDecl();
+    return ASTLocation(ParentDecl, D, TL.getNameLoc());
+  }
+
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation TypeLocResolver::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+  assert(ContainsLocation(TL) &&
+         "Should visit only after verifying that loc is in range");
+  if (ContainsLocation(TL.getNameLoc()))
+    return ASTLocation(ParentDecl, TL.getTypedefDecl(), TL.getNameLoc());
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation TypeLocResolver::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
+  assert(ContainsLocation(TL) &&
+         "Should visit only after verifying that loc is in range");
+
+  for (unsigned i = 0; i != TL.getNumArgs(); ++i) {
+    ParmVarDecl *Parm = TL.getArg(i);
+    RangePos RP = CheckRange(Parm);
+    if (RP == AfterLoc)
+      break;
+    if (RP == ContainsLoc)
+      return DeclLocResolver(Ctx, Loc).Visit(Parm);
+  }
+
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation TypeLocResolver::VisitArrayTypeLoc(ArrayTypeLoc TL) {
+  assert(ContainsLocation(TL) &&
+         "Should visit only after verifying that loc is in range");
+
+  Expr *E = TL.getSizeExpr();
+  if (E && ContainsLocation(E))
+    return StmtLocResolver(Ctx, Loc, ParentDecl).Visit(E);
+
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation TypeLocResolver::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
+  assert(ContainsLocation(TL) &&
+         "Should visit only after verifying that loc is in range");
+  if (ContainsLocation(TL.getNameLoc()))
+    return ASTLocation(ParentDecl, TL.getIFaceDecl(), TL.getNameLoc());
+
+  for (unsigned i = 0; i != TL.getNumProtocols(); ++i) {
+    SourceLocation L = TL.getProtocolLoc(i);
+    RangePos RP = CheckRange(L);
+    if (RP == AfterLoc)
+      break;
+    if (RP == ContainsLoc)
+      return ASTLocation(ParentDecl, TL.getProtocol(i), L);
+  }
+
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation TypeLocResolver::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
+  assert(ContainsLocation(TL) &&
+         "Should visit only after verifying that loc is in range");
+
+  if (TL.hasProtocolsAsWritten()) {
+    for (unsigned i = 0; i != TL.getNumProtocols(); ++i) {
+      SourceLocation L = TL.getProtocolLoc(i);
+      RangePos RP = CheckRange(L);
+      if (RP == AfterLoc)
+        break;
+      if (RP == ContainsLoc)
+        return ASTLocation(ParentDecl, TL.getProtocol(i), L);
+    }
+  }
+
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation TypeLocResolver::VisitTypeLoc(TypeLoc TL) {
+  assert(ContainsLocation(TL) &&
+         "Should visit only after verifying that loc is in range");
+  return ASTLocation(ParentDecl, TL);
+}
+
+ASTLocation LocResolverBase::ResolveInDeclarator(Decl *D, Stmt *Stm,
+                                                 TypeSourceInfo *TInfo) {
+  assert(ContainsLocation(TInfo) &&
+         "Should visit only after verifying that loc is in range");
+  
+  (void)TypeLocResolver(Ctx, Loc, D);
+  for (TypeLoc TL = TInfo->getTypeLoc(); TL; TL = TL.getNextTypeLoc())
+    if (ContainsLocation(TL))
+      return TypeLocResolver(Ctx, Loc, D).Visit(TL);
+  
+  assert(0 && "Should have found the loc in a typeloc");
+  return ASTLocation(D, Stm);
+}
+
+LocResolverBase::RangePos LocResolverBase::CheckRange(TypeSourceInfo *TInfo) {
+  if (!TInfo)
+    return BeforeLoc; // Keep looking.
+
+  for (TypeLoc TL = TInfo->getTypeLoc(); TL; TL = TL.getNextTypeLoc())
+    if (ContainsLocation(TL))
+      return ContainsLoc;
+
+  return BeforeLoc; // Keep looking.
+}
+
+LocResolverBase::RangePos LocResolverBase::CheckRange(SourceRange Range) {
+  if (!Range.isValid())
+    return BeforeLoc; // Keep looking.
+
+  // Update the end source range to cover the full length of the token
+  // positioned at the end of the source range.
+  //
+  // e.g.,
+  //   int foo
+  //   ^   ^
+  //
+  // will be updated to
+  //   int foo
+  //   ^     ^
+  unsigned TokSize = Lexer::MeasureTokenLength(Range.getEnd(),
+                                               Ctx.getSourceManager(),
+                                               Ctx.getLangOptions());
+  Range.setEnd(Range.getEnd().getFileLocWithOffset(TokSize-1));
+
+  SourceManager &SourceMgr = Ctx.getSourceManager();
+  if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), Loc))
+    return BeforeLoc;
+
+  if (SourceMgr.isBeforeInTranslationUnit(Loc, Range.getBegin()))
+    return AfterLoc;
+
+  return ContainsLoc;
+}
+
+#ifndef NDEBUG
+void LocResolverBase::print(Decl *D) {
+  llvm::raw_ostream &OS = llvm::outs();
+  OS << "#### DECL " << D->getDeclKindName() << " ####\n";
+  D->print(OS);
+  OS << " <";
+  D->getLocStart().print(OS, Ctx.getSourceManager());
+  OS << " > - <";
+  D->getLocEnd().print(OS, Ctx.getSourceManager());
+  OS << ">\n\n";
+  OS.flush();
+}
+
+void LocResolverBase::print(Stmt *Node) {
+  llvm::raw_ostream &OS = llvm::outs();
+  OS << "#### STMT " << Node->getStmtClassName() << " ####\n";
+  Node->printPretty(OS, Ctx, 0, PrintingPolicy(Ctx.getLangOptions()));
+  OS << " <";
+  Node->getLocStart().print(OS, Ctx.getSourceManager());
+  OS << " > - <";
+  Node->getLocEnd().print(OS, Ctx.getSourceManager());
+  OS << ">\n\n";
+  OS.flush();
+}
+#endif
+
+
+/// \brief Returns the AST node that a source location points to.
+///
+ASTLocation idx::ResolveLocationInAST(ASTContext &Ctx, SourceLocation Loc,
+                                      ASTLocation *LastLoc) {
+  if (Loc.isInvalid())
+    return ASTLocation();
+
+  if (LastLoc && LastLoc->isValid()) {
+    DeclContext *DC = 0;
+  
+    if (Decl *Dcl = LastLoc->dyn_AsDecl()) {
+      DC = Dcl->getDeclContext();
+    } else if (LastLoc->isStmt()) {
+      Decl *Parent = LastLoc->getParentDecl();
+      if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Parent))
+        DC = FD;
+      else { 
+        // This is needed to handle statements within an initializer.
+        // Example:
+        //   void func() { long double fabsf = __builtin_fabsl(__x); }
+        // In this case, the 'parent' of __builtin_fabsl is fabsf.
+        DC = Parent->getDeclContext();
+      }
+    } else { // We have 'N_NamedRef' or 'N_Type'
+      DC = LastLoc->getParentDecl()->getDeclContext();
+    } 
+    assert(DC && "Missing DeclContext");
+    
+    FunctionDecl *FD = dyn_cast<FunctionDecl>(DC);
+    DeclLocResolver DLocResolver(Ctx, Loc);
+    
+    if (FD && FD->isThisDeclarationADefinition() &&
+        DLocResolver.ContainsLocation(FD)) {
+      return DLocResolver.VisitFunctionDecl(FD);
+    }
+    // Fall through and try the slow path...
+    // FIXME: Optimize more cases.
+  }
+  return DeclLocResolver(Ctx, Loc).Visit(Ctx.getTranslationUnitDecl());
+}
diff --git a/lib/Index/SelectorMap.cpp b/lib/Index/SelectorMap.cpp
new file mode 100644
index 0000000..0f11e31
--- /dev/null
+++ b/lib/Index/SelectorMap.cpp
@@ -0,0 +1,84 @@
+//===- SelectorMap.cpp - Maps selectors to methods and messages -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  SelectorMap creates a mapping from selectors to ObjC method declarations
+//  and ObjC message expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/SelectorMap.h"
+#include "ASTVisitor.h"
+using namespace clang;
+using namespace idx;
+
+namespace {
+
+class SelMapper : public ASTVisitor<SelMapper> {
+  SelectorMap::SelMethMapTy &SelMethMap;
+  SelectorMap::SelRefMapTy &SelRefMap;
+
+public:
+  SelMapper(SelectorMap::SelMethMapTy &MethMap,
+            SelectorMap::SelRefMapTy &RefMap)
+    : SelMethMap(MethMap), SelRefMap(RefMap) { }
+
+  void VisitObjCMethodDecl(ObjCMethodDecl *D);
+  void VisitObjCMessageExpr(ObjCMessageExpr *Node);
+  void VisitObjCSelectorExpr(ObjCSelectorExpr *Node);
+};
+
+} // anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// SelMapper Implementation
+//===----------------------------------------------------------------------===//
+
+void SelMapper::VisitObjCMethodDecl(ObjCMethodDecl *D) {
+  if (D->getCanonicalDecl() == D)
+    SelMethMap.insert(std::make_pair(D->getSelector(), D));
+  Base::VisitObjCMethodDecl(D);
+}
+
+void SelMapper::VisitObjCMessageExpr(ObjCMessageExpr *Node) {
+  ASTLocation ASTLoc(CurrentDecl, Node);
+  SelRefMap.insert(std::make_pair(Node->getSelector(), ASTLoc));
+}
+
+void SelMapper::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
+  ASTLocation ASTLoc(CurrentDecl, Node);
+  SelRefMap.insert(std::make_pair(Node->getSelector(), ASTLoc));
+}
+
+//===----------------------------------------------------------------------===//
+// SelectorMap Implementation
+//===----------------------------------------------------------------------===//
+
+SelectorMap::SelectorMap(ASTContext &Ctx) {
+  SelMapper(SelMethMap, SelRefMap).Visit(Ctx.getTranslationUnitDecl());
+}
+
+SelectorMap::method_iterator
+SelectorMap::methods_begin(Selector Sel) const {
+  return method_iterator(SelMethMap.lower_bound(Sel));
+}
+
+SelectorMap::method_iterator
+SelectorMap::methods_end(Selector Sel) const {
+  return method_iterator(SelMethMap.upper_bound(Sel));
+}
+
+SelectorMap::astlocation_iterator
+SelectorMap::refs_begin(Selector Sel) const {
+  return astlocation_iterator(SelRefMap.lower_bound(Sel));
+}
+
+SelectorMap::astlocation_iterator
+SelectorMap::refs_end(Selector Sel) const {
+  return astlocation_iterator(SelRefMap.upper_bound(Sel));
+}