LCOV - code coverage report
Current view: top level - codegen - valaccodememberaccessmodule.vala (source / functions) Coverage Total Hit
Test: vala 0.57.0.298-a8cae1 Lines: 96.5 % 516 498
Test Date: 2024-04-25 11:34:36 Functions: - 0 0

            Line data    Source code
       1              : /* valaccodememberaccessmodule.vala
       2              :  *
       3              :  * Copyright (C) 2006-2010  Jürg Billeter
       4              :  * Copyright (C) 2006-2008  Raffaele Sandrini
       5              :  *
       6              :  * This library is free software; you can redistribute it and/or
       7              :  * modify it under the terms of the GNU Lesser General Public
       8              :  * License as published by the Free Software Foundation; either
       9              :  * version 2.1 of the License, or (at your option) any later version.
      10              : 
      11              :  * This library is distributed in the hope that it will be useful,
      12              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14              :  * Lesser General Public License for more details.
      15              : 
      16              :  * You should have received a copy of the GNU Lesser General Public
      17              :  * License along with this library; if not, write to the Free Software
      18              :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
      19              :  *
      20              :  * Author:
      21              :  *      Jürg Billeter <j@bitron.ch>
      22              :  *      Raffaele Sandrini <raffaele@sandrini.ch>
      23              :  */
      24              : 
      25         2930 : public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
      26       152037 :         public override void visit_member_access (MemberAccess expr) {
      27        76042 :                 CCodeExpression pub_inst = null;
      28              : 
      29        76042 :                 if (expr.inner != null) {
      30        49434 :                         pub_inst = get_cvalue (expr.inner);
      31              :                 }
      32              : 
      33       184236 :                 var array_type = expr.value_type as ArrayType;
      34        76042 :                 var delegate_type = expr.value_type as DelegateType;
      35              : 
      36        93229 :                 if (expr.symbol_reference is Method) {
      37        17233 :                         var m = (Method) expr.symbol_reference;
      38              : 
      39        17233 :                         if (!(m is DynamicMethod || m is ArrayMoveMethod || m is ArrayResizeMethod || m is ArrayCopyMethod)) {
      40        17215 :                                 generate_method_declaration (m, cfile);
      41              : 
      42        17215 :                                 if (!m.external && m.external_package) {
      43              :                                         // internal VAPI methods
      44              :                                         // only add them once per source file
      45          701 :                                         if (add_generated_external_symbol (m)) {
      46          183 :                                                 visit_method (m);
      47              :                                         }
      48              :                                 }
      49              :                         }
      50              : 
      51        17233 :                         if (expr.inner is BaseAccess) {
      52           50 :                                 CCodeExpression? vcast = null;
      53           50 :                                 if (m.base_method != null) {
      54           43 :                                         unowned Class base_class = (Class) m.base_method.parent_symbol;
      55           43 :                                         vcast = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_class_type_function (base_class)));
      56           43 :                                         ((CCodeFunctionCall) vcast).add_argument (new CCodeIdentifier ("%s_parent_class".printf (get_ccode_lower_case_name (current_class))));
      57            7 :                                 } else if (m.base_interface_method != null) {
      58            3 :                                         unowned Interface base_iface = (Interface) m.base_interface_method.parent_symbol;
      59            3 :                                         vcast = get_this_interface_cexpression (base_iface);
      60              :                                 }
      61           46 :                                 if (vcast != null) {
      62           46 :                                         set_cvalue (expr, new CCodeMemberAccess.pointer (vcast, get_ccode_vfunc_name (m)));
      63           46 :                                         return;
      64              :                                 }
      65              :                         }
      66              : 
      67        17187 :                         if (m.base_method != null) {
      68         1519 :                                 if (get_ccode_no_wrapper (m.base_method)) {
      69            7 :                                         unowned Class base_class = (Class) m.base_method.parent_symbol;
      70           12 :                                         if (!base_class.is_compact) {
      71            5 :                                                 var vclass = get_this_class_cexpression (base_class, expr.inner.target_value);
      72            5 :                                                 set_cvalue (expr, new CCodeMemberAccess.pointer (vclass, get_ccode_vfunc_name (m)));
      73              :                                         } else {
      74            2 :                                                 set_cvalue (expr, new CCodeMemberAccess.pointer (pub_inst, get_ccode_vfunc_name (m)));
      75              :                                         }
      76              :                                 } else {
      77         1512 :                                         set_cvalue (expr, new CCodeIdentifier (get_ccode_name (m.base_method)));
      78              :                                 }
      79        15668 :                         } else if (m.base_interface_method != null) {
      80          280 :                                 if (get_ccode_no_wrapper (m.base_interface_method)) {
      81            7 :                                         unowned Interface base_iface = (Interface) m.base_interface_method.parent_symbol;
      82            7 :                                         var vclass = get_this_interface_cexpression (base_iface, expr.inner.target_value);
      83            7 :                                         set_cvalue (expr, new CCodeMemberAccess.pointer (vclass, get_ccode_vfunc_name (m)));
      84              :                                 } else {
      85          266 :                                         set_cvalue (expr, new CCodeIdentifier (get_ccode_name (m.base_interface_method)));
      86              :                                 }
      87        15395 :                         } else if (m is CreationMethod) {
      88            5 :                                 set_cvalue (expr, new CCodeIdentifier (get_ccode_real_name (m)));
      89              :                         } else {
      90        15390 :                                 set_cvalue (expr, new CCodeIdentifier (get_ccode_name (m)));
      91              :                         }
      92              : 
      93        17375 :                         delegate_type = expr.target_type as DelegateType;
      94        17187 :                         if (delegate_type != null) {
      95          188 :                                 generate_type_declaration (delegate_type, cfile);
      96          188 :                                 set_cvalue (expr, new CCodeCastExpression (get_cvalue (expr), get_ccode_name (delegate_type.delegate_symbol)));
      97              :                         }
      98              : 
      99        17187 :                         set_delegate_target_destroy_notify (expr, new CCodeConstant ("NULL"));
     100        17187 :                         if (m.binding == MemberBinding.STATIC) {
     101         7035 :                                 set_delegate_target (expr, new CCodeConstant ("NULL"));
     102        10152 :                         } else if (m.is_async_callback) {
     103           21 :                                 if (current_method.closure) {
     104            2 :                                         var block = ((Method) m.parent_symbol).body;
     105            2 :                                         set_delegate_target (expr, new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), "_async_data_"));
     106              :                                 } else {
     107           17 :                                         set_delegate_target (expr, new CCodeIdentifier ("_data_"));
     108              :                                 }
     109        20227 :                         } else if (expr.inner != null && !expr.prototype_access) {
     110              :                                 // expr.inner is null in the special case of referencing the method in a constant initializer
     111        10094 :                                 var delegate_target = (CCodeExpression) get_ccodenode (expr.inner);
     112        10161 :                                 delegate_type = expr.target_type as DelegateType;
     113        10111 :                                 if ((expr.value_type.value_owned || (delegate_type != null && delegate_type.is_called_once)) && expr.inner.value_type.type_symbol != null && is_reference_counting (expr.inner.value_type.type_symbol)) {
     114           17 :                                         var ref_call = new CCodeFunctionCall (get_dup_func_expression (expr.inner.value_type, expr.source_reference));
     115           17 :                                         ref_call.add_argument (delegate_target);
     116           34 :                                         delegate_target = ref_call;
     117           17 :                                         set_delegate_target_destroy_notify (expr, get_destroy_func_expression (expr.inner.value_type));
     118              :                                 }
     119        10094 :                                 set_delegate_target (expr, delegate_target);
     120              :                         }
     121        58809 :                 } else if (expr.symbol_reference is ArrayLengthField) {
     122          458 :                         set_cvalue (expr, get_array_length_cexpression (expr.inner, 1));
     123        58365 :                 } else if (expr.symbol_reference is DelegateTargetField) {
     124              :                         CCodeExpression delegate_target_destroy_notify;
     125           14 :                         set_cvalue (expr, get_delegate_target_cexpression (expr.inner, out delegate_target_destroy_notify) ?? new CCodeConstant ("NULL"));
     126        58342 :                 } else if (expr.symbol_reference is DelegateDestroyField) {
     127              :                         CCodeExpression delegate_target_destroy_notify;
     128            5 :                         get_delegate_target_cexpression (expr.inner, out delegate_target_destroy_notify);
     129           10 :                         set_cvalue (expr, delegate_target_destroy_notify ?? new CCodeConstant ("NULL"));
     130        58332 :                 } else if (expr.symbol_reference is GenericDupField) {
     131           16 :                         set_cvalue (expr, get_dup_func_expression (expr.inner.value_type, expr.source_reference));
     132        58316 :                 } else if (expr.symbol_reference is GenericDestroyField) {
     133           16 :                         set_cvalue (expr, get_destroy_func_expression (expr.inner.value_type));
     134        65270 :                 } else if (expr.symbol_reference is Field) {
     135         6970 :                         var field = (Field) expr.symbol_reference;
     136         6970 :                         if (expr.lvalue) {
     137          281 :                                 expr.target_value = get_field_cvalue (field, expr.inner != null ? expr.inner.target_value : null);
     138              :                         } else {
     139         6689 :                                 expr.target_value = load_field (field, expr.inner != null ? expr.inner.target_value : null, expr);
     140              :                         }
     141        53124 :                 } else if (expr.symbol_reference is EnumValue) {
     142         1794 :                         var ev = (EnumValue) expr.symbol_reference;
     143              : 
     144         1794 :                         generate_enum_declaration ((Enum) ev.parent_symbol, cfile);
     145              : 
     146         1794 :                         set_cvalue (expr, new CCodeConstant (get_ccode_name (ev)));
     147        50092 :                 } else if (expr.symbol_reference is Constant) {
     148          556 :                         var c = (Constant) expr.symbol_reference;
     149              : 
     150          556 :                         generate_constant_declaration (c, cfile,
     151          556 :                                 c.source_reference != null && expr.source_reference != null &&
     152          556 :                                 c.source_reference.file == expr.source_reference.file);
     153              : 
     154          556 :                         string fn = c.get_full_name ();
     155          556 :                         if (fn == "GLib.Log.FILE") {
     156            1 :                                 string s = Path.get_basename (expr.source_reference.file.filename);
     157            1 :                                 set_cvalue (expr, new CCodeConstant ("\"%s\"".printf (s)));
     158          555 :                         } else if (fn == "GLib.Log.LINE") {
     159            1 :                                 int i = expr.source_reference.begin.line;
     160            1 :                                 set_cvalue (expr, new CCodeConstant ("%d".printf (i)));
     161          554 :                         } else if (fn == "GLib.Log.METHOD") {
     162            1 :                                 string s = "";
     163            1 :                                 if (current_method != null) {
     164            1 :                                         s = current_method.get_full_name ();
     165              :                                 }
     166            1 :                                 set_cvalue (expr, new CCodeConstant ("\"%s\"".printf (s)));
     167          553 :                         } else if (c.type_reference.is_non_null_simple_type ()) {
     168          337 :                                 set_cvalue (expr, new CCodeConstant (get_ccode_name (c)));
     169              :                         } else {
     170          216 :                                 set_cvalue (expr, new CCodeConstantIdentifier (get_ccode_name (c)));
     171              :                         }
     172              : 
     173          556 :                         if (array_type != null) {
     174           70 :                                 string sub = "";
     175          258 :                                 for (int i = 0; i < array_type.rank; i++) {
     176              :                                         CCodeFunctionCall ccall;
     177           94 :                                         if (context.profile == Profile.POSIX) {
     178            2 :                                                 requires_array_n_elements = true;
     179            2 :                                                 ccall = new CCodeFunctionCall (new CCodeIdentifier ("VALA_N_ELEMENTS"));
     180              :                                         } else {
     181           92 :                                                 ccall = new CCodeFunctionCall (new CCodeIdentifier ("G_N_ELEMENTS"));
     182              :                                         }
     183           94 :                                         ccall.add_argument (new CCodeIdentifier (get_ccode_name (c) + sub));
     184           94 :                                         append_array_length (expr, ccall);
     185           94 :                                         sub += "[0]";
     186              :                                 }
     187           70 :                                 ((GLibValue) expr.target_value).non_null = true;
     188              :                         }
     189        53679 :                 } else if (expr.symbol_reference is Property) {
     190         4700 :                         var prop = (Property) expr.symbol_reference;
     191              : 
     192         4700 :                         if (!(prop is DynamicProperty)) {
     193         4684 :                                 generate_property_accessor_declaration (prop.get_accessor, cfile);
     194              : 
     195         4684 :                                 if (!prop.external && prop.external_package) {
     196              :                                         // internal VAPI properties
     197              :                                         // only add them once per source file
     198           21 :                                         if (add_generated_external_symbol (prop)) {
     199            5 :                                                 visit_property (prop);
     200              :                                         }
     201              :                                 }
     202              :                         }
     203              : 
     204         4700 :                         if (pub_inst == null && prop.binding == MemberBinding.INSTANCE) {
     205              :                                 // FIXME Report this with proper source-reference on the vala side!
     206            1 :                                 Report.error (prop.source_reference, "Invalid access to instance member `%s'", prop.get_full_name ());
     207            1 :                                 set_cvalue (expr, new CCodeInvalidExpression ());
     208            1 :                                 return;
     209              :                         }
     210              : 
     211         4699 :                         unowned Property base_prop = prop;
     212         4699 :                         if (prop.base_property != null) {
     213           22 :                                 base_prop = prop.base_property;
     214         4677 :                         } else if (prop.base_interface_property != null) {
     215          195 :                                 base_prop = prop.base_interface_property;
     216              :                         }
     217         4704 :                         if (expr.inner is BaseAccess && (base_prop.is_abstract || base_prop.is_virtual)) {
     218            5 :                                 CCodeExpression? vcast = null;
     219            5 :                                 if (base_prop.parent_symbol is Class) {
     220            3 :                                         unowned Class base_class = (Class) base_prop.parent_symbol;
     221            3 :                                         vcast = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_class_type_function (base_class)));
     222            3 :                                         ((CCodeFunctionCall) vcast).add_argument (new CCodeIdentifier ("%s_parent_class".printf (get_ccode_lower_case_name (current_class))));
     223            2 :                                 } else if (base_prop.parent_symbol is Interface) {
     224            2 :                                         unowned Interface base_iface = (Interface) base_prop.parent_symbol;
     225            2 :                                         vcast = get_this_interface_cexpression (base_iface);
     226              :                                 }
     227           10 :                                 if (vcast != null) {
     228            5 :                                         var ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, "get_%s".printf (prop.name)));
     229            5 :                                         ccall.add_argument (get_cvalue (expr.inner));
     230            8 :                                         if (prop.property_type.is_real_non_null_struct_type ()) {
     231            3 :                                                 var temp_value = (GLibValue) create_temp_value (prop.get_accessor.value_type, false, expr);
     232            3 :                                                 expr.target_value = load_temp_value (temp_value);
     233            3 :                                                 var ctemp = get_cvalue_ (temp_value);
     234            3 :                                                 ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp));
     235            3 :                                                 ccode.add_expression (ccall);
     236              :                                         } else {
     237            2 :                                                 set_cvalue (expr, ccall);
     238              :                                         }
     239              :                                 } else {
     240            0 :                                         Report.error (expr.source_reference, "internal: Invalid access to `%s'", base_prop.get_full_name ());
     241              :                                 }
     242         5020 :                         } else if (prop.binding == MemberBinding.INSTANCE &&
     243         4693 :                             prop.get_accessor.automatic_body &&
     244         1229 :                             !prop.get_accessor.value_type.value_owned &&
     245         1199 :                             current_type_symbol == prop.parent_symbol &&
     246          326 :                             current_type_symbol is Class &&
     247          326 :                             prop.base_property == null &&
     248          326 :                             prop.base_interface_property == null &&
     249          326 :                             !(prop.property_type is ArrayType || prop.property_type is DelegateType)) {
     250          326 :                                 CCodeExpression inst = pub_inst;
     251          326 :                                 if (!((Class) current_type_symbol).is_compact) {
     252          325 :                                         inst = new CCodeMemberAccess.pointer (inst, "priv");
     253              :                                 }
     254          326 :                                 set_cvalue (expr, new CCodeMemberAccess.pointer (inst, get_ccode_name (prop.field)));
     255         8736 :                         } else if (!get_ccode_no_accessor_method (prop) && !(prop is DynamicProperty)) {
     256         4344 :                                 var ccall = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_name (prop.get_accessor)));
     257              : 
     258         4344 :                                 if (prop.binding == MemberBinding.INSTANCE) {
     259         4351 :                                         if (prop.parent_symbol is Struct && !((Struct) prop.parent_symbol).is_simple_type ()) {
     260              :                                                 // we need to pass struct instance by reference
     261        39742 :                                                 var instance = expr.inner.target_value;
     262            8 :                                                 if (!get_lvalue (instance)) {
     263            0 :                                                         instance = store_temp_value (instance, expr);
     264              :                                                 }
     265            8 :                                                 pub_inst = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_cvalue_ (instance));
     266              :                                         }
     267              : 
     268         4343 :                                         ccall.add_argument (pub_inst);
     269              :                                 }
     270              : 
     271         4344 :                                 bool prop_is_real_non_null_struct_type = prop.property_type.is_real_non_null_struct_type ();
     272         4344 :                                 bool requires_init = prop.property_type is DelegateType || prop_is_real_non_null_struct_type;
     273         4344 :                                 var temp_value = (GLibValue) create_temp_value (prop.get_accessor.value_type, requires_init, expr);
     274         4344 :                                 expr.target_value = load_temp_value (temp_value);
     275         4344 :                                 var ctemp = get_cvalue_ (temp_value);
     276              : 
     277              :                                 // Property access to real struct types is handled differently
     278              :                                 // The value is returned by out parameter
     279         4344 :                                 if (prop_is_real_non_null_struct_type) {
     280           79 :                                         ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp));
     281           79 :                                         ccode.add_expression (ccall);
     282              :                                 } else {
     283         4291 :                                         array_type = prop.property_type as ArrayType;
     284         4265 :                                         if (array_type != null) {
     285           34 :                                                 if (get_ccode_array_null_terminated (prop) && !get_ccode_array_length (prop)) {
     286            8 :                                                         requires_array_length = true;
     287            8 :                                                         var len_call = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_length"));
     288            8 :                                                         len_call.add_argument (ctemp);
     289              : 
     290            8 :                                                         ccode.add_assignment (ctemp, ccall);
     291            8 :                                                         ccode.add_assignment (temp_value.array_length_cvalues[0], len_call);
     292           36 :                                                 } else if (get_ccode_array_length (prop)) {
     293           18 :                                                         var temp_refs = new ArrayList<CCodeExpression> ();
     294           36 :                                                         for (int dim = 1; dim <= array_type.rank; dim++) {
     295           18 :                                                                 var length_ctype = get_ccode_array_length_type (prop);
     296           18 :                                                                 var temp_var = get_temp_variable (new CType (length_ctype, "0"), true, null, true);
     297           18 :                                                                 var temp_ref = get_variable_cexpression (temp_var.name);
     298           18 :                                                                 emit_temp_var (temp_var);
     299           18 :                                                                 ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
     300           18 :                                                                 temp_refs.add (temp_ref);
     301              :                                                         }
     302              : 
     303           18 :                                                         ccode.add_assignment (ctemp, ccall);
     304           36 :                                                         for (int dim = 1; dim <= array_type.rank; dim++) {
     305           18 :                                                                 ccode.add_assignment (temp_value.array_length_cvalues[dim - 1], temp_refs.get (dim - 1));
     306              :                                                         }
     307              :                                                 } else {
     308            0 :                                                         ccode.add_assignment (ctemp, ccall);
     309              :                                                 }
     310              :                                         } else {
     311         4239 :                                                 ccode.add_assignment (ctemp, ccall);
     312              : 
     313         4249 :                                                 delegate_type = prop.property_type as DelegateType;
     314         4239 :                                                 if (delegate_type != null && get_ccode_delegate_target (prop) && delegate_type.delegate_symbol.has_target) {
     315            6 :                                                         ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_delegate_target_cvalue (temp_value)));
     316              :                                                 } else {
     317         4233 :                                                         if (temp_value.delegate_target_cvalue != null) {
     318            4 :                                                                 ccode.add_assignment (temp_value.delegate_target_cvalue, new CCodeConstant ("NULL"));
     319              :                                                         }
     320         4233 :                                                         if (temp_value.delegate_target_destroy_notify_cvalue != null) {
     321            0 :                                                                 ccode.add_assignment (temp_value.delegate_target_destroy_notify_cvalue, new CCodeConstant ("NULL"));
     322              :                                                         }
     323              :                                                 }
     324              :                                         }
     325              :                                 }
     326              :                         } else {
     327           24 :                                 var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get"));
     328           24 :                                 ccall.add_argument (pub_inst);
     329              : 
     330              :                                 // property name is second argument of g_object_get
     331           24 :                                 ccall.add_argument (get_property_canonical_cconstant (prop));
     332              : 
     333              :                                 // g_object_get always returns owned values
     334              :                                 // therefore, property getters of properties
     335              :                                 // without accessor methods need to be marked as owned
     336           24 :                                 if (!(prop is DynamicProperty) && !prop.get_accessor.value_type.value_owned) {
     337              :                                         // only report error for types where there actually
     338              :                                         // is a difference between `owned' and `unowned'
     339            0 :                                         var owned_value_type = prop.get_accessor.value_type.copy ();
     340            0 :                                         owned_value_type.value_owned = true;
     341            0 :                                         if (requires_copy (owned_value_type)) {
     342            0 :                                                 Report.error (prop.get_accessor.source_reference, "unowned return value for getter of property `%s' not supported without accessor", prop.get_full_name ());
     343              :                                         }
     344              :                                 }
     345              : 
     346           24 :                                 if (expr.value_type.is_real_struct_type ()) {
     347              :                                         // gobject allocates structs on heap
     348            5 :                                         expr.value_type.nullable = true;
     349              :                                 }
     350              : 
     351           24 :                                 var temp_var = get_temp_variable (expr.value_type);
     352           24 :                                 var ctemp = get_variable_cexpression (temp_var.name);
     353           24 :                                 emit_temp_var (temp_var);
     354           24 :                                 ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp));
     355           24 :                                 ccall.add_argument (new CCodeConstant ("NULL"));
     356           24 :                                 ccode.add_expression (ccall);
     357              : 
     358           24 :                                 set_cvalue (expr, ctemp);
     359              : 
     360           25 :                                 if (get_ccode_array_null_terminated (prop) && !get_ccode_array_length (prop)) {
     361            1 :                                         requires_array_length = true;
     362            1 :                                         var len_call = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_length"));
     363            1 :                                         len_call.add_argument (ctemp);
     364              : 
     365            1 :                                         var glib_value = (GLibValue) expr.target_value;
     366            1 :                                         glib_value.array_length_cvalues = null;
     367            1 :                                         glib_value.append_array_length_cvalue (len_call);
     368            1 :                                         glib_value.lvalue = false;
     369              :                                 }
     370              :                         }
     371              : 
     372         4699 :                         if (prop.get_accessor.value_type is GenericType) {
     373            9 :                                 expr.target_value.value_type = prop.get_accessor.value_type.copy ();
     374              :                         } else {
     375         4690 :                                 expr.target_value.value_type = expr.value_type.copy ();
     376              :                         }
     377         4699 :                         expr.target_value = store_temp_value (expr.target_value, expr);
     378        61238 :                 } else if (expr.symbol_reference is LocalVariable) {
     379        16958 :                         var local = (LocalVariable) expr.symbol_reference;
     380              : 
     381        17223 :                         if (expr.parent_node is ReturnStatement &&
     382          314 :                             current_return_type.value_owned &&
     383          306 :                             local.variable_type.value_owned &&
     384          274 :                             !local.captured &&
     385          268 :                             !variable_accessible_in_finally (local) &&
     386          266 :                             !(local.variable_type is ArrayType && ((ArrayType) local.variable_type).inline_allocated)) {
     387              :                                 /* return expression is local variable taking ownership and
     388              :                                  * current method is transferring ownership */
     389              : 
     390              :                                 // don't ref expression
     391          265 :                                 expr.value_type.value_owned = true;
     392              : 
     393              :                                 // don't unref variable
     394          265 :                                 local.active = false;
     395              : 
     396          265 :                                 var glib_value = (GLibValue) get_local_cvalue (local);
     397          265 :                                 expr.target_value = glib_value;
     398          265 :                                 if (glib_value.delegate_target_cvalue == null) {
     399          265 :                                         glib_value.delegate_target_cvalue = new CCodeConstant ("NULL");
     400              :                                 }
     401          265 :                                 if (glib_value.delegate_target_destroy_notify_cvalue == null) {
     402          265 :                                         glib_value.delegate_target_destroy_notify_cvalue = new CCodeConstant ("NULL");
     403              :                                 }
     404              :                         } else {
     405        16693 :                                 if (expr.lvalue) {
     406         1048 :                                         expr.target_value = get_local_cvalue (local);
     407              :                                 } else {
     408        15645 :                                         expr.target_value = load_local (local, expr);
     409              :                                 }
     410              :                         }
     411        43828 :                 } else if (expr.symbol_reference is Parameter) {
     412        16506 :                         var param = (Parameter) expr.symbol_reference;
     413        16506 :                         if (expr.lvalue) {
     414          107 :                                 expr.target_value = get_parameter_cvalue (param);
     415              :                         } else {
     416        16399 :                                 expr.target_value = load_parameter (param, expr);
     417              :                         }
     418              :                 }
     419              : 
     420              :                 // Add cast for narrowed type access of variables if needed
     421        75995 :                 if (expr.symbol_reference is Variable) {
     422        40943 :                         unowned GLibValue cvalue = (GLibValue) expr.target_value;
     423        40943 :                         if (!(cvalue.value_type is GenericType) && cvalue.value_type.type_symbol != null
     424        37999 :                             && cvalue.value_type.type_symbol != expr.value_type.type_symbol) {
     425            1 :                                 cvalue.cvalue = new CCodeCastExpression (cvalue.cvalue, get_ccode_name (expr.value_type));
     426              :                         }
     427              :                 }
     428              :         }
     429              : 
     430              :         /* Returns lvalue access to the given local variable */
     431        67179 :         public override TargetValue get_local_cvalue (LocalVariable local) {
     432        67179 :                 var result = new GLibValue (local.variable_type.copy ());
     433        67179 :                 result.lvalue = true;
     434              : 
     435        67179 :                 var array_type = local.variable_type as ArrayType;
     436        67179 :                 var delegate_type = local.variable_type as DelegateType;
     437        67179 :                 if (local.is_result) {
     438              :                         // used in postconditions
     439              :                         // structs are returned as out parameter
     440           15 :                         if (local.variable_type != null && local.variable_type.is_real_non_null_struct_type ()) {
     441            0 :                                 result.cvalue = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result"));
     442              :                         } else {
     443           15 :                                 result.cvalue = new CCodeIdentifier ("result");
     444              :                         }
     445           15 :                         if (array_type != null && !array_type.fixed_length && ((current_method != null && get_ccode_array_length (current_method)) || current_property_accessor != null)) {
     446           10 :                                 for (int dim = 1; dim <= array_type.rank; dim++) {
     447            5 :                                         result.append_array_length_cvalue (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_variable_cexpression (get_array_length_cname ("result", dim))));
     448              :                                 }
     449              :                         }
     450        67460 :                 } else if (local.captured) {
     451              :                         // captured variables are stored on the heap
     452          296 :                         var block = (Block) local.parent_symbol;
     453          296 :                         result.cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_local_cname (local));
     454          296 :                         if (array_type != null && !array_type.fixed_length) {
     455           34 :                                 for (int dim = 1; dim <= array_type.rank; dim++) {
     456           17 :                                         result.append_array_length_cvalue (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_array_length_cname (get_local_cname (local), dim)));
     457              :                                 }
     458           17 :                                 if (array_type.rank == 1) {
     459           17 :                                         result.array_size_cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_array_size_cname (get_local_cname (local)));
     460              :                                 }
     461          279 :                         } else if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
     462            8 :                                 result.delegate_target_cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (get_local_cname (local)));
     463            8 :                                 if (delegate_type.is_disposable ()) {
     464            6 :                                         result.delegate_target_destroy_notify_cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_destroy_notify_cname (get_local_cname (local)));
     465              :                                 }
     466              :                         }
     467              :                 } else {
     468        66868 :                         result.cvalue = get_local_cexpression (local);
     469        66868 :                         if (array_type != null && !array_type.fixed_length) {
     470         9311 :                                 for (int dim = 1; dim <= array_type.rank; dim++) {
     471         4766 :                                         result.append_array_length_cvalue (get_variable_cexpression (get_array_length_cname (get_local_cname (local), dim)));
     472              :                                 }
     473         4545 :                                 if (array_type.rank == 1) {
     474         4403 :                                         result.array_size_cvalue = get_variable_cexpression (get_array_size_cname (get_local_cname (local)));
     475              :                                 }
     476        62323 :                         } else if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
     477          367 :                                 if (is_in_coroutine ()) {
     478           21 :                                         result.delegate_target_cvalue = get_variable_cexpression (get_delegate_target_cname (get_local_cname (local)));
     479           21 :                                         if (local.variable_type.is_disposable ()) {
     480           19 :                                                 result.delegate_target_destroy_notify_cvalue = get_variable_cexpression (get_delegate_target_destroy_notify_cname (get_local_cname (local)));
     481              :                                         }
     482              :                                 } else {
     483          346 :                                         result.delegate_target_cvalue = new CCodeIdentifier (get_delegate_target_cname (get_local_cname (local)));
     484          346 :                                         if (local.variable_type.is_disposable ()) {
     485          253 :                                                 result.delegate_target_destroy_notify_cvalue = new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_local_cname (local)));
     486              :                                         }
     487              :                                 }
     488              :                         }
     489              :                 }
     490              : 
     491        67179 :                 return result;
     492              :         }
     493              : 
     494              :         /* Returns access values to the given parameter */
     495        18198 :         public override TargetValue get_parameter_cvalue (Parameter param) {
     496        18198 :                 var result = new GLibValue (param.variable_type.copy ());
     497        18198 :                 result.lvalue = true;
     498        18198 :                 result.array_null_terminated = get_ccode_array_null_terminated (param);
     499        18198 :                 if (get_ccode_array_length_expr (param) != null) {
     500            0 :                         result.array_length_cexpr = new CCodeConstant (get_ccode_array_length_expr (param));
     501              :                 }
     502        18198 :                 result.ctype = get_ccode_type (param);
     503              : 
     504        18198 :                 var array_type = result.value_type as ArrayType;
     505        18198 :                 var delegate_type = result.value_type as DelegateType;
     506              : 
     507          176 :                 bool is_unowned_delegate = delegate_type != null && !param.variable_type.value_owned;
     508        18198 :                 if ((param.captured || is_in_coroutine ()) && !is_unowned_delegate) {
     509          303 :                         result.value_type.value_owned = true;
     510              :                 }
     511              : 
     512        26355 :                 if (param.name == "this") {
     513        10041 :                         if (is_in_coroutine ()) {
     514              :                                 // use closure
     515          100 :                                 result.cvalue = get_this_cexpression ();
     516              :                         } else {
     517         9941 :                                 unowned Struct? st = result.value_type.type_symbol as Struct;
     518         9941 :                                 if (st != null && !st.is_simple_type ()) {
     519          185 :                                         result.cvalue = new CCodeIdentifier ("(*self)");
     520              :                                 } else {
     521         9756 :                                         result.cvalue = new CCodeIdentifier ("self");
     522              :                                 }
     523              :                         }
     524              :                 } else {
     525         8157 :                         string name = get_ccode_name (param);
     526              : 
     527         8251 :                         if (param.captured && !is_in_method_precondition) {
     528              :                                 // captured variables are stored on the heap
     529           94 :                                 var block = param.parent_symbol as Block;
     530           94 :                                 if (block == null) {
     531           92 :                                         block = ((Method) param.parent_symbol).body;
     532              :                                 }
     533           94 :                                 result.cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_ccode_name (param));
     534           94 :                                 if (array_type != null && get_ccode_array_length (param)) {
     535            4 :                                         for (int dim = 1; dim <= array_type.rank; dim++) {
     536            2 :                                                 result.append_array_length_cvalue (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_variable_array_length_cname (param, dim)));
     537              :                                         }
     538           92 :                                 } else if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
     539           26 :                                         result.delegate_target_cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_ccode_delegate_target_name (param));
     540           26 :                                         if (result.value_type.is_disposable ()) {
     541            4 :                                                 result.delegate_target_destroy_notify_cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_ccode_delegate_target_destroy_notify_name (param));
     542              :                                         }
     543              :                                 }
     544         8063 :                         } else if (is_in_coroutine ()) {
     545              :                                 // use closure
     546          133 :                                 result.cvalue = get_parameter_cexpression (param);
     547          133 :                                 if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
     548            9 :                                         result.delegate_target_cvalue = get_variable_cexpression (get_ccode_delegate_target_name (param));
     549            9 :                                         if (delegate_type.is_disposable ()) {
     550            9 :                                                 result.delegate_target_destroy_notify_cvalue = get_variable_cexpression (get_ccode_delegate_target_destroy_notify_name (param));
     551              :                                         }
     552              :                                 }
     553              :                         } else {
     554         7930 :                                 unowned Struct? type_as_struct = result.value_type.type_symbol as Struct;
     555              : 
     556         7930 :                                 if (param.direction == ParameterDirection.OUT) {
     557          445 :                                         name = "_vala_%s".printf (name);
     558              :                                 }
     559              : 
     560         7930 :                                 if (param.direction == ParameterDirection.REF ||
     561         7829 :                                         (param.direction == ParameterDirection.IN && type_as_struct != null && !type_as_struct.is_simple_type () && !result.value_type.nullable)) {
     562          160 :                                         result.cvalue = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (name));
     563              :                                 } else {
     564         7770 :                                         result.cvalue = get_variable_cexpression (name);
     565              :                                 }
     566         8035 :                                 if (get_ccode_delegate_target (param) && delegate_type != null && delegate_type.delegate_symbol.has_target) {
     567          105 :                                         var target_cname = get_ccode_delegate_target_name (param);
     568          105 :                                         var destroy_cname = get_ccode_delegate_target_destroy_notify_name (param);
     569          105 :                                         if (param.direction == ParameterDirection.OUT) {
     570           10 :                                                 target_cname = "_vala_%s".printf (target_cname);
     571           10 :                                                 destroy_cname = "_vala_%s".printf (destroy_cname);
     572              :                                         }
     573          105 :                                         CCodeExpression target_expr = new CCodeIdentifier (target_cname);
     574          105 :                                         CCodeExpression delegate_target_destroy_notify = new CCodeIdentifier (destroy_cname);
     575          105 :                                         if (param.direction == ParameterDirection.REF) {
     576              :                                                 // accessing argument of ref param
     577            3 :                                                 target_expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, target_expr);
     578            3 :                                                 delegate_target_destroy_notify = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, delegate_target_destroy_notify);
     579              :                                         }
     580          210 :                                         result.delegate_target_cvalue = target_expr;
     581          105 :                                         if (result.value_type.is_disposable ()) {
     582          124 :                                                 result.delegate_target_destroy_notify_cvalue = delegate_target_destroy_notify;
     583              :                                         }
     584              :                                 }
     585              :                         }
     586         8157 :                         if (!param.captured && array_type != null) {
     587          546 :                                 if (get_ccode_array_length (param) && !get_ccode_array_null_terminated (param)) {
     588         1624 :                                         for (int dim = 1; dim <= array_type.rank; dim++) {
     589          558 :                                                 CCodeExpression length_expr = get_cexpression (get_variable_array_length_cname (param, dim));
     590          558 :                                                 if (param.direction == ParameterDirection.OUT) {
     591          103 :                                                         length_expr = get_cexpression (get_array_length_cname (name, dim));
     592          455 :                                                 } else if (param.direction == ParameterDirection.REF) {
     593              :                                                         // accessing argument of ref param
     594           24 :                                                         length_expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, length_expr);
     595              :                                                 }
     596          558 :                                                 result.append_array_length_cvalue (length_expr);
     597              :                                         }
     598              :                                 }
     599              :                         }
     600              :                 }
     601              : 
     602        18198 :                 return result;
     603              :         }
     604              : 
     605              :         /* Returns lvalue access to the given field */
     606        11146 :         public override TargetValue get_field_cvalue (Field field, TargetValue? instance) {
     607        11146 :                 var value_type = field.variable_type.copy ();
     608              : 
     609        11146 :                 var result = new GLibValue (value_type);
     610        11146 :                 if (instance != null) {
     611         9201 :                         result.actual_value_type = field.variable_type.get_actual_type (instance.value_type, null, field);
     612              :                 }
     613        11146 :                 result.lvalue = true;
     614        11146 :                 result.array_null_terminated = get_ccode_array_null_terminated (field);
     615        11146 :                 if (get_ccode_array_length_expr (field) != null) {
     616            0 :                         result.array_length_cexpr = new CCodeConstant (get_ccode_array_length_expr (field));
     617              :                 }
     618        11146 :                 result.ctype = get_ccode_type (field);
     619              : 
     620        11146 :                 var array_type = result.value_type as ArrayType;
     621        20328 :                 if (field.binding == MemberBinding.INSTANCE) {
     622         9183 :                         CCodeExpression pub_inst = null;
     623              : 
     624         9183 :                         if (instance != null) {
     625         9182 :                                 pub_inst = get_cvalue_ (instance);
     626              :                         }
     627              : 
     628         9183 :                         var instance_target_type = SemanticAnalyzer.get_data_type_for_symbol (field.parent_symbol);
     629              : 
     630         9183 :                         unowned Class? cl = instance_target_type.type_symbol as Class;
     631        19516 :                         bool is_gtypeinstance = ((instance_target_type.type_symbol == cl) && (cl == null || !cl.is_compact));
     632              : 
     633              :                         CCodeExpression inst;
     634         8186 :                         if (is_gtypeinstance && field.access == SymbolAccessibility.PRIVATE) {
     635         5498 :                                 inst = new CCodeMemberAccess.pointer (pub_inst, "priv");
     636              :                         } else {
     637         3685 :                                 if (cl != null) {
     638         2688 :                                         generate_class_struct_declaration (cl, cfile);
     639              :                                 }
     640         3685 :                                 inst = pub_inst;
     641              :                         }
     642              : 
     643         9183 :                         if (inst == null) {
     644              :                                 // FIXME Report this with proper source-reference on the vala side!
     645            1 :                                 Report.error (field.source_reference, "Invalid access to instance member `%s'", field.get_full_name ());
     646            1 :                                 result.cvalue = new CCodeInvalidExpression ();
     647            1 :                                 return result;
     648              :                         }
     649              : 
     650         9182 :                         if (instance_target_type.type_symbol.is_reference_type () || (instance != null && instance.value_type is PointerType)) {
     651         8185 :                                 result.cvalue = new CCodeMemberAccess.pointer (inst, get_ccode_name (field));
     652              :                         } else {
     653          997 :                                 result.cvalue = new CCodeMemberAccess (inst, get_ccode_name (field));
     654              :                         }
     655              : 
     656         9182 :                         if (array_type != null && get_ccode_array_length (field)) {
     657         1083 :                                 for (int dim = 1; dim <= array_type.rank; dim++) {
     658          364 :                                         CCodeExpression length_expr = null;
     659          364 :                                         string length_cname = get_variable_array_length_cname (field, dim);
     660              : 
     661          364 :                                         if (((TypeSymbol) field.parent_symbol).is_reference_type ()) {
     662          285 :                                                 length_expr = new CCodeMemberAccess.pointer (inst, length_cname);
     663              :                                         } else {
     664           79 :                                                 length_expr = new CCodeMemberAccess (inst, length_cname);
     665              :                                         }
     666              : 
     667          364 :                                         result.append_array_length_cvalue (length_expr);
     668              :                                 }
     669          587 :                                 if (array_type.rank == 1 && field.is_internal_symbol ()) {
     670          232 :                                         string size_cname = get_array_size_cname (get_ccode_name (field));
     671              : 
     672          232 :                                         if (((TypeSymbol) field.parent_symbol).is_reference_type ()) {
     673          173 :                                                 set_array_size_cvalue (result, new CCodeMemberAccess.pointer (inst, size_cname));
     674              :                                         } else {
     675           59 :                                                 set_array_size_cvalue (result, new CCodeMemberAccess (inst, size_cname));
     676              :                                         }
     677              :                                 }
     678         8919 :                         } else if (get_ccode_delegate_target (field)) {
     679           92 :                                 string target_cname = get_ccode_delegate_target_name (field);
     680           92 :                                 string target_destroy_notify_cname = get_ccode_delegate_target_destroy_notify_name (field);
     681              : 
     682           92 :                                 if (((TypeSymbol) field.parent_symbol).is_reference_type ()) {
     683           83 :                                         result.delegate_target_cvalue = new CCodeMemberAccess.pointer (inst, target_cname);
     684           83 :                                         if (result.value_type.is_disposable ()){
     685           79 :                                                 result.delegate_target_destroy_notify_cvalue = new CCodeMemberAccess.pointer (inst, target_destroy_notify_cname);
     686              :                                         }
     687              :                                 } else {
     688            9 :                                         result.delegate_target_cvalue = new CCodeMemberAccess (inst, target_cname);
     689            9 :                                         if (result.value_type.is_disposable ()) {
     690            6 :                                                 result.delegate_target_destroy_notify_cvalue = new CCodeMemberAccess (inst, target_destroy_notify_cname);
     691              :                                         }
     692              :                                 }
     693              :                         }
     694         2083 :                 } else if (field.binding == MemberBinding.CLASS) {
     695          120 :                         unowned Class cl = (Class) field.parent_symbol;
     696          120 :                         var cast = get_this_class_cexpression (cl, instance);
     697          157 :                         if (field.access == SymbolAccessibility.PRIVATE) {
     698           37 :                                 var ccall = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_class_get_private_function (cl)));
     699           37 :                                 ccall.add_argument (cast);
     700           37 :                                 result.cvalue = new CCodeMemberAccess.pointer (ccall, get_ccode_name (field));
     701              :                         } else {
     702           83 :                                 result.cvalue = new CCodeMemberAccess.pointer (cast, get_ccode_name (field));
     703              :                         }
     704              : 
     705              :                 } else {
     706         1843 :                         generate_field_declaration (field, cfile);
     707              : 
     708         1843 :                         result.cvalue = new CCodeIdentifier (get_ccode_name (field));
     709              : 
     710         1843 :                         if (array_type != null && get_ccode_array_length (field)) {
     711          182 :                                 for (int dim = 1; dim <= array_type.rank; dim++) {
     712           91 :                                         string length_cname = get_variable_array_length_cname (field, dim);
     713           91 :                                         result.append_array_length_cvalue (new CCodeIdentifier (length_cname));
     714              :                                 }
     715           91 :                                 if (array_type.rank == 1 && field.is_internal_symbol ()) {
     716           88 :                                         set_array_size_cvalue (result, new CCodeIdentifier (get_array_size_cname (get_ccode_name (field))));
     717              :                                 }
     718         1752 :                         } else if (get_ccode_delegate_target (field)) {
     719            3 :                                 result.delegate_target_cvalue = new CCodeIdentifier (get_ccode_delegate_target_name (field));
     720            3 :                                 if (result.value_type.is_disposable ()) {
     721            2 :                                         result.delegate_target_destroy_notify_cvalue = new CCodeIdentifier (get_ccode_delegate_target_destroy_notify_name (field));
     722              :                                 }
     723              :                         }
     724              :                 }
     725              : 
     726        11145 :                 return result;
     727              :         }
     728              : 
     729        39733 :         public override TargetValue load_variable (Variable variable, TargetValue value, Expression? expr = null) {
     730        39733 :                 var result = (GLibValue) value;
     731        39733 :                 var array_type = result.value_type as ArrayType;
     732        39733 :                 var delegate_type = result.value_type as DelegateType;
     733        39733 :                 if (array_type != null) {
     734         2177 :                         if (array_type.fixed_length) {
     735          132 :                                 result.array_length_cvalues = null;
     736          132 :                                 result.append_array_length_cvalue (get_ccodenode (array_type.length));
     737          132 :                                 result.lvalue = false;
     738         2130 :                         } else if (get_ccode_array_null_terminated (variable) && !get_ccode_array_length (variable)) {
     739           85 :                                 requires_array_length = true;
     740           85 :                                 var len_call = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_length"));
     741           85 :                                 len_call.add_argument (result.cvalue);
     742              : 
     743           85 :                                 result.array_length_cvalues = null;
     744           85 :                                 result.append_array_length_cvalue (len_call);
     745           85 :                                 result.lvalue = false;
     746         1960 :                         } else if (get_ccode_array_length_expr (variable) != null) {
     747            0 :                                 var length_expr = new CCodeConstant (get_ccode_array_length_expr (variable));
     748              : 
     749            0 :                                 result.array_length_cvalues = null;
     750            0 :                                 result.append_array_length_cvalue (length_expr);
     751            0 :                                 result.lvalue = false;
     752         1960 :                         } else if (!get_ccode_array_length (variable)) {
     753           25 :                                 result.array_length_cvalues = null;
     754           50 :                                 for (int dim = 1; dim <= array_type.rank; dim++) {
     755           25 :                                         result.append_array_length_cvalue (new CCodeConstant ("-1"));
     756              :                                 }
     757           25 :                                 result.lvalue = false;
     758         1935 :                         } else if (get_ccode_array_length_type (variable.variable_type) != get_ccode_array_length_type (array_type)) {
     759            0 :                                 for (int dim = 1; dim <= array_type.rank; dim++) {
     760              :                                         // cast if variable does not use int for array length
     761            0 :                                         result.array_length_cvalues[dim - 1] = new CCodeCastExpression (result.array_length_cvalues[dim - 1], get_ccode_array_length_type (array_type));
     762              :                                 }
     763            0 :                                 result.lvalue = false;
     764              :                         }
     765         2177 :                         result.array_size_cvalue = null;
     766         2177 :                         result.non_null = array_type.inline_allocated;
     767        37556 :                 } else if (delegate_type != null) {
     768          448 :                         if (!get_ccode_delegate_target (variable)) {
     769          271 :                                 result.delegate_target_cvalue = new CCodeConstant ("NULL");
     770          271 :                                 result.delegate_target_destroy_notify_cvalue = new CCodeConstant ("NULL");
     771              :                         }
     772              : 
     773          448 :                         result.lvalue = false;
     774              :                 }
     775        39733 :                 result.value_type.value_owned = false;
     776              : 
     777        39733 :                 bool use_temp = true;
     778        39733 :                 if (!is_lvalue_access_allowed (result.value_type)) {
     779              :                         // special handling for types such as va_list
     780          148 :                         use_temp = false;
     781              :                 }
     782        56996 :                 if (variable is Parameter) {
     783        17263 :                         var param = (Parameter) variable;
     784        17263 :                         if (variable.name == "this") {
     785              :                                 use_temp = false;
     786         7296 :                         } else if ((param.direction != ParameterDirection.OUT)
     787         7278 :                             && !(param.variable_type.is_real_non_null_struct_type ())) {
     788        17197 :                                 use_temp = false;
     789              :                         }
     790              :                 }
     791        39733 :                 if (variable.single_assignment && !result.value_type.is_real_non_null_struct_type ()) {
     792              :                         // no need to copy values from variables that are assigned exactly once
     793              :                         // as there is no risk of modification
     794              :                         // except for structs that are always passed by reference
     795        39733 :                         use_temp = false;
     796              :                 }
     797        39733 :                 if (result.value_type.is_non_null_simple_type ()) {
     798              :                         // no need to an extra copy of variables that are stack allocated simple types
     799         5970 :                         use_temp = false;
     800              :                 }
     801              :                 // our implementation of postfix-expressions require temporary variables
     802        39733 :                 if (expr is MemberAccess && ((MemberAccess) expr).tainted_access) {
     803        39733 :                         use_temp = true;
     804              :                 }
     805              : 
     806        39733 :                 var local = variable as LocalVariable;
     807        15689 :                 if (local != null && local.name[0] == '.') {
     808              :                         // already a temporary variable generated internally
     809              :                         // and safe to access without temporary variable
     810              :                         use_temp = false;
     811              :                 }
     812              : 
     813        38217 :                 if (use_temp) {
     814        14764 :                         result = (GLibValue) store_temp_value (result, variable);
     815              :                 }
     816              : 
     817        39733 :                 return result;
     818              :         }
     819              : 
     820              :         /* Returns unowned access to the given local variable */
     821        15689 :         public override TargetValue load_local (LocalVariable local, Expression? expr = null) {
     822        15689 :                 return load_variable (local, get_local_cvalue (local), expr);
     823              :         }
     824              : 
     825              :         /* Returns unowned access to the given parameter */
     826        17263 :         public override TargetValue load_parameter (Parameter param, Expression? expr = null) {
     827        17263 :                 return load_variable (param, get_parameter_cvalue (param), expr);
     828              :         }
     829              : 
     830              :         /* Convenience method returning access to "this" */
     831          801 :         public override TargetValue load_this_parameter (TypeSymbol sym) {
     832          801 :                 var param = new Parameter ("this", SemanticAnalyzer.get_data_type_for_symbol (sym));
     833          801 :                 return load_parameter (param);
     834              :         }
     835              : 
     836              :         /* Returns unowned access to the given field */
     837         6781 :         public override TargetValue load_field (Field field, TargetValue? instance, Expression? expr = null) {
     838         6781 :                 return load_variable (field, get_field_cvalue (field, instance), expr);
     839              :         }
     840              : }
        

Generated by: LCOV version 2.0-1