void ClangIndexer::inclusionVisitor(CXFile includedFile, CXSourceLocation *includeStack, unsigned includeLen, CXClientData userData) { ClangIndexer *indexer = static_cast<ClangIndexer*>(userData); const Location l = indexer->createLocation(includedFile, 1, 1); const uint32_t fileId = l.fileId(); if (!includeLen) { indexer->mData->dependencies[fileId].insert(fileId); } else { for (unsigned i=0; i<includeLen; ++i) { CXFile originatingFile; clang_getSpellingLocation(includeStack[i], &originatingFile, 0, 0, 0); const Location loc = indexer->createLocation(originatingFile, 1, 1); const uint32_t f = loc.fileId(); if (f) indexer->mData->dependencies[fileId].insert(f); } } }
CXChildVisitResult ClangIndexer::indexVisitor(CXCursor cursor, CXCursor parent, CXClientData data) { ClangIndexer *indexer = static_cast<ClangIndexer*>(data); // error() << "indexVisitor" << cursor; // FILE *f = fopen("/tmp/clangindex.log", "a"); // String str; // Log(&str) << cursor; // fwrite(str.constData(), 1, str.size(), f); // fwrite("\n", 1, 1, f); // fclose(f); const LastCursorUpdater updater(indexer->mLastCursor, cursor); const CXCursorKind kind = clang_getCursorKind(cursor); const RTags::CursorType type = RTags::cursorType(kind); if (type == RTags::Other) return CXChildVisit_Recurse; bool blocked = false; Location loc = indexer->createLocation(cursor, &blocked); if (blocked) { // error() << "blocked" << cursor; ++indexer->mBlocked; return CXChildVisit_Continue; } else if (loc.isNull()) { // error() << "Got null" << cursor; return CXChildVisit_Recurse; } ++indexer->mAllowed; if (indexer->mLogFile) { String out; Log(&out) << cursor; fwrite(out.constData(), 1, out.size(), indexer->mLogFile); fwrite("\n", 1, 1, indexer->mLogFile); } if (testLog(VerboseDebug)) { Log log(VerboseDebug); log << cursor; CXCursor ref = clang_getCursorReferenced(cursor); if (!clang_isInvalid(clang_getCursorKind(ref)) && !clang_equalCursors(ref, cursor)) { log << "refs" << ref; } } switch (type) { case RTags::Cursor: indexer->handleCursor(cursor, kind, loc); break; case RTags::Include: indexer->handleInclude(cursor, kind, loc); break; case RTags::Reference: switch (kind) { case CXCursor_OverloadedDeclRef: { const int count = clang_getNumOverloadedDecls(cursor); for (int i=0; i<count; ++i) { const CXCursor ref = clang_getOverloadedDecl(cursor, i); indexer->handleReference(cursor, kind, loc, ref, parent); } break; } case CXCursor_CXXDeleteExpr: indexer->handleReference(cursor, kind, loc, findDestructorForDelete(cursor), parent); break; case CXCursor_CallExpr: { // uglehack, see rtags/tests/nestedClassConstructorCallUgleHack/ const CXCursor ref = clang_getCursorReferenced(cursor); if (clang_getCursorKind(ref) == CXCursor_Constructor && clang_getCursorKind(indexer->mLastCursor) == CXCursor_TypeRef && clang_getCursorKind(parent) != CXCursor_VarDecl) { loc = indexer->createLocation(indexer->mLastCursor); indexer->handleReference(indexer->mLastCursor, kind, loc, ref, parent); } else { indexer->handleReference(cursor, kind, loc, ref, parent); } break; } default: indexer->handleReference(cursor, kind, loc, clang_getCursorReferenced(cursor), parent); break; } break; case RTags::Other: assert(0); break; } return CXChildVisit_Recurse; }