Ensure compatibility with clang 4.0.0

There are some bug fixes for libclang, so now some workarounds were broken.
This commit is contained in:
Jonathan Müller 2017-04-02 19:23:49 +02:00
commit dc5abeb785
5 changed files with 24 additions and 13 deletions

View file

@ -81,9 +81,7 @@ namespace
detail::skip(stream, "virtual"); detail::skip(stream, "virtual");
detail::skip_if(stream, to_string(access)); detail::skip_if(stream, to_string(access));
std::string name; auto name = detail::to_string(stream, stream.end());
while (!stream.done())
name += stream.get().c_str();
auto type = detail::parse_type(context, class_cur, clang_getCursorType(cur)); auto type = detail::parse_type(context, class_cur, clang_getCursorType(cur));
builder.base_class(std::move(name), std::move(type), access, is_virtual); builder.base_class(std::move(name), std::move(type), access, is_virtual);

View file

@ -88,7 +88,7 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_namespace_alias(const detail::pars
// <nested identifier>; // <nested identifier>;
std::string target_name; std::string target_name;
while (!detail::skip_if(stream, ";")) while (!stream.done() && !detail::skip_if(stream, ";"))
target_name += stream.get().c_str(); target_name += stream.get().c_str();
auto target = cpp_namespace_ref(parse_ns_target_cursor(cur), std::move(target_name)); auto target = cpp_namespace_ref(parse_ns_target_cursor(cur), std::move(target_name));
@ -112,7 +112,7 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_using_directive(const detail::pars
// <nested identifier>; // <nested identifier>;
std::string target_name; std::string target_name;
while (!detail::skip_if(stream, ";")) while (!stream.done() && !detail::skip_if(stream, ";"))
target_name += stream.get().c_str(); target_name += stream.get().c_str();
auto target = cpp_namespace_ref(parse_ns_target_cursor(cur), std::move(target_name)); auto target = cpp_namespace_ref(parse_ns_target_cursor(cur), std::move(target_name));
@ -177,7 +177,7 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_using_declaration(
// <nested identifier>; // <nested identifier>;
std::string target_name; std::string target_name;
while (!detail::skip_if(stream, ";")) while (!stream.done() && !detail::skip_if(stream, ";"))
target_name += stream.get().c_str(); target_name += stream.get().c_str();
auto target = cpp_entity_ref(parse_entity_target_cursor(cur), std::move(target_name)); auto target = cpp_entity_ref(parse_entity_target_cursor(cur), std::move(target_name));

View file

@ -104,9 +104,7 @@ namespace
auto child_extent = clang_getCursorExtent(child); auto child_extent = clang_getCursorExtent(child);
end = clang_getRangeStart(child_extent); end = clang_getRangeStart(child_extent);
range_shrunk = true; range_shrunk = true;
return CXChildVisit_Break;
} }
return CXChildVisit_Continue;
}); });
if (!range_shrunk && !token_after_is(tu, file, cur, end, ";")) if (!range_shrunk && !token_after_is(tu, file, cur, end, ";"))
@ -135,7 +133,11 @@ namespace
--paren_count; --paren_count;
prev = next; prev = next;
} }
#if CINDEX_VERSION_MINOR < 37
end = prev; end = prev;
#else
end = next;
#endif
} }
else if (kind == CXCursor_TemplateTemplateParameter else if (kind == CXCursor_TemplateTemplateParameter
&& token_after_is(tu, file, cur, end, "<")) && token_after_is(tu, file, cur, end, "<"))
@ -176,9 +178,16 @@ namespace
// need to shrink range anyway // need to shrink range anyway
end = get_next_location(tu, file, end, -1); end = get_next_location(tu, file, end, -1);
} }
else if (clang_isExpression(kind) || kind == CXCursor_CXXBaseSpecifier else if (kind == CXCursor_EnumDecl && !token_after_is(tu, file, cur, end, ";"))
{
while (!token_after_is(tu, file, cur, end, ";"))
end = get_next_location(tu, file, end);
}
else if (clang_isExpression(kind)
#if CINDEX_VERSION_MINOR < 37
|| kind == CXCursor_CXXBaseSpecifier || kind == CXCursor_TemplateTypeParameter
#endif
|| kind == CXCursor_FieldDecl || kind == CXCursor_ParmDecl || kind == CXCursor_FieldDecl || kind == CXCursor_ParmDecl
|| kind == CXCursor_TemplateTypeParameter
|| kind == CXCursor_NonTypeTemplateParameter || kind == CXCursor_NonTypeTemplateParameter
|| kind == CXCursor_TemplateTemplateParameter) || kind == CXCursor_TemplateTemplateParameter)
// need to shrink range by one // need to shrink range by one
@ -202,7 +211,9 @@ void detail::skip(detail::token_stream& stream, const char* str)
{ {
if (*str) if (*str)
{ {
// non-empty // non-empty string
DEBUG_ASSERT(!stream.done(), parse_error_handler{}, stream.cursor(),
format("expected '", str, "', got exhausted stream"));
auto& token = stream.peek(); auto& token = stream.peek();
DEBUG_ASSERT(token == str, parse_error_handler{}, stream.cursor(), DEBUG_ASSERT(token == str, parse_error_handler{}, stream.cursor(),
format("expected '", str, "', got '", token.c_str(), "'")); format("expected '", str, "', got '", token.c_str(), "'"));
@ -227,6 +238,8 @@ bool detail::skip_if(detail::token_stream& stream, const char* str, bool multi_t
{ {
if (!*str) if (!*str)
return true; return true;
else if (stream.done())
return false;
auto save = stream.cur(); auto save = stream.cur();
do do
{ {

View file

@ -32,8 +32,7 @@ enum class bar
void func(int(*)(int)); void func(int(*)(int));
extern void(* ptr)(int(*)(int))=&func; extern void(* ptr)(int(*)(int))=&func;
)";
template<typename T>int var;)";
auto file = parse({}, "code_generator.cpp", code); auto file = parse({}, "code_generator.cpp", code);
REQUIRE(get_code(*file) == code); REQUIRE(get_code(*file) == code);

View file

@ -141,6 +141,7 @@ enum c : int;
REQUIRE(e.is_declaration()); REQUIRE(e.is_declaration());
REQUIRE(!e.is_definition()); REQUIRE(!e.is_definition());
REQUIRE(!e.is_scoped()); REQUIRE(!e.is_scoped());
REQUIRE(e.underlying_type().has_value());
REQUIRE( REQUIRE(
equal_types(idx, e.underlying_type().value(), *cpp_builtin_type::build(cpp_int))); equal_types(idx, e.underlying_type().value(), *cpp_builtin_type::build(cpp_int)));
REQUIRE(count_children(e) == 0u); REQUIRE(count_children(e) == 0u);