enum CXChildVisitResult parentedDeclAndRefListBuilder(CXCursor cursor, CXCursor parent, CXClientData clientData) { ParentedCursorListPair* declsAndRefs = (ParentedCursorListPair*) clientData; if (clang_isDeclaration(clang_getCursorKind(cursor))) { ParentedCursor newEntry = { parent, cursor }; ParentedCursorList* decls = &declsAndRefs->decls; LIST_APPEND(ParentedCursor, decls, newEntry); } if (clang_isReference(clang_getCursorKind(cursor))) { ParentedCursor newEntry = { parent, cursor }; ParentedCursorList* refs = &declsAndRefs->refs; LIST_APPEND(ParentedCursor, refs, newEntry); } return CXChildVisit_Recurse; }
enum CXChildVisitResult foundChild(CXCursor cursor, CXCursor parent, CXClientData client_data) { if(clang_getCursorKind(cursor) == CXCursor_CallExpr) { printf("-%s\n", clang_getCString(clang_getCursorSpelling(cursor))); } if(clang_isDeclaration(clang_getCursorKind(cursor)) && (clang_getCursorLinkage(cursor) == CXLinkage_External || clang_getCursorLinkage(cursor) == CXLinkage_Internal)) { CXFile file; const char * filename, * wantFilename; CXSourceLocation cloc; cloc = clang_getCursorLocation(cursor); clang_getInstantiationLocation(cloc, &file, NULL, NULL, NULL); filename = clang_getCString(clang_getFileName(file)); wantFilename = (const char *)client_data; if(!filename || strcmp(wantFilename, filename)) return CXChildVisit_Recurse; if(clang_getCursorLinkage(cursor) == CXLinkage_External) printf("+%s\n", clang_getCString(clang_getCursorSpelling(cursor))); else printf("?%s\n", clang_getCString(clang_getCursorSpelling(cursor))); } return CXChildVisit_Recurse; }
void IndexerJob::nestedClassConstructorCallUgleHack(const CXCursor &parent, CursorInfo &info, CXCursorKind refKind, const Location &refLoc) { if (refKind == CXCursor_Constructor && clang_getCursorKind(mLastCursor) == CXCursor_TypeRef && clang_getCursorKind(parent) == CXCursor_CXXFunctionalCastExpr) { const CXStringScope str = clang_getCursorSpelling(mLastCursor); int start = -1; const char *cstr = str.data(); int idx = 0; while (cstr[idx]) { if (start == -1 && cstr[idx] == ' ') { start = idx; } ++idx; } if (start != -1) { // error() << "Changed symbolLength from" << info.symbolLength << "to" << (idx - start - 1) << "for dude reffing" << refLoc; info.symbolLength = idx - start - 1; } RTags::Filter in; in.kinds.insert(CXCursor_TypeRef); const List<CXCursor> typeRefs = RTags::children(parent, in); for (int i=0; i<typeRefs.size(); ++i) { const Location loc = createLocation(typeRefs.at(i)); // error() << "Added" << refLoc << "to targets for" << typeRefs.at(i); mData->symbols[loc].targets.insert(refLoc); } } }
static inline CXCursor findDestructorForDelete(const CXCursor &deleteStatement) { const CXCursor child = RTags::findFirstChild(deleteStatement); CXCursorKind kind = clang_getCursorKind(child); switch (kind) { case CXCursor_UnexposedExpr: case CXCursor_CallExpr: break; default: return nullCursor; } const CXCursor var = clang_getCursorReferenced(child); kind = clang_getCursorKind(var); switch (kind) { case CXCursor_VarDecl: case CXCursor_FieldDecl: case CXCursor_ParmDecl: case CXCursor_CXXMethod: case CXCursor_FunctionDecl: break; default: if (!clang_isInvalid(kind)) { error() << "Got unexpected cursor" << deleteStatement << var; // assert(0); } return nullCursor; } CXCursor ref = RTags::findChild(var, CXCursor_TypeRef); if (ref != CXCursor_TypeRef) ref = RTags::findChild(var, CXCursor_TemplateRef); kind = clang_getCursorKind(ref); switch (kind) { case CXCursor_TypeRef: case CXCursor_TemplateRef: break; default: return nullCursor; } const CXCursor referenced = clang_getCursorReferenced(ref); kind = clang_getCursorKind(referenced); switch (kind) { case CXCursor_StructDecl: case CXCursor_ClassDecl: case CXCursor_ClassTemplate: break; default: return nullCursor; } const CXCursor destructor = RTags::findChild(referenced, CXCursor_Destructor); return destructor; }
CXChildVisitResult visitor( CXCursor cursor, CXCursor parent, CXClientData client_data) { ClangTools::TranslationUnit::AstWalker * astWalker = reinterpret_cast<ClangTools::TranslationUnit::AstWalker *>(client_data); std::vector<std::string> & funcNames = *(reinterpret_cast<std::vector<std::string> *>(astWalker->getClientData())); auto sourceLocation = clang_getCursorLocation(cursor); CXFile file; clang_getFileLocation(sourceLocation, &file, 0, 0, 0); auto fileName = clang_getFileName(file); auto fileNameStr = ClangTools::String(fileName); if (fileNameStr != astWalker->getFileName()) { return CXChildVisit_Recurse; } auto func = std::string{}; auto def = bool{false}; if (clang_isCursorDefinition(cursor)) { def = true; } switch (clang_getCursorKind(cursor)) { case CXCursor_FunctionDecl: func = "Function "; break; case CXCursor_FunctionTemplate: func = "FunctionTemplate "; break; case CXCursor_CXXMethod: func = "CXXMethod "; break; default: return CXChildVisit_Recurse; break; } func += clang_isCursorDefinition(cursor) ? "definition: " : "declaration: "; auto semanticParent = clang_getCursorSemanticParent(cursor); auto semanticParentSpelling = clang_getCursorSpelling(semanticParent); func += ClangTools::String(semanticParentSpelling) + "::"; auto cursorSpelling = clang_getCursorSpelling(cursor); func += ClangTools::String(cursorSpelling); auto lexicalParent = clang_getCursorLexicalParent(cursor); auto lexicalParentSpelling = clang_getCursorSpelling(lexicalParent); func += " found in: " + ClangTools::String(lexicalParentSpelling); funcNames.push_back(func); return CXChildVisit_Recurse; }
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; }
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 enum CXChildVisitResult visitor_enum_cb(CXCursor cursor, CXCursor parent, CXClientData client_data) { EnumData* data = (EnumData*)client_data; ErlNifEnv *env = data->env; ERL_NIF_TERM name; ERL_NIF_TERM value; long long cvalue; CXString tmp; char* cstr; switch (clang_getCursorKind(cursor)) { case CXCursor_EnumConstantDecl: { tmp = clang_getCursorSpelling(cursor); cstr = (char*)clang_getCString(tmp); cvalue = clang_getEnumConstantDeclValue(cursor); name = enif_make_string(env, cstr, ERL_NIF_LATIN1); value = enif_make_int64(env, cvalue); data->enum_values = enif_make_list_cell(env, enif_make_tuple2(env, name, value), data->enum_values); } default: { return CXChildVisit_Continue; } } }
enum CXChildVisitResult property_list_builder(CXCursor cursor, CXCursor cursor_parent, CXClientData client_data) { ScintillaObject *current_doc_sci = (ScintillaObject *)client_data; enum CXCursorKind code_cursor_kind; CXSourceLocation code_source_location; code_source_location = clang_getCursorLocation(cursor); code_cursor_kind = clang_getCursorKind(cursor); if (code_cursor_kind == 1) { property_kind = property_helper_get_kind(current_doc_sci,code_source_location); } else if (code_cursor_kind == 6) { gchar *type = NULL; gchar *name = NULL; type = property_helper_get_type(current_doc_sci,code_source_location); name = (gchar *)clang_getCString(clang_getCursorSpelling(cursor)); chunked_property_add(&property_list, type, name, sg_do_getters, sg_do_setters, sg_placement_inner, property_kind); free(type); free(name); } return CXChildVisit_Continue; }
String IndexerJob::typeName(const CXCursor &cursor) { String ret; switch (clang_getCursorKind(cursor)) { case CXCursor_FunctionTemplate: // ### If the return value is a template type we get an empty string here case CXCursor_FunctionDecl: case CXCursor_CXXMethod: ret = typeString(clang_getResultType(clang_getCursorType(cursor))); break; case CXCursor_ClassTemplate: case CXCursor_ClassDecl: case CXCursor_StructDecl: case CXCursor_UnionDecl: ret = RTags::eatString(clang_getCursorSpelling(cursor)); break; case CXCursor_FieldDecl: // ### If the return value is a template type we get an empty string here case CXCursor_VarDecl: case CXCursor_ParmDecl: ret = typeString(clang_getCursorType(cursor)); break; default: return String(); } if (!ret.isEmpty() && !ret.endsWith('*') && !ret.endsWith('&')) ret.append(' '); return ret; }
static CXChildVisitResult parseFunctionMember (CXCursor cursor, CXCursor parent, CXClientData clientData) { auto functionDef = static_cast<FunctionDefinition*>(clientData); auto displayName = CXStringToString(clang_getCursorDisplayName(cursor)); auto kind = clang_getCursorKind(cursor); std::map<std::string, std::string> location; getSourceLocation(cursor, functionDef->getContext(), location); // std::cerr << "function: " << displayName << " kind: " << kind << ", " << hyperloop::toJSON(location) << std::endl; switch (kind) { case CXCursor_ParmDecl: { auto argType = clang_getCursorType(cursor); auto typeValue= CXStringToString(clang_getTypeSpelling(argType)); auto encoding = CXStringToString(clang_getDeclObjCTypeEncoding(cursor)); functionDef->addArgument(displayName, argType, typeValue, encoding); break; } case CXCursor_ObjCClassRef: case CXCursor_TypeRef: case CXCursor_UnexposedAttr: case CXCursor_CompoundStmt: case CXCursor_AsmLabelAttr: case CXCursor_ConstAttr: case CXCursor_PureAttr: { break; } default: { std::cerr << "not handled, function: " << displayName << " kind: " << kind << std::endl; break; } } return CXChildVisit_Continue; }
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; }
CXCursor findFirstChild(CXCursor parent) { CXCursor ret = clang_getNullCursor(); if (!clang_isInvalid(clang_getCursorKind(parent))) clang_visitChildren(parent, findFirstChildVisitor, &ret); return ret; }
Expr* CursorHelper::getExpr(CXCursor node) { if (clang_isExpression(clang_getCursorKind(node))) { return (Expr *)node.data[1]; } return NULL; }
Decl* CursorHelper::getDecl(CXCursor node) { if (clang_isDeclaration(clang_getCursorKind(node))) { return (Decl *)node.data[0]; } return NULL; }
Stmt* CursorHelper::getStmt(CXCursor node) { if (clang_isStatement(clang_getCursorKind(node))) { return (Stmt *)node.data[1]; } return NULL; }
static CXChildVisitResult findChildVisitor(CXCursor cursor, CXCursor, CXClientData data) { FindChildVisitor *u = reinterpret_cast<FindChildVisitor*>(data); if (clang_getCursorKind(cursor) == u->kind) { u->cursor = cursor; return CXChildVisit_Break; } return CXChildVisit_Continue; }
void ClangIndexer::superclassTemplateMemberFunctionUgleHack(const CXCursor &cursor, CXCursorKind kind, const Location &location, const CXCursor &ref, const CXCursor &parent) { // This is for references to superclass template functions. Awful awful // shit. See https://github.com/Andersbakken/rtags/issues/62 and commit // for details. I really should report this as a bug. if (kind == CXCursor_MemberRefExpr && clang_getCursorKind(parent) == CXCursor_CallExpr) { const CXCursor templateRef = RTags::findChild(cursor, CXCursor_TemplateRef); if (templateRef == CXCursor_TemplateRef) { const CXCursor classTemplate = clang_getCursorReferenced(templateRef); if (classTemplate == CXCursor_ClassTemplate) { FILE *f = fopen(location.path().constData(), "r"); if (f) { const CXSourceRange range = clang_getCursorExtent(cursor); const CXSourceLocation end = clang_getRangeEnd(range); unsigned offset; clang_getSpellingLocation(end, 0, 0, 0, &offset); String name; while (offset > 0) { fseek(f, --offset, SEEK_SET); char ch = static_cast<char>(fgetc(f)); if (isalnum(ch) || ch == '_' || ch == '~') { name.prepend(ch); } else { break; } } fclose(f); if (!name.isEmpty()) { RTags::Filter out; out.kinds.insert(CXCursor_MemberRefExpr); const int argCount = RTags::children(parent, RTags::Filter(), out).size(); RTags::Filter in(RTags::Filter::And); in.names.insert(name); in.argumentCount = argCount; const List<CXCursor> alternatives = RTags::children(classTemplate, in); switch (alternatives.size()) { case 1: // ### not sure this is correct with line/col handleReference(cursor, kind, Location(location.fileId(), location.line(), location.column() + 1), alternatives.first(), parent); break; case 0: break; default: warning() << "Can't decide which of these cursors are right for me" << cursor << alternatives << "Need to parse types"; break; } } } } } } }
enum CXChildVisitResult referenceListBuilder(CXCursor cursor, CXCursor parent, CXClientData clientData) { if (clang_isReference(clang_getCursorKind(cursor))) { CursorList* childList = (CursorList*) clientData; LIST_APPEND(CXCursor, childList, cursor); } return CXChildVisit_Recurse; }
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; }
std::string libclang_vim::stringize_cursor_kind(CXCursor const& cursor) { CXCursorKind const kind = clang_getCursorKind(cursor); cxstring_ptr kind_name = clang_getCursorKindSpelling(kind); auto const kind_type_name = stringize_cursor_kind_type(kind); return stringize_key_value("kind", kind_name) + (kind_type_name.empty() ? std::string{} : ("'kind_type':'" + kind_type_name + "',")) + stringize_cursor_extra_info(cursor); }
enum CXChildVisitResult visitor(CXCursor cursor, CXCursor parent, CXClientData data) { enum CXCursorKind cKind = clang_getCursorKind(cursor); CXString nameString = clang_getCursorDisplayName(cursor); CXString typeString = clang_getCursorKindSpelling(cKind); printf("Name:%s, Kind:%s\n", clang_getCString(nameString), clang_getCString(typeString)); clang_disposeString(nameString); clang_disposeString(typeString); return CXChildVisit_Continue; }
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; }
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); } } }
static inline bool isInline(const CXCursor &cursor) { switch (clang_getCursorKind(clang_getCursorLexicalParent(cursor))) { case CXCursor_ClassDecl: case CXCursor_ClassTemplate: case CXCursor_StructDecl: return true; default: return false; } }
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; }
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; }
CXCursor libclang_vim::search_kind( const CXCursor& cursor, const std::function<bool(const CXCursorKind&)>& predicate) { const auto kind = clang_getCursorKind(cursor); if (predicate(kind)) { return cursor; } auto kind_visitor_data = std::make_pair(clang_getNullCursor(), predicate); clang_visitChildren(cursor, search_kind_visitor, &kind_visitor_data); return kind_visitor_data.first; }
static CXChildVisitResult findChainVisitor(CXCursor cursor, CXCursor, CXClientData data) { FindChainVisitor *u = reinterpret_cast<FindChainVisitor*>(data); if (clang_getCursorKind(cursor) == u->kinds.at(u->ret.size())) { u->ret.append(cursor); if (u->ret.size() < u->kinds.size()) return CXChildVisit_Recurse; return CXChildVisit_Break; } return CXChildVisit_Break; }