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;
|
||||
}
|
||||
|
||||
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!)
|
||||
|
|
@ -186,9 +206,9 @@ namespace
|
|||
}
|
||||
|
||||
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
|
||||
auto prefix = prefix_cv(spelling);
|
||||
|
|
@ -219,14 +239,14 @@ namespace
|
|||
std::unique_ptr<cpp_type> parse_type_impl(const detail::parse_context& context,
|
||||
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);
|
||||
if (size != -1)
|
||||
return cpp_literal_expression::build(cpp_builtin_type::build(cpp_ulonglong),
|
||||
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{},
|
||||
type, "unexpected token");
|
||||
|
||||
|
|
@ -269,7 +289,7 @@ namespace
|
|||
// 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));
|
||||
}
|
||||
|
||||
|
|
@ -320,7 +340,7 @@ namespace
|
|||
std::unique_ptr<cpp_type> parse_member_pointee_type(const detail::parse_context& context,
|
||||
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 cv = suffix_cv(spelling);
|
||||
|
||||
|
|
@ -383,28 +403,32 @@ namespace
|
|||
|
||||
// doesn't respect cv qualifiers properly
|
||||
auto result =
|
||||
make_leave_type(type, [&](std::string&& type_spelling) -> std::unique_ptr<cpp_type> {
|
||||
// look at the template parameters,
|
||||
// see if we find a matching one
|
||||
auto param = clang_getNullCursor();
|
||||
detail::visit_children(templ, [&](const CXCursor& child) {
|
||||
if (clang_getCursorKind(child) == CXCursor_TemplateTypeParameter
|
||||
&& get_type_spelling(clang_getCursorType(child)) == type_spelling)
|
||||
{
|
||||
// found one
|
||||
DEBUG_ASSERT(clang_Cursor_isNull(param), detail::assert_handler{});
|
||||
param = child;
|
||||
}
|
||||
});
|
||||
make_leave_type(cur, type,
|
||||
[&](std::string&& type_spelling) -> std::unique_ptr<cpp_type> {
|
||||
// look at the template parameters,
|
||||
// see if we find a matching one
|
||||
auto param = clang_getNullCursor();
|
||||
detail::visit_children(templ, [&](const CXCursor& child) {
|
||||
if (clang_getCursorKind(child) == CXCursor_TemplateTypeParameter
|
||||
&& get_type_spelling(child, clang_getCursorType(child))
|
||||
== type_spelling)
|
||||
{
|
||||
// found one
|
||||
DEBUG_ASSERT(clang_Cursor_isNull(param),
|
||||
detail::assert_handler{});
|
||||
param = child;
|
||||
}
|
||||
});
|
||||
|
||||
if (clang_Cursor_isNull(param))
|
||||
return nullptr;
|
||||
else
|
||||
// found matching parameter
|
||||
return cpp_template_parameter_type::build(
|
||||
cpp_template_type_parameter_ref(detail::get_entity_id(param),
|
||||
std::move(type_spelling)));
|
||||
});
|
||||
if (clang_Cursor_isNull(param))
|
||||
return nullptr;
|
||||
else
|
||||
// found matching parameter
|
||||
return cpp_template_parameter_type::build(
|
||||
cpp_template_type_parameter_ref(detail::get_entity_id(
|
||||
param),
|
||||
std::move(type_spelling)));
|
||||
});
|
||||
|
||||
if (result)
|
||||
return result;
|
||||
|
|
@ -442,7 +466,7 @@ namespace
|
|||
std::unique_ptr<cpp_type> try_parse_instantiation_type(const detail::parse_context&,
|
||||
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();
|
||||
|
||||
std::string templ_name;
|
||||
|
|
@ -478,7 +502,7 @@ namespace
|
|||
if (clang_isExpression(clang_getCursorKind(cur)))
|
||||
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))
|
||||
return nullptr;
|
||||
remove_suffix(spelling, "...", false); // variadic decltype. fun
|
||||
|
|
@ -578,93 +602,93 @@ namespace
|
|||
return ptype;
|
||||
// fallthrough
|
||||
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:
|
||||
return make_leave_type(type,
|
||||
return make_leave_type(cur, type,
|
||||
[](std::string&&) { return cpp_builtin_type::build(cpp_void); });
|
||||
case CXType_Bool:
|
||||
return make_leave_type(type,
|
||||
return make_leave_type(cur, type,
|
||||
[](std::string&&) { return cpp_builtin_type::build(cpp_bool); });
|
||||
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);
|
||||
});
|
||||
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);
|
||||
});
|
||||
case CXType_UInt:
|
||||
return make_leave_type(type,
|
||||
return make_leave_type(cur, type,
|
||||
[](std::string&&) { return cpp_builtin_type::build(cpp_uint); });
|
||||
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);
|
||||
});
|
||||
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);
|
||||
});
|
||||
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);
|
||||
});
|
||||
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);
|
||||
});
|
||||
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);
|
||||
});
|
||||
case CXType_Int:
|
||||
return make_leave_type(type,
|
||||
return make_leave_type(cur, type,
|
||||
[](std::string&&) { return cpp_builtin_type::build(cpp_int); });
|
||||
case CXType_Long:
|
||||
return make_leave_type(type,
|
||||
return make_leave_type(cur, type,
|
||||
[](std::string&&) { return cpp_builtin_type::build(cpp_long); });
|
||||
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);
|
||||
});
|
||||
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);
|
||||
});
|
||||
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);
|
||||
});
|
||||
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);
|
||||
});
|
||||
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);
|
||||
});
|
||||
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);
|
||||
});
|
||||
case CXType_Char_U:
|
||||
case CXType_Char_S:
|
||||
return make_leave_type(type,
|
||||
return make_leave_type(cur, type,
|
||||
[](std::string&&) { return cpp_builtin_type::build(cpp_char); });
|
||||
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);
|
||||
});
|
||||
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);
|
||||
});
|
||||
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);
|
||||
});
|
||||
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);
|
||||
});
|
||||
|
||||
|
|
@ -676,7 +700,7 @@ namespace
|
|||
case CXType_Record:
|
||||
case CXType_Enum:
|
||||
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);
|
||||
if (remove_prefix(spelling, "(anonymous", false))
|
||||
spelling = ""; // anonymous type
|
||||
|
|
@ -689,7 +713,7 @@ namespace
|
|||
auto pointee = parse_type_impl(context, cur, clang_getPointeeType(type));
|
||||
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);
|
||||
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));
|
||||
|
||||
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{});
|
||||
|
|
|
|||
|
|
@ -24,7 +24,9 @@ using struct_=int;
|
|||
struct_ var2;
|
||||
|
||||
struct foo{
|
||||
int a;
|
||||
using my_int=int;
|
||||
|
||||
my_int a;
|
||||
|
||||
auto func(int)->int(*(*)(int))[42];
|
||||
|
||||
|
|
@ -66,7 +68,9 @@ struct_ var2;
|
|||
|
||||
struct foo
|
||||
{
|
||||
int a;
|
||||
using my_int = int;
|
||||
|
||||
my_int a;
|
||||
|
||||
auto func(int) -> int(*(*)(int))[42];
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue