Add simple command line tool to view the AST

This commit is contained in:
Jonathan Müller 2017-04-10 19:57:06 +02:00
commit 01b206d453
7 changed files with 358 additions and 60 deletions

View file

@ -11,6 +11,8 @@
#include <type_safe/reference.hpp>
#include <type_safe/flag_set.hpp>
#include <cppast/detail/assert.hpp>
namespace cppast
{
/// The C++ standard that should be used.
@ -24,6 +26,26 @@ namespace cppast
cpp_latest = cpp_standard::cpp_14,
};
/// \returns A human readable string representing the option,
/// it is e.g. `c++14` for `cpp_14`.
inline const char* to_string(cpp_standard standard) noexcept
{
switch (standard)
{
case cpp_standard::cpp_98:
return "c++98";
case cpp_standard::cpp_03:
return "c++03";
case cpp_standard::cpp_11:
return "c++11";
case cpp_standard::cpp_14:
return "c++14";
}
DEBUG_UNREACHABLE(detail::assert_handler{});
return "ups";
}
/// Other special compilation flags.
enum class compile_flag
{
@ -32,31 +54,18 @@ namespace cppast
ms_extensions, //< Enable MSVC extensions.
ms_compatibility, //< Enable MSVC compatibility.
_count, //< \exclude
_flag_set_size, //< \exclude
};
} // namespace cppast
namespace type_safe
{
/// Specialization of [ts::flag_set_traits]() to use [cppast::compile_flag]() with [ts::flag_set]().
template <>
struct flag_set_traits<cppast::compile_flag> : std::true_type
{
static constexpr std::size_t size() noexcept
{
return static_cast<std::size_t>(cppast::compile_flag::_count);
}
};
} // namespace type_safe
/// A [ts::flag_set]() of [cppast::compile_flag]().
using compile_flags = type_safe::flag_set<compile_flag>;
namespace cppast
{
/// Base class for the configuration of a [cppast::parser]().
class compile_config
{
public:
/// \effects Sets the given C++ standard and compilation flags.
void set_flags(cpp_standard standard, type_safe::flag_set<compile_flag> flags = {})
void set_flags(cpp_standard standard, compile_flags flags = {})
{
do_set_flags(standard, flags);
}
@ -105,8 +114,7 @@ namespace cppast
private:
/// \effects Sets the given C++ standard and compilation flags.
virtual void do_set_flags(cpp_standard standard,
type_safe::flag_set<compile_flag> flags) = 0;
virtual void do_set_flags(cpp_standard standard, compile_flags flags) = 0;
/// \effects Adds the given path to the set of include directories.
virtual void do_add_include_dir(std::string path) = 0;

View file

@ -40,7 +40,7 @@ namespace cppast
}
private:
void do_set_flags(cpp_standard standard, type_safe::flag_set<compile_flag> flags) override;
void do_set_flags(cpp_standard standard, compile_flags flags) override;
void do_add_include_dir(std::string path) override;

View file

@ -10,12 +10,22 @@ namespace cppast
class cpp_entity;
/// Information about the state of a visit operation.
enum class visitor_info
struct visitor_info
{
leaf_entity, //< Callback called for a leaf entity without children.
enum event_type
{
leaf_entity, //< Callback called for a leaf entity without children.
/// If callback returns `false`, visit operation will be aborted.
container_entity_enter, //< Callback called for a container entity before the children.
container_entity_exit, //< Callback called for a container entity after the children.
container_entity_enter, //< Callback called for a container entity before the children.
/// If callback returns `false`, none of the children will be visited,
/// going immediately to the exit event.
container_entity_exit, //< Callback called for a container entity after the children.
/// If callback returns `false`, visit operation will be aborted.
} event;
bool
last_child; //< True when the current entity is the last child of the visited parent entity.
/// \notes It will always be `false` for the initial entity.
};
/// \exclude
@ -30,21 +40,19 @@ namespace cppast
return func(e, info);
}
bool visit(const cpp_entity& e, visitor_callback_t cb, void* functor);
bool visit(const cpp_entity& e, visitor_callback_t cb, void* functor, bool last_child);
} // namespace detail
/// Visits a [cppast::cpp_entity]().
/// \effects If the given entity is a container, i.e. if it has child entities,
/// calls `f(e, visitor_info::container_entity_enter)`.
/// If that returns `true`, recursively calls `visit()` for all child entities,
/// followed by a call to `f(e, visitor_info::container_entity_exit)`.
/// If the given entity is not a container, calls `f(e, visitor_info::leave_entity)`.
/// If the functor returns `false` for [cppast::visitor_info]() other than `container_entity_enter`,
/// the visit operation is aborted.
/// \effects Invokes the callback for the current entity,
/// and any child entities.
/// It will pass a reference to the current entity and the [cppast::visitor_info]().
/// The return value of the callback controls the visit operation,
/// the semantic depend on the [cppast::visitor_info::event_type]().
template <typename Func>
void visit(const cpp_entity& e, Func f)
{
detail::visit(e, &detail::visitor_callback<Func>, &f);
detail::visit(e, &detail::visitor_callback<Func>, &f, false);
}
} // namespace cppast