diff --git a/cmake/Modules/FindLibClang.cmake b/cmake/Modules/FindLibClang.cmake index f294979..38efd25 100644 --- a/cmake/Modules/FindLibClang.cmake +++ b/cmake/Modules/FindLibClang.cmake @@ -14,7 +14,8 @@ # Known LLVM release numbers. # most recent versions come first -set(LIBCLANG_KNOWN_LLVM_VERSIONS 3.6.2 +set(LIBCLANG_KNOWN_LLVM_VERSIONS 3.7 + 3.6.2 3.6.1 3.6 3.5.1 diff --git a/docs/install.md b/docs/install.md index bb79a05..fa9931b 100644 --- a/docs/install.md +++ b/docs/install.md @@ -27,15 +27,16 @@ make install ``` ##Windows with MSYS2 (https://msys2.github.io/) -Install dependencies(replace [arch] with i686 or x86_64 depending on your MSYS2 install): +Install dependencies (replace x86_64 with i686 for 32-bit MSYS2 installs): ```sh -pacman -S git mingw-w64-[arch]-cmake make mingw-w64-[arch]-toolchain mingw-w64-[arch]-clang +pacman -S git mingw-w64-x86_64-cmake make mingw-w64-x86_64-toolchain mingw-w64-x86_64-clang ``` +Compile and install (replace mingw64 with mingw32 for 32-bit MSYS2 installs): ```sh git clone https://github.com/cppit/libclangmm.git cd libclangmm -cmake -G"MSYS Makefiles" -DCMAKE_INSTALL_PREFIX=/mingw[32 or 64] . +cmake -G"MSYS Makefiles" -DCMAKE_INSTALL_PREFIX=/mingw64 . make make install ``` diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 640cba3..a1efa98 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,11 +48,6 @@ set(cc_files add_library(${project_name} SHARED ${header_files} ${cc_files}) include_directories(${LIBCLANG_INCLUDE_DIRS}) - -#TODO: till clang is fixed on MSYS2 ((lib)clang.dll.a is missing): -if(MSYS) - set(LIBCLANG_LIBRARIES "${CMAKE_INSTALL_PREFIX}/bin/clang.dll") -endif() target_link_libraries(${project_name} ${LIBCLANG_LIBRARIES}) install(TARGETS ${project_name} RUNTIME DESTINATION bin LIBRARY DESTINATION lib) diff --git a/src/CodeCompleteResults.cc b/src/CodeCompleteResults.cc index 49ab663..8fdef7b 100644 --- a/src/CodeCompleteResults.cc +++ b/src/CodeCompleteResults.cc @@ -1,11 +1,12 @@ #include "CodeCompleteResults.h" #include "CompletionString.h" #include +#include "Utility.h" -clang::CodeCompleteResults:: -CodeCompleteResults(CXTranslationUnit &cx_tu, const std::string &file_name, - const std::map &buffers, - unsigned line_num, unsigned column) { +clang::CodeCompleteResults::CodeCompleteResults(CXTranslationUnit &cx_tu, + const std::string &file_name, + const std::map &buffers, + unsigned line_num, unsigned column) { std::vector files; for (auto &buffer : buffers) { CXUnsavedFile file; @@ -29,17 +30,19 @@ clang::CodeCompleteResults::~CodeCompleteResults() { clang_disposeCodeCompleteResults(cx_results); } -unsigned clang::CodeCompleteResults:: -size() { +unsigned clang::CodeCompleteResults::size() const { if(cx_results==NULL) return 0; return cx_results->NumResults; } -clang::CompletionString clang::CodeCompleteResults:: -get(unsigned i) { +clang::CompletionString clang::CodeCompleteResults::get(unsigned i) const { if (i >= size()) { throw std::invalid_argument("clang::CodeCompleteResults::get(unsigned i): i>=size()"); } return CompletionString(cx_results->Results[i].CompletionString); } + +std::string clang::CodeCompleteResults::get_usr() const { + return clang::to_string(clang_codeCompleteGetContainerUSR(cx_results)); +} diff --git a/src/CodeCompleteResults.h b/src/CodeCompleteResults.h index e6c8a17..ceb366c 100644 --- a/src/CodeCompleteResults.h +++ b/src/CodeCompleteResults.h @@ -2,6 +2,7 @@ #define CODECOMPLETERESULTS_H_ #include #include +#include #include "CompletionString.h" namespace clang { @@ -12,8 +13,9 @@ namespace clang { unsigned line_num, unsigned column); public: ~CodeCompleteResults(); - CompletionString get(unsigned index); - unsigned size(); + CompletionString get(unsigned index) const; + unsigned size() const; + std::string get_usr() const; CXCodeCompleteResults *cx_results; }; diff --git a/src/Cursor.cc b/src/Cursor.cc index 6cd3271..882e0fe 100644 --- a/src/Cursor.cc +++ b/src/Cursor.cc @@ -13,6 +13,10 @@ clang::SourceRange clang::Cursor::get_source_range() const { return SourceRange(clang_getCursorExtent(cx_cursor)); } +std::string clang::Cursor::get_spelling() const { + return clang::to_string(clang_getCursorSpelling(cx_cursor)); +} + std::string clang::Cursor::get_usr() const { return clang::to_string(clang_getCursorUSR(cx_cursor)); } @@ -27,4 +31,42 @@ clang::Cursor::operator bool() const { bool clang::Cursor::operator==(const Cursor& rhs) const { return get_usr()==rhs.get_usr(); -} \ No newline at end of file +} + +//TODO: Is there a way to optimise this? +bool clang::Cursor::has_type() { + auto referenced=clang_getCursorReferenced(cx_cursor); + if(clang_Cursor_isNull(referenced)) + return false; + auto type=clang_getCursorType(referenced); + auto spelling=clang::to_string(clang_getTypeSpelling(type)); + return spelling!=""; +} + +std::string clang::Cursor::get_type() { + std::string spelling; + auto referenced=clang_getCursorReferenced(cx_cursor); + if(!clang_Cursor_isNull(referenced)) { + auto type=clang_getCursorType(referenced); + spelling=clang::to_string(clang_getTypeSpelling(type)); + std::string auto_end=""; + //TODO fix const auto + if((spelling.size()>=4 && spelling.substr(0, 4)=="auto")) { + auto_end=spelling.substr(4); + auto type=clang_getCanonicalType(clang_getCursorType(cx_cursor)); + spelling=clang::to_string(clang_getTypeSpelling(type)); + if(spelling.find(" ")==std::string::npos) + spelling+=auto_end; + } + } + return spelling; +} + +std::string clang::Cursor::get_brief_comments() { + std::string comment_string; + auto referenced=get_referenced(); + if(referenced) { + comment_string=clang::to_string(clang_Cursor_getBriefCommentText(referenced.cx_cursor)); + } + return comment_string; +} diff --git a/src/Cursor.h b/src/Cursor.h index f567375..2b410d7 100644 --- a/src/Cursor.h +++ b/src/Cursor.h @@ -180,11 +180,16 @@ namespace clang { const CursorKind get_kind(); SourceLocation get_source_location() const; SourceRange get_source_range() const; + std::string get_spelling() const; std::string get_usr() const; Cursor get_referenced() const; operator bool() const; bool operator==(const Cursor& rhs) const; - + + bool has_type(); + std::string get_type(); + std::string get_brief_comments(); + CXCursor cx_cursor; }; } // namespace clang diff --git a/src/SourceLocation.cc b/src/SourceLocation.cc index 7638807..96904d6 100644 --- a/src/SourceLocation.cc +++ b/src/SourceLocation.cc @@ -9,6 +9,11 @@ clang::SourceLocation::SourceLocation(CXTranslationUnit &tu, const std::string & cx_location = clang_getLocationForOffset(tu, file, offset); } +clang::SourceLocation::SourceLocation(CXTranslationUnit &tu, const std::string &filepath, unsigned line, unsigned column) { + CXFile file = clang_getFile(tu, filepath.c_str()); + cx_location = clang_getLocation(tu, file, line, column); +} + std::string clang::SourceLocation::get_path() { std::string path; get_data(&path, NULL, NULL, NULL); diff --git a/src/SourceLocation.h b/src/SourceLocation.h index 501c9e6..74e3dff 100644 --- a/src/SourceLocation.h +++ b/src/SourceLocation.h @@ -17,6 +17,7 @@ namespace clang { class SourceLocation { friend class TranslationUnit; SourceLocation(CXTranslationUnit &tu, const std::string &filepath, unsigned offset); + SourceLocation(CXTranslationUnit &tu, const std::string &filepath, unsigned line, unsigned column); public: SourceLocation(const CXSourceLocation& cx_location) : cx_location(cx_location) {} diff --git a/src/Token.cc b/src/Token.cc index e3a9b9c..372616c 100644 --- a/src/Token.cc +++ b/src/Token.cc @@ -23,41 +23,3 @@ std::string clang::Token::get_spelling() { const clang::TokenKind clang::Token::get_kind() { return (TokenKind) clang_getTokenKind(cx_token); } - -//TODO: Is there a way to optimise this? -bool clang::Token::has_type() { - auto referenced=clang_getCursorReferenced(cx_cursor); - if(clang_Cursor_isNull(referenced)) - return false; - auto type=clang_getCursorType(referenced); - auto spelling=clang::to_string(clang_getTypeSpelling(type)); - return spelling!=""; -} - -std::string clang::Token::get_type() { - std::string spelling; - auto referenced=clang_getCursorReferenced(cx_cursor); - if(!clang_Cursor_isNull(referenced)) { - auto type=clang_getCursorType(referenced); - spelling=clang::to_string(clang_getTypeSpelling(type)); - std::string auto_end=""; - //TODO fix const auto - if((spelling.size()>=4 && spelling.substr(0, 4)=="auto")) { - auto_end=spelling.substr(4); - auto type=clang_getCanonicalType(clang_getCursorType(cx_cursor)); - spelling=clang::to_string(clang_getTypeSpelling(type)); - if(spelling.find(" ")==std::string::npos) - spelling+=auto_end; - } - } - return spelling; -} - -std::string clang::Token::get_brief_comments() { - std::string comment_string; - auto referenced=get_cursor().get_referenced(); - if(referenced) { - comment_string=clang::to_string(clang_Cursor_getBriefCommentText(referenced.cx_cursor)); - } - return comment_string; -} diff --git a/src/Token.h b/src/Token.h index d8f44db..0dd957b 100644 --- a/src/Token.h +++ b/src/Token.h @@ -25,9 +25,6 @@ namespace clang { SourceLocation get_source_location(); SourceRange get_source_range(); clang::Cursor get_cursor() {return clang::Cursor(cx_cursor);} - bool has_type(); - std::string get_type(); - std::string get_brief_comments(); CXTranslationUnit &cx_tu; CXToken& cx_token; diff --git a/src/Tokens.cc b/src/Tokens.cc index f207daa..2b8e603 100644 --- a/src/Tokens.cc +++ b/src/Tokens.cc @@ -24,14 +24,15 @@ clang::Tokens::~Tokens() { //This works across TranslationUnits! However, to get rename refactoring to work, //one have to open all the files that might include a similar token //Similar tokens defined as tokens with equal referenced cursors. -std::vector > clang::Tokens::get_similar_token_offsets(const std::string &usr) { +std::vector > clang::Tokens::get_similar_token_offsets(CursorKind kind, + const std::string &spelling, + const std::string &usr) { std::vector > offsets; for(auto &token: *this) { if(token.get_kind()==clang::Token_Identifier) { auto referenced=token.get_cursor().get_referenced(); - if(referenced && usr==referenced.get_usr()) { + if(referenced && kind==referenced.get_kind() && spelling==token.get_spelling() && usr==referenced.get_usr()) offsets.emplace_back(token.offsets); - } } } return offsets; diff --git a/src/Tokens.h b/src/Tokens.h index 26c007f..a6f0648 100644 --- a/src/Tokens.h +++ b/src/Tokens.h @@ -13,7 +13,9 @@ namespace clang { Tokens(CXTranslationUnit &cx_tu, const SourceRange &range); public: ~Tokens(); - std::vector > get_similar_token_offsets(const std::string &usr); + std::vector > get_similar_token_offsets(CursorKind kind, + const std::string &spelling, + const std::string &usr); std::vector > get_cxx_methods(); private: CXToken *cx_tokens; diff --git a/src/TranslationUnit.cc b/src/TranslationUnit.cc index 098329d..64e3af3 100644 --- a/src/TranslationUnit.cc +++ b/src/TranslationUnit.cc @@ -100,7 +100,21 @@ std::unique_ptr clang::TranslationUnit::get_tokens(unsigned start return std::unique_ptr(new Tokens(cx_tu, range)); } +std::unique_ptr clang::TranslationUnit::get_tokens(unsigned start_line, unsigned start_column, + unsigned end_line, unsigned end_column) { + auto path=clang::to_string(clang_getTranslationUnitSpelling(cx_tu)); + clang::SourceLocation start_location(cx_tu, path, start_line, start_column); + clang::SourceLocation end_location(cx_tu, path, end_line, end_column); + clang::SourceRange range(start_location, end_location); + return std::unique_ptr(new Tokens(cx_tu, range)); +} + clang::Cursor clang::TranslationUnit::get_cursor(std::string path, unsigned offset) { clang::SourceLocation location(cx_tu, path, offset); return Cursor(clang_getCursor(cx_tu, location.cx_location)); } + +clang::Cursor clang::TranslationUnit::get_cursor(std::string path, unsigned line, unsigned column) { + clang::SourceLocation location(cx_tu, path, line, column); + return Cursor(clang_getCursor(cx_tu, location.cx_location)); +} diff --git a/src/TranslationUnit.h b/src/TranslationUnit.h index 7cdd4dd..bd8dc58 100644 --- a/src/TranslationUnit.h +++ b/src/TranslationUnit.h @@ -34,10 +34,17 @@ namespace clang { const std::map &buffers, unsigned flags=DefaultFlags()); - clang::CodeCompleteResults get_code_completions(const std::map &buffers, unsigned line_number, unsigned column); + clang::CodeCompleteResults get_code_completions(const std::map &buffers, + unsigned line_number, unsigned column); + std::vector get_diagnostics(); + std::unique_ptr get_tokens(unsigned start_offset, unsigned end_offset); + std::unique_ptr get_tokens(unsigned start_line, unsigned start_column, + unsigned end_line, unsigned end_column); + clang::Cursor get_cursor(std::string path, unsigned offset); + clang::Cursor get_cursor(std::string path, unsigned line, unsigned column); CXTranslationUnit cx_tu; };