diff --git a/include/builder/builder_base.h b/include/builder/builder_base.h index d609b64..e2809bd 100644 --- a/include/builder/builder_base.h +++ b/include/builder/builder_base.h @@ -24,12 +24,7 @@ std::vector extract_call_arguments(const arg_types &...args); template std::vector extract_call_arguments_helper(const arg_types &...args); -class builder_root { -public: - virtual ~builder_root() = default; -}; - -class builder : builder_root { +class builder { typedef builder BT; @@ -46,7 +41,7 @@ class builder : builder_root { // and set the block_expr immediately builder() = default; // Copy constructor from another builder - builder(const BT &other) : builder_root() { + builder(const BT &other) { block_expr = other.block_expr; } @@ -302,10 +297,6 @@ class builder : builder_root { push_to_sequence(block_expr); } - // This is an overload for the virtual function inside member_base - virtual block::expr::Ptr get_parent() const { - return this->block_expr; - } }; void annotate(std::string); diff --git a/include/builder/dyn_var.h b/include/builder/dyn_var.h index 4864e7f..6b043a5 100644 --- a/include/builder/dyn_var.h +++ b/include/builder/dyn_var.h @@ -396,6 +396,39 @@ class dyn_var : public dyn_var_impl, public dyn_var_parent_selector } }; +// dyn var specialization for pointer types to return the appropriate types on [], * and -> + +template +class dyn_var + : public dyn_var_impl { // No need for parent selector, pointers types aren't custom types by themselves +public: + typedef dyn_var_impl super; + using super::super; + using super::operator=; + + dyn_var() : dyn_var_impl() {} + + dyn_var(const dyn_var &t) : dyn_var_impl((builder)t) {} + + builder operator=(const dyn_var &t) { + return *this = (builder)t; + } + + // Specialization for the [] operator to return the right type + dyn_var operator[](const builder &bt) { + return (cast)this->dyn_var_impl::operator[](bt); + } + dyn_var operator*() { + return this->operator[](0); + } + // Hack for creating a member that's live across return site + dyn_var _p = as_member(this, "_p"); + dyn_var *operator->() { + _p = (cast)this->operator[](0); + return _p.addr(); + } +}; + template typename std::enable_if::value>::type create_return_stmt(const T &a) { create_return_stmt((typename T::associated_BT)a); diff --git a/include/builder/forward_declarations.h b/include/builder/forward_declarations.h index 71b02a3..ff9384a 100644 --- a/include/builder/forward_declarations.h +++ b/include/builder/forward_declarations.h @@ -13,7 +13,7 @@ class builder; struct sentinel_member; template -using is_builder_type = typename std::is_base_of; +using is_builder_type = typename std::is_same; template using if_builder = typename std::enable_if::value, T>::type; diff --git a/samples/outputs.var_names/sample46 b/samples/outputs.var_names/sample46 index f53f8b3..9138055 100644 --- a/samples/outputs.var_names/sample46 +++ b/samples/outputs.var_names/sample46 @@ -57,6 +57,37 @@ FUNC_DECL MEMBER_ACCESS_EXPR (member) VAR_EXPR VAR (g_0) + DECL_STMT + POINTER_TYPE + NAMED_TYPE (FooT) + VAR (i_5) + NO_INITIALIZATION + EXPR_STMT + ASSIGN_EXPR + MEMBER_ACCESS_EXPR (member) + SQ_BKT_EXPR + VAR_EXPR + VAR (i_5) + INT_CONST (0) + MEMBER_ACCESS_EXPR (my_member) + VAR_EXPR + VAR (l_4) + EXPR_STMT + ASSIGN_EXPR + MEMBER_ACCESS_EXPR (member) + SQ_BKT_EXPR + VAR_EXPR + VAR (i_5) + INT_CONST (0) + INT_CONST (0) + EXPR_STMT + ASSIGN_EXPR + MEMBER_ACCESS_EXPR (member) + SQ_BKT_EXPR + VAR_EXPR + VAR (i_5) + INT_CONST (3) + INT_CONST (0) struct FooT { int member; }; @@ -74,5 +105,9 @@ void my_bar (void) { f_3.second_member = g_0 + 1; CarT l_4; l_4.my_member = g_0.member; + FooT* i_5; + i_5->member = l_4.my_member; + i_5->member = 0; + (i_5[3]).member = 0; } diff --git a/samples/outputs/sample46 b/samples/outputs/sample46 index f297fac..826ce3c 100644 --- a/samples/outputs/sample46 +++ b/samples/outputs/sample46 @@ -57,6 +57,37 @@ FUNC_DECL MEMBER_ACCESS_EXPR (member) VAR_EXPR VAR (var0) + DECL_STMT + POINTER_TYPE + NAMED_TYPE (FooT) + VAR (var5) + NO_INITIALIZATION + EXPR_STMT + ASSIGN_EXPR + MEMBER_ACCESS_EXPR (member) + SQ_BKT_EXPR + VAR_EXPR + VAR (var5) + INT_CONST (0) + MEMBER_ACCESS_EXPR (my_member) + VAR_EXPR + VAR (var4) + EXPR_STMT + ASSIGN_EXPR + MEMBER_ACCESS_EXPR (member) + SQ_BKT_EXPR + VAR_EXPR + VAR (var5) + INT_CONST (0) + INT_CONST (0) + EXPR_STMT + ASSIGN_EXPR + MEMBER_ACCESS_EXPR (member) + SQ_BKT_EXPR + VAR_EXPR + VAR (var5) + INT_CONST (3) + INT_CONST (0) struct FooT { int member; }; @@ -74,5 +105,9 @@ void my_bar (void) { var3.second_member = var0 + 1; CarT var4; var4.my_member = var0.member; + FooT* var5; + var5->member = var4.my_member; + var5->member = 0; + (var5[3]).member = 0; } diff --git a/samples/sample38.cpp b/samples/sample38.cpp index 45a0f08..a8ed2f2 100644 --- a/samples/sample38.cpp +++ b/samples/sample38.cpp @@ -30,34 +30,7 @@ class dyn_var : public dyn_var_impl { dyn_var member = as_member(this, "member"); }; -// Create specialization for foo_t* so that we can overload the * operator - -template <> -class dyn_var : public dyn_var_impl { -public: - typedef dyn_var_impl super; - using super::super; - using super::operator=; - builder operator=(const dyn_var &t) { - return (*this) = (builder)t; - } - dyn_var(const dyn_var &t) : dyn_var_impl((builder)t) {} - dyn_var() : dyn_var_impl() {} - - dyn_var operator*() { - // Rely on copy elision - return (cast)this->operator[](0); - } - - // This is POC of how -> operator can - // be implemented. Requires the hack of creating a dummy - // member because -> needs to return a pointer. - dyn_var _p = as_member(this, "_p"); - dyn_var *operator->() { - _p = (cast)this->operator[](0); - return _p.addr(); - } -}; +/* Specialization for foo_t* is not required because it comes built in with dyn_var now */ } // namespace builder diff --git a/samples/sample46.cpp b/samples/sample46.cpp index 5d8aaac..dca4656 100644 --- a/samples/sample46.cpp +++ b/samples/sample46.cpp @@ -38,6 +38,11 @@ static void bar(void) { dyn_var>> l; l.my_member = g.member; + + dyn_var i; + i->member = l.my_member; + (*i).member = 0; + i[3].member = 0; } int main(int argc, char *argv[]) {