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_;
|
||||
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
|
||||
|
||||
#endif // CPPAST_CPP_CLASS_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include <cppast/cpp_entity_index.hpp>
|
||||
#include <cppast/cpp_entity_kind.hpp>
|
||||
#include <cppast/cpp_alias_template.hpp>
|
||||
#include <cppast/cpp_class_template.hpp>
|
||||
|
||||
using namespace cppast;
|
||||
|
||||
|
|
@ -98,3 +100,82 @@ cpp_entity_kind cpp_class::do_get_entity_kind() const noexcept
|
|||
{
|
||||
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