Support attributes in using declaration target

Fixes parsing of libcxx.
This commit is contained in:
Jonathan Müller 2021-12-19 16:19:50 +01:00
commit d303bab0da

View file

@ -85,21 +85,22 @@ namespace
cpp_entity_id parse_ns_target_cursor(const CXCursor& cur)
{
cpp_entity_id result("");
detail::visit_children(cur,
[&](const CXCursor& child) {
auto referenced = clang_getCursorReferenced(child);
auto kind = clang_getCursorKind(referenced);
if (kind == CXCursor_Namespace)
result = detail::get_entity_id(referenced);
else if (kind == CXCursor_NamespaceAlias)
// get target of namespace alias instead
result = parse_ns_target_cursor(referenced);
else
DEBUG_UNREACHABLE(detail::parse_error_handler{}, cur,
"unexpected target for namespace "
"alias/using directive");
},
true);
detail::visit_children(
cur,
[&](const CXCursor& child) {
auto referenced = clang_getCursorReferenced(child);
auto kind = clang_getCursorKind(referenced);
if (kind == CXCursor_Namespace)
result = detail::get_entity_id(referenced);
else if (kind == CXCursor_NamespaceAlias)
// get target of namespace alias instead
result = parse_ns_target_cursor(referenced);
else
DEBUG_UNREACHABLE(detail::parse_error_handler{}, cur,
"unexpected target for namespace "
"alias/using directive");
},
true);
return result;
}
} // namespace
@ -157,47 +158,46 @@ namespace
cpp_entity_ref parse_entity_target_cursor(const CXCursor& cur, std::string name)
{
type_safe::deferred_construction<cpp_entity_ref> result;
detail::visit_children(cur,
[&](const CXCursor& child) {
if (result)
return;
detail::visit_children(
cur,
[&](const CXCursor& child) {
if (result)
return;
switch (clang_getCursorKind(child))
{
case CXCursor_TypeRef:
case CXCursor_TemplateRef:
case CXCursor_MemberRef:
case CXCursor_VariableRef:
case CXCursor_DeclRefExpr:
{
auto referenced = clang_getCursorReferenced(child);
result = cpp_entity_ref(detail::get_entity_id(referenced),
std::move(name));
break;
}
switch (clang_getCursorKind(child))
{
case CXCursor_TypeRef:
case CXCursor_TemplateRef:
case CXCursor_MemberRef:
case CXCursor_VariableRef:
case CXCursor_DeclRefExpr: {
auto referenced = clang_getCursorReferenced(child);
result = cpp_entity_ref(detail::get_entity_id(referenced), std::move(name));
break;
}
case CXCursor_OverloadedDeclRef:
{
auto size = clang_getNumOverloadedDecls(child);
DEBUG_ASSERT(size >= 1u, detail::parse_error_handler{}, cur,
"no target for using declaration");
std::vector<cpp_entity_id> ids;
for (auto i = 0u; i != size; ++i)
ids.push_back(detail::get_entity_id(
clang_getOverloadedDecl(child, i)));
result = cpp_entity_ref(std::move(ids), std::move(name));
break;
}
case CXCursor_OverloadedDeclRef: {
auto size = clang_getNumOverloadedDecls(child);
DEBUG_ASSERT(size >= 1u, detail::parse_error_handler{}, cur,
"no target for using declaration");
std::vector<cpp_entity_id> ids;
for (auto i = 0u; i != size; ++i)
ids.push_back(detail::get_entity_id(clang_getOverloadedDecl(child, i)));
result = cpp_entity_ref(std::move(ids), std::move(name));
break;
}
case CXCursor_NamespaceRef:
break; // wait for children
case CXCursor_NamespaceRef:
break; // wait for children
default:
DEBUG_UNREACHABLE(detail::parse_error_handler{}, cur,
"unexpected target for using declaration");
}
},
true);
default:
if (clang_isAttribute(clang_getCursorKind(child)))
break;
DEBUG_UNREACHABLE(detail::parse_error_handler{}, cur,
"unexpected target for using declaration");
}
},
true);
return result.value();
}
} // namespace