diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-10-17 19:48:19 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-10-17 19:48:19 +0000 |
commit | 4e7064fa7e344e8f87a5b8457e96dfdd252c4a9e (patch) | |
tree | db3fd8ec700eccc7b796986919ef8a4f88eb6696 /tools | |
parent | b4a686df4de21ec4eeca69211b21f7fe716abeae (diff) |
[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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142233 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools')
-rw-r--r-- | tools/c-index-test/c-index-test.c | 501 | ||||
-rw-r--r-- | tools/libclang/CIndex.cpp | 5 | ||||
-rw-r--r-- | tools/libclang/CIndexUSRs.cpp | 4 | ||||
-rw-r--r-- | tools/libclang/CMakeLists.txt | 5 | ||||
-rw-r--r-- | tools/libclang/CXCursor.cpp | 14 | ||||
-rw-r--r-- | tools/libclang/CXCursor.h | 10 | ||||
-rw-r--r-- | tools/libclang/CXTranslationUnit.h | 17 | ||||
-rw-r--r-- | tools/libclang/IndexBody.cpp | 72 | ||||
-rw-r--r-- | tools/libclang/IndexDecl.cpp | 218 | ||||
-rw-r--r-- | tools/libclang/IndexTypeSourceInfo.cpp | 94 | ||||
-rw-r--r-- | tools/libclang/Indexing.cpp | 479 | ||||
-rw-r--r-- | tools/libclang/IndexingContext.cpp | 695 | ||||
-rw-r--r-- | tools/libclang/IndexingContext.h | 204 | ||||
-rw-r--r-- | tools/libclang/libclang.exports | 3 |
14 files changed, 2308 insertions, 13 deletions
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index 2a3584b892..97c78dbeb0 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -1480,6 +1480,504 @@ static int find_file_refs_at(int argc, const char **argv) { 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 @@ static void print_usage(void) { " 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 @@ int cindextest_main(int argc, const char **argv) { 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) diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index bb232eb567..46f8965902 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -62,6 +62,11 @@ CXTranslationUnit cxtu::MakeCXTranslationUnit(ASTUnit *TU) { 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. diff --git a/tools/libclang/CIndexUSRs.cpp b/tools/libclang/CIndexUSRs.cpp index 91ceb7c78b..195463cbe2 100644 --- a/tools/libclang/CIndexUSRs.cpp +++ b/tools/libclang/CIndexUSRs.cpp @@ -790,7 +790,7 @@ static inline StringRef extractUSRSuffix(StringRef s) { 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 @@ bool cxcursor::getDeclCursorUSR(Decl *D, SmallVectorImpl<char> &Buf) { { USRGenerator UG(&D->getASTContext(), &Buf); - UG->Visit(D); + UG->Visit((Decl*)D); if (UG->ignoreResults()) return true; diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt index f754e980b9..00b4692ebc 100644 --- a/tools/libclang/CMakeLists.txt +++ b/tools/libclang/CMakeLists.txt @@ -28,6 +28,11 @@ set(SOURCES CXCursor.cpp CXString.cpp CXType.cpp + IndexBody.cpp + IndexDecl.cpp + IndexTypeSourceInfo.cpp + Indexing.cpp + IndexingContext.cpp ../../include/clang-c/Index.h ) diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp index db27500143..586d9beba3 100644 --- a/tools/libclang/CXCursor.cpp +++ b/tools/libclang/CXCursor.cpp @@ -468,12 +468,12 @@ cxcursor::getCursorObjCSuperClassRef(CXCursor C) { 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 @@ cxcursor::getCursorObjCProtocolRef(CXCursor C) { 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 @@ CXCursor cxcursor::MakeCursorObjCClassRef(ObjCInterfaceDecl *Class, 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 @@ cxcursor::getCursorObjCClassRef(CXCursor C) { 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; } diff --git a/tools/libclang/CXCursor.h b/tools/libclang/CXCursor.h index e402d7f970..8209cf4948 100644 --- a/tools/libclang/CXCursor.h +++ b/tools/libclang/CXCursor.h @@ -67,7 +67,8 @@ std::pair<ObjCInterfaceDecl *, SourceLocation> 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 @@ std::pair<ObjCProtocolDecl *, SourceLocation> 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 @@ std::pair<ObjCInterfaceDecl *, SourceLocation> 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 @@ CXCursor getTypeRefCursor(CXCursor cursor); /// \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); diff --git a/tools/libclang/CXTranslationUnit.h b/tools/libclang/CXTranslationUnit.h index 2b8f977539..47d7146116 100644 --- a/tools/libclang/CXTranslationUnit.h +++ b/tools/libclang/CXTranslationUnit.h @@ -28,6 +28,23 @@ namespace cxtu { 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 diff --git a/tools/libclang/IndexBody.cpp b/tools/libclang/IndexBody.cpp new file mode 100644 index 0000000000..e02a4fa81a --- /dev/null +++ b/tools/libclang/IndexBody.cpp @@ -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)); +} diff --git a/tools/libclang/IndexDecl.cpp b/tools/libclang/IndexDecl.cpp new file mode 100644 index 0000000000..5cf9f80263 --- /dev/null +++ b/tools/libclang/IndexDecl.cpp @@ -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(ObjCImple |