diff --git a/include/cppast/cpp_entity_kind.hpp b/include/cppast/cpp_entity_kind.hpp index 0d4e87e..9f7b81b 100644 --- a/include/cppast/cpp_entity_kind.hpp +++ b/include/cppast/cpp_entity_kind.hpp @@ -36,6 +36,8 @@ namespace cppast function_parameter_t, function_t, + member_function_t, + conversion_op_t, count, }; diff --git a/include/cppast/cpp_member_function.hpp b/include/cppast/cpp_member_function.hpp new file mode 100644 index 0000000..f61a6d3 --- /dev/null +++ b/include/cppast/cpp_member_function.hpp @@ -0,0 +1,174 @@ +// 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_MEMBER_FUNCTION_HPP_INCLUDED +#define CPPAST_CPP_MEMBER_FUNCTION_HPP_INCLUDED + +#include + +namespace cppast +{ + /// The `virtual`-ness of a member function. + enum cpp_virtual + { + cpp_virtual_none, //< Not `virtual`. + cpp_virtual_pure, //< Pure `virtual` function. + cpp_virtual_new, //< New `virtual` function. + cpp_virtual_override, //< Overriden `virtual` function (attribute doesn't matter). + cpp_virtual_final, //< `final` `virtual` function. + }; + + /// \returns Whether or not the given flag means the function is `virtual`. + inline bool is_virtual(cpp_virtual virt) noexcept + { + return virt != cpp_virtual_none; + } + + /// \returns Whether or not the given flag means the function overrides a `virtual` function. + inline bool is_overriden(cpp_virtual virt) noexcept + { + return virt == cpp_virtual_override || virt == cpp_virtual_final; + } + + /// Base classes for all regular member function. + /// + /// The two derived classes are [cppast::cpp_member_function]() and [cppast::cpp_conversion_op](). + class cpp_member_function_base : public cpp_function_base + { + public: + /// \returns The return type of the member function. + const cpp_type& return_type() const noexcept + { + return *return_type_; + } + + /// \returns The `virtual`-ness of the member function. + cpp_virtual virtual_info() const noexcept + { + return virtual_; + } + + /// \returns The cv-qualifier on the member function. + cpp_cv cv_qualifier() const noexcept + { + return cv_; + } + + /// \returns The ref-qualifier on the member function. + cpp_reference ref_qualifier() const noexcept + { + return ref_; + } + + /// \returns Whether or not the member function is `constexpr`. + bool is_constexpr() const noexcept + { + return constexpr_; + } + + protected: + /// Builder class for member functions. + template + class basic_member_builder : public basic_builder + { + public: + /// \effects Sets the name and return type. + basic_member_builder(std::string name, std::unique_ptr return_type) + { + this->function = std::unique_ptr(new T(std::move(name), std::move(return_type))); + } + + /// \effects Sets the cv- and ref-qualifier. + void cv_ref_qualifier(cpp_cv cv, cpp_reference ref) noexcept + { + auto& base = static_cast(*this->function); + base.cv_ = cv; + base.ref_ = ref; + } + + /// \effects Sets the `virtual`-ness of the function. + void virtual_info(cpp_virtual virt) noexcept + { + static_cast(*this->function).virtual_ = virt; + } + + /// \effects Marks the function as `constexpr`. + void is_constexpr() noexcept + { + static_cast(*this->function).constexpr_ = true; + } + }; + + /// \effects Sets name and return type, as well as the rest to defaults. + cpp_member_function_base(std::string name, std::unique_ptr return_type) + : cpp_function_base(std::move(name)), + return_type_(std::move(return_type)), + virtual_(cpp_virtual_none), + cv_(cpp_cv_none), + ref_(cpp_ref_none), + constexpr_(false) + { + } + + private: + std::unique_ptr return_type_; + cpp_virtual virtual_; + cpp_cv cv_; + cpp_reference ref_; + bool constexpr_; + }; + + /// A [cppast::cpp_entity]() modelling a member function. + class cpp_member_function final : public cpp_member_function_base + { + public: + /// Builder for [cppast::cpp_member_function](). + class builder : public basic_member_builder + { + public: + using basic_member_builder::basic_member_builder; + }; + + private: + using cpp_member_function_base::cpp_member_function_base; + + cpp_entity_kind do_get_entity_kind() const noexcept override; + }; + + /// A [cppast::cpp_entity]() modelling a C++ conversion operator. + class cpp_conversion_op final : public cpp_member_function_base + { + public: + /// Builder for [cppast::cpp_conversion_op](). + class builder : public basic_member_builder + { + public: + using basic_member_builder::basic_member_builder; + + /// \effects Marks the conversion operator `explicit`. + void is_explicit() noexcept + { + function->explicit_ = true; + } + }; + + /// \returns Whether or not the conversion is `explicit`. + bool is_explicit() const noexcept + { + return explicit_; + } + + private: + cpp_conversion_op(std::string name, std::unique_ptr return_t) + : cpp_member_function_base(std::move(name), std::move(return_t)), explicit_(false) + { + } + + cpp_entity_kind do_get_entity_kind() const noexcept override; + + bool explicit_; + }; +} // namespace cppast + +#endif // CPPAST_CPP_MEMBER_FUNCTION_HPP_INCLUDED diff --git a/src/cpp_entity_kind.cpp b/src/cpp_entity_kind.cpp index b4f820f..20e44f9 100644 --- a/src/cpp_entity_kind.cpp +++ b/src/cpp_entity_kind.cpp @@ -51,6 +51,10 @@ const char* cppast::to_string(cpp_entity_kind kind) noexcept return "function parameter"; case cpp_entity_kind::function_t: return "function"; + case cpp_entity_kind::member_function_t: + return "member function"; + case cpp_entity_kind::conversion_op_t: + return "conversion operator"; case cpp_entity_kind::count: break; @@ -82,6 +86,8 @@ bool cppast::is_type(cpp_entity_kind kind) noexcept case cpp_entity_kind::bitfield_t: case cpp_entity_kind::function_parameter_t: case cpp_entity_kind::function_t: + case cpp_entity_kind::member_function_t: + case cpp_entity_kind::conversion_op_t: case cpp_entity_kind::count: break; } diff --git a/src/cpp_member_function.cpp b/src/cpp_member_function.cpp new file mode 100644 index 0000000..2f012f2 --- /dev/null +++ b/src/cpp_member_function.cpp @@ -0,0 +1,19 @@ +// 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 + +using namespace cppast; + +cpp_entity_kind cpp_member_function::do_get_entity_kind() const noexcept +{ + return cpp_entity_kind::member_function_t; +} + +cpp_entity_kind cpp_conversion_op::do_get_entity_kind() const noexcept +{ + return cpp_entity_kind::conversion_op_t; +} diff --git a/src/visitor.cpp b/src/visitor.cpp index fb0b0f5..f576eef 100644 --- a/src/visitor.cpp +++ b/src/visitor.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include using namespace cppast; @@ -50,6 +51,10 @@ bool detail::visit(const cpp_entity& e, detail::visitor_callback_t cb, void* fun return handle_container(e, cb, functor); case cpp_entity_kind::function_t: return handle_container(e, cb, functor); + case cpp_entity_kind::member_function_t: + return handle_container(e, cb, functor); + case cpp_entity_kind::conversion_op_t: + return handle_container(e, cb, functor); case cpp_entity_kind::namespace_alias_t: case cpp_entity_kind::using_directive_t: