Add and parse cpp_static_assert
This commit is contained in:
parent
d125869df5
commit
4db09778b5
14 changed files with 200 additions and 6 deletions
|
|
@ -32,6 +32,7 @@ set(header
|
|||
../include/cppast/cpp_member_variable.hpp
|
||||
../include/cppast/cpp_namespace.hpp
|
||||
../include/cppast/cpp_preprocessor.hpp
|
||||
../include/cppast/cpp_static_assert.hpp
|
||||
../include/cppast/cpp_storage_class_specifiers.hpp
|
||||
../include/cppast/cpp_template.hpp
|
||||
../include/cppast/cpp_template_parameter.hpp
|
||||
|
|
@ -64,6 +65,7 @@ set(source
|
|||
cpp_member_variable.cpp
|
||||
cpp_namespace.cpp
|
||||
cpp_preprocessor.cpp
|
||||
cpp_static_assert.cpp
|
||||
cpp_template_parameter.cpp
|
||||
cpp_type.cpp
|
||||
cpp_type_alias.cpp
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <cppast/cpp_member_variable.hpp>
|
||||
#include <cppast/cpp_namespace.hpp>
|
||||
#include <cppast/cpp_preprocessor.hpp>
|
||||
#include <cppast/cpp_static_assert.hpp>
|
||||
#include <cppast/cpp_template_parameter.hpp>
|
||||
#include <cppast/cpp_type_alias.hpp>
|
||||
#include <cppast/cpp_variable.hpp>
|
||||
|
|
@ -843,6 +844,18 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
void generate_static_assert(code_generator& generator, const cpp_static_assert& assert)
|
||||
{
|
||||
code_generator::output output(type_safe::ref(generator), type_safe::ref(assert), false);
|
||||
if (output)
|
||||
{
|
||||
output << keyword("static_assert") << punctuation("(");
|
||||
detail::write_expression(output, assert.expression());
|
||||
output << punctuation(",") << string_literal('"' + assert.message() + '"');
|
||||
output << punctuation(");") << newl;
|
||||
}
|
||||
}
|
||||
|
||||
void generate_unexposed(code_generator& generator, const cpp_unexposed_entity& entity)
|
||||
{
|
||||
code_generator::output output(type_safe::ref(generator), type_safe::ref(entity), false);
|
||||
|
|
@ -904,6 +917,8 @@ void cppast::generate_code(code_generator& generator, const cpp_entity& e)
|
|||
CPPAST_DETAIL_HANDLE(class_template)
|
||||
CPPAST_DETAIL_HANDLE(class_template_specialization)
|
||||
|
||||
CPPAST_DETAIL_HANDLE(static_assert)
|
||||
|
||||
case cpp_entity_kind::unexposed_t:
|
||||
generate_unexposed(generator, static_cast<const cpp_unexposed_entity&>(e));
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -88,6 +88,9 @@ const char* cppast::to_string(cpp_entity_kind kind) noexcept
|
|||
case cpp_entity_kind::class_template_specialization_t:
|
||||
return "class template specialization";
|
||||
|
||||
case cpp_entity_kind::static_assert_t:
|
||||
return "static_assert";
|
||||
|
||||
case cpp_entity_kind::unexposed_t:
|
||||
return "unexposed entity";
|
||||
|
||||
|
|
@ -137,6 +140,7 @@ bool cppast::is_function(cpp_entity_kind kind) noexcept
|
|||
case cpp_entity_kind::function_template_specialization_t:
|
||||
case cpp_entity_kind::class_template_t:
|
||||
case cpp_entity_kind::class_template_specialization_t:
|
||||
case cpp_entity_kind::static_assert_t:
|
||||
case cpp_entity_kind::unexposed_t:
|
||||
case cpp_entity_kind::count:
|
||||
break;
|
||||
|
|
@ -184,6 +188,7 @@ bool cppast::is_parameter(cpp_entity_kind kind) noexcept
|
|||
case cpp_entity_kind::function_template_specialization_t:
|
||||
case cpp_entity_kind::class_template_t:
|
||||
case cpp_entity_kind::class_template_specialization_t:
|
||||
case cpp_entity_kind::static_assert_t:
|
||||
case cpp_entity_kind::unexposed_t:
|
||||
case cpp_entity_kind::count:
|
||||
break;
|
||||
|
|
@ -230,6 +235,7 @@ bool cppast::is_template(cpp_entity_kind kind) noexcept
|
|||
case cpp_entity_kind::template_type_parameter_t:
|
||||
case cpp_entity_kind::non_type_template_parameter_t:
|
||||
case cpp_entity_kind::template_template_parameter_t:
|
||||
case cpp_entity_kind::static_assert_t:
|
||||
case cpp_entity_kind::unexposed_t:
|
||||
case cpp_entity_kind::count:
|
||||
break;
|
||||
|
|
@ -277,6 +283,7 @@ bool cppast::is_template_specialization(cpp_entity_kind kind) noexcept
|
|||
case cpp_entity_kind::variable_template_t:
|
||||
case cpp_entity_kind::function_template_t:
|
||||
case cpp_entity_kind::class_template_t:
|
||||
case cpp_entity_kind::static_assert_t:
|
||||
case cpp_entity_kind::unexposed_t:
|
||||
case cpp_entity_kind::count:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ namespace
|
|||
case cpp_entity_kind::function_template_specialization_t:
|
||||
case cpp_entity_kind::class_template_t:
|
||||
case cpp_entity_kind::class_template_specialization_t:
|
||||
case cpp_entity_kind::static_assert_t:
|
||||
case cpp_entity_kind::unexposed_t:
|
||||
return nullptr;
|
||||
|
||||
|
|
|
|||
19
src/cpp_static_assert.cpp
Normal file
19
src/cpp_static_assert.cpp
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (C) 2017 Jonathan Müller <jonathanmueller.dev@gmail.com>
|
||||
// This file is subject to the license terms in the LICENSE file
|
||||
// found in the top-level directory of this distribution.
|
||||
|
||||
#include <cppast/cpp_static_assert.hpp>
|
||||
|
||||
#include <cppast/cpp_entity_kind.hpp>
|
||||
|
||||
using namespace cppast;
|
||||
|
||||
cppast::cpp_entity_kind cpp_static_assert::kind() noexcept
|
||||
{
|
||||
return cpp_entity_kind::static_assert_t;
|
||||
}
|
||||
|
||||
cppast::cpp_entity_kind cpp_static_assert::do_get_entity_kind() const noexcept
|
||||
{
|
||||
return kind();
|
||||
}
|
||||
|
|
@ -113,6 +113,7 @@ bool detail::cpp_type_ref_predicate::operator()(const cpp_entity& e)
|
|||
case cpp_entity_kind::function_template_specialization_t:
|
||||
case cpp_entity_kind::class_template_t:
|
||||
case cpp_entity_kind::class_template_specialization_t:
|
||||
case cpp_entity_kind::static_assert_t:
|
||||
case cpp_entity_kind::unexposed_t:
|
||||
case cpp_entity_kind::count:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@
|
|||
#include "parse_functions.hpp"
|
||||
|
||||
#include <cppast/cpp_storage_class_specifiers.hpp>
|
||||
#include <cppast/cpp_static_assert.hpp>
|
||||
|
||||
#include "libclang_visitor.hpp"
|
||||
|
||||
using namespace cppast;
|
||||
|
||||
|
|
@ -153,6 +156,9 @@ std::unique_ptr<cpp_entity> detail::parse_entity(const detail::parse_context& co
|
|||
case CXCursor_ClassTemplatePartialSpecialization:
|
||||
return parse_cpp_class_template_specialization(context, cur);
|
||||
|
||||
case CXCursor_StaticAssert:
|
||||
return parse_cpp_static_assert(context, cur);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -178,3 +184,39 @@ catch (parse_error& ex)
|
|||
context.logger->log("libclang parser", ex.get_diagnostic());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<cpp_entity> detail::parse_cpp_static_assert(const detail::parse_context& context,
|
||||
const CXCursor& cur)
|
||||
{
|
||||
DEBUG_ASSERT(clang_getCursorKind(cur) == CXCursor_StaticAssert, detail::assert_handler{});
|
||||
|
||||
std::unique_ptr<cpp_expression> expr;
|
||||
std::string msg;
|
||||
detail::visit_children(cur, [&](const CXCursor& child) {
|
||||
if (!expr)
|
||||
{
|
||||
DEBUG_ASSERT(clang_isExpression(clang_getCursorKind(child)),
|
||||
detail::parse_error_handler{}, cur,
|
||||
"unexpected child cursor of static assert");
|
||||
expr = detail::parse_expression(context, child);
|
||||
}
|
||||
else if (msg.empty())
|
||||
{
|
||||
DEBUG_ASSERT(clang_getCursorKind(child) == CXCursor_StringLiteral,
|
||||
detail::parse_error_handler{}, cur,
|
||||
"unexpected child cursor of static assert");
|
||||
msg = detail::get_cursor_name(child).c_str();
|
||||
DEBUG_ASSERT(msg.front() == '"' && msg.back() == '"', detail::parse_error_handler{},
|
||||
cur, "unexpected name format");
|
||||
msg.pop_back();
|
||||
msg.erase(msg.begin());
|
||||
}
|
||||
else
|
||||
DEBUG_UNREACHABLE(detail::parse_error_handler{}, cur,
|
||||
"unexpected child cursor of static assert");
|
||||
});
|
||||
|
||||
auto result = cpp_static_assert::build(std::move(expr), std::move(msg));
|
||||
context.comments.match(*result, cur);
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,6 +156,9 @@ namespace cppast
|
|||
std::unique_ptr<cpp_entity> parse_cpp_class_template_specialization(
|
||||
const parse_context& context, const CXCursor& cur);
|
||||
|
||||
std::unique_ptr<cpp_entity> parse_cpp_static_assert(const parse_context& context,
|
||||
const CXCursor& cur);
|
||||
|
||||
// parent_cur: used when parsing templates or friends
|
||||
std::unique_ptr<cpp_entity> parse_entity(
|
||||
const parse_context& context, const CXCursor& cur,
|
||||
|
|
|
|||
|
|
@ -183,13 +183,14 @@ namespace
|
|||
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
|
||||
else if (kind == CXCursor_FieldDecl || kind == CXCursor_ParmDecl
|
||||
|| kind == CXCursor_NonTypeTemplateParameter
|
||||
|| kind == CXCursor_TemplateTemplateParameter)
|
||||
|| kind == CXCursor_TemplateTemplateParameter
|
||||
#if CINDEX_VERSION_MINOR < 37
|
||||
|| clang_isExpression(kind) || kind == CXCursor_CXXBaseSpecifier
|
||||
|| kind == CXCursor_TemplateTypeParameter
|
||||
#endif
|
||||
)
|
||||
// need to shrink range by one
|
||||
end = get_next_location(tu, file, end, -1);
|
||||
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ bool detail::visit(const cpp_entity& e, detail::visitor_callback_t cb, void* fun
|
|||
case cpp_entity_kind::template_type_parameter_t:
|
||||
case cpp_entity_kind::non_type_template_parameter_t:
|
||||
case cpp_entity_kind::template_template_parameter_t:
|
||||
case cpp_entity_kind::static_assert_t:
|
||||
case cpp_entity_kind::unexposed_t:
|
||||
return cb(functor, e, {visitor_info::leaf_entity, last_child});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue