From f66ec833c1942d7f7f0c52b7710be8d494ae11d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Thu, 13 Dec 2018 17:28:51 +0100 Subject: [PATCH] Fix issue with defaulted destructors --- src/libclang/cxtokenizer.cpp | 39 ++++++++++++++++++------------------ test/cpp_member_function.cpp | 24 +++++++++++++++++++++- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/src/libclang/cxtokenizer.cpp b/src/libclang/cxtokenizer.cpp index cd373a0..34ec2be 100644 --- a/src/libclang/cxtokenizer.cpp +++ b/src/libclang/cxtokenizer.cpp @@ -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))) { - // for function definitions: remove the body, we don't care about that - // 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, ";")) + if (clang_CXXMethod_isDefaulted(cur) || !clang_isCursorDefinition(cur)) { - // we have a declaration, extend until the semicolon + // defaulted or declaration: extend until semicolon while (!token_at_is(tu, file, end, ";")) 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, "(")) { diff --git a/test/cpp_member_function.cpp b/test/cpp_member_function.cpp index 84b25d5..c3f9f01 100644 --- a/test/cpp_member_function.cpp +++ b/test/cpp_member_function.cpp @@ -384,6 +384,15 @@ struct d : c /// virtual 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); @@ -425,8 +434,21 @@ d::~d() {} REQUIRE(dtor.virtual_info().value() == cpp_virtual_flags::override); 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 REQUIRE(false); }); - REQUIRE(count == 5u); + REQUIRE(count == 7u); }