From e9e9a3bbc5641f470b9e9683beb29da1a7b3feae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Fri, 31 Mar 2017 15:20:41 +0200 Subject: [PATCH] Fix issue with functions returning functions --- src/libclang/function_parser.cpp | 47 +++++++++++++++++++++++--------- test/code_generator.cpp | 4 +-- test/test_parser.hpp | 4 +-- 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/libclang/function_parser.cpp b/src/libclang/function_parser.cpp index 684f603..545d2e4 100644 --- a/src/libclang/function_parser.cpp +++ b/src/libclang/function_parser.cpp @@ -31,20 +31,41 @@ namespace template void add_parameters(const detail::parse_context& context, Builder& builder, const CXCursor& cur) { - detail::visit_children(cur, [&](const CXCursor& child) { - if (clang_getCursorKind(child) != CXCursor_ParmDecl) - return; + if (clang_getCursorKind(cur) == CXCursor_FunctionTemplate) + { + // clang_Cursor_getNumArguments() doesn't work here + // (of course it doesn't...) + detail::visit_children(cur, [&](const CXCursor& child) { + if (clang_getCursorKind(child) != CXCursor_ParmDecl) + return; - try - { - auto parameter = parse_parameter(context, child); - builder.add_parameter(std::move(parameter)); - } - catch (detail::parse_error& ex) - { - context.logger->log("libclang parser", ex.get_diagnostic()); - } - }); + try + { + auto parameter = parse_parameter(context, child); + builder.add_parameter(std::move(parameter)); + } + catch (detail::parse_error& ex) + { + context.logger->log("libclang parser", ex.get_diagnostic()); + } + }); + } + else + { + auto no = clang_Cursor_getNumArguments(cur); + DEBUG_ASSERT(no != -1, detail::parse_error_handler{}, cur, + "unexpected number of arguments"); + for (auto i = 0; i != no; ++i) + try + { + auto parameter = parse_parameter(context, clang_Cursor_getArgument(cur, i)); + builder.add_parameter(std::move(parameter)); + } + catch (detail::parse_error& ex) + { + context.logger->log("libclang parser", ex.get_diagnostic()); + } + } } bool is_templated_cursor(const CXCursor& cur) diff --git a/test/code_generator.cpp b/test/code_generator.cpp index 5c83b80..389bb25 100644 --- a/test/code_generator.cpp +++ b/test/code_generator.cpp @@ -15,13 +15,13 @@ TEST_CASE("code_generator") struct foo{ int a; - auto func(int)->int(*)[]; + auto func(int)->int(*(*)(int))[42]; private: int const b=42; }; -int(*(foo::* mptr)(int))[]; +int(*(*(foo::* mptr)(int))(int))[42]; enum class bar :int{ diff --git a/test/test_parser.hpp b/test/test_parser.hpp index 3b66faf..6ba7073 100644 --- a/test/test_parser.hpp +++ b/test/test_parser.hpp @@ -32,8 +32,8 @@ inline std::unique_ptr parse(const cppast::cpp_entity_index& i libclang_compile_config config; config.set_flags(cpp_standard::cpp_latest); - static stderr_diagnostic_logger logger; - libclang_parser p(type_safe::ref(logger)); + stderr_diagnostic_logger logger; + libclang_parser p(type_safe::ref(logger)); auto result = p.parse(idx, name, config); REQUIRE(!logger.error_logged());