bool IndexerJob::visit(int build) { if (!mUnits.at(build).second) { abort(); return false; } clang_getInclusions(mUnits.at(build).second, IndexerJob::inclusionVisitor, this); if (isAborted()) return false; clang_visitChildren(clang_getTranslationUnitCursor(mUnits.at(build).second), IndexerJob::indexVisitor, this); if (isAborted()) return false; if (testLog(VerboseDebug)) { VerboseVisitorUserData u = { 0, "<VerboseVisitor " + mClangLines.at(build) + ">\n", this }; clang_visitChildren(clang_getTranslationUnitCursor(mUnits.at(build).second), IndexerJob::verboseVisitor, &u); u.out += "</VerboseVisitor " + mClangLines.at(build) + ">"; if (getenv("RTAGS_INDEXERJOB_DUMP_TO_FILE")) { char buf[1024]; snprintf(buf, sizeof(buf), "/tmp/%s.log", mSourceInformation.sourceFile.fileName()); FILE *f = fopen(buf, "w"); assert(f); fwrite(u.out.constData(), 1, u.out.size(), f); fclose(f); } else { logDirect(VerboseDebug, u.out); } } return !isAborted(); }
void getDescendants(CXCursor parent, CXCursor** childrenOut, unsigned* countOut) { CursorList childList = LIST_INIT(CXCursor); clang_visitChildren(parent, descendantListBuilder, &childList); *childrenOut = childList.items; *countOut = childList.count; }
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(); }); }
static CXChildVisitResult visitClass(CXCursor cursor, CXCursor /*parent*/, CXClientData client_data) { visitClassData *data = static_cast<visitClassData*>(client_data); DUMP_PARSE("visitClass", cursor); switch(cursor.kind) { case CXCursor_ClassDecl: clang_visitChildren(cursor, ::visitClass, &data); break; /* Prevent infinite recursion case CXCursor_CXXBaseSpecifier: { CXType classCursorType = clang_getCursorType(cursor); CXCursor classCursor = clang_getTypeDeclaration(classCursorType); clang_visitChildren(classCursor, ::visitClass, &data); } break; */ case CXCursor_CXXMethod: case CXCursor_FieldDecl: { std::string name(getDisposedString(clang_getCursorSpelling(cursor))); data->mMembers.push_back(name); } break; default: break; } return CXChildVisit_Continue; // return CXChildVisit_Recurse; }
CXCursor findFirstChild(CXCursor parent) { CXCursor ret = clang_getNullCursor(); if (!clang_isInvalid(clang_getCursorKind(parent))) clang_visitChildren(parent, findFirstChildVisitor, &ret); return ret; }
CXCursor findChild(CXCursor parent, const String &name) { FindChildVisitor u = { CXCursor_FirstInvalid, name, clang_getNullCursor() }; if (!clang_isInvalid(clang_getCursorKind(parent))) clang_visitChildren(parent, findChildVisitor, &u); return u.cursor; }
List<CXCursor> children(CXCursor parent, const Filter &in, const Filter &out) { ChildrenVisitor userData = { in, out, List<CXCursor>() }; if (!clang_isInvalid(clang_getCursorKind(parent))) clang_visitChildren(parent, childrenVisitor, &userData); return userData.children; }
OovStringVec Tokenizer::getMembers(size_t offset) { CLangAutoLock lock(mCLangLock, __LINE__); OovStringVec members; visitClassData data(members); // The start cursor is probably a MemberRefExpr. CXCursor memberRefCursor = getCursorAtOffset(mTransUnit, mSourceFile, offset); DUMP_PARSE_INT("getMembers", offset); DUMP_PARSE("getMembers:memberref", memberRefCursor); if(memberRefCursor.kind == CXCursor_MemberRefExpr || memberRefCursor.kind == CXCursor_DeclRefExpr) { CXType classCursorType = clang_getCursorType(memberRefCursor); CXCursor classCursor = clang_getTypeDeclaration(classCursorType); DUMP_PARSE("getMembers:classref", classCursor); if(classCursor.kind == CXCursor_ClassDecl || classCursor.kind == CXCursor_StructDecl || classCursor.kind == CXCursor_UnionDecl) { // CXCursor classCursor = clang_getCursorReferenced(startCursor); // classCursor = clang_getCursorDefinition(classCursor); clang_visitChildren(classCursor, ::visitClass, &data); } } else { // myGetCursorAtOffset(mTransUnit, mSourceFile, offset); } return members; }
/** * Параметр CXTranslationUnit_SkipFunctionBodies позволяет ускорить разбор * за счёт игнорирования парсером тел функций * Внутри функций обычно нет глобальных переменных */ void fileAction(const std::string &path) { CXTranslationUnit unit = clang_parseTranslationUnit( g_index, path.c_str(), nullptr, /* argv */ 0, /* argc */ nullptr, /* unsaved files */ 0, /* num unsaved files */ CXTranslationUnit_SkipFunctionBodies | CXTranslationUnit_DetailedPreprocessingRecord ); if (unit == nullptr) { std::cout << "Cannot parse: " << path << std::endl; return; } // Получаем курсор для всей единицы трансляции CXCursor cursorTU = clang_getTranslationUnitCursor(unit); clang_visitChildren(cursorTU, globalsFinder, NULL); clang_disposeTranslationUnit(unit); }
void filter_already_existing_methods(CXTranslationUnit code_translation_unit,gchar *filename, gchar *class_name) { size_t i; CXFile code_file; CXCursor code_cursor; CXSourceLocation code_source_location; gchar *settername; gchar *gettername; struct GcharTuple tuple; code_file = clang_getFile(code_translation_unit,filename); code_source_location = clang_getLocation(code_translation_unit,code_file,1,1); code_cursor = clang_getTranslationUnitCursor(code_translation_unit); for (i=0; i < property_list.used; i++) { gettername = malloc((strlen(sg_method_name_getter) + 1) * sizeof(gchar)); strncpy(gettername,sg_method_name_getter,strlen(sg_method_name_getter) + 1); gettername = chunked_string_replace(gettername,"$NAME",property_list.data[i].name); settername = malloc((strlen(sg_method_name_setter) + 1) * sizeof(gchar)); strncpy(settername,sg_method_name_setter,strlen(sg_method_name_setter) + 1); settername = chunked_string_replace(settername,"$NAME",property_list.data[i].name); tuple.first = gettername; tuple.second = settername; tuple.class_name = class_name; tuple.number = i; clang_visitChildren(code_cursor,filterer,&tuple); free(gettername); gettername = NULL; free(settername); settername = NULL; } }
CXCursor findChild(CXCursor parent, CXCursorKind kind) { FindChildVisitor u = { kind, String(), clang_getNullCursor() }; if (!clang_isInvalid(clang_getCursorKind(parent))) clang_visitChildren(parent, findChildVisitor, &u); return u.cursor; }
void getParentedDescendants(CXCursor parent, ParentedCursor** descendantsOut, unsigned* countOut) { ParentedCursorList descendantList = LIST_INIT(ParentedCursor); clang_visitChildren(parent, parentedDescendantListBuilder, &descendantList); *descendantsOut = descendantList.items; *countOut = descendantList.count; }
bool cursor::visitChildren(std::function<CXChildVisitResult(const cursor& cur, const cursor& parent)> visitor) { return clang_visitChildren(cur, [](CXCursor cur, CXCursor parent, CXClientData client_data) -> CXChildVisitResult { auto visitor = static_cast<std::function<CXChildVisitResult(const cursor& cur, const cursor& parent)>*>(client_data); return (*visitor)({ cur }, { parent }); }, &visitor); }
void getReferences(CXTranslationUnit tu, CXCursor** childrenOut, unsigned* countOut) { CursorList childList = LIST_INIT(CXCursor); CXCursor parent = clang_getTranslationUnitCursor(tu); clang_visitChildren(parent, referenceListBuilder, &childList); *childrenOut = childList.items; *countOut = childList.count; }
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; }
int main(int argc, const char* argv[]) { if (argc < 4) { std::cerr << "Usage:\n" << " " << argv[0] << " <dbFilename> <indexFilename> [<options>] <sourceFilename>\n"; return 1; } const char* dbFilename = argv[1]; const char* indexFilename = argv[2]; const char* sourceFilename = argv[argc-1]; // Set up the clang translation unit CXIndex cxindex = clang_createIndex(0, 0); CXTranslationUnit tu = clang_parseTranslationUnit( cxindex, 0, argv + 3, argc - 3, // Skip over dbFilename and indexFilename 0, 0, CXTranslationUnit_None); // Print any errors or warnings int n = clang_getNumDiagnostics(tu); if (n > 0) { int nErrors = 0; for (unsigned i = 0; i != n; ++i) { CXDiagnostic diag = clang_getDiagnostic(tu, i); CXString string = clang_formatDiagnostic(diag, clang_defaultDiagnosticDisplayOptions()); fprintf(stderr, "%s\n", clang_getCString(string)); if (clang_getDiagnosticSeverity(diag) == CXDiagnostic_Error || clang_getDiagnosticSeverity(diag) == CXDiagnostic_Fatal) nErrors++; } } // Create the index EverythingIndexer visitor(sourceFilename); clang_visitChildren( clang_getTranslationUnitCursor(tu), &visitorFunction, &visitor); ClicIndex& index = visitor.usrToReferences; // OK, now write the index to a compressed file std::ofstream fout(indexFilename); boost::iostreams::filtering_stream<boost::iostreams::output> zout; zout.push(boost::iostreams::gzip_compressor()); zout.push(fout); printIndex(zout, index); // Now open the database and add the index to it ClicDb db(dbFilename); BOOST_FOREACH(const ClicIndex::value_type& it, index) { const std::string& usr = it.first; db.addMultiple(usr, it.second); } return 0; }
void getParentedReferences(CXTranslationUnit tu, ParentedCursor** referencesOut, unsigned* countOut) { ParentedCursorList referenceList = LIST_INIT(ParentedCursor); CXCursor parent = clang_getTranslationUnitCursor(tu); clang_visitChildren(parent, parentedReferenceListBuilder, &referenceList); *referencesOut = referenceList.items; *countOut = referenceList.count; }
void getParentedDeclarations(CXTranslationUnit tu, ParentedCursor** declarationsOut, unsigned* countOut) { ParentedCursorList declarationList = LIST_INIT(ParentedCursor); CXCursor parent = clang_getTranslationUnitCursor(tu); clang_visitChildren(parent, parentedDeclarationListBuilder, &declarationList); *declarationsOut = declarationList.items; *countOut = declarationList.count; }
void visit_children(cpp_cursor cur, Fnc f) { auto cb = [](CXCursor cur, CXCursor parent, CXClientData data) -> CXChildVisitResult { return (*static_cast<Fnc*>(data))(cur, parent); }; clang_visitChildren(cur, cb, &f); }
static CXCursor getNthChildCursor(CXCursor cursor, int nth) { ChildCountVisitor visitorData(nth); clang_visitChildren(cursor, ChildNthVisitor, &visitorData); CXCursor childCursor = clang_getNullCursor(); if(visitorData.mCount == 0) childCursor = visitorData.mFoundCursor; return childCursor; }
int main(int argc, char *argv[]) { auto index = clang_createIndex(0, 0); auto options = clang_defaultEditingTranslationUnitOptions(); char const *args[] = { "-x", "c++", "-std=c++11" }; auto arg_count = sizeof( args ) / sizeof( *args ); filename = argv[1]; CXUnsavedFile *unsaved_files = NULL; auto unsaved_file_count = 0; tu = clang_parseTranslationUnit(index, filename.c_str(), args, arg_count, unsaved_files, unsaved_file_count, options ); if ( !tu ) { std::cout << "Translation Unit Parse Failed!\n"; return -1; } std::stringstream ss( argv[2] ); int line, col; ss >> line; ss.get(); ss >> col; std::cout << "Hello " << line << ":" << col << "\n"; auto file = clang_getFile( tu, filename.c_str() ); auto location = clang_getLocation( tu, file, line, col ); clang_visitChildren( clang_getTranslationUnitCursor( tu ), visitor, reinterpret_cast<CXClientData>(0) ); auto cursor = clang_getCursor( tu, location ); auto refcursor = clang_getCursorReferenced( cursor ); auto rrefcursor = clang_getCursorReferenced( refcursor ); auto arf = clang_getTypeKindSpelling( clang_getCursorType( cursor ).kind ); auto foo = clang_getCanonicalCursor( cursor ); auto semparent = clang_getCursorSemanticParent( cursor ); auto lexparent = clang_getCursorLexicalParent( cursor ); std::cout << cursor << "\n"; std::cout << refcursor << "\n"; std::cout << rrefcursor << "\n"; std::cout << clang_getCString(arf) << "\n"; std::cout << foo << "\n"; std::cout << "Parent: " << semparent << "\n"; std::cout << "LexParent: " << lexparent << "\n"; //clang_visitChildren( semparent, visitor, reinterpret_cast<CXClientData>(0) ); clang_disposeString( arf ); return 0; }
static enum CXChildVisitResult ide_clang_service_build_index_visitor (CXCursor cursor, CXCursor parent, CXClientData user_data) { IndexRequest *request = user_data; enum CXCursorKind kind; const gchar *style_name = NULL; g_assert (request != NULL); kind = clang_getCursorKind (cursor); switch ((int)kind) { case CXCursor_TypedefDecl: case CXCursor_TypeAliasDecl: style_name = IDE_CLANG_HIGHLIGHTER_TYPE; break; case CXCursor_FunctionDecl: style_name = IDE_CLANG_HIGHLIGHTER_FUNCTION_NAME; break; case CXCursor_EnumDecl: style_name = IDE_CLANG_HIGHLIGHTER_ENUM_NAME; clang_visitChildren (cursor, ide_clang_service_build_index_visitor, user_data); break; case CXCursor_EnumConstantDecl: style_name = IDE_CLANG_HIGHLIGHTER_ENUM_NAME; break; case CXCursor_MacroDefinition: style_name = IDE_CLANG_HIGHLIGHTER_MACRO_NAME; break; default: break; } if (style_name != NULL) { CXString cxstr; const gchar *word; cxstr = clang_getCursorSpelling (cursor); word = clang_getCString (cxstr); ide_highlight_index_insert (request->index, word, (gpointer)style_name); clang_disposeString (cxstr); } return CXChildVisit_Continue; }
CXChildVisitResult FunctionDefinition::executeParse (CXCursor cursor, ParserContext *context) { auto returnType = clang_getCursorResultType(cursor); auto returnTypeValue = CXStringToString(clang_getTypeSpelling(clang_getCursorResultType(cursor))); this->returnType = new Type(context, returnType, returnTypeValue); this->variadic = clang_isFunctionTypeVariadic(clang_getCursorType(cursor)); addBlockIfFound(context, this, this->getFramework(), this->returnType, ""); context->getParserTree()->addFunction(this); clang_visitChildren(cursor, parseFunctionMember, this); return CXChildVisit_Continue; }
static CXCursor myGetCursorAtOffset(CXTranslationUnit tu, CXFile file, unsigned offset) { CXCursor rootCursor = clang_getTranslationUnitCursor(tu); visitTranslationUnitData data(file, offset); clang_visitChildren(rootCursor, ::visitTranslationUnit, &data); fprintf(sLog.mFp, "--\n"); fflush(sLog.mFp); CXCursor cursor = data.mCursor; return cursor; }
ast_element translation_unit::ast() { // Prepare structure ast_element e; e.top_name = mName; e.top = &e; CXCursor rootCursor = clang_getTranslationUnitCursor(mUnit); clang_visitChildren(rootCursor, *visitor_ast, &e); return e; }
List<CXCursor> findChain(CXCursor parent, const List<CXCursorKind> &kinds) { assert(!kinds.isEmpty()); FindChainVisitor userData = { kinds, List<CXCursor>() }; if (!clang_isInvalid(clang_getCursorKind(parent))) clang_visitChildren(parent, findChainVisitor, &userData); if (userData.ret.size() != kinds.size()) { userData.ret.clear(); } return userData.ret; }
CXChildVisitResult search_kind_visitor(CXCursor cursor, CXCursor, CXClientData data) { auto const kind = clang_getCursorKind(cursor); if ((reinterpret_cast<DataType *>(data)->second(kind))) { (reinterpret_cast<DataType *>(data))->first = cursor; return CXChildVisit_Break; } clang_visitChildren(cursor, search_kind_visitor<DataType>, data); return CXChildVisit_Continue; }
int main(int argc, char * argv[]) { CXIndex index = clang_createIndex(0, 0); CXTranslationUnit txUnit = clang_parseTranslationUnit(index, 0, (const char * const *) argv, argc, 0, 0, CXTranslationUnit_None); CXCursor cur = clang_getTranslationUnitCursor(txUnit); clang_visitChildren(cur, visitor, NULL); clang_disposeTranslationUnit(txUnit); clang_disposeIndex(index); return 0; }
std::string AdvancedCallExprHandler( CXCursor cursor ) { auto newcursor = clang_getCursorReferenced( cursor ); std::string result = "Function"; if ( newcursor.kind == CXCursor_Constructor ) result = "Identifier"; else clang_visitChildren( cursor, CallExprVisitor, reinterpret_cast<std::string *>(&result) ); return result; }
CXChildVisitResult AST::visitor(CXCursor cursor, CXCursor, CXClientData u) { UserData *userData = reinterpret_cast<UserData*>(u); assert(userData); Cursor::Data *p = userData->parents.isEmpty() ? 0 : userData->parents.back().data.get(); Cursor c = userData->ast->construct(cursor, p); userData->parents.push_back(Cursor { c.data } ); clang_visitChildren(cursor, visitor, u); if (userData->parents.size() > 1) userData->parents.pop_back(); return CXChildVisit_Continue; }