Add support for consteval
This commit is contained in:
parent
ce218dfb8a
commit
1b03d106ab
6 changed files with 250 additions and 9 deletions
|
|
@ -226,6 +226,12 @@ public:
|
||||||
{
|
{
|
||||||
function->constexpr_ = true;
|
function->constexpr_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \effects Marks the function as `consteval`.
|
||||||
|
void is_consteval()
|
||||||
|
{
|
||||||
|
function->consteval_ = true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \returns A reference to the return [cppast::cpp_type]().
|
/// \returns A reference to the return [cppast::cpp_type]().
|
||||||
|
|
@ -248,17 +254,24 @@ public:
|
||||||
return constexpr_;
|
return constexpr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \returns Whether the function is marked `consteval`.
|
||||||
|
bool is_consteval() const noexcept
|
||||||
|
{
|
||||||
|
return consteval_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cpp_entity_kind do_get_entity_kind() const noexcept override;
|
cpp_entity_kind do_get_entity_kind() const noexcept override;
|
||||||
|
|
||||||
cpp_function(std::string name, std::unique_ptr<cpp_type> ret)
|
cpp_function(std::string name, std::unique_ptr<cpp_type> ret)
|
||||||
: cpp_function_base(std::move(name)), return_type_(std::move(ret)),
|
: cpp_function_base(std::move(name)), return_type_(std::move(ret)),
|
||||||
storage_(cpp_storage_class_auto), constexpr_(false)
|
storage_(cpp_storage_class_auto), constexpr_(false), consteval_(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::unique_ptr<cpp_type> return_type_;
|
std::unique_ptr<cpp_type> return_type_;
|
||||||
cpp_storage_class_specifiers storage_;
|
cpp_storage_class_specifiers storage_;
|
||||||
bool constexpr_;
|
bool constexpr_;
|
||||||
|
bool consteval_;
|
||||||
};
|
};
|
||||||
} // namespace cppast
|
} // namespace cppast
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,12 @@ public:
|
||||||
return constexpr_;
|
return constexpr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \returns Whether or not the member function is `consteval`.
|
||||||
|
bool is_consteval() const noexcept
|
||||||
|
{
|
||||||
|
return consteval_;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Builder class for member functions.
|
/// Builder class for member functions.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
@ -132,6 +138,12 @@ protected:
|
||||||
static_cast<cpp_member_function_base&>(*this->function).constexpr_ = true;
|
static_cast<cpp_member_function_base&>(*this->function).constexpr_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \effects Marks the function as `consteval`.
|
||||||
|
void is_consteval() noexcept
|
||||||
|
{
|
||||||
|
static_cast<cpp_member_function_base&>(*this->function).consteval_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
basic_member_builder() noexcept = default;
|
basic_member_builder() noexcept = default;
|
||||||
};
|
};
|
||||||
|
|
@ -139,7 +151,7 @@ protected:
|
||||||
/// \effects Sets name and return type, as well as the rest to defaults.
|
/// \effects Sets name and return type, as well as the rest to defaults.
|
||||||
cpp_member_function_base(std::string name, std::unique_ptr<cpp_type> return_type)
|
cpp_member_function_base(std::string name, std::unique_ptr<cpp_type> return_type)
|
||||||
: cpp_function_base(std::move(name)), return_type_(std::move(return_type)), cv_(cpp_cv_none),
|
: cpp_function_base(std::move(name)), return_type_(std::move(return_type)), cv_(cpp_cv_none),
|
||||||
ref_(cpp_ref_none), constexpr_(false)
|
ref_(cpp_ref_none), constexpr_(false), consteval_(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -151,6 +163,7 @@ private:
|
||||||
cpp_cv cv_;
|
cpp_cv cv_;
|
||||||
cpp_reference ref_;
|
cpp_reference ref_;
|
||||||
bool constexpr_;
|
bool constexpr_;
|
||||||
|
bool consteval_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A [cppast::cpp_entity]() modelling a member function.
|
/// A [cppast::cpp_entity]() modelling a member function.
|
||||||
|
|
@ -239,6 +252,12 @@ public:
|
||||||
{
|
{
|
||||||
function->constexpr_ = true;
|
function->constexpr_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \effects Marks the constructor `consteval`.
|
||||||
|
void is_consteval() noexcept
|
||||||
|
{
|
||||||
|
function->consteval_ = true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \returns Whether or not the constructor is `explicit`.
|
/// \returns Whether or not the constructor is `explicit`.
|
||||||
|
|
@ -253,15 +272,22 @@ public:
|
||||||
return constexpr_;
|
return constexpr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \returns Whether or not the constructor is `consteval`.
|
||||||
|
bool is_consteval() const noexcept
|
||||||
|
{
|
||||||
|
return consteval_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cpp_constructor(std::string name)
|
cpp_constructor(std::string name)
|
||||||
: cpp_function_base(std::move(name)), explicit_(false), constexpr_(false)
|
: cpp_function_base(std::move(name)), explicit_(false), constexpr_(false), consteval_(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
cpp_entity_kind do_get_entity_kind() const noexcept override;
|
cpp_entity_kind do_get_entity_kind() const noexcept override;
|
||||||
|
|
||||||
bool explicit_;
|
bool explicit_;
|
||||||
bool constexpr_;
|
bool constexpr_;
|
||||||
|
bool consteval_;
|
||||||
|
|
||||||
friend basic_builder<cpp_constructor>;
|
friend basic_builder<cpp_constructor>;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -465,7 +465,7 @@ bool write_variable_base(code_generator::output& output, const cpp_variable_base
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_storage_class(code_generator::output& output, cpp_storage_class_specifiers storage,
|
void write_storage_class(code_generator::output& output, cpp_storage_class_specifiers storage,
|
||||||
bool is_constexpr)
|
bool is_constexpr, bool is_consteval)
|
||||||
{
|
{
|
||||||
if (is_static(storage))
|
if (is_static(storage))
|
||||||
output << keyword("static") << whitespace;
|
output << keyword("static") << whitespace;
|
||||||
|
|
@ -475,6 +475,8 @@ void write_storage_class(code_generator::output& output, cpp_storage_class_speci
|
||||||
output << keyword("thread_local") << whitespace;
|
output << keyword("thread_local") << whitespace;
|
||||||
if (is_constexpr)
|
if (is_constexpr)
|
||||||
output << keyword("constexpr") << whitespace;
|
output << keyword("constexpr") << whitespace;
|
||||||
|
else if (is_consteval)
|
||||||
|
output << keyword("consteval") << whitespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool generate_variable(code_generator& generator, const cpp_variable& var,
|
bool generate_variable(code_generator& generator, const cpp_variable& var,
|
||||||
|
|
@ -483,7 +485,7 @@ bool generate_variable(code_generator& generator, const cpp_variable& var,
|
||||||
code_generator::output output(type_safe::ref(generator), type_safe::ref(var), cur_access);
|
code_generator::output output(type_safe::ref(generator), type_safe::ref(var), cur_access);
|
||||||
if (output)
|
if (output)
|
||||||
{
|
{
|
||||||
write_storage_class(output, var.storage_class(), var.is_constexpr());
|
write_storage_class(output, var.storage_class(), var.is_constexpr(), false);
|
||||||
|
|
||||||
write_variable_base(output, var, var.name());
|
write_variable_base(output, var, var.name());
|
||||||
output << punctuation(";") << newl;
|
output << punctuation(";") << newl;
|
||||||
|
|
@ -602,7 +604,7 @@ bool generate_function(code_generator& generator, const cpp_function& func,
|
||||||
{
|
{
|
||||||
if (is_friended(func))
|
if (is_friended(func))
|
||||||
output << keyword("friend") << whitespace;
|
output << keyword("friend") << whitespace;
|
||||||
write_storage_class(output, func.storage_class(), func.is_constexpr());
|
write_storage_class(output, func.storage_class(), func.is_constexpr(), func.is_consteval());
|
||||||
|
|
||||||
if (output.options() & code_generator::exclude_return)
|
if (output.options() & code_generator::exclude_return)
|
||||||
output.excluded(func) << whitespace;
|
output.excluded(func) << whitespace;
|
||||||
|
|
@ -705,6 +707,8 @@ bool generate_member_function(code_generator& generator, const cpp_member_functi
|
||||||
output << keyword("friend") << whitespace;
|
output << keyword("friend") << whitespace;
|
||||||
if (func.is_constexpr())
|
if (func.is_constexpr())
|
||||||
output << keyword("constexpr") << whitespace;
|
output << keyword("constexpr") << whitespace;
|
||||||
|
else if (func.is_consteval())
|
||||||
|
output << keyword("consteval") << whitespace;
|
||||||
else
|
else
|
||||||
write_prefix_virtual(output, func.virtual_info());
|
write_prefix_virtual(output, func.virtual_info());
|
||||||
|
|
||||||
|
|
@ -756,6 +760,8 @@ bool generate_conversion_op(code_generator& generator, const cpp_conversion_op&
|
||||||
output << keyword("explicit") << whitespace;
|
output << keyword("explicit") << whitespace;
|
||||||
if (op.is_constexpr())
|
if (op.is_constexpr())
|
||||||
output << keyword("constexpr") << whitespace;
|
output << keyword("constexpr") << whitespace;
|
||||||
|
else if (op.is_consteval())
|
||||||
|
output << keyword("consteval") << whitespace;
|
||||||
else
|
else
|
||||||
write_prefix_virtual(output, op.virtual_info());
|
write_prefix_virtual(output, op.virtual_info());
|
||||||
|
|
||||||
|
|
@ -791,6 +797,8 @@ bool generate_constructor(code_generator& generator, const cpp_constructor& ctor
|
||||||
output << keyword("explicit") << whitespace;
|
output << keyword("explicit") << whitespace;
|
||||||
if (ctor.is_constexpr())
|
if (ctor.is_constexpr())
|
||||||
output << keyword("constexpr") << whitespace;
|
output << keyword("constexpr") << whitespace;
|
||||||
|
if (ctor.is_consteval())
|
||||||
|
output << keyword("consteval") << whitespace;
|
||||||
|
|
||||||
output << identifier(ctor.semantic_scope()) << identifier(ctor.name());
|
output << identifier(ctor.semantic_scope()) << identifier(ctor.name());
|
||||||
write_function_parameters(output, ctor);
|
write_function_parameters(output, ctor);
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,7 @@ struct prefix_info
|
||||||
{
|
{
|
||||||
cpp_attribute_list attributes;
|
cpp_attribute_list attributes;
|
||||||
bool is_constexpr = false;
|
bool is_constexpr = false;
|
||||||
|
bool is_consteval = false;
|
||||||
bool is_virtual = false;
|
bool is_virtual = false;
|
||||||
bool is_explicit = false;
|
bool is_explicit = false;
|
||||||
bool is_friend = false;
|
bool is_friend = false;
|
||||||
|
|
@ -284,7 +285,9 @@ prefix_info parse_prefix_info(detail::cxtoken_stream& stream, const char* name,
|
||||||
|
|
||||||
while (!stream.done() && !prefix_end(stream, name, is_ctor_dtor))
|
while (!stream.done() && !prefix_end(stream, name, is_ctor_dtor))
|
||||||
{
|
{
|
||||||
if (detail::skip_if(stream, "constexpr"))
|
if (detail::skip_if(stream, "consteval"))
|
||||||
|
result.is_consteval = true;
|
||||||
|
else if (detail::skip_if(stream, "constexpr"))
|
||||||
result.is_constexpr = true;
|
result.is_constexpr = true;
|
||||||
else if (detail::skip_if(stream, "virtual"))
|
else if (detail::skip_if(stream, "virtual"))
|
||||||
result.is_virtual = true;
|
result.is_virtual = true;
|
||||||
|
|
@ -534,8 +537,13 @@ std::unique_ptr<cpp_entity> parse_cpp_function_impl(const detail::parse_context&
|
||||||
builder.storage_class(cpp_storage_class_specifiers(
|
builder.storage_class(cpp_storage_class_specifiers(
|
||||||
detail::get_storage_class(cur)
|
detail::get_storage_class(cur)
|
||||||
| (is_static ? cpp_storage_class_static : cpp_storage_class_none)));
|
| (is_static ? cpp_storage_class_static : cpp_storage_class_none)));
|
||||||
|
|
||||||
|
DEBUG_ASSERT(!(prefix.is_constexpr && prefix.is_consteval), detail::parse_error_handler{}, cur,
|
||||||
|
"function cannot be both constexpr and consteval");
|
||||||
if (prefix.is_constexpr)
|
if (prefix.is_constexpr)
|
||||||
builder.is_constexpr();
|
builder.is_constexpr();
|
||||||
|
else if (prefix.is_consteval)
|
||||||
|
builder.is_consteval();
|
||||||
|
|
||||||
skip_parameters(stream);
|
skip_parameters(stream);
|
||||||
|
|
||||||
|
|
@ -687,6 +695,8 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_member_function(const detail::pars
|
||||||
|
|
||||||
if (prefix.is_constexpr)
|
if (prefix.is_constexpr)
|
||||||
builder.is_constexpr();
|
builder.is_constexpr();
|
||||||
|
else if (prefix.is_consteval)
|
||||||
|
builder.is_consteval();
|
||||||
|
|
||||||
skip_parameters(stream);
|
skip_parameters(stream);
|
||||||
return handle_suffix(context, cur, builder, stream, prefix.is_virtual,
|
return handle_suffix(context, cur, builder, stream, prefix.is_virtual,
|
||||||
|
|
@ -751,6 +761,8 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_conversion_op(const detail::parse_
|
||||||
builder.is_explicit();
|
builder.is_explicit();
|
||||||
else if (prefix.is_constexpr)
|
else if (prefix.is_constexpr)
|
||||||
builder.is_constexpr();
|
builder.is_constexpr();
|
||||||
|
else if (prefix.is_consteval)
|
||||||
|
builder.is_consteval();
|
||||||
|
|
||||||
return handle_suffix(context, cur, builder, stream, prefix.is_virtual,
|
return handle_suffix(context, cur, builder, stream, prefix.is_virtual,
|
||||||
parse_scope(cur, is_friend));
|
parse_scope(cur, is_friend));
|
||||||
|
|
@ -785,6 +797,8 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_constructor(const detail::parse_co
|
||||||
builder.is_constexpr();
|
builder.is_constexpr();
|
||||||
else if (prefix.is_explicit)
|
else if (prefix.is_explicit)
|
||||||
builder.is_explicit();
|
builder.is_explicit();
|
||||||
|
else if (prefix.is_consteval)
|
||||||
|
builder.is_consteval();
|
||||||
|
|
||||||
skip_parameters(stream);
|
skip_parameters(stream);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -274,6 +274,51 @@ void n(int i = int());
|
||||||
REQUIRE(count == 15u);
|
REQUIRE(count == 15u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("consteval cpp_function")
|
||||||
|
{
|
||||||
|
if (libclang_parser::libclang_minor_version() < 60)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto code = R"(
|
||||||
|
/// consteval void p();
|
||||||
|
consteval void p();
|
||||||
|
/// static consteval void q();
|
||||||
|
static consteval void q();
|
||||||
|
)";
|
||||||
|
auto check_body = [](const cpp_function& func, cpp_function_body_kind kind) {
|
||||||
|
REQUIRE(func.body_kind() == kind);
|
||||||
|
REQUIRE(func.is_declaration() == is_declaration(kind));
|
||||||
|
REQUIRE(func.is_definition() == is_definition(kind));
|
||||||
|
};
|
||||||
|
|
||||||
|
cpp_entity_index idx;
|
||||||
|
auto file = parse(idx, "consteval_function.cpp", code, false, cppast::cpp_standard::cpp_2a);
|
||||||
|
auto count = test_visit<cpp_function>(*file, [&](const cpp_function& func) {
|
||||||
|
if (func.name() == "p" || func.name() == "q")
|
||||||
|
{
|
||||||
|
REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_void)));
|
||||||
|
REQUIRE(func.signature() == "()");
|
||||||
|
REQUIRE(!func.is_variadic());
|
||||||
|
REQUIRE(!func.noexcept_condition());
|
||||||
|
check_body(func, cpp_function_declaration);
|
||||||
|
|
||||||
|
if (func.name() == "p")
|
||||||
|
{
|
||||||
|
REQUIRE(func.is_consteval());
|
||||||
|
REQUIRE(func.storage_class() == cpp_storage_class_none);
|
||||||
|
}
|
||||||
|
else if (func.name() == "q")
|
||||||
|
{
|
||||||
|
REQUIRE(func.is_consteval());
|
||||||
|
REQUIRE(func.storage_class() == cpp_storage_class_static);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
REQUIRE(false);
|
||||||
|
});
|
||||||
|
REQUIRE(count == 2u);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("static cpp_function")
|
TEST_CASE("static cpp_function")
|
||||||
{
|
{
|
||||||
auto code = R"(
|
auto code = R"(
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,10 @@
|
||||||
// This file is subject to the license terms in the LICENSE file
|
// This file is subject to the license terms in the LICENSE file
|
||||||
// found in the top-level directory of this distribution.
|
// found in the top-level directory of this distribution.
|
||||||
|
|
||||||
|
#include "test_parser.hpp"
|
||||||
#include <cppast/cpp_member_function.hpp>
|
#include <cppast/cpp_member_function.hpp>
|
||||||
#include <cppast/cpp_template.hpp>
|
#include <cppast/cpp_template.hpp>
|
||||||
|
|
||||||
#include "test_parser.hpp"
|
|
||||||
|
|
||||||
using namespace cppast;
|
using namespace cppast;
|
||||||
|
|
||||||
TEST_CASE("cpp_member_function")
|
TEST_CASE("cpp_member_function")
|
||||||
|
|
@ -454,3 +453,139 @@ e::~e() = default;
|
||||||
});
|
});
|
||||||
REQUIRE(count == 7u);
|
REQUIRE(count == 7u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("consteval cpp_constructor")
|
||||||
|
{
|
||||||
|
if (libclang_parser::libclang_minor_version() < 60)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// only test constructor specific stuff
|
||||||
|
const char* code;
|
||||||
|
auto is_template = false;
|
||||||
|
SECTION("non-template")
|
||||||
|
{
|
||||||
|
code = R"(
|
||||||
|
struct foo
|
||||||
|
{
|
||||||
|
/// consteval foo(int)=delete;
|
||||||
|
consteval foo(int) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
)";
|
||||||
|
}
|
||||||
|
SECTION("template")
|
||||||
|
{
|
||||||
|
is_template = true;
|
||||||
|
code = R"(
|
||||||
|
template <typename T>
|
||||||
|
struct foo
|
||||||
|
{
|
||||||
|
/// consteval foo(int)=delete;
|
||||||
|
consteval foo(int) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
)";
|
||||||
|
}
|
||||||
|
INFO(is_template);
|
||||||
|
|
||||||
|
cpp_entity_index idx;
|
||||||
|
auto file = parse(idx, "consteval_constructor.cpp", code, false, cppast::cpp_standard::cpp_2a);
|
||||||
|
auto count = test_visit<cpp_constructor>(*file, [&](const cpp_constructor& cont) {
|
||||||
|
REQUIRE(!cont.is_variadic());
|
||||||
|
REQUIRE(cont.name() == "foo");
|
||||||
|
|
||||||
|
if (cont.semantic_parent())
|
||||||
|
{
|
||||||
|
if (is_template)
|
||||||
|
REQUIRE(cont.semantic_parent().value().name() == "foo<T>::");
|
||||||
|
else
|
||||||
|
REQUIRE(cont.semantic_parent().value().name() == "foo::");
|
||||||
|
REQUIRE(!cont.noexcept_condition());
|
||||||
|
REQUIRE(!cont.is_constexpr());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
REQUIRE(cont.name() == "foo");
|
||||||
|
|
||||||
|
if (count_children(cont.parameters()) == 1u)
|
||||||
|
{
|
||||||
|
REQUIRE(!cont.noexcept_condition());
|
||||||
|
REQUIRE(!cont.is_explicit());
|
||||||
|
REQUIRE(cont.is_consteval());
|
||||||
|
REQUIRE(cont.body_kind() == cpp_function_deleted);
|
||||||
|
REQUIRE(cont.signature() == "(int)");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
REQUIRE(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
REQUIRE(count == 1u);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("consteval cpp_conversion_op")
|
||||||
|
{
|
||||||
|
if (libclang_parser::libclang_minor_version() < 60)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto code = R"(
|
||||||
|
namespace ns
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
struct type2 {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// most of it only need to be check in member function
|
||||||
|
struct foo
|
||||||
|
{
|
||||||
|
/// consteval operator ns::type2<int>();
|
||||||
|
consteval operator ns::type2<int>()
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// consteval operator ns::type2<char>();
|
||||||
|
consteval operator ns::type2<char>()
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
)";
|
||||||
|
cpp_entity_index idx;
|
||||||
|
auto file = parse(idx, "consteval_op.cpp", code, false, cppast::cpp_standard::cpp_2a);
|
||||||
|
auto count = test_visit<cpp_conversion_op>(*file, [&](const cpp_conversion_op& op) {
|
||||||
|
REQUIRE(count_children(op.parameters()) == 0u);
|
||||||
|
REQUIRE(!op.is_variadic());
|
||||||
|
REQUIRE(op.body_kind() == cpp_function_definition);
|
||||||
|
REQUIRE(op.ref_qualifier() == cpp_ref_none);
|
||||||
|
REQUIRE(!op.virtual_info());
|
||||||
|
REQUIRE(!op.noexcept_condition());
|
||||||
|
|
||||||
|
if (!op.is_explicit() && op.is_consteval())
|
||||||
|
{
|
||||||
|
REQUIRE(op.cv_qualifier() == cpp_cv_none);
|
||||||
|
REQUIRE(op.signature() == "()");
|
||||||
|
if (op.name() == "operator ns::type2<int>")
|
||||||
|
{
|
||||||
|
REQUIRE(op.return_type().kind() == cpp_type_kind::template_instantiation_t);
|
||||||
|
auto& inst = static_cast<const cpp_template_instantiation_type&>(op.return_type());
|
||||||
|
|
||||||
|
REQUIRE(inst.primary_template().name() == "ns::type2");
|
||||||
|
REQUIRE(!inst.arguments_exposed());
|
||||||
|
REQUIRE(inst.unexposed_arguments() == "int");
|
||||||
|
}
|
||||||
|
else if (op.name() == "operator ns::type2<char>")
|
||||||
|
{
|
||||||
|
REQUIRE(op.return_type().kind() == cpp_type_kind::template_instantiation_t);
|
||||||
|
auto& inst = static_cast<const cpp_template_instantiation_type&>(op.return_type());
|
||||||
|
|
||||||
|
REQUIRE(inst.primary_template().name() == "ns::type2");
|
||||||
|
REQUIRE(!inst.arguments_exposed());
|
||||||
|
REQUIRE(inst.unexposed_arguments() == "char");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
REQUIRE(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
REQUIRE(count == 2u);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue