/// <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 string generate_delegate_wrapper(Method m, DelegateType dt, CodeNode node) { var d = dt.delegate_symbol; string delegate_name; var sig = d.parent_symbol as Signal; var dynamic_sig = sig as DynamicSignal; if (dynamic_sig != null) { delegate_name = get_dynamic_signal_cname(dynamic_sig); } else if (sig != null) { delegate_name = get_ccode_lower_case_prefix(sig.parent_symbol) + get_ccode_lower_case_name(sig); } else { delegate_name = Symbol.camel_case_to_lower_case(get_ccode_name(d)); } string wrapper_name = "_%s_%s".printf(get_ccode_name(m), delegate_name); if (!add_wrapper(wrapper_name)) { // wrapper already defined return(wrapper_name); } // declaration string return_type_cname = get_ccode_name(d.return_type); if (d.return_type.is_real_non_null_struct_type()) { // structs are returned via out parameter return_type_cname = "void"; } var function = new CCodeFunction(wrapper_name, return_type_cname); function.modifiers = CCodeModifiers.STATIC; push_function(function); var cparam_map = new Dictionary <int, CCodeParameter>(); if (d.has_target) { var cparam = new CCodeParameter("self", "gpointer"); cparam_map[get_param_pos(get_ccode_instance_pos(d))] = cparam; } if (d.sender_type != null) { var param = new Parameter("_sender", d.sender_type); generate_parameter(param, cfile, cparam_map, null); } var d_params = d.get_parameters(); foreach (Parameter param in d_params) { if (dynamic_sig != null && param.variable_type is ArrayType && ((ArrayType)param.variable_type).element_type.data_type == string_type.data_type) { // use null-terminated string arrays for dynamic signals for compatibility reasons param.set_attribute_bool("CCode", "array_length", false); param.set_attribute_bool("CCode", "array_null_terminated", true); } generate_parameter(param, cfile, cparam_map, null); } if (get_ccode_array_length(d) && d.return_type is ArrayType) { // return array length if appropriate var array_type = (ArrayType)d.return_type; var array_length_type = get_ccode_array_length_type(d) != null?get_ccode_array_length_type(d) : "int"; array_length_type += "*"; for (int dim = 1; dim <= array_type.rank; dim++) { var cparam = new CCodeParameter(get_array_length_cname("result", dim), array_length_type); cparam_map[get_param_pos(get_ccode_array_length_pos(d) + 0.01 * dim)] = cparam; } } else if (d.return_type is DelegateType) { // return delegate target if appropriate var deleg_type = (DelegateType)d.return_type; if (deleg_type.delegate_symbol.has_target) { var cparam = new CCodeParameter(get_delegate_target_cname("result"), "void**"); cparam_map[get_param_pos(get_ccode_delegate_target_pos(d))] = cparam; if (deleg_type.is_disposable()) { cparam = new CCodeParameter(get_delegate_target_destroy_notify_cname("result"), "GDestroyNotify*"); cparam_map[get_param_pos(get_ccode_delegate_target_pos(d) + 0.01)] = cparam; } } } else if (d.return_type.is_real_non_null_struct_type()) { var cparam = new CCodeParameter("result", "%s*".printf(get_ccode_name(d.return_type))); cparam_map[get_param_pos(-3)] = cparam; } if (m.get_error_types().Count > 0) { var cparam = new CCodeParameter("error", "GError**"); cparam_map[get_param_pos(-1)] = cparam; } // append C parameters in the right order int last_pos = -1; int min_pos; while (true) { min_pos = -1; foreach (int pos in cparam_map.Keys) { if (pos > last_pos && (min_pos == -1 || pos < min_pos)) { min_pos = pos; } } if (min_pos == -1) { break; } function.add_parameter(cparam_map[min_pos]); last_pos = min_pos; } // definition var carg_map = new Dictionary <int, CCodeExpression>(); int i = 0; if (m.binding == MemberBinding.INSTANCE || m.closure) { CCodeExpression arg; if (d.has_target) { arg = new CCodeIdentifier("self"); if (!m.closure && m.this_parameter != null) { arg = convert_from_generic_pointer(arg, m.this_parameter.variable_type); } } else { // use first delegate parameter as instance if (d_params.Count == 0 || m.closure) { Report.error(node != null ? node.source_reference : null, "Cannot create delegate without target for instance method or closure"); arg = new CCodeConstant("NULL"); } else { arg = new CCodeIdentifier(get_variable_cname(d_params[0].name)); i = 1; } } carg_map[get_param_pos(get_ccode_instance_pos(m))] = arg; } bool first = true; foreach (Parameter param in m.get_parameters()) { if (first && d.sender_type != null && m.get_parameters().Count == d.get_parameters().Count + 1) { // sender parameter carg_map[get_param_pos(get_ccode_pos(param))] = new CCodeIdentifier("_sender"); first = false; continue; } CCodeExpression arg; arg = new CCodeIdentifier(get_variable_cname(d_params[i].name)); if (d_params[i].variable_type is GenericType) { arg = convert_from_generic_pointer(arg, param.variable_type); } carg_map[get_param_pos(get_ccode_pos(param))] = arg; // handle array arguments if (get_ccode_array_length(param) && param.variable_type is ArrayType) { var array_type = (ArrayType)param.variable_type; for (int dim = 1; dim <= array_type.rank; dim++) { CCodeExpression clength; if (get_ccode_array_null_terminated(d_params[i])) { requires_array_length = true; var len_call = new CCodeFunctionCall(new CCodeIdentifier("_vala_array_length")); len_call.add_argument(new CCodeIdentifier(d_params[i].name)); clength = len_call; } else if (!get_ccode_array_length(d_params[i])) { clength = new CCodeConstant("-1"); } else { clength = new CCodeIdentifier(get_parameter_array_length_cname(d_params[i], dim)); } carg_map[get_param_pos(get_ccode_array_length_pos(param) + 0.01 * dim)] = clength; } } else if (param.variable_type is DelegateType) { var deleg_type = (DelegateType)param.variable_type; if (deleg_type.delegate_symbol.has_target) { var ctarget = new CCodeIdentifier(get_ccode_delegate_target_name(d_params[i])); carg_map[get_param_pos(get_ccode_delegate_target_pos(param))] = ctarget; if (deleg_type.is_disposable()) { var ctarget_destroy_notify = new CCodeIdentifier(get_delegate_target_destroy_notify_cname(d_params[i].name)); carg_map[get_param_pos(get_ccode_delegate_target_pos(m) + 0.01)] = ctarget_destroy_notify; } } } i++; } if (get_ccode_array_length(m) && m.return_type is ArrayType) { var array_type = (ArrayType)m.return_type; for (int dim = 1; dim <= array_type.rank; dim++) { CCodeExpression clength; if (!get_ccode_array_length(d)) { clength = new CCodeConstant("NULL"); } else { clength = new CCodeIdentifier(get_array_length_cname("result", dim)); } carg_map[get_param_pos(get_ccode_array_length_pos(m) + 0.01 * dim)] = clength; } } else if (m.return_type is DelegateType) { var deleg_type = (DelegateType)m.return_type; if (deleg_type.delegate_symbol.has_target) { var ctarget = new CCodeIdentifier(get_delegate_target_cname("result")); carg_map[get_param_pos(get_ccode_delegate_target_pos(m))] = ctarget; if (deleg_type.is_disposable()) { var ctarget_destroy_notify = new CCodeIdentifier(get_delegate_target_destroy_notify_cname("result")); carg_map[get_param_pos(get_ccode_delegate_target_pos(m) + 0.01)] = ctarget_destroy_notify; } } } else if (m.return_type.is_real_non_null_struct_type()) { carg_map[get_param_pos(-3)] = new CCodeIdentifier("result"); } if (m.get_error_types().Count > 0) { carg_map[get_param_pos(-1)] = new CCodeIdentifier("error"); } var ccall = new CCodeFunctionCall(new CCodeIdentifier(get_ccode_name(m))); // append C arguments in the right order last_pos = -1; while (true) { min_pos = -1; foreach (int pos in carg_map.Keys) { if (pos > last_pos && (min_pos == -1 || pos < min_pos)) { min_pos = pos; } } if (min_pos == -1) { break; } ccall.add_argument(carg_map[min_pos]); last_pos = min_pos; } if (m.coroutine) { ccall.add_argument(new CCodeConstant("NULL")); ccall.add_argument(new CCodeConstant("NULL")); } if (m.return_type is VoidType || m.return_type.is_real_non_null_struct_type()) { ccode.add_expression(ccall); if (!(d.return_type is VoidType || d.return_type.is_real_non_null_struct_type())) { // return a default value ccode.add_declaration(return_type_cname, new CCodeVariableDeclarator("result", default_value_for_type(d.return_type, true))); } } else { CCodeExpression result = ccall; if (d.return_type is GenericType) { result = convert_to_generic_pointer(result, m.return_type); } ccode.add_declaration(return_type_cname, new CCodeVariableDeclarator("result", result)); } if (d.has_target /* TODO: && dt.value_owned */ && dt.is_called_once) { // destroy notify "self" after the call CCodeExpression destroy_notify = null; if (m.closure) { int block_id = get_block_id(current_closure_block); destroy_notify = new CCodeIdentifier("block%d_data_unref".printf(block_id)); } else if (get_this_type() != null && m.binding != MemberBinding.STATIC && !m.is_async_callback && is_reference_counting(m.this_parameter.variable_type.data_type)) { destroy_notify = get_destroy_func_expression(m.this_parameter.variable_type); } if (destroy_notify != null) { var unref_call = new CCodeFunctionCall(destroy_notify); unref_call.add_argument(new CCodeIdentifier("self")); ccode.add_expression(unref_call); } } if (!(m.return_type is VoidType || m.return_type.is_real_non_null_struct_type()) || !(d.return_type is VoidType || d.return_type.is_real_non_null_struct_type())) { ccode.add_return(new CCodeIdentifier("result")); } pop_function(); // append to file cfile.add_function_declaration(function); cfile.add_function(function); return(wrapper_name); }
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(); } }
public override void generate_class_init(Class cl) { if (!cl.is_subtype_of(gobject_type)) { return; } /* set property handlers */ var ccall = new CCodeFunctionCall(new CCodeIdentifier("G_OBJECT_CLASS")); ccall.add_argument(new CCodeIdentifier("klass")); if (class_has_readable_properties(cl) || cl.get_type_parameters().Count > 0) { ccode.add_assignment(CCodeMemberAccess.pointer(ccall, "get_property"), new CCodeIdentifier("_vala_%s_get_property".printf(get_ccode_lower_case_name(cl, null)))); } if (class_has_writable_properties(cl) || cl.get_type_parameters().Count > 0) { ccode.add_assignment(CCodeMemberAccess.pointer(ccall, "set_property"), new CCodeIdentifier("_vala_%s_set_property".printf(get_ccode_lower_case_name(cl, null)))); } /* set constructor */ if (cl.constructor != null) { var ccast = new CCodeFunctionCall(new CCodeIdentifier("G_OBJECT_CLASS")); ccast.add_argument(new CCodeIdentifier("klass")); ccode.add_assignment(CCodeMemberAccess.pointer(ccast, "constructor"), new CCodeIdentifier("%s_constructor".printf(get_ccode_lower_case_name(cl, null)))); } /* set finalize function */ if (cl.get_fields().Count > 0 || cl.destructor != null) { var ccast = new CCodeFunctionCall(new CCodeIdentifier("G_OBJECT_CLASS")); ccast.add_argument(new CCodeIdentifier("klass")); ccode.add_assignment(CCodeMemberAccess.pointer(ccast, "finalize"), new CCodeIdentifier("%s_finalize".printf(get_ccode_lower_case_name(cl, null)))); } /* create type, dup_func, and destroy_func properties for generic types */ foreach (TypeParameter type_param in cl.get_type_parameters()) { string func_name, enum_value; CCodeConstant func_name_constant; CCodeFunctionCall cinst, cspec; var name_prefix = type_param.name.ToLower(); var canonical_prefix = name_prefix.Replace("_", "-"); func_name = "%s_type".printf(name_prefix); func_name_constant = new CCodeConstant("\"%s-type\"".printf(canonical_prefix)); enum_value = "%s_%s".printf(get_ccode_lower_case_name(cl, null), func_name).ToUpper(); cinst = new CCodeFunctionCall(new CCodeIdentifier("g_object_class_install_property")); cinst.add_argument(ccall); cinst.add_argument(new CCodeConstant(enum_value)); cspec = new CCodeFunctionCall(new CCodeIdentifier("g_param_spec_gtype")); cspec.add_argument(func_name_constant); cspec.add_argument(new CCodeConstant("\"type\"")); cspec.add_argument(new CCodeConstant("\"type\"")); cspec.add_argument(new CCodeIdentifier("G_TYPE_NONE")); cspec.add_argument(new CCodeConstant("G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY")); cinst.add_argument(cspec); ccode.add_expression(cinst); prop_enum.add_value(new CCodeEnumValue(enum_value)); func_name = "%s_dup_func".printf(name_prefix); func_name_constant = new CCodeConstant("\"%s-dup-func\"".printf(canonical_prefix)); enum_value = "%s_%s".printf(get_ccode_lower_case_name(cl, null), func_name).ToUpper(); cinst = new CCodeFunctionCall(new CCodeIdentifier("g_object_class_install_property")); cinst.add_argument(ccall); cinst.add_argument(new CCodeConstant(enum_value)); cspec = new CCodeFunctionCall(new CCodeIdentifier("g_param_spec_pointer")); cspec.add_argument(func_name_constant); cspec.add_argument(new CCodeConstant("\"dup func\"")); cspec.add_argument(new CCodeConstant("\"dup func\"")); cspec.add_argument(new CCodeConstant("G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY")); cinst.add_argument(cspec); ccode.add_expression(cinst); prop_enum.add_value(new CCodeEnumValue(enum_value)); func_name = "%s_destroy_func".printf(name_prefix); func_name_constant = new CCodeConstant("\"%s-destroy-func\"".printf(canonical_prefix)); enum_value = "%s_%s".printf(get_ccode_lower_case_name(cl, null), func_name).ToUpper(); cinst = new CCodeFunctionCall(new CCodeIdentifier("g_object_class_install_property")); cinst.add_argument(ccall); cinst.add_argument(new CCodeConstant(enum_value)); cspec = new CCodeFunctionCall(new CCodeIdentifier("g_param_spec_pointer")); cspec.add_argument(func_name_constant); cspec.add_argument(new CCodeConstant("\"destroy func\"")); cspec.add_argument(new CCodeConstant("\"destroy func\"")); cspec.add_argument(new CCodeConstant("G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY")); cinst.add_argument(cspec); ccode.add_expression(cinst); prop_enum.add_value(new CCodeEnumValue(enum_value)); } /* create properties */ var props = cl.get_properties(); foreach (Property prop in props) { if (!is_gobject_property(prop)) { continue; } if (prop.comment != null) { ccode.add_statement(new CCodeComment(prop.comment.content)); } var cinst = new CCodeFunctionCall(new CCodeIdentifier("g_object_class_install_property")); cinst.add_argument(ccall); cinst.add_argument(new CCodeConstant(get_ccode_upper_case_name(prop))); cinst.add_argument(get_param_spec(prop)); ccode.add_expression(cinst); } }
public override TargetValue load_variable(Variable variable, TargetValue value) { var result = (GLibValue)value; var array_type = result.value_type as ArrayType; var delegate_type = result.value_type as DelegateType; if (array_type != null) { if (array_type.fixed_length) { result.array_length_cvalues = null; result.append_array_length_cvalue(get_ccodenode(array_type.length)); result.lvalue = false; } else if (get_ccode_array_null_terminated(variable)) { requires_array_length = true; var len_call = new CCodeFunctionCall(new CCodeIdentifier("_vala_array_length")); len_call.add_argument(result.cvalue); result.array_length_cvalues = null; result.append_array_length_cvalue(len_call); result.lvalue = false; } else if (get_ccode_array_length_expr(variable) != null) { var length_expr = new CCodeConstant(get_ccode_array_length_expr(variable)); result.array_length_cvalues = null; result.append_array_length_cvalue(length_expr); result.lvalue = false; } else if (!get_ccode_array_length(variable)) { result.array_length_cvalues = null; for (int dim = 1; dim <= array_type.rank; dim++) { result.append_array_length_cvalue(new CCodeConstant("-1")); } result.lvalue = false; } else if (get_ccode_array_length_type(variable) != null) { for (int dim = 1; dim <= array_type.rank; dim++) { // cast if variable does not use int for array length result.array_length_cvalues[dim - 1] = new CCodeCastExpression(result.array_length_cvalues[dim - 1], "gint"); } result.lvalue = false; } result.array_size_cvalue = null; } else if (delegate_type != null) { if (!delegate_type.delegate_symbol.has_target || !get_ccode_delegate_target(variable)) { result.delegate_target_cvalue = new CCodeConstant("NULL"); } result.delegate_target_destroy_notify_cvalue = new CCodeConstant("NULL"); result.lvalue = false; } result.value_type.value_owned = false; bool use_temp = true; if (!is_lvalue_access_allowed(result.value_type)) { // special handling for types such as va_list use_temp = false; } if (variable is Parameter && variable.name == "this") { use_temp = false; } if (variable.single_assignment && !result.value_type.is_real_non_null_struct_type()) { // no need to copy values from variables that are assigned exactly once // as there is no risk of modification // except for structs that are always passed by reference use_temp = false; } var local = variable as LocalVariable; if (local != null && local.name[0] == '.') { // already a temporary variable generated internally // and safe to access without temporary variable use_temp = false; } if (use_temp) { result = (GLibValue)store_temp_value(result, variable); } return(result); }