From fe5eb5a047b691c84a662b130c2b6185921ac5e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Tue, 24 Jan 2017 20:29:30 +0100 Subject: [PATCH] Add cpp_base_class --- include/cppast/cpp_class.hpp | 70 +++++++++++++++++++++++++++++- include/cppast/cpp_entity_kind.hpp | 1 + src/cpp_class.cpp | 5 +++ src/cpp_entity_kind.cpp | 4 +- src/visitor.cpp | 1 + 5 files changed, 78 insertions(+), 3 deletions(-) diff --git a/include/cppast/cpp_class.hpp b/include/cppast/cpp_class.hpp index 0eaa9b3..9762b3d 100644 --- a/include/cppast/cpp_class.hpp +++ b/include/cppast/cpp_class.hpp @@ -7,6 +7,7 @@ #include #include +#include namespace cppast { @@ -61,6 +62,51 @@ namespace cppast cpp_access_specifier_kind access_; }; + /// A [cppast::cpp_entity]() modelling a base class specifier. + class cpp_base_class final : public cpp_entity + { + public: + /// \returns A newly created base class specifier. + /// \notes It is not meant to be registered at the [cppast::cpp_entity_index](), + /// as nothing can refer to the specifier itself. + static std::unique_ptr build(const cpp_type_ref& base, + cpp_access_specifier_kind access, + bool is_virtual) + { + return std::unique_ptr(new cpp_base_class(base, access, is_virtual)); + } + + /// \returns An entity reference to the base class. + cpp_type_ref entity() const + { + return cpp_type_ref(base_id_, name()); + } + + /// \returns The access specifier of the base class. + cpp_access_specifier_kind access_specifier() const noexcept + { + return access_; + } + + /// \returns Whether or not it is a `virtual` base class. + bool is_virtual() const noexcept + { + return virtual_; + } + + private: + cpp_base_class(const cpp_type_ref& base, cpp_access_specifier_kind access, bool is_virtual) + : cpp_entity(base.name()), base_id_(base.id()), access_(access), virtual_(is_virtual) + { + } + + cpp_entity_kind do_get_entity_kind() const noexcept override; + + cpp_entity_id base_id_; + cpp_access_specifier_kind access_; + bool virtual_; + }; + /// A [cppast::cpp_entity]() modelling a C++ class. class cpp_class final : public cpp_entity, public cpp_entity_container { @@ -75,6 +121,19 @@ namespace cppast { } + /// \effects Builds a [cppast::cpp_base_class]() and adds it. + void base_class(const cpp_type_ref& base, cpp_access_specifier_kind access, + bool is_virtual) + { + add_base_class(cpp_base_class::build(base, access, is_virtual)); + } + + /// \effects Adds a new base class. + void add_base_class(std::unique_ptr base) noexcept + { + class_->bases_.push_back(*class_, std::move(base)); + } + /// \effects Builds a [cppast::cpp_access_specifier]() and adds it. void access_specifier(cpp_access_specifier_kind access) { @@ -109,6 +168,12 @@ namespace cppast return final_; } + /// \returns An iteratable object iterating over the [cppast::cpp_base_class]() specifiers. + detail::iteratable_intrusive_list bases() const noexcept + { + return type_safe::ref(bases_); + } + private: cpp_class(std::string name, cpp_class_kind kind, bool final) : cpp_entity(std::move(name)), kind_(kind), final_(final) @@ -123,8 +188,9 @@ namespace cppast return name(); } - cpp_class_kind kind_; - bool final_; + detail::intrusive_list bases_; + cpp_class_kind kind_; + bool final_; }; } // namespace cppast diff --git a/include/cppast/cpp_entity_kind.hpp b/include/cppast/cpp_entity_kind.hpp index cc0759e..9e35f1a 100644 --- a/include/cppast/cpp_entity_kind.hpp +++ b/include/cppast/cpp_entity_kind.hpp @@ -28,6 +28,7 @@ namespace cppast class_t, access_specifier_t, + base_class_t, variable_t, diff --git a/src/cpp_class.cpp b/src/cpp_class.cpp index b6f6b41..3687b8f 100644 --- a/src/cpp_class.cpp +++ b/src/cpp_class.cpp @@ -51,6 +51,11 @@ cpp_entity_kind cpp_access_specifier::do_get_entity_kind() const noexcept return cpp_entity_kind::access_specifier_t; } +cpp_entity_kind cpp_base_class::do_get_entity_kind() const noexcept +{ + return cpp_entity_kind::base_class_t; +} + cpp_entity_kind cpp_class::do_get_entity_kind() const noexcept { return cpp_entity_kind::class_t; diff --git a/src/cpp_entity_kind.cpp b/src/cpp_entity_kind.cpp index a7b2455..27aea47 100644 --- a/src/cpp_entity_kind.cpp +++ b/src/cpp_entity_kind.cpp @@ -37,6 +37,8 @@ const char* cppast::to_string(cpp_entity_kind kind) noexcept return "class"; case cpp_entity_kind::access_specifier_t: return "access specifier"; + case cpp_entity_kind::base_class_t: + return "base class specifier"; case cpp_entity_kind::variable_t: return "variable"; @@ -70,7 +72,7 @@ bool cppast::is_type(cpp_entity_kind kind) noexcept case cpp_entity_kind::using_declaration_t: case cpp_entity_kind::enum_value_t: case cpp_entity_kind::access_specifier_t: - break; + case cpp_entity_kind::base_class_t: case cpp_entity_kind::variable_t: case cpp_entity_kind::function_parameter_t: case cpp_entity_kind::function_t: diff --git a/src/visitor.cpp b/src/visitor.cpp index b70b021..8bfa2f3 100644 --- a/src/visitor.cpp +++ b/src/visitor.cpp @@ -57,6 +57,7 @@ bool detail::visit(const cpp_entity& e, detail::visitor_callback_t cb, void* fun case cpp_entity_kind::type_alias_t: case cpp_entity_kind::enum_value_t: case cpp_entity_kind::access_specifier_t: + case cpp_entity_kind::base_class_t: case cpp_entity_kind::variable_t: case cpp_entity_kind::function_parameter_t: return cb(functor, e, visitor_info::leaf_entity);