public override CCodeExpression get_array_length_cvalue(TargetValue value, int dim = -1) { var array_type = value.value_type as ArrayType; if (array_type != null && array_type.fixed_length) { return(get_ccodenode(array_type.length)); } // dim == -1 => total size over all dimensions if (dim == -1) { if (array_type != null && array_type.rank > 1) { CCodeExpression cexpr = get_array_length_cvalue(value, 1); for (dim = 2; dim <= array_type.rank; dim++) { cexpr = new CCodeBinaryExpression(CCodeBinaryOperator.MUL, cexpr, get_array_length_cvalue(value, dim)); } return(cexpr); } else { dim = 1; } } List <CCodeExpression> size = ((GLibValue)value).array_length_cvalues; Debug.Assert(size != null && size.Count >= dim); return(size[dim - 1]); }
public override void append_vala_array_free() { // _vala_array_destroy only frees elements but not the array itself var fun = new CCodeFunction("_vala_array_destroy", "void"); fun.modifiers = CCodeModifiers.STATIC; fun.add_parameter(new CCodeParameter("array", "gpointer")); fun.add_parameter(new CCodeParameter("array_length", "gint")); fun.add_parameter(new CCodeParameter("destroy_func", "GDestroyNotify")); push_function(fun); var ccondarr = new CCodeBinaryExpression(CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier("array"), new CCodeConstant("NULL")); var ccondfunc = new CCodeBinaryExpression(CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier("destroy_func"), new CCodeConstant("NULL")); ccode.open_if(new CCodeBinaryExpression(CCodeBinaryOperator.AND, ccondarr, ccondfunc)); ccode.add_declaration("int", new CCodeVariableDeclarator("i")); append_vala_array_free_loop(); ccode.close(); pop_function(); cfile.add_function_declaration(fun); cfile.add_function(fun); // _vala_array_free frees elements and array fun = new CCodeFunction("_vala_array_free", "void"); fun.modifiers = CCodeModifiers.STATIC; fun.add_parameter(new CCodeParameter("array", "gpointer")); fun.add_parameter(new CCodeParameter("array_length", "gint")); fun.add_parameter(new CCodeParameter("destroy_func", "GDestroyNotify")); push_function(fun); // call _vala_array_destroy to free the array elements var ccall = new CCodeFunctionCall(new CCodeIdentifier("_vala_array_destroy")); ccall.add_argument(new CCodeIdentifier("array")); ccall.add_argument(new CCodeIdentifier("array_length")); ccall.add_argument(new CCodeIdentifier("destroy_func")); ccode.add_expression(ccall); var carrfree = new CCodeFunctionCall(new CCodeIdentifier("g_free")); carrfree.add_argument(new CCodeIdentifier("array")); ccode.add_expression(carrfree); pop_function(); cfile.add_function_declaration(fun); cfile.add_function(fun); }
CCodeExpression serialize_array_dim(ArrayType array_type, int dim, CCodeExpression array_expr, CCodeExpression array_iter_expr) { string builder_name = "_tmp%d_".printf(next_temp_var_id++); string index_name = "_tmp%d_".printf(next_temp_var_id++); ccode.add_declaration("GVariantBuilder", new CCodeVariableDeclarator(builder_name)); ccode.add_declaration("int", new CCodeVariableDeclarator(index_name)); var gvariant_type = new CCodeFunctionCall(new CCodeIdentifier("G_VARIANT_TYPE")); gvariant_type.add_argument(new CCodeConstant("\"%s\"".printf(get_type_signature(array_type)))); var builder_init = new CCodeFunctionCall(new CCodeIdentifier("g_variant_builder_init")); builder_init.add_argument(new CCodeUnaryExpression(CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier(builder_name))); builder_init.add_argument(gvariant_type); ccode.add_expression(builder_init); var cforinit = new CCodeAssignment(new CCodeIdentifier(index_name), new CCodeConstant("0")); var cforcond = new CCodeBinaryExpression(CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier(index_name), get_array_length(array_expr, dim)); var cforiter = new CCodeUnaryExpression(CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier(index_name)); ccode.open_for(cforinit, cforcond, cforiter); CCodeExpression element_variant; if (dim < array_type.rank) { element_variant = serialize_array_dim(array_type, dim + 1, array_expr, array_iter_expr); } else { var element_expr = new CCodeUnaryExpression(CCodeUnaryOperator.POINTER_INDIRECTION, array_iter_expr); element_variant = serialize_expression(array_type.element_type, element_expr); } var builder_add = new CCodeFunctionCall(new CCodeIdentifier("g_variant_builder_add_value")); builder_add.add_argument(new CCodeUnaryExpression(CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier(builder_name))); builder_add.add_argument(element_variant); ccode.add_expression(builder_add); if (dim == array_type.rank) { var array_iter_incr = new CCodeUnaryExpression(CCodeUnaryOperator.POSTFIX_INCREMENT, array_iter_expr); ccode.add_expression(array_iter_incr); } ccode.close(); var builder_end = new CCodeFunctionCall(new CCodeIdentifier("g_variant_builder_end")); builder_end.add_argument(new CCodeUnaryExpression(CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier(builder_name))); return(builder_end); }
public override void visit_slice_expression(SliceExpression expr) { var ccontainer = get_cvalue(expr.container); var cstart = get_cvalue(expr.start); var cstop = get_cvalue(expr.stop); var cstartpointer = new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, ccontainer, cstart); var splicelen = new CCodeBinaryExpression(CCodeBinaryOperator.MINUS, cstop, cstart); set_cvalue(expr, cstartpointer); append_array_length(expr, splicelen); }
public CCodeFunction generate_enum_from_string_function(ValaEnum en) { var from_string_name = "%s_from_string".printf(get_ccode_lower_case_name(en, null)); var from_string_func = new CCodeFunction(from_string_name, get_ccode_name(en)); from_string_func.add_parameter(new CCodeParameter("str", "const char*")); from_string_func.add_parameter(new CCodeParameter("error", "GError**")); push_function(from_string_func); ccode.add_declaration(get_ccode_name(en), CCodeVariableDeclarator.zero("value", new CCodeConstant("0"))); bool firstif = true; foreach (EnumValue enum_value in en.get_values()) { string dbus_value = get_dbus_value(enum_value, enum_value.name); var string_comparison = new CCodeFunctionCall(new CCodeIdentifier("strcmp")); string_comparison.add_argument(new CCodeIdentifier("str")); string_comparison.add_argument(new CCodeConstant("\"%s\"".printf(dbus_value))); var cond = new CCodeBinaryExpression(CCodeBinaryOperator.EQUALITY, string_comparison, new CCodeConstant("0")); if (firstif) { ccode.open_if(cond); firstif = false; } else { ccode.else_if(cond); } ccode.add_assignment(new CCodeIdentifier("value"), new CCodeIdentifier(get_ccode_name(enum_value))); } ccode.add_else(); var set_error = new CCodeFunctionCall(new CCodeIdentifier("g_set_error")); set_error.add_argument(new CCodeIdentifier("error")); set_error.add_argument(new CCodeIdentifier("G_DBUS_ERROR")); set_error.add_argument(new CCodeIdentifier("G_DBUS_ERROR_INVALID_ARGS")); set_error.add_argument(new CCodeConstant("\"Invalid value for enum `%s'\"".printf(get_ccode_name(en)))); ccode.add_expression(set_error); ccode.close(); ccode.add_return(new CCodeIdentifier("value")); pop_function(); return(from_string_func); }
void generate_async_ready_callback_wrapper(Method m, string function_name) { var function = new CCodeFunction(function_name, "void"); function.modifiers = CCodeModifiers.STATIC; function.add_parameter(new CCodeParameter("*source_object", "GObject")); function.add_parameter(new CCodeParameter("*res", "GAsyncResult")); function.add_parameter(new CCodeParameter("*user_data", "void")); push_function(function); // Set _task_complete_ to false after calling back to the real func var async_result_cast = new CCodeFunctionCall(new CCodeIdentifier("G_TASK")); async_result_cast.add_argument(new CCodeIdentifier("res")); var dataname = Symbol.lower_case_to_camel_case(get_ccode_name(m)) + "Data"; ccode.add_declaration(dataname + "*", new CCodeVariableDeclarator("_task_data_")); var get_data_call = new CCodeFunctionCall(new CCodeIdentifier("g_task_get_task_data")); get_data_call.add_argument(async_result_cast); var data_var = new CCodeIdentifier("_task_data_"); ccode.add_assignment(data_var, get_data_call); var task_inner_callback = CCodeMemberAccess.pointer(data_var, "_callback_"); var callback_is_nonnull = new CCodeBinaryExpression(CCodeBinaryOperator.INEQUALITY, task_inner_callback, new CCodeConstant("NULL")); ccode.open_if(callback_is_nonnull); var nested_callback = new CCodeFunctionCall(task_inner_callback); nested_callback.add_argument(new CCodeIdentifier("source_object")); nested_callback.add_argument(new CCodeIdentifier("res")); nested_callback.add_argument(new CCodeIdentifier("user_data")); ccode.add_expression(nested_callback); ccode.close(); ccode.add_assignment(CCodeMemberAccess.pointer(data_var, "_task_complete_"), new CCodeConstant("TRUE")); pop_function(); cfile.add_function_declaration(function); cfile.add_function(function); }
void append_struct_array_free_loop(Struct st) { var cforinit = new CCodeAssignment(new CCodeIdentifier("i"), new CCodeConstant("0")); var cforcond = new CCodeBinaryExpression(CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier("i"), new CCodeIdentifier("array_length")); var cforiter = new CCodeAssignment(new CCodeIdentifier("i"), new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, new CCodeIdentifier("i"), new CCodeConstant("1"))); ccode.open_for(cforinit, cforcond, cforiter); var cptrarray = new CCodeIdentifier("array"); var cea = new CCodeElementAccess(cptrarray, new CCodeIdentifier("i")); var cfreecall = new CCodeFunctionCall(get_destroy_func_expression(new StructValueType(st))); cfreecall.add_argument(new CCodeUnaryExpression(CCodeUnaryOperator.ADDRESS_OF, cea)); ccode.add_expression(cfreecall); ccode.close(); }
public override void visit_element_access(ElementAccess expr) { List <Expression> indices = expr.get_indices(); int rank = indices.Count; var ccontainer = get_cvalue(expr.container); var cindex = get_cvalue(indices[0]); if (expr.container.symbol_reference is ArrayLengthField) { /* Figure if cindex is a constant expression and calculate dim...*/ var lit = indices[0] as IntegerLiteral; var memberaccess = expr.container as MemberAccess; if (lit != null && memberaccess != null) { int dim = int.Parse(lit.value); set_cvalue(expr, get_array_length_cexpression(memberaccess.inner, dim + 1)); } else { Report.error(expr.source_reference, "only integer literals supported as index"); } } else { // access to element in an array for (int i = 1; i < rank; i++) { var cmul = new CCodeBinaryExpression(CCodeBinaryOperator.MUL, cindex, get_array_length_cexpression(expr.container, i + 1)); cindex = new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, cmul, get_cvalue(indices[i])); } set_cvalue(expr, new CCodeElementAccess(ccontainer, cindex)); } expr.target_value.value_type = expr.value_type.copy(); if (!expr.lvalue) { expr.target_value = store_temp_value(expr.target_value, expr); } ((GLibValue)expr.target_value).lvalue = true; }
void append_vala_array_free_loop() { var cforinit = new CCodeAssignment(new CCodeIdentifier("i"), new CCodeConstant("0")); var cforcond = new CCodeBinaryExpression(CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier("i"), new CCodeIdentifier("array_length")); var cforiter = new CCodeAssignment(new CCodeIdentifier("i"), new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, new CCodeIdentifier("i"), new CCodeConstant("1"))); ccode.open_for(cforinit, cforcond, cforiter); var cptrarray = new CCodeCastExpression(new CCodeIdentifier("array"), "gpointer*"); var cea = new CCodeElementAccess(cptrarray, new CCodeIdentifier("i")); var cfreecond = new CCodeBinaryExpression(CCodeBinaryOperator.INEQUALITY, cea, new CCodeConstant("NULL")); ccode.open_if(cfreecond); var cfreecall = new CCodeFunctionCall(new CCodeIdentifier("destroy_func")); cfreecall.add_argument(cea); ccode.add_expression(cfreecall); ccode.close(); }
public override string append_struct_array_free(Struct st) { string cname = "_vala_%s_array_free".printf(get_ccode_name(st)); if (cfile.add_declaration(cname)) { return(cname); } var fun = new CCodeFunction(cname, "void"); fun.modifiers = CCodeModifiers.STATIC; fun.add_parameter(new CCodeParameter("array", "%s *".printf(get_ccode_name(st)))); fun.add_parameter(new CCodeParameter("array_length", "gint")); push_function(fun); var ccondarr = new CCodeBinaryExpression(CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier("array"), new CCodeConstant("NULL")); ccode.open_if(ccondarr); ccode.add_declaration("int", new CCodeVariableDeclarator("i")); append_struct_array_free_loop(st); ccode.close(); var carrfree = new CCodeFunctionCall(new CCodeIdentifier("g_free")); carrfree.add_argument(new CCodeIdentifier("array")); ccode.add_expression(carrfree); pop_function(); cfile.add_function_declaration(fun); cfile.add_function(fun); return(cname); }
public override void add_simple_check(CodeNode node, bool always_fails = false) { current_method_inner_error = true; var inner_error = get_variable_cexpression("_inner_error_"); if (always_fails) { // inner_error is always set, avoid unnecessary if statement // eliminates C warnings } else { var ccond = new CCodeBinaryExpression(CCodeBinaryOperator.INEQUALITY, inner_error, new CCodeConstant("NULL")); var unlikely = new CCodeFunctionCall(new CCodeIdentifier("G_UNLIKELY")); unlikely.add_argument(ccond); ccode.open_if(unlikely); } if (current_try != null) { // surrounding try found // free local variables if (is_in_catch) { append_local_free(current_symbol, false, current_catch); } else { append_local_free(current_symbol, false, current_try); } var error_types = new List <DataType>(); foreach (DataType node_error_type in node.get_error_types()) { error_types.Add(node_error_type); } bool has_general_catch_clause = false; if (!is_in_catch) { var handled_error_types = new List <DataType>(); foreach (CatchClause clause in current_try.get_catch_clauses()) { // keep track of unhandled error types foreach (DataType node_error_type in error_types) { if (clause.error_type == null || node_error_type.compatible(clause.error_type)) { handled_error_types.Add(node_error_type); } } foreach (DataType handled_error_type in handled_error_types) { error_types.Remove(handled_error_type); } handled_error_types.Clear(); if (clause.error_type.equals(gerror_type)) { // general catch clause, this should be the last one has_general_catch_clause = true; ccode.add_goto(clause.clabel_name); break; } else { var catch_type = clause.error_type as ErrorType; if (catch_type.error_code != null) { /* catch clause specifies a specific error code */ var error_match = new CCodeFunctionCall(new CCodeIdentifier("g_error_matches")); error_match.add_argument(inner_error); error_match.add_argument(new CCodeIdentifier(get_ccode_upper_case_name(catch_type.data_type))); error_match.add_argument(new CCodeIdentifier(get_ccode_name(catch_type.error_code))); ccode.open_if(error_match); } else { /* catch clause specifies a full error domain */ var ccond = new CCodeBinaryExpression(CCodeBinaryOperator.EQUALITY, CCodeMemberAccess.pointer(inner_error, "domain"), new CCodeIdentifier (get_ccode_upper_case_name(clause.error_type.data_type))); ccode.open_if(ccond); } // go to catch clause if error domain matches ccode.add_goto(clause.clabel_name); ccode.close(); } } } if (has_general_catch_clause) { // every possible error is already caught // as there is a general catch clause // no need to do anything else } else if (error_types.Count > 0) { // go to finally clause if no catch clause matches // and there are still unhandled error types ccode.add_goto("__finally%d".printf(current_try_id)); } else if (in_finally_block(node)) { // do not check unexpected errors happening within finally blocks // as jump out of finally block is not supported } else { // should never happen with correct bindings uncaught_error_statement(inner_error, true); } } else if (current_method != null && current_method.get_error_types().Count > 0) { // current method can fail, propagate error CCodeBinaryExpression ccond = null; foreach (DataType error_type in current_method.get_error_types()) { // If GLib.Error is allowed we propagate everything if (error_type.equals(gerror_type)) { ccond = null; break; } // Check the allowed error domains to propagate var domain_check = new CCodeBinaryExpression(CCodeBinaryOperator.EQUALITY, CCodeMemberAccess.pointer (inner_error, "domain"), new CCodeIdentifier(get_ccode_upper_case_name(error_type.data_type))); if (ccond == null) { ccond = domain_check; } else { ccond = new CCodeBinaryExpression(CCodeBinaryOperator.OR, ccond, domain_check); } } if (ccond != null) { ccode.open_if(ccond); return_with_exception(inner_error); ccode.add_else(); uncaught_error_statement(inner_error); ccode.close(); } else { return_with_exception(inner_error); } } else { uncaught_error_statement(inner_error); } if (!always_fails) { ccode.close(); } }
/// <summary> /// Constructs the C function from the specified type. /// </summary> public void init_from_type(bool plugin, bool declaration_only) { bool use_thread_safe = !plugin; bool fundamental = false; Class cl = get_type_declaration() as Class; if (cl != null && !cl.is_compact && cl.base_class == null) { fundamental = true; } string type_id_name = "%s_type_id".printf(CCodeBaseModule.get_ccode_lower_case_name(get_type_declaration())); var type_block = new CCodeBlock(); CCodeDeclaration cdecl; if (use_thread_safe) { cdecl = new CCodeDeclaration("gsize"); cdecl.add_declarator(new CCodeVariableDeclarator(type_id_name + "__volatile", new CCodeConstant("0"))); } else { cdecl = new CCodeDeclaration("GType"); cdecl.add_declarator(new CCodeVariableDeclarator(type_id_name, new CCodeConstant("0"))); } cdecl.modifiers = CCodeModifiers.STATIC; if (use_thread_safe) { cdecl.modifiers |= CCodeModifiers.VOLATILE; } if (!plugin) { type_block.add_statement(cdecl); } else { source_declaration_fragment.append(cdecl); } CCodeFunction fun; if (!plugin) { fun = new CCodeFunction("%s_get_type".printf(CCodeBaseModule.get_ccode_lower_case_name(get_type_declaration())), "GType"); fun.modifiers = CCodeModifiers.CONST; /* Function will not be prototyped anyway */ if (get_accessibility() == SymbolAccessibility.PRIVATE) { // avoid C warning as this function is not always used fun.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.UNUSED; } else if (context.hide_internal && get_accessibility() == SymbolAccessibility.INTERNAL) { // avoid C warning as this function is not always used fun.modifiers |= CCodeModifiers.INTERNAL | CCodeModifiers.UNUSED; } fun.is_declaration = true; declaration_fragment.append(fun.copy()); fun.is_declaration = false; } else { fun = new CCodeFunction("%s_register_type".printf(CCodeBaseModule.get_ccode_lower_case_name(get_type_declaration())), "GType"); fun.add_parameter(new CCodeParameter("module", "GTypeModule *")); var get_fun = new CCodeFunction("%s_get_type".printf(CCodeBaseModule.get_ccode_lower_case_name(get_type_declaration())), "GType"); get_fun.modifiers = CCodeModifiers.CONST; get_fun.is_declaration = true; declaration_fragment.append(get_fun.copy()); get_fun.is_declaration = false; get_fun.block = new CCodeBlock(); get_fun.block.add_statement(new CCodeReturnStatement(new CCodeIdentifier(type_id_name))); definition_fragment.append(get_fun); } string type_value_table_decl_name = null; var type_init = new CCodeBlock(); if (fundamental) { var cgtypetabledecl = new CCodeDeclaration("const GTypeValueTable"); cgtypetabledecl.modifiers = CCodeModifiers.STATIC; cgtypetabledecl.add_declarator(new CCodeVariableDeclarator("g_define_type_value_table", new CCodeConstant("{ %s, %s, %s, %s, \"p\", %s, \"p\", %s }".printf(get_gtype_value_table_init_function_name(), get_gtype_value_table_free_function_name(), get_gtype_value_table_copy_function_name(), get_gtype_value_table_peek_pointer_function_name(), get_gtype_value_table_collect_value_function_name(), get_gtype_value_table_lcopy_value_function_name())))); type_value_table_decl_name = "&g_define_type_value_table"; type_init.add_statement(cgtypetabledecl); } else { type_value_table_decl_name = "NULL"; } if (get_type_declaration() is ObjectTypeSymbol) { var ctypedecl = new CCodeDeclaration("const GTypeInfo"); ctypedecl.modifiers = CCodeModifiers.STATIC; ctypedecl.add_declarator(new CCodeVariableDeclarator("g_define_type_info", new CCodeConstant("{ sizeof (%s), (GBaseInitFunc) %s, (GBaseFinalizeFunc) %s, (GClassInitFunc) %s, (GClassFinalizeFunc) %s, NULL, %s, 0, (GInstanceInitFunc) %s, %s }".printf(get_type_struct_name(), get_base_init_func_name(), (plugin) ? get_base_finalize_func_name() : "NULL", get_class_init_func_name(), get_class_finalize_func_name(), get_instance_struct_size(), get_instance_init_func_name(), type_value_table_decl_name)))); type_init.add_statement(ctypedecl); if (fundamental) { var ctypefundamentaldecl = new CCodeDeclaration("const GTypeFundamentalInfo"); ctypefundamentaldecl.modifiers = CCodeModifiers.STATIC; ctypefundamentaldecl.add_declarator(new CCodeVariableDeclarator("g_define_type_fundamental_info", new CCodeConstant("{ (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) }"))); type_init.add_statement(ctypefundamentaldecl); } } type_init.add_statement(get_type_interface_init_declaration()); CCodeFunctionCall reg_call; if (get_type_declaration() is Struct) { reg_call = new CCodeFunctionCall(new CCodeIdentifier("g_boxed_type_register_static")); } else if (get_type_declaration() is ValaEnum) { var en = get_type_declaration() as ValaEnum; if (en.is_flags) { reg_call = new CCodeFunctionCall(new CCodeIdentifier("g_flags_register_static")); } else { reg_call = new CCodeFunctionCall(new CCodeIdentifier("g_enum_register_static")); } } else if (fundamental) { reg_call = new CCodeFunctionCall(new CCodeIdentifier("g_type_register_fundamental")); reg_call.add_argument(new CCodeFunctionCall(new CCodeIdentifier("g_type_fundamental_next"))); } else if (!plugin) { reg_call = new CCodeFunctionCall(new CCodeIdentifier("g_type_register_static")); reg_call.add_argument(new CCodeIdentifier(get_parent_type_name())); } else { reg_call = new CCodeFunctionCall(new CCodeIdentifier("g_type_module_register_type")); reg_call.add_argument(new CCodeIdentifier("module")); reg_call.add_argument(new CCodeIdentifier(get_parent_type_name())); } reg_call.add_argument(new CCodeConstant("\"%s\"".printf(CCodeBaseModule.get_ccode_name(get_type_declaration())))); if (get_type_declaration() is Struct) { var st = (Struct)get_type_declaration(); reg_call.add_argument(new CCodeCastExpression(new CCodeIdentifier(CCodeBaseModule.get_ccode_dup_function(st)), "GBoxedCopyFunc")); reg_call.add_argument(new CCodeCastExpression(new CCodeIdentifier(CCodeBaseModule.get_ccode_free_function(st)), "GBoxedFreeFunc")); } else if (get_type_declaration() is ValaEnum) { var en = get_type_declaration() as ValaEnum; var clist = new CCodeInitializerList(); /* or during visit time? */ CCodeInitializerList clist_ev = null; foreach (EnumValue ev in en.get_values()) { clist_ev = new CCodeInitializerList(); clist_ev.append(new CCodeConstant(CCodeBaseModule.get_ccode_name(ev))); clist_ev.append(new CCodeIdentifier("\"%s\"".printf(CCodeBaseModule.get_ccode_name(ev)))); clist_ev.append(CCodeBaseModule.get_enum_value_canonical_cconstant(ev)); clist.append(clist_ev); } clist_ev = new CCodeInitializerList(); clist_ev.append(new CCodeConstant("0")); clist_ev.append(new CCodeConstant("NULL")); clist_ev.append(new CCodeConstant("NULL")); clist.append(clist_ev); var enum_decl = new CCodeVariableDeclarator("values[]", clist); if (en.is_flags) { cdecl = new CCodeDeclaration("const GFlagsValue"); } else { cdecl = new CCodeDeclaration("const GEnumValue"); } cdecl.add_declarator(enum_decl); cdecl.modifiers = CCodeModifiers.STATIC; type_init.add_statement(cdecl); reg_call.add_argument(new CCodeIdentifier("values")); } else { reg_call.add_argument(new CCodeIdentifier("&g_define_type_info")); if (fundamental) { reg_call.add_argument(new CCodeIdentifier("&g_define_type_fundamental_info")); } reg_call.add_argument(new CCodeConstant(get_type_flags())); } if (use_thread_safe && !plugin) { var temp_decl = new CCodeDeclaration("GType"); temp_decl.add_declarator(new CCodeVariableDeclarator(type_id_name, reg_call)); type_init.add_statement(temp_decl); } else { type_init.add_statement(new CCodeExpressionStatement(new CCodeAssignment(new CCodeIdentifier(type_id_name), reg_call))); } if (cl != null && cl.has_class_private_fields) { CCodeFunctionCall add_class_private_call; add_class_private_call = new CCodeFunctionCall(new CCodeIdentifier("g_type_add_class_private")); add_class_private_call.add_argument(new CCodeIdentifier(type_id_name)); add_class_private_call.add_argument(new CCodeIdentifier("sizeof (%sClassPrivate)".printf(CCodeBaseModule.get_ccode_name(get_type_declaration())))); type_init.add_statement(new CCodeExpressionStatement(add_class_private_call)); } if (!declaration_only) { get_type_interface_init_statements(type_init, plugin); } if (!plugin) { CCodeExpression condition; // the condition that guards the type initialisation if (use_thread_safe) { var enter = new CCodeFunctionCall(new CCodeIdentifier("g_once_init_enter")); enter.add_argument(new CCodeUnaryExpression(CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier(type_id_name + "__volatile"))); condition = enter; var leave = new CCodeFunctionCall(new CCodeIdentifier("g_once_init_leave")); leave.add_argument(new CCodeUnaryExpression(CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier(type_id_name + "__volatile"))); leave.add_argument(new CCodeIdentifier(type_id_name)); type_init.add_statement(new CCodeExpressionStatement(leave)); } else { var id = new CCodeIdentifier(type_id_name); var zero = new CCodeConstant("0"); condition = new CCodeBinaryExpression(CCodeBinaryOperator.EQUALITY, id, zero); } CCodeExpression cond; if (use_thread_safe) { cond = condition; } else { cond = new CCodeFunctionCall(new CCodeIdentifier("G_UNLIKELY")); (cond as CCodeFunctionCall).add_argument(condition); } var cif = new CCodeIfStatement(cond, type_init); type_block.add_statement(cif); } else { type_block = type_init; } if (use_thread_safe) { type_block.add_statement(new CCodeReturnStatement(new CCodeIdentifier(type_id_name + "__volatile"))); } else { type_block.add_statement(new CCodeReturnStatement(new CCodeIdentifier(type_id_name))); } fun.block = type_block; definition_fragment.append(fun); }
public override void visit_field(Field f) { base.visit_field(f); var cl = current_class; if (cl == null || cl.error) { return; } if (f.binding != MemberBinding.INSTANCE || f.get_attribute("GtkChild") == null) { return; } /* If the field has a [GtkChild] attribute but its class doesn'thave a * [GtkTemplate] attribute, we throw an error */ if (!is_gtk_template(cl)) { Report.error(f.source_reference, "[GtkChild] is only allowed in classes with a [GtkTemplate] attribute"); return; } push_context(class_init_context); /* Map ui widget to a class field */ var gtk_name = f.get_attribute_string("GtkChild", "name", f.name); var child_class = current_child_to_class_map[gtk_name]; if (child_class == null) { Report.error(f.source_reference, "could not find child `%s'".printf(gtk_name)); return; } /* We allow Gtk child to have stricter type than class field */ var field_class = f.variable_type.data_type as Class; if (field_class == null || !child_class.is_subtype_of(field_class)) { Report.error(f.source_reference, "cannot convert from Gtk child type `%s' to `%s'".printf(child_class.get_full_name(), field_class.get_full_name())); return; } var internal_child = f.get_attribute_bool("GtkChild", "internal"); CCodeExpression offset; if (f.is_private_symbol()) { // new glib api, we add the private struct offset to get the final field offset out of the instance var private_field_offset = new CCodeFunctionCall(new CCodeIdentifier("G_STRUCT_OFFSET")); private_field_offset.add_argument(new CCodeIdentifier("%sPrivate".printf(get_ccode_name(cl)))); private_field_offset.add_argument(new CCodeIdentifier(get_ccode_name(f))); offset = new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, new CCodeIdentifier("%s_private_offset".printf(get_ccode_name(cl))), private_field_offset); } else { var offset_call = new CCodeFunctionCall(new CCodeIdentifier("G_STRUCT_OFFSET")); offset_call.add_argument(new CCodeIdentifier(get_ccode_name(cl))); offset_call.add_argument(new CCodeIdentifier(get_ccode_name(f))); offset = offset_call; } var call = new CCodeFunctionCall(new CCodeIdentifier("gtk_widget_class_bind_template_child_full")); call.add_argument(new CCodeIdentifier("GTK_WIDGET_CLASS (klass)")); call.add_argument(new CCodeConstant("\"%s\"".printf(gtk_name))); call.add_argument(new CCodeConstant(internal_child ? "TRUE" : "FALSE")); call.add_argument(offset); ccode.add_expression(call); pop_context(); if (!field_class.external && !field_class.external_package) { current_required_app_classes.Add(field_class); } }
void generate_finish_function(Method m) { push_context(new EmitContext()); string dataname = Symbol.lower_case_to_camel_case(get_ccode_name(m)) + "Data"; var finishfunc = new CCodeFunction(get_ccode_finish_real_name(m)); var cparam_map = new Dictionary <int, CCodeParameter>(); cparam_map[get_param_pos(0.1)] = new CCodeParameter("_res_", "GAsyncResult*"); generate_cparameters(m, cfile, cparam_map, finishfunc, null, null, null, 2); if (m.is_private_symbol() || m.base_method != null || m.base_interface_method != null) { finishfunc.modifiers |= CCodeModifiers.STATIC; } else if (context.hide_internal && m.is_internal_symbol()) { finishfunc.modifiers |= CCodeModifiers.INTERNAL; } push_function(finishfunc); var return_type = m.return_type; if (m is CreationMethod) { var type_sym = (TypeSymbol)m.parent_symbol; if (type_sym is ObjectTypeSymbol) { ccode.add_declaration(get_ccode_name(type_sym) + "*", new CCodeVariableDeclarator("result")); } } else if (!(return_type is VoidType) && !return_type.is_real_non_null_struct_type()) { ccode.add_declaration(get_ccode_name(m.return_type), new CCodeVariableDeclarator("result")); } var data_var = new CCodeIdentifier("_data_"); ccode.add_declaration(dataname + "*", new CCodeVariableDeclarator("_data_")); var async_result_cast = new CCodeFunctionCall(new CCodeIdentifier("G_TASK")); async_result_cast.add_argument(new CCodeIdentifier("_res_")); var ccall = new CCodeFunctionCall(new CCodeIdentifier("g_task_propagate_pointer")); ccall.add_argument(async_result_cast); if (m.get_error_types().Count > 0) { ccall.add_argument(new CCodeIdentifier("error")); } else { ccall.add_argument(new CCodeConstant("NULL")); } ccode.add_assignment(data_var, ccall); bool has_cancellable = false; foreach (Parameter param in m.get_parameters()) { if (param.variable_type is ObjectType && param.variable_type.data_type.get_full_name() == "GLib.Cancellable") { has_cancellable = true; break; } } // If a task is cancelled, g_task_propagate_pointer returns NULL if (m.get_error_types().Count > 0 || has_cancellable) { var is_null = new CCodeBinaryExpression(CCodeBinaryOperator.EQUALITY, new CCodeConstant("NULL"), data_var); ccode.open_if(is_null); return_default_value(return_type); ccode.close(); } emit_context.push_symbol(m); foreach (Parameter param in m.get_parameters()) { if (param.direction != ParameterDirection.IN) { return_out_parameter(param); if (!(param.variable_type is ValaValueType) || param.variable_type.nullable) { ccode.add_assignment(CCodeMemberAccess.pointer(data_var, get_variable_cname(param.name)), new CCodeConstant("NULL")); } } } emit_context.pop_symbol(); if (m is CreationMethod) { ccode.add_assignment(new CCodeIdentifier("result"), CCodeMemberAccess.pointer(data_var, "self")); ccode.add_assignment(CCodeMemberAccess.pointer(data_var, "self"), new CCodeConstant("NULL")); ccode.add_return(new CCodeIdentifier("result")); } else if (return_type.is_real_non_null_struct_type()) { // structs are returned via out parameter CCodeExpression cexpr = CCodeMemberAccess.pointer(data_var, "result"); if (requires_copy(return_type)) { cexpr = get_cvalue_(copy_value(new GLibValue(return_type, cexpr, true), return_type)); } ccode.add_assignment(new CCodeUnaryExpression(CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier("result")), cexpr); } else if (!(return_type is VoidType)) { ccode.add_assignment(new CCodeIdentifier("result"), CCodeMemberAccess.pointer(data_var, "result")); if (return_type is ArrayType) { var array_type = (ArrayType)return_type; if (get_ccode_array_length(m)) { for (int dim = 1; dim <= array_type.rank; dim++) { ccode.add_assignment(new CCodeUnaryExpression(CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier(get_array_length_cname("result", dim))), CCodeMemberAccess.pointer(data_var, get_array_length_cname("result", dim))); } } } else if (return_type is DelegateType && ((DelegateType)return_type).delegate_symbol.has_target) { ccode.add_assignment(new CCodeUnaryExpression(CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier(get_delegate_target_cname("result"))), CCodeMemberAccess.pointer(data_var, get_delegate_target_cname("result"))); } if (!(return_type is ValaValueType) || return_type.nullable) { ccode.add_assignment(CCodeMemberAccess.pointer(data_var, "result"), new CCodeConstant("NULL")); } ccode.add_return(new CCodeIdentifier("result")); } pop_function(); cfile.add_function(finishfunc); pop_context(); }
void deserialize_array_dim(ArrayType array_type, int dim, string temp_name, CCodeExpression variant_expr, CCodeExpression expr) { string subiter_name = "_tmp%d_".printf(next_temp_var_id++); string element_name = "_tmp%d_".printf(next_temp_var_id++); ccode.add_declaration("int", new CCodeVariableDeclarator("%s_length%d".printf(temp_name, dim), new CCodeConstant("0"))); ccode.add_declaration("GVariantIter", new CCodeVariableDeclarator(subiter_name)); ccode.add_declaration("GVariant*", new CCodeVariableDeclarator(element_name)); var iter_call = new CCodeFunctionCall(new CCodeIdentifier("g_variant_iter_init")); iter_call.add_argument(new CCodeUnaryExpression(CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier(subiter_name))); iter_call.add_argument(variant_expr); ccode.add_expression(iter_call); iter_call = new CCodeFunctionCall(new CCodeIdentifier("g_variant_iter_next_value")); iter_call.add_argument(new CCodeUnaryExpression(CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier(subiter_name))); var cforcond = new CCodeBinaryExpression(CCodeBinaryOperator.INEQUALITY, new CCodeAssignment(new CCodeIdentifier(element_name), iter_call), new CCodeConstant("NULL")); var cforiter = new CCodeUnaryExpression(CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier("%s_length%d".printf(temp_name, dim))); ccode.open_for(null, cforcond, cforiter); if (dim < array_type.rank) { deserialize_array_dim(array_type, dim + 1, temp_name, new CCodeIdentifier(element_name), expr); } else { var size_check = new CCodeBinaryExpression(CCodeBinaryOperator.EQUALITY, new CCodeIdentifier(temp_name + "_size"), new CCodeIdentifier(temp_name + "_length")); ccode.open_if(size_check); // tmp_size = (2 * tmp_size); var new_size = new CCodeBinaryExpression(CCodeBinaryOperator.MUL, new CCodeConstant("2"), new CCodeIdentifier(temp_name + "_size")); ccode.add_assignment(new CCodeIdentifier(temp_name + "_size"), new_size); var renew_call = new CCodeFunctionCall(new CCodeIdentifier("g_renew")); renew_call.add_argument(new CCodeIdentifier(get_ccode_name(array_type.element_type))); renew_call.add_argument(new CCodeIdentifier(temp_name)); // add one extra element for NULL-termination renew_call.add_argument(new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, new CCodeIdentifier(temp_name + "_size"), new CCodeConstant("1"))); ccode.add_assignment(new CCodeIdentifier(temp_name), renew_call); ccode.close(); var element_access = new CCodeElementAccess(new CCodeIdentifier(temp_name), new CCodeUnaryExpression(CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier(temp_name + "_length"))); bool may_fail; var element_expr = deserialize_expression(array_type.element_type, new CCodeIdentifier(element_name), null, out may_fail, null); ccode.add_assignment(element_access, element_expr); } var unref = new CCodeFunctionCall(new CCodeIdentifier("g_variant_unref")); unref.add_argument(new CCodeIdentifier(element_name)); ccode.add_expression(unref); ccode.close(); if (expr != null) { ccode.add_assignment(get_array_length(expr, dim), new CCodeIdentifier("%s_length%d".printf(temp_name, dim))); } }
public override void visit_foreach_statement(ForeachStatement stmt) { ccode.open_block(); var collection_backup = stmt.collection_variable; var collection_type = collection_backup.variable_type; var array_type = collection_type as ArrayType; if (array_type != null) { // avoid assignment issues array_type.inline_allocated = false; array_type.fixed_length = false; } visit_local_variable(collection_backup); ccode.add_assignment(get_variable_cexpression(get_local_cname(collection_backup)), get_cvalue(stmt.collection)); if (stmt.tree_can_fail && stmt.collection.tree_can_fail) { // exception handling add_simple_check(stmt.collection); } if (stmt.collection.value_type is ArrayType) { array_type = (ArrayType)stmt.collection.value_type; var array_len = get_array_length_cexpression(stmt.collection); // store array length for use by _vala_array_free ccode.add_assignment(get_variable_cexpression(get_array_length_cname(get_local_cname(collection_backup), 1)), array_len); var iterator_variable = new LocalVariable(int_type.copy(), stmt.variable_name + "_it"); visit_local_variable(iterator_variable); var it_name = get_local_cname(iterator_variable); var ccond = new CCodeBinaryExpression(CCodeBinaryOperator.LESS_THAN, get_variable_cexpression(it_name), array_len); ccode.open_for(new CCodeAssignment(get_variable_cexpression(it_name), new CCodeConstant("0")), ccond, new CCodeAssignment(get_variable_cexpression(it_name), new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, get_variable_cexpression(it_name), new CCodeConstant("1")))); CCodeExpression element_expr = new CCodeElementAccess(get_variable_cexpression(get_local_cname(collection_backup)), get_variable_cexpression(it_name)); var element_type = array_type.element_type.copy(); element_type.value_owned = false; element_expr = get_cvalue_(transform_value(new GLibValue(element_type, element_expr, true), stmt.type_reference, stmt)); visit_local_variable(stmt.element_variable); ccode.add_assignment(get_variable_cexpression(get_local_cname(stmt.element_variable)), element_expr); // set array length for stacked arrays if (stmt.type_reference is ArrayType) { var inner_array_type = (ArrayType)stmt.type_reference; for (int dim = 1; dim <= inner_array_type.rank; dim++) { ccode.add_assignment(get_variable_cexpression(get_array_length_cname(get_local_cname(stmt.element_variable), dim)), new CCodeConstant("-1")); } } stmt.body.emit(this); ccode.close(); } else if (stmt.collection.value_type.compatible(new ObjectType(glist_type)) || stmt.collection.value_type.compatible(new ObjectType(gslist_type))) { // iterating over a GList or GSList var iterator_variable = new LocalVariable(collection_type.copy(), stmt.variable_name + "_it"); visit_local_variable(iterator_variable); var it_name = get_local_cname(iterator_variable); var ccond = new CCodeBinaryExpression(CCodeBinaryOperator.INEQUALITY, get_variable_cexpression(it_name), new CCodeConstant("NULL")); ccode.open_for(new CCodeAssignment(get_variable_cexpression(it_name), get_variable_cexpression(get_local_cname(collection_backup))), ccond, new CCodeAssignment(get_variable_cexpression(it_name), CCodeMemberAccess.pointer(get_variable_cexpression(it_name), "next"))); CCodeExpression element_expr = CCodeMemberAccess.pointer(get_variable_cexpression(it_name), "data"); if (collection_type.get_type_arguments().Count != 1) { Report.error(stmt.source_reference, "internal error: missing generic type argument"); stmt.error = true; return; } var element_data_type = collection_type.get_type_arguments()[0].copy(); element_data_type.value_owned = false; element_expr = convert_from_generic_pointer(element_expr, element_data_type); element_expr = get_cvalue_(transform_value(new GLibValue(element_data_type, element_expr), stmt.type_reference, stmt)); visit_local_variable(stmt.element_variable); ccode.add_assignment(get_variable_cexpression(get_local_cname(stmt.element_variable)), element_expr); stmt.body.emit(this); ccode.close(); } else if (stmt.collection.value_type.compatible(new ObjectType(gvaluearray_type))) { // iterating over a GValueArray var iterator_variable = new LocalVariable(uint_type.copy(), "%s_index".printf(stmt.variable_name)); visit_local_variable(iterator_variable); var arr_index = get_variable_cname(get_local_cname(iterator_variable)); var ccond = new CCodeBinaryExpression(CCodeBinaryOperator.LESS_THAN, get_variable_cexpression(arr_index), CCodeMemberAccess.pointer(get_variable_cexpression(get_local_cname(collection_backup)), "n_values")); ccode.open_for(new CCodeAssignment(get_variable_cexpression(arr_index), new CCodeConstant("0")), ccond, new CCodeAssignment(get_variable_cexpression(arr_index), new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, get_variable_cexpression(arr_index), new CCodeConstant("1")))); var get_item = new CCodeFunctionCall(new CCodeIdentifier("g_value_array_get_nth")); get_item.add_argument(get_variable_cexpression(get_local_cname(collection_backup))); get_item.add_argument(get_variable_cexpression(arr_index)); CCodeExpression element_expr = new CCodeUnaryExpression(CCodeUnaryOperator.POINTER_INDIRECTION, get_item); if (stmt.type_reference.value_owned) { element_expr = get_cvalue_(copy_value(new GLibValue(stmt.type_reference, element_expr), new StructValueType(gvalue_type))); } visit_local_variable(stmt.element_variable); ccode.add_assignment(get_variable_cexpression(get_local_cname(stmt.element_variable)), element_expr); stmt.body.emit(this); ccode.close(); } foreach (LocalVariable local in stmt.get_local_variables()) { if (requires_destroy(local.variable_type)) { ccode.add_expression(destroy_local(local)); } } ccode.close(); }
string generate_array_add_wrapper(ArrayType array_type) { string add_func = "_vala_array_add%d".printf(++next_array_add_id); if (!add_wrapper(add_func)) { // wrapper already defined return(add_func); } var function = new CCodeFunction(add_func, "void"); function.modifiers = CCodeModifiers.STATIC; function.add_parameter(new CCodeParameter("array", "%s *".printf(get_ccode_name(array_type)))); function.add_parameter(new CCodeParameter("length", "int*")); function.add_parameter(new CCodeParameter("size", "int*")); push_function(function); string typename = get_ccode_name(array_type.element_type); CCodeExpression value = new CCodeIdentifier("value"); if (array_type.element_type.is_real_struct_type()) { if (!array_type.element_type.nullable || !array_type.element_type.value_owned) { typename = "const " + typename; } if (!array_type.element_type.nullable) { typename += "*"; value = new CCodeUnaryExpression(CCodeUnaryOperator.POINTER_INDIRECTION, value); } } function.add_parameter(new CCodeParameter("value", typename)); var array = new CCodeUnaryExpression(CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier("array")); var length = new CCodeUnaryExpression(CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier("length")); var size = new CCodeUnaryExpression(CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier("size")); var renew_call = new CCodeFunctionCall(new CCodeIdentifier("g_renew")); renew_call.add_argument(new CCodeIdentifier(get_ccode_name(array_type.element_type))); renew_call.add_argument(array); if (array_type.element_type.is_reference_type_or_type_parameter()) { // NULL terminate array renew_call.add_argument(new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, size, new CCodeConstant("1"))); } else { renew_call.add_argument(size); } var csizecheck = new CCodeBinaryExpression(CCodeBinaryOperator.EQUALITY, length, size); ccode.open_if(csizecheck); ccode.add_assignment(size, new CCodeConditionalExpression(size, new CCodeBinaryExpression(CCodeBinaryOperator.MUL, new CCodeConstant("2"), size), new CCodeConstant("4"))); ccode.add_assignment(array, renew_call); ccode.close(); ccode.add_assignment(new CCodeElementAccess(array, new CCodeUnaryExpression(CCodeUnaryOperator.POSTFIX_INCREMENT, length)), value); if (array_type.element_type.is_reference_type_or_type_parameter()) { // NULL terminate array ccode.add_assignment(new CCodeElementAccess(array, length), new CCodeConstant("NULL")); } pop_function(); cfile.add_function_declaration(function); cfile.add_function(function); return(add_func); }
string generate_array_dup_wrapper(ArrayType array_type) { string dup_func = "_vala_array_dup%d".printf(++next_array_dup_id); if (!add_wrapper(dup_func)) { // wrapper already defined return(dup_func); } // declaration var function = new CCodeFunction(dup_func, get_ccode_name(array_type)); function.modifiers = CCodeModifiers.STATIC; function.add_parameter(new CCodeParameter("self", get_ccode_name(array_type))); // total length over all dimensions function.add_parameter(new CCodeParameter("length", "int")); if (array_type.element_type is GenericType) { // dup function array elements string func_name = "%s_dup_func".printf(array_type.element_type.type_parameter.name.ToLower()); function.add_parameter(new CCodeParameter(func_name, "GBoxedCopyFunc")); } // definition push_context(new EmitContext()); push_function(function); if (requires_copy(array_type.element_type)) { var cvardecl = new CCodeVariableDeclarator("result"); var gnew = new CCodeFunctionCall(new CCodeIdentifier("g_new0")); gnew.add_argument(new CCodeIdentifier(get_ccode_name(array_type.element_type))); CCodeExpression length_expr = new CCodeIdentifier("length"); // add extra item to have array NULL-terminated for all reference types if (array_type.element_type.data_type != null && array_type.element_type.data_type.is_reference_type()) { length_expr = new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, length_expr, new CCodeConstant("1")); } gnew.add_argument(length_expr); ccode.add_declaration(get_ccode_name(array_type), cvardecl); ccode.add_assignment(new CCodeIdentifier("result"), gnew); ccode.add_declaration("int", new CCodeVariableDeclarator("i")); ccode.open_for(new CCodeAssignment(new CCodeIdentifier("i"), new CCodeConstant("0")), new CCodeBinaryExpression(CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier("i"), new CCodeIdentifier("length")), new CCodeUnaryExpression(CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier("i"))); ccode.add_assignment(new CCodeElementAccess(new CCodeIdentifier("result"), new CCodeIdentifier("i")), get_cvalue_(copy_value(new GLibValue(array_type.element_type, new CCodeElementAccess(new CCodeIdentifier("self"), new CCodeIdentifier("i")), true), array_type))); ccode.close(); ccode.add_return(new CCodeIdentifier("result")); } else { var dup_call = new CCodeFunctionCall(new CCodeIdentifier("g_memdup")); dup_call.add_argument(new CCodeIdentifier("self")); var sizeof_call = new CCodeFunctionCall(new CCodeIdentifier("sizeof")); sizeof_call.add_argument(new CCodeIdentifier(get_ccode_name(array_type.element_type))); dup_call.add_argument(new CCodeBinaryExpression(CCodeBinaryOperator.MUL, new CCodeIdentifier("length"), sizeof_call)); ccode.add_return(dup_call); } // append to file cfile.add_function_declaration(function); cfile.add_function(function); pop_context(); return(dup_func); }
public override void append_vala_array_move() { cfile.add_include("string.h"); // assumes that overwritten array elements are null before invocation // FIXME will leak memory if that's not the case var fun = new CCodeFunction("_vala_array_move", "void"); fun.modifiers = CCodeModifiers.STATIC; fun.add_parameter(new CCodeParameter("array", "gpointer")); fun.add_parameter(new CCodeParameter("element_size", "gsize")); fun.add_parameter(new CCodeParameter("src", "gint")); fun.add_parameter(new CCodeParameter("dest", "gint")); fun.add_parameter(new CCodeParameter("length", "gint")); push_function(fun); var array = new CCodeCastExpression(new CCodeIdentifier("array"), "char*"); var element_size = new CCodeIdentifier("element_size"); var length = new CCodeIdentifier("length"); var src = new CCodeIdentifier("src"); var src_end = new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, src, length); var dest = new CCodeIdentifier("dest"); var dest_end = new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, dest, length); var src_address = new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, array, new CCodeBinaryExpression(CCodeBinaryOperator.MUL, src, element_size)); var dest_address = new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, array, new CCodeBinaryExpression(CCodeBinaryOperator.MUL, dest, element_size)); var dest_end_address = new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, array, new CCodeBinaryExpression(CCodeBinaryOperator.MUL, dest_end, element_size)); var ccall = new CCodeFunctionCall(new CCodeIdentifier("g_memmove")); ccall.add_argument(dest_address); ccall.add_argument(src_address); ccall.add_argument(new CCodeBinaryExpression(CCodeBinaryOperator.MUL, length, element_size)); ccode.add_expression(ccall); ccode.open_if(new CCodeBinaryExpression(CCodeBinaryOperator.AND, new CCodeBinaryExpression(CCodeBinaryOperator.LESS_THAN, src, dest), new CCodeBinaryExpression(CCodeBinaryOperator.GREATER_THAN, src_end, dest))); var czero1 = new CCodeFunctionCall(new CCodeIdentifier("memset")); czero1.add_argument(src_address); czero1.add_argument(new CCodeConstant("0")); czero1.add_argument(new CCodeBinaryExpression(CCodeBinaryOperator.MUL, new CCodeBinaryExpression(CCodeBinaryOperator.MINUS, dest, src), element_size)); ccode.add_expression(czero1); ccode.else_if(new CCodeBinaryExpression(CCodeBinaryOperator.AND, new CCodeBinaryExpression(CCodeBinaryOperator.GREATER_THAN, src, dest), new CCodeBinaryExpression(CCodeBinaryOperator.LESS_THAN, src, dest_end))); var czero2 = new CCodeFunctionCall(new CCodeIdentifier("memset")); czero2.add_argument(dest_end_address); czero2.add_argument(new CCodeConstant("0")); czero2.add_argument(new CCodeBinaryExpression(CCodeBinaryOperator.MUL, new CCodeBinaryExpression(CCodeBinaryOperator.MINUS, src, dest), element_size)); ccode.add_expression(czero2); ccode.else_if(new CCodeBinaryExpression(CCodeBinaryOperator.INEQUALITY, src, dest)); var czero3 = new CCodeFunctionCall(new CCodeIdentifier("memset")); czero3.add_argument(src_address); czero3.add_argument(new CCodeConstant("0")); czero3.add_argument(new CCodeBinaryExpression(CCodeBinaryOperator.MUL, length, element_size)); ccode.add_expression(czero3); ccode.close(); pop_function(); cfile.add_function_declaration(fun); cfile.add_function(fun); }
public override void visit_array_creation_expression(ArrayCreationExpression expr) { var array_type = expr.target_type as ArrayType; LocalVariable temp_var; CCodeExpression name_cnode; int i; if (array_type != null && array_type.fixed_length) { // no heap allocation for fixed-length arrays temp_var = get_temp_variable(array_type, true, expr); name_cnode = get_variable_cexpression(temp_var.name); i = 0; emit_temp_var(temp_var); append_initializer_list(name_cnode, expr.initializer_list, expr.rank, ref i); set_cvalue(expr, name_cnode); return; } var gnew = new CCodeFunctionCall(new CCodeIdentifier("g_new0")); gnew.add_argument(new CCodeIdentifier(get_ccode_name(expr.element_type))); bool first = true; CCodeExpression cexpr = null; // iterate over each dimension foreach (Expression size in expr.get_sizes()) { CCodeExpression csize = get_cvalue(size); append_array_length(expr, csize); if (first) { cexpr = csize; first = false; } else { cexpr = new CCodeBinaryExpression(CCodeBinaryOperator.MUL, cexpr, csize); } } // add extra item to have array NULL-terminated for all reference types if (expr.element_type.data_type != null && expr.element_type.data_type.is_reference_type()) { cexpr = new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, cexpr, new CCodeConstant("1")); } gnew.add_argument(cexpr); temp_var = get_temp_variable(expr.value_type, true, expr); name_cnode = get_variable_cexpression(temp_var.name); i = 0; emit_temp_var(temp_var); ccode.add_assignment(name_cnode, gnew); if (expr.initializer_list != null) { append_initializer_list(name_cnode, expr.initializer_list, expr.rank, ref i); } set_cvalue(expr, name_cnode); }
void visit_string_switch_statement(SwitchStatement stmt) { // we need a temporary variable to save the property value var temp_value = create_temp_value(stmt.expression.value_type, false, stmt); var ctemp = get_cvalue_(temp_value); var cinit = new CCodeAssignment(ctemp, get_cvalue(stmt.expression)); var czero = new CCodeConstant("0"); var free_call = new CCodeFunctionCall(new CCodeIdentifier("g_free")); free_call.add_argument(ctemp); var cisnull = new CCodeBinaryExpression(CCodeBinaryOperator.EQUALITY, new CCodeConstant("NULL"), ctemp); var cquark = new CCodeFunctionCall(new CCodeIdentifier("g_quark_from_string")); cquark.add_argument(ctemp); var ccond = new CCodeConditionalExpression(cisnull, new CCodeConstant("0"), cquark); int label_temp_id = next_temp_var_id++; temp_value = create_temp_value(gquark_type, true, stmt); int label_count = 0; foreach (SwitchSection section in stmt.get_sections()) { if (section.has_default_label()) { continue; } foreach (SwitchLabel label in section.get_labels()) { label.expression.emit(this); var cexpr = get_cvalue(label.expression); if (is_constant_ccode_expression(cexpr)) { var cname = "_tmp%d_label%d".printf(label_temp_id, label_count++); ccode.add_declaration(get_ccode_name(gquark_type), new CCodeVariableDeclarator(cname, czero), CCodeModifiers.STATIC); } } } ccode.add_expression(cinit); ctemp = get_cvalue_(temp_value); cinit = new CCodeAssignment(ctemp, ccond); ccode.add_expression(cinit); if (stmt.expression.value_type.value_owned) { // free owned string ccode.add_expression(free_call); } SwitchSection default_section = null; label_count = 0; int n = 0; foreach (SwitchSection section in stmt.get_sections()) { if (section.has_default_label()) { default_section = section; continue; } CCodeBinaryExpression cor = null; foreach (SwitchLabel label in section.get_labels()) { label.expression.emit(this); var cexpr = get_cvalue(label.expression); if (is_constant_ccode_expression(cexpr)) { var cname = new CCodeIdentifier("_tmp%d_label%d".printf(label_temp_id, label_count++)); var ccondition = new CCodeBinaryExpression(CCodeBinaryOperator.INEQUALITY, czero, cname); var ccall = new CCodeFunctionCall(new CCodeIdentifier("g_quark_from_static_string")); cinit = new CCodeAssignment(cname, ccall); ccall.add_argument(cexpr); cexpr = new CCodeConditionalExpression(ccondition, cname, cinit); } else { var ccall = new CCodeFunctionCall(new CCodeIdentifier("g_quark_from_string")); ccall.add_argument(cexpr); cexpr = ccall; } var ccmp = new CCodeBinaryExpression(CCodeBinaryOperator.EQUALITY, ctemp, cexpr); if (cor == null) { cor = ccmp; } else { cor = new CCodeBinaryExpression(CCodeBinaryOperator.OR, cor, ccmp); } } if (n > 0) { ccode.else_if(cor); } else { ccode.open_if(cor); } ccode.open_switch(new CCodeConstant("0")); ccode.add_default(); section.emit(this); ccode.close(); n++; } if (default_section != null) { if (n > 0) { ccode.add_else(); } ccode.open_switch(new CCodeConstant("0")); ccode.add_default(); default_section.emit(this); ccode.close(); } if (n > 0) { ccode.close(); } }
void generate_async_function(Method m) { push_context(new EmitContext()); string callback_wrapper = null; if (!context.require_glib_version(2, 44)) { callback_wrapper = get_ccode_real_name(m) + "_async_ready_wrapper"; generate_async_ready_callback_wrapper(m, callback_wrapper); } var dataname = Symbol.lower_case_to_camel_case(get_ccode_name(m)) + "Data"; var asyncfunc = new CCodeFunction(get_ccode_real_name(m), "void"); var cparam_map = new Dictionary <int, CCodeParameter>(); cparam_map[get_param_pos(-1)] = new CCodeParameter("_callback_", "GAsyncReadyCallback"); cparam_map[get_param_pos(-0.9)] = new CCodeParameter("_user_data_", "gpointer"); generate_cparameters(m, cfile, cparam_map, asyncfunc, null, null, null, 1); if (m.base_method != null || m.base_interface_method != null) { // declare *_real_* function asyncfunc.modifiers |= CCodeModifiers.STATIC; cfile.add_function_declaration(asyncfunc); } else if (m.is_private_symbol()) { asyncfunc.modifiers |= CCodeModifiers.STATIC; } else if (context.hide_internal && m.is_internal_symbol()) { asyncfunc.modifiers |= CCodeModifiers.INTERNAL; } push_function(asyncfunc); // logic copied from valaccodemethodmodule if (m.overrides || (m.base_interface_method != null && !m.is_abstract && !m.is_virtual)) { Method base_method; if (m.overrides) { base_method = m.base_method; } else { base_method = m.base_interface_method; } var base_expression_type = new ObjectType((ObjectTypeSymbol)base_method.parent_symbol); var type_symbol = m.parent_symbol as ObjectTypeSymbol; var self_target_type = new ObjectType(type_symbol); var cself = get_cvalue_(transform_value(new GLibValue(base_expression_type, new CCodeIdentifier("base"), true), self_target_type, m)); ccode.add_declaration("%s *".printf(get_ccode_name(type_symbol)), new CCodeVariableDeclarator("self")); ccode.add_assignment(new CCodeIdentifier("self"), cself); } var dataalloc = new CCodeFunctionCall(new CCodeIdentifier("g_slice_new0")); dataalloc.add_argument(new CCodeIdentifier(dataname)); var data_var = new CCodeIdentifier("_data_"); ccode.add_declaration(dataname + "*", new CCodeVariableDeclarator("_data_")); ccode.add_assignment(data_var, dataalloc); if (!context.require_glib_version(2, 44)) { ccode.add_assignment(CCodeMemberAccess.pointer(data_var, "_callback_"), new CCodeConstant("_callback_")); } var create_result = new CCodeFunctionCall(new CCodeIdentifier("g_task_new")); var t = m.parent_symbol as TypeSymbol; if (!(m is CreationMethod) && m.binding == MemberBinding.INSTANCE && t != null && t.is_subtype_of(gobject_type)) { var gobject_cast = new CCodeFunctionCall(new CCodeIdentifier("G_OBJECT")); gobject_cast.add_argument(new CCodeIdentifier("self")); create_result.add_argument(gobject_cast); } else { create_result.add_argument(new CCodeConstant("NULL")); } Parameter cancellable_param = null; foreach (Parameter param in m.get_parameters()) { if (param.variable_type is ObjectType && param.variable_type.data_type.get_full_name() == "GLib.Cancellable") { cancellable_param = param; break; } } if (cancellable_param == null) { create_result.add_argument(new CCodeConstant("NULL")); } else { create_result.add_argument(new CCodeIdentifier(get_variable_cname(cancellable_param.name))); } if (context.require_glib_version(2, 44)) { create_result.add_argument(new CCodeIdentifier("_callback_")); } else { create_result.add_argument(new CCodeIdentifier(callback_wrapper)); } create_result.add_argument(new CCodeIdentifier("_user_data_")); ccode.add_assignment(CCodeMemberAccess.pointer(data_var, "_async_result"), create_result); if (!context.require_glib_version(2, 44)) { var task_completed_var = CCodeMemberAccess.pointer(data_var, "_task_complete_"); var callback = new CCodeIdentifier("_callback_"); var callback_is_null = new CCodeBinaryExpression(CCodeBinaryOperator.EQUALITY, callback, new CCodeConstant("NULL")); ccode.open_if(callback_is_null); ccode.add_assignment(task_completed_var, new CCodeConstant("TRUE")); ccode.close(); } var attach_data_call = new CCodeFunctionCall(new CCodeIdentifier("g_task_set_task_data")); attach_data_call.add_argument(CCodeMemberAccess.pointer(data_var, "_async_result")); attach_data_call.add_argument(data_var); attach_data_call.add_argument(new CCodeIdentifier(get_ccode_real_name(m) + "_data_free")); ccode.add_expression(attach_data_call); if (m is CreationMethod) { ccode.add_assignment(CCodeMemberAccess.pointer(data_var, "object_type"), new CCodeIdentifier("object_type")); } else if (m.binding == MemberBinding.INSTANCE) { var this_type = m.this_parameter.variable_type.copy(); this_type.value_owned = true; // create copy if necessary as variables in async methods may need to be kept alive CCodeExpression cself = new CCodeIdentifier("self"); if (this_type.is_real_non_null_struct_type()) { cself = new CCodeUnaryExpression(CCodeUnaryOperator.POINTER_INDIRECTION, cself); } if (requires_copy(this_type)) { cself = get_cvalue_(copy_value(new GLibValue(m.this_parameter.variable_type, cself, true), m.this_parameter)); } ccode.add_assignment(CCodeMemberAccess.pointer(data_var, "self"), cself); } emit_context.push_symbol(m); foreach (Parameter param in m.get_parameters()) { if (param.direction != ParameterDirection.OUT) { // create copy if necessary as variables in async methods may need to be kept alive var old_captured = param.captured; param.captured = false; current_method.coroutine = false; TargetValue value; if (param.variable_type.value_owned) { // do not use load_parameter for reference/ownership transfer // otherwise delegate destroy notify will not be moved value = get_parameter_cvalue(param); } else { value = load_parameter(param); } current_method.coroutine = true; store_parameter(param, value); param.captured = old_captured; } } emit_context.pop_symbol(); foreach (var type_param in m.get_type_parameters()) { var type = "%s_type".printf(type_param.name.ToLower()); var dup_func = "%s_dup_func".printf(type_param.name.ToLower()); var destroy_func = "%s_destroy_func".printf(type_param.name.ToLower()); ccode.add_assignment(CCodeMemberAccess.pointer(data_var, type), new CCodeIdentifier(type)); ccode.add_assignment(CCodeMemberAccess.pointer(data_var, dup_func), new CCodeIdentifier(dup_func)); ccode.add_assignment(CCodeMemberAccess.pointer(data_var, destroy_func), new CCodeIdentifier(destroy_func)); } var ccall = new CCodeFunctionCall(new CCodeIdentifier(get_ccode_real_name(m) + "_co")); ccall.add_argument(data_var); ccode.add_expression(ccall); cfile.add_function(asyncfunc); pop_context(); }
public override void store_value(TargetValue lvalue, TargetValue value, SourceReference source_reference = null) { var array_type = lvalue.value_type as ArrayType; if (array_type != null && array_type.fixed_length) { cfile.add_include("string.h"); // it is necessary to use memcpy for fixed-length (stack-allocated) arrays // simple assignments do not work in C var sizeof_call = new CCodeFunctionCall(new CCodeIdentifier("sizeof")); sizeof_call.add_argument(new CCodeIdentifier(get_ccode_name(array_type.element_type))); var size = new CCodeBinaryExpression(CCodeBinaryOperator.MUL, get_ccodenode(array_type.length), sizeof_call); var ccopy = new CCodeFunctionCall(new CCodeIdentifier("memcpy")); ccopy.add_argument(get_cvalue_(lvalue)); ccopy.add_argument(get_cvalue_(value)); ccopy.add_argument(size); ccode.add_expression(ccopy); return; } var cexpr = get_cvalue_(value); if (get_ctype(lvalue) != null) { cexpr = new CCodeCastExpression(cexpr, get_ctype(lvalue)); } /* * If this is a SimpleType struct being passed by value * and the user specified a custom user function * use the specified function instead to do assignments rather than dest = source */ var st_left = lvalue.value_type.data_type as Struct; var st_right = value.value_type.data_type as Struct; if ( st_left != null && st_right != null && lvalue.value_type.compatible(value.value_type) && st_left.is_simple_type() && lvalue.value_type is StructValueType && st_left.has_attribute_argument("CCode", "copy_function") ) { //copy_function (src, dest) var copy_call = new CCodeFunctionCall(new CCodeIdentifier(get_ccode_copy_function(st_left))); copy_call.add_argument(get_cvalue_(value)); copy_call.add_argument(get_cvalue_(lvalue)); ccode.add_expression(copy_call); return; } ccode.add_assignment(get_cvalue_(lvalue), cexpr); if (array_type != null && ((GLibValue)lvalue).array_length_cvalues != null) { var glib_value = (GLibValue)value; if (glib_value.array_length_cvalues != null) { for (int dim = 1; dim <= array_type.rank; dim++) { ccode.add_assignment(get_array_length_cvalue(lvalue, dim), get_array_length_cvalue(value, dim)); } } else if (glib_value.array_null_terminated) { requires_array_length = true; var len_call = new CCodeFunctionCall(new CCodeIdentifier("_vala_array_length")); len_call.add_argument(get_cvalue_(value)); ccode.add_assignment(get_array_length_cvalue(lvalue, 1), len_call); } else { for (int dim = 1; dim <= array_type.rank; dim++) { ccode.add_assignment(get_array_length_cvalue(lvalue, dim), new CCodeConstant("-1")); } } if (array_type.rank == 1 && get_array_size_cvalue(lvalue) != null) { ccode.add_assignment(get_array_size_cvalue(lvalue), get_array_length_cvalue(lvalue, 1)); } } var delegate_type = lvalue.value_type as DelegateType; if (delegate_type != null && delegate_type.delegate_symbol.has_target) { var lvalue_target = get_delegate_target_cvalue(lvalue); var rvalue_target = get_delegate_target_cvalue(value); if (lvalue_target != null) { if (rvalue_target != null) { ccode.add_assignment(lvalue_target, rvalue_target); } else { Report.error(source_reference, "Assigning delegate without required target in scope"); ccode.add_assignment(lvalue_target, new CCodeInvalidExpression()); } var lvalue_destroy_notify = get_delegate_target_destroy_notify_cvalue(lvalue); var rvalue_destroy_notify = get_delegate_target_destroy_notify_cvalue(value); if (lvalue_destroy_notify != null) { if (rvalue_destroy_notify != null) { ccode.add_assignment(lvalue_destroy_notify, rvalue_destroy_notify); } else { ccode.add_assignment(lvalue_destroy_notify, new CCodeConstant("NULL")); } } } } }
private void add_set_property_function(Class cl) { var set_prop = new CCodeFunction("_vala_%s_set_property".printf(get_ccode_lower_case_name(cl, null)), "void"); set_prop.modifiers = CCodeModifiers.STATIC; set_prop.add_parameter(new CCodeParameter("object", "GObject *")); set_prop.add_parameter(new CCodeParameter("property_id", "guint")); set_prop.add_parameter(new CCodeParameter("value", "const GValue *")); set_prop.add_parameter(new CCodeParameter("pspec", "GParamSpec *")); push_function(set_prop); CCodeFunctionCall ccall = generate_instance_cast(new CCodeIdentifier("object"), cl); ccode.add_declaration("%s *".printf(get_ccode_name(cl)), new CCodeVariableDeclarator("self", ccall)); ccode.open_switch(new CCodeIdentifier("property_id")); var props = cl.get_properties(); foreach (Property prop in props) { if (prop.set_accessor == null || prop.is_abstract) { continue; } if (!is_gobject_property(prop)) { continue; } Property base_prop = prop; CCodeExpression cself = new CCodeIdentifier("self"); if (prop.base_property != null) { var base_type = (Class)prop.base_property.parent_symbol; base_prop = prop.base_property; cself = get_cvalue_(transform_value(new GLibValue(new ObjectType(cl), cself, true), new ObjectType(base_type), prop)); generate_property_accessor_declaration(prop.base_property.set_accessor, cfile); } else if (prop.base_interface_property != null) { var base_type = (Interface)prop.base_interface_property.parent_symbol; base_prop = prop.base_interface_property; cself = get_cvalue_(transform_value(new GLibValue(new ObjectType(cl), cself, true), new ObjectType(base_type), prop)); generate_property_accessor_declaration(prop.base_interface_property.set_accessor, cfile); } CCodeExpression cfunc; if (!get_ccode_no_accessor_method(base_prop) && !get_ccode_concrete_accessor(base_prop)) { cfunc = new CCodeIdentifier(get_ccode_name(base_prop.set_accessor)); } else { // use the static real function as helper cfunc = new CCodeIdentifier(get_ccode_real_name(prop.set_accessor)); } ccode.add_case(new CCodeIdentifier(get_ccode_upper_case_name(prop))); ccall = new CCodeFunctionCall(cfunc); ccall.add_argument(cself); if (prop.property_type is ArrayType && ((ArrayType)prop.property_type).element_type.data_type == string_type.data_type) { ccode.open_block(); ccode.add_declaration("gpointer", new CCodeVariableDeclarator("boxed")); var cgetcall = new CCodeFunctionCall(new CCodeIdentifier("g_value_get_boxed")); cgetcall.add_argument(new CCodeIdentifier("value")); ccode.add_assignment(new CCodeIdentifier("boxed"), cgetcall); ccall.add_argument(new CCodeIdentifier("boxed")); var cisnull = new CCodeBinaryExpression(CCodeBinaryOperator.EQUALITY, new CCodeIdentifier("boxed"), new CCodeConstant("NULL")); var cstrvlen = new CCodeFunctionCall(new CCodeIdentifier("g_strv_length")); cstrvlen.add_argument(new CCodeIdentifier("boxed")); var ccond = new CCodeConditionalExpression(cisnull, new CCodeConstant("0"), cstrvlen); ccall.add_argument(ccond); add_guarded_expression(prop, ccall); ccode.close(); } else { var cgetcall = new CCodeFunctionCall(); if (prop.property_type.data_type != null) { cgetcall.call = new CCodeIdentifier(get_ccode_get_value_function(prop.property_type.data_type)); } else { cgetcall.call = new CCodeIdentifier("g_value_get_pointer"); } cgetcall.add_argument(new CCodeIdentifier("value")); ccall.add_argument(cgetcall); add_guarded_expression(prop, ccall); } ccode.add_break(); } /* type, dup func, and destroy func properties for generic types */ foreach (TypeParameter type_param in cl.get_type_parameters()) { string func_name, enum_value; CCodeMemberAccess cfield; CCodeFunctionCall cgetcall; func_name = "%s_type".printf(type_param.name.ToLower()); enum_value = "%s_%s".printf(get_ccode_lower_case_name(cl, null), func_name).ToUpper(); ccode.add_case(new CCodeIdentifier(enum_value)); cfield = CCodeMemberAccess.pointer(CCodeMemberAccess.pointer(new CCodeIdentifier("self"), "priv"), func_name); cgetcall = new CCodeFunctionCall(new CCodeIdentifier("g_value_get_gtype")); cgetcall.add_argument(new CCodeIdentifier("value")); ccode.add_assignment(cfield, cgetcall); ccode.add_break(); func_name = "%s_dup_func".printf(type_param.name.ToLower()); enum_value = "%s_%s".printf(get_ccode_lower_case_name(cl, null), func_name).ToUpper(); ccode.add_case(new CCodeIdentifier(enum_value)); cfield = CCodeMemberAccess.pointer(CCodeMemberAccess.pointer(new CCodeIdentifier("self"), "priv"), func_name); cgetcall = new CCodeFunctionCall(new CCodeIdentifier("g_value_get_pointer")); cgetcall.add_argument(new CCodeIdentifier("value")); ccode.add_assignment(cfield, cgetcall); ccode.add_break(); func_name = "%s_destroy_func".printf(type_param.name.ToLower()); enum_value = "%s_%s".printf(get_ccode_lower_case_name(cl, null), func_name).ToUpper(); ccode.add_case(new CCodeIdentifier(enum_value)); cfield = CCodeMemberAccess.pointer(CCodeMemberAccess.pointer(new CCodeIdentifier("self"), "priv"), func_name); cgetcall = new CCodeFunctionCall(new CCodeIdentifier("g_value_get_pointer")); cgetcall.add_argument(new CCodeIdentifier("value")); ccode.add_assignment(cfield, cgetcall); ccode.add_break(); } ccode.add_default(); emit_invalid_property_id_warn(); ccode.add_break(); ccode.close(); pop_function(); cfile.add_function_declaration(set_prop); cfile.add_function(set_prop); }