[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

Argyrios Kyrtzidis kyrtzidis at apple.com
Thu Oct 20 10:24:54 PDT 2011


On Oct 20, 2011, at 12:40 AM, James Molloy wrote:

> 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?

Sorry about that, fixed in r142590.

> 
> 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