Add signature() to cpp_function_base
This commit is contained in:
parent
592eb0284f
commit
93d2c58f7f
8 changed files with 112 additions and 22 deletions
|
|
@ -94,6 +94,14 @@ namespace cppast
|
|||
return variadic_;
|
||||
}
|
||||
|
||||
/// \returns The signature of the function,
|
||||
/// i.e. parameters and cv/ref-qualifiers if a member function.
|
||||
/// It has the form `(int,char,...) const`.
|
||||
std::string signature() const
|
||||
{
|
||||
return do_get_signature();
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Builder class for functions.
|
||||
///
|
||||
|
|
@ -176,6 +184,10 @@ namespace cppast
|
|||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
/// \returns The signature, it is called by [*signature()]().
|
||||
virtual std::string do_get_signature() const;
|
||||
|
||||
private:
|
||||
detail::intrusive_list<cpp_function_parameter> parameters_;
|
||||
std::unique_ptr<cpp_expression> noexcept_expr_;
|
||||
|
|
|
|||
|
|
@ -23,24 +23,10 @@ namespace cppast
|
|||
pure, //< Set if the function is pure.
|
||||
override, //< Set if the function overrides a base class function.
|
||||
final, //< Set if the function is marked `final`.
|
||||
};
|
||||
} // namespace cppast
|
||||
|
||||
/// \exclude
|
||||
namespace type_safe
|
||||
{
|
||||
template <>
|
||||
struct flag_set_traits<cppast::cpp_virtual_flags> : std::true_type
|
||||
{
|
||||
static constexpr std::size_t size() noexcept
|
||||
{
|
||||
return 3u;
|
||||
}
|
||||
_flag_set_size, //< \exclude
|
||||
};
|
||||
} // namespace type_safe
|
||||
|
||||
namespace cppast
|
||||
{
|
||||
/// The `virtual` information of a member function.
|
||||
///
|
||||
/// This is an optional of the combination of the [cppast::cpp_virtual_flags]().
|
||||
|
|
@ -161,6 +147,9 @@ namespace cppast
|
|||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string do_get_signature() const override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<cpp_type> return_type_;
|
||||
cpp_virtual virtual_;
|
||||
|
|
|
|||
|
|
@ -434,6 +434,9 @@ namespace cppast
|
|||
// write prefix, variadic, name, suffix
|
||||
void write_type(code_generator::output& output, const cpp_type& type, std::string name,
|
||||
bool is_variadic = false);
|
||||
|
||||
// simple to_string() for types
|
||||
std::string to_string(const cpp_type& type);
|
||||
} // namespace detail
|
||||
} // namespace cppast
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,22 @@ cpp_entity_kind cpp_function_parameter::do_get_entity_kind() const noexcept
|
|||
return kind();
|
||||
}
|
||||
|
||||
std::string cpp_function_base::do_get_signature() const
|
||||
{
|
||||
std::string result = "(";
|
||||
for (auto& param : parameters())
|
||||
result += detail::to_string(param.type()) + ',';
|
||||
if (is_variadic())
|
||||
result += "...";
|
||||
|
||||
if (result.back() == ',')
|
||||
result.back() = ')';
|
||||
else
|
||||
result.push_back(')');
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
cpp_entity_kind cpp_function::kind() noexcept
|
||||
{
|
||||
return cpp_entity_kind::function_t;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,23 @@
|
|||
|
||||
using namespace cppast;
|
||||
|
||||
std::string cpp_member_function_base::do_get_signature() const
|
||||
{
|
||||
auto result = cpp_function_base::do_get_signature();
|
||||
|
||||
if (is_const(cv_qualifier()))
|
||||
result += " const";
|
||||
if (is_volatile(cv_qualifier()))
|
||||
result += " volatile";
|
||||
|
||||
if (ref_qualifier() == cpp_ref_lvalue)
|
||||
result += " &";
|
||||
else if (ref_qualifier() == cpp_ref_rvalue)
|
||||
result += " &&";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
cpp_entity_kind cpp_member_function::kind() noexcept
|
||||
{
|
||||
return cpp_entity_kind::member_function_t;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <cppast/cpp_entity.hpp>
|
||||
#include <cppast/cpp_entity_kind.hpp>
|
||||
#include <cppast/cpp_function_type.hpp>
|
||||
#include <cppast/cpp_type_alias.hpp>
|
||||
#include <cppast/cpp_template.hpp>
|
||||
|
||||
using namespace cppast;
|
||||
|
|
@ -545,3 +546,37 @@ void detail::write_type(code_generator::output& output, const cpp_type& type, st
|
|||
output << operator_ws << punctuation("...") << operator_ws;
|
||||
write_type_suffix(output, type);
|
||||
}
|
||||
|
||||
std::string detail::to_string(const cpp_type& type)
|
||||
{
|
||||
class to_string_generator : public code_generator
|
||||
{
|
||||
public:
|
||||
std::string get()
|
||||
{
|
||||
return std::move(result_);
|
||||
}
|
||||
|
||||
private:
|
||||
void do_indent() override
|
||||
{
|
||||
}
|
||||
|
||||
void do_unindent() override
|
||||
{
|
||||
}
|
||||
|
||||
void do_write_token_seq(string_view tokens) override
|
||||
{
|
||||
result_ += tokens.c_str();
|
||||
}
|
||||
|
||||
std::string result_;
|
||||
} generator;
|
||||
|
||||
// just a dummy type for the output
|
||||
static auto dummy_entity = cpp_type_alias::build("foo", cpp_builtin_type::build(cpp_int));
|
||||
to_string_generator::output output(type_safe::ref(generator), type_safe::ref(*dummy_entity));
|
||||
write_type(output, type, "");
|
||||
return generator.get();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,12 +77,13 @@ void ns::l()
|
|||
if (func.name() == "a")
|
||||
{
|
||||
REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_void)));
|
||||
REQUIRE(count_children(func.parameters()) == 0u);
|
||||
REQUIRE(func.signature() == "()");
|
||||
REQUIRE(!func.is_variadic());
|
||||
}
|
||||
else if (func.name() == "b")
|
||||
{
|
||||
REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_int)));
|
||||
REQUIRE(func.signature() == "(int,float*)");
|
||||
|
||||
auto count = 0u;
|
||||
for (auto& param : func.parameters())
|
||||
|
|
@ -122,6 +123,7 @@ void ns::l()
|
|||
cpp_ulonglong),
|
||||
"10")),
|
||||
cpp_ref_lvalue)));
|
||||
REQUIRE(func.signature() == "(decltype(42),...)");
|
||||
|
||||
auto count = 0u;
|
||||
for (auto& param : func.parameters())
|
||||
|
|
@ -147,7 +149,7 @@ void ns::l()
|
|||
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(count_children(func.parameters()) == 0u);
|
||||
REQUIRE(func.signature() == "()");
|
||||
REQUIRE(!func.is_variadic());
|
||||
REQUIRE(func.storage_class() == cpp_storage_class_none);
|
||||
REQUIRE(!func.is_constexpr());
|
||||
|
|
@ -172,7 +174,7 @@ void ns::l()
|
|||
|| func.name() == "j")
|
||||
{
|
||||
REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_void)));
|
||||
REQUIRE(count_children(func.parameters()) == 0u);
|
||||
REQUIRE(func.signature() == "()");
|
||||
REQUIRE(!func.is_variadic());
|
||||
REQUIRE(!func.noexcept_condition());
|
||||
check_body(func, cpp_function_declaration);
|
||||
|
|
@ -201,7 +203,7 @@ void ns::l()
|
|||
else if (func.name() == "k" || func.name() == "l")
|
||||
{
|
||||
REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_void)));
|
||||
REQUIRE(count_children(func.parameters()) == 0u);
|
||||
REQUIRE(func.signature() == "()");
|
||||
REQUIRE(!func.is_variadic());
|
||||
REQUIRE(!func.noexcept_condition());
|
||||
REQUIRE(!func.is_constexpr());
|
||||
|
|
@ -247,7 +249,7 @@ void foo::a() {}
|
|||
auto file = parse(idx, "static_cpp_function.cpp", code);
|
||||
auto count = test_visit<cpp_function>(*file, [&](const cpp_function& func) {
|
||||
REQUIRE(!func.is_variadic());
|
||||
REQUIRE(count_children(func.parameters()) == 0u);
|
||||
REQUIRE(func.signature() == "()");
|
||||
REQUIRE(func.storage_class() == cpp_storage_class_static);
|
||||
|
||||
if (func.name() == "a")
|
||||
|
|
|
|||
|
|
@ -57,10 +57,10 @@ struct bar : foo<int>
|
|||
cpp_entity_index idx;
|
||||
auto file = parse(idx, "cpp_member_function.cpp", code);
|
||||
auto count = test_visit<cpp_member_function>(*file, [&](const cpp_member_function& func) {
|
||||
REQUIRE(count_children(func.parameters()) == 0u);
|
||||
REQUIRE(!func.is_variadic());
|
||||
REQUIRE(!func.is_constexpr());
|
||||
REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_void)));
|
||||
|
||||
if (func.name() != "b" && func.name() != "d")
|
||||
REQUIRE(!func.noexcept_condition());
|
||||
if (func.name() != "g" && func.name() != "h")
|
||||
|
|
@ -74,6 +74,7 @@ struct bar : foo<int>
|
|||
REQUIRE(func.is_definition());
|
||||
REQUIRE(func.cv_qualifier() == cpp_cv_none);
|
||||
REQUIRE(func.ref_qualifier() == cpp_ref_none);
|
||||
REQUIRE(func.signature() == "()");
|
||||
}
|
||||
else if (func.name() == "b")
|
||||
{
|
||||
|
|
@ -84,31 +85,37 @@ struct bar : foo<int>
|
|||
"true")));
|
||||
REQUIRE(func.cv_qualifier() == cpp_cv_none);
|
||||
REQUIRE(func.ref_qualifier() == cpp_ref_none);
|
||||
REQUIRE(func.signature() == "()");
|
||||
}
|
||||
else if (func.name() == "c")
|
||||
{
|
||||
REQUIRE(func.cv_qualifier() == cpp_cv_const);
|
||||
REQUIRE(func.ref_qualifier() == cpp_ref_none);
|
||||
REQUIRE(func.signature() == "() const");
|
||||
}
|
||||
else if (func.name() == "d")
|
||||
{
|
||||
REQUIRE(func.cv_qualifier() == cpp_cv_const_volatile);
|
||||
REQUIRE(func.ref_qualifier() == cpp_ref_none);
|
||||
REQUIRE(func.signature() == "() const volatile");
|
||||
}
|
||||
else if (func.name() == "e")
|
||||
{
|
||||
REQUIRE(func.cv_qualifier() == cpp_cv_none);
|
||||
REQUIRE(func.ref_qualifier() == cpp_ref_lvalue);
|
||||
REQUIRE(func.signature() == "() &");
|
||||
}
|
||||
else if (func.name() == "f")
|
||||
{
|
||||
REQUIRE(func.cv_qualifier() == cpp_cv_const_volatile);
|
||||
REQUIRE(func.ref_qualifier() == cpp_ref_rvalue);
|
||||
REQUIRE(func.signature() == "() const volatile &&");
|
||||
}
|
||||
else if (func.name() == "g")
|
||||
{
|
||||
REQUIRE(func.cv_qualifier() == cpp_cv_none);
|
||||
REQUIRE(func.ref_qualifier() == cpp_ref_none);
|
||||
REQUIRE(func.signature() == "()");
|
||||
REQUIRE(func.virtual_info());
|
||||
if (func.parent().value().name() == "foo")
|
||||
REQUIRE(func.virtual_info().value() == type_safe::flag_set<cpp_virtual_flags>{});
|
||||
|
|
@ -124,6 +131,7 @@ struct bar : foo<int>
|
|||
{
|
||||
REQUIRE(func.cv_qualifier() == cpp_cv_none);
|
||||
REQUIRE(func.ref_qualifier() == cpp_ref_none);
|
||||
REQUIRE(func.signature() == "()");
|
||||
REQUIRE(func.virtual_info());
|
||||
if (func.parent().value().name() == "foo")
|
||||
REQUIRE(func.virtual_info().value() == cpp_virtual_flags::pure);
|
||||
|
|
@ -137,12 +145,14 @@ struct bar : foo<int>
|
|||
{
|
||||
REQUIRE(func.cv_qualifier() == cpp_cv_none);
|
||||
REQUIRE(func.ref_qualifier() == cpp_ref_none);
|
||||
REQUIRE(func.signature() == "()");
|
||||
REQUIRE(func.body_kind() == cpp_function_definition);
|
||||
}
|
||||
else if (func.name() == "j")
|
||||
{
|
||||
REQUIRE(func.cv_qualifier() == cpp_cv_none);
|
||||
REQUIRE(func.ref_qualifier() == cpp_ref_none);
|
||||
REQUIRE(func.signature() == "()");
|
||||
REQUIRE(func.body_kind() == cpp_function_deleted);
|
||||
}
|
||||
else
|
||||
|
|
@ -207,16 +217,19 @@ struct foo
|
|||
*cpp_reference_type::build(cpp_builtin_type::build(cpp_int),
|
||||
cpp_ref_lvalue)));
|
||||
REQUIRE(op.cv_qualifier() == cpp_cv_none);
|
||||
REQUIRE(op.signature() == "()");
|
||||
}
|
||||
else if (op.is_explicit() && !op.is_constexpr())
|
||||
{
|
||||
REQUIRE(op.name() == "operator bool");
|
||||
REQUIRE(equal_types(idx, op.return_type(), *cpp_builtin_type::build(cpp_bool)));
|
||||
REQUIRE(op.cv_qualifier() == cpp_cv_const);
|
||||
REQUIRE(op.signature() == "() const");
|
||||
}
|
||||
else if (!op.is_explicit() && op.is_constexpr())
|
||||
{
|
||||
REQUIRE(op.cv_qualifier() == cpp_cv_none);
|
||||
REQUIRE(op.signature() == "()");
|
||||
if (op.name() == "operator ns::type<int>")
|
||||
{
|
||||
REQUIRE(op.return_type().kind() == cpp_type_kind::template_instantiation_t);
|
||||
|
|
@ -316,6 +329,7 @@ foo<T>::foo(int) {}
|
|||
REQUIRE(!cont.is_explicit());
|
||||
REQUIRE(!cont.is_constexpr());
|
||||
REQUIRE(cont.body_kind() == cpp_function_defaulted);
|
||||
REQUIRE(cont.signature() == "()");
|
||||
}
|
||||
else if (count_children(cont.parameters()) == 1u)
|
||||
{
|
||||
|
|
@ -323,6 +337,7 @@ foo<T>::foo(int) {}
|
|||
REQUIRE(cont.is_explicit());
|
||||
REQUIRE(!cont.is_constexpr());
|
||||
REQUIRE(cont.body_kind() == cpp_function_declaration);
|
||||
REQUIRE(cont.signature() == "(int)");
|
||||
}
|
||||
else if (count_children(cont.parameters()) == 2u)
|
||||
{
|
||||
|
|
@ -330,6 +345,7 @@ foo<T>::foo(int) {}
|
|||
REQUIRE(!cont.is_explicit());
|
||||
REQUIRE(cont.is_constexpr());
|
||||
REQUIRE(cont.body_kind() == cpp_function_deleted);
|
||||
REQUIRE(cont.signature() == "(int,char)");
|
||||
}
|
||||
else
|
||||
REQUIRE(false);
|
||||
|
|
@ -372,7 +388,7 @@ d::~d() {}
|
|||
|
||||
auto file = parse({}, "cpp_destructor.cpp", code);
|
||||
auto count = test_visit<cpp_destructor>(*file, [&](const cpp_destructor& dtor) {
|
||||
REQUIRE(count_children(dtor.parameters()) == 0u);
|
||||
REQUIRE(dtor.signature() == "()");
|
||||
REQUIRE(!dtor.is_variadic());
|
||||
|
||||
if (dtor.name() == "~a")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue