Implement code generation
This commit is contained in:
parent
c44e0b512e
commit
d18070a799
29 changed files with 2522 additions and 280 deletions
421
include/cppast/code_generator.hpp
Normal file
421
include/cppast/code_generator.hpp
Normal file
|
|
@ -0,0 +1,421 @@
|
|||
// Copyright (C) 2017 Jonathan Müller <jonathanmueller.dev@gmail.com>
|
||||
// This file is subject to the license terms in the LICENSE file
|
||||
// found in the top-level directory of this distribution.
|
||||
|
||||
#ifndef CPPAST_CODE_GENERATOR_HPP_INCLUDED
|
||||
#define CPPAST_CODE_GENERATOR_HPP_INCLUDED
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <type_safe/index.hpp>
|
||||
|
||||
#include <cppast/cpp_entity.hpp>
|
||||
#include <cppast/cpp_entity_ref.hpp>
|
||||
|
||||
namespace cppast
|
||||
{
|
||||
/// A simple string view implementation, like [std::string_view]().
|
||||
///
|
||||
/// It "views" - stores a pointer to - some kind of string.
|
||||
class string_view
|
||||
{
|
||||
public:
|
||||
/// \effects Creates it viewing the [std::string]().
|
||||
string_view(const std::string& str) noexcept : str_(str.c_str()), length_(str.length())
|
||||
{
|
||||
}
|
||||
|
||||
/// \effects Creates it viewing the C string `str`.
|
||||
constexpr string_view(const char* str) noexcept : str_(str), length_(std::strlen(str))
|
||||
{
|
||||
}
|
||||
|
||||
/// \effects Creates it viewing the C string literal.
|
||||
template <std::size_t Size>
|
||||
constexpr string_view(const char (&str)[Size]) noexcept : str_(str), length_(Size - 1u)
|
||||
{
|
||||
}
|
||||
|
||||
/// \returns The number of characters.
|
||||
constexpr std::size_t length() const noexcept
|
||||
{
|
||||
return length_;
|
||||
}
|
||||
|
||||
/// \returns The C string.
|
||||
constexpr const char* c_str() const noexcept
|
||||
{
|
||||
return str_;
|
||||
}
|
||||
|
||||
/// \returns The character at the given index.
|
||||
/// \requires `i < length()`.
|
||||
char operator[](type_safe::index_t i) const noexcept
|
||||
{
|
||||
return type_safe::at(str_, i);
|
||||
}
|
||||
|
||||
private:
|
||||
const char* str_;
|
||||
std::size_t length_;
|
||||
};
|
||||
|
||||
/// \exclude
|
||||
namespace detail
|
||||
{
|
||||
template <typename Tag>
|
||||
class semantic_string_view
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
explicit semantic_string_view(T&& obj,
|
||||
decltype(string_view(std::forward<T>(obj)), 0) = 0)
|
||||
: str_(std::forward<T>(obj))
|
||||
{
|
||||
}
|
||||
|
||||
const string_view& str() const noexcept
|
||||
{
|
||||
return str_;
|
||||
}
|
||||
|
||||
private:
|
||||
string_view str_;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
/// A special [cppast::string_view]() representing a C++ keyword token.
|
||||
using keyword = detail::semantic_string_view<struct keyword_tag>;
|
||||
|
||||
/// A special [cppast::string_view]() representing a C++ identifier token.
|
||||
using identifier = detail::semantic_string_view<struct identifier_tag>;
|
||||
|
||||
/// A special [cppast::string_view]() representing a C++ string or character literal token.
|
||||
using string_literal = detail::semantic_string_view<struct str_literal_tag>;
|
||||
|
||||
/// A special [cppast::string_view]() representing a C++ integer literal token.
|
||||
using int_literal = detail::semantic_string_view<struct int_literal_tag>;
|
||||
|
||||
/// A special [cppast::string_view]() representing a C++ floating point literal token.
|
||||
using float_literal = detail::semantic_string_view<struct float_literal_tag>;
|
||||
|
||||
/// A special [cppast::string_view]() representing a C++ punctuation token like `.` or `(`.
|
||||
using punctuation = detail::semantic_string_view<struct punctuation_tag>;
|
||||
|
||||
/// A special [cppast::string_view]() representing a C++ preprocessor token.
|
||||
using preprocessor_token = detail::semantic_string_view<struct preprocessor_tag>;
|
||||
|
||||
/// A special [cppast::string_view]() representing a sequence of unknown C++ tokens.
|
||||
using token_seq = detail::semantic_string_view<struct token_seq_tag>;
|
||||
|
||||
/// Tag type to represent an end-of-line character.
|
||||
constexpr struct newl_t
|
||||
{
|
||||
constexpr newl_t() noexcept
|
||||
{
|
||||
}
|
||||
} newl;
|
||||
|
||||
/// Tag type to represent a single space character.
|
||||
constexpr struct whitespace_t
|
||||
{
|
||||
constexpr whitespace_t() noexcept
|
||||
{
|
||||
}
|
||||
} whitespace;
|
||||
|
||||
/// Base class to control the code generation.
|
||||
///
|
||||
/// Inherit from it to customize how a [cppast::cpp_entity]() is printed
|
||||
/// by [cppast::generate_code]().
|
||||
class code_generator
|
||||
{
|
||||
public:
|
||||
code_generator(const code_generator&) = delete;
|
||||
code_generator& operator=(const code_generator&) = delete;
|
||||
virtual ~code_generator() noexcept = default;
|
||||
|
||||
/// Sentinel type used to output a given entity.
|
||||
class output
|
||||
{
|
||||
public:
|
||||
/// \effects Creates it giving the generator, the entity
|
||||
/// and whether or not the entity is a container.
|
||||
/// It is a container if while this object lives
|
||||
/// any other `output` objects are created.
|
||||
///
|
||||
/// It will call `on_container_begin()` or `on_leaf()`,
|
||||
/// respectively.
|
||||
explicit output(type_safe::object_ref<code_generator> gen,
|
||||
type_safe::object_ref<const cpp_entity> e, bool is_container)
|
||||
: gen_(gen), print_(is_container ? gen_->on_container_begin(*e) : gen_->on_leaf(*e))
|
||||
{
|
||||
if (is_container)
|
||||
e_ = e;
|
||||
}
|
||||
|
||||
/// \effects If the entity is a container
|
||||
/// and `on_container_begin()` returned `true`,
|
||||
/// calls `on_container_end()`,
|
||||
/// else does nothing.
|
||||
~output() noexcept
|
||||
{
|
||||
if (print_ && e_)
|
||||
gen_->on_container_end(e_.value());
|
||||
}
|
||||
|
||||
output(const output&) = delete;
|
||||
output& operator=(const output&) = delete;
|
||||
|
||||
/// \returns Whether or not the `on_XXX` function returned `true`.
|
||||
/// \notes If this returns `false`,
|
||||
/// the other functions have no effects.
|
||||
explicit operator bool() const noexcept
|
||||
{
|
||||
return print_;
|
||||
}
|
||||
|
||||
/// \returns A reference to the generator.
|
||||
type_safe::object_ref<code_generator> generator() const noexcept
|
||||
{
|
||||
return gen_;
|
||||
}
|
||||
|
||||
/// \effects Call `do_indent()` followed by `do_write_newline()` (if `print_newline` is `true`).
|
||||
void indent(bool print_newline = true) const noexcept
|
||||
{
|
||||
if (print_)
|
||||
{
|
||||
gen_->do_indent();
|
||||
if (print_newline)
|
||||
gen_->do_write_newline();
|
||||
}
|
||||
}
|
||||
|
||||
/// \effects Calls `do_unindent()`.
|
||||
void unindent() const noexcept
|
||||
{
|
||||
if (print_)
|
||||
gen_->do_unindent();
|
||||
}
|
||||
|
||||
/// \effects Calls `do_write_keyword()`.
|
||||
const output& operator<<(const keyword& k) const
|
||||
{
|
||||
if (print_)
|
||||
gen_->do_write_keyword(k.str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \effects Calls `do_write_identifier()`.
|
||||
const output& operator<<(const identifier& ident) const
|
||||
{
|
||||
if (print_)
|
||||
gen_->do_write_identifier(ident.str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \effects Calls `do_write_reference()`.
|
||||
template <typename T, class Predicate>
|
||||
const output& operator<<(const basic_cpp_entity_ref<T, Predicate>& ref) const
|
||||
{
|
||||
if (print_)
|
||||
gen_->do_write_reference(ref.id(), ref.name());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \effects Calls `do_write_punctuation()`.
|
||||
const output& operator<<(const punctuation& punct) const
|
||||
{
|
||||
if (print_)
|
||||
gen_->do_write_punctuation(punct.str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \effects Calls `do_write_str_literal`.
|
||||
const output& operator<<(const string_literal& lit) const
|
||||
{
|
||||
if (print_)
|
||||
gen_->do_write_str_literal(lit.str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \effects Calls `do_write_int_literal()`.
|
||||
const output& operator<<(const int_literal& lit) const
|
||||
{
|
||||
if (print_)
|
||||
gen_->do_write_int_literal(lit.str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \effects Calls `do_write_float_literal()`.
|
||||
const output& operator<<(const float_literal& lit) const
|
||||
{
|
||||
if (print_)
|
||||
gen_->do_write_float_literal(lit.str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \effects Calls `do_write_preprocessor()`.
|
||||
const output& operator<<(const preprocessor_token& tok) const
|
||||
{
|
||||
if (print_)
|
||||
gen_->do_write_preprocessor(tok.str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \effects Calls `do_write_token_seq()`.
|
||||
const output& operator<<(const token_seq& seq) const
|
||||
{
|
||||
if (print_)
|
||||
gen_->do_write_token_seq(seq.str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \effects Calls `do_write_newline()`.
|
||||
const output& operator<<(newl_t) const
|
||||
{
|
||||
if (print_)
|
||||
gen_->do_write_newline();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \effects Calls `do_write_whitespace()`.
|
||||
const output& operator<<(whitespace_t) const
|
||||
{
|
||||
if (print_)
|
||||
gen_->do_write_whitespace();
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
type_safe::object_ref<code_generator> gen_;
|
||||
type_safe::optional_ref<const cpp_entity> e_;
|
||||
bool print_;
|
||||
};
|
||||
|
||||
protected:
|
||||
code_generator() noexcept = default;
|
||||
|
||||
private:
|
||||
/// \effects Will be invoked before code of a container entity is generated.
|
||||
/// The base class version has no effect.
|
||||
/// \returns Whether or not that entity should actually be generated.
|
||||
/// The base class version returns `true`.
|
||||
virtual bool on_container_begin(const cpp_entity& e)
|
||||
{
|
||||
(void)e;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \effects Will be invoked after all code of a container entity has been generated.
|
||||
/// The base class version has no effect.
|
||||
virtual void on_container_end(const cpp_entity& e)
|
||||
{
|
||||
(void)e;
|
||||
}
|
||||
|
||||
/// \effects Will be invoked before code of a non-container entity is generated.
|
||||
/// The base class version has no effect.
|
||||
/// \returns Whether or not that entity should actually be generated.
|
||||
/// The base class version returns `true`.
|
||||
virtual bool on_leaf(const cpp_entity& e)
|
||||
{
|
||||
(void)e;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \effects Will be invoked when the indentation level should be increased by one.
|
||||
/// The level change must be applied on the next call to `do_write_newline()`.
|
||||
virtual void do_indent() = 0;
|
||||
|
||||
/// \effects Will be invoked when the indentation level should be decreased by one.
|
||||
/// The level change must be applied immediately if nothing else has been written on the current line.
|
||||
virtual void do_unindent() = 0;
|
||||
|
||||
/// \effects Writes the given token sequence.
|
||||
virtual void do_write_token_seq(string_view tokens) = 0;
|
||||
|
||||
/// \effects Writes the specified special token.
|
||||
/// The base class version simply forwards to `do_write_token_seq()`.
|
||||
/// \notes This is useful for syntax highlighting, for example.
|
||||
/// \group write
|
||||
virtual void do_write_keyword(string_view keyword)
|
||||
{
|
||||
do_write_token_seq(keyword);
|
||||
}
|
||||
/// \group write
|
||||
virtual void do_write_identifier(string_view identifier)
|
||||
{
|
||||
do_write_token_seq(identifier);
|
||||
}
|
||||
/// \group write
|
||||
virtual void do_write_reference(type_safe::array_ref<const cpp_entity_id> id,
|
||||
string_view name)
|
||||
{
|
||||
(void)id;
|
||||
do_write_token_seq(name);
|
||||
}
|
||||
/// \group write
|
||||
virtual void do_write_punctuation(string_view punct)
|
||||
{
|
||||
do_write_token_seq(punct);
|
||||
}
|
||||
/// \group write
|
||||
virtual void do_write_str_literal(string_view str)
|
||||
{
|
||||
do_write_token_seq(str);
|
||||
}
|
||||
/// \group write
|
||||
virtual void do_write_int_literal(string_view str)
|
||||
{
|
||||
do_write_token_seq(str);
|
||||
}
|
||||
/// \group write
|
||||
virtual void do_write_float_literal(string_view str)
|
||||
{
|
||||
do_write_token_seq(str);
|
||||
}
|
||||
/// \group write
|
||||
virtual void do_write_preprocessor(string_view punct)
|
||||
{
|
||||
do_write_token_seq(punct);
|
||||
}
|
||||
|
||||
/// \effects Writes a newline.
|
||||
/// It is guaranteed that this is the only way a newline will be printed.
|
||||
/// The base class forwards to `do_write_token_seq()`.
|
||||
virtual void do_write_newline()
|
||||
{
|
||||
do_write_token_seq("\n");
|
||||
}
|
||||
/// \effects Writes a whitespace character.
|
||||
/// It will be invoked only where a whitespace is truly needed,
|
||||
/// like between two keywords.
|
||||
/// The base class forwards to `do_write_token_seq()`.
|
||||
virtual void do_write_whitespace()
|
||||
{
|
||||
do_write_token_seq(" ");
|
||||
}
|
||||
};
|
||||
|
||||
/// Generates code for the given entity.
|
||||
///
|
||||
/// How the code is generated is customized by the generator.
|
||||
/// The implementation will write whitespace only where necessary,
|
||||
/// but a newline after each entity.
|
||||
/// This allows customization of formatting.
|
||||
void generate_code(code_generator& generator, const cpp_entity& e);
|
||||
|
||||
/// \exclude
|
||||
class cpp_template_argument;
|
||||
|
||||
/// \exclude
|
||||
namespace detail
|
||||
{
|
||||
void write_template_arguments(code_generator::output& output,
|
||||
type_safe::array_ref<const cpp_template_argument> arguments);
|
||||
} // namespace detail
|
||||
} // namespace cppast
|
||||
|
||||
#endif // CPPAST_CODE_GENERATOR_HPP_INCLUDED
|
||||
|
|
@ -44,7 +44,7 @@ namespace cppast
|
|||
|
||||
cpp_type_kind do_get_kind() const noexcept override
|
||||
{
|
||||
return cpp_type_kind::array;
|
||||
return cpp_type_kind::array_t;
|
||||
}
|
||||
|
||||
std::unique_ptr<cpp_type> type_;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ namespace cppast
|
|||
|
||||
cpp_type_kind do_get_kind() const noexcept override
|
||||
{
|
||||
return cpp_type_kind::decltype_;
|
||||
return cpp_type_kind::decltype_t;
|
||||
}
|
||||
|
||||
std::unique_ptr<cpp_expression> expr_;
|
||||
|
|
@ -54,7 +54,7 @@ namespace cppast
|
|||
|
||||
cpp_type_kind do_get_kind() const noexcept override
|
||||
{
|
||||
return cpp_type_kind::decltype_auto;
|
||||
return cpp_type_kind::decltype_auto_t;
|
||||
}
|
||||
};
|
||||
} // namespace cppast
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ namespace cppast
|
|||
/// The kind of a [cppast::cpp_expression]().
|
||||
enum class cpp_expression_kind
|
||||
{
|
||||
literal,
|
||||
literal_t,
|
||||
|
||||
unexposed,
|
||||
unexposed_t,
|
||||
};
|
||||
|
||||
/// Base class for all C++ expressions.
|
||||
|
|
@ -83,7 +83,7 @@ namespace cppast
|
|||
|
||||
cpp_expression_kind do_get_kind() const noexcept override
|
||||
{
|
||||
return cpp_expression_kind::unexposed;
|
||||
return cpp_expression_kind::unexposed_t;
|
||||
}
|
||||
|
||||
std::string str_;
|
||||
|
|
@ -115,11 +115,17 @@ namespace cppast
|
|||
|
||||
cpp_expression_kind do_get_kind() const noexcept override
|
||||
{
|
||||
return cpp_expression_kind::literal;
|
||||
return cpp_expression_kind::literal_t;
|
||||
}
|
||||
|
||||
std::string value_;
|
||||
};
|
||||
|
||||
/// \exclude
|
||||
namespace detail
|
||||
{
|
||||
void write_expression(code_generator::output& output, const cpp_expression& expr);
|
||||
} // namespace detail
|
||||
} // namespace cppast
|
||||
|
||||
#endif // CPPAST_CPP_EXPRESSION_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ namespace cppast
|
|||
|
||||
cpp_type_kind do_get_kind() const noexcept override
|
||||
{
|
||||
return cpp_type_kind::function;
|
||||
return cpp_type_kind::function_t;
|
||||
}
|
||||
|
||||
std::unique_ptr<cpp_type> return_type_;
|
||||
|
|
@ -154,7 +154,7 @@ namespace cppast
|
|||
|
||||
cpp_type_kind do_get_kind() const noexcept override
|
||||
{
|
||||
return cpp_type_kind::member_function;
|
||||
return cpp_type_kind::member_function_t;
|
||||
}
|
||||
|
||||
std::unique_ptr<cpp_type> class_type_, return_type_;
|
||||
|
|
@ -197,7 +197,7 @@ namespace cppast
|
|||
|
||||
cpp_type_kind do_get_kind() const noexcept override
|
||||
{
|
||||
return cpp_type_kind::member_object;
|
||||
return cpp_type_kind::member_object_t;
|
||||
}
|
||||
|
||||
std::unique_ptr<cpp_type> class_type_, object_type_;
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ namespace cppast
|
|||
|
||||
cpp_type_kind do_get_kind() const noexcept override
|
||||
{
|
||||
return cpp_type_kind::template_instantiation;
|
||||
return cpp_type_kind::template_instantiation_t;
|
||||
}
|
||||
|
||||
type_safe::variant<std::vector<cpp_template_argument>, std::string> arguments_;
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ namespace cppast
|
|||
|
||||
cpp_type_kind do_get_kind() const noexcept override
|
||||
{
|
||||
return cpp_type_kind::template_parameter;
|
||||
return cpp_type_kind::template_parameter_t;
|
||||
}
|
||||
|
||||
cpp_template_type_parameter_ref parameter_;
|
||||
|
|
|
|||
|
|
@ -9,34 +9,35 @@
|
|||
|
||||
#include <cppast/detail/intrusive_list.hpp>
|
||||
#include <cppast/cpp_entity_ref.hpp>
|
||||
#include <cppast/code_generator.hpp>
|
||||
|
||||
namespace cppast
|
||||
{
|
||||
/// The kinds of a [cppast::cpp_type]().
|
||||
enum class cpp_type_kind
|
||||
{
|
||||
builtin,
|
||||
user_defined,
|
||||
builtin_t,
|
||||
user_defined_t,
|
||||
|
||||
auto_,
|
||||
decltype_,
|
||||
decltype_auto,
|
||||
auto_t,
|
||||
decltype_t,
|
||||
decltype_auto_t,
|
||||
|
||||
cv_qualified,
|
||||
pointer,
|
||||
reference,
|
||||
cv_qualified_t,
|
||||
pointer_t,
|
||||
reference_t,
|
||||
|
||||
array,
|
||||
function,
|
||||
member_function,
|
||||
member_object,
|
||||
array_t,
|
||||
function_t,
|
||||
member_function_t,
|
||||
member_object_t,
|
||||
|
||||
template_parameter,
|
||||
template_instantiation,
|
||||
template_parameter_t,
|
||||
template_instantiation_t,
|
||||
|
||||
dependent,
|
||||
dependent_t,
|
||||
|
||||
unexposed,
|
||||
unexposed_t,
|
||||
};
|
||||
|
||||
/// Base class for all C++ types.
|
||||
|
|
@ -95,7 +96,7 @@ namespace cppast
|
|||
|
||||
cpp_type_kind do_get_kind() const noexcept override
|
||||
{
|
||||
return cpp_type_kind::unexposed;
|
||||
return cpp_type_kind::unexposed_t;
|
||||
}
|
||||
|
||||
std::string name_;
|
||||
|
|
@ -163,7 +164,7 @@ namespace cppast
|
|||
|
||||
cpp_type_kind do_get_kind() const noexcept override
|
||||
{
|
||||
return cpp_type_kind::builtin;
|
||||
return cpp_type_kind::builtin_t;
|
||||
}
|
||||
|
||||
cpp_builtin_type_kind kind_;
|
||||
|
|
@ -207,7 +208,7 @@ namespace cppast
|
|||
|
||||
cpp_type_kind do_get_kind() const noexcept override
|
||||
{
|
||||
return cpp_type_kind::user_defined;
|
||||
return cpp_type_kind::user_defined_t;
|
||||
}
|
||||
|
||||
cpp_type_ref entity_;
|
||||
|
|
@ -228,7 +229,7 @@ namespace cppast
|
|||
|
||||
cpp_type_kind do_get_kind() const noexcept override
|
||||
{
|
||||
return cpp_type_kind::auto_;
|
||||
return cpp_type_kind::auto_t;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -269,7 +270,7 @@ namespace cppast
|
|||
|
||||
cpp_type_kind do_get_kind() const noexcept override
|
||||
{
|
||||
return cpp_type_kind::dependent;
|
||||
return cpp_type_kind::dependent_t;
|
||||
}
|
||||
|
||||
std::string name_;
|
||||
|
|
@ -331,7 +332,7 @@ namespace cppast
|
|||
|
||||
cpp_type_kind do_get_kind() const noexcept override
|
||||
{
|
||||
return cpp_type_kind::cv_qualified;
|
||||
return cpp_type_kind::cv_qualified_t;
|
||||
}
|
||||
|
||||
std::unique_ptr<cpp_type> type_;
|
||||
|
|
@ -361,7 +362,7 @@ namespace cppast
|
|||
|
||||
cpp_type_kind do_get_kind() const noexcept override
|
||||
{
|
||||
return cpp_type_kind::pointer;
|
||||
return cpp_type_kind::pointer_t;
|
||||
}
|
||||
|
||||
std::unique_ptr<cpp_type> pointee_;
|
||||
|
|
@ -409,12 +410,31 @@ namespace cppast
|
|||
|
||||
cpp_type_kind do_get_kind() const noexcept override
|
||||
{
|
||||
return cpp_type_kind::reference;
|
||||
return cpp_type_kind::reference_t;
|
||||
}
|
||||
|
||||
std::unique_ptr<cpp_type> referee_;
|
||||
cpp_reference ref_;
|
||||
};
|
||||
|
||||
/// \exclude
|
||||
namespace detail
|
||||
{
|
||||
// whether or not it requires special treatment when printing it
|
||||
// i.e. function pointer types are complex as the identifier has to be put inside
|
||||
bool is_complex_type(const cpp_type& type) noexcept;
|
||||
|
||||
// write part of the type that comes before the variable name
|
||||
void write_type_prefix(code_generator::output& output, const cpp_type& type);
|
||||
|
||||
// write part of the type that comes after the name
|
||||
// for non-complex types, this does nothing
|
||||
void write_type_suffix(code_generator::output& output, const cpp_type& type);
|
||||
|
||||
// write prefix, variadic, name, suffix
|
||||
void write_type(code_generator::output& output, const cpp_type& type, std::string name,
|
||||
bool is_variadic = false);
|
||||
} // namespace detail
|
||||
} // namespace cppast
|
||||
|
||||
#endif // CPPAST_CPP_TYPE_HPP_INCLUDED
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue