void DumpThread::run() { const auto key = mConnection->disconnected().connect([this](const std::shared_ptr<Connection> &) { abort(); }); CXIndex index = clang_createIndex(0, 0); CXTranslationUnit translationUnit = 0; String clangLine; RTags::parseTranslationUnit(mSource.sourceFile(), mSource.toCommandLine(Source::Default), translationUnit, index, 0, 0, CXTranslationUnit_DetailedPreprocessingRecord, &clangLine); if (!(mQueryFlags & QueryMessage::DumpCheckIncludes)) writeToConnetion(String::format<128>("Indexed: %s => %s", clangLine.constData(), translationUnit ? "success" : "failure")); if (translationUnit) { clang_visitChildren(clang_getTranslationUnitCursor(translationUnit), DumpThread::visitor, this); clang_disposeTranslationUnit(translationUnit); } clang_disposeIndex(index); mConnection->disconnected().disconnect(key); std::weak_ptr<Connection> conn = mConnection; if (mQueryFlags & QueryMessage::DumpCheckIncludes) { checkIncludes(); } EventLoop::mainEventLoop()->callLater([conn]() { if (auto c = conn.lock()) c->finish(); }); }
void DumpThread::checkIncludes() { for (const auto &it : mDependencies) { const Path path = Location::path(it.first); if (path.isSystem()) continue; for (const auto &dep : it.second->includes) { Set<uint32_t> seen; if (!validateNeedsInclude(it.second, static_cast<Dep*>(dep.second), seen)) { writeToConnetion(String::format<128>("%s includes %s for no reason", path.constData(), Location::path(dep.second->fileId).constData())); } } for (const auto &ref : it.second->references) { const Path refPath = Location::path(ref.first); if (refPath.startsWith("/usr/include/sys/_types/_") || refPath.startsWith("/usr/include/_types/_")) continue; Set<uint32_t> seen; if (!validateHasInclude(ref.first, it.second, seen)) { List<String> reasons; for (const auto &r : ref.second) { String reason; Log log(&reason); log << r.first << "=>" << r.second; reasons << reason; } writeToConnetion(String::format<128>("%s should include %s (%s)", Location::path(it.first).constData(), Location::path(ref.first).constData(), String::join(reasons, " ").constData())); // for (const auto &incs : mDependencies[ref.first]->dependents) { // writeToConnetion(String::format<128>("GOT INCLUDER %s:%d", Location::path(incs.first).constData(), // incs.first)); // } } } } for (auto it : mDependencies) { delete it.second; } }
void DumpThread::run() { CXIndex index = clang_createIndex(0, 0); CXTranslationUnit translationUnit = 0; String clangLine; RTags::parseTranslationUnit(mSource.sourceFile(), mSource.toCommandLine(Source::Default), translationUnit, index, 0, 0, CXTranslationUnit_DetailedPreprocessingRecord, &clangLine); writeToConnetion(String::format<128>("Indexed: %s => %s", clangLine.constData(), translationUnit ? "success" : "failure")); if (translationUnit) { clang_visitChildren(clang_getTranslationUnitCursor(translationUnit), DumpThread::visitor, this); clang_disposeTranslationUnit(translationUnit); } clang_disposeIndex(index); EventLoop::mainEventLoop()->callLaterMove(std::bind((bool(Connection::*)(Message&&))&Connection::send, mConnection, std::placeholders::_1), FinishMessage()); }
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; }