+ast_value::ast_value(ast_copy_type_t, const ast_value &other, const std::string &name)
+ : ast_value(ast_copy_type, static_cast<const ast_expression&>(other), name)
+{}
+
+ast_value::ast_value(ast_copy_type_t, const ast_value &other)
+ : ast_value(ast_copy_type, static_cast<const ast_expression&>(other), other.m_name)
+{}
+
+ast_value::ast_value(ast_copy_type_t, const ast_expression &other, const std::string &name)
+ : ast_expression(ast_copy_type, other)
+ , m_name(name)
+{}
+
+ast_value::ast_value(lex_ctx_t ctx, const std::string &name, qc_type t)
+ : ast_expression(ctx, TYPE_ast_value, t)
+ , m_name(name)
+{
+ m_keep_node = true; // keep values, always
+ memset(&m_constval, 0, sizeof(m_constval));
+}
+
+ast_value::~ast_value()
+{
+ if (m_argcounter)
+ mem_d((void*)m_argcounter);
+ if (m_hasvalue) {
+ switch (m_vtype)
+ {
+ case TYPE_STRING:
+ mem_d((void*)m_constval.vstring);
+ break;
+ case TYPE_FUNCTION:
+ // unlink us from the function node
+ m_constval.vfunc->m_function_type = nullptr;
+ break;
+ // NOTE: delete function? currently collected in
+ // the parser structure
+ default:
+ break;
+ }
+ }
+ if (m_ir_values)
+ mem_d(m_ir_values);
+
+ // initlist imples an array which implies .next in the expression exists.
+ if (m_initlist.size() && m_next->m_vtype == TYPE_STRING) {
+ for (auto &it : m_initlist)
+ if (it.vstring)
+ mem_d(it.vstring);
+ }
+}
+
+static size_t ast_type_to_string_impl(const ast_expression *e, char *buf, size_t bufsize, size_t pos)