From e687e95fa62b26fa3d6e930ffbbec8fb389cf30e Mon Sep 17 00:00:00 2001 From: eidheim Date: Fri, 21 Jul 2017 09:17:28 +0200 Subject: [PATCH] Improved get_similar_token_offsets to also include virtual and override functions --- cmake/Modules/FindLibClang.cmake | 15 ++++++------ src/Cursor.cc | 24 ++++++++++++++++++++ src/Cursor.h | 3 +++ src/Tokens.cc | 39 +++++++++++++++++++++++++------- src/Tokens.h | 5 ++-- 5 files changed, 69 insertions(+), 17 deletions(-) diff --git a/cmake/Modules/FindLibClang.cmake b/cmake/Modules/FindLibClang.cmake index 6eae07c..30e4c23 100644 --- a/cmake/Modules/FindLibClang.cmake +++ b/cmake/Modules/FindLibClang.cmake @@ -14,21 +14,20 @@ # Known LLVM release numbers. # most recent versions come first -set(LIBCLANG_KNOWN_LLVM_VERSIONS 4.0.0 - 4.0 +set(LIBCLANG_KNOWN_LLVM_VERSIONS 5.0.0 5.0 + 4.0.1 + 4.0.0_1 4.0.0 4.0 3.9.1 - 3.9.0 - 3.9 + 3.9.0 3.9 3.8.1 - 3.8 + 3.8.0 3.8 3.7.1 3.7 3.6.2 3.6.1 3.6 3.5.1 - 3.5.0 #Arch Linux - 3.5 #LLVM Debian/Ubuntu packages from http://llvm.org/apt/ + 3.5.0 3.5 3.4.2 3.4.1 3.4 3.3 3.2 3.1) set(libclang_llvm_header_search_paths) @@ -64,6 +63,7 @@ endforeach() find_path(LIBCLANG_INCLUDE_DIR clang-c/Index.h PATHS ${libclang_llvm_header_search_paths} PATH_SUFFIXES LLVM/include #Windows package from http://llvm.org/releases/ + llvm50/include llvm41/include llvm40/include llvm39/include llvm38/include llvm37/include llvm36/include # FreeBSD DOC "The path to the directory that contains clang-c/Index.h") # On Windows with MSVC, the import library uses the ".imp" file extension @@ -77,6 +77,7 @@ endif() find_library(LIBCLANG_LIBRARY NAMES libclang.imp libclang clang PATHS ${libclang_llvm_lib_search_paths} PATH_SUFFIXES LLVM/lib #Windows package from http://llvm.org/releases/ + llvm50/lib llvm41/lib llvm40/lib llvm39/lib llvm38/lib llvm37/lib llvm36/lib # FreeBSD DOC "The file that corresponds to the libclang library.") get_filename_component(LIBCLANG_LIBRARY_DIR ${LIBCLANG_LIBRARY} PATH) diff --git a/src/Cursor.cc b/src/Cursor.cc index 0194f94..8e03e55 100644 --- a/src/Cursor.cc +++ b/src/Cursor.cc @@ -70,6 +70,30 @@ std::string clangmm::Cursor::get_usr_extended() const { return usr; } +std::unordered_set clangmm::Cursor::get_all_usr_extended() const { + std::unordered_set usrs; + if(get_kind()==Kind::CXXMethod) { + class Recursive { + public: + static void overridden(std::unordered_set &usrs, const Cursor &cursor) { + usrs.emplace(cursor.get_usr_extended()); + CXCursor *cursors; + unsigned size; + clang_getOverriddenCursors(cursor.cx_cursor, &cursors, &size); + for(unsigned c=0;c #include +#include namespace clangmm { class Cursor { @@ -197,6 +198,8 @@ namespace clangmm { std::string get_usr() const; /// Improved usr that is also template and argument invariant std::string get_usr_extended() const; + /// Also get overridden cursors + std::unordered_set get_all_usr_extended() const; Cursor get_referenced() const; Cursor get_canonical() const; Cursor get_definition() const; diff --git a/src/Tokens.cc b/src/Tokens.cc index d8bea47..635a48a 100644 --- a/src/Tokens.cc +++ b/src/Tokens.cc @@ -1,5 +1,6 @@ #include "Tokens.h" #include "Utility.h" +#include clangmm::Tokens::Tokens(CXTranslationUnit &cx_tu, const SourceRange &range): cx_tu(cx_tu) { clang_tokenize(cx_tu, range.cx_range, &cx_tokens, &num_tokens); @@ -19,14 +20,36 @@ clangmm::Tokens::~Tokens() { } //This works across TranslationUnits. Similar tokens defined as tokens with equal canonical cursors. -std::vector > clangmm::Tokens::get_similar_token_offsets(const std::string &spelling, const std::string &usr) { - std::vector > offsets; - for(auto &token: *this) { - if(token.is_identifier()) { - auto referenced=token.get_cursor().get_referenced(); - if(referenced && spelling==token.get_spelling() && usr==referenced.get_usr_extended()) - offsets.emplace_back(token.offsets); +std::vector > clangmm::Tokens::get_similar_token_offsets(Cursor::Kind kind, const std::string &spelling, + const std::unordered_set &usrs) { + // Special case for virtual and override functions + if(kind==Cursor::Kind::CXXMethod) { + std::vector > offsets; + for(auto &token: *this) { + if(token.is_identifier()) { + auto referenced=token.get_cursor().get_referenced(); + if(referenced && referenced.get_kind()==Cursor::Kind::CXXMethod && spelling==token.get_spelling()) { + auto referenced_usrs=referenced.get_all_usr_extended(); + for(auto &usr: referenced_usrs) { + if(usrs.count(usr)) { + offsets.emplace_back(token.offsets); + break; + } + } + } + } } + return offsets; + } + else { + std::vector > offsets; + for(auto &token: *this) { + if(token.is_identifier()) { + auto referenced=token.get_cursor().get_referenced(); + if(referenced && spelling==token.get_spelling() && usrs.count(referenced.get_usr_extended())) + offsets.emplace_back(token.offsets); + } + } + return offsets; } - return offsets; } diff --git a/src/Tokens.h b/src/Tokens.h index 63317e1..9a8c7ed 100644 --- a/src/Tokens.h +++ b/src/Tokens.h @@ -3,7 +3,7 @@ #include #include "SourceRange.h" #include "Token.h" -#include +#include #include namespace clangmm { @@ -13,7 +13,8 @@ namespace clangmm { Tokens(CXTranslationUnit &cx_tu, const SourceRange &range); public: ~Tokens(); - std::vector > get_similar_token_offsets(const std::string &spelling, const std::string &usr); + std::vector > get_similar_token_offsets(Cursor::Kind kind, const std::string &spelling, + const std::unordered_set &usrs); private: CXToken *cx_tokens; unsigned num_tokens;