LCOV - code coverage report
Current view: top level - gcc/m2/gm2-gcc - m2statement.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 75.4 % 334 252
Test Date: 2026-02-28 14:20:25 Functions: 71.4 % 42 30
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* m2statement.cc provides an interface to GCC statement trees.
       2              : 
       3              : Copyright (C) 2012-2026 Free Software Foundation, Inc.
       4              : Contributed by Gaius Mulley <gaius@glam.ac.uk>.
       5              : 
       6              : This file is part of GNU Modula-2.
       7              : 
       8              : GNU Modula-2 is free software; you can redistribute it and/or modify
       9              : it under the terms of the GNU General Public License as published by
      10              : the Free Software Foundation; either version 3, or (at your option)
      11              : any later version.
      12              : 
      13              : GNU Modula-2 is distributed in the hope that it will be useful, but
      14              : WITHOUT ANY WARRANTY; without even the implied warranty of
      15              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16              : General Public License for more details.
      17              : 
      18              : You should have received a copy of the GNU General Public License
      19              : along with GNU Modula-2; see the file COPYING3.  If not see
      20              : <http://www.gnu.org/licenses/>.  */
      21              : 
      22              : #include "gcc-consolidation.h"
      23              : 
      24              : #include "../gm2-lang.h"
      25              : #include "../m2-tree.h"
      26              : 
      27              : /* Prototypes.  */
      28              : 
      29              : #define m2statement_c
      30              : #include "m2assert.h"
      31              : #include "m2block.h"
      32              : #include "m2decl.h"
      33              : #include "m2expr.h"
      34              : #include "m2statement.h"
      35              : #include "m2tree.h"
      36              : #include "m2treelib.h"
      37              : #include "m2type.h"
      38              : #include "m2convert.h"
      39              : #include "m2builtins.h"
      40              : #include "m2pp.h"
      41              : 
      42              : static GTY (()) tree param_list = NULL_TREE; /* Ready for the next time we
      43              :                                                 call/define a function.  */
      44              : static GTY (()) tree last_function = NULL_TREE;
      45              : 
      46              : 
      47              : /* BuildStartFunctionCode generate function entry code.  */
      48              : 
      49              : void
      50       105973 : m2statement_BuildStartFunctionCode (location_t location, tree fndecl,
      51              :                                     bool isexported, bool isinline)
      52              : {
      53       105973 :   tree param_decl;
      54              : 
      55       105973 :   ASSERT_BOOL (isexported);
      56       105973 :   ASSERT_BOOL (isinline);
      57              :   /* Announce we are compiling this function.  */
      58       105973 :   announce_function (fndecl);
      59              : 
      60              :   /* Set up to compile the function and enter it.  */
      61              : 
      62       105973 :   DECL_INITIAL (fndecl) = NULL_TREE;
      63              : 
      64       105973 :   current_function_decl = fndecl;
      65       105973 :   m2block_pushFunctionScope (fndecl);
      66       105973 :   m2statement_SetBeginLocation (location);
      67              : 
      68       105973 :   ASSERT_BOOL ((cfun != NULL));
      69              :   /* Initialize the RTL code for the function.  */
      70       105973 :   allocate_struct_function (fndecl, false);
      71              :   /* Begin the statement tree for this function.  */
      72       105973 :   DECL_SAVED_TREE (fndecl) = NULL_TREE;
      73              : 
      74              :   /* Set the context of these parameters to this function.  */
      75       282884 :   for (param_decl = DECL_ARGUMENTS (fndecl); param_decl;
      76       176911 :        param_decl = TREE_CHAIN (param_decl))
      77       176911 :     DECL_CONTEXT (param_decl) = fndecl;
      78              : 
      79              :   /* This function exists in static storage.  (This does not mean
      80              :   `static' in the C sense!) */
      81       105973 :   TREE_STATIC (fndecl) = 1;
      82       105973 :   TREE_PUBLIC (fndecl) = isexported;
      83              :   /* We could do better here by detecting ADR
      84              :      or type PROC used on this function.  --fixme--  */
      85       105973 :   TREE_ADDRESSABLE (fndecl) = 1;
      86       105973 :   DECL_DECLARED_INLINE_P (fndecl) = 0; /* isinline;  */
      87       105973 : }
      88              : 
      89              : /* BuildEndFunctionCode generates the function epilogue.  */
      90              : 
      91              : void
      92       105961 : m2statement_BuildEndFunctionCode (location_t location, tree fndecl, bool nested)
      93              : {
      94       105961 :   tree block = DECL_INITIAL (fndecl);
      95              : 
      96       105961 :   BLOCK_SUPERCONTEXT (block) = fndecl;
      97              : 
      98              :   /* Must mark the RESULT_DECL as being in this function.  */
      99       105961 :   DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
     100              : 
     101              :   /* And attach it to the function.  */
     102       105961 :   DECL_INITIAL (fndecl) = block;
     103              : 
     104       105961 :   m2block_finishFunctionCode (fndecl);
     105       105961 :   m2statement_SetEndLocation (location);
     106              : 
     107       105961 :   m2pp_dump_gimple (M2PP_DUMP_PRE_GENERICIZE, fndecl);
     108       105961 :   gm2_genericize (fndecl);
     109       105961 :   if (nested)
     110          744 :     (void)cgraph_node::get_create (fndecl);
     111              :   else
     112              :     {
     113       105217 :       m2pp_dump_gimple (M2PP_DUMP_POST_GENERICIZE, fndecl);
     114       105217 :       cgraph_node::finalize_function (fndecl, false);
     115              :     }
     116              : 
     117       105961 :   m2block_popFunctionScope ();
     118              : 
     119              :   /* We're leaving the context of this function, so zap cfun.  It's
     120              :      still in DECL_STRUCT_FUNCTION, and we'll restore it in
     121              :      tree_rest_of_compilation.  */
     122       105961 :   set_cfun (NULL);
     123       105961 :   current_function_decl = NULL;
     124       105961 : }
     125              : 
     126              : /* BuildPushFunctionContext pushes the current function context.
     127              :    Maps onto push_function_context in ../function.cc.  */
     128              : 
     129              : void
     130        76755 : m2statement_BuildPushFunctionContext (void)
     131              : {
     132        76755 :   push_function_context ();
     133        76755 : }
     134              : 
     135              : /* BuildPopFunctionContext pops the current function context.  Maps
     136              :    onto pop_function_context in ../function.cc.  */
     137              : 
     138              : void
     139        76755 : m2statement_BuildPopFunctionContext (void)
     140              : {
     141        76755 :   pop_function_context ();
     142        76755 : }
     143              : 
     144              : void
     145       182728 : m2statement_SetBeginLocation (location_t location)
     146              : {
     147       182728 :   if (cfun != NULL)
     148            0 :     cfun->function_start_locus = location;
     149       182728 : }
     150              : 
     151              : void
     152       105961 : m2statement_SetEndLocation (location_t location)
     153              : {
     154       105961 :   if (cfun != NULL)
     155       105961 :     cfun->function_end_locus = location;
     156       105961 : }
     157              : 
     158              : /* copy_record_fields copy each record field from right to left.  */
     159              : 
     160              : static
     161              : void
     162           72 : copy_record_fields (location_t location, tree left, tree right)
     163              : {
     164           72 :   unsigned int i;
     165           72 :   tree right_value;
     166           72 :   tree left_type = TREE_TYPE (left);
     167           72 :   vec<constructor_elt, va_gc> *values = CONSTRUCTOR_ELTS (right);
     168          204 :   FOR_EACH_CONSTRUCTOR_VALUE (values, i, right_value)
     169              :     {
     170          132 :       tree left_field = m2treelib_get_field_no (left_type, NULL_TREE, false, i);
     171          132 :       tree left_ref = m2expr_BuildComponentRef (location, left, left_field);
     172          132 :       m2statement_CopyByField (location, left_ref, right_value);
     173              :     }
     174           72 : }
     175              : 
     176              : /* copy_array copy each element of an array from array right to array left.  */
     177              : 
     178              : static
     179              : void
     180            0 : copy_array (location_t location, tree left, tree right)
     181              : {
     182            0 :   unsigned int i;
     183            0 :   tree value;
     184            0 :   vec<constructor_elt, va_gc> *values = CONSTRUCTOR_ELTS (right);
     185            0 :   tree array_type = TREE_TYPE (left);
     186            0 :   tree index_type = TYPE_DOMAIN (array_type);
     187            0 :   tree elt_type = TREE_TYPE (array_type);
     188            0 :   tree low_indice = TYPE_MIN_VALUE (index_type);
     189            0 :   low_indice
     190            0 :       = m2convert_BuildConvert (location, index_type, low_indice, false);
     191            0 :   FOR_EACH_CONSTRUCTOR_VALUE (values, i, value)
     192              :     {
     193            0 :       tree idx = m2decl_BuildIntegerConstant (i);
     194            0 :       idx = m2convert_BuildConvert (location, index_type, idx, false);
     195            0 :       tree array_ref = build4_loc (location, ARRAY_REF, elt_type, left,
     196              :                                    idx, low_indice, NULL_TREE);
     197            0 :       m2statement_CopyByField (location, array_ref, value);
     198              :     }
     199            0 : }
     200              : 
     201              : /* copy_array cst into left using strncpy.  */
     202              : 
     203              : static
     204              : void
     205           84 : copy_strncpy (location_t location, tree left, tree cst)
     206              : {
     207           84 :   tree result = m2builtins_BuiltinStrNCopy (location,
     208              :                                             m2expr_BuildAddr (location, left, false),
     209              :                                             m2expr_BuildAddr (location, cst, false),
     210           84 :                                             m2decl_BuildIntegerConstant (m2expr_StringLength (cst)));
     211           84 :   TREE_SIDE_EFFECTS (result) = true;
     212           84 :   TREE_USED (left) = true;
     213           84 :   TREE_USED (cst) = true;
     214           84 :   add_stmt (location, result);
     215           84 : }
     216              : 
     217              : /* copy_memcpy copy right into left using builtin_memcpy.  */
     218              : 
     219              : static
     220              : void
     221            0 : copy_memcpy (location_t location, tree left, tree right)
     222              : {
     223            0 :   tree result = m2builtins_BuiltinMemCopy (location,
     224              :                                            m2expr_BuildAddr (location, left, false),
     225              :                                            m2expr_BuildAddr (location, right, false),
     226              :                                            m2expr_GetSizeOf (location, left));
     227            0 :   TREE_SIDE_EFFECTS (result) = true;
     228            0 :   TREE_USED (left) = true;
     229            0 :   TREE_USED (right) = true;
     230            0 :   add_stmt (location, result);
     231            0 : }
     232              : 
     233              : /* CopyByField_Lower copy right to left using memcpy for unions,
     234              :    strncpy for string cst, field assignment for records,
     235              :    array element assignment for array constructors.  For all
     236              :    other types it uses BuildAssignmentStatement.  */
     237              : 
     238              : static
     239              : void
     240          156 : CopyByField_Lower (location_t location,
     241              :                    tree left, tree right)
     242              : {
     243          156 :   tree left_type = TREE_TYPE (left);
     244          156 :   enum tree_code right_code = TREE_CODE (right);
     245          156 :   enum tree_code left_code = TREE_CODE (left_type);
     246              : 
     247          156 :   if (left_code == RECORD_TYPE && right_code == CONSTRUCTOR)
     248           72 :     copy_record_fields (location, left, right);
     249           84 :   else if (left_code == ARRAY_TYPE && right_code == CONSTRUCTOR)
     250            0 :     copy_array (location, left, right);
     251           84 :   else if (left_code == UNION_TYPE && right_code == CONSTRUCTOR)
     252            0 :     copy_memcpy (location, left, right);
     253           84 :   else if (right_code == STRING_CST)
     254           84 :     copy_strncpy (location, left, right);
     255              :   else
     256            0 :     m2statement_BuildAssignmentStatement (location, left, right);
     257          156 : }
     258              : 
     259              : /* CopyByField recursively checks each field to ensure GCC
     260              :    type equivalence and if so it uses assignment.
     261              :    Otherwise use strncpy or memcpy depending upon type.  */
     262              : 
     263              : void
     264          204 : m2statement_CopyByField (location_t location, tree des, tree expr)
     265              : {
     266          204 :   if (m2type_IsGccStrictTypeEquivalent (des, expr))
     267           48 :     m2statement_BuildAssignmentStatement (location, des, expr);
     268              :   else
     269          156 :     CopyByField_Lower (location, des, expr);
     270          204 : }
     271              : 
     272              : /* BuildAssignmentTree builds the assignment of, des, and, expr.
     273              :    It returns, des.  */
     274              : 
     275              : tree
     276       683718 : m2statement_BuildAssignmentTree (location_t location, tree des, tree expr)
     277              : {
     278       683718 :   tree result;
     279              : 
     280       683718 :   m2assert_AssertLocation (location);
     281      1378560 :   STRIP_TYPE_NOPS (expr);
     282              : 
     283       683718 :   if (TREE_CODE (expr) == FUNCTION_DECL)
     284          672 :     result = build2 (MODIFY_EXPR, TREE_TYPE (des), des,
     285              :                      m2expr_BuildAddr (location, expr, false));
     286              :   else
     287              :     {
     288       683046 :       gcc_assert (TREE_CODE (TREE_TYPE (des)) != TYPE_DECL);
     289       683046 :       if (TREE_TYPE (expr) == TREE_TYPE (des))
     290       410699 :         result = build2 (MODIFY_EXPR, TREE_TYPE (des), des, expr);
     291              :       else
     292       544694 :         result = build2 (
     293       272347 :             MODIFY_EXPR, TREE_TYPE (des), des,
     294       272347 :             m2convert_BuildConvert (location, TREE_TYPE (des), expr, false));
     295              :     }
     296              : 
     297       683718 :   TREE_SIDE_EFFECTS (result) = true;
     298       683718 :   TREE_USED (des) = true;
     299       683718 :   TREE_USED (expr) = true;
     300       683718 :   add_stmt (location, result);
     301       683718 :   return des;
     302              : }
     303              : 
     304              : /* BuildAssignmentStatement builds the assignment of, des, and, expr.  */
     305              : 
     306              : void
     307       682674 : m2statement_BuildAssignmentStatement (location_t location, tree des, tree expr)
     308              : {
     309       682674 :   m2statement_BuildAssignmentTree (location, des, expr);
     310       682674 : }
     311              : 
     312              : /* BuildGoto builds a goto operation.  */
     313              : 
     314              : void
     315       121886 : m2statement_BuildGoto (location_t location, char *name)
     316              : {
     317       121886 :   tree label = m2block_getLabel (location, name);
     318              : 
     319       121886 :   m2assert_AssertLocation (location);
     320       121886 :   TREE_USED (label) = true;
     321       121886 :   add_stmt (location, build1 (GOTO_EXPR, void_type_node, label));
     322       121886 : }
     323              : 
     324              : /* DeclareLabel create a label, name.  */
     325              : 
     326              : void
     327       102806 : m2statement_DeclareLabel (location_t location, char *name)
     328              : {
     329       102806 :   tree label = m2block_getLabel (location, name);
     330              : 
     331       102806 :   m2assert_AssertLocation (location);
     332       102806 :   add_stmt (location, build1 (LABEL_EXPR, void_type_node, label));
     333       102806 : }
     334              : 
     335              : /* BuildParam build a list of parameters, ready for a subsequent
     336              :    procedure call.  */
     337              : 
     338              : void
     339       609034 : m2statement_BuildParam (location_t location, tree param)
     340              : {
     341       609034 :   m2assert_AssertLocation (location);
     342              : 
     343       609034 :   TREE_USED (param) = true;
     344       609034 :   if (TREE_CODE (param) == FUNCTION_DECL)
     345        43702 :     param = m2expr_BuildAddr (location, param, false);
     346              : 
     347       609034 :   param_list = chainon (build_tree_list (NULL_TREE, param), param_list);
     348       609034 : }
     349              : 
     350              : /* nCount return the number of chained tree nodes in list, t.  */
     351              : 
     352              : static int
     353       230028 : nCount (tree t)
     354              : {
     355       230028 :   int i = 0;
     356              : 
     357       837408 :   while (t != NULL)
     358              :     {
     359       607380 :       i++;
     360       607380 :       t = TREE_CHAIN (t);
     361              :     }
     362       230028 :   return i;
     363              : }
     364              : 
     365              : /* BuildProcedureCallTree creates a procedure call from a procedure
     366              :    and parameter list and the return type, rettype.  */
     367              : 
     368              : tree
     369       229304 : m2statement_BuildProcedureCallTree (location_t location, tree procedure,
     370              :                                     tree rettype)
     371              : {
     372       229304 :   tree functype = TREE_TYPE (procedure);
     373       229304 :   tree funcptr = build1 (ADDR_EXPR, build_pointer_type (functype), procedure);
     374       229304 :   tree call;
     375       229304 :   int n = nCount (param_list);
     376       229304 :   tree *argarray = XALLOCAVEC (tree, n);
     377       229304 :   tree t = param_list;
     378       229304 :   int i;
     379              : 
     380       229304 :   m2assert_AssertLocation (location);
     381       229304 :   ASSERT_CONDITION (
     382              :       last_function
     383       229304 :       == NULL_TREE); /* Previous function value has not been collected.  */
     384       229304 :   TREE_USED (procedure) = true;
     385              : 
     386       835518 :   for (i = 0; i < n; i++)
     387              :     {
     388       606214 :       argarray[i] = TREE_VALUE (t);
     389       606214 :       t = TREE_CHAIN (t);
     390              :     }
     391              : 
     392       229304 :   if (rettype == NULL_TREE)
     393              :     {
     394       156603 :       rettype = void_type_node;
     395       156603 :       call = build_call_array_loc (location, rettype, funcptr, n, argarray);
     396       156603 :       TREE_USED (call) = true;
     397       156603 :       TREE_SIDE_EFFECTS (call) = true;
     398              : 
     399              : #if defined(DEBUG_PROCEDURE_CALLS)
     400              :       fprintf (stderr, "built the modula-2 call, here is the tree\n");
     401              :       fflush (stderr);
     402              :       debug_tree (call);
     403              : #endif
     404              : 
     405       156603 :       param_list
     406       156603 :           = NULL_TREE; /* Ready for the next time we call a procedure.  */
     407       156603 :       last_function = NULL_TREE;
     408       156603 :       return call;
     409              :     }
     410              :   else
     411              :     {
     412        72701 :       last_function = build_call_array_loc (
     413              :           location, m2tree_skip_type_decl (rettype), funcptr, n, argarray);
     414        72701 :       TREE_USED (last_function) = true;
     415        72701 :       TREE_SIDE_EFFECTS (last_function) = true;
     416        72701 :       param_list
     417        72701 :           = NULL_TREE; /* Ready for the next time we call a procedure.  */
     418        72701 :       return last_function;
     419              :     }
     420              : }
     421              : 
     422              : /* BuildIndirectProcedureCallTree creates a procedure call from a
     423              :    procedure and parameter list and the return type, rettype.  */
     424              : 
     425              : tree
     426          724 : m2statement_BuildIndirectProcedureCallTree (location_t location,
     427              :                                             tree procedure, tree rettype)
     428              : {
     429          724 :   tree call;
     430          724 :   int n = nCount (param_list);
     431          724 :   tree *argarray = XALLOCAVEC (tree, n);
     432          724 :   tree t = param_list;
     433          724 :   int i;
     434              : 
     435          724 :   m2assert_AssertLocation (location);
     436          724 :   TREE_USED (procedure) = true;
     437          724 :   TREE_SIDE_EFFECTS (procedure) = true;
     438              : 
     439         1890 :   for (i = 0; i < n; i++)
     440              :     {
     441         1166 :       argarray[i] = TREE_VALUE (t);
     442         1166 :       t = TREE_CHAIN (t);
     443              :     }
     444              : 
     445          724 :   if (rettype == NULL_TREE)
     446              :     {
     447          636 :       rettype = void_type_node;
     448          636 :       call = build_call_array_loc (location, rettype, procedure, n, argarray);
     449          636 :       TREE_USED (call) = true;
     450          636 :       TREE_SIDE_EFFECTS (call) = true;
     451              : 
     452              : #if defined(DEBUG_PROCEDURE_CALLS)
     453              :       fprintf (stderr, "built the modula-2 call, here is the tree\n");
     454              :       fflush (stderr);
     455              :       debug_tree (call);
     456              : #endif
     457              : 
     458          636 :       last_function = NULL_TREE;
     459          636 :       param_list
     460          636 :           = NULL_TREE; /* Ready for the next time we call a procedure.  */
     461          636 :       return call;
     462              :     }
     463              :   else
     464              :     {
     465           88 :       last_function = build_call_array_loc (
     466              :           location, m2tree_skip_type_decl (rettype), procedure, n, argarray);
     467           88 :       TREE_USED (last_function) = true;
     468           88 :       TREE_SIDE_EFFECTS (last_function) = true;
     469           88 :       param_list
     470           88 :           = NULL_TREE; /* Ready for the next time we call a procedure.  */
     471           88 :       return last_function;
     472              :     }
     473              : }
     474              : 
     475              : 
     476              : /* BuildBuiltinCallTree calls the builtin procedure.  */
     477              : 
     478              : tree
     479         1146 : m2statement_BuildBuiltinCallTree (tree func)
     480              : {
     481         1146 :   TREE_USED (func) = true;
     482         1146 :   TREE_SIDE_EFFECTS (func) = true;
     483         1146 :   param_list
     484         1146 :     = NULL_TREE; /* Ready for the next time we call a procedure.  */
     485         1146 :   return func;
     486              : }
     487              : 
     488              : 
     489              : /* BuildFunctValue generates code for
     490              :    value := last_function (foobar).  */
     491              : 
     492              : tree
     493        85797 : m2statement_BuildFunctValue (location_t location, tree value)
     494              : {
     495        85797 :   tree assign
     496        85797 :       = m2treelib_build_modify_expr (location, value, NOP_EXPR, last_function);
     497              : 
     498        85797 :   m2assert_AssertLocation (location);
     499        85797 :   ASSERT_CONDITION (
     500              :       last_function
     501        85797 :       != NULL_TREE);  /* No value available, possible used before.  */
     502              : 
     503        85797 :   TREE_SIDE_EFFECTS (assign) = true;
     504        85797 :   TREE_USED (assign) = true;
     505        85797 :   TREE_USED (value) = true;
     506        85797 :   last_function = NULL_TREE;
     507        85797 :   return assign;
     508              : }
     509              : 
     510              : /* BuildCall2 builds a tree representing: function (arg1, arg2).  */
     511              : 
     512              : tree
     513            0 : m2statement_BuildCall2 (location_t location, tree function, tree rettype,
     514              :                         tree arg1, tree arg2)
     515              : {
     516            0 :   m2assert_AssertLocation (location);
     517            0 :   ASSERT_CONDITION (param_list == NULL_TREE);
     518              : 
     519            0 :   param_list = chainon (build_tree_list (NULL_TREE, arg2), param_list);
     520            0 :   param_list = chainon (build_tree_list (NULL_TREE, arg1), param_list);
     521            0 :   return m2statement_BuildProcedureCallTree (location, function, rettype);
     522              : }
     523              : 
     524              : /* BuildCall3 builds a tree representing: function (arg1, arg2, arg3).  */
     525              : 
     526              : tree
     527            0 : m2statement_BuildCall3 (location_t location, tree function, tree rettype,
     528              :                         tree arg1, tree arg2, tree arg3)
     529              : {
     530            0 :   m2assert_AssertLocation (location);
     531            0 :   ASSERT_CONDITION (param_list == NULL_TREE);
     532              : 
     533            0 :   param_list = chainon (build_tree_list (NULL_TREE, arg3), param_list);
     534            0 :   param_list = chainon (build_tree_list (NULL_TREE, arg2), param_list);
     535            0 :   param_list = chainon (build_tree_list (NULL_TREE, arg1), param_list);
     536            0 :   return m2statement_BuildProcedureCallTree (location, function, rettype);
     537              : }
     538              : 
     539              : /* BuildFunctionCallTree creates a procedure function call from
     540              :    a procedure and parameter list and the return type, rettype.
     541              :    No tree is returned as the tree is held in the last_function global
     542              :    variable.  It is expected the BuildFunctValue is to be called after
     543              :    a call to BuildFunctionCallTree.  */
     544              : 
     545              : void
     546         5720 : m2statement_BuildFunctionCallTree (location_t location, tree procedure,
     547              :                                    tree rettype)
     548              : {
     549         5720 :   m2statement_BuildProcedureCallTree (location, procedure, rettype);
     550         5720 : }
     551              : 
     552              : /* SetLastFunction assigns last_function to, t.  */
     553              : 
     554              : void
     555       222691 : m2statement_SetLastFunction (tree t)
     556              : {
     557       222691 :   last_function = t;
     558       222691 : }
     559              : 
     560              : /* SetParamList assigns param_list to, t.  */
     561              : 
     562              : void
     563         1152 : m2statement_SetParamList (tree t)
     564              : {
     565         1152 :   param_list = t;
     566         1152 : }
     567              : 
     568              : /* GetLastFunction returns, last_function.  */
     569              : 
     570              : tree
     571            0 : m2statement_GetLastFunction (void)
     572              : {
     573            0 :   return last_function;
     574              : }
     575              : 
     576              : /* GetParamList returns, param_list.  */
     577              : 
     578              : tree
     579         1152 : m2statement_GetParamList (void)
     580              : {
     581         1152 :   return param_list;
     582              : }
     583              : 
     584              : /* GetCurrentFunction returns the current_function.  */
     585              : 
     586              : tree
     587            0 : m2statement_GetCurrentFunction (void)
     588              : {
     589            0 :   return current_function_decl;
     590              : }
     591              : 
     592              : /* GetParamTree return parameter, i.  */
     593              : 
     594              : tree
     595            0 : m2statement_GetParamTree (tree call, unsigned int i)
     596              : {
     597            0 :   return CALL_EXPR_ARG (call, i);
     598              : }
     599              : 
     600              : /* BuildTryFinally returns a TRY_FINALL_EXPR with the call and
     601              :    cleanups attached.  */
     602              : 
     603              : tree
     604            0 : m2statement_BuildTryFinally (location_t location, tree call, tree cleanups)
     605              : {
     606            0 :   return build_stmt (location, TRY_FINALLY_EXPR, call, cleanups);
     607              : }
     608              : 
     609              : /* BuildCleanUp return a CLEANUP_POINT_EXPR which will clobber,
     610              :    param.  */
     611              : 
     612              : tree
     613            0 : m2statement_BuildCleanUp (tree param)
     614              : {
     615            0 :   tree clobber = build_constructor (TREE_TYPE (param), NULL);
     616            0 :   TREE_THIS_VOLATILE (clobber) = 1;
     617            0 :   return build2 (MODIFY_EXPR, TREE_TYPE (param), param, clobber);
     618              : }
     619              : 
     620              : /* BuildAsm generates an inline assembler instruction.  */
     621              : 
     622              : void
     623           27 : m2statement_BuildAsm (location_t location, tree instr, bool isVolatile,
     624              :                       bool isSimple, tree inputs, tree outputs, tree trash,
     625              :                       tree labels)
     626              : {
     627           27 :   tree string = resolve_asm_operand_names (instr, outputs, inputs, labels);
     628           27 :   tree args = build_stmt (location, ASM_EXPR, string, outputs, inputs, trash,
     629              :                           labels);
     630              : 
     631           27 :   m2assert_AssertLocation (location);
     632              : 
     633              :   /* ASM statements without outputs, including simple ones, are treated
     634              :      as volatile.  */
     635           27 :   ASM_BASIC_P (args) = isSimple;
     636           27 :   ASM_VOLATILE_P (args) = isVolatile;
     637              : 
     638           27 :   add_stmt (location, args);
     639           27 : }
     640              : 
     641              : /* BuildStart creates a module initialization function.  We make
     642              :    this function public if it is not an inner module.  The linker
     643              :    will create a call list for all linked modules which determines
     644              :    the initialization sequence for all modules.  */
     645              : 
     646              : tree
     647            0 : m2statement_BuildStart (location_t location, char *name, bool inner_module)
     648              : {
     649            0 :   tree fntype;
     650            0 :   tree fndecl;
     651              : 
     652            0 :   m2assert_AssertLocation (location);
     653              :   /* The function type depends on the return type and type of args.  */
     654            0 :   fntype = build_function_type (integer_type_node, NULL_TREE);
     655            0 :   fndecl = build_decl (location, FUNCTION_DECL, get_identifier (name), fntype);
     656              : 
     657            0 :   DECL_EXTERNAL (fndecl) = 0;
     658            0 :   if (inner_module)
     659            0 :     TREE_PUBLIC (fndecl) = 0;
     660              :   else
     661            0 :     TREE_PUBLIC (fndecl) = 1;
     662              : 
     663            0 :   TREE_STATIC (fndecl) = 1;
     664            0 :   DECL_RESULT (fndecl)
     665            0 :       = build_decl (location, RESULT_DECL, NULL_TREE, integer_type_node);
     666            0 :   DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
     667              : 
     668              :   /* Prevent the optimizer from removing it if it is public.  */
     669            0 :   if (TREE_PUBLIC (fndecl))
     670            0 :     gm2_mark_addressable (fndecl);
     671              : 
     672            0 :   m2statement_BuildStartFunctionCode (location, fndecl, !inner_module,
     673              :                                       inner_module);
     674            0 :   return fndecl;
     675              : }
     676              : 
     677              : /* BuildEnd complete the initialization function for this module.  */
     678              : 
     679              : void
     680            0 : m2statement_BuildEnd (location_t location, tree fndecl, bool nested)
     681              : {
     682            0 :   m2statement_BuildEndFunctionCode (location, fndecl, nested);
     683            0 :   current_function_decl = NULL;
     684            0 :   set_cfun (NULL);
     685            0 : }
     686              : 
     687              : /* BuildCallInner call the inner module function.  It has no
     688              :    parameters and no return value.  */
     689              : 
     690              : void
     691          672 : m2statement_BuildCallInner (location_t location, tree fndecl)
     692              : {
     693          672 :   m2assert_AssertLocation (location);
     694          672 :   param_list = NULL_TREE;
     695          672 :   add_stmt (location,
     696              :             m2statement_BuildProcedureCallTree (location, fndecl, NULL_TREE));
     697          672 : }
     698              : 
     699              : 
     700              : /* BuildIfThenDoEnd returns a tree which will only execute
     701              :    statement, s, if, condition, is true.  */
     702              : 
     703              : tree
     704       115700 : m2statement_BuildIfThenDoEnd (tree condition, tree then_block)
     705              : {
     706       115700 :   if (then_block == NULL_TREE)
     707              :     return NULL_TREE;
     708              :   else
     709        16843 :     return fold_build3 (COND_EXPR, void_type_node, condition, then_block,
     710              :                         alloc_stmt_list ());
     711              : }
     712              : 
     713              : /* BuildIfThenElseEnd returns a tree which will execute then_block
     714              :    or else_block depending upon, condition.  */
     715              : 
     716              : tree
     717         6768 : m2statement_BuildIfThenElseEnd (tree condition, tree then_block,
     718              :                                 tree else_block)
     719              : {
     720         6768 :   if (then_block == NULL_TREE)
     721              :     return NULL_TREE;
     722              :   else
     723         1188 :     return fold_build3 (COND_EXPR, void_type_node, condition, then_block,
     724              :                         else_block);
     725              : }
     726              : 
     727              : /* BuildReturnValueCode generates the code associated with:
     728              :    RETURN ( value ).  */
     729              : 
     730              : void
     731        27443 : m2statement_BuildReturnValueCode (location_t location, tree fndecl, tree value)
     732              : {
     733        27443 :   tree ret_stmt;
     734        27443 :   tree t;
     735              : 
     736        27443 :   m2assert_AssertLocation (location);
     737        82329 :   t = build2 (
     738        27443 :       MODIFY_EXPR, TREE_TYPE (DECL_RESULT (fndecl)), DECL_RESULT (fndecl),
     739              :       m2convert_BuildConvert (
     740        27443 :           location, m2tree_skip_type_decl (TREE_TYPE (DECL_RESULT (fndecl))),
     741              :           value, false));
     742              : 
     743        27443 :   ret_stmt = build_stmt (location, RETURN_EXPR, t);
     744        27443 :   add_stmt (location, ret_stmt);
     745        27443 : }
     746              : 
     747              : /* IfExprJump if expr then jump to the label.  */
     748              : 
     749              : void
     750        76689 : m2statement_IfExprJump (location_t location, tree exp, char *label)
     751              : {
     752        76689 :   tree if_jump;
     753              : 
     754        76689 :   m2assert_AssertLocation (location);
     755        76689 :   if (TREE_CODE (TREE_TYPE (exp)) != BOOLEAN_TYPE)
     756        76671 :     exp = convert_loc (location, m2type_GetBooleanType (), exp);
     757              : 
     758        76689 :   m2block_push_statement_list (m2block_begin_statement_list ());
     759        76689 :   m2statement_BuildGoto (location, label);
     760        76689 :   if_jump = build3 (COND_EXPR, void_type_node, exp,
     761              :                     m2block_pop_statement_list (),
     762              :                     alloc_stmt_list ());
     763        76689 :   add_stmt (location, if_jump);
     764        76689 : }
     765              : 
     766              : 
     767              : /* IfBitInSetJump if bit in set jump to label.  */
     768              : 
     769              : void
     770            0 : m2statement_IfBitInSetJump (location_t location, bool invertCondition,
     771              :                             tree setvalue, tree bit, char *label)
     772              : {
     773            0 :   tree condition;
     774              : 
     775            0 :   condition = m2expr_BuildNotEqualTo (location,
     776              :                                       m2expr_BuildLogicalAnd (location,
     777              :                                                               m2expr_BuildLSL (location,
     778              :                                                                                m2expr_GetWordOne (location),
     779              :                                                                                bit, false),
     780              :                                                               setvalue),
     781              :                                       m2expr_GetWordZero (location)) ;
     782            0 :   if (invertCondition)
     783            0 :     condition = m2expr_BuildEqualTo (location, condition,
     784              :                                      m2type_GetBooleanFalse ());
     785            0 :   m2statement_IfExprJump (location, condition, label);
     786            0 : }
     787              : 
     788              : #include "gt-m2-m2statement.h"
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.