diff --git a/include/cppast/cpp_class.hpp b/include/cppast/cpp_class.hpp new file mode 100644 index 0000000..0eaa9b3 --- /dev/null +++ b/include/cppast/cpp_class.hpp @@ -0,0 +1,131 @@ +// Copyright (C) 2017 Jonathan Müller +// This file is subject to the license terms in the LICENSE file +// found in the top-level directory of this distribution. + +#ifndef CPPAST_CPP_CLASS_HPP_INCLUDED +#define CPPAST_CPP_CLASS_HPP_INCLUDED + +#include +#include + +namespace cppast +{ + /// The keyword used on the declaration of a [cppast::cpp_class](). + enum class cpp_class_kind + { + class_t, + struct_t, + union_t, + }; + + /// \returns The keyword as a string. + const char* to_string(cpp_class_kind kind) noexcept; + + /// The C++ access specifiers. + enum cpp_access_specifier_kind + { + cpp_public, + cpp_protected, + cpp_private + }; + + /// \returns The access specifier keyword as a string. + const char* to_string(cpp_access_specifier_kind access) noexcept; + + /// A [cppast::cpp_entity]() modelling a C++ access specifier. + class cpp_access_specifier final : public cpp_entity + { + public: + /// \returns A newly created access specifier. + /// \notes It is not meant to be registered at the [cppast::cpp_entity_index](), + /// as nothing can refer to it. + static std::unique_ptr build(cpp_access_specifier_kind kind) + { + return std::unique_ptr(new cpp_access_specifier(kind)); + } + + /// \returns The kind of access specifier. + cpp_access_specifier_kind access_specifier() const noexcept + { + return access_; + } + + private: + cpp_access_specifier(cpp_access_specifier_kind access) + : cpp_entity(to_string(access)), access_(access) + { + } + + cpp_entity_kind do_get_entity_kind() const noexcept override; + + cpp_access_specifier_kind access_; + }; + + /// A [cppast::cpp_entity]() modelling a C++ class. + class cpp_class final : public cpp_entity, public cpp_entity_container + { + public: + /// Builds a [cppast::cpp_class](). + class builder + { + public: + /// \effects Sets the name and kind and whether it is `final`. + explicit builder(std::string name, cpp_class_kind kind, bool is_final) + : class_(new cpp_class(std::move(name), kind, is_final)) + { + } + + /// \effects Builds a [cppast::cpp_access_specifier]() and adds it. + void access_specifier(cpp_access_specifier_kind access) + { + add_child(cpp_access_specifier::build(access)); + } + + /// \effects Adds an entity. + void add_child(std::unique_ptr child) noexcept + { + class_->add_child(std::move(child)); + } + + /// \effects Registers the class in the [cppast::cpp_entity_index](), + /// using the given [cppast::cpp_entity_id](). + /// \returns The finished class. + std::unique_ptr finish(const cpp_entity_index& idx, + cpp_entity_id id) noexcept; + + private: + std::unique_ptr class_; + }; + + /// \returns The keyword used in the declaration of the class. + cpp_class_kind class_kind() const noexcept + { + return kind_; + } + + /// \returns Whether or not the class was declared `final`. + bool is_final() const noexcept + { + return final_; + } + + private: + cpp_class(std::string name, cpp_class_kind kind, bool final) + : cpp_entity(std::move(name)), kind_(kind), final_(final) + { + } + + cpp_entity_kind do_get_entity_kind() const noexcept override; + + /// \returns The name of the namespace. + type_safe::optional do_get_scope_name() const override + { + return name(); + } + + cpp_class_kind kind_; + bool final_; + }; +} // namespace cppast + +#endif // CPPAST_CPP_CLASS_HPP_INCLUDED diff --git a/include/cppast/cpp_entity_kind.hpp b/include/cppast/cpp_entity_kind.hpp index 0e4ecfb..cc0759e 100644 --- a/include/cppast/cpp_entity_kind.hpp +++ b/include/cppast/cpp_entity_kind.hpp @@ -26,6 +26,9 @@ namespace cppast enum_t, enum_value_t, + class_t, + access_specifier_t, + variable_t, function_parameter_t, diff --git a/src/cpp_class.cpp b/src/cpp_class.cpp new file mode 100644 index 0000000..b6f6b41 --- /dev/null +++ b/src/cpp_class.cpp @@ -0,0 +1,57 @@ +// Copyright (C) 2017 Jonathan Müller +// This file is subject to the license terms in the LICENSE file +// found in the top-level directory of this distribution. + +#include + +#include +#include + +using namespace cppast; + +std::unique_ptr cpp_class::builder::finish(const cpp_entity_index& idx, + cpp_entity_id id) noexcept +{ + idx.register_entity(std::move(id), type_safe::ref(*class_)); + return std::move(class_); +} + +const char* cppast::to_string(cpp_class_kind kind) noexcept +{ + switch (kind) + { + case cpp_class_kind::class_t: + return "class"; + case cpp_class_kind::struct_t: + return "struct"; + case cpp_class_kind::union_t: + return "union"; + } + + return "should not get here"; +} + +const char* cppast::to_string(cpp_access_specifier_kind access) noexcept +{ + switch (access) + { + case cpp_public: + return "public"; + case cpp_protected: + return "protected"; + case cpp_private: + return "private"; + } + + return "should not get here either"; +} + +cpp_entity_kind cpp_access_specifier::do_get_entity_kind() const noexcept +{ + return cpp_entity_kind::access_specifier_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 4d26f61..a7b2455 100644 --- a/src/cpp_entity_kind.cpp +++ b/src/cpp_entity_kind.cpp @@ -33,6 +33,11 @@ const char* cppast::to_string(cpp_entity_kind kind) noexcept case cpp_entity_kind::enum_value_t: return "enum value"; + case cpp_entity_kind::class_t: + return "class"; + case cpp_entity_kind::access_specifier_t: + return "access specifier"; + case cpp_entity_kind::variable_t: return "variable"; @@ -52,8 +57,9 @@ bool cppast::is_type(cpp_entity_kind kind) noexcept { switch (kind) { - case cpp_entity_kind::enum_t: case cpp_entity_kind::type_alias_t: + case cpp_entity_kind::enum_t: + case cpp_entity_kind::class_t: return true; case cpp_entity_kind::file_t: @@ -63,6 +69,8 @@ bool cppast::is_type(cpp_entity_kind kind) noexcept case cpp_entity_kind::using_directive_t: 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::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 951ae18..b70b021 100644 --- a/src/visitor.cpp +++ b/src/visitor.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -45,6 +46,8 @@ bool detail::visit(const cpp_entity& e, detail::visitor_callback_t cb, void* fun return handle_container(e, cb, functor); case cpp_entity_kind::enum_t: return handle_container(e, cb, functor); + case cpp_entity_kind::class_t: + return handle_container(e, cb, functor); case cpp_entity_kind::function_t: return handle_container(e, cb, functor); @@ -53,6 +56,7 @@ bool detail::visit(const cpp_entity& e, detail::visitor_callback_t cb, void* fun case cpp_entity_kind::using_declaration_t: 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::variable_t: case cpp_entity_kind::function_parameter_t: return cb(functor, e, visitor_info::leaf_entity);