diff --git a/include/builder/block_type_extractor.h b/include/builder/block_type_extractor.h index 15a9d8a..212018d 100644 --- a/include/builder/block_type_extractor.h +++ b/include/builder/block_type_extractor.h @@ -8,6 +8,50 @@ namespace builder { struct custom_type_base; + + +template +struct check_valid_type { + typedef void type; +}; + +extern int type_naming_counter; + +template +struct type_namer { + static std::string obtained_name; + static std::string get_type_name() { + if (obtained_name == "") { + obtained_name = "custom_struct" + std::to_string(type_naming_counter++); + } + return obtained_name; + } +}; +template +std::string type_namer::obtained_name = ""; + +template +struct type_namer::type> { + static std::string get_type_name() { + return T::type_name; + } +}; + +template +struct type_template { + static std::vector get_templates() { + return {}; + } +}; + +template +struct type_template::type> { + static std::vector get_templates() { + return T::get_template_arg_types(); + } +}; + + // The main definition of the type extractor classes template class type_extractor { @@ -15,11 +59,11 @@ class type_extractor { // This implementation is currenty only used // by custom types which are derived from custom_type_base static block::type::Ptr extract_type(void) { - static_assert(std::is_base_of::value, - "Custom types should inherit from builder::custom_type_base"); + //static_assert(std::is_base_of::value, + //"Custom types should inherit from builder::custom_type_base"); block::named_type::Ptr type = std::make_shared(); - type->type_name = T::type_name; - type->template_args = T::get_template_arg_types(); + type->type_name = type_namer::get_type_name(); + type->template_args = type_template::get_templates(); return type; } }; diff --git a/include/builder/dyn_var.h b/include/builder/dyn_var.h index 9cf35ac..0c64872 100644 --- a/include/builder/dyn_var.h +++ b/include/builder/dyn_var.h @@ -35,6 +35,8 @@ class var { // Feature to gather members of this type std::vector members; + // Counter for naming unnamed members + int member_counter = 0; static block::type::Ptr create_block_type(void) { // Cannot create block type for abstract class @@ -146,6 +148,22 @@ class dyn_var_impl : public var { } dyn_var_impl() { + // implementation for auto member detection + if (parents_stack && parents_stack->size() != 0) { + current_state = member_var; + parent_var = parents_stack->back(); + var_name = "mem" + std::to_string(parent_var->member_counter++); + block_var = nullptr; + block_decl_stmt = nullptr; + + if (options::track_members) { + parent_var->members.push_back(this); + block_var = std::make_shared(); + block_var->var_type = create_block_type(); + block_var->var_name = var_name; + } + return; + } create_dyn_var(false); } // Basic and other constructors @@ -165,6 +183,21 @@ class dyn_var_impl : public var { *ptr_to_leak = block_var; } dyn_var_impl(const with_name &v) { + if (parents_stack && parents_stack->size() != 0) { + current_state = member_var; + parent_var = parents_stack->back(); + var_name = v.name; + block_var = nullptr; + block_decl_stmt = nullptr; + + if (options::track_members) { + parent_var->members.push_back(this); + block_var = std::make_shared(); + block_var->var_type = create_block_type(); + block_var->var_name = var_name; + } + return; + } // with_name constructors don't usually get declarations create_dyn_var(!v.with_decl); block_var->var_name = v.name; @@ -174,6 +207,8 @@ class dyn_var_impl : public var { dyn_var_impl(const defer_init &) { // Do nothing here + // Defer init "automatically" supports custom types + // because well, we don't create declarations anyway } // The function to actually initialize a dyn_var, if it // has been deferred. It is OKAY to call this even if defer_init @@ -302,7 +337,11 @@ struct member_initializer_end { }; template -struct dyn_var_parent_selector::value>::type> +struct dyn_var_parent_selector::value && !std::is_base_of::value + && !std::is_base_of::value + >::type> : public member_initializer_begin, public T, public member_initializer_end {}; // Actual dyn_var implementation diff --git a/samples/outputs.var_names/sample56 b/samples/outputs.var_names/sample56 new file mode 100644 index 0000000..4844794 --- /dev/null +++ b/samples/outputs.var_names/sample56 @@ -0,0 +1,57 @@ +FUNC_DECL + SCALAR_TYPE (VOID) + STMT_BLOCK + DECL_STMT + NAMED_TYPE (my_type) + VAR (a_0) + NO_INITIALIZATION + DECL_STMT + NAMED_TYPE (custom_struct0) + VAR (b_1) + NO_INITIALIZATION + EXPR_STMT + ASSIGN_EXPR + MEMBER_ACCESS_EXPR (nested) + VAR_EXPR + VAR (a_0) + VAR_EXPR + VAR (b_1) + EXPR_STMT + ASSIGN_EXPR + MEMBER_ACCESS_EXPR (mem0) + MEMBER_ACCESS_EXPR (nested) + VAR_EXPR + VAR (a_0) + MEMBER_ACCESS_EXPR (mem0) + VAR_EXPR + VAR (a_0) + EXPR_STMT + MINUS_EXPR + ASSIGN_EXPR + MEMBER_ACCESS_EXPR (mem1) + MEMBER_ACCESS_EXPR (nested) + VAR_EXPR + VAR (a_0) + PLUS_EXPR + MEMBER_ACCESS_EXPR (mem1) + MEMBER_ACCESS_EXPR (nested) + VAR_EXPR + VAR (a_0) + INT_CONST (1) + INT_CONST (1) +struct custom_struct0 { + int mem0; + float mem1; +}; +struct my_type { + custom_struct0 nested; + int mem0; +}; +void bar (void) { + my_type a_0; + custom_struct0 b_1; + a_0.nested = b_1; + (a_0.nested).mem0 = a_0.mem0; + ((a_0.nested).mem1 = (a_0.nested).mem1 + 1) - 1; +} + diff --git a/samples/outputs/sample56 b/samples/outputs/sample56 new file mode 100644 index 0000000..b10f3aa --- /dev/null +++ b/samples/outputs/sample56 @@ -0,0 +1,57 @@ +FUNC_DECL + SCALAR_TYPE (VOID) + STMT_BLOCK + DECL_STMT + NAMED_TYPE (my_type) + VAR (var0) + NO_INITIALIZATION + DECL_STMT + NAMED_TYPE (custom_struct0) + VAR (var1) + NO_INITIALIZATION + EXPR_STMT + ASSIGN_EXPR + MEMBER_ACCESS_EXPR (nested) + VAR_EXPR + VAR (var0) + VAR_EXPR + VAR (var1) + EXPR_STMT + ASSIGN_EXPR + MEMBER_ACCESS_EXPR (mem0) + MEMBER_ACCESS_EXPR (nested) + VAR_EXPR + VAR (var0) + MEMBER_ACCESS_EXPR (mem0) + VAR_EXPR + VAR (var0) + EXPR_STMT + MINUS_EXPR + ASSIGN_EXPR + MEMBER_ACCESS_EXPR (mem1) + MEMBER_ACCESS_EXPR (nested) + VAR_EXPR + VAR (var0) + PLUS_EXPR + MEMBER_ACCESS_EXPR (mem1) + MEMBER_ACCESS_EXPR (nested) + VAR_EXPR + VAR (var0) + INT_CONST (1) + INT_CONST (1) +struct custom_struct0 { + int mem0; + float mem1; +}; +struct my_type { + custom_struct0 nested; + int mem0; +}; +void bar (void) { + my_type var0; + custom_struct0 var1; + var0.nested = var1; + (var0.nested).mem0 = var0.mem0; + ((var0.nested).mem1 = (var0.nested).mem1 + 1) - 1; +} + diff --git a/samples/sample56.cpp b/samples/sample56.cpp new file mode 100644 index 0000000..9ca4fe5 --- /dev/null +++ b/samples/sample56.cpp @@ -0,0 +1,44 @@ +#include "blocks/c_code_generator.h" +#include "builder/builder.h" +#include "builder/builder_context.h" +#include "builder/dyn_var.h" +#include "builder/static_var.h" +#include + +using builder::as_member; +using builder::dyn_var; +using builder::static_var; + + +struct struct_type { + dyn_var x; + dyn_var y; +}; + +struct my_type { + static constexpr const char* type_name = "my_type"; + dyn_var nested = builder::with_name("nested"); + dyn_var another; +}; + +static void bar(void) { + dyn_var a; + dyn_var b; + + a.nested = b; + a.nested.x = a.another; + + a.nested.y++; +} + +int main(int argc, char *argv[]) { + + builder::builder_context context; + auto ast = context.extract_function_ast(bar, "bar"); + ast->dump(std::cout, 0); + + block::c_code_generator::generate_struct_decl>(std::cout); + block::c_code_generator::generate_struct_decl>(std::cout); + block::c_code_generator::generate_code(ast, std::cout, 0); + return 0; +} diff --git a/src/builder/block_type_extractor.cpp b/src/builder/block_type_extractor.cpp new file mode 100644 index 0000000..2d14da6 --- /dev/null +++ b/src/builder/block_type_extractor.cpp @@ -0,0 +1,5 @@ +#include "builder/block_type_extractor.h" + +namespace builder { +int type_naming_counter = 0; +}