Fix issue with conversion op parsing & instantiation type
This commit is contained in:
parent
6e7a8c921c
commit
1c973cb0fa
4 changed files with 29 additions and 16 deletions
|
|
@ -545,6 +545,8 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_member_function(const detail::pars
|
||||||
std::move(prefix.semantic_parent));
|
std::move(prefix.semantic_parent));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
std::unique_ptr<cpp_entity> detail::parse_cpp_conversion_op(const detail::parse_context& context,
|
std::unique_ptr<cpp_entity> detail::parse_cpp_conversion_op(const detail::parse_context& context,
|
||||||
const CXCursor& cur)
|
const CXCursor& cur)
|
||||||
{
|
{
|
||||||
|
|
@ -559,24 +561,27 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_conversion_op(const detail::parse_
|
||||||
// heuristic to find arguments tokens
|
// heuristic to find arguments tokens
|
||||||
// skip forward, skipping inside brackets
|
// skip forward, skipping inside brackets
|
||||||
auto type_start = stream.cur();
|
auto type_start = stream.cur();
|
||||||
while (true)
|
auto finished = false;
|
||||||
|
while (!stream.done() && !finished)
|
||||||
{
|
{
|
||||||
if (detail::skip_if(stream, "("))
|
if (stream.peek() == "(")
|
||||||
{
|
{
|
||||||
if (detail::skip_if(stream, ")"))
|
if (detail::skip_if(stream, "(") && detail::skip_if(stream, ")"))
|
||||||
break;
|
finished = true;
|
||||||
else
|
else
|
||||||
detail::skip_brackets(stream);
|
detail::skip_brackets(stream);
|
||||||
}
|
}
|
||||||
else if (detail::skip_if(stream, "["))
|
else if (stream.peek() == "[")
|
||||||
detail::skip_brackets(stream);
|
detail::skip_brackets(stream);
|
||||||
else if (detail::skip_if(stream, "{"))
|
else if (stream.peek() == "{")
|
||||||
detail::skip_brackets(stream);
|
detail::skip_brackets(stream);
|
||||||
else if (detail::skip_if(stream, "<"))
|
else if (stream.peek() == "<")
|
||||||
detail::skip_brackets(stream);
|
detail::skip_brackets(stream);
|
||||||
else
|
else
|
||||||
stream.bump();
|
stream.bump();
|
||||||
}
|
}
|
||||||
|
DEBUG_ASSERT(finished, detail::parse_error_handler{}, cur,
|
||||||
|
"unable to find end of conversion op type");
|
||||||
// bump arguments back
|
// bump arguments back
|
||||||
stream.bump_back();
|
stream.bump_back();
|
||||||
stream.bump_back();
|
stream.bump_back();
|
||||||
|
|
|
||||||
|
|
@ -290,7 +290,7 @@ detail::token_iterator detail::find_closing_bracket(detail::token_stream stream)
|
||||||
|
|
||||||
auto bracket_count = 1;
|
auto bracket_count = 1;
|
||||||
auto paren_count = 0; // internal nested parenthesis
|
auto paren_count = 0; // internal nested parenthesis
|
||||||
while (bracket_count != 0)
|
while (!stream.done() && bracket_count != 0)
|
||||||
{
|
{
|
||||||
auto& cur = stream.get().value();
|
auto& cur = stream.get().value();
|
||||||
if (paren_count == 0 && cur == open_bracket)
|
if (paren_count == 0 && cur == open_bracket)
|
||||||
|
|
@ -307,7 +307,8 @@ detail::token_iterator detail::find_closing_bracket(detail::token_stream stream)
|
||||||
}
|
}
|
||||||
stream.bump_back();
|
stream.bump_back();
|
||||||
// only check first parameter, token might be ">>"
|
// only check first parameter, token might be ">>"
|
||||||
DEBUG_ASSERT(paren_count == 0 && stream.peek().value()[0] == close_bracket[0],
|
DEBUG_ASSERT(bracket_count == 0 && paren_count == 0
|
||||||
|
&& stream.peek().value()[0] == close_bracket[0],
|
||||||
parse_error_handler{}, stream.cursor(),
|
parse_error_handler{}, stream.cursor(),
|
||||||
"find_closing_bracket() internal parse error");
|
"find_closing_bracket() internal parse error");
|
||||||
return stream.cur();
|
return stream.cur();
|
||||||
|
|
|
||||||
|
|
@ -585,10 +585,14 @@ namespace
|
||||||
return cpp_builtin_type::build(cpp_nullptr);
|
return cpp_builtin_type::build(cpp_nullptr);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
case CXType_Elaborated:
|
||||||
|
if (auto itype = try_parse_instantiation_type(context, cur, type))
|
||||||
|
// elaborated types can be instantiation types
|
||||||
|
return itype;
|
||||||
|
// fallthrough
|
||||||
case CXType_Record:
|
case CXType_Record:
|
||||||
case CXType_Enum:
|
case CXType_Enum:
|
||||||
case CXType_Typedef:
|
case CXType_Typedef:
|
||||||
case CXType_Elaborated:
|
|
||||||
return make_leave_type(type, [&](std::string&& spelling) {
|
return make_leave_type(type, [&](std::string&& spelling) {
|
||||||
auto decl = clang_getTypeDeclaration(type);
|
auto decl = clang_getTypeDeclaration(type);
|
||||||
if (remove_prefix(spelling, "(anonymous"))
|
if (remove_prefix(spelling, "(anonymous"))
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
// found in the top-level directory of this distribution.
|
// found in the top-level directory of this distribution.
|
||||||
|
|
||||||
#include <cppast/cpp_member_function.hpp>
|
#include <cppast/cpp_member_function.hpp>
|
||||||
|
#include <cppast/cpp_template.hpp>
|
||||||
|
|
||||||
#include "test_parser.hpp"
|
#include "test_parser.hpp"
|
||||||
|
|
||||||
|
|
@ -155,6 +156,7 @@ TEST_CASE("cpp_conversion_op")
|
||||||
auto code = R"(
|
auto code = R"(
|
||||||
namespace ns
|
namespace ns
|
||||||
{
|
{
|
||||||
|
template <typename T>
|
||||||
using type = char;
|
using type = char;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -165,8 +167,8 @@ struct foo
|
||||||
operator int&();
|
operator int&();
|
||||||
/// explicit operator bool()const;
|
/// explicit operator bool()const;
|
||||||
explicit operator bool() const;
|
explicit operator bool() const;
|
||||||
/// constexpr operator ns::type();
|
/// constexpr operator ns::type<int>();
|
||||||
constexpr operator ns::type();
|
constexpr operator ns::type<int>();
|
||||||
};
|
};
|
||||||
)";
|
)";
|
||||||
|
|
||||||
|
|
@ -196,10 +198,11 @@ struct foo
|
||||||
}
|
}
|
||||||
else if (!op.is_explicit() && op.is_constexpr())
|
else if (!op.is_explicit() && op.is_constexpr())
|
||||||
{
|
{
|
||||||
REQUIRE(op.name() == "operator ns::type");
|
REQUIRE(op.name() == "operator ns::type<int>");
|
||||||
REQUIRE(equal_types(idx, op.return_type(),
|
cpp_template_instantiation_type::builder builder(
|
||||||
*cpp_user_defined_type::build(
|
cpp_template_ref(cpp_entity_id(""), "ns::type"));
|
||||||
cpp_type_ref(cpp_entity_id(""), "ns::type"))));
|
builder.add_unexposed_arguments("int");
|
||||||
|
REQUIRE(equal_types(idx, op.return_type(), *builder.finish()));
|
||||||
REQUIRE(op.cv_qualifier() == cpp_cv_none);
|
REQUIRE(op.cv_qualifier() == cpp_cv_none);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue