Fix issue with defaulted destructors

This commit is contained in:
Jonathan Müller 2018-12-13 17:28:51 +01:00
commit f66ec833c1
2 changed files with 42 additions and 21 deletions

View file

@ -239,30 +239,29 @@ CXSourceRange get_extent(const CXTranslationUnit& tu, const CXFile& file, const
if (cursor_is_function(kind) || cursor_is_function(clang_getTemplateCursorKind(cur))) if (cursor_is_function(kind) || cursor_is_function(clang_getTemplateCursorKind(cur)))
{ {
// for function definitions: remove the body, we don't care about that if (clang_CXXMethod_isDefaulted(cur) || !clang_isCursorDefinition(cur))
// for function declarations: extend until the semiclon
auto is_definition = false;
// if it has the corresponding children, it's a definition and we can shrink the range
detail::visit_children(cur, [&](const CXCursor& child) {
if (is_definition)
return;
else if (clang_getCursorKind(child) == CXCursor_CompoundStmt
|| clang_getCursorKind(child) == CXCursor_CXXTryStmt
|| clang_getCursorKind(child) == CXCursor_InitListExpr)
{
auto child_extent = clang_getCursorExtent(child);
end = clang_getRangeStart(child_extent);
is_definition = true;
}
});
if (!is_definition && !token_at_is(tu, file, end, ";"))
{ {
// we have a declaration, extend until the semicolon // defaulted or declaration: extend until semicolon
while (!token_at_is(tu, file, end, ";")) while (!token_at_is(tu, file, end, ";"))
end = get_next_location(tu, file, end, 1); end = get_next_location(tu, file, end, 1);
} }
else
{
// declaration: remove body, we don't care about that
auto has_children = false;
detail::visit_children(cur, [&](const CXCursor& child) {
if (has_children)
return;
else if (clang_getCursorKind(child) == CXCursor_CompoundStmt
|| clang_getCursorKind(child) == CXCursor_CXXTryStmt
|| clang_getCursorKind(child) == CXCursor_InitListExpr)
{
auto child_extent = clang_getCursorExtent(child);
end = clang_getRangeStart(child_extent);
has_children = true;
}
});
}
} }
else if (kind == CXCursor_TemplateTypeParameter && token_at_is(tu, file, end, "(")) else if (kind == CXCursor_TemplateTypeParameter && token_at_is(tu, file, end, "("))
{ {

View file

@ -384,6 +384,15 @@ struct d : c
/// virtual d::~d(); /// virtual d::~d();
d::~d() {} d::~d() {}
struct e : c
{
/// virtual ~e() override final;
~e() final;
};
/// virtual e::~e()=default;
e::~e() = default;
)"; )";
auto file = parse({}, "cpp_destructor.cpp", code); auto file = parse({}, "cpp_destructor.cpp", code);
@ -425,8 +434,21 @@ d::~d() {}
REQUIRE(dtor.virtual_info().value() == cpp_virtual_flags::override); REQUIRE(dtor.virtual_info().value() == cpp_virtual_flags::override);
REQUIRE(!dtor.noexcept_condition()); REQUIRE(!dtor.noexcept_condition());
} }
else if (dtor.name() == "~e")
{
REQUIRE(dtor.virtual_info());
if (dtor.is_declaration())
REQUIRE(dtor.virtual_info().value()
== (cpp_virtual_flags::override | cpp_virtual_flags::final));
else
{
REQUIRE(dtor.virtual_info().value() == cpp_virtual_flags::override);
REQUIRE(dtor.body_kind() == cpp_function_defaulted);
}
REQUIRE(!dtor.noexcept_condition());
}
else else
REQUIRE(false); REQUIRE(false);
}); });
REQUIRE(count == 5u); REQUIRE(count == 7u);
} }