[cfe-commits] r142233 - in /cfe/trunk: include/clang-c/Index.h tools/c-index-test/c-index-test.c tools/libclang/CIndex.cpp tools/libclang/CIndexUSRs.cpp tools/libclang/CMakeLists.txt tools/libclang/CXCursor.cpp tools/libclang/CXCursor.h tools/libclang

James Molloy james.molloy at arm.com
Thu Oct 20 00:40:37 PDT 2011


Hi Argyrios,

Sorry to bring this up but our internal builders have been down for the past
few days.

This commit breaks our Clang build, because you've put a C++-style comment
in C code:

c-index-test.c:1542 r142233 akirtzidis  // FIXME: free these.

Could you please fix this comment?

Thanks,

James

-----Original Message-----
From: cfe-commits-bounces at cs.uiuc.edu
[mailto:cfe-commits-bounces at cs.uiuc.edu] On Behalf Of Argyrios Kyrtzidis
Sent: 17 October 2011 20:48
To: cfe-commits at cs.uiuc.edu
Subject: [cfe-commits] r142233 - in /cfe/trunk: include/clang-c/Index.h
tools/c-index-test/c-index-test.c tools/libclang/CIndex.cpp
tools/libclang/CIndexUSRs.cpp tools/libclang/CMakeLists.txt
tools/libclang/CXCursor.cpp tools/libclang/CXCursor.h tools/libclang/...

Author: akirtzidis
Date: Mon Oct 17 14:48:19 2011
New Revision: 142233

URL: http://llvm.org/viewvc/llvm-project?rev=142233&view=rev
Log:
[libclang] Introduce a new high level API for indexing clients that assumes
more of the work involved in indexing a translation unit and simplifies
client
implementations.

Only C/ObjC for now, C++ (and comments) to come.

Added:
    cfe/trunk/tools/libclang/IndexBody.cpp
    cfe/trunk/tools/libclang/IndexDecl.cpp
    cfe/trunk/tools/libclang/IndexTypeSourceInfo.cpp
    cfe/trunk/tools/libclang/Indexing.cpp
    cfe/trunk/tools/libclang/IndexingContext.cpp
    cfe/trunk/tools/libclang/IndexingContext.h
Modified:
    cfe/trunk/include/clang-c/Index.h
    cfe/trunk/tools/c-index-test/c-index-test.c
    cfe/trunk/tools/libclang/CIndex.cpp
    cfe/trunk/tools/libclang/CIndexUSRs.cpp
    cfe/trunk/tools/libclang/CMakeLists.txt
    cfe/trunk/tools/libclang/CXCursor.cpp
    cfe/trunk/tools/libclang/CXCursor.h
    cfe/trunk/tools/libclang/CXTranslationUnit.h
    cfe/trunk/tools/libclang/libclang.exports

Modified: cfe/trunk/include/clang-c/Index.h
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=14
2233&r1=142232&r2=142233&view=diff
============================================================================
==
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Mon Oct 17 14:48:19 2011
@@ -3855,6 +3855,329 @@
 #  endif
 #endif
 
+typedef void *CXIdxFile;
+typedef void *CXIdxEntity;
+typedef void *CXIdxContainer;
+typedef void *CXIdxMacro;
+typedef void *CXIdxASTFile;
+
+typedef struct {
+  void *ptr_data[2];
+  unsigned int_data;
+} CXIdxLoc;
+
+typedef struct {
+  CXIdxLoc hashLoc;
+  const char *filename;
+  CXIdxFile file;
+  int isImport;
+  int isAngled;
+} CXIdxIncludedFileInfo;
+
+typedef struct {
+  CXFile file;
+  CXIdxLoc loc;
+  int isModule;
+} CXIdxImportedASTFileInfo;
+
+typedef struct {
+  CXIdxLoc loc;
+  const char *name;
+} CXIdxMacroInfo;
+
+typedef struct {
+  CXIdxMacroInfo *macroInfo;
+  CXIdxLoc defBegin;
+  unsigned defLength;
+} CXIdxMacroDefinedInfo;
+
+typedef struct {
+  CXIdxLoc loc;
+  const char *name;
+  CXIdxMacro macro;
+} CXIdxMacroUndefinedInfo;
+
+typedef struct {
+  CXIdxLoc loc;
+  const char *name;
+  CXIdxMacro macro;
+} CXIdxMacroExpandedInfo;
+
+typedef struct {
+  const char *name;
+  const char *USR;
+} CXIdxEntityInfo;
+
+typedef struct {
+  CXCursor cursor;
+  CXIdxLoc loc;
+  CXIdxContainer container;
+} CXIdxIndexedDeclInfo;
+
+typedef struct {
+  CXIdxEntityInfo *entityInfo;
+  CXCursor cursor;
+  CXIdxLoc loc;
+  CXIdxASTFile ASTFile;
+} CXIdxImportedEntityInfo;
+
+typedef struct {
+  CXIdxMacroInfo *macroInfo;
+  CXIdxASTFile ASTFile;
+} CXIdxImportedMacroInfo;
+
+typedef struct {
+  CXIdxEntityInfo *entityInfo;
+  CXIdxIndexedDeclInfo *declInfo;
+} CXIdxIndexedEntityInfo;
+
+typedef struct {
+  CXIdxIndexedDeclInfo *declInfo;
+  CXIdxEntity entity;
+} CXIdxIndexedRedeclInfo;
+
+typedef struct {
+  CXCursor cursor;
+  CXIdxLoc loc;
+  CXIdxEntity entity;
+} CXIdxContainerInfo;
+
+typedef struct {
+  CXIdxIndexedEntityInfo *indexedEntityInfo;
+} CXIdxTypedefInfo;
+
+typedef struct {
+  CXIdxIndexedEntityInfo *indexedEntityInfo;
+  int isDefinition;
+} CXIdxFunctionInfo;
+
+typedef struct {
+  CXIdxIndexedRedeclInfo *indexedRedeclInfo;
+  int isDefinition;
+} CXIdxFunctionRedeclInfo;
+
+typedef struct {
+  CXIdxIndexedEntityInfo *indexedEntityInfo;
+  int isDefinition;
+} CXIdxVariableInfo;
+
+typedef struct {
+  CXIdxIndexedRedeclInfo *indexedRedeclInfo;
+  int isDefinition;
+} CXIdxVariableRedeclInfo;
+
+typedef struct {
+  CXIdxIndexedEntityInfo *indexedEntityInfo;
+  int isDefinition;
+  int isAnonymous;
+} CXIdxTagTypeInfo;
+
+typedef struct {
+  CXIdxIndexedRedeclInfo *indexedRedeclInfo;
+  int isDefinition;
+} CXIdxTagTypeRedeclInfo;
+
+typedef struct {
+  CXIdxContainerInfo *containerInfo;
+} CXIdxTagTypeDefinitionInfo;
+
+typedef struct {
+  CXIdxIndexedEntityInfo *indexedEntityInfo;
+} CXIdxFieldInfo;
+
+typedef struct {
+  CXIdxIndexedEntityInfo *indexedEntityInfo;
+} CXIdxEnumeratorInfo;
+
+typedef struct {
+  CXIdxIndexedEntityInfo *indexedEntityInfo;
+  int isForwardRef;
+} CXIdxObjCClassInfo;
+
+typedef struct {
+  CXIdxIndexedEntityInfo *indexedEntityInfo;
+  int isForwardRef;
+} CXIdxObjCProtocolInfo;
+
+typedef struct {
+  CXIdxIndexedEntityInfo *indexedEntityInfo;
+  CXIdxEntity objcClass;
+} CXIdxObjCCategoryInfo;
+
+typedef struct {
+  CXIdxIndexedEntityInfo *indexedEntityInfo;
+  int isDefinition;
+} CXIdxObjCMethodInfo;
+
+typedef struct {
+  CXIdxIndexedEntityInfo *indexedEntityInfo;
+} CXIdxObjCPropertyInfo;
+
+typedef struct {
+  CXIdxIndexedRedeclInfo *indexedRedeclInfo;
+  int isDefinition;
+} CXIdxObjCMethodRedeclInfo;
+
+typedef struct {
+  CXIdxContainerInfo *containerInfo;
+  CXIdxLoc bodyBegin;
+} CXIdxStmtBodyInfo;
+
+typedef struct {
+  CXIdxContainerInfo *containerInfo;
+} CXIdxObjCContainerInfo;
+
+typedef struct {
+  CXIdxEntity objcClass;
+  CXIdxLoc loc;
+} CXIdxObjCBaseClassInfo;
+
+typedef struct {
+  CXIdxEntity protocol;
+  CXIdxLoc loc;
+} CXIdxObjCProtocolRefInfo;
+
+typedef struct {
+  CXCursor cursor;
+  CXIdxEntity objcClass;
+  CXIdxContainer container;
+  CXIdxObjCBaseClassInfo *baseInfo;
+  CXIdxObjCProtocolRefInfo **protocols;
+  unsigned numProtocols;
+} CXIdxObjCClassDefineInfo;
+
+typedef struct {
+  CXIdxContainer container;
+  CXIdxLoc endLoc;
+} CXIdxEndContainerInfo;
+
+typedef struct {
+  CXCursor cursor;
+  CXIdxLoc loc;
+  CXIdxEntity referencedEntity;
+  CXIdxEntity parentEntity;
+  CXIdxContainer container;
+} CXIdxEntityRefInfo;
+
+typedef struct {
+  void (*diagnostic)(CXClientData client_data,
+                     CXDiagnostic, void *reserved);
+
+  CXIdxFile (*recordFile)(CXClientData client_data,
+                          CXFile file, void *reserved);
+
+  void (*ppIncludedFile)(CXClientData client_data,
+                         CXIdxIncludedFileInfo *);
+
+  CXIdxMacro (*ppMacroDefined)(CXClientData client_data,
+                               CXIdxMacroDefinedInfo *);
+
+  void (*ppMacroUndefined)(CXClientData client_data,
+                           CXIdxMacroUndefinedInfo *);
+
+  void (*ppMacroExpanded)(CXClientData client_data,
+                          CXIdxMacroExpandedInfo *);
+  
+  CXIdxASTFile (*importedASTFile)(CXClientData client_data,
+                                  CXIdxImportedASTFileInfo *);
+
+  CXIdxEntity (*importedEntity)(CXClientData client_data,
+                                CXIdxImportedEntityInfo *);
+
+  CXIdxEntity (*importedMacro)(CXClientData client_data,
+                               CXIdxImportedMacroInfo *);
+
+  CXIdxContainer (*startedTranslationUnit)(CXClientData client_data,
+                                           void *reserved);
+
+  CXIdxEntity (*indexTypedef)(CXClientData client_data,
+                              CXIdxTypedefInfo *);
+
+  CXIdxEntity (*indexFunction)(CXClientData client_data,
+                               CXIdxFunctionInfo *);
+
+  void (*indexFunctionRedeclaration)(CXClientData client_data,
+                                     CXIdxFunctionRedeclInfo *);
+
+  CXIdxEntity (*indexVariable)(CXClientData client_data,
+                               CXIdxVariableInfo *);
+
+  void (*indexVariableRedeclaration)(CXClientData client_data,
+                                     CXIdxVariableRedeclInfo *);
+
+  CXIdxEntity (*indexTagType)(CXClientData client_data,
+                              CXIdxTagTypeInfo *);
+
+  void (*indexTagTypeRedeclaration)(CXClientData client_data,
+                                    CXIdxTagTypeRedeclInfo *);
+
+  CXIdxEntity (*indexField)(CXClientData client_data,
+                            CXIdxFieldInfo *);
+
+  CXIdxEntity (*indexEnumerator)(CXClientData client_data,
+                                 CXIdxEnumeratorInfo *);
+
+  CXIdxContainer (*startedTagTypeDefinition)(CXClientData client_data,
+                                            CXIdxTagTypeDefinitionInfo *);
+
+  CXIdxEntity (*indexObjCClass)(CXClientData client_data,
+                                CXIdxObjCClassInfo *);
+
+  CXIdxEntity (*indexObjCProtocol)(CXClientData client_data,
+                                   CXIdxObjCProtocolInfo *);
+
+  CXIdxEntity (*indexObjCCategory)(CXClientData client_data,
+                                   CXIdxObjCCategoryInfo *);
+
+  CXIdxEntity (*indexObjCMethod)(CXClientData client_data,
+                                 CXIdxObjCMethodInfo *);
+
+  CXIdxEntity (*indexObjCProperty)(CXClientData client_data,
+                                   CXIdxObjCPropertyInfo *);
+
+  void (*indexObjCMethodRedeclaration)(CXClientData client_data,
+                                       CXIdxObjCMethodRedeclInfo *);
+
+  CXIdxContainer (*startedStatementBody)(CXClientData client_data,
+                                         CXIdxStmtBodyInfo *);
+
+  CXIdxContainer (*startedObjCContainer)(CXClientData client_data,
+                                         CXIdxObjCContainerInfo *);
+
+  void (*defineObjCClass)(CXClientData client_data,
+                          CXIdxObjCClassDefineInfo *);
+
+  void (*endedContainer)(CXClientData client_data,
+                         CXIdxEndContainerInfo *);
+
+  void (*indexEntityReference)(CXClientData client_data,
+                               CXIdxEntityRefInfo *);
+
+} IndexerCallbacks;
+
+CINDEX_LINKAGE int clang_indexTranslationUnit(CXIndex CIdx,
+                                         CXClientData client_data,
+                                         IndexerCallbacks *index_callbacks,
+                                         unsigned index_callbacks_size,
+                                         unsigned index_options,
+                                         const char *source_filename,
+                                         const char * const
*command_line_args,
+                                         int num_command_line_args,
+                                         struct CXUnsavedFile
*unsaved_files,
+                                         unsigned num_unsaved_files,
+                                         CXTranslationUnit *out_TU,
+                                         unsigned TU_options);
+
+CINDEX_LINKAGE void clang_indexLoc_getFileLocation(CXIdxLoc loc,
+                                                   CXIdxFile *indexFile,
+                                                   CXFile *file,
+                                                   unsigned *line,
+                                                   unsigned *column,
+                                                   unsigned *offset);
+
+CINDEX_LINKAGE
+CXSourceLocation clang_indexLoc_getCXSourceLocation(CXIdxLoc loc);
+
 /**
  * @}
  */

Modified: cfe/trunk/tools/c-index-test/c-index-test.c
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-tes
t.c?rev=142233&r1=142232&r2=142233&view=diff
============================================================================
==
--- cfe/trunk/tools/c-index-test/c-index-test.c (original)
+++ cfe/trunk/tools/c-index-test/c-index-test.c Mon Oct 17 14:48:19 2011
@@ -1480,6 +1480,504 @@
   return 0;
 }
 
+typedef struct {
+  const char *check_prefix;
+  int first_check_printed;
+} IndexData;
+
+static void printCheck(IndexData *data) {
+  if (data->check_prefix) {
+    if (data->first_check_printed) {
+      printf("// %s-NEXT: ", data->check_prefix);
+    } else {
+      printf("// %s     : ", data->check_prefix);
+      data->first_check_printed = 1;
+    }
+  }
+}
+
+static void printCXIndexFile(CXIdxFile file) {
+  CXString filename = clang_getFileName((CXFile)file);
+  printf("%s", clang_getCString(filename));
+  clang_disposeString(filename);
+}
+
+static void printCXIndexLoc(CXIdxLoc loc) {
+  CXString filename;
+  const char *cname, *end;
+  CXIdxFile file;
+  unsigned line, column;
+  
+  clang_indexLoc_getFileLocation(loc, &file, 0, &line, &column, 0);
+  if (line == 0) {
+    printf("<null loc>");
+    return;
+  }
+  filename = clang_getFileName((CXFile)file);
+  cname = clang_getCString(filename);
+  end = cname + strlen(cname);
+  int isHeader = (end[-2] == '.' && end[-1] == 'h');
+  
+  if (isHeader) {
+    printCXIndexFile(file);
+    printf(":");
+  }
+  printf("%d:%d", line, column);
+}
+
+static CXIdxEntity makeCXIndexEntity(CXIdxIndexedEntityInfo *info) {
+  const char *name;
+  CXIdxLoc loc;
+  char *newStr;
+  CXIdxFile file;
+  unsigned line, column;
+  
+  name = info->entityInfo->name;
+  if (!name)
+    name = "<anon-tag>";
+
+  loc = info->declInfo->loc;
+  clang_indexLoc_getFileLocation(loc, &file, 0, &line, &column, 0);
+ // FIXME: free these.
+  newStr = (char *)malloc(strlen(name) + 10);
+  sprintf(newStr, "%s:%d:%d", name, line, column);
+  return (CXIdxEntity)newStr;
+}
+
+static CXIdxContainer makeCXIndexContainer(CXIdxEntity entity) {
+  return (CXIdxContainer)entity;
+}
+
+static void printCXIndexEntity(CXIdxEntity entity) {
+  printf("{%s}", (const char *)entity);
+}
+
+static void printCXIndexContainer(CXIdxContainer container) {
+  printf("[%s]", (const char *)container);
+}
+
+static void printIndexedDeclInfo(CXIdxIndexedDeclInfo *info) {
+  printf(" | cursor: ");
+  PrintCursor(info->cursor);
+  printf(" | loc: ");
+  printCXIndexLoc(info->loc);
+  printf(" | container: ");
+  printCXIndexContainer(info->container);
+}
+
+static void printIndexedEntityInfo(const char *cb,
+                                   CXClientData client_data,
+                                   CXIdxIndexedEntityInfo *info) {
+  const char *name;
+  IndexData *index_data;
+  index_data = (IndexData *)client_data;
+  printCheck(index_data);
+
+  name = info->entityInfo->name;
+  if (!name)
+    name = "<anon-tag>";
+
+  printf("%s: %s", cb, info->entityInfo->name);
+  printIndexedDeclInfo(info->declInfo);
+  printf(" | USR: %s", info->entityInfo->USR);
+}
+
+static void printIndexedRedeclInfo(const char *cb,
+                                   CXClientData client_data,
+                                   CXIdxIndexedRedeclInfo *info) {
+  IndexData *index_data;
+  index_data = (IndexData *)client_data;
+  printCheck(index_data);
+
+  printf("%s redeclaration: ", cb);
+  printCXIndexEntity(info->entity);
+  printIndexedDeclInfo(info->declInfo);
+}
+
+static void printStartedContainerInfo(const char *cb,
+                                   CXClientData client_data,
+                                   CXIdxContainerInfo *info) {
+  IndexData *index_data;
+  index_data = (IndexData *)client_data;
+  printCheck(index_data);
+
+  printf("started %s: ", cb);
+  printCXIndexEntity(info->entity);
+  printf(" | cursor: ");
+  PrintCursor(info->cursor);
+  printf(" | loc: ");
+  printCXIndexLoc(info->loc);
+}
+
+static void index_diagnostic(CXClientData client_data,
+                             CXDiagnostic diag, void *reserved) {
+  CXString str;
+  const char *cstr;
+  IndexData *index_data;
+  index_data = (IndexData *)client_data;
+  printCheck(index_data);
+
+  str = clang_formatDiagnostic(diag,
clang_defaultDiagnosticDisplayOptions());
+  cstr = clang_getCString(str);
+  printf("diagnostic: %s", cstr);
+  clang_disposeString(str);  
+}
+
+static CXIdxFile index_recordFile(CXClientData client_data,
+                                  CXFile file, void *reserved) {
+  return (CXIdxFile)file;
+}
+
+static void index_ppIncludedFile(CXClientData client_data,
+                                 CXIdxIncludedFileInfo *info) {
+  IndexData *index_data;
+  index_data = (IndexData *)client_data;
+  printCheck(index_data);
+
+  printf("included file: ");
+  printCXIndexFile(info->file);
+  printf(" | name: \"%s\"", info->filename);
+  printf(" | hash loc: ");
+  printCXIndexLoc(info->hashLoc);
+  printf(" | isImport: %d | isAngled: %d\n", info->isImport,
info->isAngled);
+}
+
+static CXIdxMacro index_ppMacroDefined(CXClientData client_data,
+                                       CXIdxMacroDefinedInfo *info) {
+  IndexData *index_data;
+  index_data = (IndexData *)client_data;
+  printCheck(index_data);
+
+  printf("macro defined: %s", info->macroInfo->name);
+  printf(" | loc: ");
+  printCXIndexLoc(info->macroInfo->loc);
+  printf(" | defBegin: ");
+  printCXIndexLoc(info->defBegin);
+  printf(" | length: %d\n", info->defLength);
+
+  return (CXIdxMacro)info->macroInfo->name;
+}
+
+static void index_ppMacroUndefined(CXClientData client_data,
+                                         CXIdxMacroUndefinedInfo *info) {
+  IndexData *index_data;
+  index_data = (IndexData *)client_data;
+  printCheck(index_data);
+
+  printf("macro undefined: %s", info->name);
+  printf(" | loc: ");
+  printCXIndexLoc(info->loc);
+  printf("\n");
+}
+
+static void index_ppMacroExpanded(CXClientData client_data,
+                                        CXIdxMacroExpandedInfo *info) {
+  IndexData *index_data;
+  index_data = (IndexData *)client_data;
+  printCheck(index_data);
+
+  printf("macro expanded: %s", info->name);
+  printf(" | loc: ");
+  printCXIndexLoc(info->loc);
+  printf("\n");
+}
+
+static CXIdxEntity index_importedEntity(CXClientData client_data,
+                                        CXIdxImportedEntityInfo *info) {
+  IndexData *index_data;
+  CXIdxIndexedDeclInfo DeclInfo = { info->cursor, info->loc, 0 };
+  CXIdxIndexedEntityInfo EntityInfo = { info->entityInfo, &DeclInfo };
+  const char *name;
+  index_data = (IndexData *)client_data;
+  printCheck(index_data);
+
+  name = info->entityInfo->name;
+  if (!name)
+    name = "<anon-tag>";
+
+  printf("imported entity: %s", name);
+  printf(" | cursor: ");
+  PrintCursor(info->cursor);
+  printf(" | loc: ");
+  printCXIndexLoc(info->loc);
+  printf("\n");
+
+  return makeCXIndexEntity(&EntityInfo);
+}
+
+static CXIdxContainer index_startedTranslationUnit(CXClientData
client_data,
+                                                   void *reserved) {
+  IndexData *index_data;
+  index_data = (IndexData *)client_data;
+  printCheck(index_data);
+
+  printf("started TU\n");
+  return (CXIdxContainer)"TU";
+}
+
+static CXIdxEntity index_indexTypedef(CXClientData client_data,
+                                      CXIdxTypedefInfo *info) {
+  printIndexedEntityInfo("typedef", client_data, info->indexedEntityInfo);
+  printf("\n");
+  
+  return makeCXIndexEntity(info->indexedEntityInfo);
+}
+
+static CXIdxEntity index_indexFunction(CXClientData client_data,
+                                       CXIdxFunctionInfo *info) {
+  printIndexedEntityInfo("function", client_data, info->indexedEntityInfo);
+  printf(" | isDefinition: %d\n", info->isDefinition);
+
+  return makeCXIndexEntity(info->indexedEntityInfo);
+}
+
+static void index_indexFunctionRedeclaration(CXClientData client_data,
+                                             CXIdxFunctionRedeclInfo *info)
{
+  printIndexedRedeclInfo("function", client_data, info->indexedRedeclInfo);
+  printf(" | isDefinition: %d\n", info->isDefinition);
+}
+
+static CXIdxEntity index_indexVariable(CXClientData client_data,
+                                       CXIdxVariableInfo *info) {
+  printIndexedEntityInfo("variable", client_data, info->indexedEntityInfo);
+  printf(" | isDefinition: %d\n", info->isDefinition);
+
+  return makeCXIndexEntity(info->indexedEntityInfo);
+}
+
+static void index_indexVariableRedeclaration(CXClientData client_data,
+                                             CXIdxVariableRedeclInfo *info)
{
+  printIndexedRedeclInfo("variable", client_data, info->indexedRedeclInfo);
+  printf(" | isDefinition: %d\n", info->isDefinition);
+}
+
+static CXIdxEntity index_indexTagType(CXClientData client_data,
+                                       CXIdxTagTypeInfo *info) {
+  printIndexedEntityInfo("tag type", client_data, info->indexedEntityInfo);
+  printf(" | isDefinition: %d | anon: %d\n",
+         info->isDefinition, info->isAnonymous);
+
+  return makeCXIndexEntity(info->indexedEntityInfo);
+}
+
+static void index_indexTagTypeRedeclaration(CXClientData client_data,
+                                             CXIdxTagTypeRedeclInfo *info)
{
+  printIndexedRedeclInfo("tag type", client_data, info->indexedRedeclInfo);
+  printf(" | isDefinition: %d\n", info->isDefinition);
+}
+
+static CXIdxEntity index_indexField(CXClientData client_data,
+                                      CXIdxFieldInfo *info) {
+  printIndexedEntityInfo("field", client_data, info->indexedEntityInfo);
+  printf("\n");
+  
+  return makeCXIndexEntity(info->indexedEntityInfo);
+}
+
+static CXIdxEntity index_indexEnumerator(CXClientData client_data,
+                                         CXIdxEnumeratorInfo *info) {
+  printIndexedEntityInfo("enumerator", client_data,
info->indexedEntityInfo);
+  printf("\n");
+  
+  return makeCXIndexEntity(info->indexedEntityInfo);
+}
+
+static CXIdxContainer
+index_startedTagTypeDefinition(CXClientData client_data,
+                               CXIdxTagTypeDefinitionInfo *info) {
+  printStartedContainerInfo("tag type definition", client_data,
+                            info->containerInfo);
+  printf("\n");
+  
+  return makeCXIndexContainer(info->containerInfo->entity);
+}
+
+static CXIdxEntity index_indexObjCClass(CXClientData client_data,
+                                       CXIdxObjCClassInfo *info) {
+  printIndexedEntityInfo("ObjC class", client_data,
info->indexedEntityInfo);
+  printf(" | forward ref: %d\n", info->isForwardRef);
+
+  return makeCXIndexEntity(info->indexedEntityInfo);
+}
+
+static CXIdxEntity index_indexObjCProtocol(CXClientData client_data,
+                                       CXIdxObjCProtocolInfo *info) {
+  printIndexedEntityInfo("ObjC protocol", client_data,
+                         info->indexedEntityInfo);
+  printf(" | forward ref: %d\n", info->isForwardRef);
+
+  return makeCXIndexEntity(info->indexedEntityInfo);
+}
+
+static CXIdxEntity index_indexObjCCategory(CXClientData client_data,
+                                           CXIdxObjCCategoryInfo *info) {
+  printIndexedEntityInfo("ObjC category", client_data,
+                         info->indexedEntityInfo);
+  printf(" | class: ");
+  printCXIndexEntity(info->objcClass);
+  printf("\n");
+
+  return makeCXIndexEntity(info->indexedEntityInfo);
+}
+
+static CXIdxEntity index_indexObjCMethod(CXClientData client_data,
+                                       CXIdxObjCMethodInfo *info) {
+  printIndexedEntityInfo("ObjC Method", client_data,
info->indexedEntityInfo);
+  printf(" | isDefinition: %d\n", info->isDefinition);
+
+  return makeCXIndexEntity(info->indexedEntityInfo);
+}
+
+static CXIdxEntity index_indexObjCProperty(CXClientData client_data,
+                                           CXIdxObjCPropertyInfo *info) {
+  printIndexedEntityInfo("ObjC property", client_data,
info->indexedEntityInfo);
+  printf("\n");
+
+  return makeCXIndexEntity(info->indexedEntityInfo);
+}
+
+static void index_indexObjCMethodRedeclaration(CXClientData client_data,
+                                             CXIdxObjCMethodRedeclInfo
*info) {
+  printIndexedRedeclInfo("ObjC Method", client_data,
info->indexedRedeclInfo);
+  printf(" | isDefinition: %d\n", info->isDefinition);
+}
+
+static CXIdxContainer
+index_startedStatementBody(CXClientData client_data,
+                           CXIdxStmtBodyInfo *info) {
+  printStartedContainerInfo("body", client_data, info->containerInfo);
+  printf(" | body: ");
+  printCXIndexLoc(info->bodyBegin);
+  printf("\n");
+  
+  return makeCXIndexContainer(info->containerInfo->entity);
+}
+
+static CXIdxContainer
+index_startedObjCContainer(CXClientData client_data,
+                           CXIdxObjCContainerInfo *info) {
+  printStartedContainerInfo("ObjC container", client_data,
info->containerInfo);
+  printf("\n");
+  
+  return makeCXIndexContainer(info->containerInfo->entity);
+}
+
+static void index_defineObjCClass(CXClientData client_data,
+                                  CXIdxObjCClassDefineInfo *info) {
+  IndexData *index_data;
+  index_data = (IndexData *)client_data;
+  printCheck(index_data);
+
+  printf("define objc class: ");
+  printCXIndexEntity(info->objcClass);
+  printf(" | cursor: ");
+  PrintCursor(info->cursor);
+  printf(" | container: ");
+  printCXIndexContainer(info->container);
+  
+  if (info->baseInfo) {
+    printf(" | base: ");
+    printCXIndexEntity(info->baseInfo->objcClass);
+    printf(" | base loc: ");
+    printCXIndexLoc(info->baseInfo->loc);
+  }
+
+  printf("\n");
+}
+
+static void index_endedContainer(CXClientData client_data,
+                                 CXIdxEndContainerInfo *info) {
+  IndexData *index_data;
+  index_data = (IndexData *)client_data;
+  printCheck(index_data);
+
+  printf("ended container: ");
+  printCXIndexContainer(info->container);
+  printf(" | end: ");
+  printCXIndexLoc(info->endLoc);
+  printf("\n");
+}
+
+static void index_indexEntityReference(CXClientData client_data,
+                                       CXIdxEntityRefInfo *info) {
+  IndexData *index_data;
+  index_data = (IndexData *)client_data;
+  printCheck(index_data);
+
+  printf("reference: ");
+  printCXIndexEntity(info->referencedEntity);
+  printf(" | cursor: ");
+  PrintCursor(info->cursor);
+  printf(" | loc: ");
+  printCXIndexLoc(info->loc);
+  printf(" | parent: ");
+  printCXIndexEntity(info->parentEntity);
+  printf(" | container: ");
+  printCXIndexContainer(info->container);
+  printf("\n");
+}
+
+static IndexerCallbacks IndexCB = {
+  index_diagnostic,
+  index_recordFile,
+  index_ppIncludedFile,
+  index_ppMacroDefined,
+  index_ppMacroUndefined,
+  index_ppMacroExpanded,
+  0, //importedASTFile
+  index_importedEntity,
+  0,//index_importedMacro,
+  index_startedTranslationUnit,
+  index_indexTypedef,
+  index_indexFunction,
+  index_indexFunctionRedeclaration,
+  index_indexVariable,
+  index_indexVariableRedeclaration,
+  index_indexTagType,
+  index_indexTagTypeRedeclaration,
+  index_indexField,
+  index_indexEnumerator,
+  index_startedTagTypeDefinition,
+  index_indexObjCClass,
+  index_indexObjCProtocol,
+  index_indexObjCCategory,
+  index_indexObjCMethod,
+  index_indexObjCProperty,
+  index_indexObjCMethodRedeclaration,
+  index_startedStatementBody,
+  index_startedObjCContainer,
+  index_defineObjCClass,
+  index_endedContainer,
+  index_indexEntityReference
+};
+
+static int index_file(int argc, const char **argv) {
+  const char *check_prefix;
+  CXIndex CIdx;
+  IndexData index_data;
+
+  check_prefix = 0;
+  if (argc > 0) {
+    if (strstr(argv[0], "-check-prefix=") == argv[0]) {
+      check_prefix = argv[0] + strlen("-check-prefix=");
+      ++argv;
+      --argc;
+    }
+  }
+
+  if (argc == 0) {
+    fprintf(stderr, "no compiler arguments\n");
+    return -1;
+  }
+
+  CIdx = clang_createIndex(0, 1);
+  index_data.check_prefix = check_prefix;
+  index_data.first_check_printed = 0;
+
+  return clang_indexTranslationUnit(CIdx, &index_data,
&IndexCB,sizeof(IndexCB),
+                                    0, 0, argv, argc, 0, 0, 0, 0);
+}
+
 int perform_token_annotation(int argc, const char **argv) {
   const char *input = argv[1];
   char *filename = 0;
@@ -1848,6 +2346,7 @@
     "       c-index-test -code-completion-timing=<site> <compiler
arguments>\n"
     "       c-index-test -cursor-at=<site> <compiler arguments>\n"
     "       c-index-test -file-refs-at=<site> <compiler arguments>\n"
+    "       c-index-test -index-file [-check-prefix=<FileCheck prefix>]
<compiler arguments>\n"
     "       c-index-test -test-file-scan <AST file> <source file> "
           "[FileCheck prefix]\n");
   fprintf(stderr,
@@ -1897,6 +2396,8 @@
     return inspect_cursor_at(argc, argv);
   if (argc > 2 && strstr(argv[1], "-file-refs-at=") == argv[1])
     return find_file_refs_at(argc, argv);
+  if (argc > 2 && strcmp(argv[1], "-index-file") == 0)
+    return index_file(argc - 2, argv + 2);
   else if (argc >= 4 && strncmp(argv[1], "-test-load-tu", 13) == 0) {
     CXCursorVisitor I = GetVisitor(argv[1] + 13);
     if (I)

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=
142233&r1=142232&r2=142233&view=diff
============================================================================
==
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Mon Oct 17 14:48:19 2011
@@ -62,6 +62,11 @@
   return D;
 }
 
+cxtu::CXTUOwner::~CXTUOwner() {
+  if (TU)
+    clang_disposeTranslationUnit(TU);
+}
+
 /// \brief The result of comparing two source ranges.
 enum RangeComparisonResult {
   /// \brief Either the ranges overlap or one of the ranges is invalid.

Modified: cfe/trunk/tools/libclang/CIndexUSRs.cpp
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexUSRs.cpp?
rev=142233&r1=142232&r2=142233&view=diff
============================================================================
==
--- cfe/trunk/tools/libclang/CIndexUSRs.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexUSRs.cpp Mon Oct 17 14:48:19 2011
@@ -790,7 +790,7 @@
   return s.startswith("c:") ? s.substr(2) : "";
 }
 
-bool cxcursor::getDeclCursorUSR(Decl *D, SmallVectorImpl<char> &Buf) {
+bool cxcursor::getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf)
{
   // Don't generate USRs for things with invalid locations.
   if (!D || D->getLocStart().isInvalid())
     return true;
@@ -820,7 +820,7 @@
 
   {
     USRGenerator UG(&D->getASTContext(), &Buf);
-    UG->Visit(D);
+    UG->Visit((Decl*)D);
 
     if (UG->ignoreResults())
       return true;

Modified: cfe/trunk/tools/libclang/CMakeLists.txt
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CMakeLists.txt?
rev=142233&r1=142232&r2=142233&view=diff
============================================================================
==
--- cfe/trunk/tools/libclang/CMakeLists.txt (original)
+++ cfe/trunk/tools/libclang/CMakeLists.txt Mon Oct 17 14:48:19 2011
@@ -28,6 +28,11 @@
   CXCursor.cpp
   CXString.cpp
   CXType.cpp
+  IndexBody.cpp
+  IndexDecl.cpp
+  IndexTypeSourceInfo.cpp
+  Indexing.cpp
+  IndexingContext.cpp
   ../../include/clang-c/Index.h
   )
 

Modified: cfe/trunk/tools/libclang/CXCursor.cpp
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?re
v=142233&r1=142232&r2=142233&view=diff
============================================================================
==
--- cfe/trunk/tools/libclang/CXCursor.cpp (original)
+++ cfe/trunk/tools/libclang/CXCursor.cpp Mon Oct 17 14:48:19 2011
@@ -468,12 +468,12 @@
 
reinterpret_cast<uintptr_t>(C.data[1])));
 }
 
-CXCursor cxcursor::MakeCursorObjCProtocolRef(ObjCProtocolDecl *Super, 
+CXCursor cxcursor::MakeCursorObjCProtocolRef(const ObjCProtocolDecl *Proto,

                                              SourceLocation Loc, 
                                              CXTranslationUnit TU) {
-  assert(Super && TU && "Invalid arguments!");
+  assert(Proto && TU && "Invalid arguments!");
   void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
-  CXCursor C = { CXCursor_ObjCProtocolRef, 0, { Super, RawLoc, TU } };
+  CXCursor C = { CXCursor_ObjCProtocolRef, 0, { (void*)Proto, RawLoc, TU }
};
   return C;    
 }
 
@@ -485,7 +485,7 @@
 
reinterpret_cast<uintptr_t>(C.data[1])));
 }
 
-CXCursor cxcursor::MakeCursorObjCClassRef(ObjCInterfaceDecl *Class, 
+CXCursor cxcursor::MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class, 
                                           SourceLocation Loc, 
                                           CXTranslationUnit TU) {
   // 'Class' can be null for invalid code.
@@ -493,7 +493,7 @@
     return MakeCXCursorInvalid(CXCursor_InvalidCode);
   assert(TU && "Invalid arguments!");
   void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
-  CXCursor C = { CXCursor_ObjCClassRef, 0, { Class, RawLoc, TU } };
+  CXCursor C = { CXCursor_ObjCClassRef, 0, { (void*)Class, RawLoc, TU } };
   return C;    
 }
 
@@ -505,11 +505,11 @@
 
reinterpret_cast<uintptr_t>(C.data[1])));
 }
 
-CXCursor cxcursor::MakeCursorTypeRef(TypeDecl *Type, SourceLocation Loc, 
+CXCursor cxcursor::MakeCursorTypeRef(const TypeDecl *Type, SourceLocation
Loc, 
                                      CXTranslationUnit TU) {
   assert(Type && TU && "Invalid arguments!");
   void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
-  CXCursor C = { CXCursor_TypeRef, 0, { Type, RawLoc, TU } };
+  CXCursor C = { CXCursor_TypeRef, 0, { (void*)Type, RawLoc, TU } };
   return C;    
 }
 

Modified: cfe/trunk/tools/libclang/CXCursor.h
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.h?rev=
142233&r1=142232&r2=142233&view=diff
============================================================================
==
--- cfe/trunk/tools/libclang/CXCursor.h (original)
+++ cfe/trunk/tools/libclang/CXCursor.h Mon Oct 17 14:48:19 2011
@@ -67,7 +67,8 @@
   getCursorObjCSuperClassRef(CXCursor C);
 
 /// \brief Create an Objective-C protocol reference at the given location.
-CXCursor MakeCursorObjCProtocolRef(ObjCProtocolDecl *Proto, SourceLocation
Loc, 
+CXCursor MakeCursorObjCProtocolRef(const ObjCProtocolDecl *Proto,
+                                   SourceLocation Loc, 
                                    CXTranslationUnit TU);
 
 /// \brief Unpack an ObjCProtocolRef cursor into the protocol it references
@@ -76,7 +77,8 @@
   getCursorObjCProtocolRef(CXCursor C);
 
 /// \brief Create an Objective-C class reference at the given location.
-CXCursor MakeCursorObjCClassRef(ObjCInterfaceDecl *Class, SourceLocation
Loc, 
+CXCursor MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class,
+                                SourceLocation Loc, 
                                 CXTranslationUnit TU);
 
 /// \brief Unpack an ObjCClassRef cursor into the class it references
@@ -85,7 +87,7 @@
   getCursorObjCClassRef(CXCursor C);
 
 /// \brief Create a type reference at the given location.
-CXCursor MakeCursorTypeRef(TypeDecl *Type, SourceLocation Loc,
+CXCursor MakeCursorTypeRef(const TypeDecl *Type, SourceLocation Loc,
                            CXTranslationUnit TU);
                                
 /// \brief Unpack a TypeRef cursor into the class it references
@@ -221,7 +223,7 @@
 /// \brief Generate a USR for \arg D and put it in \arg Buf.
 /// \returns true if no USR was computed or the result should be ignored,
 /// false otherwise.
-bool getDeclCursorUSR(Decl *D, SmallVectorImpl<char> &Buf);
+bool getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf);
 
 bool operator==(CXCursor X, CXCursor Y);
   

Modified: cfe/trunk/tools/libclang/CXTranslationUnit.h
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXTranslationUn
it.h?rev=142233&r1=142232&r2=142233&view=diff
============================================================================
==
--- cfe/trunk/tools/libclang/CXTranslationUnit.h (original)
+++ cfe/trunk/tools/libclang/CXTranslationUnit.h Mon Oct 17 14:48:19 2011
@@ -28,6 +28,23 @@
 
 CXTranslationUnitImpl *MakeCXTranslationUnit(ASTUnit *TU);
 
+class CXTUOwner {
+  CXTranslationUnitImpl *TU;
+  
+public:
+  CXTUOwner(CXTranslationUnitImpl *tu) : TU(tu) { }
+  ~CXTUOwner();
+
+  CXTranslationUnitImpl *getTU() const { return TU; }
+
+  CXTranslationUnitImpl *takeTU() {
+    CXTranslationUnitImpl *retTU = TU;
+    TU = 0;
+    return retTU;
+  }
+};
+
+
 }} // end namespace clang::cxtu
 
 #endif

Added: cfe/trunk/tools/libclang/IndexBody.cpp
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/IndexBody.cpp?r
ev=142233&view=auto
============================================================================
==
--- cfe/trunk/tools/libclang/IndexBody.cpp (added)
+++ cfe/trunk/tools/libclang/IndexBody.cpp Mon Oct 17 14:48:19 2011
@@ -0,0 +1,72 @@
+//===- CIndexHigh.cpp - Higher level API functions
------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------
===//
+
+#include "IndexingContext.h"
+
+#include "clang/AST/RecursiveASTVisitor.h"
+
+using namespace clang;
+using namespace cxindex;
+
+namespace {
+
+class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
+  IndexingContext &IndexCtx;
+  const DeclContext *ParentDC;
+
+public:
+  BodyIndexer(IndexingContext &indexCtx, const DeclContext *DC)
+    : IndexCtx(indexCtx), ParentDC(DC) { }
+  
+  bool shouldWalkTypesOfTypeLocs() const { return false; }
+
+  bool TraverseTypeLoc(TypeLoc TL) {
+    IndexCtx.indexTypeLoc(TL, 0, ParentDC);
+    return true;
+  }
+
+  bool VisitDeclRefExpr(DeclRefExpr *E) {
+    const NamedDecl *D = E->getDecl();
+    if (!D)
+      return true;
+    if (D->getParentFunctionOrMethod())
+      return true;
+    
+    IndexCtx.handleReference(D, E->getLocation(), 0, ParentDC, E);
+    return true;
+  }
+
+  bool VisitMemberExpr(MemberExpr *E) {
+    const NamedDecl *D = E->getMemberDecl();
+    if (!D)
+      return true;
+    if (D->getParentFunctionOrMethod())
+      return true;
+    
+    IndexCtx.handleReference(D, E->getMemberLoc(), 0, ParentDC, E);
+    return true;
+  }
+
+  bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
+    const NamedDecl *D = E->getDecl();
+    if (!D)
+      return true;
+    if (D->getParentFunctionOrMethod())
+      return true;
+    
+    IndexCtx.handleReference(D, E->getLocation(), 0, ParentDC, E);
+    return true;
+  }
+};
+
+} // anonymous namespace
+
+void IndexingContext::indexBody(const Stmt *S, const DeclContext *DC) {
+  BodyIndexer(*this, DC).TraverseStmt(const_cast<Stmt*>(S));
+}

Added: cfe/trunk/tools/libclang/IndexDecl.cpp
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/IndexDecl.cpp?r
ev=142233&view=auto
============================================================================
==
--- cfe/trunk/tools/libclang/IndexDecl.cpp (added)
+++ cfe/trunk/tools/libclang/IndexDecl.cpp Mon Oct 17 14:48:19 2011
@@ -0,0 +1,218 @@
+//===- CIndexHigh.cpp - Higher level API functions
------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------
===//
+
+#include "IndexingContext.h"
+
+#include "clang/AST/DeclVisitor.h"
+
+using namespace clang;
+using namespace cxindex;
+
+namespace {
+
+class IndexingDeclVisitor : public DeclVisitor<IndexingDeclVisitor, bool> {
+  IndexingContext &IndexCtx;
+
+public:
+  explicit IndexingDeclVisitor(IndexingContext &indexCtx)
+    : IndexCtx(indexCtx) { }
+
+  bool VisitFunctionDecl(FunctionDecl *D) {
+    IndexCtx.handleFunction(D);
+    IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
+    if (D->isThisDeclarationADefinition()) {
+      const Stmt *Body = D->getBody();
+      if (Body) {
+        IndexCtx.invokeStartedStatementBody(D, D);
+        IndexCtx.indexBody(Body, D);
+        IndexCtx.invokeEndedContainer(D);
+      }
+    }
+    return true;
+  }
+
+  bool VisitVarDecl(VarDecl *D) {
+    IndexCtx.handleVar(D);
+    IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
+    return true;
+  }
+
+  bool VisitFieldDecl(FieldDecl *D) {
+    IndexCtx.handleField(D);
+    IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
+    return true;
+  }
+  
+  bool VisitEnumConstantDecl(EnumConstantDecl *D) {
+    IndexCtx.handleEnumerator(D);
+    return true;
+  }
+
+  bool VisitTypedefDecl(TypedefDecl *D) {
+    IndexCtx.handleTypedef(D);
+    IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
+    return true;
+  }
+
+  bool VisitTagDecl(TagDecl *D) {
+    // Non-free standing tags are handled in indexTypeSourceInfo.
+    if (D->isFreeStanding())
+      IndexCtx.indexTagDecl(D);
+    return true;
+  }
+
+  bool VisitObjCClassDecl(ObjCClassDecl *D) {
+    ObjCClassDecl::ObjCClassRef *Ref = D->getForwardDecl();
+    if (Ref->getInterface()->getLocation() == Ref->getLocation()) {
+      IndexCtx.handleObjCInterface(Ref->getInterface());
+    } else {
+      IndexCtx.handleReference(Ref->getInterface(),
+                               Ref->getLocation(),
+                               0,
+                               Ref->getInterface()->getDeclContext());
+    }
+    return true;
+  }
+
+  bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
+    ObjCForwardProtocolDecl::protocol_loc_iterator LI =
D->protocol_loc_begin();
+    for (ObjCForwardProtocolDecl::protocol_iterator
+           I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I,
++LI) {
+      SourceLocation Loc = *LI;
+      ObjCProtocolDecl *PD = *I;
+
+      if (PD->getLocation() == Loc) {
+        IndexCtx.handleObjCProtocol(PD);
+      } else {
+        IndexCtx.handleReference(PD, Loc, 0, PD->getDeclContext());
+      }
+    }
+    return true;
+  }
+
+  bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
+    // Only definitions are handled here.
+    if (D->isForwardDecl())
+      return true;
+
+    if (!D->isInitiallyForwardDecl())
+      IndexCtx.handleObjCInterface(D);
+
+    IndexCtx.indexTUDeclsInObjCContainer();
+    IndexCtx.invokeStartedObjCContainer(D);
+    IndexCtx.defineObjCInterface(D);
+    IndexCtx.indexDeclContext(D);
+    IndexCtx.invokeEndedContainer(D);
+    return true;
+  }
+
+  bool VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
+    // Only definitions are handled here.
+    if (D->isForwardDecl())
+      return true;
+
+    if (!D->isInitiallyForwardDecl())
+      IndexCtx.handleObjCProtocol(D);
+
+    IndexCtx.indexTUDeclsInObjCContainer();
+    IndexCtx.invokeStartedObjCContainer(D);
+    IndexCtx.indexDeclContext(D);
+    IndexCtx.invokeEndedContainer(D);
+    return true;
+  }
+
+  bool VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
+    ObjCInterfaceDecl *Class = D->getClassInterface();
+    if (Class->isImplicitInterfaceDecl())
+      IndexCtx.handleObjCInterface(Class);
+
+    IndexCtx.indexTUDeclsInObjCContainer();
+    IndexCtx.invokeStartedObjCContainer(D);
+    IndexCtx.indexDeclContext(D);
+    IndexCtx.invokeEndedContainer(D);
+    return true;
+  }
+
+  bool VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
+    if (!D->IsClassExtension())
+      IndexCtx.handleObjCCategory(D);
+
+    IndexCtx.indexTUDeclsInObjCContainer();
+    IndexCtx.invokeStartedObjCContainer(D);
+    IndexCtx.indexDeclContext(D);
+    IndexCtx.invokeEndedContainer(D);
+    return true;
+  }
+
+  bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
+    IndexCtx.indexTUDeclsInObjCContainer();
+    IndexCtx.invokeStartedObjCContainer(D);
+    IndexCtx.indexDeclContext(D);
+    IndexCtx.invokeEndedContainer(D);
+    return true;
+  }
+
+  bool VisitObjCMethodDecl(ObjCMethodDecl *D) {
+    IndexCtx.handleObjCMethod(D);
+    IndexCtx.indexTypeSourceInfo(D->getResultTypeSourceInfo(), D);
+    for (ObjCMethodDecl::param_iterator
+           I = D->param_begin(), E = D->param_end(); I != E; ++I)
+      IndexCtx.indexTypeSourceInfo((*I)->getTypeSourceInfo(), D);
+
+    if (D->isThisDeclarationADefinition()) {
+      const Stmt *Body = D->getBody();
+      if (Body) {
+        IndexCtx.invokeStartedStatementBody(D, D);
+        IndexCtx.indexBody(Body, D);
+        IndexCtx.invokeEndedContainer(D);
+      }
+    }
+    return true;
+  }
+
+  bool VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
+    IndexCtx.handleObjCProperty(D);
+    IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
+    return true;
+  }
+};
+
+} // anonymous namespace
+
+void IndexingContext::indexDecl(const Decl *D) {
+  bool Handled = IndexingDeclVisitor(*this).Visit(const_cast<Decl*>(D));
+  if (!Handled && isa<DeclContext>(D))
+    indexDeclContext(cast<DeclContext>(D));
+}
+
+void IndexingContext::indexDeclContext(const DeclContext *DC) {
+  for (DeclContext::decl_iterator
+         I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
+    indexDecl(*I);
+  }
+}
+
+void IndexingContext::indexDeclGroupRef(DeclGroupRef DG) {
+  for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
+    Decl *D = *I;
+    if (isNotFromSourceFile(D->getLocation()))
+      return;
+
+    if (isa<ObjCMethodDecl>(D))
+      continue; // Wait for the objc container.
+
+    indexDecl(D);
+  }
+}
+
+void IndexingContext::indexTUDeclsInObjCContainer() {
+  for (unsigned i = 0, e = TUDeclsInObjCContainer.size(); i != e; ++i)
+    indexDeclGroupRef(TUDeclsInObjCContainer[i]);
+  TUDeclsInObjCContainer.clear();
+}

Added: cfe/trunk/tools/libclang/IndexTypeSourceInfo.cpp
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/IndexTypeSource
Info.cpp?rev=142233&view=auto
============================================================================
==
--- cfe/trunk/tools/libclang/IndexTypeSourceInfo.cpp (added)
+++ cfe/trunk/tools/libclang/IndexTypeSourceInfo.cpp Mon Oct 17 14:48:19
2011
@@ -0,0 +1,94 @@
+//===- CIndexHigh.cpp - Higher level API functions
------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------
===//
+
+#include "IndexingContext.h"
+
+#include "clang/AST/RecursiveASTVisitor.h"
+
+using namespace clang;
+using namespace cxindex;
+
+namespace {
+
+class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
+  IndexingContext &IndexCtx;
+  const NamedDecl *Parent;
+  const DeclContext *ParentDC;
+
+public:
+  TypeIndexer(IndexingContext &indexCtx, const NamedDecl *parent,
+              const DeclContext *DC)
+    : IndexCtx(indexCtx), Parent(parent), ParentDC(DC) { }
+  
+  bool shouldWalkTypesOfTypeLocs() const { return false; }
+
+  bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+    IndexCtx.handleReference(TL.getTypedefNameDecl(), TL.getNameLoc(),
+                             Parent, ParentDC);
+    return true;
+  }
+
+  bool VisitTagTypeLoc(TagTypeLoc TL) {
+    TagDecl *D = TL.getDecl();
+
+    if (TL.isDefinition()) {
+      IndexCtx.indexTagDecl(D);
+      return true;
+    }
+
+    if (D->getLocation() == TL.getNameLoc())
+      IndexCtx.handleTagDecl(D);
+    else
+      IndexCtx.handleReference(D, TL.getNameLoc(),
+                               Parent, ParentDC);
+    return true;
+  }
+
+  bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
+    IndexCtx.handleReference(TL.getIFaceDecl(), TL.getNameLoc(),
+                             Parent, ParentDC);
+    return true;
+  }
+
+  bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
+    for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) {
+      IndexCtx.handleReference(TL.getProtocol(i), TL.getProtocolLoc(i),
+                               Parent, ParentDC);
+    }
+    return true;
+  }
+};
+
+} // anonymous namespace
+
+void IndexingContext::indexTypeSourceInfo(TypeSourceInfo *TInfo,
+                                          const NamedDecl *Parent,
+                                          const DeclContext *DC) {
+  if (!TInfo || TInfo->getTypeLoc().isNull())
+    return;
+  
+  if (DC == 0)
+    DC = Parent->getDeclContext();
+  indexTypeLoc(TInfo->getTypeLoc(), Parent, DC);
+}
+
+void IndexingContext::indexTypeLoc(TypeLoc TL,
+                                   const NamedDecl *Parent,
+                                   const DeclContext *DC) {
+  TypeIndexer(*this, Parent, DC).TraverseTypeLoc(TL);
+}
+
+void IndexingContext::indexTagDecl(const TagDecl *D) {
+  handleTagDecl(D);
+  if (D->isThisDeclarationADefinition()) {
+    invokeStartedTagTypeDefinition(D);
+    indexDeclContext(D);
+    invokeEndedContainer(D);
+  }
+}

Added: cfe/trunk/tools/libclang/Indexing.cpp
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/Indexing.cpp?re
v=142233&view=auto
============================================================================
==
--- cfe/trunk/tools/libclang/Indexing.cpp (added)
+++ cfe/trunk/tools/libclang/Indexing.cpp Mon Oct 17 14:48:19 2011
@@ -0,0 +1,479 @@
+//===- CIndexHigh.cpp - Higher level API functions
------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------
===//
+
+#include "IndexingContext.h"
+#include "CXCursor.h"
+#include "CXSourceLocation.h"
+#include "CXTranslationUnit.h"
+#include "CXString.h"
+#include "CIndexer.h"
+
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/Utils.h"
+#include "clang/Sema/SemaConsumer.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/CrashRecoveryContext.h"
+
+using namespace clang;
+using namespace cxstring;
+using namespace cxtu;
+using namespace cxindex;
+
+namespace {
+
+//===----------------------------------------------------------------------
===//
+// IndexPPCallbacks
+//===----------------------------------------------------------------------
===//
+
+class IndexPPCallbacks : public PPCallbacks {
+  Preprocessor &PP;
+  IndexingContext &IndexCtx;
+
+public:
+  IndexPPCallbacks(Preprocessor &PP, IndexingContext &indexCtx)
+    : PP(PP), IndexCtx(indexCtx) { }
+
+  virtual void InclusionDirective(SourceLocation HashLoc,
+                                  const Token &IncludeTok,
+                                  StringRef FileName,
+                                  bool IsAngled,
+                                  const FileEntry *File,
+                                  SourceLocation EndLoc,
+                                  StringRef SearchPath,
+                                  StringRef RelativePath) {
+    bool isImport = (IncludeTok.is(tok::identifier) &&
+            IncludeTok.getIdentifierInfo()->getPPKeywordID() ==
tok::pp_import);
+    IndexCtx.ppIncludedFile(HashLoc, FileName, File, isImport, IsAngled);
+  }
+
+  /// MacroDefined - This hook is called whenever a macro definition is
seen.
+  virtual void MacroDefined(const Token &Id, const MacroInfo *MI) {
+    if (MI->isBuiltinMacro())
+      return;
+    if (IndexCtx.isNotFromSourceFile(MI->getDefinitionLoc()))
+      return;
+
+    SourceLocation Loc = MI->getDefinitionLoc();
+    SourceLocation DefBegin = MI->tokens_empty() ? Loc
+                                     :
MI->getReplacementToken(0).getLocation();
+    IndexCtx.ppMacroDefined(Loc,
+                            Id.getIdentifierInfo()->getName(),
+                            DefBegin,
+                            MI->getDefinitionLength(PP.getSourceManager()),
+                            MI);
+  }
+
+  /// MacroUndefined - This hook is called whenever a macro #undef is seen.
+  /// MI is released immediately following this callback.
+  virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo
*MI) {
+    if (MI->isBuiltinMacro())
+      return;
+    if (IndexCtx.isNotFromSourceFile(MI->getDefinitionLoc()))
+      return;
+
+    SourceLocation Loc = MacroNameTok.getLocation();
+    IndexCtx.ppMacroUndefined(Loc,
+                            MacroNameTok.getIdentifierInfo()->getName(),
+                            MI);
+  }
+
+  /// MacroExpands - This is called by when a macro invocation is found.
+  virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI,
+                            SourceRange Range) {
+    if (MI->isBuiltinMacro())
+      return;
+    if (IndexCtx.isNotFromSourceFile(MI->getDefinitionLoc()))
+      return;
+
+    SourceLocation Loc = MacroNameTok.getLocation();
+    IndexCtx.ppMacroExpanded(Loc,
+                             MacroNameTok.getIdentifierInfo()->getName(),
+                             MI);
+  }
+  
+  /// SourceRangeSkipped - This hook is called when a source range is
skipped.
+  /// \param Range The SourceRange that was skipped. The range begins at
the
+  /// #if/#else directive and ends after the #endif/#else directive.
+  virtual void SourceRangeSkipped(SourceRange Range) {
+  }
+};
+
+//===----------------------------------------------------------------------
===//
+// IndexingConsumer
+//===----------------------------------------------------------------------
===//
+
+class IndexingConsumer : public ASTConsumer {
+  IndexingContext &IndexCtx;
+
+public:
+  explicit IndexingConsumer(IndexingContext &indexCtx)
+    : IndexCtx(indexCtx) { }
+
+  // ASTConsumer Implementation
+
+  virtual void Initialize(ASTContext &Context) {
+    IndexCtx.setASTContext(Context);
+    IndexCtx.invokeStartedTranslationUnit();
+  }
+
+  virtual void HandleTranslationUnit(ASTContext &Ctx) {
+    IndexCtx.invokeFinishedTranslationUnit();
+  }
+
+  virtual void HandleTopLevelDecl(DeclGroupRef DG) {
+    IndexCtx.indexDeclGroupRef(DG);
+  }
+
+  /// \brief Handle the specified top-level declaration that occurred
inside
+  /// and ObjC container.
+  virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) {
+    // They will be handled after the interface is seen first.
+    IndexCtx.addTUDeclInObjCContainer(D);
+  }
+
+  /// \brief This is called by the AST reader when deserializing things.
+  /// The default implementation forwards to HandleTopLevelDecl but we
don't
+  /// care about them when indexing, so have an empty definition.
+  virtual void HandleInterestingDecl(DeclGroupRef D) {}
+};
+
+//===----------------------------------------------------------------------
===//
+// IndexingDiagnosticConsumer
+//===----------------------------------------------------------------------
===//
+
+class IndexingDiagnosticConsumer : public DiagnosticConsumer {
+  IndexingContext &IndexCtx;
+  
+public:
+  explicit IndexingDiagnosticConsumer(IndexingContext &indexCtx)
+    : IndexCtx(indexCtx) {}
+  
+  virtual void HandleDiagnostic(DiagnosticsEngine::Level Level,
+                                const Diagnostic &Info) {
+    // Default implementation (Warnings/errors count).
+    DiagnosticConsumer::HandleDiagnostic(Level, Info);
+
+    IndexCtx.handleDiagnostic(StoredDiagnostic(Level, Info));
+  }
+
+  DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
+    return new IgnoringDiagConsumer();
+  }
+};
+
+class CaptureDiagnosticConsumer : public DiagnosticConsumer {
+  SmallVector<StoredDiagnostic, 4> Errors;
+public:
+
+  virtual void HandleDiagnostic(DiagnosticsEngine::Level level,
+                                const Diagnostic &Info) {
+    if (level >= DiagnosticsEngine::Error)
+      Errors.push_back(StoredDiagnostic(level, Info));
+  }
+
+  DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
+    return new IgnoringDiagConsumer();
+  }
+};
+
+//===----------------------------------------------------------------------
===//
+// IndexingFrontendAction
+//===----------------------------------------------------------------------
===//
+
+class IndexingFrontendAction : public ASTFrontendAction {
+  IndexingContext IndexCtx;
+
+public:
+  IndexingFrontendAction(CXClientData clientData,
+                         IndexerCallbacks &indexCallbacks,
+                         unsigned indexOptions,
+                         CXTranslationUnit cxTU)
+    : IndexCtx(clientData, indexCallbacks, indexOptions, cxTU) { }
+
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         StringRef InFile) {
+    CI.getDiagnostics().setClient(new IndexingDiagnosticConsumer(IndexCtx),
+                                  /*own=*/true);
+    IndexCtx.setASTContext(CI.getASTContext());
+    Preprocessor &PP = CI.getPreprocessor();
+    PP.addPPCallbacks(new IndexPPCallbacks(PP, IndexCtx));
+    return new IndexingConsumer(IndexCtx);
+  }
+
+  virtual TranslationUnitKind getTranslationUnitKind() { return TU_Prefix;
}
+  virtual bool hasCodeCompletionSupport() const { return false; }
+};
+
+//===----------------------------------------------------------------------
===//
+// clang_indexTranslationUnit Implementation
+//===----------------------------------------------------------------------
===//
+
+struct IndexTranslationUnitInfo {
+  CXIndex CIdx;
+  CXClientData client_data;
+  IndexerCallbacks *index_callbacks;
+  unsigned index_callbacks_size;
+  unsigned index_options;
+  const char *source_filename;
+  const char *const *command_line_args;
+  int num_command_line_args;
+  struct CXUnsavedFile *unsaved_files;
+  unsigned num_unsaved_files;
+  CXTranslationUnit *out_TU;
+  unsigned TU_options;
+  int result;
+};
+
+struct MemBufferOwner {
+  SmallVector<const llvm::MemoryBuffer *, 8> Buffers;
+  
+  ~MemBufferOwner() {
+    for (SmallVectorImpl<const llvm::MemoryBuffer *>::iterator
+           I = Buffers.begin(), E = Buffers.end(); I != E; ++I)
+      delete *I;
+  }
+};
+
+} // anonymous namespace
+
+static void clang_indexTranslationUnit_Impl(void *UserData) {
+  IndexTranslationUnitInfo *ITUI =
+    static_cast<IndexTranslationUnitInfo*>(UserData);
+  CXIndex CIdx = ITUI->CIdx;
+  CXClientData client_data = ITUI->client_data;
+  IndexerCallbacks *client_index_callbacks = ITUI->index_callbacks;
+  unsigned index_callbacks_size = ITUI->index_callbacks_size;
+  unsigned index_options = ITUI->index_options;
+  const char *source_filename = ITUI->source_filename;
+  const char * const *command_line_args = ITUI->command_line_args;
+  int num_command_line_args = ITUI->num_command_line_args;
+  struct CXUnsavedFile *unsaved_files = ITUI->unsaved_files;
+  unsigned num_unsaved_files = ITUI->num_unsaved_files;
+  CXTranslationUnit *out_TU  = ITUI->out_TU;
+  unsigned TU_options = ITUI->TU_options;
+  ITUI->result = 1; // init as error.
+  
+  if (out_TU)
+    *out_TU = 0;
+  bool requestedToGetTU = (out_TU != 0); 
+
+  if (!CIdx)
+    return;
+  if (!client_index_callbacks || index_callbacks_size == 0)
+    return;
+
+  IndexerCallbacks CB;
+  memset(&CB, 0, sizeof(CB));
+  unsigned ClientCBSize = index_callbacks_size < sizeof(CB)
+                                  ? index_callbacks_size : sizeof(CB);
+  memcpy(&CB, client_index_callbacks, ClientCBSize);
+
+  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
+
+  (void)CXXIdx;
+  (void)TU_options;
+  
+  CaptureDiagnosticConsumer *CaptureDiag = new CaptureDiagnosticConsumer();
+
+  // Configure the diagnostics.
+  DiagnosticOptions DiagOpts;
+  llvm::IntrusiveRefCntPtr<DiagnosticsEngine>
+    Diags(CompilerInstance::createDiagnostics(DiagOpts,
num_command_line_args, 
+                                                command_line_args,
+                                                CaptureDiag,
+                                                /*ShouldOwnClient=*/true));
+
+  // Recover resources if we crash before exiting this function.
+  llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
+    llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
+    DiagCleanup(Diags.getPtr());
+  
+  llvm::OwningPtr<std::vector<const char *> > 
+    Args(new std::vector<const char*>());
+
+  // Recover resources if we crash before exiting this method.
+  llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
+    ArgsCleanup(Args.get());
+  
+  Args->insert(Args->end(), command_line_args,
+               command_line_args + num_command_line_args);
+
+  // The 'source_filename' argument is optional.  If the caller does not
+  // specify it then it is assumed that the source file is specified
+  // in the actual argument list.
+  // Put the source file after command_line_args otherwise if '-x' flag is
+  // present it will be unused.
+  if (source_filename)
+    Args->push_back(source_filename);
+  
+  llvm::IntrusiveRefCntPtr<CompilerInvocation>
+    CInvok(createInvocationFromCommandLine(*Args, Diags));
+
+  if (!CInvok)
+    return;
+
+  // Recover resources if we crash before exiting this function.
+  llvm::CrashRecoveryContextCleanupRegistrar<CompilerInvocation,
+    llvm::CrashRecoveryContextReleaseRefCleanup<CompilerInvocation> >
+    CInvokCleanup(CInvok.getPtr());
+
+  if (CInvok->getFrontendOpts().Inputs.empty())
+    return;
+
+  llvm::OwningPtr<MemBufferOwner> BufOwner(new MemBufferOwner());
+
+  // Recover resources if we crash before exiting this method.
+  llvm::CrashRecoveryContextCleanupRegistrar<MemBufferOwner>
+    BufOwnerCleanup(BufOwner.get());
+
+  for (unsigned I = 0; I != num_unsaved_files; ++I) {
+    StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
+    const llvm::MemoryBuffer *Buffer
+      = llvm::MemoryBuffer::getMemBufferCopy(Data,
unsaved_files[I].Filename);
+
CInvok->getPreprocessorOpts().addRemappedFile(unsaved_files[I].Filename,
Buffer);
+    BufOwner->Buffers.push_back(Buffer);
+  }
+
+  // Since libclang is primarily used by batch tools dealing with
+  // (often very broken) source code, where spell-checking can have a
+  // significant negative impact on performance (particularly when 
+  // precompiled headers are involved), we disable it.
+  CInvok->getLangOpts().SpellChecking = false;
+
+  if (!requestedToGetTU)
+    CInvok->getPreprocessorOpts().DetailedRecord = false;
+
+  ASTUnit *Unit = ASTUnit::create(CInvok.getPtr(), Diags);
+  llvm::OwningPtr<CXTUOwner> CXTU(new
CXTUOwner(MakeCXTranslationUnit(Unit)));
+
+  // Recover resources if we crash before exiting this method.
+  llvm::CrashRecoveryContextCleanupRegistrar<CXTUOwner>
+    CXTUCleanup(CXTU.get());
+
+  llvm::OwningPtr<IndexingFrontendAction> IndexAction;
+  IndexAction.reset(new IndexingFrontendAction(client_data, CB,
+                                               index_options,
CXTU->getTU()));
+
+  // Recover resources if we crash before exiting this method.
+  llvm::CrashRecoveryContextCleanupRegistrar<IndexingFrontendAction>
+    IndexActionCleanup(IndexAction.get());
+
+  Unit = ASTUnit::LoadFromCompilerInvocationAction(CInvok.getPtr(), Diags,
+                                                       IndexAction.get(),
+                                                       Unit);
+  if (!Unit)
+    return;
+
+  // FIXME: Set state of the ASTUnit according to the TU_options.
+  if (out_TU)
+    *out_TU = CXTU->takeTU();
+
+  ITUI->result = 0; // success.
+}
+
+//===----------------------------------------------------------------------
===//
+// libclang public APIs.
+//===----------------------------------------------------------------------
===//
+
+extern "C" {
+
+int clang_indexTranslationUnit(CXIndex CIdx,
+                                CXClientData client_data,
+                                IndexerCallbacks *index_callbacks,
+                                unsigned index_callbacks_size,
+                                unsigned index_options,
+                                const char *source_filename,
+                                const char * const *command_line_args,
+                                int num_command_line_args,
+                                struct CXUnsavedFile *unsaved_files,
+                                unsigned num_unsaved_files,
+                                CXTranslationUnit *out_TU,
+                                unsigned TU_options) {
+  IndexTranslationUnitInfo ITUI = { CIdx, client_data, index_callbacks,
+                                    index_callbacks_size, index_options,
+                                    source_filename, command_line_args,
+                                    num_command_line_args, unsaved_files,
+                                    num_unsaved_files, out_TU, TU_options,
0 };
+
+  if (getenv("CINDEXTEST_NOTHREADS")) {
+    clang_indexTranslationUnit_Impl(&ITUI);
+    return ITUI.result;
+  }
+
+  llvm::CrashRecoveryContext CRC;
+
+  if (!RunSafely(CRC, clang_indexTranslationUnit_Impl, &ITUI)) {
+    fprintf(stderr, "libclang: crash detected during parsing: {\n");
+    fprintf(stderr, "  'source_filename' : '%s'\n", source_filename);
+    fprintf(stderr, "  'command_line_args' : [");
+    for (int i = 0; i != num_command_line_args; ++i) {
+      if (i)
+        fprintf(stderr, ", ");
+      fprintf(stderr, "'%s'", command_line_args[i]);
+    }
+    fprintf(stderr, "],\n");
+    fprintf(stderr, "  'unsaved_files' : [");
+    for (unsigned i = 0; i != num_unsaved_files; ++i) {
+      if (i)
+        fprintf(stderr, ", ");
+      fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
+              unsaved_files[i].Length);
+    }
+    fprintf(stderr, "],\n");
+    fprintf(stderr, "  'options' : %d,\n", TU_options);
+    fprintf(stderr, "}\n");
+    
+    return 1;
+  } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
+    if (out_TU)
+      PrintLibclangResourceUsage(*out_TU);
+  }
+  
+  return ITUI.result;
+}
+
+void clang_indexLoc_getFileLocation(CXIdxLoc location,
+                                    CXIdxFile *indexFile,
+                                    CXFile *file,
+                                    unsigned *line,
+                                    unsigned *column,
+                                    unsigned *offset) {
+  if (indexFile) *indexFile = 0;
+  if (file)   *file = 0;
+  if (line)   *line = 0;
+  if (column) *column = 0;
+  if (offset) *offset = 0;
+
+  SourceLocation Loc =
SourceLocation::getFromRawEncoding(location.int_data);
+  if (!location.ptr_data[0] || Loc.isInvalid())
+    return;
+
+  IndexingContext &IndexCtx =
+      *static_cast<IndexingContext*>(location.ptr_data[0]);
+  IndexCtx.translateLoc(Loc, indexFile, file, line, column, offset);
+}
+
+CXSourceLocation clang_indexLoc_getCXSourceLocation(CXIdxLoc location) {
+  SourceLocation Loc =
SourceLocation::getFromRawEncoding(location.int_data);
+  if (!location.ptr_data[0] || Loc.isInvalid())
+    return clang_getNullLocation();
+
+  IndexingContext &IndexCtx =
+      *static_cast<IndexingContext*>(location.ptr_data[0]);
+  return cxloc::translateSourceLocation(IndexCtx.getASTContext(), Loc);
+}
+
+} // end: extern "C"
+

Added: cfe/trunk/tools/libclang/IndexingContext.cpp
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/IndexingContext
.cpp?rev=142233&view=auto
============================================================================
==
--- cfe/trunk/tools/libclang/IndexingContext.cpp (added)
+++ cfe/trunk/tools/libclang/IndexingContext.cpp Mon Oct 17 14:48:19 2011
@@ -0,0 +1,695 @@
+//===- CIndexHigh.cpp - Higher level API functions
------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------
===//
+
+#include "IndexingContext.h"
+#include "CXTranslationUnit.h"
+#include "CIndexDiagnostic.h"
+
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/AST/DeclObjC.h"
+
+using namespace clang;
+using namespace cxindex;
+using namespace cxcursor;
+
+const char *IndexingContext::StrAdapter::toCStr(StringRef Str) {
+  if (Str.empty())
+    return "";
+  if (Str.data()[Str.size()] == '\0')
+    return Str.data();
+  Scratch += Str;
+  Scratch.push_back('\0');
+  return Scratch.data() + (Scratch.size() - Str.size() - 1);
+}
+
+void IndexingContext::setASTContext(ASTContext &ctx) {
+  Ctx = &ctx;
+  static_cast<ASTUnit*>(CXTU->TUData)->setASTContext(&ctx);
+}
+
+void IndexingContext::ppIncludedFile(SourceLocation hashLoc,
+                                     StringRef filename,
+                                     const FileEntry *File,
+                                     bool isImport, bool isAngled) {
+  if (!CB.ppIncludedFile)
+    return;
+
+  StrAdapter SA(this);
+  CXIdxIncludedFileInfo Info = { getIndexLoc(hashLoc),
+                                 SA.toCStr(filename),
+                                 getIndexFile(File),
+                                 isImport, isAngled };
+  CB.ppIncludedFile(ClientData, &Info);
+}
+
+void IndexingContext::ppMacroDefined(SourceLocation Loc, StringRef Name,
+                                     SourceLocation DefBegin, unsigned
Length,
+                                     const void *OpaqueMacro) {
+  if (!CB.ppMacroDefined)
+    return;
+
+  StrAdapter SA(this);
+  CXIdxMacroInfo MacroInfo =  { getIndexLoc(Loc), SA.toCStr(Name) }; 
+  CXIdxMacroDefinedInfo Info = { &MacroInfo,
+                                 getIndexLoc(DefBegin), Length };
+  CXIdxMacro idxMacro = CB.ppMacroDefined(ClientData, &Info);
+  MacroMap[OpaqueMacro] = idxMacro;
+}
+
+void IndexingContext::ppMacroUndefined(SourceLocation Loc, StringRef Name,
+                                       const void *OpaqueMacro) {
+  if (!CB.ppMacroUndefined)
+    return;
+
+  StrAdapter SA(this);
+  CXIdxMacroUndefinedInfo Info = { getIndexLoc(Loc),
+                                   SA.toCStr(Name), 0 };
+  CB.ppMacroUndefined(ClientData, &Info);
+}
+
+void IndexingContext::ppMacroExpanded(SourceLocation Loc, StringRef Name,
+                                      const void *OpaqueMacro) {
+  if (!CB.ppMacroExpanded)
+    return;
+
+  StrAdapter SA(this);
+  CXIdxMacroExpandedInfo Info = { getIndexLoc(Loc),
+                                   SA.toCStr(Name), 0 };
+  CB.ppMacroExpanded(ClientData, &Info);
+}
+
+void IndexingContext::invokeStartedTranslationUnit() {
+  CXIdxContainer idxCont = 0;
+  if (CB.startedTranslationUnit)
+    idxCont = CB.startedTranslationUnit(ClientData, 0);
+  addContainerInMap(Ctx->getTranslationUnitDecl(), idxCont);
+}
+
+void IndexingContext::invokeFinishedTranslationUnit() {
+  invokeEndedContainer(Ctx->getTranslationUnitDecl());
+}
+
+void IndexingContext::handleDiagnostic(const StoredDiagnostic &StoredDiag)
{
+  if (!CB.diagnostic)
+    return;
+
+  CXStoredDiagnostic CXDiag(StoredDiag, Ctx->getLangOptions());
+  CB.diagnostic(ClientData, &CXDiag, 0);
+}
+
+void IndexingContext::handleFunction(const FunctionDecl *D) {
+  StrAdapter SA(this);
+
+  if (D->isFirstDeclaration()) {
+    CXIdxEntity idxEntity = 0;
+    if (CB.indexFunction) {
+      CXIdxEntityInfo EntityInfo;
+      CXIdxIndexedDeclInfo DeclInfo;
+      CXIdxIndexedEntityInfo IdxEntityInfo;
+      getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+      CXIdxFunctionInfo Info = { &IdxEntityInfo,
+                                 D->isThisDeclarationADefinition() };
+
+      idxEntity = CB.indexFunction(ClientData, &Info);
+    }
+
+    addEntityInMap(D, idxEntity);
+
+  } else {
+    if (CB.indexFunctionRedeclaration) {
+      CXIdxIndexedDeclInfo DeclInfo;
+      CXIdxIndexedRedeclInfo RedeclInfo;
+      getIndexedRedeclInfo(D, RedeclInfo, DeclInfo);
+      CXIdxFunctionRedeclInfo Info = { &RedeclInfo,
+                                       D->isThisDeclarationADefinition() };
+
+      CB.indexFunctionRedeclaration(ClientData, &Info);
+    }
+  }
+}
+
+void IndexingContext::handleVar(const VarDecl *D) {
+  StrAdapter SA(this);
+
+  if (D->isFirstDeclaration()) {
+    CXIdxEntity idxEntity = 0;
+    if (CB.indexVariable) {
+      CXIdxEntityInfo EntityInfo;
+      CXIdxIndexedDeclInfo DeclInfo;
+      CXIdxIndexedEntityInfo IdxEntityInfo;
+      getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+      CXIdxVariableInfo Info = { &IdxEntityInfo,
+                                 D->isThisDeclarationADefinition() };
+
+      idxEntity = CB.indexVariable(ClientData, &Info);
+    }
+
+    addEntityInMap(D, idxEntity);
+
+  } else {
+    if (CB.indexVariableRedeclaration) {
+      CXIdxIndexedDeclInfo DeclInfo;
+      CXIdxIndexedRedeclInfo RedeclInfo;
+      getIndexedRedeclInfo(D, RedeclInfo, DeclInfo);
+      CXIdxVariableRedeclInfo Info = { &RedeclInfo,
+                                       D->isThisDeclarationADefinition() };
+
+      CB.indexVariableRedeclaration(ClientData, &Info);
+    }
+  }
+}
+
+void IndexingContext::handleField(const FieldDecl *D) {
+  StrAdapter SA(this);
+
+  CXIdxEntity idxEntity = 0;
+  if (CB.indexTypedef) {
+    CXIdxEntityInfo EntityInfo;
+    CXIdxIndexedDeclInfo DeclInfo;
+    CXIdxIndexedEntityInfo IdxEntityInfo;
+    getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+    CXIdxFieldInfo Info = { &IdxEntityInfo };
+
+    idxEntity = CB.indexField(ClientData, &Info);
+  }
+
+  addEntityInMap(D, idxEntity);
+}
+
+void IndexingContext::handleEnumerator(const EnumConstantDecl *D) {
+  StrAdapter SA(this);
+
+  CXIdxEntity idxEntity = 0;
+  if (CB.indexTypedef) {
+    CXIdxEntityInfo EntityInfo;
+    CXIdxIndexedDeclInfo DeclInfo;
+    CXIdxIndexedEntityInfo IdxEntityInfo;
+    getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+    CXIdxEnumeratorInfo Info = { &IdxEntityInfo };
+
+    idxEntity = CB.indexEnumerator(ClientData, &Info);
+  }
+
+  addEntityInMap(D, idxEntity);
+}
+
+void IndexingContext::handleTagDecl(const TagDecl *D) {
+  StrAdapter SA(this);
+
+  if (D->isFirstDeclaration()) {
+    CXIdxEntity idxEntity = 0;
+    if (CB.indexTagType) {
+      CXIdxEntityInfo EntityInfo;
+      CXIdxIndexedDeclInfo DeclInfo;
+      CXIdxIndexedEntityInfo IdxEntityInfo;
+      getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+      CXIdxTagTypeInfo Info = { &IdxEntityInfo,
+                                 D->isThisDeclarationADefinition(),
+                                 D->getIdentifier() == 0};
+
+      idxEntity = CB.indexTagType(ClientData, &Info);
+    }
+
+    addEntityInMap(D, idxEntity);
+
+  } else {
+    if (CB.indexTagTypeRedeclaration) {
+      CXIdxIndexedDeclInfo DeclInfo;
+      CXIdxIndexedRedeclInfo RedeclInfo;
+      getIndexedRedeclInfo(D, RedeclInfo, DeclInfo);
+      CXIdxTagTypeRedeclInfo Info = { &RedeclInfo,
+                                      D->isThisDeclarationADefinition() };
+
+      CB.indexTagTypeRedeclaration(ClientData, &Info);
+    }
+  }
+}
+
+void IndexingContext::handleTypedef(const TypedefDecl *D) {
+  StrAdapter SA(this);
+
+  CXIdxEntity idxEntity = 0;
+  if (CB.indexTypedef) {
+    CXIdxEntityInfo EntityInfo;
+    CXIdxIndexedDeclInfo DeclInfo;
+    CXIdxIndexedEntityInfo IdxEntityInfo;
+    getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+    CXIdxTypedefInfo Info = { &IdxEntityInfo };
+
+    idxEntity = CB.indexTypedef(ClientData, &Info);
+  }
+
+  addEntityInMap(D, idxEntity);
+}
+
+void IndexingContext::handleObjCInterface(const ObjCInterfaceDecl *D) {
+  StrAdapter SA(this);
+
+  CXIdxEntity idxEntity = 0;
+  if (CB.indexObjCClass) {
+    CXIdxEntityInfo EntityInfo;
+    CXIdxIndexedDeclInfo DeclInfo;
+    CXIdxIndexedEntityInfo IdxEntityInfo;
+    getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+    CXIdxObjCClassInfo Info = { &IdxEntityInfo,
+                                D->isForwardDecl() };
+
+    idxEntity = CB.indexObjCClass(ClientData, &Info);
+  }
+
+  addEntityInMap(D, idxEntity);
+}
+
+void IndexingContext::defineObjCInterface(const ObjCInterfaceDecl *D) {
+  if (!CB.defineObjCClass)
+    return;
+
+  CXIdxObjCBaseClassInfo BaseClass = { getIndexEntity(D->getSuperClass()),
+                                       getIndexLoc(D->getSuperClassLoc())
};
+  if (D->getSuperClass()) {
+    BaseClass.objcClass = getIndexEntity(D->getSuperClass());
+    BaseClass.loc = getIndexLoc(D->getSuperClassLoc());
+  }
+  
+  SmallVector<CXIdxObjCProtocolRefInfo, 4> ProtInfos;
+  ObjCInterfaceDecl::protocol_loc_iterator LI = D->protocol_loc_begin();
+  for (ObjCInterfaceDecl::protocol_iterator
+         I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I, ++LI)
{
+    SourceLocation Loc = *LI;
+    ObjCProtocolDecl *PD = *I;
+    CXIdxObjCProtocolRefInfo ProtInfo = { getIndexEntity(PD),
+                                          getIndexLoc(Loc) };
+    ProtInfos.push_back(ProtInfo);
+  }
+
+  SmallVector<CXIdxObjCProtocolRefInfo *, 4> Prots;
+  for (unsigned i = 0, e = Prots.size(); i != e; ++i)
+    Prots.push_back(&ProtInfos[i]);
+  
+  CXIdxObjCClassDefineInfo Info = { getCursor(D),
+                                    getIndexEntity(D), 
+                                    getIndexContainerForDC(D),
+                                    D->getSuperClass() ? &BaseClass : 0,
+                                    Prots.data(),
+                                    Prots.size() };
+  CB.defineObjCClass(ClientData, &Info);
+}
+
+void IndexingContext::handleObjCProtocol(const ObjCProtocolDecl *D) {
+  StrAdapter SA(this);
+
+  CXIdxEntity idxEntity = 0;
+  if (CB.indexObjCProtocol) {
+    CXIdxEntityInfo EntityInfo;
+    CXIdxIndexedDeclInfo DeclInfo;
+    CXIdxIndexedEntityInfo IdxEntityInfo;
+    getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+    CXIdxObjCProtocolInfo Info = { &IdxEntityInfo,
+                                D->isForwardDecl() };
+
+    idxEntity = CB.indexObjCProtocol(ClientData, &Info);
+  }
+
+  addEntityInMap(D, idxEntity);
+}
+
+void IndexingContext::handleObjCCategory(const ObjCCategoryDecl *D) {
+  StrAdapter SA(this);
+
+  CXIdxEntity idxEntity = 0;
+  if (CB.indexObjCCategory) {
+    CXIdxEntityInfo EntityInfo;
+    CXIdxIndexedDeclInfo DeclInfo;
+    CXIdxIndexedEntityInfo IdxEntityInfo;
+    getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+    CXIdxObjCCategoryInfo Info = { &IdxEntityInfo,
+                                   getIndexEntity(D->getClassInterface())
};
+
+    idxEntity = CB.indexObjCCategory(ClientData, &Info);
+  }
+
+  addEntityInMap(D, idxEntity);
+}
+
+void IndexingContext::handleObjCMethod(const ObjCMethodDecl *D) {
+  StrAdapter SA(this);
+
+  if (D->isCanonicalDecl()) {
+    CXIdxEntity idxEntity = 0;
+    if (CB.indexObjCMethod) {
+      CXIdxEntityInfo EntityInfo;
+      CXIdxIndexedDeclInfo DeclInfo;
+      CXIdxIndexedEntityInfo IdxEntityInfo;
+      getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+      CXIdxObjCMethodInfo Info = { &IdxEntityInfo,
+                                   D->isThisDeclarationADefinition() };
+
+      idxEntity = CB.indexObjCMethod(ClientData, &Info);
+    }
+
+    addEntityInMap(D, idxEntity);
+
+  } else {
+    if (CB.indexObjCMethodRedeclaration) {
+      CXIdxIndexedRedeclInfo RedeclInfo;
+      CXIdxIndexedDeclInfo DeclInfo;
+      getIndexedRedeclInfo(D, RedeclInfo, DeclInfo);
+      CXIdxObjCMethodRedeclInfo Info = { &RedeclInfo,
+                                         D->isThisDeclarationADefinition()
};
+
+      CB.indexObjCMethodRedeclaration(ClientData, &Info);
+    }
+  }
+}
+
+void IndexingContext::handleObjCProperty(const ObjCPropertyDecl *D) {
+  StrAdapter SA(this);
+
+  CXIdxEntity idxEntity = 0;
+  if (CB.indexObjCProperty) {
+    CXIdxEntityInfo EntityInfo;
+    CXIdxIndexedDeclInfo DeclInfo;
+    CXIdxIndexedEntityInfo IdxEntityInfo;
+    getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+    CXIdxObjCPropertyInfo Info = { &IdxEntityInfo };
+
+    idxEntity = CB.indexObjCProperty(ClientData, &Info);
+  }
+
+  addEntityInMap(D, idxEntity);
+}
+
+void IndexingContext::handleReference(const NamedDecl *D, SourceLocation
Loc,
+                                      const NamedDecl *Parent,
+                                      const DeclContext *DC,
+                                      const Expr *E) {
+  if (Loc.isInvalid())
+    return;
+  if (!CB.indexEntityReference)
+    return;
+  if (isNotFromSourceFile(D->getLocation()))
+    return;
+
+  CXIdxEntityRefInfo Info = { E ? MakeCXCursor((Stmt*)E,
+                                               (Decl*)cast<Decl>(DC), CXTU)
+                                : getRefCursor(D, Loc),
+                              getIndexLoc(Loc),
+                              getIndexEntity(D),
+                              getIndexEntity(Parent),
+                              getIndexContainerForDC(DC) };
+  CB.indexEntityReference(ClientData, &Info);
+}
+
+void IndexingContext::invokeStartedStatementBody(const NamedDecl *D,
+                                                 const DeclContext *DC) {
+  const Stmt *Body = cast<Decl>(DC)->getBody();
+  assert(Body);
+
+  CXIdxContainer idxCont = 0;
+  if (CB.startedStatementBody) {
+    CXIdxContainerInfo ContainerInfo;
+    getContainerInfo(D, ContainerInfo);
+    CXIdxStmtBodyInfo Info = { &ContainerInfo,
+                               getIndexLoc(Body->getLocStart()) };
+
+    idxCont = CB.startedStatementBody(ClientData, &Info);
+  }
+  addContainerInMap(DC, idxCont);
+}
+
+void IndexingContext::invokeStartedTagTypeDefinition(const TagDecl *D) {
+  CXIdxContainer idxCont = 0;
+  if (CB.startedTagTypeDefinition) {
+    CXIdxContainerInfo ContainerInfo;
+    getContainerInfo(D, ContainerInfo);
+    CXIdxTagTypeDefinitionInfo Info = { &ContainerInfo };
+
+    idxCont = CB.startedTagTypeDefinition(ClientData, &Info);
+  }
+  addContainerInMap(D, idxCont);
+}
+
+void IndexingContext::invokeStartedObjCContainer(const ObjCContainerDecl
*D) {
+  CXIdxContainer idxCont = 0;
+  if (CB.startedObjCContainer) {
+    CXIdxContainerInfo ContainerInfo;
+    getContainerInfo(D, ContainerInfo);
+    CXIdxObjCContainerInfo Info = { &ContainerInfo };
+
+    idxCont = CB.startedObjCContainer(ClientData, &Info);
+  }
+  addContainerInMap(D, idxCont);
+}
+
+void IndexingContext::invokeEndedContainer(const DeclContext *DC) {
+  if (CB.endedContainer) {
+    CXIdxEndContainerInfo Info = { getIndexContainerForDC(DC),
+                                   getIndexLoc(cast<Decl>(DC)->getLocEnd())
};
+    CB.endedContainer(ClientData, &Info);
+  }
+}
+
+bool IndexingContext::isNotFromSourceFile(SourceLocation Loc) const {
+  if (Loc.isInvalid())
+    return true;
+  SourceManager &SM = Ctx->getSourceManager();
+  SourceLocation FileLoc = SM.getFileLoc(Loc);
+  FileID FID = SM.getFileID(FileLoc);
+  return SM.getFileEntryForID(FID) == 0;
+}
+
+void IndexingContext::addContainerInMap(const DeclContext *DC,
+                                        CXIdxContainer container) {
+  assert(getScopedContext(DC) == DC);
+  ContainerMapTy::iterator I = ContainerMap.find(DC);
+  if (I == ContainerMap.end()) {
+    if (container)
+      ContainerMap[DC] = container;
+    return;
+  }
+  // Allow changing the container of a previously seen DeclContext so we
+  // can handle invalid user code, like a function re-definition.
+  if (container)
+    I->second = container;
+  else
+    ContainerMap.erase(I);
+}
+
+void IndexingContext::addEntityInMap(const NamedDecl *D, CXIdxEntity
entity) {
+  assert(getEntityDecl(D) == D &&
+         "Tried to add a non-entity (canonical) decl");
+  assert(EntityMap.find(D) == EntityMap.end());
+  if (entity || D->isFromASTFile())
+    EntityMap[D] = entity;
+}
+
+CXIdxEntity IndexingContext::getIndexEntity(const NamedDecl *D) {
+  if (!D)
+    return 0;
+  D = getEntityDecl(D);
+  EntityMapTy::const_iterator I = EntityMap.find(D);
+  if (I != EntityMap.end())
+    return I->second;
+
+  if (!D->isFromASTFile()) {
+    //assert(0 && "Entity not in map");
+    return 0;
+  }
+
+  StrAdapter SA(this);
+  
+  CXIdxEntity idxEntity = 0;
+  if (CB.importedEntity) {
+    CXIdxEntityInfo EntityInfo;
+    getEntityInfo(D, EntityInfo, SA);
+    CXIdxImportedEntityInfo Info = { &EntityInfo,
+                                     getCursor(D),
+                                     getIndexLoc(D->getLocation()),
+                                     /*CXIdxASTFile*/0 };
+    idxEntity = CB.importedEntity(ClientData, &Info);
+  }
+  addEntityInMap(D, idxEntity);
+  return idxEntity;
+}
+
+const NamedDecl *IndexingContext::getEntityDecl(const NamedDecl *D) const {
+  assert(D);
+  D = cast<NamedDecl>(D->getCanonicalDecl());
+
+  if (const ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(D)) {
+    if (Cat->IsClassExtension())
+      return getEntityDecl(Cat->getClassInterface());
+
+  } else if (const ObjCImplementationDecl *
+               ImplD = dyn_cast<ObjCImplementationDecl>(D)) {
+    return getEntityDecl(ImplD->getClassInterface());
+
+  } else if (const ObjCCategoryImplDecl *
+               CatImplD = dyn_cast<ObjCCategoryImplDecl>(D)) {
+    return getEntityDecl(CatImplD->getCategoryDecl());
+  }
+
+  return D;
+}
+
+const DeclContext *
+IndexingContext::getScopedContext(const DeclContext *DC) const {
+  // Local contexts are ignored for indexing.
+  const DeclContext *FuncCtx = cast<Decl>(DC)->getParentFunctionOrMethod();
+  if (FuncCtx)
+    return FuncCtx;
+
+  // We consider enums always scoped for indexing.
+  if (isa<TagDecl>(DC))
+    return DC;
+
+  if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
+    if (NS->isAnonymousNamespace())
+      return getScopedContext(NS->getParent());
+    return NS;
+  }
+
+  return DC->getRedeclContext();
+}
+
+CXIdxContainer
+IndexingContext::getIndexContainerForDC(const DeclContext *DC) const {
+  DC = getScopedContext(DC);
+  ContainerMapTy::const_iterator I = ContainerMap.find(DC);
+//  assert(I != ContainerMap.end() &&
+//         "Failed to include a scoped context in the container map");
+  return I->second;
+}
+
+CXIdxFile IndexingContext::getIndexFile(const FileEntry *File) {
+  if (!File)
+    return 0;
+  if (!CB.recordFile)
+    return 0;
+
+  FileMapTy::iterator FI = FileMap.find(File);
+  if (FI != FileMap.end())
+    return FI->second;
+
+  CXIdxFile idxFile = CB.recordFile(ClientData, (CXFile)File, 0);
+  FileMap[File] = idxFile;
+  return idxFile;
+}
+
+CXIdxLoc IndexingContext::getIndexLoc(SourceLocation Loc) const {
+  CXIdxLoc idxLoc =  { {0, 0}, 0 };
+  if (Loc.isInvalid())
+    return idxLoc;
+
+  idxLoc.ptr_data[0] = (void*)this;
+  idxLoc.int_data = Loc.getRawEncoding();
+  return idxLoc;
+}
+
+void IndexingContext::translateLoc(SourceLocation Loc,
+                                   CXIdxFile *indexFile, CXFile *file,
+                                   unsigned *line, unsigned *column,
+                                   unsigned *offset) {
+  if (Loc.isInvalid())
+    return;
+
+  SourceManager &SM = Ctx->getSourceManager();
+  Loc = SM.getFileLoc(Loc);
+
+  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
+  FileID FID = LocInfo.first;
+  unsigned FileOffset = LocInfo.second;
+
+  if (FID.isInvalid())
+    return;
+  
+  const FileEntry *FE = SM.getFileEntryForID(FID);
+  if (indexFile)
+    *indexFile = getIndexFile(FE);
+  if (file)
+    *file = (void *)FE;
+  if (line)
+    *line = SM.getLineNumber(FID, FileOffset);
+  if (column)
+    *column = SM.getColumnNumber(FID, FileOffset);
+  if (offset)
+    *offset = FileOffset;
+}
+
+void IndexingContext::getIndexedEntityInfo(const NamedDecl *D,
+                          CXIdxIndexedEntityInfo &IdxEntityInfo,
+                          CXIdxEntityInfo &EntityInfo,
+                          CXIdxIndexedDeclInfo &IdxDeclInfo,
+                          StrAdapter &SA) {
+  getEntityInfo(D, EntityInfo, SA);
+  getIndexedDeclInfo(D, IdxDeclInfo);
+  IdxEntityInfo.entityInfo = &EntityInfo;
+  IdxEntityInfo.declInfo = &IdxDeclInfo;
+}
+
+void IndexingContext::getIndexedDeclInfo(const NamedDecl *D,
+                                         CXIdxIndexedDeclInfo &IdxDeclInfo)
{
+  IdxDeclInfo.cursor = getCursor(D);
+  IdxDeclInfo.loc = getIndexLoc(D->getLocation());
+  IdxDeclInfo.container = getIndexContainer(D);
+}
+
+void IndexingContext::getIndexedRedeclInfo(const NamedDecl *D,
+                          CXIdxIndexedRedeclInfo &RedeclInfo,
+                          CXIdxIndexedDeclInfo &IdxDeclInfo) {
+  getIndexedDeclInfo(D, IdxDeclInfo);
+  RedeclInfo.declInfo = &IdxDeclInfo;
+  RedeclInfo.entity = getIndexEntity(D);
+}
+
+void IndexingContext::getContainerInfo(const NamedDecl *D,
+                          CXIdxContainerInfo &ContainerInfo) {
+  ContainerInfo.cursor = getCursor(D);
+  ContainerInfo.loc = getIndexLoc(D->getLocation());
+  ContainerInfo.entity = getIndexEntity(D);
+}
+
+void IndexingContext::getEntityInfo(const NamedDecl *D,
+                          CXIdxEntityInfo &EntityInfo,
+                          StrAdapter &SA) {
+  if (IdentifierInfo *II = D->getIdentifier()) {
+    EntityInfo.name = SA.toCStr(II->getName());
+
+  } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
+    EntityInfo.name = 0;
+
+  } else {
+    unsigned Begin = SA.getCurSize();
+    {
+      llvm::raw_svector_ostream OS(SA.getBuffer());
+      D->printName(OS);
+    }
+    EntityInfo.name = SA.getCStr(Begin);
+  }
+
+  unsigned Begin = SA.getCurSize();
+  bool Ignore = getDeclCursorUSR(D, SA.getBuffer());
+  if (Ignore) {
+    EntityInfo.USR = "";
+  } else {
+    EntityInfo.USR = SA.getCStr(Begin);
+  }
+}
+
+CXCursor IndexingContext::getRefCursor(const NamedDecl *D, SourceLocation
Loc) {
+  if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
+    return MakeCursorTypeRef(TD, Loc, CXTU);
+  if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
+    return MakeCursorObjCClassRef(ID, Loc, CXTU);
+  if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
+    return MakeCursorObjCProtocolRef(PD, Loc, CXTU);
+  
+  //assert(0 && "not yet");
+  return clang_getNullCursor();
+}

Added: cfe/trunk/tools/libclang/IndexingContext.h
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/IndexingContext
.h?rev=142233&view=auto
============================================================================
==
--- cfe/trunk/tools/libclang/IndexingContext.h (added)
+++ cfe/trunk/tools/libclang/IndexingContext.h Mon Oct 17 14:48:19 2011
@@ -0,0 +1,204 @@
+//===- IndexingContext.h - Higher level API functions
------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------
===//
+
+#include "Index_Internal.h"
+#include "CXCursor.h"
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclGroup.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace clang {
+  class FileEntry;
+  class ObjCPropertyDecl;
+
+namespace cxindex {
+  class IndexingContext;
+
+class IndexingContext {
+  ASTContext *Ctx;
+  CXClientData ClientData;
+  IndexerCallbacks &CB;
+  unsigned IndexOptions;
+  CXTranslationUnit CXTU;
+  
+  typedef llvm::DenseMap<const FileEntry *, CXIdxFile> FileMapTy;
+  typedef llvm::DenseMap<const NamedDecl *, CXIdxEntity> EntityMapTy;
+  typedef llvm::DenseMap<const void *, CXIdxMacro> MacroMapTy;
+  typedef llvm::DenseMap<const DeclContext *, CXIdxContainer>
ContainerMapTy;
+  FileMapTy FileMap;
+  EntityMapTy EntityMap;
+  MacroMapTy MacroMap;
+  ContainerMapTy ContainerMap;
+
+  SmallVector<DeclGroupRef, 8> TUDeclsInObjCContainer;
+  
+  llvm::SmallString<256> StrScratch;
+
+  class StrAdapter {
+    llvm::SmallString<256> &Scratch;
+
+  public:
+    StrAdapter(IndexingContext *indexCtx)
+      : Scratch(indexCtx->StrScratch) {}
+    ~StrAdapter() { Scratch.clear(); }
+
+    const char *toCStr(StringRef Str);
+
+    unsigned getCurSize() const { return Scratch.size(); }
+
+    const char *getCStr(unsigned CharIndex) {
+      Scratch.push_back('\0');
+      return Scratch.data() + CharIndex;
+    }
+
+    SmallVectorImpl<char> &getBuffer() { return Scratch; }
+  };
+
+public:
+  IndexingContext(CXClientData clientData, IndexerCallbacks
&indexCallbacks,
+                  unsigned indexOptions, CXTranslationUnit cxTU)
+    : Ctx(0), ClientData(clientData), CB(indexCallbacks),
+      IndexOptions(indexOptions), CXTU(cxTU) { }
+
+  ASTContext &getASTContext() const { return *Ctx; }
+
+  void setASTContext(ASTContext &ctx);
+
+  void ppIncludedFile(SourceLocation hashLoc,
+                      StringRef filename, const FileEntry *File,
+                      bool isImport, bool isAngled);
+
+  void ppMacroDefined(SourceLocation Loc, StringRef Name,
+                      SourceLocation DefBegin, unsigned Length,
+                      const void *OpaqueMacro);
+
+  void ppMacroUndefined(SourceLocation Loc, StringRef Name,
+                        const void *OpaqueMacro);
+
+  void ppMacroExpanded(SourceLocation Loc, StringRef Name,
+                       const void *OpaqueMacro);
+
+  void invokeStartedTranslationUnit();
+
+  void invokeFinishedTranslationUnit();
+
+  void indexDecl(const Decl *D);
+
+  void indexTagDecl(const TagDecl *D);
+
+  void indexTypeSourceInfo(TypeSourceInfo *TInfo, const NamedDecl *Parent,
+                           const DeclContext *DC = 0);
+
+  void indexTypeLoc(TypeLoc TL, const NamedDecl *Parent,
+                           const DeclContext *DC);
+
+  void indexDeclContext(const DeclContext *DC);
+  
+  void indexBody(const Stmt *S, const DeclContext *DC);
+
+  void handleDiagnostic(const StoredDiagnostic &StoredDiag);
+
+  void handleFunction(const FunctionDecl *FD);
+
+  void handleVar(const VarDecl *D);
+
+  void handleField(const FieldDecl *D);
+
+  void handleEnumerator(const EnumConstantDecl *D);
+
+  void handleTagDecl(const TagDecl *D);
+  
+  void handleTypedef(const TypedefDecl *D);
+
+  void handleObjCInterface(const ObjCInterfaceDecl *D);
+  
+  void defineObjCInterface(const ObjCInterfaceDecl *D);
+
+  void handleObjCProtocol(const ObjCProtocolDecl *D);
+
+  void handleObjCCategory(const ObjCCategoryDecl *D);
+
+  void handleObjCMethod(const ObjCMethodDecl *D);
+
+  void handleObjCProperty(const ObjCPropertyDecl *D);
+
+  void handleReference(const NamedDecl *D, SourceLocation Loc,
+                       const NamedDecl *Parent,
+                       const DeclContext *DC,
+                       const Expr *E = 0);
+  
+  void invokeStartedTagTypeDefinition(const TagDecl *D);
+
+  void invokeStartedStatementBody(const NamedDecl *D, const DeclContext
*DC);
+  
+  void invokeStartedObjCContainer(const ObjCContainerDecl *D);
+
+  void invokeEndedContainer(const DeclContext *DC);
+
+  bool isNotFromSourceFile(SourceLocation Loc) const;
+
+  void indexTUDeclsInObjCContainer();
+  void indexDeclGroupRef(DeclGroupRef DG);
+
+  void addTUDeclInObjCContainer(DeclGroupRef DG) {
+    TUDeclsInObjCContainer.push_back(DG);
+  }
+
+  void translateLoc(SourceLocation Loc, CXIdxFile *indexFile, CXFile *file,
+                    unsigned *line, unsigned *column, unsigned *offset);
+
+private:
+  void addEntityInMap(const NamedDecl *D, CXIdxEntity entity);
+
+  void addContainerInMap(const DeclContext *DC, CXIdxContainer container);
+
+  CXIdxEntity getIndexEntity(const NamedDecl *D);
+
+  const NamedDecl *getEntityDecl(const NamedDecl *D) const;
+
+  CXIdxContainer getIndexContainer(const NamedDecl *D) const {
+    return getIndexContainerForDC(D->getDeclContext());
+  }
+
+  const DeclContext *getScopedContext(const DeclContext *DC) const;
+  CXIdxContainer getIndexContainerForDC(const DeclContext *DC) const;
+
+  CXIdxFile getIndexFile(const FileEntry *File);
+  
+  CXIdxLoc getIndexLoc(SourceLocation Loc) const;
+
+  void getIndexedEntityInfo(const NamedDecl *D,
+                            CXIdxIndexedEntityInfo &IdxEntityInfo,
+                            CXIdxEntityInfo &EntityInfo,
+                            CXIdxIndexedDeclInfo &IdxDeclInfo,
+                            StrAdapter &SA);
+
+  void getIndexedDeclInfo(const NamedDecl *D,
+                          CXIdxIndexedDeclInfo &IdxDeclInfo);
+
+  void getIndexedRedeclInfo(const NamedDecl *D,
+                            CXIdxIndexedRedeclInfo &RedeclInfo,
+                            CXIdxIndexedDeclInfo &IdxDeclInfo);
+
+  void getContainerInfo(const NamedDecl *D,
+                        CXIdxContainerInfo &ContainerInfo);
+
+  void getEntityInfo(const NamedDecl *D,
+                     CXIdxEntityInfo &EntityInfo,
+                     StrAdapter &SA);
+
+  CXCursor getCursor(const NamedDecl *D) {
+    return cxcursor::MakeCXCursor(const_cast<NamedDecl*>(D), CXTU);
+  }
+
+  CXCursor getRefCursor(const NamedDecl *D, SourceLocation Loc);
+};
+
+}} // end clang::cxindex

Modified: cfe/trunk/tools/libclang/libclang.exports
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.export
s?rev=142233&r1=142232&r2=142233&view=diff
============================================================================
==
--- cfe/trunk/tools/libclang/libclang.exports (original)
+++ cfe/trunk/tools/libclang/libclang.exports Mon Oct 17 14:48:19 2011
@@ -129,6 +129,9 @@
 clang_getTypeDeclaration
 clang_getTypeKindSpelling
 clang_hashCursor
+clang_indexLoc_getCXSourceLocation
+clang_indexLoc_getFileLocation
+clang_indexTranslationUnit
 clang_isAttribute
 clang_isConstQualifiedType
 clang_isCursorDefinition


_______________________________________________
cfe-commits mailing list
cfe-commits at cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits








More information about the cfe-commits mailing list