parent
5069f2f167
commit
373717cc5e
2 changed files with 103 additions and 85 deletions
|
|
@ -116,8 +116,10 @@ std::string get_type_spelling(const CXCursor& cur, const CXType& type)
|
|||
};
|
||||
*/
|
||||
|
||||
// auto canonical = detail::cxstring(clang_getTypeSpelling(clang_getCanonicalType(type))).std_str();
|
||||
// auto declaration = detail::cxstring(clang_getCursorSpelling(clang_getTypeDeclaration(type))).std_str();
|
||||
// auto canonical =
|
||||
// detail::cxstring(clang_getTypeSpelling(clang_getCanonicalType(type))).std_str(); auto
|
||||
// declaration =
|
||||
// detail::cxstring(clang_getCursorSpelling(clang_getTypeDeclaration(type))).std_str();
|
||||
auto spelling = detail::cxstring(clang_getTypeSpelling(type)).std_str();
|
||||
if (need_to_remove_scope(cur, type))
|
||||
{
|
||||
|
|
@ -270,16 +272,32 @@ std::unique_ptr<cpp_expression> parse_array_size(const CXCursor& cur, const CXTy
|
|||
type, "unexpected token");
|
||||
|
||||
std::string size_expr;
|
||||
auto bracket_count = 1;
|
||||
for (auto ptr = spelling.c_str() + spelling.size() - 2u; bracket_count != 0; --ptr)
|
||||
{
|
||||
if (*ptr == ']')
|
||||
++bracket_count;
|
||||
else if (*ptr == '[')
|
||||
--bracket_count;
|
||||
|
||||
if (bracket_count != 0)
|
||||
size_expr += *ptr;
|
||||
auto ptr = spelling.rbegin();
|
||||
while (true)
|
||||
{
|
||||
// Consume the final closing ].
|
||||
++ptr;
|
||||
|
||||
auto bracket_count = 1;
|
||||
while (bracket_count != 0)
|
||||
{
|
||||
if (*ptr == ']')
|
||||
++bracket_count;
|
||||
else if (*ptr == '[')
|
||||
--bracket_count;
|
||||
|
||||
if (bracket_count != 0)
|
||||
size_expr += *ptr;
|
||||
|
||||
++ptr;
|
||||
}
|
||||
|
||||
if (ptr == spelling.rend() || *ptr != ']')
|
||||
// We don't have another ].
|
||||
break;
|
||||
// We do have another ], as we want the innermost, we need to restart.
|
||||
size_expr.clear();
|
||||
}
|
||||
|
||||
return size_expr.empty()
|
||||
|
|
@ -662,8 +680,7 @@ std::unique_ptr<cpp_type> parse_type_impl(const detail::parse_context& context,
|
|||
cpp_type_ref(detail::get_entity_id(decl), std::move(spelling)));
|
||||
});
|
||||
|
||||
case CXType_Pointer:
|
||||
{
|
||||
case CXType_Pointer: {
|
||||
auto pointee = parse_type_impl(context, cur, clang_getPointeeType(type));
|
||||
auto pointer = cpp_pointer_type::build(std::move(pointee));
|
||||
|
||||
|
|
@ -672,8 +689,7 @@ std::unique_ptr<cpp_type> parse_type_impl(const detail::parse_context& context,
|
|||
return make_cv_qualified(std::move(pointer), cv);
|
||||
}
|
||||
case CXType_LValueReference:
|
||||
case CXType_RValueReference:
|
||||
{
|
||||
case CXType_RValueReference: {
|
||||
auto referee = parse_type_impl(context, cur, clang_getPointeeType(type));
|
||||
return cpp_reference_type::build(std::move(referee), get_reference_kind(type));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,8 +25,7 @@ bool equal_types(const cpp_entity_index& idx, const cpp_type& parsed, const cpp_
|
|||
return static_cast<const cpp_builtin_type&>(parsed).builtin_type_kind()
|
||||
== static_cast<const cpp_builtin_type&>(synthesized).builtin_type_kind();
|
||||
|
||||
case cpp_type_kind::user_defined_t:
|
||||
{
|
||||
case cpp_type_kind::user_defined_t: {
|
||||
auto& user_parsed = static_cast<const cpp_user_defined_type&>(parsed);
|
||||
auto& user_synthesized = static_cast<const cpp_user_defined_type&>(synthesized);
|
||||
return equal_ref(idx, user_parsed.entity(), user_synthesized.entity());
|
||||
|
|
@ -40,8 +39,7 @@ bool equal_types(const cpp_entity_index& idx, const cpp_type& parsed, const cpp_
|
|||
case cpp_type_kind::decltype_auto_t:
|
||||
return true;
|
||||
|
||||
case cpp_type_kind::cv_qualified_t:
|
||||
{
|
||||
case cpp_type_kind::cv_qualified_t: {
|
||||
auto& cv_a = static_cast<const cpp_cv_qualified_type&>(parsed);
|
||||
auto& cv_b = static_cast<const cpp_cv_qualified_type&>(synthesized);
|
||||
return cv_a.cv_qualifier() == cv_b.cv_qualifier()
|
||||
|
|
@ -51,16 +49,14 @@ bool equal_types(const cpp_entity_index& idx, const cpp_type& parsed, const cpp_
|
|||
case cpp_type_kind::pointer_t:
|
||||
return equal_types(idx, static_cast<const cpp_pointer_type&>(parsed).pointee(),
|
||||
static_cast<const cpp_pointer_type&>(synthesized).pointee());
|
||||
case cpp_type_kind::reference_t:
|
||||
{
|
||||
case cpp_type_kind::reference_t: {
|
||||
auto& ref_a = static_cast<const cpp_reference_type&>(parsed);
|
||||
auto& ref_b = static_cast<const cpp_reference_type&>(synthesized);
|
||||
return ref_a.reference_kind() == ref_b.reference_kind()
|
||||
&& equal_types(idx, ref_a.referee(), ref_b.referee());
|
||||
}
|
||||
|
||||
case cpp_type_kind::array_t:
|
||||
{
|
||||
case cpp_type_kind::array_t: {
|
||||
auto& array_a = static_cast<const cpp_array_type&>(parsed);
|
||||
auto& array_b = static_cast<const cpp_array_type&>(synthesized);
|
||||
|
||||
|
|
@ -71,14 +67,15 @@ bool equal_types(const cpp_entity_index& idx, const cpp_type& parsed, const cpp_
|
|||
// check size
|
||||
if (!array_a.size().has_value() && !array_b.size().has_value())
|
||||
return true;
|
||||
else if (array_a.size().has_value() != array_b.size().has_value())
|
||||
return false;
|
||||
|
||||
auto& size_a = array_a.size().value();
|
||||
auto& size_b = array_b.size().value();
|
||||
return equal_expressions(size_a, size_b);
|
||||
}
|
||||
|
||||
case cpp_type_kind::function_t:
|
||||
{
|
||||
case cpp_type_kind::function_t: {
|
||||
auto& func_a = static_cast<const cpp_function_type&>(parsed);
|
||||
auto& func_b = static_cast<const cpp_function_type&>(synthesized);
|
||||
|
||||
|
|
@ -98,8 +95,7 @@ bool equal_types(const cpp_entity_index& idx, const cpp_type& parsed, const cpp_
|
|||
}
|
||||
return iter_a == func_a.parameter_types().end() && iter_b == func_b.parameter_types().end();
|
||||
}
|
||||
case cpp_type_kind::member_function_t:
|
||||
{
|
||||
case cpp_type_kind::member_function_t: {
|
||||
auto& func_a = static_cast<const cpp_member_function_type&>(parsed);
|
||||
auto& func_b = static_cast<const cpp_member_function_type&>(synthesized);
|
||||
|
||||
|
|
@ -121,8 +117,7 @@ bool equal_types(const cpp_entity_index& idx, const cpp_type& parsed, const cpp_
|
|||
}
|
||||
return iter_a == func_a.parameter_types().end() && iter_b == func_b.parameter_types().end();
|
||||
}
|
||||
case cpp_type_kind::member_object_t:
|
||||
{
|
||||
case cpp_type_kind::member_object_t: {
|
||||
auto& obj_a = static_cast<const cpp_member_object_type&>(parsed);
|
||||
auto& obj_b = static_cast<const cpp_member_object_type&>(synthesized);
|
||||
|
||||
|
|
@ -131,15 +126,13 @@ bool equal_types(const cpp_entity_index& idx, const cpp_type& parsed, const cpp_
|
|||
return equal_types(idx, obj_a.object_type(), obj_b.object_type());
|
||||
}
|
||||
|
||||
case cpp_type_kind::template_parameter_t:
|
||||
{
|
||||
case cpp_type_kind::template_parameter_t: {
|
||||
auto& entity_parsed = static_cast<const cpp_template_parameter_type&>(parsed).entity();
|
||||
auto& entity_synthesized
|
||||
= static_cast<const cpp_template_parameter_type&>(synthesized).entity();
|
||||
return equal_ref(idx, entity_parsed, entity_synthesized);
|
||||
}
|
||||
case cpp_type_kind::template_instantiation_t:
|
||||
{
|
||||
case cpp_type_kind::template_instantiation_t: {
|
||||
auto& inst_parsed = static_cast<const cpp_template_instantiation_type&>(parsed);
|
||||
auto& inst_synthesized = static_cast<const cpp_template_instantiation_type&>(synthesized);
|
||||
|
||||
|
|
@ -182,8 +175,7 @@ bool equal_types(const cpp_entity_index& idx, const cpp_type& parsed, const cpp_
|
|||
return iter_a == inst_parsed.arguments().value().end()
|
||||
&& iter_b == inst_synthesized.arguments().value().end();
|
||||
}
|
||||
case cpp_type_kind::dependent_t:
|
||||
{
|
||||
case cpp_type_kind::dependent_t: {
|
||||
auto& dep_a = static_cast<const cpp_dependent_type&>(parsed);
|
||||
auto& dep_b = static_cast<const cpp_dependent_type&>(synthesized);
|
||||
return dep_a.name() == dep_b.name() && equal_types(idx, dep_a.dependee(), dep_b.dependee());
|
||||
|
|
@ -242,6 +234,8 @@ using k = int[42];
|
|||
using l = float*[];
|
||||
/// using m=char[42];
|
||||
using m = char[3 * 2 + 4 ? 42 : 43];
|
||||
/// using m2=char[][1];
|
||||
using m2 = char[][1];
|
||||
|
||||
// function pointers
|
||||
/// using n=void(*)(int);
|
||||
|
|
@ -299,6 +293,7 @@ typedef e* j;
|
|||
typedef int k[42];
|
||||
typedef float* l[];
|
||||
typedef char m[3 * 2 + 4 ? 42 : 43];
|
||||
typedef char m2[][1];
|
||||
|
||||
// function pointers
|
||||
typedef void(*n)(int);
|
||||
|
|
@ -343,78 +338,85 @@ typedef decltype(0) w;
|
|||
if (alias.name() == "a")
|
||||
{
|
||||
auto type = cpp_builtin_type::build(cpp_int);
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
}
|
||||
else if (alias.name() == "b")
|
||||
{
|
||||
auto type = add_cv(cpp_builtin_type::build(cpp_longdouble), cpp_cv_const_volatile);
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
}
|
||||
else if (alias.name() == "c")
|
||||
{
|
||||
auto type = cpp_pointer_type::build(cpp_builtin_type::build(cpp_int));
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
}
|
||||
else if (alias.name() == "d")
|
||||
{
|
||||
auto type
|
||||
= cpp_pointer_type::build(add_cv(cpp_builtin_type::build(cpp_uint), cpp_cv_const));
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
}
|
||||
else if (alias.name() == "e")
|
||||
{
|
||||
auto type = add_cv(cpp_pointer_type::build(
|
||||
add_cv(cpp_builtin_type::build(cpp_uint), cpp_cv_const)),
|
||||
cpp_cv_volatile);
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
add_cv(cpp_builtin_type::build(cpp_uint), cpp_cv_const)),
|
||||
cpp_cv_volatile);
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
}
|
||||
else if (alias.name() == "f")
|
||||
{
|
||||
auto type = cpp_reference_type::build(cpp_builtin_type::build(cpp_int), cpp_ref_lvalue);
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
}
|
||||
else if (alias.name() == "g")
|
||||
{
|
||||
auto type
|
||||
= cpp_reference_type::build(add_cv(cpp_builtin_type::build(cpp_int), cpp_cv_const),
|
||||
cpp_ref_rvalue);
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
cpp_ref_rvalue);
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
}
|
||||
else if (alias.name() == "h")
|
||||
{
|
||||
auto type = cpp_user_defined_type::build(cpp_type_ref(cpp_entity_id(""), "c"));
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
}
|
||||
else if (alias.name() == "i")
|
||||
{
|
||||
auto type = add_cv(cpp_user_defined_type::build(cpp_type_ref(cpp_entity_id(""), "d")),
|
||||
cpp_cv_const);
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
cpp_cv_const);
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
}
|
||||
else if (alias.name() == "j")
|
||||
{
|
||||
auto type = cpp_pointer_type::build(
|
||||
cpp_user_defined_type::build(cpp_type_ref(cpp_entity_id(""), "e")));
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
cpp_user_defined_type::build(cpp_type_ref(cpp_entity_id(""), "e")));
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
}
|
||||
else if (alias.name() == "k")
|
||||
{
|
||||
auto type
|
||||
= cpp_array_type::build(cpp_builtin_type::build(cpp_int), make_size("42", true));
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
}
|
||||
else if (alias.name() == "l")
|
||||
{
|
||||
auto type
|
||||
= cpp_array_type::build(cpp_pointer_type::build(cpp_builtin_type::build(cpp_float)),
|
||||
nullptr);
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
nullptr);
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
}
|
||||
else if (alias.name() == "m")
|
||||
{
|
||||
auto type
|
||||
= cpp_array_type::build(cpp_builtin_type::build(cpp_char), make_size("42", true));
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
}
|
||||
else if (alias.name() == "m2")
|
||||
{
|
||||
auto inner
|
||||
= cpp_array_type::build(cpp_builtin_type::build(cpp_char), make_size("1", true));
|
||||
auto type = cpp_array_type::build(std::move(inner), nullptr);
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
}
|
||||
else if (alias.name() == "n")
|
||||
{
|
||||
|
|
@ -422,108 +424,108 @@ typedef decltype(0) w;
|
|||
builder.add_parameter(cpp_builtin_type::build(cpp_int));
|
||||
auto type = cpp_pointer_type::build(builder.finish());
|
||||
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
}
|
||||
else if (alias.name() == "o")
|
||||
{
|
||||
cpp_function_type::builder builder(
|
||||
cpp_pointer_type::build(cpp_builtin_type::build(cpp_char)));
|
||||
cpp_pointer_type::build(cpp_builtin_type::build(cpp_char)));
|
||||
builder.add_parameter(
|
||||
cpp_reference_type::build(add_cv(cpp_builtin_type::build(cpp_int), cpp_cv_const),
|
||||
cpp_ref_lvalue));
|
||||
cpp_reference_type::build(add_cv(cpp_builtin_type::build(cpp_int), cpp_cv_const),
|
||||
cpp_ref_lvalue));
|
||||
builder.is_variadic();
|
||||
auto type = cpp_reference_type::build(builder.finish(), cpp_ref_lvalue);
|
||||
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
}
|
||||
else if (alias.name() == "p")
|
||||
{
|
||||
cpp_function_type::builder builder(
|
||||
cpp_user_defined_type::build(cpp_type_ref(cpp_entity_id(""), "n")));
|
||||
cpp_user_defined_type::build(cpp_type_ref(cpp_entity_id(""), "n")));
|
||||
builder.add_parameter(cpp_builtin_type::build(cpp_int));
|
||||
builder.add_parameter(
|
||||
cpp_user_defined_type::build(cpp_type_ref(cpp_entity_id(""), "o")));
|
||||
cpp_user_defined_type::build(cpp_type_ref(cpp_entity_id(""), "o")));
|
||||
auto type = cpp_pointer_type::build(builder.finish());
|
||||
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
}
|
||||
else if (alias.name() == "q")
|
||||
{
|
||||
cpp_member_function_type::builder builder(cpp_user_defined_type::build(
|
||||
cpp_type_ref(cpp_entity_id(""), "foo")),
|
||||
cpp_builtin_type::build(cpp_void));
|
||||
cpp_type_ref(cpp_entity_id(""), "foo")),
|
||||
cpp_builtin_type::build(cpp_void));
|
||||
builder.add_parameter(cpp_builtin_type::build(cpp_int));
|
||||
auto type = cpp_pointer_type::build(builder.finish());
|
||||
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
}
|
||||
else if (alias.name() == "r")
|
||||
{
|
||||
auto obj = cpp_reference_type::build(add_cv(cpp_user_defined_type::build(
|
||||
cpp_type_ref(cpp_entity_id(""), "foo")),
|
||||
cpp_cv_const),
|
||||
cpp_ref_lvalue);
|
||||
cpp_type_ref(cpp_entity_id(""), "foo")),
|
||||
cpp_cv_const),
|
||||
cpp_ref_lvalue);
|
||||
|
||||
cpp_member_function_type::builder builder(std::move(obj),
|
||||
cpp_builtin_type::build(cpp_void));
|
||||
cpp_builtin_type::build(cpp_void));
|
||||
builder.add_parameter(cpp_builtin_type::build(cpp_int));
|
||||
builder.is_variadic();
|
||||
auto type = cpp_pointer_type::build(builder.finish());
|
||||
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
}
|
||||
else if (alias.name() == "s")
|
||||
{
|
||||
// in old libclang version, the member type isn't exposed for some reason
|
||||
auto pointee
|
||||
= cpp_member_object_type::build(cpp_user_defined_type::build(
|
||||
cpp_type_ref(cpp_entity_id(""), "foo")),
|
||||
cpp_unexposed_type::build("int"));
|
||||
cpp_type_ref(cpp_entity_id(""), "foo")),
|
||||
cpp_unexposed_type::build("int"));
|
||||
auto type = cpp_pointer_type::build(std::move(pointee));
|
||||
auto is_unexposed = equal_types(idx, alias.underlying_type(), *type);
|
||||
|
||||
if (!is_unexposed)
|
||||
{
|
||||
pointee = cpp_member_object_type::build(cpp_user_defined_type::build(
|
||||
cpp_type_ref(cpp_entity_id(""), "foo")),
|
||||
cpp_builtin_type::build(cpp_int));
|
||||
cpp_type_ref(cpp_entity_id(""), "foo")),
|
||||
cpp_builtin_type::build(cpp_int));
|
||||
type = cpp_pointer_type::build(std::move(pointee));
|
||||
auto is_builtin = equal_types(idx, alias.underlying_type(), *type);
|
||||
REQUIRE(is_builtin);
|
||||
CHECK(is_builtin);
|
||||
}
|
||||
}
|
||||
else if (alias.name() == "t")
|
||||
{
|
||||
auto type = cpp_user_defined_type::build(cpp_type_ref(cpp_entity_id(""), "t_"));
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
return false; // inhibit comment check for next three entities
|
||||
// as they can't be documented (will always apply to the inline type)
|
||||
}
|
||||
else if (alias.name() == "u")
|
||||
{
|
||||
auto type = cpp_pointer_type::build(
|
||||
add_cv(cpp_user_defined_type::build(cpp_type_ref(cpp_entity_id(""), "u_")),
|
||||
cpp_cv_const));
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
add_cv(cpp_user_defined_type::build(cpp_type_ref(cpp_entity_id(""), "u_")),
|
||||
cpp_cv_const));
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
return false;
|
||||
}
|
||||
else if (alias.name() == "v")
|
||||
{
|
||||
auto type = cpp_user_defined_type::build(cpp_type_ref(cpp_entity_id(""), ""));
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
return false;
|
||||
}
|
||||
else if (alias.name() == "w")
|
||||
{
|
||||
auto type = cpp_decltype_type::build(
|
||||
cpp_unexposed_expression::build(cpp_builtin_type::build(cpp_int),
|
||||
cpp_token_string::tokenize("0")));
|
||||
REQUIRE(equal_types(idx, alias.underlying_type(), *type));
|
||||
cpp_unexposed_expression::build(cpp_builtin_type::build(cpp_int),
|
||||
cpp_token_string::tokenize("0")));
|
||||
CHECK(equal_types(idx, alias.underlying_type(), *type));
|
||||
}
|
||||
else
|
||||
REQUIRE(false);
|
||||
CHECK(false);
|
||||
|
||||
return check_code;
|
||||
});
|
||||
REQUIRE(count == 23u);
|
||||
REQUIRE(count == 24u);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue