[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