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

            Line data    Source code
       1              : /* valaccodecontrolflowmodule.vala
       2              :  *
       3              :  * Copyright (C) 2006-2011  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              : using GLib;
      26              : 
      27         2930 : public abstract class Vala.CCodeControlFlowModule : CCodeMethodModule {
      28         4905 :         public override void visit_if_statement (IfStatement stmt) {
      29         4905 :                 ccode.open_if (get_cvalue (stmt.condition));
      30              : 
      31         4905 :                 stmt.true_statement.emit (this);
      32              : 
      33         4905 :                 if (stmt.false_statement != null) {
      34         2411 :                         ccode.add_else ();
      35         2411 :                         stmt.false_statement.emit (this);
      36              :                 }
      37              : 
      38         4905 :                 ccode.close ();
      39              :         }
      40              : 
      41           56 :         void visit_string_switch_statement (SwitchStatement stmt) {
      42              :                 // we need a temporary variable to save the property value
      43           28 :                 var temp_value = create_temp_value (stmt.expression.value_type, false, stmt);
      44          628 :                 var ctemp = get_cvalue_ (temp_value);
      45              : 
      46           28 :                 var cinit = new CCodeAssignment (ctemp, get_cvalue (stmt.expression));
      47           28 :                 var czero = new CCodeConstant ("0");
      48              : 
      49           28 :                 var free_call = new CCodeFunctionCall (new CCodeIdentifier ("g_free"));
      50           28 :                 free_call.add_argument (ctemp);
      51              : 
      52           28 :                 var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeConstant ("NULL"), ctemp);
      53           28 :                 var cquark = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_string"));
      54           28 :                 cquark.add_argument (ctemp);
      55              : 
      56           28 :                 var ccond = new CCodeConditionalExpression (cisnull, new CCodeConstant ("0"), cquark);
      57              : 
      58           28 :                 int label_temp_id = next_temp_var_id++;
      59              : 
      60           28 :                 temp_value = create_temp_value (gquark_type, true, stmt);
      61              : 
      62           28 :                 int label_count = 0;
      63              : 
      64          310 :                 foreach (SwitchSection section in stmt.get_sections ()) {
      65          152 :                         if (section.has_default_label ()) {
      66           22 :                                 continue;
      67              :                         }
      68              : 
      69          410 :                         foreach (SwitchLabel label in section.get_labels ()) {
      70          140 :                                 label.expression.emit (this);
      71          140 :                                 var cexpr = get_cvalue (label.expression);
      72              : 
      73          140 :                                 if (is_constant_ccode_expression (cexpr)) {
      74          140 :                                         var cname = "_tmp%d_label%d".printf (label_temp_id, label_count++);
      75              : 
      76          140 :                                         ccode.add_declaration (get_ccode_name (gquark_type), new CCodeVariableDeclarator (cname, czero), CCodeModifiers.STATIC);
      77              :                                 }
      78              :                         }
      79              :                 }
      80              : 
      81           28 :                 ccode.add_expression (cinit);
      82              : 
      83           56 :                 ctemp = get_cvalue_ (temp_value);
      84           28 :                 cinit = new CCodeAssignment (ctemp, ccond);
      85              : 
      86           28 :                 ccode.add_expression (cinit);
      87              : 
      88           28 :                 if (stmt.expression.value_type.value_owned) {
      89              :                         // free owned string
      90            1 :                         ccode.add_expression (free_call);
      91              :                 }
      92              : 
      93           28 :                 SwitchSection default_section = null;
      94           28 :                 label_count = 0;
      95              : 
      96           28 :                 int n = 0;
      97              : 
      98          310 :                 foreach (SwitchSection section in stmt.get_sections ()) {
      99          152 :                         if (section.has_default_label ()) {
     100          566 :                                 default_section = section;
     101           22 :                                 continue;
     102              :                         }
     103              : 
     104          130 :                         CCodeBinaryExpression cor = null;
     105          410 :                         foreach (SwitchLabel label in section.get_labels ()) {
     106          140 :                                 label.expression.emit (this);
     107          140 :                                 var cexpr = get_cvalue (label.expression);
     108              : 
     109          280 :                                 if (is_constant_ccode_expression (cexpr)) {
     110          140 :                                         var cname = new CCodeIdentifier ("_tmp%d_label%d".printf (label_temp_id, label_count++));
     111          140 :                                         var ccondition = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, czero, cname);
     112          140 :                                         var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_static_string"));
     113          140 :                                         cinit = new CCodeAssignment (cname, ccall);
     114              : 
     115          140 :                                         ccall.add_argument (cexpr);
     116              : 
     117          140 :                                         cexpr = new CCodeConditionalExpression (ccondition, cname, cinit);
     118              :                                 } else {
     119            0 :                                         var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_string"));
     120            0 :                                         ccall.add_argument (cexpr);
     121            0 :                                         cexpr = ccall;
     122              :                                 }
     123              : 
     124          140 :                                 var ccmp = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ctemp, cexpr);
     125              : 
     126          140 :                                 if (cor == null) {
     127          270 :                                         cor = ccmp;
     128              :                                 } else {
     129           10 :                                         cor = new CCodeBinaryExpression (CCodeBinaryOperator.OR, cor, ccmp);
     130              :                                 }
     131              :                         }
     132              : 
     133          130 :                         if (n > 0) {
     134          102 :                                 ccode.else_if (cor);
     135              :                         } else {
     136           28 :                                 ccode.open_if (cor);
     137              :                         }
     138              : 
     139          130 :                         ccode.open_switch (new CCodeConstant ("0"));
     140          130 :                         ccode.add_default ();
     141              : 
     142          130 :                         section.emit (this);
     143              : 
     144          130 :                         ccode.close ();
     145              : 
     146          130 :                         n++;
     147              :                 }
     148              : 
     149           28 :                 if (default_section != null) {
     150           22 :                         if (n > 0) {
     151           22 :                                 ccode.add_else ();
     152              :                         }
     153              : 
     154           22 :                         ccode.open_switch (new CCodeConstant ("0"));
     155           22 :                         ccode.add_default ();
     156              : 
     157           22 :                         default_section.emit (this);
     158              : 
     159           22 :                         ccode.close ();
     160              :                 }
     161              : 
     162           28 :                 if (n > 0) {
     163           28 :                         ccode.close ();
     164              :                 }
     165              :         }
     166              : 
     167           88 :         public override void visit_switch_statement (SwitchStatement stmt) {
     168           88 :                 if (stmt.expression.value_type.compatible (string_type)) {
     169           28 :                         visit_string_switch_statement (stmt);
     170           28 :                         return;
     171              :                 }
     172              : 
     173           60 :                 ccode.open_switch (get_cvalue (stmt.expression));
     174              : 
     175           60 :                 bool has_default = false;
     176              : 
     177          668 :                 foreach (SwitchSection section in stmt.get_sections ()) {
     178          304 :                         if (section.has_default_label ()) {
     179           35 :                                 ccode.add_default ();
     180           35 :                                 has_default = true;
     181              :                         }
     182          304 :                         section.emit (this);
     183              :                 }
     184              : 
     185           60 :                 if (!has_default) {
     186              :                         // silence C compiler
     187           25 :                         ccode.add_default ();
     188           25 :                         ccode.add_break ();
     189              :                 }
     190              : 
     191           60 :                 ccode.close ();
     192              :         }
     193              : 
     194          531 :         public override void visit_switch_label (SwitchLabel label) {
     195          531 :                 if (((SwitchStatement) label.section.parent_node).expression.value_type.compatible (string_type)) {
     196              :                         return;
     197              :                 }
     198              : 
     199          369 :                 if (label.expression != null) {
     200          334 :                         label.expression.emit (this);
     201              : 
     202          334 :                         visit_end_full_expression (label.expression);
     203              : 
     204          334 :                         ccode.add_case (get_cvalue (label.expression));
     205              :                 }
     206              :         }
     207              : 
     208          465 :         public override void visit_loop_statement (LoopStatement stmt) {
     209          465 :                 if (context.profile == Profile.GOBJECT) {
     210          465 :                         ccode.open_while (new CCodeConstant ("TRUE"));
     211              :                 } else {
     212            0 :                         cfile.add_include ("stdbool.h");
     213            0 :                         ccode.open_while (new CCodeConstant ("true"));
     214              :                 }
     215              : 
     216          465 :                 stmt.body.emit (this);
     217              : 
     218          465 :                 ccode.close ();
     219              :         }
     220              : 
     221          318 :         public override void visit_foreach_statement (ForeachStatement stmt) {
     222          159 :                 ccode.open_block ();
     223              : 
     224          159 :                 var collection_backup = stmt.collection_variable;
     225          159 :                 var collection_type = collection_backup.variable_type;
     226              : 
     227          159 :                 var array_type = collection_type as ArrayType;
     228          113 :                 if (array_type != null) {
     229              :                         // avoid assignment issues
     230          113 :                         array_type.inline_allocated = false;
     231          113 :                         array_type.fixed_length = false;
     232              :                 }
     233              : 
     234          159 :                 visit_local_variable (collection_backup);
     235          159 :                 ccode.add_assignment (get_variable_cexpression (get_local_cname (collection_backup)), get_cvalue (stmt.collection));
     236              : 
     237          159 :                 if (stmt.tree_can_fail && stmt.collection.tree_can_fail) {
     238              :                         // exception handling
     239            0 :                         add_simple_check (stmt.collection);
     240              :                 }
     241              : 
     242          272 :                 if (stmt.collection.value_type is ArrayType) {
     243          226 :                         array_type = (ArrayType) stmt.collection.value_type;
     244              : 
     245          113 :                         var array_len = get_variable_cexpression (get_array_length_cname (get_local_cname (collection_backup), 1));
     246              : 
     247              :                         // store array length for use by _vala_array_free
     248          113 :                         ccode.add_assignment (array_len, get_array_length_cexpression (stmt.collection));
     249              : 
     250          113 :                         var iterator_variable = new LocalVariable (array_type.length_type.copy (), stmt.variable_name + "_it");
     251          113 :                         visit_local_variable (iterator_variable);
     252          113 :                         var it_name = get_local_cname (iterator_variable);
     253              : 
     254          113 :                         var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, get_variable_cexpression (it_name), array_len);
     255              : 
     256          113 :                         ccode.open_for (new CCodeAssignment (get_variable_cexpression (it_name), new CCodeConstant ("0")),
     257              :                                            ccond,
     258              :                                            new CCodeAssignment (get_variable_cexpression (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, get_variable_cexpression (it_name), new CCodeConstant ("1"))));
     259              : 
     260          113 :                         CCodeExpression element_expr = new CCodeElementAccess (get_variable_cexpression (get_local_cname (collection_backup)), get_variable_cexpression (it_name));
     261              : 
     262          113 :                         var element_type = array_type.element_type.copy ();
     263          113 :                         element_type.value_owned = false;
     264          226 :                         element_expr = get_cvalue_ (transform_value (new GLibValue (element_type, element_expr, true), stmt.type_reference, stmt));
     265              : 
     266          113 :                         visit_local_variable (stmt.element_variable);
     267          113 :                         ccode.add_assignment (get_variable_cexpression (get_local_cname (stmt.element_variable)), element_expr);
     268              : 
     269              :                         // set array length for stacked arrays
     270          113 :                         if (stmt.type_reference is ArrayType) {
     271            0 :                                 var inner_array_type = (ArrayType) stmt.type_reference;
     272            0 :                                 for (int dim = 1; dim <= inner_array_type.rank; dim++) {
     273            0 :                                         ccode.add_assignment (get_variable_cexpression (get_array_length_cname (get_local_cname (stmt.element_variable), dim)), new CCodeConstant ("-1"));
     274              :                                 }
     275              :                         }
     276              : 
     277          113 :                         stmt.body.emit (this);
     278              : 
     279          113 :                         ccode.close ();
     280           50 :                 } else if (stmt.collection.value_type.compatible (new ObjectType (garray_type))) {
     281              :                         // iterating over a GArray
     282              : 
     283            4 :                         var iterator_variable = new LocalVariable (uint_type.copy (), "%s_index".printf (stmt.variable_name));
     284            4 :                         visit_local_variable (iterator_variable);
     285            4 :                         var arr_index = get_variable_cname (get_local_cname (iterator_variable));
     286              : 
     287            4 :                         var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, get_variable_cexpression (arr_index), new CCodeMemberAccess.pointer (get_variable_cexpression (get_local_cname (collection_backup)), "len"));
     288              : 
     289            4 :                         ccode.open_for (new CCodeAssignment (get_variable_cexpression (arr_index), new CCodeConstant ("0")),
     290              :                                            ccond,
     291              :                                            new CCodeAssignment (get_variable_cexpression (arr_index), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, get_variable_cexpression (arr_index), new CCodeConstant ("1"))));
     292              : 
     293            4 :                         var get_item = new CCodeFunctionCall (new CCodeIdentifier ("g_array_index"));
     294            4 :                         get_item.add_argument (get_variable_cexpression (get_local_cname (collection_backup)));
     295            4 :                         get_item.add_argument (new CCodeIdentifier (get_ccode_name (stmt.type_reference)));
     296            4 :                         get_item.add_argument (get_variable_cexpression (arr_index));
     297              : 
     298            4 :                         if (collection_type.get_type_arguments ().size != 1) {
     299            0 :                                 Report.error (stmt.source_reference, "internal error: missing generic type argument");
     300            0 :                                 stmt.error = true;
     301            0 :                                 return;
     302              :                         }
     303              : 
     304            4 :                         var element_type = collection_type.get_type_arguments ().get (0).copy ();
     305            4 :                         element_type.value_owned = false;
     306            8 :                         var element_expr = get_cvalue_ (transform_value (new GLibValue (element_type, get_item, true), stmt.type_reference, stmt));
     307              : 
     308            4 :                         visit_local_variable (stmt.element_variable);
     309            4 :                         ccode.add_assignment (get_variable_cexpression (get_local_cname (stmt.element_variable)), element_expr);
     310              : 
     311            4 :                         stmt.body.emit (this);
     312              : 
     313            4 :                         ccode.close ();
     314           73 :                 } else if (stmt.collection.value_type.compatible (new ObjectType (glist_type)) || stmt.collection.value_type.compatible (new ObjectType (gslist_type))) {
     315              :                         // iterating over a GList or GSList
     316              : 
     317           31 :                         var iterator_variable = new LocalVariable (collection_type.copy (), stmt.variable_name + "_it");
     318           31 :                         visit_local_variable (iterator_variable);
     319           31 :                         var it_name = get_local_cname (iterator_variable);
     320              : 
     321           31 :                         var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, get_variable_cexpression (it_name), new CCodeConstant ("NULL"));
     322              : 
     323           31 :                         ccode.open_for (new CCodeAssignment (get_variable_cexpression (it_name), get_variable_cexpression (get_local_cname (collection_backup))),
     324              :                                                         ccond,
     325              :                                                         new CCodeAssignment (get_variable_cexpression (it_name), new CCodeMemberAccess.pointer (get_variable_cexpression (it_name), "next")));
     326              : 
     327           31 :                         CCodeExpression element_expr = new CCodeMemberAccess.pointer (get_variable_cexpression (it_name), "data");
     328              : 
     329           31 :                         if (collection_type.get_type_arguments ().size != 1) {
     330            0 :                                 Report.error (stmt.source_reference, "internal error: missing generic type argument");
     331            0 :                                 stmt.error = true;
     332            0 :                                 return;
     333              :                         }
     334              : 
     335           31 :                         var element_data_type = collection_type.get_type_arguments ().get (0).copy ();
     336           31 :                         element_data_type.value_owned = false;
     337           31 :                         element_expr = convert_from_generic_pointer (element_expr, element_data_type);
     338           62 :                         element_expr = get_cvalue_ (transform_value (new GLibValue (element_data_type, element_expr), stmt.type_reference, stmt));
     339              : 
     340           31 :                         visit_local_variable (stmt.element_variable);
     341           31 :                         ccode.add_assignment (get_variable_cexpression (get_local_cname (stmt.element_variable)), element_expr);
     342              : 
     343           31 :                         stmt.body.emit (this);
     344              : 
     345           31 :                         ccode.close ();
     346           17 :                 } else if (stmt.collection.value_type.compatible (new ObjectType ((Class) genericarray_type))) {
     347              :                         // iterating over a GenericArray / GPtrArray
     348              : 
     349            6 :                         var iterator_variable = new LocalVariable (uint_type.copy (), "%s_index".printf (stmt.variable_name));
     350            6 :                         visit_local_variable (iterator_variable);
     351            6 :                         var arr_index = get_variable_cname (get_local_cname (iterator_variable));
     352              : 
     353            6 :                         var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, get_variable_cexpression (arr_index), new CCodeMemberAccess.pointer (get_variable_cexpression (get_local_cname (collection_backup)), "len"));
     354              : 
     355            6 :                         ccode.open_for (new CCodeAssignment (get_variable_cexpression (arr_index), new CCodeConstant ("0")),
     356              :                                            ccond,
     357              :                                            new CCodeAssignment (get_variable_cexpression (arr_index), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, get_variable_cexpression (arr_index), new CCodeConstant ("1"))));
     358              : 
     359            6 :                         var get_item = new CCodeFunctionCall (new CCodeIdentifier ("g_ptr_array_index"));
     360            6 :                         get_item.add_argument (get_variable_cexpression (get_local_cname (collection_backup)));
     361            6 :                         get_item.add_argument (get_variable_cexpression (arr_index));
     362              : 
     363            6 :                         CCodeExpression element_expr = get_item;
     364            6 :                         element_expr = convert_from_generic_pointer (element_expr, stmt.element_variable.variable_type);
     365              : 
     366            6 :                         if (stmt.type_reference.value_owned) {
     367            6 :                                 element_expr = get_cvalue_ (copy_value (new GLibValue (stmt.type_reference, element_expr), stmt.element_variable));
     368              :                         }
     369              : 
     370            6 :                         visit_local_variable (stmt.element_variable);
     371            6 :                         ccode.add_assignment (get_variable_cexpression (get_local_cname (stmt.element_variable)), element_expr);
     372              : 
     373            6 :                         stmt.body.emit (this);
     374              : 
     375            6 :                         ccode.close ();
     376            7 :                 } else if (stmt.collection.value_type.compatible (new ObjectType (gvaluearray_type))) {
     377              :                         // iterating over a GValueArray
     378              : 
     379            2 :                         var iterator_variable = new LocalVariable (uint_type.copy (), "%s_index".printf (stmt.variable_name));
     380            2 :                         visit_local_variable (iterator_variable);
     381            2 :                         var arr_index = get_variable_cname (get_local_cname (iterator_variable));
     382              : 
     383            2 :                         var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, get_variable_cexpression (arr_index), new CCodeMemberAccess.pointer (get_variable_cexpression (get_local_cname (collection_backup)), "n_values"));
     384              : 
     385            2 :                         ccode.open_for (new CCodeAssignment (get_variable_cexpression (arr_index), new CCodeConstant ("0")),
     386              :                                            ccond,
     387              :                                            new CCodeAssignment (get_variable_cexpression (arr_index), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, get_variable_cexpression (arr_index), new CCodeConstant ("1"))));
     388              : 
     389            2 :                         var get_item = new CCodeFunctionCall (new CCodeIdentifier ("g_value_array_get_nth"));
     390            2 :                         get_item.add_argument (get_variable_cexpression (get_local_cname (collection_backup)));
     391            2 :                         get_item.add_argument (get_variable_cexpression (arr_index));
     392              : 
     393            2 :                         CCodeExpression element_expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_item);
     394              : 
     395            2 :                         if (stmt.type_reference.value_owned) {
     396            2 :                                 element_expr = get_cvalue_ (copy_value (new GLibValue (stmt.type_reference, element_expr), new StructValueType (gvalue_type)));
     397              :                         }
     398              : 
     399            2 :                         visit_local_variable (stmt.element_variable);
     400            2 :                         ccode.add_assignment (get_variable_cexpression (get_local_cname (stmt.element_variable)), element_expr);
     401              : 
     402            2 :                         stmt.body.emit (this);
     403              : 
     404            2 :                         ccode.close ();
     405            5 :                 } else if (stmt.collection.value_type.compatible (new ObjectType (gsequence_type))) {
     406              :                         // iterating over a GSequence
     407              : 
     408            2 :                         var iterator_variable = new LocalVariable (new ObjectType (gsequence_iter_type), "%s_iter".printf (stmt.variable_name));
     409            2 :                         visit_local_variable (iterator_variable);
     410            2 :                         var sequence_iter = get_variable_cname (get_local_cname (iterator_variable));
     411              : 
     412            2 :                         var ccond_is_end = new CCodeFunctionCall (new CCodeIdentifier ("g_sequence_iter_is_end"));
     413            2 :                         ccond_is_end.add_argument (get_variable_cexpression (sequence_iter));
     414            2 :                         var ccond = new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, ccond_is_end);
     415            2 :                         var cbegin = new CCodeFunctionCall (new CCodeIdentifier ("g_sequence_get_begin_iter"));
     416            2 :                         cbegin.add_argument (get_variable_cexpression (get_local_cname (collection_backup)));
     417            2 :                         var cnext = new CCodeFunctionCall (new CCodeIdentifier ("g_sequence_iter_next"));
     418            2 :                         cnext.add_argument (get_variable_cexpression (sequence_iter));
     419              : 
     420            2 :                         ccode.open_for (new CCodeAssignment (get_variable_cexpression (sequence_iter), cbegin),
     421              :                                         ccond,
     422              :                                         new CCodeAssignment (get_variable_cexpression (sequence_iter), cnext));
     423              : 
     424            2 :                         var get_item = new CCodeFunctionCall (new CCodeIdentifier ("g_sequence_get"));
     425            2 :                         get_item.add_argument (get_variable_cexpression (sequence_iter));
     426              : 
     427            2 :                         CCodeExpression element_expr = get_item;
     428              : 
     429            2 :                         if (collection_type.get_type_arguments ().size != 1) {
     430            0 :                                 Report.error (stmt.source_reference, "internal error: missing generic type argument");
     431            0 :                                 stmt.error = true;
     432            0 :                                 return;
     433              :                         }
     434              : 
     435            2 :                         var element_type = collection_type.get_type_arguments ().get (0).copy ();
     436            2 :                         element_type.value_owned = false;
     437            2 :                         element_expr = convert_from_generic_pointer (element_expr, element_type);
     438            4 :                         element_expr = get_cvalue_ (transform_value (new GLibValue (element_type, element_expr), stmt.type_reference, stmt));
     439              : 
     440            2 :                         visit_local_variable (stmt.element_variable);
     441            2 :                         ccode.add_assignment (get_variable_cexpression (get_local_cname (stmt.element_variable)), element_expr);
     442              : 
     443            2 :                         stmt.body.emit (this);
     444              : 
     445            2 :                         ccode.close ();
     446            2 :                 } else if (stmt.collection.value_type.compatible (string_type)) {
     447              :                         // iterating over a string
     448              : 
     449            1 :                         var validate = new CCodeFunctionCall (new CCodeIdentifier ("g_utf8_validate"));
     450            1 :                         validate.add_argument (get_variable_cexpression (get_local_cname (collection_backup)));
     451            1 :                         validate.add_argument (new CCodeConstant ("-1"));
     452            1 :                         validate.add_argument (new CCodeConstant ("NULL"));
     453            1 :                         var cassert = new CCodeFunctionCall (new CCodeIdentifier ("_vala_warn_if_fail"));
     454            1 :                         cassert.add_argument (validate);
     455            1 :                         cassert.add_argument (new CCodeConstant ("\"Invalid UTF-8 string\""));
     456            1 :                         requires_assert = true;
     457            1 :                         ccode.add_expression (cassert);
     458              : 
     459            1 :                         var iterator_variable = new LocalVariable (collection_type, "%s_iter".printf (stmt.variable_name));
     460            1 :                         visit_local_variable (iterator_variable);
     461            1 :                         var string_iter = get_variable_cname (get_local_cname (iterator_variable));
     462              : 
     463            1 :                         var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_variable_cexpression (string_iter)), new CCodeConstant ("'\\0'"));
     464            1 :                         var next_char_call = new CCodeFunctionCall (new CCodeIdentifier ("g_utf8_next_char"));
     465            1 :                         next_char_call.add_argument (get_variable_cexpression (string_iter));
     466              : 
     467            1 :                         ccode.open_for (new CCodeAssignment (get_variable_cexpression (string_iter), get_variable_cexpression (collection_backup.name)),
     468              :                                         ccond,
     469              :                                         new CCodeAssignment (get_variable_cexpression (string_iter), next_char_call));
     470              : 
     471            1 :                         var element_expr = new CCodeFunctionCall (new CCodeIdentifier ("g_utf8_get_char"));
     472            1 :                         element_expr.add_argument (get_variable_cexpression (string_iter));
     473              : 
     474            1 :                         visit_local_variable (stmt.element_variable);
     475            1 :                         ccode.add_assignment (get_variable_cexpression (get_local_cname (stmt.element_variable)), element_expr);
     476              : 
     477            1 :                         stmt.body.emit (this);
     478              : 
     479            1 :                         ccode.close ();
     480              :                 } else {
     481            0 :                         Report.error (stmt.source_reference, "internal error: unsupported collection type");
     482            0 :                         stmt.error = true;
     483            0 :                         return;
     484              :                 }
     485              : 
     486          477 :                 foreach (LocalVariable local in stmt.get_local_variables ()) {
     487          159 :                         if (requires_destroy (local.variable_type)) {
     488           15 :                                 ccode.add_expression (destroy_local (local));
     489              :                         }
     490              :                 }
     491              : 
     492          159 :                 ccode.close ();
     493              :         }
     494              : 
     495          808 :         public override void visit_break_statement (BreakStatement stmt) {
     496          808 :                 append_local_free (current_symbol, stmt);
     497              : 
     498          808 :                 ccode.add_break ();
     499              :         }
     500              : 
     501           41 :         public override void visit_continue_statement (ContinueStatement stmt) {
     502           41 :                 append_local_free (current_symbol, stmt);
     503              : 
     504           41 :                 ccode.add_continue ();
     505              :         }
     506              : }
     507              : 
        

Generated by: LCOV version 2.0-1