CXChildVisitResult DumpThread::visitor(CXCursor cursor, CXCursor, CXClientData userData) { DumpThread *that = reinterpret_cast<DumpThread*>(userData); assert(that); CXSourceLocation location = clang_getCursorLocation(cursor); if (!clang_equalLocations(location, nullLocation)) { CXString file; unsigned line, col; clang_getPresumedLocation(location, &file, &line, &col); Path path = RTags::eatString(file); if (!path.isEmpty()) { uint32_t &fileId = that->mFiles[path]; if (!fileId) { const Path resolved = path.resolved(); fileId = Location::insertFile(resolved); that->mFiles[path] = that->mFiles[resolved] = fileId; } if (that->mQueryFlags & QueryMessage::DumpIncludeHeaders || fileId == that->mSource.fileId) { const Location loc(fileId, line, col); String message; message.reserve(256); if (!(that->mQueryFlags & QueryMessage::NoContext)) message += loc.context(); CXSourceRange range = clang_getCursorExtent(cursor); CXSourceLocation rangeEnd = clang_getRangeEnd(range); unsigned endLine, endColumn; clang_getPresumedLocation(rangeEnd, 0, &endLine, &endColumn); if (endLine == line) { message += String::format<32>(" // %d-%d, %d: ", col, endColumn, that->mIndentLevel); } else { message += String::format<32>(" // %d-%d:%d, %d: ", col, endLine, endColumn, that->mIndentLevel); } message += RTags::cursorToString(cursor, RTags::AllCursorToStringFlags); message.append(" " + RTags::typeName(cursor) + " "); CXCursor ref = clang_getCursorReferenced(cursor); if (clang_equalCursors(ref, cursor)) { message.append("refs self"); } else if (!clang_equalCursors(ref, nullCursor)) { message.append("refs "); message.append(RTags::cursorToString(ref, RTags::AllCursorToStringFlags)); } CXCursor canonical = clang_getCanonicalCursor(cursor); if (!clang_equalCursors(canonical, cursor) && !clang_equalCursors(canonical, nullCursor)) { message.append("canonical "); message.append(RTags::cursorToString(canonical, RTags::AllCursorToStringFlags)); } that->writeToConnetion(message); } } } ++that->mIndentLevel; clang_visitChildren(cursor, DumpThread::visitor, userData); --that->mIndentLevel; return CXChildVisit_Continue; }
void DumpThread::checkIncludes(const Location &location, const CXCursor &cursor) { if (clang_getCursorKind(cursor) == CXCursor_InclusionDirective) { handleInclude(location, cursor); } else { const CXCursor ref = clang_getCursorReferenced(cursor); if (!clang_equalCursors(cursor, nullCursor) && !clang_equalCursors(cursor, ref)) { handleReference(location, ref); } } }
virtual enum CXChildVisitResult visit(CXCursor cursor, CXCursor parent) { CXFile file; unsigned int line, column, offset; clang_getInstantiationLocation( clang_getCursorLocation(cursor), &file, &line, &column, &offset); CXCursorKind kind = clang_getCursorKind(cursor); const char* cursorFilename = clang_getCString(clang_getFileName(file)); if (!clang_getFileName(file).data || strcmp(cursorFilename, translationUnitFilename) != 0) { return CXChildVisit_Continue; } CXCursor refCursor = clang_getCursorReferenced(cursor); if (!clang_equalCursors(refCursor, clang_getNullCursor())) { CXFile refFile; unsigned int refLine, refColumn, refOffset; clang_getInstantiationLocation( clang_getCursorLocation(refCursor), &refFile, &refLine, &refColumn, &refOffset); if (clang_getFileName(refFile).data) { std::string referencedUsr(clang_getCString(clang_getCursorUSR(refCursor))); if (!referencedUsr.empty()) { std::stringstream ss; ss << cursorFilename << ":" << line << ":" << column << ":" << kind; std::string location(ss.str()); usrToReferences[referencedUsr].insert(location); } } } return CXChildVisit_Recurse; }
static void PrintCursor(CXCursor Cursor) { if (clang_isInvalid(Cursor.kind)) { CXString ks = clang_getCursorKindSpelling(Cursor.kind); printf("Invalid Cursor => %s", clang_getCString(ks)); clang_disposeString(ks); } else { CXString string, ks; CXCursor Referenced; unsigned line, column; ks = clang_getCursorKindSpelling(Cursor.kind); string = clang_getCursorSpelling(Cursor); printf("%s=%s", clang_getCString(ks), clang_getCString(string)); clang_disposeString(ks); clang_disposeString(string); Referenced = clang_getCursorReferenced(Cursor); if (!clang_equalCursors(Referenced, clang_getNullCursor())) { CXSourceLocation Loc = clang_getCursorLocation(Referenced); clang_getInstantiationLocation(Loc, 0, &line, &column, 0); printf(":%d:%d", line, column); } if (clang_isCursorDefinition(Cursor)) printf(" (Definition)"); } }
void ClangParser::linkIdentifier(CodeOutputInterface &ol,FileDef *fd, uint &line,uint &column,const char *text,int tokenIndex) { CXCursor c = p->cursors[tokenIndex]; CXCursor r = clang_getCursorReferenced(c); if (!clang_equalCursors(r, c)) { c=r; // link to referenced location } CXCursor t = clang_getSpecializedCursorTemplate(c); if (!clang_Cursor_isNull(t) && !clang_equalCursors(t,c)) { c=t; // link to template } CXString usr = clang_getCursorUSR(c); const char *usrStr = clang_getCString(usr); Definition *d = usrStr ? Doxygen::clangUsrMap->find(usrStr) : 0; //CXCursorKind kind = clang_getCursorKind(c); //if (d==0) //{ // printf("didn't find definition for '%s' usr='******' kind=%d\n", // text,usrStr,kind); //} //else //{ // printf("found definition for '%s' usr='******' name='%s'\n", // text,usrStr,d->name().data()); //} if (d && d->isLinkable()) { if (g_insideBody && g_currentMemberDef && d->definitionType()==Definition::TypeMember && (g_currentMemberDef!=d || g_currentLine<line)) // avoid self-reference { addDocCrossReference(g_currentMemberDef,(MemberDef*)d); } writeMultiLineCodeLink(ol,fd,line,column,d,text); } else { codifyLines(ol,fd,text,line,column); } clang_disposeString(usr); }
std::ostream& operator<<( std::ostream &os, CXCursor cursor ) { auto spelling = clang_getCursorKindSpelling( cursor.kind ); auto morespell = clang_getCursorSpelling( cursor ); os << clang_getCString( spelling ) << ":" << clang_getCString( morespell ) << " "; clang_disposeString( spelling ); clang_disposeString( morespell ); auto refcursor = clang_getCursorReferenced( cursor ); if ( clang_equalCursors( refcursor, clang_getNullCursor() )|| clang_equalCursors( refcursor, cursor ) ) return os; return os << " [ " << refcursor << " ] "; }
void ClangParser::linkIdentifier(CodeOutputInterface &ol, QSharedPointer<FileDef> fd, uint &line, uint &column, const QString &text, int tokenIndex) { CXCursor c = p->cursors[tokenIndex]; CXCursor r = clang_getCursorReferenced(c); if (! clang_equalCursors(r, c)) { // link to referenced location c = r; } CXCursor t = clang_getSpecializedCursorTemplate(c); if (! clang_Cursor_isNull(t) && !clang_equalCursors(t, c)) { // link to template c = t; } CXString usr = clang_getCursorUSR(c); const char *usrStr = clang_getCString(usr); QSharedPointer<Definition> d; if (usrStr) { d = Doxy_Globals::clangUsrMap.value(usrStr); } if (d && d->isLinkable()) { if (g_insideBody && g_currentMemberDef && d->definitionType() == Definition::TypeMember && (g_currentMemberDef != d || g_currentLine < line)) { // avoid self-reference addDocCrossReference(g_currentMemberDef, d.dynamicCast<MemberDef>()); } writeMultiLineCodeLink(ol, fd, line, column, d, text); } else { codifyLines(ol, fd, text, line, column, ""); } clang_disposeString(usr); }
static int perform_file_scan(const char *ast_file, const char *source_file, const char *prefix) { CXIndex Idx; CXTranslationUnit TU; FILE *fp; CXCursor prevCursor = clang_getNullCursor(); CXFile file; unsigned line = 1, col = 1; unsigned start_line = 1, start_col = 1; if (!(Idx = clang_createIndex(/* excludeDeclsFromPCH */ 1, /* displayDiagnosics=*/1))) { fprintf(stderr, "Could not create Index\n"); return 1; } if (!CreateTranslationUnit(Idx, ast_file, &TU)) return 1; if ((fp = fopen(source_file, "r")) == NULL) { fprintf(stderr, "Could not open '%s'\n", source_file); return 1; } file = clang_getFile(TU, source_file); for (;;) { CXCursor cursor; int c = fgetc(fp); if (c == '\n') { ++line; col = 1; } else ++col; /* Check the cursor at this position, and dump the previous one if we have * found something new. */ cursor = clang_getCursor(TU, clang_getLocation(TU, file, line, col)); if ((c == EOF || !clang_equalCursors(cursor, prevCursor)) && prevCursor.kind != CXCursor_InvalidFile) { print_cursor_file_scan(prevCursor, start_line, start_col, line, col, prefix); start_line = line; start_col = col; } if (c == EOF) break; prevCursor = cursor; } fclose(fp); return 0; }
MetadataClass::Ptr MetadataModule::FindUnspecializedTemplateClassByCursor(CXCursor cursor) { for (auto& ptr : Classes) { if (ptr->IsTemplated && !ptr->IsTemplateInstance && clang_equalCursors(ptr->ClangCursor, cursor)) { return ptr; } } return nullptr; }
MetadataClass::Ptr MetadataModule::FindClassByCursor(CXCursor cursor) { for (auto& ptr : Classes) { if (clang_equalCursors(ptr->ClangCursor, cursor)) { return ptr; } } return nullptr; }
SEXP R_clang_equalCursors(SEXP r_arg1, SEXP r_arg2) { SEXP r_ans = R_NilValue; CXCursor arg1 = * GET_REF(r_arg1, CXCursor); CXCursor arg2 = * GET_REF(r_arg2, CXCursor); unsigned int ans; ans = clang_equalCursors(arg1, arg2); r_ans = ScalarReal(ans) ; return(r_ans); }
CXChildVisitResult IndexerJob::verboseVisitor(CXCursor cursor, CXCursor, CXClientData userData) { VerboseVisitorUserData *u = reinterpret_cast<VerboseVisitorUserData*>(userData); Location loc = u->job->createLocation(cursor); if (loc.fileId()) { CXCursor ref = clang_getCursorReferenced(cursor); VerboseVisitorUserData *u = reinterpret_cast<VerboseVisitorUserData*>(userData); if (u->indent >= 0) u->out += String(u->indent, ' '); u->out += RTags::cursorToString(cursor); if (clang_equalCursors(ref, cursor)) { u->out += " refs self"; } else if (!clang_equalCursors(ref, nullCursor)) { u->out += " refs " + RTags::cursorToString(ref); } if (loc.fileId() && u->job->mVisitedFiles.contains(loc.fileId())) { if (u->job->mData->references.contains(loc)) { u->out += " used as reference\n"; } else if (u->job->mData->symbols.contains(loc)) { u->out += " used as cursor\n"; } else { u->out += " not used\n"; } } else { u->out += " not indexed\n"; } } if (u->indent >= 0) { u->indent += 2; clang_visitChildren(cursor, IndexerJob::verboseVisitor, userData); u->indent -= 2; return CXChildVisit_Continue; } else { return CXChildVisit_Recurse; } }
CXChildVisitResult IndexerJob::dumpVisitor(CXCursor cursor, CXCursor, CXClientData userData) { DumpUserData *dump = reinterpret_cast<DumpUserData*>(userData); assert(dump); assert(dump->job); Location loc = dump->job->createLocation(cursor); if (loc.fileId()) { CXCursor ref = clang_getCursorReferenced(cursor); String out; out.reserve(256); int col = -1; if (dump->showContext) { out.append(loc.context(&col)); if (col != -1) { out.append(String::format<32>(" // %d, %d: ", col, dump->indentLevel)); } else { out.append(String::format<32>(" // %d: ", dump->indentLevel)); } } else { out.append(String(dump->indentLevel * 2, ' ')); } out.append(RTags::cursorToString(cursor, RTags::AllCursorToStringFlags)); out.append(" " + typeName(cursor) + " "); if (clang_equalCursors(ref, cursor)) { out.append("refs self"); } else if (!clang_equalCursors(ref, nullCursor)) { out.append("refs "); out.append(RTags::cursorToString(ref, RTags::AllCursorToStringFlags)); } dump->job->write(out); } ++dump->indentLevel; clang_visitChildren(cursor, IndexerJob::dumpVisitor, userData); --dump->indentLevel; return CXChildVisit_Continue; }
CXCursor ClangIndexer::resolveAutoTypeRef(const CXCursor &cursor) const { assert(clang_getCursorKind(cursor) == CXCursor_VarDecl); ResolveAutoTypeRefUserData userData = { nullCursor, 0 }; clang_visitChildren(cursor, resolveAutoTypeRefVisitor, &userData); if (userData.index > 1) { if (!clang_equalCursors(userData.ref, nullCursor)) { // error() << "Fixed cursor for" << cursor << userData.ref; // << userData.chain; return userData.ref; // } else { // error() << "Couldn't fix cursor for" << cursor << userData.ref; // // << userData.chain; } } // error() << "Need to find type for" << cursor << child; return nullCursor; }
static CXChildVisitResult resolveAutoTypeRefVisitor(CXCursor cursor, CXCursor, CXClientData data) { ResolveAutoTypeRefUserData *userData = reinterpret_cast<ResolveAutoTypeRefUserData*>(data); const CXCursorKind kind = clang_getCursorKind(cursor); // userData->chain.append(kind); // error() << "Got here" << cursor << userData->chain; ++userData->index; switch (kind) { case CXCursor_TypeRef: case CXCursor_TemplateRef: // error() << "Found typeRef" << cursor; userData->ref = cursor; return CXChildVisit_Break; case CXCursor_UnexposedExpr: { CXCursor ref = clang_getCursorReferenced(cursor); // error() << "got unexposed expr ref" << ref; switch (clang_getCursorKind(ref)) { case CXCursor_VarDecl: case CXCursor_FunctionDecl: case CXCursor_CXXMethod: { ResolveAutoTypeRefUserData u = { nullCursor, 0 }; clang_visitChildren(ref, resolveAutoTypeRefVisitor, &u); // error() << "Visited for typeRef" << u.ref // << clang_isInvalid(clang_getCursorKind(u.ref)) // << u.chain; if (!clang_equalCursors(u.ref, nullCursor)) { userData->ref = u.ref; return CXChildVisit_Break; } break; } default: break; } break; } case CXCursor_ParmDecl: // nothing to find here return CXChildVisit_Break; default: break; } return CXChildVisit_Recurse; }
static enum CXChildVisitResult visit(CXCursor cursor, CXCursor parent, CXClientData userData) { (void)parent; int indent = *(int*)userData; int i; for (i=0; i<indent; ++i) { printf(" "); } printCursor(cursor); CXCursor ref = clang_getCursorReferenced(cursor); if (!clang_isInvalid(clang_getCursorKind(ref)) && !clang_equalCursors(ref, cursor)) { for (i=0; i<indent; ++i) { printf(" "); } printf("-> "); printCursor(ref); } ++indent; clang_visitChildren(cursor, visit, &indent); return CXChildVisit_Continue; }
bool operator==(const CXCursor& lhs, const CXCursor& rhs) { return clang_equalCursors(lhs, rhs) != 0; }
bool cursor::operator==(const cursor& o) const { return clang_equalCursors(cur, o.cur); }
bool QAnnotatedTokenSet::operator !=(const QAnnotatedTokenSet &other){ Q_D(QAnnotatedTokenSet); return !clang_equalCursors(d->cursor, other.cursor()); }
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; }
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_VarDecl: { const CXCursor typeRef = resolveAutoTypeRef(cursor); if (!clang_equalCursors(typeRef, nullCursor)) { // const CXSourceRange range = clang_Cursor_getSpellingNameRange(mLastCursor, 0, 0); // error() << "Found" << typeRef << "for" << cursor << mLastCursor // << createLocation(mLastCursor) // << clang_Range_isNull(range) // << createLocation(clang_getCursorLocation(mLastCursor)); auto info = handleReference(mLastCursor, clang_getCursorKind(mLastCursor), createLocation(clang_getCursorLocation(mLastCursor)), clang_getCursorReferenced(typeRef), nullCursor); if (info) { // the type is read from the cursor passed in and that won't // be correct in this case info->type = clang_getCursorType(typeRef).kind; info->symbolLength = 4; info->symbolName += " (auto)"; info->endLine = info->startLine; info->endColumn = info->startColumn + 4; } } break; } 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; }
static void PrintCursor(CXCursor Cursor) { if (clang_isInvalid(Cursor.kind)) { CXString ks = clang_getCursorKindSpelling(Cursor.kind); printf("Invalid Cursor => %s", clang_getCString(ks)); clang_disposeString(ks); } else { CXString string, ks; CXCursor Referenced; unsigned line, column; CXCursor SpecializationOf; ks = clang_getCursorKindSpelling(Cursor.kind); string = clang_getCursorSpelling(Cursor); printf("%s=%s", clang_getCString(ks), clang_getCString(string)); clang_disposeString(ks); clang_disposeString(string); Referenced = clang_getCursorReferenced(Cursor); if (!clang_equalCursors(Referenced, clang_getNullCursor())) { CXSourceLocation Loc = clang_getCursorLocation(Referenced); clang_getInstantiationLocation(Loc, 0, &line, &column, 0); printf(":%d:%d", line, column); } if (clang_isCursorDefinition(Cursor)) printf(" (Definition)"); switch (clang_getCursorAvailability(Cursor)) { case CXAvailability_Available: break; case CXAvailability_Deprecated: printf(" (deprecated)"); break; case CXAvailability_NotAvailable: printf(" (unavailable)"); break; } if (Cursor.kind == CXCursor_IBOutletCollectionAttr) { CXType T = clang_getCanonicalType(clang_getIBOutletCollectionType(Cursor)); CXString S = clang_getTypeKindSpelling(T.kind); printf(" [IBOutletCollection=%s]", clang_getCString(S)); clang_disposeString(S); } if (Cursor.kind == CXCursor_CXXBaseSpecifier) { enum CX_CXXAccessSpecifier access = clang_getCXXAccessSpecifier(Cursor); unsigned isVirtual = clang_isVirtualBase(Cursor); const char *accessStr = 0; switch (access) { case CX_CXXInvalidAccessSpecifier: accessStr = "invalid"; break; case CX_CXXPublic: accessStr = "public"; break; case CX_CXXProtected: accessStr = "protected"; break; case CX_CXXPrivate: accessStr = "private"; break; } printf(" [access=%s isVirtual=%s]", accessStr, isVirtual ? "true" : "false"); } SpecializationOf = clang_getSpecializedCursorTemplate(Cursor); if (!clang_equalCursors(SpecializationOf, clang_getNullCursor())) { CXSourceLocation Loc = clang_getCursorLocation(SpecializationOf); CXString Name = clang_getCursorSpelling(SpecializationOf); clang_getInstantiationLocation(Loc, 0, &line, &column, 0); printf(" [Specialization of %s:%d:%d]", clang_getCString(Name), line, column); clang_disposeString(Name); } } }
CXChildVisitResult IndexerJob::indexVisitor(CXCursor cursor, CXCursor parent, CXClientData data) { IndexerJob *job = static_cast<IndexerJob*>(data); { MutexLocker lock(&job->mMutex); if (job->mAborted) return CXChildVisit_Break; } const LastCursorUpdater updater(job->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 = job->createLocation(cursor, &blocked); if (blocked) { return CXChildVisit_Continue; } else if (loc.isNull()) { return CXChildVisit_Recurse; } 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: job->handleCursor(cursor, kind, loc); break; case RTags::Include: job->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); job->handleReference(cursor, kind, loc, ref, parent); } break; } case CXCursor_CXXDeleteExpr: job->handleReference(cursor, kind, loc, findDestructorForDelete(cursor), parent); break; default: job->handleReference(cursor, kind, loc, clang_getCursorReferenced(cursor), parent); break; } break; case RTags::Other: assert(0); break; } return CXChildVisit_Recurse; }
bool Cursor::operator==(const Cursor &other) const { return clang_equalCursors(m_cx_cursor, other.m_cx_cursor) == 0; }
CXChildVisitResult DumpThread::visit(const CXCursor &cursor) { if (isAborted()) return CXChildVisit_Break; const Location location = createLocation(cursor); if (!location.isNull()) { if (mQueryFlags & QueryMessage::DumpCheckIncludes) { checkIncludes(location, cursor); return CXChildVisit_Recurse; } else { Flags<Location::ToStringFlag> locationFlags; if (mQueryFlags & QueryMessage::NoColor) locationFlags |= Location::NoColor; CXSourceRange range = clang_getCursorExtent(cursor); CXSourceLocation rangeEnd = clang_getRangeEnd(range); unsigned int endLine, endColumn; clang_getPresumedLocation(rangeEnd, 0, &endLine, &endColumn); if (!(mQueryFlags & QueryMessage::DumpIncludeHeaders) && location.fileId() != mSource.fileId) { return CXChildVisit_Continue; } String message; message.reserve(256); if (!(mQueryFlags & QueryMessage::NoContext)) { message = location.context(locationFlags); } if (endLine == location.line()) { message += String::format<32>(" // %d-%d, %d: ", location.column(), endColumn, mIndentLevel); } else { message += String::format<32>(" // %d-%d:%d, %d: ", location.column(), endLine, endColumn, mIndentLevel); } message += RTags::cursorToString(cursor, RTags::AllCursorToStringFlags); message.append(" " + RTags::typeName(cursor));; if (clang_getCursorKind(cursor) == CXCursor_VarDecl) { const std::shared_ptr<RTags::Auto> autoResolved = RTags::resolveAuto(cursor); if (autoResolved && !clang_equalCursors(autoResolved->cursor, nullCursor)) { message += "auto resolves to " + RTags::cursorToString(autoResolved->cursor, RTags::AllCursorToStringFlags); } } CXCursor ref = clang_getCursorReferenced(cursor); if (clang_equalCursors(ref, cursor)) { message.append("refs self"); } else if (!clang_equalCursors(ref, nullCursor)) { message.append("refs "); message.append(RTags::cursorToString(ref, RTags::AllCursorToStringFlags)); } CXCursor canonical = clang_getCanonicalCursor(cursor); if (!clang_equalCursors(canonical, cursor) && !clang_equalCursors(canonical, nullCursor)) { message.append("canonical "); message.append(RTags::cursorToString(canonical, RTags::AllCursorToStringFlags)); } CXCursor specialized = clang_getSpecializedCursorTemplate(cursor); if (!clang_equalCursors(specialized, cursor) && !clang_equalCursors(specialized, nullCursor)) { message.append("specialized "); message.append(RTags::cursorToString(specialized, RTags::AllCursorToStringFlags)); } writeToConnetion(message); } } ++mIndentLevel; clang_visitChildren(cursor, DumpThread::visitor, this); if (isAborted()) return CXChildVisit_Break; --mIndentLevel; return CXChildVisit_Continue; }
bool operator==(const Cursor &first, const Cursor &second) { return clang_equalCursors(first.cxCursor, second.cxCursor); }