Add and parse cpp_friend
Only works in clang>=4.
This commit is contained in:
parent
9c46c96820
commit
c3d1d97892
18 changed files with 629 additions and 92 deletions
|
|
@ -6,43 +6,44 @@ set(detail_header
|
|||
../include/cppast/detail/assert.hpp
|
||||
../include/cppast/detail/intrusive_list.hpp)
|
||||
set(header
|
||||
../include/cppast/code_generator.hpp
|
||||
../include/cppast/compile_config.hpp
|
||||
../include/cppast/cpp_alias_template.hpp
|
||||
../include/cppast/cpp_array_type.hpp
|
||||
../include/cppast/cpp_class.hpp
|
||||
../include/cppast/cpp_class_template.hpp
|
||||
../include/cppast/cpp_decltype_type.hpp
|
||||
../include/cppast/cpp_entity.hpp
|
||||
../include/cppast/cpp_entity.hpp
|
||||
../include/cppast/cpp_entity_container.hpp
|
||||
../include/cppast/cpp_entity_index.hpp
|
||||
../include/cppast/cpp_entity_kind.hpp
|
||||
../include/cppast/cpp_entity_ref.hpp
|
||||
../include/cppast/cpp_enum.hpp
|
||||
../include/cppast/cpp_expression.hpp
|
||||
../include/cppast/cpp_file.hpp
|
||||
../include/cppast/cpp_forward_declarable.hpp
|
||||
../include/cppast/cpp_function.hpp
|
||||
../include/cppast/cpp_function_template.hpp
|
||||
../include/cppast/cpp_function_type.hpp
|
||||
../include/cppast/cpp_language_linkage.hpp
|
||||
../include/cppast/cpp_member_function.hpp
|
||||
../include/cppast/cpp_member_variable.hpp
|
||||
../include/cppast/cpp_namespace.hpp
|
||||
../include/cppast/cpp_preprocessor.hpp
|
||||
../include/cppast/cpp_storage_class_specifiers.hpp
|
||||
../include/cppast/cpp_template.hpp
|
||||
../include/cppast/cpp_template_parameter.hpp
|
||||
../include/cppast/cpp_type.hpp
|
||||
../include/cppast/cpp_type_alias.hpp
|
||||
../include/cppast/cpp_variable.hpp
|
||||
../include/cppast/cpp_variable_base.hpp
|
||||
../include/cppast/cpp_variable_template.hpp
|
||||
../include/cppast/diagnostic.hpp
|
||||
../include/cppast/libclang_parser.hpp
|
||||
../include/cppast/parser.hpp
|
||||
../include/cppast/visitor.hpp)
|
||||
../include/cppast/code_generator.hpp
|
||||
../include/cppast/compile_config.hpp
|
||||
../include/cppast/cpp_alias_template.hpp
|
||||
../include/cppast/cpp_array_type.hpp
|
||||
../include/cppast/cpp_class.hpp
|
||||
../include/cppast/cpp_class_template.hpp
|
||||
../include/cppast/cpp_decltype_type.hpp
|
||||
../include/cppast/cpp_entity.hpp
|
||||
../include/cppast/cpp_entity.hpp
|
||||
../include/cppast/cpp_entity_container.hpp
|
||||
../include/cppast/cpp_entity_index.hpp
|
||||
../include/cppast/cpp_entity_kind.hpp
|
||||
../include/cppast/cpp_entity_ref.hpp
|
||||
../include/cppast/cpp_enum.hpp
|
||||
../include/cppast/cpp_expression.hpp
|
||||
../include/cppast/cpp_file.hpp
|
||||
../include/cppast/cpp_forward_declarable.hpp
|
||||
../include/cppast/cpp_friend.hpp
|
||||
../include/cppast/cpp_function.hpp
|
||||
../include/cppast/cpp_function_template.hpp
|
||||
../include/cppast/cpp_function_type.hpp
|
||||
../include/cppast/cpp_language_linkage.hpp
|
||||
../include/cppast/cpp_member_function.hpp
|
||||
../include/cppast/cpp_member_variable.hpp
|
||||
../include/cppast/cpp_namespace.hpp
|
||||
../include/cppast/cpp_preprocessor.hpp
|
||||
../include/cppast/cpp_storage_class_specifiers.hpp
|
||||
../include/cppast/cpp_template.hpp
|
||||
../include/cppast/cpp_template_parameter.hpp
|
||||
../include/cppast/cpp_type.hpp
|
||||
../include/cppast/cpp_type_alias.hpp
|
||||
../include/cppast/cpp_variable.hpp
|
||||
../include/cppast/cpp_variable_base.hpp
|
||||
../include/cppast/cpp_variable_template.hpp
|
||||
../include/cppast/diagnostic.hpp
|
||||
../include/cppast/libclang_parser.hpp
|
||||
../include/cppast/parser.hpp
|
||||
../include/cppast/visitor.hpp)
|
||||
set(source
|
||||
code_generator.cpp
|
||||
cpp_alias_template.cpp
|
||||
|
|
@ -54,6 +55,7 @@ set(source
|
|||
cpp_enum.cpp
|
||||
cpp_expression.cpp
|
||||
cpp_file.cpp
|
||||
cpp_friend.cpp
|
||||
cpp_function.cpp
|
||||
cpp_function_template.cpp
|
||||
cpp_language_linkage.cpp
|
||||
|
|
@ -74,6 +76,7 @@ set(libclang_source
|
|||
libclang/debug_helper.hpp
|
||||
libclang/enum_parser.cpp
|
||||
libclang/expression_parser.cpp
|
||||
libclang/friend_parser.cpp
|
||||
libclang/function_parser.cpp
|
||||
libclang/language_linkage_parser.cpp
|
||||
libclang/libclang_parser.cpp
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <cppast/cpp_entity_kind.hpp>
|
||||
#include <cppast/cpp_enum.hpp>
|
||||
#include <cppast/cpp_file.hpp>
|
||||
#include <cppast/cpp_friend.hpp>
|
||||
#include <cppast/cpp_function.hpp>
|
||||
#include <cppast/cpp_function_template.hpp>
|
||||
#include <cppast/cpp_language_linkage.hpp>
|
||||
|
|
@ -279,6 +280,8 @@ namespace
|
|||
code_generator::output output(type_safe::ref(generator), type_safe::ref(c), true);
|
||||
if (output)
|
||||
{
|
||||
if (is_friended(c))
|
||||
output << keyword("friend") << whitespace;
|
||||
output << keyword(to_string(c.class_kind())) << whitespace;
|
||||
|
||||
if (spec)
|
||||
|
|
@ -476,7 +479,7 @@ namespace
|
|||
code_generator::output output(type_safe::ref(generator), type_safe::ref(func), true);
|
||||
if (output)
|
||||
{
|
||||
if (func.is_friend())
|
||||
if (is_friended(func))
|
||||
output << keyword("friend") << whitespace;
|
||||
write_storage_class(output, func.storage_class(), func.is_constexpr());
|
||||
|
||||
|
|
@ -566,6 +569,8 @@ namespace
|
|||
code_generator::output output(type_safe::ref(generator), type_safe::ref(func), true);
|
||||
if (output)
|
||||
{
|
||||
if (is_friended(func))
|
||||
output << keyword("friend") << whitespace;
|
||||
if (func.is_constexpr())
|
||||
output << keyword("constexpr") << whitespace;
|
||||
else
|
||||
|
|
@ -606,6 +611,8 @@ namespace
|
|||
code_generator::output output(type_safe::ref(generator), type_safe::ref(op), true);
|
||||
if (output)
|
||||
{
|
||||
if (is_friended(op))
|
||||
output << keyword("friend") << whitespace;
|
||||
if (op.is_explicit())
|
||||
output << keyword("explicit") << whitespace;
|
||||
if (op.is_constexpr())
|
||||
|
|
@ -630,6 +637,8 @@ namespace
|
|||
code_generator::output output(type_safe::ref(generator), type_safe::ref(ctor), true);
|
||||
if (output)
|
||||
{
|
||||
if (is_friended(ctor))
|
||||
output << keyword("friend") << whitespace;
|
||||
if (ctor.is_explicit())
|
||||
output << keyword("explicit") << whitespace;
|
||||
if (ctor.is_constexpr())
|
||||
|
|
@ -648,6 +657,8 @@ namespace
|
|||
code_generator::output output(type_safe::ref(generator), type_safe::ref(dtor), true);
|
||||
if (output)
|
||||
{
|
||||
if (is_friended(dtor))
|
||||
output << keyword("friend") << whitespace;
|
||||
write_prefix_virtual(output, dtor.virtual_info());
|
||||
output << identifier(dtor.name()) << punctuation("(") << punctuation(")");
|
||||
write_noexcept(output, dtor, false);
|
||||
|
|
@ -683,6 +694,24 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
void generate_friend(code_generator& generator, const cpp_friend& f)
|
||||
{
|
||||
code_generator::output output(type_safe::ref(generator), type_safe::ref(f), true);
|
||||
if (output)
|
||||
{
|
||||
if (auto e = f.entity())
|
||||
generate_code(generator, e.value());
|
||||
else if (auto type = f.type())
|
||||
{
|
||||
output << keyword("friend") << whitespace;
|
||||
detail::write_type(output, type.value(), "");
|
||||
output << punctuation(";");
|
||||
}
|
||||
else
|
||||
DEBUG_UNREACHABLE(detail::assert_handler{});
|
||||
}
|
||||
}
|
||||
|
||||
void generate_template_type_parameter(code_generator& generator,
|
||||
const cpp_template_type_parameter& param)
|
||||
{
|
||||
|
|
@ -785,7 +814,10 @@ namespace
|
|||
code_generator::output output(type_safe::ref(generator), type_safe::ref(func), true);
|
||||
if (output)
|
||||
{
|
||||
write_template_parameters(output, func);
|
||||
DEBUG_ASSERT(func.is_full_specialization(), detail::assert_handler{});
|
||||
if (!is_friended(func))
|
||||
// don't write template parameters in friend
|
||||
write_template_parameters(output, func);
|
||||
generate_function_base(generator, func.function(), func);
|
||||
}
|
||||
}
|
||||
|
|
@ -859,6 +891,8 @@ void cppast::generate_code(code_generator& generator, const cpp_entity& e)
|
|||
CPPAST_DETAIL_HANDLE(constructor)
|
||||
CPPAST_DETAIL_HANDLE(destructor)
|
||||
|
||||
CPPAST_DETAIL_HANDLE(friend)
|
||||
|
||||
CPPAST_DETAIL_HANDLE(template_type_parameter)
|
||||
CPPAST_DETAIL_HANDLE(non_type_template_parameter)
|
||||
CPPAST_DETAIL_HANDLE(template_template_parameter)
|
||||
|
|
|
|||
|
|
@ -65,6 +65,9 @@ const char* cppast::to_string(cpp_entity_kind kind) noexcept
|
|||
case cpp_entity_kind::destructor_t:
|
||||
return "destructor";
|
||||
|
||||
case cpp_entity_kind::friend_t:
|
||||
return "friend";
|
||||
|
||||
case cpp_entity_kind::template_type_parameter_t:
|
||||
return "template type parameter";
|
||||
case cpp_entity_kind::non_type_template_parameter_t:
|
||||
|
|
@ -124,6 +127,7 @@ bool cppast::is_type(cpp_entity_kind kind) noexcept
|
|||
case cpp_entity_kind::conversion_op_t:
|
||||
case cpp_entity_kind::constructor_t:
|
||||
case cpp_entity_kind::destructor_t:
|
||||
case cpp_entity_kind::friend_t:
|
||||
case cpp_entity_kind::template_type_parameter_t:
|
||||
case cpp_entity_kind::non_type_template_parameter_t:
|
||||
case cpp_entity_kind::template_template_parameter_t:
|
||||
|
|
@ -170,6 +174,7 @@ bool cppast::is_function(cpp_entity_kind kind) noexcept
|
|||
case cpp_entity_kind::member_variable_t:
|
||||
case cpp_entity_kind::bitfield_t:
|
||||
case cpp_entity_kind::function_parameter_t:
|
||||
case cpp_entity_kind::friend_t:
|
||||
case cpp_entity_kind::template_type_parameter_t:
|
||||
case cpp_entity_kind::non_type_template_parameter_t:
|
||||
case cpp_entity_kind::template_template_parameter_t:
|
||||
|
|
@ -219,6 +224,7 @@ bool cppast::is_parameter(cpp_entity_kind kind) noexcept
|
|||
case cpp_entity_kind::conversion_op_t:
|
||||
case cpp_entity_kind::constructor_t:
|
||||
case cpp_entity_kind::destructor_t:
|
||||
case cpp_entity_kind::friend_t:
|
||||
case cpp_entity_kind::alias_template_t:
|
||||
case cpp_entity_kind::variable_template_t:
|
||||
case cpp_entity_kind::function_template_t:
|
||||
|
|
@ -267,6 +273,7 @@ bool cppast::is_template(cpp_entity_kind kind) noexcept
|
|||
case cpp_entity_kind::conversion_op_t:
|
||||
case cpp_entity_kind::constructor_t:
|
||||
case cpp_entity_kind::destructor_t:
|
||||
case cpp_entity_kind::friend_t:
|
||||
case cpp_entity_kind::template_type_parameter_t:
|
||||
case cpp_entity_kind::non_type_template_parameter_t:
|
||||
case cpp_entity_kind::template_template_parameter_t:
|
||||
|
|
@ -309,6 +316,7 @@ bool cppast::is_template_specialization(cpp_entity_kind kind) noexcept
|
|||
case cpp_entity_kind::conversion_op_t:
|
||||
case cpp_entity_kind::constructor_t:
|
||||
case cpp_entity_kind::destructor_t:
|
||||
case cpp_entity_kind::friend_t:
|
||||
case cpp_entity_kind::template_type_parameter_t:
|
||||
case cpp_entity_kind::non_type_template_parameter_t:
|
||||
case cpp_entity_kind::template_template_parameter_t:
|
||||
|
|
|
|||
26
src/cpp_friend.cpp
Normal file
26
src/cpp_friend.cpp
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (C) 2017 Jonathan Müller <jonathanmueller.dev@gmail.com>
|
||||
// This file is subject to the license terms in the LICENSE file
|
||||
// found in the top-level directory of this distribution.
|
||||
|
||||
#include <cppast/cpp_friend.hpp>
|
||||
|
||||
#include <cppast/cpp_entity_kind.hpp>
|
||||
|
||||
using namespace cppast;
|
||||
|
||||
cpp_entity_kind cpp_friend::kind() noexcept
|
||||
{
|
||||
return cpp_entity_kind::friend_t;
|
||||
}
|
||||
|
||||
cpp_entity_kind cpp_friend::do_get_entity_kind() const noexcept
|
||||
{
|
||||
return kind();
|
||||
}
|
||||
|
||||
bool cppast::is_friended(const cpp_entity& e) noexcept
|
||||
{
|
||||
if (is_templated(e))
|
||||
return is_friended(e.parent().value());
|
||||
return e.parent() && e.parent().value().kind() == cpp_entity_kind::friend_t;
|
||||
}
|
||||
|
|
@ -89,29 +89,40 @@ namespace
|
|||
}
|
||||
|
||||
std::unique_ptr<cpp_entity> detail::parse_cpp_class(const detail::parse_context& context,
|
||||
const CXCursor& cur)
|
||||
const CXCursor& cur, const CXCursor& parent_cur)
|
||||
{
|
||||
auto builder = make_class_builder(cur);
|
||||
context.comments.match(builder.get(), cur);
|
||||
detail::visit_children(cur, [&](const CXCursor& child) {
|
||||
auto kind = clang_getCursorKind(child);
|
||||
if (kind == CXCursor_CXXAccessSpecifier)
|
||||
add_access_specifier(builder, child);
|
||||
else if (kind == CXCursor_CXXBaseSpecifier)
|
||||
add_base_class(builder, context, child, cur);
|
||||
else if (kind == CXCursor_CXXFinalAttr)
|
||||
builder.is_final();
|
||||
else if (kind == CXCursor_TemplateTypeParameter || kind == CXCursor_NonTypeTemplateParameter
|
||||
|| kind == CXCursor_TemplateTemplateParameter || clang_isExpression(kind)
|
||||
|| clang_isReference(kind))
|
||||
// other children due to templates and stuff
|
||||
return;
|
||||
else if (auto entity = parse_entity(context, child))
|
||||
builder.add_child(std::move(entity));
|
||||
});
|
||||
auto is_templated = (clang_getTemplateCursorKind(cur) != CXCursor_NoDeclFound
|
||||
|| !clang_Cursor_isNull(clang_getSpecializedCursorTemplate(cur)));
|
||||
if (clang_isCursorDefinition(cur))
|
||||
#if CPPAST_CINDEX_HAS_FRIEND
|
||||
auto is_friend = clang_getCursorKind(parent_cur) == CXCursor_FriendDecl;
|
||||
#else
|
||||
auto is_friend = false;
|
||||
#endif
|
||||
|
||||
auto builder = make_class_builder(cur);
|
||||
if (!is_friend)
|
||||
{
|
||||
context.comments.match(builder.get(), cur);
|
||||
detail::visit_children(cur, [&](const CXCursor& child) {
|
||||
auto kind = clang_getCursorKind(child);
|
||||
if (kind == CXCursor_CXXAccessSpecifier)
|
||||
add_access_specifier(builder, child);
|
||||
else if (kind == CXCursor_CXXBaseSpecifier)
|
||||
add_base_class(builder, context, child, cur);
|
||||
else if (kind == CXCursor_CXXFinalAttr)
|
||||
builder.is_final();
|
||||
else if (kind == CXCursor_TemplateTypeParameter
|
||||
|| kind == CXCursor_NonTypeTemplateParameter
|
||||
|| kind == CXCursor_TemplateTemplateParameter || clang_isExpression(kind)
|
||||
|| clang_isReference(kind))
|
||||
// other children due to templates and stuff
|
||||
return;
|
||||
else if (auto entity = parse_entity(context, child))
|
||||
builder.add_child(std::move(entity));
|
||||
});
|
||||
}
|
||||
|
||||
if (!is_friend && clang_isCursorDefinition(cur))
|
||||
return is_templated ? builder.finish() : builder.finish(*context.idx, get_entity_id(cur));
|
||||
else
|
||||
return is_templated ? builder.finish_declaration(detail::get_entity_id(cur)) :
|
||||
|
|
|
|||
107
src/libclang/friend_parser.cpp
Normal file
107
src/libclang/friend_parser.cpp
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
// Copyright (C) 2017 Jonathan Müller <jonathanmueller.dev@gmail.com>
|
||||
// This file is subject to the license terms in the LICENSE file
|
||||
// found in the top-level directory of this distribution.
|
||||
|
||||
#include <cppast/cpp_friend.hpp>
|
||||
|
||||
#include <cppast/cpp_template_parameter.hpp>
|
||||
#include <cppast/cpp_template.hpp>
|
||||
|
||||
#include "parse_functions.hpp"
|
||||
#include "libclang_visitor.hpp"
|
||||
|
||||
using namespace cppast;
|
||||
|
||||
#if CPPAST_CINDEX_HAS_FRIEND
|
||||
std::unique_ptr<cpp_entity> detail::parse_cpp_friend(const detail::parse_context& context,
|
||||
const CXCursor& cur)
|
||||
{
|
||||
DEBUG_ASSERT(clang_getCursorKind(cur) == CXCursor_FriendDecl, detail::assert_handler{});
|
||||
|
||||
std::string comment;
|
||||
std::unique_ptr<cpp_entity> entity;
|
||||
std::unique_ptr<cpp_type> type;
|
||||
std::string namespace_str;
|
||||
type_safe::optional<cpp_template_instantiation_type::builder> inst_builder;
|
||||
detail::visit_children(cur, [&](const CXCursor& child) {
|
||||
auto kind = clang_getCursorKind(child);
|
||||
if (kind == CXCursor_TypeRef)
|
||||
{
|
||||
auto referenced = clang_getCursorReferenced(child);
|
||||
if (inst_builder)
|
||||
{
|
||||
namespace_str.clear();
|
||||
inst_builder.value().add_argument(
|
||||
detail::parse_type(context, referenced, clang_getCursorType(referenced)));
|
||||
}
|
||||
else if (clang_getCursorKind(referenced) == CXCursor_TemplateTypeParameter)
|
||||
// parse template parameter type
|
||||
type = cpp_template_parameter_type::build(
|
||||
cpp_template_type_parameter_ref(detail::get_entity_id(referenced),
|
||||
detail::get_cursor_name(child).c_str()));
|
||||
else if (!namespace_str.empty())
|
||||
{
|
||||
// parse as user defined type
|
||||
// we can't use the other branch here,
|
||||
// as then the class name would be wrong
|
||||
auto name = detail::get_cursor_name(referenced);
|
||||
type =
|
||||
cpp_user_defined_type::build(cpp_type_ref(detail::get_entity_id(referenced),
|
||||
namespace_str + "::" + name.c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// for some reason libclang gives a type ref here
|
||||
// we actually need a class decl cursor, so parse the referenced one
|
||||
// this might be a definition, so give friend information to the parser
|
||||
entity = parse_entity(context, referenced, cur);
|
||||
comment = type_safe::copy(entity->comment()).value_or("");
|
||||
}
|
||||
}
|
||||
else if (kind == CXCursor_NamespaceRef)
|
||||
namespace_str += detail::get_cursor_name(child).c_str();
|
||||
else if (kind == CXCursor_TemplateRef)
|
||||
{
|
||||
if (!namespace_str.empty())
|
||||
namespace_str += "::";
|
||||
auto templ = cpp_template_ref(detail::get_entity_id(clang_getCursorReferenced(child)),
|
||||
namespace_str + detail::get_cursor_name(child).c_str());
|
||||
namespace_str.clear();
|
||||
if (!inst_builder)
|
||||
inst_builder = cpp_template_instantiation_type::builder(std::move(templ));
|
||||
else
|
||||
inst_builder.value().add_argument(std::move(templ));
|
||||
}
|
||||
else if (clang_isDeclaration(kind))
|
||||
{
|
||||
entity = parse_entity(context, child);
|
||||
// steal comment
|
||||
comment = type_safe::copy(entity->comment()).value_or("");
|
||||
entity->set_comment(type_safe::nullopt);
|
||||
}
|
||||
else if (inst_builder && clang_isExpression(kind))
|
||||
{
|
||||
namespace_str.clear();
|
||||
inst_builder.value().add_argument(detail::parse_expression(context, child));
|
||||
}
|
||||
});
|
||||
|
||||
std::unique_ptr<cpp_entity> result;
|
||||
if (entity)
|
||||
result = cpp_friend::build(std::move(entity));
|
||||
else if (type)
|
||||
result = cpp_friend::build(std::move(type));
|
||||
else if (inst_builder)
|
||||
result = cpp_friend::build(inst_builder.value().finish());
|
||||
else
|
||||
DEBUG_UNREACHABLE(detail::parse_error_handler{}, cur,
|
||||
"unknown child entity of friend declaration");
|
||||
if (!comment.empty())
|
||||
// set comment of entity...
|
||||
result->set_comment(std::move(comment));
|
||||
// ... but override if this finds a different comment
|
||||
// due to clang_getCursorReferenced(), this may happen
|
||||
context.comments.match(*result, cur);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -384,7 +384,7 @@ namespace
|
|||
builder.noexcept_condition(std::move(suffix.noexcept_condition));
|
||||
|
||||
if (is_templated_cursor(cur))
|
||||
return builder.finish(suffix.body_kind);
|
||||
return builder.finish(detail::get_entity_id(cur), suffix.body_kind);
|
||||
else
|
||||
return builder.finish(*context.idx, detail::get_entity_id(cur), suffix.body_kind);
|
||||
}
|
||||
|
|
@ -493,7 +493,7 @@ namespace
|
|||
builder.virtual_info(virt.value());
|
||||
|
||||
if (is_templated_cursor(cur))
|
||||
return builder.finish(suffix.body_kind);
|
||||
return builder.finish(detail::get_entity_id(cur), suffix.body_kind);
|
||||
else
|
||||
return builder.finish(*context.idx, detail::get_entity_id(cur), suffix.body_kind);
|
||||
}
|
||||
|
|
@ -618,7 +618,7 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_constructor(const detail::parse_co
|
|||
builder.noexcept_condition(std::move(suffix.noexcept_condition));
|
||||
|
||||
if (is_templated_cursor(cur))
|
||||
return builder.finish(suffix.body_kind);
|
||||
return builder.finish(detail::get_entity_id(cur), suffix.body_kind);
|
||||
else
|
||||
return builder.finish(*context.idx, detail::get_entity_id(cur), suffix.body_kind);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ void detail::comment_context::match(cpp_entity& e, unsigned line) const
|
|||
|
||||
std::unique_ptr<cpp_entity> detail::parse_entity(const detail::parse_context& context,
|
||||
const CXCursor& cur,
|
||||
const CXCursor& template_cur) try
|
||||
const CXCursor& parent_cur) try
|
||||
{
|
||||
auto kind = clang_getCursorKind(cur);
|
||||
switch (kind)
|
||||
|
|
@ -94,7 +94,7 @@ std::unique_ptr<cpp_entity> detail::parse_entity(const detail::parse_context& co
|
|||
|
||||
case CXCursor_TypeAliasDecl:
|
||||
case CXCursor_TypedefDecl:
|
||||
return parse_cpp_type_alias(context, cur, template_cur);
|
||||
return parse_cpp_type_alias(context, cur, parent_cur);
|
||||
case CXCursor_EnumDecl:
|
||||
return parse_cpp_enum(context, cur);
|
||||
case CXCursor_ClassDecl:
|
||||
|
|
@ -102,7 +102,7 @@ std::unique_ptr<cpp_entity> detail::parse_entity(const detail::parse_context& co
|
|||
case CXCursor_UnionDecl:
|
||||
if (auto spec = try_parse_full_cpp_class_template_specialization(context, cur))
|
||||
return spec;
|
||||
return parse_cpp_class(context, cur);
|
||||
return parse_cpp_class(context, cur, parent_cur);
|
||||
|
||||
case CXCursor_VarDecl:
|
||||
return parse_cpp_variable(context, cur);
|
||||
|
|
@ -130,6 +130,11 @@ std::unique_ptr<cpp_entity> detail::parse_entity(const detail::parse_context& co
|
|||
case CXCursor_Destructor:
|
||||
return parse_cpp_destructor(context, cur);
|
||||
|
||||
#if CPPAST_CINDEX_HAS_FRIEND
|
||||
case CXCursor_FriendDecl:
|
||||
return parse_cpp_friend(context, cur);
|
||||
#endif
|
||||
|
||||
case CXCursor_TypeAliasTemplateDecl:
|
||||
return parse_cpp_alias_template(context, cur);
|
||||
case CXCursor_FunctionTemplate:
|
||||
|
|
|
|||
|
|
@ -13,6 +13,12 @@
|
|||
#include "parse_error.hpp" // for convenience
|
||||
#include "preprocessor.hpp"
|
||||
|
||||
#if CINDEX_VERSION_MINOR >= 36
|
||||
#define CPPAST_CINDEX_HAS_FRIEND 1
|
||||
#else
|
||||
#define CPPAST_CINDEX_HAS_FRIEND 0
|
||||
#endif
|
||||
|
||||
namespace cppast
|
||||
{
|
||||
class cpp_expression;
|
||||
|
|
@ -118,7 +124,8 @@ namespace cppast
|
|||
std::unique_ptr<cpp_entity> parse_cpp_enum(const parse_context& context,
|
||||
const CXCursor& cur);
|
||||
std::unique_ptr<cpp_entity> parse_cpp_class(const parse_context& context,
|
||||
const CXCursor& cur);
|
||||
const CXCursor& cur,
|
||||
const CXCursor& parent_cur);
|
||||
|
||||
std::unique_ptr<cpp_entity> parse_cpp_variable(const parse_context& context,
|
||||
const CXCursor& cur);
|
||||
|
|
@ -137,6 +144,9 @@ namespace cppast
|
|||
std::unique_ptr<cpp_entity> parse_cpp_destructor(const parse_context& context,
|
||||
const CXCursor& cur);
|
||||
|
||||
std::unique_ptr<cpp_entity> parse_cpp_friend(const parse_context& context,
|
||||
const CXCursor& cur);
|
||||
|
||||
std::unique_ptr<cpp_entity> parse_cpp_alias_template(const parse_context& context,
|
||||
const CXCursor& cur);
|
||||
std::unique_ptr<cpp_entity> parse_cpp_function_template(const parse_context& context,
|
||||
|
|
@ -146,10 +156,10 @@ namespace cppast
|
|||
std::unique_ptr<cpp_entity> parse_cpp_class_template_specialization(
|
||||
const parse_context& context, const CXCursor& cur);
|
||||
|
||||
// as_template: true, iff currently parsing a template
|
||||
// parent_cur: used when parsing templates or friends
|
||||
std::unique_ptr<cpp_entity> parse_entity(
|
||||
const parse_context& context, const CXCursor& cur,
|
||||
const CXCursor& template_cur = clang_getNullCursor());
|
||||
const CXCursor& parent_cur = clang_getNullCursor());
|
||||
}
|
||||
} // namespace cppast::detail
|
||||
|
||||
|
|
|
|||
|
|
@ -333,7 +333,7 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_class_template(const detail::parse
|
|||
{
|
||||
DEBUG_ASSERT(clang_getCursorKind(cur) == CXCursor_ClassTemplate, detail::assert_handler{});
|
||||
|
||||
auto c = detail::parse_cpp_class(context, cur);
|
||||
auto c = detail::parse_cpp_class(context, cur, clang_getNullCursor());
|
||||
if (!c)
|
||||
return nullptr;
|
||||
|
||||
|
|
@ -373,7 +373,7 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_class_template_specialization(
|
|||
detail::assert_handler{});
|
||||
|
||||
auto primary = clang_getSpecializedCursorTemplate(cur);
|
||||
auto c = detail::parse_cpp_class(context, cur);
|
||||
auto c = detail::parse_cpp_class(context, cur, clang_getNullCursor());
|
||||
if (!c)
|
||||
return nullptr;
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ bool detail::visit(const cpp_entity& e, detail::visitor_callback_t cb, void* fun
|
|||
case cpp_entity_kind::bitfield_t:
|
||||
case cpp_entity_kind::function_parameter_t:
|
||||
case cpp_entity_kind::destructor_t:
|
||||
case cpp_entity_kind::friend_t:
|
||||
case cpp_entity_kind::template_type_parameter_t:
|
||||
case cpp_entity_kind::non_type_template_parameter_t:
|
||||
case cpp_entity_kind::unexposed_t:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue