Fix member variable type which is typedef in same class
Type spelling included all scopes. See foonathan/standardese#82.
This commit is contained in:
parent
b2121b19c2
commit
2b3ddf360b
2 changed files with 89 additions and 60 deletions
|
|
@ -85,9 +85,29 @@ namespace
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string get_type_spelling(const CXType& type)
|
bool need_to_remove_scope(const CXCursor& cur, const CXType& type)
|
||||||
{
|
{
|
||||||
return detail::cxstring(clang_getTypeSpelling(type)).c_str();
|
if (type.kind != CXType_Typedef)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// typedefs declared in the same class include all scopes in the name)
|
||||||
|
// (because of course they do)
|
||||||
|
auto parent = clang_getCursorSemanticParent(cur);
|
||||||
|
auto decl_parent = clang_getCursorSemanticParent(clang_getTypeDeclaration(type));
|
||||||
|
return clang_equalCursors(parent, decl_parent) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get_type_spelling(const CXCursor& cur, const CXType& type)
|
||||||
|
{
|
||||||
|
auto spelling = detail::cxstring(clang_getTypeSpelling(type)).std_str();
|
||||||
|
if (need_to_remove_scope(cur, type))
|
||||||
|
{
|
||||||
|
auto colon = spelling.rfind(':');
|
||||||
|
if (colon != std::string::npos)
|
||||||
|
spelling.erase(0, colon + 1u);
|
||||||
|
}
|
||||||
|
|
||||||
|
return spelling;
|
||||||
}
|
}
|
||||||
|
|
||||||
// const/volatile at the end (because people do that apparently!)
|
// const/volatile at the end (because people do that apparently!)
|
||||||
|
|
@ -186,9 +206,9 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Builder>
|
template <typename Builder>
|
||||||
std::unique_ptr<cpp_type> make_leave_type(const CXType& type, Builder b)
|
std::unique_ptr<cpp_type> make_leave_type(const CXCursor& cur, const CXType& type, Builder b)
|
||||||
{
|
{
|
||||||
auto spelling = get_type_spelling(type);
|
auto spelling = get_type_spelling(cur, type);
|
||||||
|
|
||||||
// check for cv qualifiers on the leave type
|
// check for cv qualifiers on the leave type
|
||||||
auto prefix = prefix_cv(spelling);
|
auto prefix = prefix_cv(spelling);
|
||||||
|
|
@ -219,14 +239,14 @@ namespace
|
||||||
std::unique_ptr<cpp_type> parse_type_impl(const detail::parse_context& context,
|
std::unique_ptr<cpp_type> parse_type_impl(const detail::parse_context& context,
|
||||||
const CXCursor& cur, const CXType& type);
|
const CXCursor& cur, const CXType& type);
|
||||||
|
|
||||||
std::unique_ptr<cpp_expression> parse_array_size(const CXType& type)
|
std::unique_ptr<cpp_expression> parse_array_size(const CXCursor& cur, const CXType& type)
|
||||||
{
|
{
|
||||||
auto size = clang_getArraySize(type);
|
auto size = clang_getArraySize(type);
|
||||||
if (size != -1)
|
if (size != -1)
|
||||||
return cpp_literal_expression::build(cpp_builtin_type::build(cpp_ulonglong),
|
return cpp_literal_expression::build(cpp_builtin_type::build(cpp_ulonglong),
|
||||||
std::to_string(size));
|
std::to_string(size));
|
||||||
|
|
||||||
auto spelling = get_type_spelling(type);
|
auto spelling = get_type_spelling(cur, type);
|
||||||
DEBUG_ASSERT(spelling.size() > 2u && spelling.back() == ']', detail::parse_error_handler{},
|
DEBUG_ASSERT(spelling.size() > 2u && spelling.back() == ']', detail::parse_error_handler{},
|
||||||
type, "unexpected token");
|
type, "unexpected token");
|
||||||
|
|
||||||
|
|
@ -269,7 +289,7 @@ namespace
|
||||||
// only downside of this workaround: we've stripped away typedefs
|
// only downside of this workaround: we've stripped away typedefs
|
||||||
}
|
}
|
||||||
|
|
||||||
auto size = parse_array_size(canonical); // type may not work, see above
|
auto size = parse_array_size(cur, canonical); // type may not work, see above
|
||||||
return cpp_array_type::build(parse_type_impl(context, cur, value_type), std::move(size));
|
return cpp_array_type::build(parse_type_impl(context, cur, value_type), std::move(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -320,7 +340,7 @@ namespace
|
||||||
std::unique_ptr<cpp_type> parse_member_pointee_type(const detail::parse_context& context,
|
std::unique_ptr<cpp_type> parse_member_pointee_type(const detail::parse_context& context,
|
||||||
const CXCursor& cur, const CXType& type)
|
const CXCursor& cur, const CXType& type)
|
||||||
{
|
{
|
||||||
auto spelling = get_type_spelling(type);
|
auto spelling = get_type_spelling(cur, type);
|
||||||
auto ref = member_function_ref_qualifier(spelling);
|
auto ref = member_function_ref_qualifier(spelling);
|
||||||
auto cv = suffix_cv(spelling);
|
auto cv = suffix_cv(spelling);
|
||||||
|
|
||||||
|
|
@ -383,28 +403,32 @@ namespace
|
||||||
|
|
||||||
// doesn't respect cv qualifiers properly
|
// doesn't respect cv qualifiers properly
|
||||||
auto result =
|
auto result =
|
||||||
make_leave_type(type, [&](std::string&& type_spelling) -> std::unique_ptr<cpp_type> {
|
make_leave_type(cur, type,
|
||||||
// look at the template parameters,
|
[&](std::string&& type_spelling) -> std::unique_ptr<cpp_type> {
|
||||||
// see if we find a matching one
|
// look at the template parameters,
|
||||||
auto param = clang_getNullCursor();
|
// see if we find a matching one
|
||||||
detail::visit_children(templ, [&](const CXCursor& child) {
|
auto param = clang_getNullCursor();
|
||||||
if (clang_getCursorKind(child) == CXCursor_TemplateTypeParameter
|
detail::visit_children(templ, [&](const CXCursor& child) {
|
||||||
&& get_type_spelling(clang_getCursorType(child)) == type_spelling)
|
if (clang_getCursorKind(child) == CXCursor_TemplateTypeParameter
|
||||||
{
|
&& get_type_spelling(child, clang_getCursorType(child))
|
||||||
// found one
|
== type_spelling)
|
||||||
DEBUG_ASSERT(clang_Cursor_isNull(param), detail::assert_handler{});
|
{
|
||||||
param = child;
|
// found one
|
||||||
}
|
DEBUG_ASSERT(clang_Cursor_isNull(param),
|
||||||
});
|
detail::assert_handler{});
|
||||||
|
param = child;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (clang_Cursor_isNull(param))
|
if (clang_Cursor_isNull(param))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
else
|
else
|
||||||
// found matching parameter
|
// found matching parameter
|
||||||
return cpp_template_parameter_type::build(
|
return cpp_template_parameter_type::build(
|
||||||
cpp_template_type_parameter_ref(detail::get_entity_id(param),
|
cpp_template_type_parameter_ref(detail::get_entity_id(
|
||||||
std::move(type_spelling)));
|
param),
|
||||||
});
|
std::move(type_spelling)));
|
||||||
|
});
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -442,7 +466,7 @@ namespace
|
||||||
std::unique_ptr<cpp_type> try_parse_instantiation_type(const detail::parse_context&,
|
std::unique_ptr<cpp_type> try_parse_instantiation_type(const detail::parse_context&,
|
||||||
const CXCursor& cur, const CXType& type)
|
const CXCursor& cur, const CXType& type)
|
||||||
{
|
{
|
||||||
return make_leave_type(type, [&](std::string&& spelling) -> std::unique_ptr<cpp_type> {
|
return make_leave_type(cur, type, [&](std::string&& spelling) -> std::unique_ptr<cpp_type> {
|
||||||
auto ptr = spelling.c_str();
|
auto ptr = spelling.c_str();
|
||||||
|
|
||||||
std::string templ_name;
|
std::string templ_name;
|
||||||
|
|
@ -478,7 +502,7 @@ namespace
|
||||||
if (clang_isExpression(clang_getCursorKind(cur)))
|
if (clang_isExpression(clang_getCursorKind(cur)))
|
||||||
return nullptr; // don't use decltype here
|
return nullptr; // don't use decltype here
|
||||||
|
|
||||||
return make_leave_type(type, [&](std::string&& spelling) -> std::unique_ptr<cpp_type> {
|
return make_leave_type(cur, type, [&](std::string&& spelling) -> std::unique_ptr<cpp_type> {
|
||||||
if (!remove_prefix(spelling, "decltype(", false))
|
if (!remove_prefix(spelling, "decltype(", false))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
remove_suffix(spelling, "...", false); // variadic decltype. fun
|
remove_suffix(spelling, "...", false); // variadic decltype. fun
|
||||||
|
|
@ -578,93 +602,93 @@ namespace
|
||||||
return ptype;
|
return ptype;
|
||||||
// fallthrough
|
// fallthrough
|
||||||
case CXType_Complex:
|
case CXType_Complex:
|
||||||
return cpp_unexposed_type::build(get_type_spelling(type).c_str());
|
return cpp_unexposed_type::build(get_type_spelling(cur, type).c_str());
|
||||||
|
|
||||||
case CXType_Void:
|
case CXType_Void:
|
||||||
return make_leave_type(type,
|
return make_leave_type(cur, type,
|
||||||
[](std::string&&) { return cpp_builtin_type::build(cpp_void); });
|
[](std::string&&) { return cpp_builtin_type::build(cpp_void); });
|
||||||
case CXType_Bool:
|
case CXType_Bool:
|
||||||
return make_leave_type(type,
|
return make_leave_type(cur, type,
|
||||||
[](std::string&&) { return cpp_builtin_type::build(cpp_bool); });
|
[](std::string&&) { return cpp_builtin_type::build(cpp_bool); });
|
||||||
case CXType_UChar:
|
case CXType_UChar:
|
||||||
return make_leave_type(type, [](std::string&&) {
|
return make_leave_type(cur, type, [](std::string&&) {
|
||||||
return cpp_builtin_type::build(cpp_uchar);
|
return cpp_builtin_type::build(cpp_uchar);
|
||||||
});
|
});
|
||||||
case CXType_UShort:
|
case CXType_UShort:
|
||||||
return make_leave_type(type, [](std::string&&) {
|
return make_leave_type(cur, type, [](std::string&&) {
|
||||||
return cpp_builtin_type::build(cpp_ushort);
|
return cpp_builtin_type::build(cpp_ushort);
|
||||||
});
|
});
|
||||||
case CXType_UInt:
|
case CXType_UInt:
|
||||||
return make_leave_type(type,
|
return make_leave_type(cur, type,
|
||||||
[](std::string&&) { return cpp_builtin_type::build(cpp_uint); });
|
[](std::string&&) { return cpp_builtin_type::build(cpp_uint); });
|
||||||
case CXType_ULong:
|
case CXType_ULong:
|
||||||
return make_leave_type(type, [](std::string&&) {
|
return make_leave_type(cur, type, [](std::string&&) {
|
||||||
return cpp_builtin_type::build(cpp_ulong);
|
return cpp_builtin_type::build(cpp_ulong);
|
||||||
});
|
});
|
||||||
case CXType_ULongLong:
|
case CXType_ULongLong:
|
||||||
return make_leave_type(type, [](std::string&&) {
|
return make_leave_type(cur, type, [](std::string&&) {
|
||||||
return cpp_builtin_type::build(cpp_ulonglong);
|
return cpp_builtin_type::build(cpp_ulonglong);
|
||||||
});
|
});
|
||||||
case CXType_UInt128:
|
case CXType_UInt128:
|
||||||
return make_leave_type(type, [](std::string&&) {
|
return make_leave_type(cur, type, [](std::string&&) {
|
||||||
return cpp_builtin_type::build(cpp_uint128);
|
return cpp_builtin_type::build(cpp_uint128);
|
||||||
});
|
});
|
||||||
case CXType_SChar:
|
case CXType_SChar:
|
||||||
return make_leave_type(type, [](std::string&&) {
|
return make_leave_type(cur, type, [](std::string&&) {
|
||||||
return cpp_builtin_type::build(cpp_schar);
|
return cpp_builtin_type::build(cpp_schar);
|
||||||
});
|
});
|
||||||
case CXType_Short:
|
case CXType_Short:
|
||||||
return make_leave_type(type, [](std::string&&) {
|
return make_leave_type(cur, type, [](std::string&&) {
|
||||||
return cpp_builtin_type::build(cpp_short);
|
return cpp_builtin_type::build(cpp_short);
|
||||||
});
|
});
|
||||||
case CXType_Int:
|
case CXType_Int:
|
||||||
return make_leave_type(type,
|
return make_leave_type(cur, type,
|
||||||
[](std::string&&) { return cpp_builtin_type::build(cpp_int); });
|
[](std::string&&) { return cpp_builtin_type::build(cpp_int); });
|
||||||
case CXType_Long:
|
case CXType_Long:
|
||||||
return make_leave_type(type,
|
return make_leave_type(cur, type,
|
||||||
[](std::string&&) { return cpp_builtin_type::build(cpp_long); });
|
[](std::string&&) { return cpp_builtin_type::build(cpp_long); });
|
||||||
case CXType_LongLong:
|
case CXType_LongLong:
|
||||||
return make_leave_type(type, [](std::string&&) {
|
return make_leave_type(cur, type, [](std::string&&) {
|
||||||
return cpp_builtin_type::build(cpp_longlong);
|
return cpp_builtin_type::build(cpp_longlong);
|
||||||
});
|
});
|
||||||
case CXType_Int128:
|
case CXType_Int128:
|
||||||
return make_leave_type(type, [](std::string&&) {
|
return make_leave_type(cur, type, [](std::string&&) {
|
||||||
return cpp_builtin_type::build(cpp_int128);
|
return cpp_builtin_type::build(cpp_int128);
|
||||||
});
|
});
|
||||||
case CXType_Float:
|
case CXType_Float:
|
||||||
return make_leave_type(type, [](std::string&&) {
|
return make_leave_type(cur, type, [](std::string&&) {
|
||||||
return cpp_builtin_type::build(cpp_float);
|
return cpp_builtin_type::build(cpp_float);
|
||||||
});
|
});
|
||||||
case CXType_Double:
|
case CXType_Double:
|
||||||
return make_leave_type(type, [](std::string&&) {
|
return make_leave_type(cur, type, [](std::string&&) {
|
||||||
return cpp_builtin_type::build(cpp_double);
|
return cpp_builtin_type::build(cpp_double);
|
||||||
});
|
});
|
||||||
case CXType_LongDouble:
|
case CXType_LongDouble:
|
||||||
return make_leave_type(type, [](std::string&&) {
|
return make_leave_type(cur, type, [](std::string&&) {
|
||||||
return cpp_builtin_type::build(cpp_longdouble);
|
return cpp_builtin_type::build(cpp_longdouble);
|
||||||
});
|
});
|
||||||
case CXType_Float128:
|
case CXType_Float128:
|
||||||
return make_leave_type(type, [](std::string&&) {
|
return make_leave_type(cur, type, [](std::string&&) {
|
||||||
return cpp_builtin_type::build(cpp_float128);
|
return cpp_builtin_type::build(cpp_float128);
|
||||||
});
|
});
|
||||||
case CXType_Char_U:
|
case CXType_Char_U:
|
||||||
case CXType_Char_S:
|
case CXType_Char_S:
|
||||||
return make_leave_type(type,
|
return make_leave_type(cur, type,
|
||||||
[](std::string&&) { return cpp_builtin_type::build(cpp_char); });
|
[](std::string&&) { return cpp_builtin_type::build(cpp_char); });
|
||||||
case CXType_Char16:
|
case CXType_Char16:
|
||||||
return make_leave_type(type, [](std::string&&) {
|
return make_leave_type(cur, type, [](std::string&&) {
|
||||||
return cpp_builtin_type::build(cpp_char16);
|
return cpp_builtin_type::build(cpp_char16);
|
||||||
});
|
});
|
||||||
case CXType_Char32:
|
case CXType_Char32:
|
||||||
return make_leave_type(type, [](std::string&&) {
|
return make_leave_type(cur, type, [](std::string&&) {
|
||||||
return cpp_builtin_type::build(cpp_char32);
|
return cpp_builtin_type::build(cpp_char32);
|
||||||
});
|
});
|
||||||
case CXType_WChar:
|
case CXType_WChar:
|
||||||
return make_leave_type(type, [](std::string&&) {
|
return make_leave_type(cur, type, [](std::string&&) {
|
||||||
return cpp_builtin_type::build(cpp_wchar);
|
return cpp_builtin_type::build(cpp_wchar);
|
||||||
});
|
});
|
||||||
case CXType_NullPtr:
|
case CXType_NullPtr:
|
||||||
return make_leave_type(type, [](std::string&&) {
|
return make_leave_type(cur, type, [](std::string&&) {
|
||||||
return cpp_builtin_type::build(cpp_nullptr);
|
return cpp_builtin_type::build(cpp_nullptr);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -676,7 +700,7 @@ namespace
|
||||||
case CXType_Record:
|
case CXType_Record:
|
||||||
case CXType_Enum:
|
case CXType_Enum:
|
||||||
case CXType_Typedef:
|
case CXType_Typedef:
|
||||||
return make_leave_type(type, [&](std::string&& spelling) {
|
return make_leave_type(cur, type, [&](std::string&& spelling) {
|
||||||
auto decl = clang_getTypeDeclaration(type);
|
auto decl = clang_getTypeDeclaration(type);
|
||||||
if (remove_prefix(spelling, "(anonymous", false))
|
if (remove_prefix(spelling, "(anonymous", false))
|
||||||
spelling = ""; // anonymous type
|
spelling = ""; // anonymous type
|
||||||
|
|
@ -689,7 +713,7 @@ namespace
|
||||||
auto pointee = parse_type_impl(context, cur, clang_getPointeeType(type));
|
auto pointee = parse_type_impl(context, cur, clang_getPointeeType(type));
|
||||||
auto pointer = cpp_pointer_type::build(std::move(pointee));
|
auto pointer = cpp_pointer_type::build(std::move(pointee));
|
||||||
|
|
||||||
auto spelling = get_type_spelling(type);
|
auto spelling = get_type_spelling(cur, type);
|
||||||
auto cv = suffix_cv(spelling);
|
auto cv = suffix_cv(spelling);
|
||||||
return make_cv_qualified(std::move(pointer), cv);
|
return make_cv_qualified(std::move(pointer), cv);
|
||||||
}
|
}
|
||||||
|
|
@ -714,7 +738,8 @@ namespace
|
||||||
return cpp_pointer_type::build(parse_member_pointee_type(context, cur, type));
|
return cpp_pointer_type::build(parse_member_pointee_type(context, cur, type));
|
||||||
|
|
||||||
case CXType_Auto:
|
case CXType_Auto:
|
||||||
return make_leave_type(type, [&](std::string&&) { return cpp_auto_type::build(); });
|
return make_leave_type(cur, type,
|
||||||
|
[&](std::string&&) { return cpp_auto_type::build(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_UNREACHABLE(detail::assert_handler{});
|
DEBUG_UNREACHABLE(detail::assert_handler{});
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,9 @@ using struct_=int;
|
||||||
struct_ var2;
|
struct_ var2;
|
||||||
|
|
||||||
struct foo{
|
struct foo{
|
||||||
int a;
|
using my_int=int;
|
||||||
|
|
||||||
|
my_int a;
|
||||||
|
|
||||||
auto func(int)->int(*(*)(int))[42];
|
auto func(int)->int(*(*)(int))[42];
|
||||||
|
|
||||||
|
|
@ -66,7 +68,9 @@ struct_ var2;
|
||||||
|
|
||||||
struct foo
|
struct foo
|
||||||
{
|
{
|
||||||
int a;
|
using my_int = int;
|
||||||
|
|
||||||
|
my_int a;
|
||||||
|
|
||||||
auto func(int) -> int(*(*)(int))[42];
|
auto func(int) -> int(*(*)(int))[42];
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue