Add semantic parent to forward declarable entities

This commit is contained in:
Jonathan Müller 2017-04-14 16:44:25 +02:00
commit 599f2bbff8
20 changed files with 260 additions and 109 deletions

View file

@ -70,11 +70,14 @@ class e
namespace ns
{
/// struct base{
/// };
struct base {};
/// struct base;
struct base;
}
/// struct ns::base{
/// };
struct ns::base {};
/// struct f
/// :ns::base,virtual protected e{
/// };
@ -296,5 +299,5 @@ struct g
else
REQUIRE(false);
});
REQUIRE(count == 11u);
REQUIRE(count == 12u);
}

View file

@ -41,9 +41,17 @@ enum class b : int
b_c
};
/// enum c
/// :int;
enum c : int;
namespace ns
{
/// enum c
/// :int;
enum c : int;
}
/// enum ns::c
/// :int{
/// };
enum ns::c : int {};
)";
cpp_entity_index idx;
@ -137,18 +145,21 @@ enum c : int;
}
else if (e.name() == "c")
{
REQUIRE(e.is_declaration());
REQUIRE(!e.is_definition());
if (e.semantic_scope() == "ns::")
REQUIRE(e.is_definition());
else
REQUIRE(e.is_declaration());
REQUIRE(!e.is_scoped());
REQUIRE(e.has_explicit_type());
REQUIRE(equal_types(idx, e.underlying_type(), *cpp_builtin_type::build(cpp_int)));
REQUIRE(count_children(e) == 0u);
auto definition = get_definition(idx, e);
REQUIRE(!definition);
REQUIRE(definition);
}
else
REQUIRE(false);
});
REQUIRE(count == 4u);
REQUIRE(count == 5u);
}

View file

@ -170,20 +170,23 @@ int d() {}
}
else if (func.name() == "e")
REQUIRE(func.is_definition());
else if (func.name() == "b::b")
else if (func.name() == "b")
{
REQUIRE(func.semantic_scope() == "b::");
REQUIRE(func.is_declaration());
REQUIRE(func.definition());
check_definition(func.definition().value(), "b::b");
}
else if (func.name() == "b::f")
else if (func.name() == "f")
{
REQUIRE(func.semantic_scope() == "b::");
REQUIRE(func.is_declaration());
REQUIRE(func.definition());
check_definition(func.definition().value(), "b::f");
}
else if (func.name() == "b::operator int")
else if (func.name() == "operator int")
{
REQUIRE(func.semantic_scope() == "b::");
REQUIRE(func.is_declaration());
REQUIRE(func.definition());
check_definition(func.definition().value(), "operator int");

View file

@ -198,7 +198,7 @@ void ns::l()
REQUIRE(func.storage_class() == cpp_storage_class_static);
}
}
else if (func.name() == "k" || func.name() == "l" || func.name() == "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);
@ -210,9 +210,12 @@ void ns::l()
if (func.name() == "k")
check_body(func, cpp_function_deleted);
else if (func.name() == "l")
check_body(func, cpp_function_declaration);
else if (func.name() == "ns::l")
check_body(func, cpp_function_definition);
{
if (func.semantic_scope() == "ns::")
check_body(func, cpp_function_definition);
else
check_body(func, cpp_function_declaration);
}
}
else
REQUIRE(false);
@ -247,16 +250,16 @@ void foo::a() {}
REQUIRE(count_children(func.parameters()) == 0u);
REQUIRE(func.storage_class() == cpp_storage_class_static);
if (func.name() == "a" || func.name() == "foo::a")
if (func.name() == "a")
{
REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_void)));
REQUIRE(!func.noexcept_condition());
REQUIRE(!func.is_constexpr());
if (func.name() == "a")
REQUIRE(func.body_kind() == cpp_function_declaration);
else
if (func.semantic_scope() == "foo::")
REQUIRE(func.body_kind() == cpp_function_definition);
else
REQUIRE(func.body_kind() == cpp_function_declaration);
}
else if (func.name() == "b")
{

View file

@ -185,11 +185,12 @@ d::d(const int&);
REQUIRE(!tfunc.arguments_exposed());
auto templ = tfunc.primary_template();
if (tfunc.name() == "d::operator int")
if (tfunc.name() == "operator int")
REQUIRE(equal_ref(idx, templ, cpp_template_ref(cpp_entity_id(""), tfunc.name()),
"d::operator T"));
else
REQUIRE(equal_ref(idx, templ, cpp_template_ref(cpp_entity_id(""), tfunc.name())));
REQUIRE(equal_ref(idx, templ, cpp_template_ref(cpp_entity_id(""), tfunc.name()),
(tfunc.function().semantic_scope() + tfunc.name()).c_str()));
if (tfunc.name() == "a")
{
@ -197,6 +198,7 @@ d::d(const int&);
REQUIRE(tfunc.function().kind() == cpp_entity_kind::function_t);
auto& func = static_cast<const cpp_function&>(tfunc.function());
REQUIRE(func.semantic_scope() == "");
REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_int)));
@ -214,12 +216,13 @@ d::d(const int&);
}
REQUIRE(count == 1u);
}
else if (tfunc.name() == "d::b")
else if (tfunc.name() == "b")
{
REQUIRE(tfunc.unexposed_arguments() == "0,int");
REQUIRE(tfunc.function().kind() == cpp_entity_kind::function_t);
auto& func = static_cast<const cpp_function&>(tfunc.function());
REQUIRE(func.semantic_scope() == "d::");
cpp_template_instantiation_type::builder builder(
cpp_template_ref(cpp_entity_id(""), "type"));
@ -234,17 +237,18 @@ d::d(const int&);
}
REQUIRE(count == 1u);
}
else if (tfunc.name() == "d::c")
else if (tfunc.name() == "c")
{
REQUIRE(tfunc.unexposed_arguments() == "");
REQUIRE(tfunc.function().kind() == cpp_entity_kind::member_function_t);
auto& func = static_cast<const cpp_member_function&>(tfunc.function());
REQUIRE(func.semantic_scope() == "d::");
REQUIRE(func.cv_qualifier() == cpp_cv_none);
REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_int)));
}
else if (tfunc.name() == "d::operator int")
else if (tfunc.name() == "operator int")
{
REQUIRE(tfunc.unexposed_arguments() == "");
@ -254,12 +258,13 @@ d::d(const int&);
REQUIRE(equal_types(idx, func.return_type(), *cpp_builtin_type::build(cpp_int)));
}
else if (tfunc.name() == "d::d")
else if (tfunc.name() == "d")
{
REQUIRE(tfunc.unexposed_arguments() == "");
REQUIRE(tfunc.function().kind() == cpp_entity_kind::constructor_t);
auto& func = static_cast<const cpp_constructor&>(tfunc.function());
REQUIRE(func.semantic_scope() == "d::");
auto count = 0u;
for (auto& param : func.parameters())

View file

@ -12,6 +12,7 @@ TEST_CASE("cpp_member_function")
{
auto code = R"(
// no need to test parameters/return types
template <typename T>
struct foo
{
/// void a();
@ -39,7 +40,11 @@ struct foo
void j() = delete;
};
struct bar : foo
/// void foo<T>::a();
template <typename T>
void foo<T>::a() {}
struct bar : foo<int>
{
/// virtual void g() override;
void g();
@ -59,11 +64,13 @@ struct bar : foo
REQUIRE(!func.noexcept_condition());
if (func.name() != "g" && func.name() != "h")
REQUIRE(!func.virtual_info());
if (func.name() != "i" && func.name() != "j")
if (func.semantic_scope().empty() && func.name() != "i" && func.name() != "j")
REQUIRE(func.body_kind() == cpp_function_declaration);
if (func.name() == "a")
{
if (func.semantic_scope() == "foo::")
REQUIRE(func.is_definition());
REQUIRE(func.cv_qualifier() == cpp_cv_none);
REQUIRE(func.ref_qualifier() == cpp_ref_none);
}
@ -140,7 +147,7 @@ struct bar : foo
else
REQUIRE(false);
});
REQUIRE(count == 12u);
REQUIRE(count == 13u);
}
TEST_CASE("cpp_conversion_op")
@ -248,13 +255,14 @@ foo<T>::foo(int) {}
auto file = parse(idx, "cpp_constructor.cpp", code);
auto count = test_visit<cpp_constructor>(*file, [&](const cpp_constructor& cont) {
REQUIRE(!cont.is_variadic());
REQUIRE(cont.name() == "foo");
if (cont.is_definition() && count_children(cont.parameters()) == 1u)
if (cont.semantic_parent())
{
if (is_template)
REQUIRE(cont.name() == "foo<T>::foo");
REQUIRE(cont.semantic_parent().value().name() == "foo<T>::");
else
REQUIRE(cont.name() == "foo::foo");
REQUIRE(cont.semantic_parent().value().name() == "foo::");
REQUIRE(!cont.noexcept_condition());
REQUIRE(!cont.is_constexpr());
}

View file

@ -10,6 +10,7 @@
#include <catch.hpp>
#include <cppast/code_generator.hpp>
#include <cppast/cpp_class.hpp>
#include <cppast/cpp_entity_kind.hpp>
#include <cppast/cpp_expression.hpp>
#include <cppast/cpp_type.hpp>
@ -157,7 +158,13 @@ inline std::string full_name(const cppast::cpp_entity& e)
scopes = cur_scope.name() + "::" + scopes;
});
return scopes + e.name();
if (e.kind() == cppast::cpp_entity_kind::class_t)
{
auto& c = static_cast<const cppast::cpp_class&>(e);
return scopes + c.semantic_scope() + c.name();
}
else
return scopes + e.name();
}
// checks the full name/parent