From 8cdb3184f8a1f3e5396d953b238ce2e217f0cb1c Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Tue, 5 Dec 2017 10:47:09 +0900 Subject: [PATCH] cxx: Fix compilation after merge This resolves a few issues and brings back the experimental features. Also, disable some of the ugliest experiments: - manual function overrides, - define APIs only in eo_cxx namespace Some APIs are generated behind EFL_CXXPERIMENT (eg. event_name_cb_add or some weak pointer stuff). I believe they are useful but would like to make sure there are no serious drawbacks with generating those. --- src/bin/eolian_cxx/eolian_cxx.cc | 52 ++----------------- src/examples/elementary/popup_cxx_example.cc | 3 +- .../eolian_cxx/grammar/class_definition.hpp | 37 +++++++------ src/lib/eolian_cxx/grammar/context.hpp | 2 +- .../grammar/function_declaration.hpp | 4 ++ .../grammar/function_definition.hpp | 4 ++ src/lib/eolian_cxx/grammar/generator.hpp | 1 + src/lib/eolian_cxx/grammar/klass_def.hpp | 8 ++- src/lib/eolian_cxx/grammar/parameter.hpp | 10 +++- .../eolian_cxx/grammar/part_declaration.hpp | 3 +- .../grammar/part_implementation.hpp | 3 +- .../grammar/type_function_declaration.hpp | 5 +- 12 files changed, 54 insertions(+), 78 deletions(-) diff --git a/src/bin/eolian_cxx/eolian_cxx.cc b/src/bin/eolian_cxx/eolian_cxx.cc index 3720aa9251..134700ae6c 100644 --- a/src/bin/eolian_cxx/eolian_cxx.cc +++ b/src/bin/eolian_cxx/eolian_cxx.cc @@ -241,55 +241,9 @@ types_generate(std::string const& fname, options_type const& opts, const Eolian_Function *func = eolian_typedecl_function_pointer_get(tp); if (!func) return false; - Eina_Iterator *param_itr = eolian_function_parameters_get(func); - std::vector params; - - /* const */ Eolian_Function_Parameter *param; - while (::eina_iterator_next(param_itr, reinterpret_cast(¶m))) - { - parameter_direction param_dir; - switch (eolian_parameter_direction_get(param)) - { - /* Note: Inverted on purpose, as the direction objects are - * passed is inverted (from C to C++ for function pointers). - * FIXME: This is probably not right in all cases. */ - case EOLIAN_IN_PARAM: param_dir = parameter_direction::out; break; - case EOLIAN_INOUT_PARAM: param_dir = parameter_direction::inout; break; - case EOLIAN_OUT_PARAM: param_dir = parameter_direction::in; break; - default: return false; - } - - const Eolian_Type *param_type_eolian = eolian_parameter_type_get(param); - type_def param_type(param_type_eolian, opts.unit, EOLIAN_C_TYPE_PARAM); - std::string param_name = eolian_parameter_name_get(param); - std::string param_c_type = eolian_type_c_type_get(param_type_eolian, EOLIAN_C_TYPE_PARAM); - parameter_def param_def(param_dir, param_type, param_name, param_c_type); - params.push_back(std::move(param_def)); - } - ::eina_iterator_free(param_itr); - - const Eolian_Type *ret_type_eolian = eolian_function_return_type_get(func, EOLIAN_FUNCTION_POINTER); - - type_def ret_type = void_; - if (ret_type_eolian) - ret_type = type_def(ret_type_eolian, opts.unit, EOLIAN_C_TYPE_RETURN); - - /* - // List namespaces. Not used as function_wrapper lives in efl::eolian. - std::vector namespaces; - Eina_Iterator *ns_itr = eolian_typedecl_namespaces_get(tp); - char *ns; - while (::eina_iterator_next(ns_itr, reinterpret_cast(&ns))) - namespaces.push_back(std::string(ns)); - ::eina_iterator_free(ns_itr); - */ - - std::string name = eolian_function_name_get(func); - std::string c_name = eolian_typedecl_full_name_get(tp); - std::replace(c_name.begin(), c_name.end(), '.', '_'); - bool beta = eolian_function_is_beta(func); - - function_def def(ret_type, name, params, c_name, beta, false, true); + function_def def(func, EOLIAN_FUNCTION_POINTER, opts.unit); + def.c_name = eolian_typedecl_full_name_get(tp); + std::replace(def.c_name.begin(), def.c_name.end(), '.', '_'); functions.push_back(std::move(def)); } ::eina_iterator_free(itr); diff --git a/src/examples/elementary/popup_cxx_example.cc b/src/examples/elementary/popup_cxx_example.cc index 8a06a81ac0..7c6d85ce7a 100644 --- a/src/examples/elementary/popup_cxx_example.cc +++ b/src/examples/elementary/popup_cxx_example.cc @@ -1,6 +1,7 @@ // g++ -g `pkg-config --cflags --libs elementary-cxx efl-cxx eina-cxx eo-cxx ecore-cxx evas-cxx edje-cxx` popup_cxx_example.cc -o popup_cxx_example -#define EFL_CXX_WREF_EASY +#define EFL_CXXPERIMENTAL + #include #include #include diff --git a/src/lib/eolian_cxx/grammar/class_definition.hpp b/src/lib/eolian_cxx/grammar/class_definition.hpp index 771121d8ee..b282f71bf9 100644 --- a/src/lib/eolian_cxx/grammar/class_definition.hpp +++ b/src/lib/eolian_cxx/grammar/class_definition.hpp @@ -208,26 +208,17 @@ struct class_definition_generator if(!as_generator(scope_tab << "/// @endcond\n").generate(sink, attributes::unused, context)) return false; // EXPERIMENTAL: Parts - if(!as_generator("#ifdef EFL_CXXPERIMENTAL\n").generate(sink, attributes::unused, context)) return false; - if(!as_generator(*(scope_tab << part_declaration << ";\n")) - .generate(sink, cls.parts, context)) return false; - if(!as_generator("#endif \n").generate(sink, attributes::unused, context)) return false; + if (!cls.parts.empty()) + { + if(!as_generator("#ifdef EFL_CXXPERIMENTAL\n").generate(sink, attributes::unused, context)) return false; + if(!as_generator(*(scope_tab << part_declaration << ";\n")) + .generate(sink, cls.parts, context)) return false; + if(!as_generator("#endif \n").generate(sink, attributes::unused, context)) return false; + } if(!as_generator( scope_tab << "::efl::eo::wref<" << string << "> _get_wref() const { " "return ::efl::eo::wref<" << string << ">(*this); }\n" - ).generate(sink, std::make_tuple(cls.cxx_name, cls.cxx_name), context)) return false; - - // EXPERIMENTAL: wref and implicit conversion to Eo* - if(!as_generator("#ifdef EFL_CXXPERIMENTAL\n").generate(sink, attributes::unused, context)) return false; - // For easy wref, operator-> in wref needs to also return a pointer type - if(!as_generator( scope_tab << "const " << string << "* operator->() const { return this; }\n" - ).generate(sink, std::make_tuple(cls.cxx_name, cls.cxx_name), context)) return false; - if(!as_generator( scope_tab << string << "* operator->() { return this; }\n" - ).generate(sink, std::make_tuple(cls.cxx_name, cls.cxx_name), context)) return false; - // For easy interfacing with C: no need to use _eo_ptr() - if(!as_generator( scope_tab << "operator Eo*() const { return _eo_ptr(); }\n" - ).generate(sink, attributes::unused, context)) return false; - if(!as_generator("#endif \n").generate(sink, attributes::unused, context)) return false; + ).generate(sink, std::make_tuple(cls.cxx_name, cls.cxx_name), context)) return false; // eo_concrete if(!as_generator( scope_tab << "::efl::eo::concrete const& _get_concrete() const { return *this; }\n" @@ -241,6 +232,18 @@ struct class_definition_generator << scope_tab << "using ::efl::eo::concrete::operator bool;\n" ).generate(sink, attributes::unused, context)) return false; + // EXPERIMENTAL: wref and implicit conversion to Eo* + if(!as_generator("#ifdef EFL_CXXPERIMENTAL\n").generate(sink, attributes::unused, context)) return false; + // For easy wref, operator-> in wref needs to also return a pointer type + if(!as_generator( scope_tab << "const " << string << "* operator->() const { return this; }\n" + ).generate(sink, std::make_tuple(cls.cxx_name, cls.cxx_name), context)) return false; + if(!as_generator( scope_tab << string << "* operator->() { return this; }\n" + ).generate(sink, std::make_tuple(cls.cxx_name, cls.cxx_name), context)) return false; + // For easy interfacing with C: no need to use _eo_ptr() + if(!as_generator( scope_tab << "operator Eo*() const { return _eo_ptr(); }\n" + ).generate(sink, attributes::unused, context)) return false; + if(!as_generator("#endif \n").generate(sink, attributes::unused, context)) return false; + if(!as_generator( scope_tab << "friend bool operator==(" << string << " const& lhs, " << string << " const& rhs)\n" << scope_tab << "{ return lhs._get_concrete() == rhs._get_concrete(); }\n" << scope_tab << "friend bool operator!=(" << string << " const& lhs, " << string << " const& rhs)\n" diff --git a/src/lib/eolian_cxx/grammar/context.hpp b/src/lib/eolian_cxx/grammar/context.hpp index 79e54178e0..e4839200bc 100644 --- a/src/lib/eolian_cxx/grammar/context.hpp +++ b/src/lib/eolian_cxx/grammar/context.hpp @@ -56,7 +56,7 @@ Tag const& context_find_tag(context_cons const& context } template -Tag const& context_find_tag(context_null const& context) +Tag const& context_find_tag(context_null const&) { throw std::logic_error("Context for generation not available"); } diff --git a/src/lib/eolian_cxx/grammar/function_declaration.hpp b/src/lib/eolian_cxx/grammar/function_declaration.hpp index a2770abf18..f30f7569dc 100644 --- a/src/lib/eolian_cxx/grammar/function_declaration.hpp +++ b/src/lib/eolian_cxx/grammar/function_declaration.hpp @@ -48,10 +48,12 @@ struct function_declaration_generator .generate(sink, std::make_tuple(_klass_name.namespaces, _klass_name.eolian_name), add_upper_case_context(ctx))) return false; +#ifdef USE_EOCXX_MANUAL_OVERRIDES if(!as_generator ("#ifndef EOLIAN_CXX_" << string << "_DECLARATION\n") .generate(sink, f.c_name, add_upper_case_context(ctx))) return false; +#endif std::string template_statement(f.template_statement()); if (!template_statement.empty() && @@ -68,11 +70,13 @@ struct function_declaration_generator .generate(sink, std::make_tuple(f.return_type, escape_keyword(f.name), f.parameters), ctx)) return false; +#ifdef USE_EOCXX_MANUAL_OVERRIDES if(!as_generator ("#else\n" << scope_tab << "EOLIAN_CXX_" << string << "_DECLARATION\n" "#endif\n") .generate(sink, f.c_name, add_upper_case_context(ctx))) return false; +#endif if(f.is_protected && !as_generator("#endif\n").generate(sink, attributes::unused, ctx)) diff --git a/src/lib/eolian_cxx/grammar/function_definition.hpp b/src/lib/eolian_cxx/grammar/function_definition.hpp index 46df876b33..3161b76041 100644 --- a/src/lib/eolian_cxx/grammar/function_definition.hpp +++ b/src/lib/eolian_cxx/grammar/function_definition.hpp @@ -54,10 +54,12 @@ struct function_definition_generator .generate(sink, std::make_tuple(_klass_name.namespaces, _klass_name.eolian_name), add_upper_case_context(ctx))) return false; +#ifdef USE_EOCXX_MANUAL_OVERRIDES if(!as_generator ("#ifndef EOLIAN_CXX_" << string << "_IMPLEMENTATION\n") .generate(sink, f.c_name, add_upper_case_context(ctx))) return false; +#endif std::string template_statement(f.template_statement()); if (!template_statement.empty() && @@ -166,11 +168,13 @@ struct function_definition_generator if(!as_generator("}\n").generate(sink, attributes::unused, ctx)) return false; +#ifdef USE_EOCXX_MANUAL_OVERRIDES if(!as_generator ("#else\n" << scope_tab << "EOLIAN_CXX_" << string << "_IMPLEMENTATION\n" "#endif\n") .generate(sink, f.c_name, add_upper_case_context(ctx))) return false; +#endif if(f.is_beta && !as_generator("#endif\n").generate(sink, attributes::unused, ctx)) diff --git a/src/lib/eolian_cxx/grammar/generator.hpp b/src/lib/eolian_cxx/grammar/generator.hpp index 10e96c7c13..6d0be7e4f1 100644 --- a/src/lib/eolian_cxx/grammar/generator.hpp +++ b/src/lib/eolian_cxx/grammar/generator.hpp @@ -5,6 +5,7 @@ // EXPERIMENTAL //#define USE_EOCXX_INHERIT_ONLY +//#define USE_EOCXX_MANUAL_OVERRIDES namespace efl { namespace eolian { namespace grammar { diff --git a/src/lib/eolian_cxx/grammar/klass_def.hpp b/src/lib/eolian_cxx/grammar/klass_def.hpp index b2aae1bbef..1cb5ecfba0 100644 --- a/src/lib/eolian_cxx/grammar/klass_def.hpp +++ b/src/lib/eolian_cxx/grammar/klass_def.hpp @@ -458,17 +458,15 @@ struct function_def return !(lhs == rhs); } function_def() = default; - function_def(type_def return_type, std::string name, std::vector parameters - , std::string c_name, std::string filename, bool is_beta) - : return_type(return_type), name(name), parameters(parameters), c_name(c_name), filename(filename), is_beta(is_beta) {} function_def(type_def _return_type, std::string const& _name, std::vector const& _parameters, std::string const& _c_name, + std::string _filename, bool _is_beta = false, bool _is_protected = false, bool _is_function_pointer = false) : return_type(_return_type), name(_name), parameters(_parameters), - c_name(_c_name), is_beta(_is_beta), is_protected(_is_protected), + c_name(_c_name), filename(_filename), is_beta(_is_beta), is_protected(_is_protected), is_function_pointer(_is_function_pointer) {} function_def( ::Eolian_Function const* function, Eolian_Function_Type type, Eolian_Unit const* unit) @@ -572,7 +570,7 @@ struct function_def char typenam[2] = { 0, }; typenam[0] = template_typename++; std::string statement = "auto fw = new ::efl::eolian::function_wrapper<"; - statement += param.c_type + ", " + typenam + ">(" + param.param_name + ");"; + statement += param.type.c_type + ", " + typenam + ">(" + param.param_name + ");"; statements.push_back(statement); } } diff --git a/src/lib/eolian_cxx/grammar/parameter.hpp b/src/lib/eolian_cxx/grammar/parameter.hpp index 5d8d3aef5c..68f5450dd1 100644 --- a/src/lib/eolian_cxx/grammar/parameter.hpp +++ b/src/lib/eolian_cxx/grammar/parameter.hpp @@ -78,12 +78,20 @@ struct parameter_as_argument_generator template bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const { - return as_generator(parameter_type << "(" << string << ")").generate(sink, std::make_tuple(param, param.param_name), context); + attributes::parameter_def param_copy = param; + if (param.direction == attributes::parameter_direction::in) + param_copy.direction = attributes::parameter_direction::out; + else if (param.direction == attributes::parameter_direction::out) + param_copy.direction = attributes::parameter_direction::in; + return as_generator(parameter_type << "(" << string << ")") + .generate(sink, std::make_tuple(param_copy, param_copy.param_name), context); } }; template <> struct is_eager_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; namespace type_traits { template <> struct attributes_needed : std::integral_constant {}; diff --git a/src/lib/eolian_cxx/grammar/part_declaration.hpp b/src/lib/eolian_cxx/grammar/part_declaration.hpp index 04258c4020..30646fcbae 100644 --- a/src/lib/eolian_cxx/grammar/part_declaration.hpp +++ b/src/lib/eolian_cxx/grammar/part_declaration.hpp @@ -31,7 +31,8 @@ struct part_declaration_generator template <> struct is_eager_generator : std::true_type {}; - +template <> +struct is_generator : std::true_type {}; namespace type_traits { template <> struct attributes_needed : std::integral_constant {}; diff --git a/src/lib/eolian_cxx/grammar/part_implementation.hpp b/src/lib/eolian_cxx/grammar/part_implementation.hpp index cee2fc7fa8..692ebca7c1 100644 --- a/src/lib/eolian_cxx/grammar/part_implementation.hpp +++ b/src/lib/eolian_cxx/grammar/part_implementation.hpp @@ -53,7 +53,8 @@ private: template <> struct is_eager_generator : std::true_type {}; - +template <> +struct is_generator : std::true_type {}; namespace type_traits { template <> struct attributes_needed : std::integral_constant {}; diff --git a/src/lib/eolian_cxx/grammar/type_function_declaration.hpp b/src/lib/eolian_cxx/grammar/type_function_declaration.hpp index eccedf8f4a..93ebe45940 100644 --- a/src/lib/eolian_cxx/grammar/type_function_declaration.hpp +++ b/src/lib/eolian_cxx/grammar/type_function_declaration.hpp @@ -56,7 +56,7 @@ struct type_function_declaration_generator { std::vector c_args; for (auto itr : f.parameters) - c_args.push_back(", " + itr.c_type + " " + itr.param_name); + c_args.push_back(", " + itr.type.c_type + " " + itr.param_name); if (!as_generator( scope_tab << "static " << string << " caller(void *cxx_call_data" << *(string) << ") {\n" @@ -102,7 +102,8 @@ struct type_function_declaration_generator { template <> struct is_eager_generator : std::true_type {}; - +template <> +struct is_generator : std::true_type {}; namespace type_traits { template <> struct attributes_needed : std::integral_constant {};