From 43e50599e730a8c83948d807e58d3b97a51b7faa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Thu, 15 Jun 2017 20:31:31 +0200 Subject: [PATCH] Make using declaration parser more robust --- src/libclang/namespace_parser.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/libclang/namespace_parser.cpp b/src/libclang/namespace_parser.cpp index 77f4615..f3b8797 100644 --- a/src/libclang/namespace_parser.cpp +++ b/src/libclang/namespace_parser.cpp @@ -5,6 +5,7 @@ #include "parse_functions.hpp" #include +#include #include "libclang_visitor.hpp" @@ -127,13 +128,14 @@ std::unique_ptr detail::parse_cpp_using_directive(const detail::pars namespace { - std::vector parse_entity_target_cursor(const CXCursor& cur) + cpp_entity_ref parse_entity_target_cursor(const CXCursor& cur, std::string name) { - std::vector result; + type_safe::deferred_construction result; detail::visit_children(cur, [&](const CXCursor& child) { - if (!result.empty()) + if (result) return; + switch (clang_getCursorKind(child)) { case CXCursor_TypeRef: @@ -143,17 +145,21 @@ namespace case CXCursor_DeclRefExpr: { auto referenced = clang_getCursorReferenced(child); - result.push_back(detail::get_entity_id(referenced)); + result = cpp_entity_ref(detail::get_entity_id(referenced), + std::move(name)); break; } case CXCursor_OverloadedDeclRef: { auto size = clang_getNumOverloadedDecls(child); - DEBUG_ASSERT(size >= 1u, detail::assert_handler{}); + DEBUG_ASSERT(size >= 1u, detail::parse_error_handler{}, cur, + "no target for using declaration"); + std::vector ids; for (auto i = 0u; i != size; ++i) - result.push_back(detail::get_entity_id( + ids.push_back(detail::get_entity_id( clang_getOverloadedDecl(child, i))); + result = cpp_entity_ref(std::move(ids), std::move(name)); break; } @@ -167,7 +173,7 @@ namespace }, true); - return result; + return result.value(); } } @@ -187,7 +193,7 @@ std::unique_ptr detail::parse_cpp_using_declaration( while (!stream.done() && !detail::skip_if(stream, ";")) target_name += stream.get().c_str(); - auto target = cpp_entity_ref(parse_entity_target_cursor(cur), std::move(target_name)); + auto target = parse_entity_target_cursor(cur, std::move(target_name)); auto result = cpp_using_declaration::build(std::move(target)); context.comments.match(*result, cur); return std::move(result);