Introduce the 'Index' library.

Its purpose is to provide the basic infrastructure for cross-translation-unit analysis like indexing, refactoring, etc.

Currently it is very "primitive" and with no type-names support. It can provide functionality like
"show me all references of this function from these translation units".

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74802 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Index/Entity.cpp b/lib/Index/Entity.cpp
new file mode 100644
index 0000000..c1d8702
--- /dev/null
+++ b/lib/Index/Entity.cpp
@@ -0,0 +1,132 @@
+//===--- Entity.h - Cross-translation-unit "token" for decls ----*- C++ -*-===//
+//
+//                     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 "clang/Index/Entity.h"
+#include "clang/Index/Program.h"
+#include "ProgramImpl.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 *> {
+  ProgramImpl &Prog;
+  
+public:
+  EntityGetter(ProgramImpl &prog) : Prog(prog) { }
+  
+  Entity *get(Entity *Parent, DeclarationName Name);
+  
+  Entity *VisitNamedDecl(NamedDecl *D);
+  Entity *VisitVarDecl(VarDecl *D);
+  Entity *VisitFunctionDecl(FunctionDecl *D); 
+};
+
+}
+}
+
+Entity *EntityGetter::get(Entity *Parent, DeclarationName Name) {
+  // FIXME: Only works for DeclarationNames that are identifiers.
+
+  if (!Name.isIdentifier())
+    return 0;
+
+  IdentifierInfo *II = Name.getAsIdentifierInfo();
+  ProgramImpl::IdEntryTy *Id =
+      &Prog.getIdents().GetOrCreateValue(II->getName(),
+                                         II->getName() + II->getLength());
+  
+  llvm::FoldingSetNodeID ID;
+  Entity::Profile(ID, Parent, Id);
+  
+  ProgramImpl::EntitySetTy &Entities = Prog.getEntities();
+  void *InsertPos = 0;
+  if (Entity *Ent = Entities.FindNodeOrInsertPos(ID, InsertPos))
+    return Ent;
+  
+  void *Buf = Prog.Allocate(sizeof(Entity));
+  Entity *New = new (Buf) Entity(Parent, Id);
+  Entities.InsertNode(New, InsertPos);
+  return New;
+}
+
+Entity *EntityGetter::VisitNamedDecl(NamedDecl *D) {
+  // FIXME: Function declarations that are inside functions ?
+  if (!D->getDeclContext()->isFileContext())
+    return 0;
+
+  Entity *Parent = Visit(cast<Decl>(D->getDeclContext()));
+  return get(Parent, D->getDeclName());
+}
+
+Entity *EntityGetter::VisitVarDecl(VarDecl *D) {
+  // If it's static it cannot be referred to by another translation unit.
+  if (D->getStorageClass() == VarDecl::Static)
+    return 0;
+  
+  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 0;
+  
+  return VisitNamedDecl(D);
+}
+
+//===----------------------------------------------------------------------===//
+// Entity Implementation
+//===----------------------------------------------------------------------===//
+
+/// \brief Find the Decl that can be referred to by this entity.
+Decl *Entity::getDecl(ASTContext &AST) {
+  DeclContext *DC =
+    Parent == 0 ? AST.getTranslationUnitDecl()
+                : cast<DeclContext>(Parent->getDecl(AST));
+  if (!DC)
+    return 0; // Couldn't get the parent context.
+    
+  ProgramImpl::IdEntryTy *Entry = static_cast<ProgramImpl::IdEntryTy *>(Id);
+  IdentifierInfo &II = AST.Idents.get(Entry->getKeyData());
+  
+  DeclContext::lookup_result Res = DC->lookup(DeclarationName(&II));
+  for (DeclContext::lookup_iterator I = Res.first, E = Res.second; I!=E; ++I) {
+    if (!isa<TagDecl>(*I))
+      return *I;
+  }
+
+  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 *Entity::get(Decl *D, Program &Prog) {
+  assert(D && "Passed null Decl");
+  ProgramImpl &Impl = *static_cast<ProgramImpl*>(Prog.Impl);
+  return EntityGetter(Impl).Visit(D);
+}