Add get_class() function to resolve base class types
This commit is contained in:
parent
9df3b39e1e
commit
2c7b06dea9
2 changed files with 91 additions and 0 deletions
|
|
@ -235,6 +235,16 @@ namespace cppast
|
||||||
cpp_class_kind kind_;
|
cpp_class_kind kind_;
|
||||||
bool final_;
|
bool final_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// \returns The type the base class refers to.
|
||||||
|
/// It is either a class or some form of typedef.
|
||||||
|
type_safe::optional_ref<const cpp_entity> get_class_or_typedef(const cpp_entity_index& index,
|
||||||
|
const cpp_base_class& base);
|
||||||
|
|
||||||
|
/// \returns The type the base class refers to.
|
||||||
|
/// Typedefs are unwrapped.
|
||||||
|
type_safe::optional_ref<const cpp_class> get_class(const cpp_entity_index& index,
|
||||||
|
const cpp_base_class& base);
|
||||||
} // namespace cppast
|
} // namespace cppast
|
||||||
|
|
||||||
#endif // CPPAST_CPP_CLASS_HPP_INCLUDED
|
#endif // CPPAST_CPP_CLASS_HPP_INCLUDED
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include <cppast/cpp_entity_index.hpp>
|
#include <cppast/cpp_entity_index.hpp>
|
||||||
#include <cppast/cpp_entity_kind.hpp>
|
#include <cppast/cpp_entity_kind.hpp>
|
||||||
|
#include <cppast/cpp_alias_template.hpp>
|
||||||
|
#include <cppast/cpp_class_template.hpp>
|
||||||
|
|
||||||
using namespace cppast;
|
using namespace cppast;
|
||||||
|
|
||||||
|
|
@ -98,3 +100,82 @@ cpp_entity_kind cpp_class::do_get_entity_kind() const noexcept
|
||||||
{
|
{
|
||||||
return kind();
|
return kind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
cpp_entity_ref get_type_ref(const cpp_type& type)
|
||||||
|
{
|
||||||
|
if (type.kind() == cpp_type_kind::user_defined_t)
|
||||||
|
{
|
||||||
|
auto& ref = static_cast<const cpp_user_defined_type&>(type).entity();
|
||||||
|
return cpp_entity_ref(ref.id()[0u], ref.name());
|
||||||
|
}
|
||||||
|
else if (type.kind() == cpp_type_kind::template_instantiation_t)
|
||||||
|
{
|
||||||
|
auto& ref =
|
||||||
|
static_cast<const cpp_template_instantiation_type&>(type).primary_template();
|
||||||
|
return cpp_entity_ref(ref.id()[0u], ref.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_ASSERT(type.kind() == cpp_type_kind::template_parameter_t
|
||||||
|
|| type.kind() == cpp_type_kind::decltype_t
|
||||||
|
|| type.kind() == cpp_type_kind::decltype_auto_t
|
||||||
|
|| type.kind() == cpp_type_kind::unexposed_t,
|
||||||
|
detail::assert_handler{});
|
||||||
|
return cpp_entity_ref(cpp_entity_id("<null id>"), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
type_safe::optional_ref<const cpp_entity> get_entity_impl(const cpp_entity_index& index,
|
||||||
|
const cpp_entity_ref& ref)
|
||||||
|
{
|
||||||
|
auto result = ref.get(index);
|
||||||
|
if (result.empty())
|
||||||
|
return nullptr;
|
||||||
|
DEBUG_ASSERT(result.size() == 1u, detail::assert_handler{});
|
||||||
|
|
||||||
|
auto entity = result.front();
|
||||||
|
if (entity->kind() == cpp_class_template::kind())
|
||||||
|
return type_safe::ref(static_cast<const cpp_class_template&>(*entity).class_());
|
||||||
|
else if (entity->kind() == cpp_class_template_specialization::kind())
|
||||||
|
return type_safe::ref(
|
||||||
|
static_cast<const cpp_class_template_specialization&>(*entity).class_());
|
||||||
|
else
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
type_safe::optional_ref<const cpp_class> get_class_impl(const cpp_entity_index& index,
|
||||||
|
const cpp_entity_ref& ref)
|
||||||
|
{
|
||||||
|
auto entity = get_entity_impl(index, ref);
|
||||||
|
if (!entity)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (entity.value().kind() == cpp_alias_template::kind())
|
||||||
|
{
|
||||||
|
auto& alias = static_cast<const cppast::cpp_alias_template&>(entity.value());
|
||||||
|
return get_class_impl(index, get_type_ref(alias.type_alias().underlying_type()));
|
||||||
|
}
|
||||||
|
else if (entity.value().kind() == cpp_type_alias::kind())
|
||||||
|
{
|
||||||
|
auto& alias = static_cast<const cppast::cpp_type_alias&>(entity.value());
|
||||||
|
return get_class_impl(index, get_type_ref(alias.underlying_type()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG_ASSERT(entity.value().kind() == cpp_class::kind(), detail::assert_handler{});
|
||||||
|
return type_safe::ref(static_cast<const cpp_class&>(entity.value()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type_safe::optional_ref<const cpp_class> cppast::get_class(const cpp_entity_index& index,
|
||||||
|
const cpp_base_class& base)
|
||||||
|
{
|
||||||
|
return get_class_impl(index, get_type_ref(base.type()));
|
||||||
|
}
|
||||||
|
|
||||||
|
type_safe::optional_ref<const cpp_entity> cppast::get_class_or_typedef(
|
||||||
|
const cpp_entity_index& index, const cpp_base_class& base)
|
||||||
|
{
|
||||||
|
return get_entity_impl(index, get_type_ref(base.type()));
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue