Browse Source

Added workaround for libclang crash when looking for definitions of completion items

pipelines/235045657
eidheim 5 years ago
parent
commit
e21dd3681d
  1. 20
      src/source_clang.cpp

20
src/source_clang.cpp

@ -1335,9 +1335,10 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
auto implementation_locations = [this](const Identifier &identifier) { auto implementation_locations = [this](const Identifier &identifier) {
std::vector<Offset> offsets; std::vector<Offset> offsets;
if(identifier) { if(identifier) {
wait_parsing(); if(parsed) {
wait_parsing(); // Wait for other views to finish parsing
//First, look for a definition cursor that is equal // First, look for a definition cursor that is equal
auto identifier_usr = identifier.cursor.get_usr(); auto identifier_usr = identifier.cursor.get_usr();
for(auto &view : views) { for(auto &view : views) {
if(auto clang_view = dynamic_cast<Source::ClangView *>(view)) { if(auto clang_view = dynamic_cast<Source::ClangView *>(view)) {
@ -1347,10 +1348,8 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
if((cursor_kind == clangmm::Cursor::Kind::FunctionDecl || cursor_kind == clangmm::Cursor::Kind::CXXMethod || if((cursor_kind == clangmm::Cursor::Kind::FunctionDecl || cursor_kind == clangmm::Cursor::Kind::CXXMethod ||
cursor_kind == clangmm::Cursor::Kind::Constructor || cursor_kind == clangmm::Cursor::Kind::Destructor || cursor_kind == clangmm::Cursor::Kind::Constructor || cursor_kind == clangmm::Cursor::Kind::Destructor ||
cursor_kind == clangmm::Cursor::Kind::FunctionTemplate || cursor_kind == clangmm::Cursor::Kind::ConversionFunction) && cursor_kind == clangmm::Cursor::Kind::FunctionTemplate || cursor_kind == clangmm::Cursor::Kind::ConversionFunction) &&
token.is_identifier()) { identifier.kind == cursor_kind && token.is_identifier() && clang_isCursorDefinition(cursor.cx_cursor) &&
auto token_spelling = token.get_spelling(); identifier.spelling == token.get_spelling() && identifier_usr == cursor.get_usr()) {
if(identifier.kind == cursor.get_kind() && identifier.spelling == token_spelling && identifier_usr == cursor.get_usr()) {
if(clang_isCursorDefinition(cursor.cx_cursor)) {
Offset offset; Offset offset;
auto location = cursor.get_source_location(); auto location = cursor.get_source_location();
auto clang_offset = location.get_offset(); auto clang_offset = location.get_offset();
@ -1362,12 +1361,11 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
} }
} }
} }
}
}
if(!offsets.empty()) if(!offsets.empty())
return offsets; return offsets;
}
//If no implementation was found, try using clang_getCursorDefinition // If no implementation was found, try using clang_getCursorDefinition
auto definition = identifier.cursor.get_definition(); auto definition = identifier.cursor.get_definition();
if(definition) { if(definition) {
auto location = definition.get_source_location(); auto location = definition.get_source_location();
@ -1380,7 +1378,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
return offsets; return offsets;
} }
//If no implementation was found, use declaration if it is a function template // If no implementation was found, use declaration if it is a function template
auto canonical = identifier.cursor.get_canonical(); auto canonical = identifier.cursor.get_canonical();
auto cursor = clang_tu->get_cursor(canonical.get_source_location()); auto cursor = clang_tu->get_cursor(canonical.get_source_location());
if(cursor && cursor.get_kind() == clangmm::Cursor::Kind::FunctionTemplate) { if(cursor && cursor.get_kind() == clangmm::Cursor::Kind::FunctionTemplate) {
@ -1394,7 +1392,7 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
return offsets; return offsets;
} }
//If no implementation was found, try using Ctags // If no implementation was found, try using Ctags
auto name = identifier.cursor.get_spelling(); auto name = identifier.cursor.get_spelling();
auto parent = identifier.cursor.get_semantic_parent(); auto parent = identifier.cursor.get_semantic_parent();
while(parent && parent.get_kind() != clangmm::Cursor::Kind::TranslationUnit) { while(parent && parent.get_kind() != clangmm::Cursor::Kind::TranslationUnit) {

Loading…
Cancel
Save