From 67f247533c63966dc9912fc4de8f4717548f421b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Mon, 27 Mar 2017 21:47:57 +0200 Subject: [PATCH] Add is_templated() helper --- include/cppast/cpp_entity.hpp | 8 ++++++++ src/cpp_entity.cpp | 9 +++++++++ src/libclang/function_parser.cpp | 8 ++++---- test/cpp_alias_template.cpp | 2 ++ test/cpp_class_template.cpp | 1 + test/cpp_function_template.cpp | 2 ++ 6 files changed, 26 insertions(+), 4 deletions(-) diff --git a/include/cppast/cpp_entity.hpp b/include/cppast/cpp_entity.hpp index 4512f03..942e9d2 100644 --- a/include/cppast/cpp_entity.hpp +++ b/include/cppast/cpp_entity.hpp @@ -119,7 +119,15 @@ namespace cppast friend detail::intrusive_list_node; }; + /// \returns Whether or not the entity is templated. + /// If this function returns `true` that means the entity is not the "real" entity, + /// but contains just the information for the template which is the parent entity. + /// \notes Do not use this entity other to read information from the template entity. + bool is_templated(const cpp_entity& e) noexcept; + /// \returns The full name of the [cppast::cpp_entity](), with all scopes. + /// \notes Enitites without a name ([cppast::cpp_using_declaration]() etc.) do not have a full name either. + /// \notes For (template) parameters the full name is the name itself. std::string full_name(const cpp_entity& e); } // namespace cppast diff --git a/src/cpp_entity.cpp b/src/cpp_entity.cpp index 82dc485..20ef888 100644 --- a/src/cpp_entity.cpp +++ b/src/cpp_entity.cpp @@ -8,6 +8,15 @@ using namespace cppast; +bool cppast::is_templated(const cpp_entity& e) noexcept +{ + if (!e.parent()) + return false; + else if (!is_template(e.parent().value().kind())) + return false; + return e.parent().value().name() == e.name(); +} + std::string cppast::full_name(const cpp_entity& e) { if (e.name().empty()) diff --git a/src/libclang/function_parser.cpp b/src/libclang/function_parser.cpp index 9f6688b..d5f9f90 100644 --- a/src/libclang/function_parser.cpp +++ b/src/libclang/function_parser.cpp @@ -61,7 +61,7 @@ namespace }); } - bool is_templated(const CXCursor& cur) + bool is_templated_cursor(const CXCursor& cur) { return clang_getTemplateCursorKind(cur) != CXCursor_NoDeclFound || !clang_Cursor_isNull(clang_getSpecializedCursorTemplate(cur)); @@ -376,7 +376,7 @@ namespace if (suffix.noexcept_condition) builder.noexcept_condition(std::move(suffix.noexcept_condition)); - if (is_templated(cur)) + if (is_templated_cursor(cur)) return builder.finish(suffix.body_kind); else return builder.finish(*context.idx, detail::get_entity_id(cur), suffix.body_kind); @@ -485,7 +485,7 @@ namespace if (auto virt = calculate_virtual(cur, is_virtual, suffix.virtual_keywords)) builder.virtual_info(virt.value()); - if (is_templated(cur)) + if (is_templated_cursor(cur)) return builder.finish(suffix.body_kind); else return builder.finish(*context.idx, detail::get_entity_id(cur), suffix.body_kind); @@ -610,7 +610,7 @@ std::unique_ptr detail::parse_cpp_constructor(const detail::parse_co if (suffix.noexcept_condition) builder.noexcept_condition(std::move(suffix.noexcept_condition)); - if (is_templated(cur)) + if (is_templated_cursor(cur)) return builder.finish(suffix.body_kind); else return builder.finish(*context.idx, detail::get_entity_id(cur), suffix.body_kind); diff --git a/test/cpp_alias_template.cpp b/test/cpp_alias_template.cpp index be26370..d02f954 100644 --- a/test/cpp_alias_template.cpp +++ b/test/cpp_alias_template.cpp @@ -40,6 +40,8 @@ using h = g; cpp_entity_index idx; auto file = parse(idx, "cpp_alias_template.cpp", code); auto count = test_visit(*file, [&](const cpp_alias_template& alias) { + REQUIRE(is_templated(alias.type_alias())); + if (alias.name() == "a") { check_template_parameters(alias, {{cpp_entity_kind::template_type_parameter_t, "T"}}); diff --git a/test/cpp_class_template.cpp b/test/cpp_class_template.cpp index a8de989..21b87d0 100644 --- a/test/cpp_class_template.cpp +++ b/test/cpp_class_template.cpp @@ -62,6 +62,7 @@ struct b<0, T> {}; auto count = test_visit(*file, [&](const cpp_class_template& templ) { auto& c = templ.class_(); REQUIRE(!c.is_final()); + REQUIRE(is_templated(c)); if (templ.name() == "a") { diff --git a/test/cpp_function_template.cpp b/test/cpp_function_template.cpp index 7130c3e..d4407b1 100644 --- a/test/cpp_function_template.cpp +++ b/test/cpp_function_template.cpp @@ -54,6 +54,8 @@ d::d(const int&); cpp_entity_index idx; auto file = parse(idx, "cpp_function_template.cpp", code); auto count = test_visit(*file, [&](const cpp_function_template& tfunc) { + REQUIRE(is_templated(tfunc.function())); + if (tfunc.name() == "a") { check_template_parameters(tfunc, {{cpp_entity_kind::template_type_parameter_t, "T"}});