From 3e678a45a8dc43fe89abb8d1ae01c51d38ec684d Mon Sep 17 00:00:00 2001 From: eidheim Date: Fri, 11 Aug 2017 08:38:04 +0200 Subject: [PATCH] Corrected: when getting tokens from a header, FieldDecl tokens are getting ClassDecl or StructDecl cursors --- src/Tokens.cc | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/Tokens.cc b/src/Tokens.cc index 7d030f0..92bc023 100644 --- a/src/Tokens.cc +++ b/src/Tokens.cc @@ -7,10 +7,42 @@ clangmm::Tokens::Tokens(CXTranslationUnit &cx_tu, const SourceRange &range): cx_ cx_cursors.resize(num_tokens); clang_annotateTokens(cx_tu, cx_tokens, num_tokens, cx_cursors.data()); for (unsigned i = 0; i < num_tokens; i++) { - if(cx_cursors[i].kind==CXCursor_DeclRefExpr) { //Temporary fix to a libclang bug + if(cx_cursors[i].kind==CXCursor_DeclRefExpr) { // Temporary fix to a libclang bug auto real_cursor=clang_getCursor(cx_tu, clang_getTokenLocation(cx_tu, cx_tokens[i])); cx_cursors[i]=real_cursor; } + // Corrects: when getting tokens from a header, FieldDecl tokens are getting ClassDecl or StructDecl cursors + else if(cx_cursors[i].kind==CXCursor_ClassDecl || cx_cursors[i].kind==CXCursor_StructDecl) { + Token token(cx_tu, cx_tokens[i], cx_cursors[i]); + auto cursor=token.get_cursor(); + if(token.offsets.second!=cursor.get_source_range().get_offsets().second && token.offsets.first!=cursor.get_source_location().get_offset() && token.is_identifier()) { + class VisitorData { + public: + std::string path; + bool found_path; + std::pair offsets; + CXCursor found_cursor; + }; + VisitorData data{token.get_source_location().get_path(), false, token.offsets, clang_getNullCursor()}; + auto translation_unit_cursor = clang_getTranslationUnitCursor(cx_tu); + clang_visitChildren(translation_unit_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data_) { + auto data=static_cast(data_); + Cursor cursor(cx_cursor); + if(data->found_path || cursor.get_source_location().get_path()==data->path) { + data->found_path=true; + if(cursor.get_source_range().get_offsets().second==data->offsets.second && cursor.get_source_location().get_offset()==data->offsets.first) { + data->found_cursor=cx_cursor; + return CXChildVisit_Break; + } + return CXChildVisit_Recurse; + } + return CXChildVisit_Continue; + }, &data); + + if(!clang_Cursor_isNull(data.found_cursor)) + cx_cursors[i]=data.found_cursor; + } + } emplace_back(Token(cx_tu, cx_tokens[i], cx_cursors[i])); } }