Improve function scope parsing
This commit is contained in:
parent
c07f80ccf3
commit
7a9f6fdfac
5 changed files with 126 additions and 66 deletions
|
|
@ -74,7 +74,7 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_friend(const detail::parse_context
|
||||||
}
|
}
|
||||||
else if (clang_isDeclaration(kind))
|
else if (clang_isDeclaration(kind))
|
||||||
{
|
{
|
||||||
entity = parse_entity(context, child);
|
entity = parse_entity(context, child, cur);
|
||||||
if (entity)
|
if (entity)
|
||||||
{
|
{
|
||||||
// steal comment
|
// steal comment
|
||||||
|
|
|
||||||
|
|
@ -85,13 +85,72 @@ namespace
|
||||||
detail::skip_brackets(stream);
|
detail::skip_brackets(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_class(const CXCursor& parent)
|
||||||
|
{
|
||||||
|
auto kind = clang_getCursorKind(parent);
|
||||||
|
return kind == CXCursor_ClassDecl || kind == CXCursor_StructDecl
|
||||||
|
|| kind == CXCursor_UnionDecl || kind == CXCursor_ClassTemplate
|
||||||
|
|| kind == CXCursor_ClassTemplatePartialSpecialization;
|
||||||
|
}
|
||||||
|
|
||||||
|
CXCursor get_definition_scope(const CXCursor& cur, bool is_friend)
|
||||||
|
{
|
||||||
|
auto parent = clang_getCursorLexicalParent(cur);
|
||||||
|
if (is_friend)
|
||||||
|
{
|
||||||
|
// find the lexical parent that isn't a class
|
||||||
|
// as the definition scope is a namespace
|
||||||
|
while (is_class(parent))
|
||||||
|
parent = clang_getCursorSemanticParent(parent);
|
||||||
|
|
||||||
|
DEBUG_ASSERT(clang_getCursorKind(parent) == CXCursor_Namespace
|
||||||
|
|| clang_getCursorKind(parent) == CXCursor_TranslationUnit,
|
||||||
|
detail::parse_error_handler{}, cur,
|
||||||
|
"unable to find definition scope of friend");
|
||||||
|
}
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool equivalent_cursor(const CXCursor& a, const CXCursor& b)
|
||||||
|
{
|
||||||
|
if (clang_getCursorKind(a) == clang_getCursorKind(b)
|
||||||
|
&& clang_getCursorKind(a) == CXCursor_Namespace)
|
||||||
|
return detail::cxstring(clang_getCursorUSR(a))
|
||||||
|
== detail::cxstring(clang_getCursorUSR(b));
|
||||||
|
else
|
||||||
|
return clang_equalCursors(a, b) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
type_safe::optional<cpp_entity_ref> parse_scope(const CXCursor& cur, bool is_friend)
|
||||||
|
{
|
||||||
|
std::string scope;
|
||||||
|
// find the semantic parents we need until we're at the same level of the parent where the definition is
|
||||||
|
// the semantic parents are all the scopes that need to be appended
|
||||||
|
for (auto definition = get_definition_scope(cur, is_friend),
|
||||||
|
parent = clang_getCursorSemanticParent(cur);
|
||||||
|
!equivalent_cursor(definition, parent); parent = clang_getCursorSemanticParent(parent))
|
||||||
|
{
|
||||||
|
DEBUG_ASSERT(!clang_isTranslationUnit(clang_getCursorKind(parent)),
|
||||||
|
detail::parse_error_handler{}, cur,
|
||||||
|
"infinite loop while calculating scope");
|
||||||
|
auto parent_name = detail::cxstring(clang_getCursorDisplayName(parent));
|
||||||
|
scope = parent_name.std_str() + "::" + std::move(scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scope.empty())
|
||||||
|
return type_safe::nullopt;
|
||||||
|
else
|
||||||
|
return cpp_entity_ref(detail::get_entity_id(clang_getCursorSemanticParent(cur)),
|
||||||
|
std::move(scope));
|
||||||
|
}
|
||||||
|
|
||||||
// just the tokens occurring in the prefix
|
// just the tokens occurring in the prefix
|
||||||
struct prefix_info
|
struct prefix_info
|
||||||
{
|
{
|
||||||
type_safe::optional<cpp_entity_ref> semantic_parent;
|
bool is_constexpr = false;
|
||||||
bool is_constexpr = false;
|
bool is_virtual = false;
|
||||||
bool is_virtual = false;
|
bool is_explicit = false;
|
||||||
bool is_explicit = false;
|
bool is_friend = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool prefix_end(detail::token_stream& stream, const char* name, bool is_ctor)
|
bool prefix_end(detail::token_stream& stream, const char* name, bool is_ctor)
|
||||||
|
|
@ -137,25 +196,15 @@ namespace
|
||||||
{
|
{
|
||||||
prefix_info result;
|
prefix_info result;
|
||||||
|
|
||||||
std::string scope;
|
|
||||||
while (!stream.done() && !prefix_end(stream, name, is_ctor))
|
while (!stream.done() && !prefix_end(stream, name, is_ctor))
|
||||||
{
|
{
|
||||||
if (detail::skip_if(stream, "constexpr"))
|
if (detail::skip_if(stream, "constexpr"))
|
||||||
{
|
|
||||||
result.is_constexpr = true;
|
result.is_constexpr = true;
|
||||||
scope.clear();
|
|
||||||
}
|
|
||||||
else if (detail::skip_if(stream, "virtual"))
|
else if (detail::skip_if(stream, "virtual"))
|
||||||
{
|
|
||||||
result.is_virtual = true;
|
result.is_virtual = true;
|
||||||
scope.clear();
|
|
||||||
}
|
|
||||||
else if (detail::skip_if(stream, "explicit"))
|
else if (detail::skip_if(stream, "explicit"))
|
||||||
{
|
|
||||||
result.is_explicit = true;
|
result.is_explicit = true;
|
||||||
scope.clear();
|
else
|
||||||
}
|
|
||||||
else if (!detail::append_scope(stream, scope))
|
|
||||||
stream.bump();
|
stream.bump();
|
||||||
}
|
}
|
||||||
DEBUG_ASSERT(!stream.done(), detail::parse_error_handler{}, stream.cursor(),
|
DEBUG_ASSERT(!stream.done(), detail::parse_error_handler{}, stream.cursor(),
|
||||||
|
|
@ -164,14 +213,6 @@ namespace
|
||||||
{ // function name can be enclosed in parentheses
|
{ // function name can be enclosed in parentheses
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!scope.empty() && scope.back() == ':')
|
|
||||||
{
|
|
||||||
result.semantic_parent =
|
|
||||||
cpp_entity_ref(detail::get_entity_id(
|
|
||||||
clang_getCursorSemanticParent(stream.cursor())),
|
|
||||||
std::move(scope));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -372,7 +413,8 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<cpp_entity> parse_cpp_function_impl(const detail::parse_context& context,
|
std::unique_ptr<cpp_entity> parse_cpp_function_impl(const detail::parse_context& context,
|
||||||
const CXCursor& cur, bool is_static)
|
const CXCursor& cur, bool is_static,
|
||||||
|
bool is_friend)
|
||||||
{
|
{
|
||||||
auto name = detail::get_cursor_name(cur);
|
auto name = detail::get_cursor_name(cur);
|
||||||
|
|
||||||
|
|
@ -405,21 +447,21 @@ namespace
|
||||||
|
|
||||||
if (is_templated_cursor(cur))
|
if (is_templated_cursor(cur))
|
||||||
return builder.finish(detail::get_entity_id(cur), suffix.body_kind,
|
return builder.finish(detail::get_entity_id(cur), suffix.body_kind,
|
||||||
std::move(prefix.semantic_parent));
|
parse_scope(cur, is_friend));
|
||||||
else
|
else
|
||||||
return builder.finish(*context.idx, detail::get_entity_id(cur), suffix.body_kind,
|
return builder.finish(*context.idx, detail::get_entity_id(cur), suffix.body_kind,
|
||||||
std::move(prefix.semantic_parent));
|
parse_scope(cur, is_friend));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<cpp_entity> detail::parse_cpp_function(const detail::parse_context& context,
|
std::unique_ptr<cpp_entity> detail::parse_cpp_function(const detail::parse_context& context,
|
||||||
const CXCursor& cur)
|
const CXCursor& cur, bool is_friend)
|
||||||
{
|
{
|
||||||
DEBUG_ASSERT(clang_getCursorKind(cur) == CXCursor_FunctionDecl
|
DEBUG_ASSERT(clang_getCursorKind(cur) == CXCursor_FunctionDecl
|
||||||
|| clang_getTemplateCursorKind(cur) == CXCursor_FunctionDecl,
|
|| clang_getTemplateCursorKind(cur) == CXCursor_FunctionDecl,
|
||||||
detail::assert_handler{});
|
detail::assert_handler{});
|
||||||
type_safe::optional<cpp_entity_ref> semantic_parent;
|
type_safe::optional<cpp_entity_ref> semantic_parent;
|
||||||
return parse_cpp_function_impl(context, cur, false);
|
return parse_cpp_function_impl(context, cur, false, is_friend);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<cpp_entity> detail::try_parse_static_cpp_function(
|
std::unique_ptr<cpp_entity> detail::try_parse_static_cpp_function(
|
||||||
|
|
@ -429,7 +471,7 @@ std::unique_ptr<cpp_entity> detail::try_parse_static_cpp_function(
|
||||||
|| clang_getTemplateCursorKind(cur) == CXCursor_CXXMethod,
|
|| clang_getTemplateCursorKind(cur) == CXCursor_CXXMethod,
|
||||||
detail::assert_handler{});
|
detail::assert_handler{});
|
||||||
if (clang_CXXMethod_isStatic(cur))
|
if (clang_CXXMethod_isStatic(cur))
|
||||||
return parse_cpp_function_impl(context, cur, true);
|
return parse_cpp_function_impl(context, cur, true, false);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -521,7 +563,7 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<cpp_entity> detail::parse_cpp_member_function(const detail::parse_context& context,
|
std::unique_ptr<cpp_entity> detail::parse_cpp_member_function(const detail::parse_context& context,
|
||||||
const CXCursor& cur)
|
const CXCursor& cur, bool is_friend)
|
||||||
{
|
{
|
||||||
DEBUG_ASSERT(clang_getCursorKind(cur) == CXCursor_CXXMethod
|
DEBUG_ASSERT(clang_getCursorKind(cur) == CXCursor_CXXMethod
|
||||||
|| clang_getTemplateCursorKind(cur) == CXCursor_CXXMethod,
|
|| clang_getTemplateCursorKind(cur) == CXCursor_CXXMethod,
|
||||||
|
|
@ -548,11 +590,11 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_member_function(const detail::pars
|
||||||
|
|
||||||
skip_parameters(stream);
|
skip_parameters(stream);
|
||||||
return handle_suffix(context, cur, builder, stream, prefix.is_virtual,
|
return handle_suffix(context, cur, builder, stream, prefix.is_virtual,
|
||||||
std::move(prefix.semantic_parent));
|
parse_scope(cur, is_friend));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<cpp_entity> detail::parse_cpp_conversion_op(const detail::parse_context& context,
|
std::unique_ptr<cpp_entity> detail::parse_cpp_conversion_op(const detail::parse_context& context,
|
||||||
const CXCursor& cur)
|
const CXCursor& cur, bool is_friend)
|
||||||
{
|
{
|
||||||
DEBUG_ASSERT(clang_getCursorKind(cur) == CXCursor_ConversionFunction
|
DEBUG_ASSERT(clang_getCursorKind(cur) == CXCursor_ConversionFunction
|
||||||
|| clang_getTemplateCursorKind(cur) == CXCursor_ConversionFunction,
|
|| clang_getTemplateCursorKind(cur) == CXCursor_ConversionFunction,
|
||||||
|
|
@ -609,11 +651,11 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_conversion_op(const detail::parse_
|
||||||
builder.is_constexpr();
|
builder.is_constexpr();
|
||||||
|
|
||||||
return handle_suffix(context, cur, builder, stream, prefix.is_virtual,
|
return handle_suffix(context, cur, builder, stream, prefix.is_virtual,
|
||||||
std::move(prefix.semantic_parent));
|
parse_scope(cur, is_friend));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<cpp_entity> detail::parse_cpp_constructor(const detail::parse_context& context,
|
std::unique_ptr<cpp_entity> detail::parse_cpp_constructor(const detail::parse_context& context,
|
||||||
const CXCursor& cur)
|
const CXCursor& cur, bool is_friend)
|
||||||
{
|
{
|
||||||
DEBUG_ASSERT(clang_getCursorKind(cur) == CXCursor_Constructor
|
DEBUG_ASSERT(clang_getCursorKind(cur) == CXCursor_Constructor
|
||||||
|| clang_getTemplateCursorKind(cur) == CXCursor_Constructor,
|
|| clang_getTemplateCursorKind(cur) == CXCursor_Constructor,
|
||||||
|
|
@ -648,14 +690,14 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_constructor(const detail::parse_co
|
||||||
|
|
||||||
if (is_templated_cursor(cur))
|
if (is_templated_cursor(cur))
|
||||||
return builder.finish(detail::get_entity_id(cur), suffix.body_kind,
|
return builder.finish(detail::get_entity_id(cur), suffix.body_kind,
|
||||||
std::move(prefix.semantic_parent));
|
parse_scope(cur, is_friend));
|
||||||
else
|
else
|
||||||
return builder.finish(*context.idx, detail::get_entity_id(cur), suffix.body_kind,
|
return builder.finish(*context.idx, detail::get_entity_id(cur), suffix.body_kind,
|
||||||
std::move(prefix.semantic_parent));
|
parse_scope(cur, is_friend));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<cpp_entity> detail::parse_cpp_destructor(const detail::parse_context& context,
|
std::unique_ptr<cpp_entity> detail::parse_cpp_destructor(const detail::parse_context& context,
|
||||||
const CXCursor& cur)
|
const CXCursor& cur, bool is_friend)
|
||||||
{
|
{
|
||||||
DEBUG_ASSERT(clang_getCursorKind(cur) == CXCursor_Destructor, detail::assert_handler{});
|
DEBUG_ASSERT(clang_getCursorKind(cur) == CXCursor_Destructor, detail::assert_handler{});
|
||||||
|
|
||||||
|
|
@ -672,5 +714,5 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_destructor(const detail::parse_con
|
||||||
detail::skip(stream, "(");
|
detail::skip(stream, "(");
|
||||||
detail::skip(stream, ")");
|
detail::skip(stream, ")");
|
||||||
return handle_suffix(context, cur, builder, stream, prefix_info.is_virtual,
|
return handle_suffix(context, cur, builder, stream, prefix_info.is_virtual,
|
||||||
std::move(prefix_info.semantic_parent));
|
parse_scope(cur, is_friend));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,19 @@ void detail::comment_context::match(cpp_entity& e, unsigned line) const
|
||||||
e.set_comment(std::move(cur_++->comment));
|
e.set_comment(std::move(cur_++->comment));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
bool is_friend(const CXCursor& parent_cur)
|
||||||
|
{
|
||||||
|
#if CPPAST_CINDEX_HAS_FRIEND
|
||||||
|
return clang_getCursorKind(parent_cur) == CXCursor_FriendDecl;
|
||||||
|
#else
|
||||||
|
(void)parent_cur;
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<cpp_entity> detail::parse_entity(const detail::parse_context& context,
|
std::unique_ptr<cpp_entity> detail::parse_entity(const detail::parse_context& context,
|
||||||
const CXCursor& cur,
|
const CXCursor& cur,
|
||||||
const CXCursor& parent_cur) try
|
const CXCursor& parent_cur) try
|
||||||
|
|
@ -145,25 +158,29 @@ std::unique_ptr<cpp_entity> detail::parse_entity(const detail::parse_context& co
|
||||||
return parse_cpp_member_variable(context, cur);
|
return parse_cpp_member_variable(context, cur);
|
||||||
|
|
||||||
case CXCursor_FunctionDecl:
|
case CXCursor_FunctionDecl:
|
||||||
if (auto tfunc = try_parse_cpp_function_template_specialization(context, cur))
|
if (auto tfunc =
|
||||||
|
try_parse_cpp_function_template_specialization(context, cur, is_friend(parent_cur)))
|
||||||
return tfunc;
|
return tfunc;
|
||||||
return parse_cpp_function(context, cur);
|
return parse_cpp_function(context, cur, is_friend(parent_cur));
|
||||||
case CXCursor_CXXMethod:
|
case CXCursor_CXXMethod:
|
||||||
if (auto tfunc = try_parse_cpp_function_template_specialization(context, cur))
|
if (auto tfunc =
|
||||||
|
try_parse_cpp_function_template_specialization(context, cur, is_friend(parent_cur)))
|
||||||
return tfunc;
|
return tfunc;
|
||||||
else if (auto func = try_parse_static_cpp_function(context, cur))
|
else if (auto func = try_parse_static_cpp_function(context, cur))
|
||||||
return func;
|
return func;
|
||||||
return parse_cpp_member_function(context, cur);
|
return parse_cpp_member_function(context, cur, is_friend(parent_cur));
|
||||||
case CXCursor_ConversionFunction:
|
case CXCursor_ConversionFunction:
|
||||||
if (auto tfunc = try_parse_cpp_function_template_specialization(context, cur))
|
if (auto tfunc =
|
||||||
|
try_parse_cpp_function_template_specialization(context, cur, is_friend(parent_cur)))
|
||||||
return tfunc;
|
return tfunc;
|
||||||
return parse_cpp_conversion_op(context, cur);
|
return parse_cpp_conversion_op(context, cur, is_friend(parent_cur));
|
||||||
case CXCursor_Constructor:
|
case CXCursor_Constructor:
|
||||||
if (auto tfunc = try_parse_cpp_function_template_specialization(context, cur))
|
if (auto tfunc =
|
||||||
|
try_parse_cpp_function_template_specialization(context, cur, is_friend(parent_cur)))
|
||||||
return tfunc;
|
return tfunc;
|
||||||
return parse_cpp_constructor(context, cur);
|
return parse_cpp_constructor(context, cur, is_friend(parent_cur));
|
||||||
case CXCursor_Destructor:
|
case CXCursor_Destructor:
|
||||||
return parse_cpp_destructor(context, cur);
|
return parse_cpp_destructor(context, cur, is_friend(parent_cur));
|
||||||
|
|
||||||
#if CPPAST_CINDEX_HAS_FRIEND
|
#if CPPAST_CINDEX_HAS_FRIEND
|
||||||
case CXCursor_FriendDecl:
|
case CXCursor_FriendDecl:
|
||||||
|
|
@ -173,7 +190,7 @@ std::unique_ptr<cpp_entity> detail::parse_entity(const detail::parse_context& co
|
||||||
case CXCursor_TypeAliasTemplateDecl:
|
case CXCursor_TypeAliasTemplateDecl:
|
||||||
return parse_cpp_alias_template(context, cur);
|
return parse_cpp_alias_template(context, cur);
|
||||||
case CXCursor_FunctionTemplate:
|
case CXCursor_FunctionTemplate:
|
||||||
return parse_cpp_function_template(context, cur);
|
return parse_cpp_function_template(context, cur, is_friend(parent_cur));
|
||||||
case CXCursor_ClassTemplate:
|
case CXCursor_ClassTemplate:
|
||||||
return parse_cpp_class_template(context, cur);
|
return parse_cpp_class_template(context, cur);
|
||||||
case CXCursor_ClassTemplatePartialSpecialization:
|
case CXCursor_ClassTemplatePartialSpecialization:
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ namespace cppast
|
||||||
|
|
||||||
// on all function cursors except on destructor
|
// on all function cursors except on destructor
|
||||||
std::unique_ptr<cpp_entity> try_parse_cpp_function_template_specialization(
|
std::unique_ptr<cpp_entity> try_parse_cpp_function_template_specialization(
|
||||||
const parse_context& context, const CXCursor& cur);
|
const parse_context& context, const CXCursor& cur, bool is_friend);
|
||||||
|
|
||||||
// on class cursors
|
// on class cursors
|
||||||
std::unique_ptr<cpp_entity> try_parse_full_cpp_class_template_specialization(
|
std::unique_ptr<cpp_entity> try_parse_full_cpp_class_template_specialization(
|
||||||
|
|
@ -134,15 +134,15 @@ namespace cppast
|
||||||
const CXCursor& cur);
|
const CXCursor& cur);
|
||||||
|
|
||||||
std::unique_ptr<cpp_entity> parse_cpp_function(const parse_context& context,
|
std::unique_ptr<cpp_entity> parse_cpp_function(const parse_context& context,
|
||||||
const CXCursor& cur);
|
const CXCursor& cur, bool is_friend);
|
||||||
std::unique_ptr<cpp_entity> parse_cpp_member_function(const parse_context& context,
|
std::unique_ptr<cpp_entity> parse_cpp_member_function(const parse_context& context,
|
||||||
const CXCursor& cur);
|
const CXCursor& cur, bool is_friend);
|
||||||
std::unique_ptr<cpp_entity> parse_cpp_conversion_op(const parse_context& context,
|
std::unique_ptr<cpp_entity> parse_cpp_conversion_op(const parse_context& context,
|
||||||
const CXCursor& cur);
|
const CXCursor& cur, bool is_friend);
|
||||||
std::unique_ptr<cpp_entity> parse_cpp_constructor(const parse_context& context,
|
std::unique_ptr<cpp_entity> parse_cpp_constructor(const parse_context& context,
|
||||||
const CXCursor& cur);
|
const CXCursor& cur, bool is_friend);
|
||||||
std::unique_ptr<cpp_entity> parse_cpp_destructor(const parse_context& context,
|
std::unique_ptr<cpp_entity> parse_cpp_destructor(const parse_context& context,
|
||||||
const CXCursor& cur);
|
const CXCursor& cur, bool is_friend);
|
||||||
|
|
||||||
std::unique_ptr<cpp_entity> parse_cpp_friend(const parse_context& context,
|
std::unique_ptr<cpp_entity> parse_cpp_friend(const parse_context& context,
|
||||||
const CXCursor& cur);
|
const CXCursor& cur);
|
||||||
|
|
@ -150,7 +150,8 @@ namespace cppast
|
||||||
std::unique_ptr<cpp_entity> parse_cpp_alias_template(const parse_context& context,
|
std::unique_ptr<cpp_entity> parse_cpp_alias_template(const parse_context& context,
|
||||||
const CXCursor& cur);
|
const CXCursor& cur);
|
||||||
std::unique_ptr<cpp_entity> parse_cpp_function_template(const parse_context& context,
|
std::unique_ptr<cpp_entity> parse_cpp_function_template(const parse_context& context,
|
||||||
const CXCursor& cur);
|
const CXCursor& cur,
|
||||||
|
bool is_friend);
|
||||||
std::unique_ptr<cpp_entity> parse_cpp_class_template(const parse_context& context,
|
std::unique_ptr<cpp_entity> parse_cpp_class_template(const parse_context& context,
|
||||||
const CXCursor& cur);
|
const CXCursor& cur);
|
||||||
std::unique_ptr<cpp_entity> parse_cpp_class_template_specialization(
|
std::unique_ptr<cpp_entity> parse_cpp_class_template_specialization(
|
||||||
|
|
|
||||||
|
|
@ -216,7 +216,7 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_alias_template(const detail::parse
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<cpp_entity> detail::parse_cpp_function_template(
|
std::unique_ptr<cpp_entity> detail::parse_cpp_function_template(
|
||||||
const detail::parse_context& context, const CXCursor& cur)
|
const detail::parse_context& context, const CXCursor& cur, bool is_friend)
|
||||||
{
|
{
|
||||||
DEBUG_ASSERT(clang_getCursorKind(cur) == CXCursor_FunctionTemplate, detail::assert_handler{});
|
DEBUG_ASSERT(clang_getCursorKind(cur) == CXCursor_FunctionTemplate, detail::assert_handler{});
|
||||||
|
|
||||||
|
|
@ -224,19 +224,19 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_function_template(
|
||||||
switch (clang_getTemplateCursorKind(cur))
|
switch (clang_getTemplateCursorKind(cur))
|
||||||
{
|
{
|
||||||
case CXCursor_FunctionDecl:
|
case CXCursor_FunctionDecl:
|
||||||
func = detail::parse_cpp_function(context, cur);
|
func = detail::parse_cpp_function(context, cur, is_friend);
|
||||||
break;
|
break;
|
||||||
case CXCursor_CXXMethod:
|
case CXCursor_CXXMethod:
|
||||||
if (auto sfunc = detail::try_parse_static_cpp_function(context, cur))
|
if (auto sfunc = detail::try_parse_static_cpp_function(context, cur))
|
||||||
func = std::move(sfunc);
|
func = std::move(sfunc);
|
||||||
else
|
else
|
||||||
func = detail::parse_cpp_member_function(context, cur);
|
func = detail::parse_cpp_member_function(context, cur, is_friend);
|
||||||
break;
|
break;
|
||||||
case CXCursor_ConversionFunction:
|
case CXCursor_ConversionFunction:
|
||||||
func = detail::parse_cpp_conversion_op(context, cur);
|
func = detail::parse_cpp_conversion_op(context, cur, is_friend);
|
||||||
break;
|
break;
|
||||||
case CXCursor_Constructor:
|
case CXCursor_Constructor:
|
||||||
func = detail::parse_cpp_constructor(context, cur);
|
func = detail::parse_cpp_constructor(context, cur, is_friend);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -284,7 +284,7 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<cpp_entity> detail::try_parse_cpp_function_template_specialization(
|
std::unique_ptr<cpp_entity> detail::try_parse_cpp_function_template_specialization(
|
||||||
const detail::parse_context& context, const CXCursor& cur)
|
const detail::parse_context& context, const CXCursor& cur, bool is_friend)
|
||||||
{
|
{
|
||||||
auto templ = clang_getSpecializedCursorTemplate(cur);
|
auto templ = clang_getSpecializedCursorTemplate(cur);
|
||||||
if (clang_Cursor_isNull(templ))
|
if (clang_Cursor_isNull(templ))
|
||||||
|
|
@ -294,19 +294,19 @@ std::unique_ptr<cpp_entity> detail::try_parse_cpp_function_template_specializati
|
||||||
switch (clang_getCursorKind(cur))
|
switch (clang_getCursorKind(cur))
|
||||||
{
|
{
|
||||||
case CXCursor_FunctionDecl:
|
case CXCursor_FunctionDecl:
|
||||||
func = detail::parse_cpp_function(context, cur);
|
func = detail::parse_cpp_function(context, cur, is_friend);
|
||||||
break;
|
break;
|
||||||
case CXCursor_CXXMethod:
|
case CXCursor_CXXMethod:
|
||||||
if (auto sfunc = detail::try_parse_static_cpp_function(context, cur))
|
if (auto sfunc = detail::try_parse_static_cpp_function(context, cur))
|
||||||
func = std::move(sfunc);
|
func = std::move(sfunc);
|
||||||
else
|
else
|
||||||
func = detail::parse_cpp_member_function(context, cur);
|
func = detail::parse_cpp_member_function(context, cur, is_friend);
|
||||||
break;
|
break;
|
||||||
case CXCursor_ConversionFunction:
|
case CXCursor_ConversionFunction:
|
||||||
func = detail::parse_cpp_conversion_op(context, cur);
|
func = detail::parse_cpp_conversion_op(context, cur, is_friend);
|
||||||
break;
|
break;
|
||||||
case CXCursor_Constructor:
|
case CXCursor_Constructor:
|
||||||
func = detail::parse_cpp_constructor(context, cur);
|
func = detail::parse_cpp_constructor(context, cur, is_friend);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue