diff --git a/include/cppast/cpp_entity_kind.hpp b/include/cppast/cpp_entity_kind.hpp index 24f4fa0..ba4bfb9 100644 --- a/include/cppast/cpp_entity_kind.hpp +++ b/include/cppast/cpp_entity_kind.hpp @@ -15,6 +15,7 @@ namespace cppast file_t, macro_definition_t, + include_directive_t, language_linkage_t, diff --git a/include/cppast/cpp_entity_ref.hpp b/include/cppast/cpp_entity_ref.hpp index c6d4e93..497c475 100644 --- a/include/cppast/cpp_entity_ref.hpp +++ b/include/cppast/cpp_entity_ref.hpp @@ -15,7 +15,6 @@ namespace cppast { public: /// \effects Creates it giving it the target id and name. - /// \requires An entity of matching kind must eventually register in the [cppast::cpp_entity_index]() using that id. basic_cpp_entity_ref(cpp_entity_id target_id, std::string target_name) : target_(std::move(target_id)), name_(std::move(target_name)) { @@ -34,6 +33,7 @@ namespace cppast } /// \returns The [cppast::cpp_entity]() it refers to. + /// \requires An entity of matching kind must be registered in the [cppast::cpp_entity_index]() using the given id. const T& get(const cpp_entity_index& idx) const noexcept { auto entity = idx.lookup(target_); diff --git a/include/cppast/cpp_file.hpp b/include/cppast/cpp_file.hpp index d40ca12..0f43cfd 100644 --- a/include/cppast/cpp_file.hpp +++ b/include/cppast/cpp_file.hpp @@ -7,6 +7,7 @@ #include #include +#include namespace cppast { @@ -52,6 +53,18 @@ namespace cppast /// \returns [cpp_entity_type::file_t](). cpp_entity_kind do_get_entity_kind() const noexcept override; }; + + /// \exclude + namespace detail + { + struct cpp_file_ref_predicate + { + bool operator()(const cpp_entity& e); + }; + } // namespace detail + + /// A reference to a [cppast::cpp_file](). + using cpp_file_ref = basic_cpp_entity_ref; } // namespace cppast #endif // CPPAST_CPP_FILE_HPP_INCLUDED diff --git a/include/cppast/cpp_preprocessor.hpp b/include/cppast/cpp_preprocessor.hpp index 5322320..eced975 100644 --- a/include/cppast/cpp_preprocessor.hpp +++ b/include/cppast/cpp_preprocessor.hpp @@ -8,6 +8,7 @@ #include #include +#include namespace cppast { @@ -59,6 +60,50 @@ namespace cppast type_safe::optional parameters_; std::string replacement_; }; + + /// The kind of [cppast::cpp_include_directive](). + enum class cpp_include_kind + { + system, //< An `#include <...>`. + local, //< An `#include "..."`. + }; + + /// A [cppast::cpp_entity]() modelling an `#include`. + class cpp_include_directive final : public cpp_entity + { + public: + /// \returns A newly built include directive. + /// \notes It is not meant to be registered in the [cppast::cpp_entity_index](), + /// as no other [cppast::cpp_entity]() can refer to it. + static std::unique_ptr build(const cpp_file_ref& target, + cpp_include_kind kind) + { + return std::unique_ptr(new cpp_include_directive(target, kind)); + } + + /// \returns A reference to the [cppast::cpp_file]() it includes. + cpp_file_ref target() const noexcept + { + return cpp_file_ref(target_, name()); + } + + /// \returns The kind of include it is. + cpp_include_kind include_kind() const noexcept + { + return kind_; + } + + private: + cpp_entity_kind do_get_entity_kind() const noexcept override; + + cpp_include_directive(const cpp_file_ref& target, cpp_include_kind kind) + : cpp_entity(target.name()), target_(target.id()), kind_(kind) + { + } + + cpp_entity_id target_; + cpp_include_kind kind_; + }; } // namespace cppast #endif // CPPAST_CPP_PREPROCESSOR_HPP_INCLUDED diff --git a/src/cpp_entity_kind.cpp b/src/cpp_entity_kind.cpp index 1bbfad8..07414f2 100644 --- a/src/cpp_entity_kind.cpp +++ b/src/cpp_entity_kind.cpp @@ -15,6 +15,8 @@ const char* cppast::to_string(cpp_entity_kind kind) noexcept case cpp_entity_kind::macro_definition_t: return "macro definition"; + case cpp_entity_kind::include_directive_t: + return "include directive"; case cpp_entity_kind::language_linkage_t: return "language linkage"; @@ -101,6 +103,7 @@ bool cppast::is_type(cpp_entity_kind kind) noexcept case cpp_entity_kind::file_t: case cpp_entity_kind::macro_definition_t: + case cpp_entity_kind::include_directive_t: case cpp_entity_kind::language_linkage_t: case cpp_entity_kind::namespace_t: case cpp_entity_kind::namespace_alias_t: @@ -148,6 +151,7 @@ bool cppast::is_template(cpp_entity_kind kind) noexcept case cpp_entity_kind::file_t: case cpp_entity_kind::macro_definition_t: + case cpp_entity_kind::include_directive_t: case cpp_entity_kind::language_linkage_t: case cpp_entity_kind::namespace_t: case cpp_entity_kind::namespace_alias_t: diff --git a/src/cpp_file.cpp b/src/cpp_file.cpp index 0181c17..511607b 100644 --- a/src/cpp_file.cpp +++ b/src/cpp_file.cpp @@ -12,3 +12,8 @@ cpp_entity_kind cpp_file::do_get_entity_kind() const noexcept { return cpp_entity_kind::file_t; } + +bool detail::cpp_file_ref_predicate::operator()(const cpp_entity& e) +{ + return e.kind() == cpp_entity_kind::file_t; +} diff --git a/src/cpp_preprocessor.cpp b/src/cpp_preprocessor.cpp index 3c353d5..8722f2e 100644 --- a/src/cpp_preprocessor.cpp +++ b/src/cpp_preprocessor.cpp @@ -12,3 +12,8 @@ cpp_entity_kind cpp_macro_definition::do_get_entity_kind() const noexcept { return cpp_entity_kind::macro_definition_t; } + +cpp_entity_kind cpp_include_directive::do_get_entity_kind() const noexcept +{ + return cpp_entity_kind::include_directive_t; +} diff --git a/src/visitor.cpp b/src/visitor.cpp index b33d543..4c9366e 100644 --- a/src/visitor.cpp +++ b/src/visitor.cpp @@ -78,6 +78,7 @@ bool detail::visit(const cpp_entity& e, detail::visitor_callback_t cb, void* fun return handle_container(e, cb, functor); case cpp_entity_kind::macro_definition_t: + case cpp_entity_kind::include_directive_t: case cpp_entity_kind::namespace_alias_t: case cpp_entity_kind::using_directive_t: case cpp_entity_kind::using_declaration_t: