[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/CXTranslationUnit.h tools/libclang/IndexBody.cpp tools/libclang/IndexDecl.cpp tools/libclang/IndexTypeSourceInfo.cpp tools/libclang/Indexing.cpp tools/libclang/IndexingContext.cpp tools/libclang/IndexingContext.h tools/libclang/libclang.exports
Argyrios Kyrtzidis
akyrtzi at gmail.com
Mon Oct 17 12:48:19 PDT 2011
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=142233&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-test.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?rev=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/CXTranslationUnit.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?rev=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?rev=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/IndexTypeSourceInfo.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?rev=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.exports?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
More information about the cfe-commits
mailing list