From 5dd99a45adac4b9a583e14dd468dd13b156e2c7e Mon Sep 17 00:00:00 2001 From: Ajay Brahmakshatriya Date: Fri, 8 Dec 2023 11:05:56 -0500 Subject: [PATCH] Added support for defer init for dyn_var --- include/builder/dyn_var.h | 20 +++++++++++++++++ samples/outputs.var_names/sample53 | 10 +++++++++ samples/outputs/sample53 | 10 +++++++++ samples/sample53.cpp | 36 ++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+) create mode 100644 samples/outputs.var_names/sample53 create mode 100644 samples/outputs/sample53 create mode 100644 samples/sample53.cpp diff --git a/include/builder/dyn_var.h b/include/builder/dyn_var.h index 1d5702f..a09c30e 100644 --- a/include/builder/dyn_var.h +++ b/include/builder/dyn_var.h @@ -90,6 +90,13 @@ struct with_name { with_name(const std::string &n, bool wd = false) : name(n), with_decl(wd) {} }; +// constructor helper to defer the initialization of dyn_var +// This allows declaring dyn_var outside the context, but initialize +// them later +struct defer_init { + // No members +}; + template class dyn_var_impl : public var { public: @@ -226,6 +233,19 @@ class dyn_var_impl : public var { block_var->preferred_name = ""; var_name = v.name; } + + dyn_var_impl(const defer_init&) { + // Do nothing here + } + // The function to actually initialize a dyn_var, if it + // has been deferred. It is OKAY to call this even if defer_init + // is not used, but is not adviced. This can definitely be called multiple + // times and will produce the same dyn_var based on the static tag at the + // time of this call + // Currently we don't support init val, but can be added if needed + void deferred_init(void) { + create_dyn_var(false); + } dyn_var_impl(const dyn_var_sentinel_type &a, std::string name = "") { create_dyn_var(true); if (name != "") { diff --git a/samples/outputs.var_names/sample53 b/samples/outputs.var_names/sample53 new file mode 100644 index 0000000..b049c23 --- /dev/null +++ b/samples/outputs.var_names/sample53 @@ -0,0 +1,10 @@ +void foo (void) { + int obj_0; + int x_1 = 0; + if (x_1) { + obj_0 = 1; + } else { + obj_0 = 2; + } +} + diff --git a/samples/outputs/sample53 b/samples/outputs/sample53 new file mode 100644 index 0000000..0988e23 --- /dev/null +++ b/samples/outputs/sample53 @@ -0,0 +1,10 @@ +void foo (void) { + int var0; + int var1 = 0; + if (var1) { + var0 = 1; + } else { + var0 = 2; + } +} + diff --git a/samples/sample53.cpp b/samples/sample53.cpp new file mode 100644 index 0000000..6bb8e3c --- /dev/null +++ b/samples/sample53.cpp @@ -0,0 +1,36 @@ +// Include the headers +#include "blocks/c_code_generator.h" +#include "builder/dyn_var.h" +#include "builder/lib/utils.h" +#include "builder/static_var.h" +#include + +// Include the BuildIt types +using builder::dyn_var; +using builder::static_var; + + +struct external_object_t { + dyn_var member = builder::defer_init(); +}; + +static void foo(external_object_t &obj) { + // Init not + obj.member.deferred_init(); + + dyn_var x = 0; + if (x) { + obj.member = 1; + } else { + obj.member = 2; + } +} + +int main(int argc, char *argv[]) { + + external_object_t obj; + + builder::builder_context context; + block::c_code_generator::generate_code(context.extract_function_ast(foo, "foo", obj), std::cout, 0); + return 0; +}