diff --git a/src/libclang/function_parser.cpp b/src/libclang/function_parser.cpp index 9ccc0bf..576374f 100644 --- a/src/libclang/function_parser.cpp +++ b/src/libclang/function_parser.cpp @@ -113,7 +113,7 @@ namespace prefix_info result; std::string scope; - while (!prefix_end(stream, name)) + while (!stream.done() && !prefix_end(stream, name)) { if (detail::skip_if(stream, "constexpr")) { @@ -157,6 +157,8 @@ namespace scope.clear(); } } + DEBUG_ASSERT(!stream.done(), detail::parse_error_handler{}, stream.cursor(), + "unable to find end of function prefix"); if (!scope.empty() && scope.back() == ':') result.scope_name = std::move(scope); @@ -592,7 +594,10 @@ std::unique_ptr detail::parse_cpp_constructor(const detail::parse_co DEBUG_ASSERT(clang_getCursorKind(cur) == CXCursor_Constructor || clang_getTemplateCursorKind(cur) == CXCursor_Constructor, detail::assert_handler{}); - auto name = detail::get_cursor_name(cur); + std::string name = detail::get_cursor_name(cur).c_str(); + auto pos = name.find('<'); + if (pos != std::string::npos) + name.erase(pos); detail::tokenizer tokenizer(context.tu, context.file, cur); detail::token_stream stream(tokenizer, cur); diff --git a/test/cpp_member_function.cpp b/test/cpp_member_function.cpp index 35c1cbe..baadec0 100644 --- a/test/cpp_member_function.cpp +++ b/test/cpp_member_function.cpp @@ -203,8 +203,11 @@ struct foo TEST_CASE("cpp_constructor") { - auto code = R"( -// only test constructor specific stuff + // only test constructor specific stuff + const char* code; + SECTION("non-template") + { + code = R"( struct foo { /// foo()noexcept=default; @@ -215,6 +218,22 @@ struct foo constexpr foo(int, char) = delete; }; )"; + } + SECTION("template") + { + code = R"( +template +struct foo +{ + /// foo()noexcept=default; + foo() noexcept = default; + /// explicit foo(int); + explicit foo(int); + /// constexpr foo(int,char)=delete; + constexpr foo(int, char) = delete; +}; +)"; + } cpp_entity_index idx; auto file = parse(idx, "cpp_constructor.cpp", code);