diff --git a/include/cppast/visitor.hpp b/include/cppast/visitor.hpp index 6195dbc..889c194 100644 --- a/include/cppast/visitor.hpp +++ b/include/cppast/visitor.hpp @@ -5,6 +5,7 @@ #ifndef CPPAST_VISITOR_HPP_INCLUDED #define CPPAST_VISITOR_HPP_INCLUDED +#include #include #include @@ -24,6 +25,9 @@ namespace cppast container_entity_exit, //< Callback called for a container entity after the children. /// If callback returns `false`, visit operation will be aborted. } event; + + cpp_access_specifier_kind access; //< The current access specifier. + bool last_child; //< True when the current entity is the last child of the visited parent entity. /// \notes It will always be `false` for the initial entity. @@ -42,7 +46,8 @@ namespace cppast return func(e, info); } - bool visit(const cpp_entity& e, visitor_callback_t cb, void* functor, bool last_child); + bool visit(const cpp_entity& e, visitor_callback_t cb, void* functor, + cpp_access_specifier_kind cur_access, bool last_child); } // namespace detail /// Visits a [cppast::cpp_entity](). @@ -54,7 +59,7 @@ namespace cppast template void visit(const cpp_entity& e, Func f) { - detail::visit(e, &detail::visitor_callback, &f, false); + detail::visit(e, &detail::visitor_callback, &f, cpp_public, false); } /// Visits a [cppast::cpp_entity](). diff --git a/src/visitor.cpp b/src/visitor.cpp index 78c47bf..73a2327 100644 --- a/src/visitor.cpp +++ b/src/visitor.cpp @@ -5,8 +5,6 @@ #include #include -#include -#include #include #include #include @@ -20,56 +18,78 @@ using namespace cppast; namespace { + cpp_access_specifier_kind get_initial_access(const cpp_entity& e) + { + if (e.kind() == cpp_class::kind()) + return static_cast(e).class_kind() == cpp_class_kind::class_t ? + cpp_private : + cpp_public; + return cpp_public; + } + + void update_access(cpp_access_specifier_kind& child_access, const cpp_entity& child) + { + if (child.kind() == cpp_access_specifier::kind()) + child_access = static_cast(child).access_specifier(); + } + template bool handle_container(const cpp_entity& e, detail::visitor_callback_t cb, void* functor, - bool last_child) + cpp_access_specifier_kind cur_access, bool last_child) { auto& container = static_cast(e); auto handle_children = - cb(functor, container, {visitor_info::container_entity_enter, last_child}); + cb(functor, container, {visitor_info::container_entity_enter, cur_access, last_child}); if (handle_children) { + auto child_access = get_initial_access(e); for (auto iter = container.begin(); iter != container.end();) { auto& cur = *iter; ++iter; - if (!detail::visit(cur, cb, functor, iter == container.end())) + + update_access(child_access, cur); + + if (!detail::visit(cur, cb, functor, child_access, iter == container.end())) return false; } } - return cb(functor, container, {visitor_info::container_entity_exit, last_child}); + return cb(functor, container, + {visitor_info::container_entity_exit, cur_access, last_child}); } } bool detail::visit(const cpp_entity& e, detail::visitor_callback_t cb, void* functor, - bool last_child) + cpp_access_specifier_kind cur_access, bool last_child) { switch (e.kind()) { case cpp_entity_kind::file_t: - return handle_container(e, cb, functor, last_child); + return handle_container(e, cb, functor, cur_access, last_child); case cpp_entity_kind::language_linkage_t: - return handle_container(e, cb, functor, last_child); + return handle_container(e, cb, functor, cur_access, last_child); case cpp_entity_kind::namespace_t: - return handle_container(e, cb, functor, last_child); + return handle_container(e, cb, functor, cur_access, last_child); case cpp_entity_kind::enum_t: - return handle_container(e, cb, functor, last_child); + return handle_container(e, cb, functor, cur_access, last_child); case cpp_entity_kind::class_t: - return handle_container(e, cb, functor, last_child); + return handle_container(e, cb, functor, cur_access, last_child); case cpp_entity_kind::alias_template_t: - return handle_container(e, cb, functor, last_child); + return handle_container(e, cb, functor, cur_access, last_child); case cpp_entity_kind::variable_template_t: - return handle_container(e, cb, functor, last_child); + return handle_container(e, cb, functor, cur_access, last_child); case cpp_entity_kind::function_template_t: - return handle_container(e, cb, functor, last_child); + return handle_container(e, cb, functor, cur_access, last_child); case cpp_entity_kind::function_template_specialization_t: - return handle_container(e, cb, functor, last_child); + return handle_container(e, cb, functor, cur_access, + last_child); case cpp_entity_kind::class_template_t: - return handle_container(e, cb, functor, last_child); + return handle_container(e, cb, functor, cur_access, last_child); case cpp_entity_kind::class_template_specialization_t: - return handle_container(e, cb, functor, last_child); + return handle_container(e, cb, functor, cur_access, + last_child); case cpp_entity_kind::macro_definition_t: case cpp_entity_kind::include_directive_t: @@ -95,7 +115,7 @@ bool detail::visit(const cpp_entity& e, detail::visitor_callback_t cb, void* fun case cpp_entity_kind::template_template_parameter_t: case cpp_entity_kind::static_assert_t: case cpp_entity_kind::unexposed_t: - return cb(functor, e, {visitor_info::leaf_entity, last_child}); + return cb(functor, e, {visitor_info::leaf_entity, cur_access, last_child}); case cpp_entity_kind::count: break;