Remove parameter children from e.g. cpp_function_base

Also template parameter children of cpp_template_template_parameter.
Now accessible over named function, consistent with base classes, other template parameters etc.
This commit is contained in:
Jonathan Müller 2017-04-11 18:50:02 +02:00
commit c5d6df957c
9 changed files with 63 additions and 59 deletions

View file

@ -5,8 +5,8 @@
#ifndef CPPAST_CPP_FUNCTION_HPP_INCLUDED #ifndef CPPAST_CPP_FUNCTION_HPP_INCLUDED
#define CPPAST_CPP_FUNCTION_HPP_INCLUDED #define CPPAST_CPP_FUNCTION_HPP_INCLUDED
#include <cppast/detail/intrusive_list.hpp>
#include <cppast/cpp_entity.hpp> #include <cppast/cpp_entity.hpp>
#include <cppast/cpp_entity_container.hpp>
#include <cppast/cpp_forward_declarable.hpp> #include <cppast/cpp_forward_declarable.hpp>
#include <cppast/cpp_storage_class_specifiers.hpp> #include <cppast/cpp_storage_class_specifiers.hpp>
#include <cppast/cpp_variable_base.hpp> #include <cppast/cpp_variable_base.hpp>
@ -64,12 +64,15 @@ namespace cppast
/// Base class for all entities that are functions. /// Base class for all entities that are functions.
/// ///
/// It contains arguments and common flags. /// It contains arguments and common flags.
class cpp_function_base class cpp_function_base : public cpp_entity, public cpp_forward_declarable
: public cpp_entity,
public cpp_entity_container<cpp_function_base, cpp_function_parameter>,
public cpp_forward_declarable
{ {
public: public:
/// \returns An iteratable object iterating over the [cppast::cpp_function__parameter]() entities.
detail::iteratable_intrusive_list<cpp_function_parameter> parameters() const noexcept
{
return type_safe::ref(parameters_);
}
/// \returns The [cppast::cpp_function_body_kind](). /// \returns The [cppast::cpp_function_body_kind]().
/// \notes This matches the [cppast::cpp_forward_declarable]() queries. /// \notes This matches the [cppast::cpp_forward_declarable]() queries.
cpp_function_body_kind body_kind() const noexcept cpp_function_body_kind body_kind() const noexcept
@ -107,7 +110,9 @@ namespace cppast
/// \effects Adds a parameter. /// \effects Adds a parameter.
void add_parameter(std::unique_ptr<cpp_function_parameter> parameter) void add_parameter(std::unique_ptr<cpp_function_parameter> parameter)
{ {
static_cast<cpp_function_base&>(*function).add_child(std::move(parameter)); static_cast<cpp_function_base&>(*function).parameters_.push_back(*function,
std::move(
parameter));
} }
/// \effects Marks the function as variadic. /// \effects Marks the function as variadic.
@ -168,9 +173,10 @@ namespace cppast
} }
private: private:
std::unique_ptr<cpp_expression> noexcept_expr_; detail::intrusive_list<cpp_function_parameter> parameters_;
cpp_function_body_kind body_; std::unique_ptr<cpp_expression> noexcept_expr_;
bool variadic_; cpp_function_body_kind body_;
bool variadic_;
}; };
/// A [cppast::cpp_entity]() modelling a C++ function. /// A [cppast::cpp_entity]() modelling a C++ function.

View file

@ -8,8 +8,8 @@
#include <type_safe/optional.hpp> #include <type_safe/optional.hpp>
#include <type_safe/variant.hpp> #include <type_safe/variant.hpp>
#include <cppast/detail/intrusive_list.hpp>
#include <cppast/cpp_entity.hpp> #include <cppast/cpp_entity.hpp>
#include <cppast/cpp_entity_container.hpp>
#include <cppast/cpp_variable_base.hpp> #include <cppast/cpp_variable_base.hpp>
namespace cppast namespace cppast
@ -170,9 +170,7 @@ namespace cppast
using cpp_template_ref = basic_cpp_entity_ref<cpp_entity, detail::cpp_template_ref_predicate>; using cpp_template_ref = basic_cpp_entity_ref<cpp_entity, detail::cpp_template_ref_predicate>;
/// A [cppast::cpp_entity]() modelling a C++ template template parameter. /// A [cppast::cpp_entity]() modelling a C++ template template parameter.
class cpp_template_template_parameter final class cpp_template_template_parameter final : public cpp_template_parameter
: public cpp_template_parameter,
public cpp_entity_container<cpp_template_template_parameter, cpp_template_parameter>
{ {
public: public:
static cpp_entity_kind kind() noexcept; static cpp_entity_kind kind() noexcept;
@ -197,7 +195,7 @@ namespace cppast
/// \effects Adds a parameter to the template. /// \effects Adds a parameter to the template.
void add_parameter(std::unique_ptr<cpp_template_parameter> param) void add_parameter(std::unique_ptr<cpp_template_parameter> param)
{ {
parameter_->add_child(std::move(param)); parameter_->parameters_.push_back(*parameter_, std::move(param));
} }
/// \effects Sets the default template. /// \effects Sets the default template.
@ -220,6 +218,12 @@ namespace cppast
std::unique_ptr<cpp_template_template_parameter> parameter_; std::unique_ptr<cpp_template_template_parameter> parameter_;
}; };
/// \returns An iteratable object containing the template parameters of the template template parameter.
detail::iteratable_intrusive_list<cpp_template_parameter> parameters() const noexcept
{
return type_safe::ref(parameters_);
}
/// \returns The keyword used in the template parameter. /// \returns The keyword used in the template parameter.
cpp_template_keyword keyword() const noexcept cpp_template_keyword keyword() const noexcept
{ {
@ -241,8 +245,9 @@ namespace cppast
cpp_entity_kind do_get_entity_kind() const noexcept override; cpp_entity_kind do_get_entity_kind() const noexcept override;
type_safe::optional<cpp_template_ref> default_; detail::intrusive_list<cpp_template_parameter> parameters_;
cpp_template_keyword keyword_; type_safe::optional<cpp_template_ref> default_;
cpp_template_keyword keyword_;
}; };
/// An argument for a [cppast::cpp_template_parameter](). /// An argument for a [cppast::cpp_template_parameter]().

View file

@ -422,7 +422,7 @@ namespace
void write_function_parameters(code_generator::output& output, const cpp_function_base& base) void write_function_parameters(code_generator::output& output, const cpp_function_base& base)
{ {
output << punctuation("("); output << punctuation("(");
auto need_sep = write_container(output, base, punctuation(",")); auto need_sep = write_container(output, base.parameters(), punctuation(","));
if (base.is_variadic()) if (base.is_variadic())
{ {
if (need_sep) if (need_sep)
@ -753,7 +753,7 @@ namespace
if (output) if (output)
{ {
output << keyword("template") << punctuation("<"); output << keyword("template") << punctuation("<");
write_container(output, param, punctuation(",")); write_container(output, param.parameters(), punctuation(","));
output << punctuation(">") << keyword(to_string(param.keyword())) << whitespace; output << punctuation(">") << keyword(to_string(param.keyword())) << whitespace;
if (param.is_variadic()) if (param.is_variadic())
output << punctuation("..."); output << punctuation("...");

View file

@ -11,12 +11,9 @@
#include <cppast/cpp_class_template.hpp> #include <cppast/cpp_class_template.hpp>
#include <cppast/cpp_enum.hpp> #include <cppast/cpp_enum.hpp>
#include <cppast/cpp_file.hpp> #include <cppast/cpp_file.hpp>
#include <cppast/cpp_function.hpp>
#include <cppast/cpp_function_template.hpp> #include <cppast/cpp_function_template.hpp>
#include <cppast/cpp_language_linkage.hpp> #include <cppast/cpp_language_linkage.hpp>
#include <cppast/cpp_member_function.hpp>
#include <cppast/cpp_namespace.hpp> #include <cppast/cpp_namespace.hpp>
#include <cppast/cpp_template_parameter.hpp>
#include <cppast/cpp_variable_template.hpp> #include <cppast/cpp_variable_template.hpp>
using namespace cppast; using namespace cppast;
@ -61,16 +58,6 @@ bool detail::visit(const cpp_entity& e, detail::visitor_callback_t cb, void* fun
return handle_container<cpp_enum>(e, cb, functor, last_child); return handle_container<cpp_enum>(e, cb, functor, last_child);
case cpp_entity_kind::class_t: case cpp_entity_kind::class_t:
return handle_container<cpp_class>(e, cb, functor, last_child); return handle_container<cpp_class>(e, cb, functor, last_child);
case cpp_entity_kind::function_t:
return handle_container<cpp_function>(e, cb, functor, last_child);
case cpp_entity_kind::member_function_t:
return handle_container<cpp_member_function>(e, cb, functor, last_child);
case cpp_entity_kind::conversion_op_t:
return handle_container<cpp_conversion_op>(e, cb, functor, last_child);
case cpp_entity_kind::constructor_t:
return handle_container<cpp_constructor>(e, cb, functor, last_child);
case cpp_entity_kind::template_template_parameter_t:
return handle_container<cpp_template_template_parameter>(e, cb, functor, last_child);
case cpp_entity_kind::alias_template_t: case cpp_entity_kind::alias_template_t:
return handle_container<cpp_alias_template>(e, cb, functor, last_child); return handle_container<cpp_alias_template>(e, cb, functor, last_child);
case cpp_entity_kind::variable_template_t: case cpp_entity_kind::variable_template_t:
@ -97,10 +84,15 @@ bool detail::visit(const cpp_entity& e, detail::visitor_callback_t cb, void* fun
case cpp_entity_kind::member_variable_t: case cpp_entity_kind::member_variable_t:
case cpp_entity_kind::bitfield_t: case cpp_entity_kind::bitfield_t:
case cpp_entity_kind::function_parameter_t: case cpp_entity_kind::function_parameter_t:
case cpp_entity_kind::function_t:
case cpp_entity_kind::member_function_t:
case cpp_entity_kind::conversion_op_t:
case cpp_entity_kind::constructor_t:
case cpp_entity_kind::destructor_t: case cpp_entity_kind::destructor_t:
case cpp_entity_kind::friend_t: case cpp_entity_kind::friend_t:
case cpp_entity_kind::template_type_parameter_t: case cpp_entity_kind::template_type_parameter_t:
case cpp_entity_kind::non_type_template_parameter_t: case cpp_entity_kind::non_type_template_parameter_t:
case cpp_entity_kind::template_template_parameter_t:
case cpp_entity_kind::unexposed_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, last_child});

View file

@ -205,7 +205,7 @@ struct b<0, T> {};
*cpp_template_parameter_type::build( *cpp_template_parameter_type::build(
cpp_template_type_parameter_ref(cpp_entity_id(""), cpp_template_type_parameter_ref(cpp_entity_id(""),
"T")))); "T"))));
for (auto& param : mfunc) for (auto& param : mfunc.parameters())
REQUIRE( REQUIRE(
equal_types(idx, param.type(), equal_types(idx, param.type(),
*cpp_template_parameter_type::build( *cpp_template_parameter_type::build(

View file

@ -77,7 +77,7 @@ void ns::l()
if (func.name() == "a") if (func.name() == "a")
{ {
REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_void))); REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_void)));
REQUIRE(count_children(func) == 0u); REQUIRE(count_children(func.parameters()) == 0u);
REQUIRE(!func.is_variadic()); REQUIRE(!func.is_variadic());
} }
else if (func.name() == "b") else if (func.name() == "b")
@ -85,7 +85,7 @@ void ns::l()
REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_int))); REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_int)));
auto count = 0u; auto count = 0u;
for (auto& param : func) for (auto& param : func.parameters())
{ {
if (param.name() == "a") if (param.name() == "a")
{ {
@ -124,7 +124,7 @@ void ns::l()
cpp_ref_lvalue))); cpp_ref_lvalue)));
auto count = 0u; auto count = 0u;
for (auto& param : func) for (auto& param : func.parameters())
{ {
if (param.name() == "a") if (param.name() == "a")
{ {
@ -147,7 +147,7 @@ void ns::l()
else if (func.name() == "d" || func.name() == "e" || func.name() == "f") else if (func.name() == "d" || func.name() == "e" || func.name() == "f")
{ {
REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_void))); REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_void)));
REQUIRE(count_children(func) == 0u); REQUIRE(count_children(func.parameters()) == 0u);
REQUIRE(!func.is_variadic()); REQUIRE(!func.is_variadic());
REQUIRE(func.storage_class() == cpp_storage_class_none); REQUIRE(func.storage_class() == cpp_storage_class_none);
REQUIRE(!func.is_constexpr()); REQUIRE(!func.is_constexpr());
@ -172,7 +172,7 @@ void ns::l()
|| func.name() == "j") || func.name() == "j")
{ {
REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_void))); REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_void)));
REQUIRE(count_children(func) == 0u); REQUIRE(count_children(func.parameters()) == 0u);
REQUIRE(!func.is_variadic()); REQUIRE(!func.is_variadic());
REQUIRE(!func.noexcept_condition()); REQUIRE(!func.noexcept_condition());
check_body(func, cpp_function_declaration); check_body(func, cpp_function_declaration);
@ -201,7 +201,7 @@ void ns::l()
else if (func.name() == "k" || func.name() == "l" || func.name() == "ns::l") else if (func.name() == "k" || func.name() == "l" || func.name() == "ns::l")
{ {
REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_void))); REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_void)));
REQUIRE(count_children(func) == 0u); REQUIRE(count_children(func.parameters()) == 0u);
REQUIRE(!func.is_variadic()); REQUIRE(!func.is_variadic());
REQUIRE(!func.noexcept_condition()); REQUIRE(!func.noexcept_condition());
REQUIRE(!func.is_constexpr()); REQUIRE(!func.is_constexpr());
@ -244,7 +244,7 @@ void foo::a() {}
auto file = parse(idx, "static_cpp_function.cpp", code); auto file = parse(idx, "static_cpp_function.cpp", code);
auto count = test_visit<cpp_function>(*file, [&](const cpp_function& func) { auto count = test_visit<cpp_function>(*file, [&](const cpp_function& func) {
REQUIRE(!func.is_variadic()); REQUIRE(!func.is_variadic());
REQUIRE(count_children(func) == 0u); REQUIRE(count_children(func.parameters()) == 0u);
REQUIRE(func.storage_class() == cpp_storage_class_static); REQUIRE(func.storage_class() == cpp_storage_class_static);
if (func.name() == "a" || func.name() == "foo::a") if (func.name() == "a" || func.name() == "foo::a")

View file

@ -88,7 +88,7 @@ d::d(const int&);
*cpp_template_parameter_type::build(parameter))); *cpp_template_parameter_type::build(parameter)));
auto count = 0u; auto count = 0u;
for (auto& param : func) for (auto& param : func.parameters())
{ {
++count; ++count;
REQUIRE( REQUIRE(
@ -117,7 +117,7 @@ d::d(const int&);
auto type_parameter = cpp_template_type_parameter_ref(cpp_entity_id(""), "T"); auto type_parameter = cpp_template_type_parameter_ref(cpp_entity_id(""), "T");
auto count = 0u; auto count = 0u;
for (auto& param : func) for (auto& param : func.parameters())
{ {
++count; ++count;
REQUIRE(equal_types(idx, param.type(), REQUIRE(equal_types(idx, param.type(),
@ -161,7 +161,7 @@ d::d(const int&);
auto parameter = cpp_template_type_parameter_ref(cpp_entity_id(""), "T"); auto parameter = cpp_template_type_parameter_ref(cpp_entity_id(""), "T");
auto count = 0u; auto count = 0u;
for (auto& param : func) for (auto& param : func.parameters())
{ {
++count; ++count;
REQUIRE( REQUIRE(
@ -201,7 +201,7 @@ d::d(const int&);
REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_int))); REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_int)));
auto count = 0u; auto count = 0u;
for (auto& param : func) for (auto& param : func.parameters())
{ {
++count; ++count;
REQUIRE( REQUIRE(
@ -227,7 +227,7 @@ d::d(const int&);
REQUIRE(equal_types(idx, func.return_type(), *builder.finish())); REQUIRE(equal_types(idx, func.return_type(), *builder.finish()));
auto count = 0u; auto count = 0u;
for (auto& param : func) for (auto& param : func.parameters())
{ {
++count; ++count;
REQUIRE(equal_types(idx, param.type(), *cpp_builtin_type::build(cpp_int))); REQUIRE(equal_types(idx, param.type(), *cpp_builtin_type::build(cpp_int)));
@ -262,7 +262,7 @@ d::d(const int&);
auto& func = static_cast<const cpp_constructor&>(tfunc.function()); auto& func = static_cast<const cpp_constructor&>(tfunc.function());
auto count = 0u; auto count = 0u;
for (auto& param : func) for (auto& param : func.parameters())
{ {
++count; ++count;
REQUIRE( REQUIRE(

View file

@ -51,7 +51,7 @@ struct bar : foo
cpp_entity_index idx; cpp_entity_index idx;
auto file = parse(idx, "cpp_member_function.cpp", code); auto file = parse(idx, "cpp_member_function.cpp", code);
auto count = test_visit<cpp_member_function>(*file, [&](const cpp_member_function& func) { auto count = test_visit<cpp_member_function>(*file, [&](const cpp_member_function& func) {
REQUIRE(count_children(func) == 0u); REQUIRE(count_children(func.parameters()) == 0u);
REQUIRE(!func.is_variadic()); REQUIRE(!func.is_variadic());
REQUIRE(!func.is_constexpr()); REQUIRE(!func.is_constexpr());
REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_void))); REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_void)));
@ -166,7 +166,7 @@ struct foo
cpp_entity_index idx; cpp_entity_index idx;
auto file = parse(idx, "cpp_conversion_op.cpp", code); auto file = parse(idx, "cpp_conversion_op.cpp", code);
auto count = test_visit<cpp_conversion_op>(*file, [&](const cpp_conversion_op& op) { auto count = test_visit<cpp_conversion_op>(*file, [&](const cpp_conversion_op& op) {
REQUIRE(count_children(op) == 0u); REQUIRE(count_children(op.parameters()) == 0u);
REQUIRE(!op.is_variadic()); REQUIRE(!op.is_variadic());
REQUIRE(op.body_kind() == cpp_function_declaration); REQUIRE(op.body_kind() == cpp_function_declaration);
REQUIRE(op.ref_qualifier() == cpp_ref_none); REQUIRE(op.ref_qualifier() == cpp_ref_none);
@ -241,7 +241,7 @@ struct foo
REQUIRE(!cont.is_variadic()); REQUIRE(!cont.is_variadic());
REQUIRE(cont.name() == "foo"); REQUIRE(cont.name() == "foo");
if (count_children(cont) == 0u) if (count_children(cont.parameters()) == 0u)
{ {
REQUIRE(cont.noexcept_condition()); REQUIRE(cont.noexcept_condition());
REQUIRE( REQUIRE(
@ -252,14 +252,14 @@ struct foo
REQUIRE(!cont.is_constexpr()); REQUIRE(!cont.is_constexpr());
REQUIRE(cont.body_kind() == cpp_function_defaulted); REQUIRE(cont.body_kind() == cpp_function_defaulted);
} }
else if (count_children(cont) == 1u) else if (count_children(cont.parameters()) == 1u)
{ {
REQUIRE(!cont.noexcept_condition()); REQUIRE(!cont.noexcept_condition());
REQUIRE(cont.is_explicit()); REQUIRE(cont.is_explicit());
REQUIRE(!cont.is_constexpr()); REQUIRE(!cont.is_constexpr());
REQUIRE(cont.body_kind() == cpp_function_declaration); REQUIRE(cont.body_kind() == cpp_function_declaration);
} }
else if (count_children(cont) == 2u) else if (count_children(cont.parameters()) == 2u)
{ {
REQUIRE(!cont.noexcept_condition()); REQUIRE(!cont.noexcept_condition());
REQUIRE(!cont.is_explicit()); REQUIRE(!cont.is_explicit());
@ -302,7 +302,7 @@ struct d : c
auto file = parse({}, "cpp_destructor.cpp", code); auto file = parse({}, "cpp_destructor.cpp", code);
auto count = test_visit<cpp_destructor>(*file, [&](const cpp_destructor& dtor) { auto count = test_visit<cpp_destructor>(*file, [&](const cpp_destructor& dtor) {
REQUIRE(count_children(dtor) == 0u); REQUIRE(count_children(dtor.parameters()) == 0u);
REQUIRE(!dtor.is_variadic()); REQUIRE(!dtor.is_variadic());
if (dtor.name() == "~a") if (dtor.name() == "~a")

View file

@ -236,7 +236,7 @@ using d = void;
REQUIRE(!param.default_template()); REQUIRE(!param.default_template());
auto no = 0u; auto no = 0u;
for (auto& p_param : param) for (auto& p_param : param.parameters())
{ {
++no; ++no;
REQUIRE(p_param.name() == "T"); REQUIRE(p_param.name() == "T");
@ -250,18 +250,18 @@ using d = void;
REQUIRE(param.is_variadic()); REQUIRE(param.is_variadic());
REQUIRE(!param.default_template()); REQUIRE(!param.default_template());
auto cur = param.begin(); auto cur = param.parameters().begin();
REQUIRE(cur != param.end()); REQUIRE(cur != param.parameters().end());
REQUIRE(cur->name().empty()); REQUIRE(cur->name().empty());
REQUIRE(cur->kind() == cpp_entity_kind::non_type_template_parameter_t); REQUIRE(cur->kind() == cpp_entity_kind::non_type_template_parameter_t);
++cur; ++cur;
REQUIRE(cur != param.end()); REQUIRE(cur != param.parameters().end());
REQUIRE(cur->name().empty()); REQUIRE(cur->name().empty());
REQUIRE(cur->kind() == cpp_entity_kind::template_type_parameter_t); REQUIRE(cur->kind() == cpp_entity_kind::template_type_parameter_t);
++cur; ++cur;
REQUIRE(cur == param.end()); REQUIRE(cur == param.parameters().end());
} }
else if (param.name() == "C") else if (param.name() == "C")
{ {
@ -276,7 +276,7 @@ using d = void;
REQUIRE(entities[0]->name() == "def"); REQUIRE(entities[0]->name() == "def");
auto no = 0u; auto no = 0u;
for (auto& p_param : param) for (auto& p_param : param.parameters())
{ {
++no; ++no;
REQUIRE(p_param.name() == ""); REQUIRE(p_param.name() == "");
@ -297,13 +297,14 @@ using d = void;
REQUIRE(entities[0]->name() == "a"); REQUIRE(entities[0]->name() == "a");
auto no = 0u; auto no = 0u;
for (auto& p_param : param) for (auto& p_param : param.parameters())
{ {
++no; ++no;
REQUIRE(p_param.name() == ""); REQUIRE(p_param.name() == "");
REQUIRE(p_param.kind() == cpp_entity_kind::template_template_parameter_t); REQUIRE(p_param.kind() == cpp_entity_kind::template_template_parameter_t);
for (auto& p_p_param : for (auto& p_p_param :
static_cast<const cpp_template_template_parameter&>(p_param)) static_cast<const cpp_template_template_parameter&>(p_param)
.parameters())
{ {
++no; ++no;
REQUIRE(p_p_param.name() == ""); REQUIRE(p_p_param.name() == "");