See More

// Copyright (C) 2017-2019 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_PREPROCESSOR_HPP_INCLUDED #define CPPAST_CPP_PREPROCESSOR_HPP_INCLUDED #include #include #include namespace cppast { /// A [cppast::cpp_entity]() modelling a macro parameter. class cpp_macro_parameter final : public cpp_entity { public: static cpp_entity_kind kind() noexcept; /// \returns A newly built macro parameter. /// \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(std::string name) { return std::unique_ptr(new cpp_macro_parameter(std::move(name))); } private: cpp_macro_parameter(std::string name) : cpp_entity(std::move(name)) {} cpp_entity_kind do_get_entity_kind() const noexcept override; }; /// A [cppast::cpp_entity]() modelling a macro definition. class cpp_macro_definition final : public cpp_entity { public: static cpp_entity_kind kind() noexcept; /// \returns A newly built object like macro. /// \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_object_like(std::string name, std::string replacement) { std::unique_ptr result{new cpp_macro_definition(std::move(name))}; result->replacement_ = std::move(replacement); return result; } /// Builds a function like macro. class function_like_builder { public: /// \effects Sets the name of the function like macro. function_like_builder(std::string name) : result_(new cpp_macro_definition(std::move(name))) { result_->kind_ = function_like; } /// \effects Sets the replacement text. void replacement(std::string replacement) { result_->replacement_ = std::move(replacement); } /// \effects Marks the macro as variadic. void is_variadic() { result_->kind_ = variadic_function; } /// \effects Adds a parameter. /// \group param void parameter(std::unique_ptr param) { result_->parameters_.push_back(*result_, std::move(param)); } /// \group param void parameter(std::string name) { parameter(cpp_macro_parameter::build(std::move(name))); } /// \returns The finished macro. /// \notes It is not meant to be registered in the [cppast::cpp_entity_index](), /// as no other [cppast::cpp_entity]() can refer to it. std::unique_ptr finish() { return std::move(result_); } private: std::unique_ptr result_; }; /// \returns The replacement text of the macro. const std::string& replacement() const noexcept { return replacement_; } /// \returns Whether or not it is an object like macro. bool is_object_like() const noexcept { return kind_ == object_like; } /// \returns Whether or not it is a function like macro. bool is_function_like() const noexcept { return kind_ != object_like; } /// \returns Whether or not it is a variadic macro. bool is_variadic() const noexcept { return kind_ == variadic_function; } /// \returns The parameters of the macro. /// \notes It has none if it is not a function like macro. detail::iteratable_intrusive_list parameters() const noexcept { return type_safe::ref(parameters_); } private: cpp_entity_kind do_get_entity_kind() const noexcept override; cpp_macro_definition(std::string name) : cpp_entity(std::move(name)), kind_(object_like) {} detail::intrusive_list parameters_; std::string replacement_; enum : char { object_like, function_like, variadic_function, } kind_; friend function_like_builder; }; /// 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: static cpp_entity_kind kind() noexcept; /// \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, std::string full_path) { return std::unique_ptr( new cpp_include_directive(target, kind, std::move(full_path))); } /// \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_; } /// \returns The full path of the included file. const std::string& full_path() const noexcept { return full_path_; } private: cpp_entity_kind do_get_entity_kind() const noexcept override; cpp_include_directive(const cpp_file_ref& target, cpp_include_kind kind, std::string full_path) : cpp_entity(target.name()), target_(target.id()[0u]), kind_(kind), full_path_(std::move(full_path)) { DEBUG_ASSERT(!target.is_overloaded(), detail::precondition_error_handler{}); } cpp_entity_id target_; cpp_include_kind kind_; std::string full_path_; }; } // namespace cppast #endif // CPPAST_CPP_PREPROCESSOR_HPP_INCLUDED