bool IndexerJob::handleCursor(const CXCursor &cursor, CXCursorKind kind, const Location &location) { CursorInfo &info = mData->symbols[location]; if (!info.symbolLength || !RTags::isCursor(info.kind)) { CXStringScope name = clang_getCursorSpelling(cursor); const char *cstr = name.data(); info.symbolLength = cstr ? strlen(cstr) : 0; info.type = clang_getCursorType(cursor).kind; if (!info.symbolLength) { // this is for these constructs: // typedef struct { // int a; // } foobar; // // We end up not getting a spelling for the cursor switch (kind) { case CXCursor_ClassDecl: info.symbolLength = 5; info.symbolName = "class"; break; case CXCursor_UnionDecl: info.symbolLength = 5; info.symbolName = "union"; break; case CXCursor_StructDecl: info.symbolLength = 6; info.symbolName = "struct"; break; default: mData->symbols.remove(location); return false; } } else { info.symbolName = addNamePermutations(cursor, location); } CXSourceRange range = clang_getCursorExtent(cursor); unsigned start, end; clang_getSpellingLocation(clang_getRangeStart(range), 0, 0, 0, &start); clang_getSpellingLocation(clang_getRangeEnd(range), 0, 0, 0, &end); info.start = start; info.end = end; if (kind == CXCursor_EnumConstantDecl) { #if CLANG_VERSION_MINOR > 1 info.enumValue = clang_getEnumConstantDeclValue(cursor); #else info.definition = clang_isCursorDefinition(cursor); #endif } else{ info.definition = clang_isCursorDefinition(cursor); } info.kind = kind; const String usr = RTags::eatString(clang_getCursorUSR(cursor)); if (!usr.isEmpty()) mData->usrMap[usr].insert(location); switch (info.kind) { case CXCursor_Constructor: case CXCursor_Destructor: { Location parentLocation = createLocation(clang_getCursorSemanticParent(cursor)); // consider doing this for only declaration/inline definition since // declaration and definition should know of one another if (parentLocation.isValid()) { CursorInfo &parent = mData->symbols[parentLocation]; parent.references.insert(location); info.references.insert(parentLocation); } break; } case CXCursor_CXXMethod: { List<CursorInfo*> infos; infos.append(&info); addOverriddenCursors(cursor, location, infos); break; } default: break; } } return true; }
bool ClangIndexer::handleCursor(const CXCursor &cursor, CXCursorKind kind, const Location &location) { // error() << "Got a cursor" << cursor; std::shared_ptr<CursorInfo> &info = mData->symbols[location]; if (!info) info = std::make_shared<CursorInfo>(); if (!info->symbolLength) { // if (mLogFile) { // String out; // Log(&out) << cursor << a; // fwrite(out.constData(), 1, out.size(), mLogFile); // fwrite("\n", 1, 1, mLogFile); // } CXStringScope name = clang_getCursorSpelling(cursor); const char *cstr = name.data(); info->symbolLength = cstr ? strlen(cstr) : 0; info->type = clang_getCursorType(cursor).kind; if (!info->symbolLength) { // this is for these constructs: // typedef struct { // int a; // } foobar; // // We end up not getting a spelling for the cursor switch (kind) { case CXCursor_ClassDecl: info->symbolLength = 5; info->symbolName = "class"; break; case CXCursor_UnionDecl: info->symbolLength = 5; info->symbolName = "union"; break; case CXCursor_StructDecl: info->symbolLength = 6; info->symbolName = "struct"; break; default: mData->symbols.remove(location); return false; } } else { info->symbolName = addNamePermutations(cursor, location); } CXSourceRange range = clang_getCursorExtent(cursor); CXSourceLocation rangeStart = clang_getRangeStart(range); CXSourceLocation rangeEnd = clang_getRangeEnd(range); unsigned startLine, startColumn, endLine, endColumn; clang_getPresumedLocation(rangeStart, 0, &startLine, &startColumn); clang_getPresumedLocation(rangeEnd, 0, &endLine, &endColumn); info->startLine = startLine; info->startColumn = startColumn; info->endLine = endLine; info->endColumn = endColumn; if (kind == CXCursor_EnumConstantDecl) { #if CINDEX_VERSION_MINOR > 1 info->enumValue = clang_getEnumConstantDeclValue(cursor); #else info->definition = 1; #endif } else { info->definition = clang_isCursorDefinition(cursor); } info->kind = kind; // apparently some function decls will give a different usr for // their definition and their declaration. Using the canonical // cursor's usr allows us to join them. Check JSClassRelease in // JavaScriptCore for an example. const String usr = RTags::eatString(clang_getCursorUSR(clang_getCanonicalCursor(cursor))); if (!usr.isEmpty()) mData->usrMap[usr].insert(location); switch (info->kind) { case CXCursor_Constructor: case CXCursor_Destructor: { Location parentLocation = createLocation(clang_getCursorSemanticParent(cursor)); // consider doing this for only declaration/inline definition since // declaration and definition should know of one another if (parentLocation.isValid()) { std::shared_ptr<CursorInfo> &parent = mData->symbols[parentLocation]; if (!parent) parent = std::make_shared<CursorInfo>(); parent->references.insert(location); info->references.insert(parentLocation); } break; } case CXCursor_CXXMethod: { List<CursorInfo*> infos; infos.append(info.get()); addOverriddenCursors(cursor, location, infos); break; } default: break; } } return true; }