LCOV - code coverage report
Current view: top level - gcc/m2/gm2-gcc - m2decl.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 91.1 % 168 153
Test Date: 2026-03-28 14:25:54 Functions: 83.3 % 18 15
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* m2decl.cc provides an interface to GCC decl 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              : #define m2decl_c
      28              : #include "m2assert.h"
      29              : #include "m2block.h"
      30              : #include "m2decl.h"
      31              : #include "m2expr.h"
      32              : #include "m2tree.h"
      33              : #include "m2treelib.h"
      34              : #include "m2type.h"
      35              : #include "m2convert.h"
      36              : 
      37              : extern GTY (()) tree current_function_decl;
      38              : 
      39              : /* Used in BuildStartFunctionType.  */
      40              : static GTY (()) tree param_type_list;
      41              : static GTY (()) tree param_list = NULL_TREE; /* Ready for the next time we
      42              :                                                 call/define a function.  */
      43              : #if 0
      44              : tree
      45              : m2decl_DeclareM2linkStaticInitialization (location_t location,
      46              :                                           int ScaffoldStatic)
      47              : {
      48              :   m2block_pushGlobalScope ();
      49              :   /* Generate: int M2LINK_StaticInitialization = ScaffoldStatic;  */
      50              :   tree init = m2decl_BuildIntegerConstant (ScaffoldStatic);
      51              :   tree static_init = m2decl_DeclareKnownVariable (location, "m2pim_M2LINK_StaticInitialization",
      52              :                                                   integer_type_node,
      53              :                                                   TRUE, FALSE, FALSE, TRUE, NULL_TREE, init);
      54              :   m2block_popGlobalScope ();
      55              :   return static_init;
      56              : }
      57              : 
      58              : 
      59              : tree
      60              : m2decl_DeclareM2linkForcedModuleInitOrder (location_t location,
      61              :                                            const char *RuntimeOverride)
      62              : {
      63              :   m2block_pushGlobalScope ();
      64              :   /* Generate: const char *ForcedModuleInitOrder = RuntimeOverride;  */
      65              :   tree ptr_to_char = build_pointer_type (char_type_node);
      66              :   TYPE_READONLY (ptr_to_char) = TRUE;
      67              :   tree init = m2decl_BuildPtrToTypeString (location, RuntimeOverride, ptr_to_char);
      68              :   tree forced_order = m2decl_DeclareKnownVariable (location, "m2pim_M2LINK_ForcedModuleInitOrder",
      69              :                                                    ptr_to_char,
      70              :                                                    TRUE, FALSE, FALSE, TRUE, NULL_TREE, init);
      71              :   m2block_popGlobalScope ();
      72              :   return forced_order;
      73              : }
      74              : #endif
      75              : 
      76              : 
      77              : /* DeclareKnownVariable declares a variable to GCC.  */
      78              : 
      79              : tree
      80       680874 : m2decl_DeclareKnownVariable (location_t location, const char *name, tree type,
      81              :                              bool exported, bool imported, bool istemporary,
      82              :                              bool isglobal, tree scope, tree initial)
      83              : {
      84       680874 :   tree id;
      85       680874 :   tree decl;
      86              : 
      87       680874 :   m2assert_AssertLocation (location);
      88       680874 :   ASSERT (m2tree_is_type (type), type);
      89       680874 :   ASSERT_BOOL (isglobal);
      90              : 
      91       680874 :   id = get_identifier (name);
      92       680874 :   type = m2tree_skip_type_decl (type);
      93       680874 :   decl = build_decl (location, VAR_DECL, id, type);
      94              : 
      95       680874 :   DECL_SOURCE_LOCATION (decl) = location;
      96              : 
      97       680874 :   DECL_EXTERNAL (decl) = imported;
      98       680874 :   TREE_STATIC (decl) = isglobal;
      99       680874 :   TREE_PUBLIC (decl) = exported || imported;
     100              : 
     101       680874 :   gcc_assert ((istemporary == 0) || (istemporary == 1));
     102              : 
     103              :   /* The variable was not declared by GCC, but by the front end.  */
     104       680874 :   DECL_ARTIFICIAL (decl) = istemporary;
     105              :   /* If istemporary then we don't want debug info for it.  */
     106       680874 :   DECL_IGNORED_P (decl) = istemporary;
     107              :   /* If istemporary we don't want even the fancy names of those printed in
     108              :      -fdump-final-insns= dumps.  */
     109       680874 :   DECL_NAMELESS (decl) = istemporary;
     110              : 
     111              :   /* Make the variable writable.  */
     112       680874 :   TREE_READONLY (decl) = 0;
     113              : 
     114       680874 :   DECL_CONTEXT (decl) = scope;
     115              : 
     116       680874 :   if (initial)
     117            0 :     DECL_INITIAL (decl) = initial;
     118              : 
     119       680874 :   m2block_pushDecl (decl);
     120              : 
     121       680874 :   if (DECL_SIZE (decl) == 0)
     122            0 :     error ("storage size of %qD has not been resolved", decl);
     123              : 
     124       680874 :   if ((TREE_PUBLIC (decl) == 0) && DECL_EXTERNAL (decl))
     125            0 :     internal_error ("inconsistent because %qs",
     126              :                     "PUBLIC_DECL(decl) == 0 && DECL_EXTERNAL(decl) == 1");
     127              : 
     128       680874 :   m2block_addDeclExpr (build_stmt (location, DECL_EXPR, decl));
     129              : 
     130       680874 :   return decl;
     131              : }
     132              : 
     133              : /* DeclareKnownConstant - given a constant, value, of, type, create a
     134              :    constant in the GCC symbol table.  Note that the name of the
     135              :    constant is not used as _all_ constants are declared in the global
     136              :    scope.  The front end deals with scoping rules - here we declare
     137              :    all constants with no names in the global scope.  This allows
     138              :    M2SubExp and constant folding routines the liberty of operating
     139              :    with quadruples which all assume constants can always be
     140              :    referenced.  */
     141              : 
     142              : tree
     143        68065 : m2decl_DeclareKnownConstant (location_t location, tree type, tree value)
     144              : {
     145        68065 :   tree id = make_node (IDENTIFIER_NODE); /* Ignore the name of the constant. */
     146        68065 :   tree decl;
     147              : 
     148        68065 :   m2assert_AssertLocation (location);
     149        68065 :   m2expr_ConstantExpressionWarning (value);
     150        68065 :   type = m2tree_skip_type_decl (type);
     151        68065 :   layout_type (type);
     152              : 
     153        68065 :   decl = build_decl (location, CONST_DECL, id, type);
     154              : 
     155        68065 :   value = copy_node (value);
     156        68065 :   TREE_TYPE (value) = type;
     157        68065 :   DECL_INITIAL (decl) = value;
     158        68065 :   TREE_TYPE (decl) = type;
     159        68065 :   decl = m2block_global_constant (decl);
     160        68065 :   return decl;
     161              : }
     162              : 
     163              : /* BuildParameterDeclaration - creates and returns one parameter
     164              :    from, name, and, type.  It appends this parameter to the internal
     165              :    param_type_list.  */
     166              : 
     167              : tree
     168      8109824 : m2decl_BuildParameterDeclaration (location_t location, const char *name, tree type,
     169              :                                   bool isreference)
     170              : {
     171      8109824 :   tree parm_decl;
     172              : 
     173      8109824 :   m2assert_AssertLocation (location);
     174      8109824 :   ASSERT_BOOL (isreference);
     175      8109824 :   type = m2tree_skip_type_decl (type);
     176      8109824 :   layout_type (type);
     177      8109824 :   if (isreference)
     178       200353 :     type = build_reference_type (type);
     179              : 
     180      8109824 :   if (name == NULL)
     181       102144 :     parm_decl = build_decl (location, PARM_DECL, NULL, type);
     182              :   else
     183      8007680 :     parm_decl = build_decl (location, PARM_DECL, get_identifier (name), type);
     184      8109824 :   DECL_ARG_TYPE (parm_decl) = type;
     185      8109824 :   if (isreference)
     186       200353 :     TREE_READONLY (parm_decl) = TRUE;
     187              : 
     188      8109824 :   param_list = chainon (parm_decl, param_list);
     189      8109824 :   layout_type (type);
     190      8109824 :   param_type_list = tree_cons (NULL_TREE, type, param_type_list);
     191      8109824 :   return parm_decl;
     192              : }
     193              : 
     194              : /* BuildStartFunctionDeclaration - initializes global variables ready
     195              :    for building a function.  */
     196              : 
     197              : void
     198      3978877 : m2decl_BuildStartFunctionDeclaration (bool uses_varargs)
     199              : {
     200      3978877 :   if (uses_varargs)
     201        11320 :     param_type_list = NULL_TREE;
     202              :   else
     203      3967557 :     param_type_list = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
     204      3978877 :   param_list = NULL_TREE; /* Ready for when we define a function.  */
     205      3978877 : }
     206              : 
     207              : /* BuildEndFunctionDeclaration - build a function which will return a
     208              :    value of returntype.  The arguments have been created by
     209              :    BuildParameterDeclaration.  */
     210              : 
     211              : tree
     212      3978877 : m2decl_BuildEndFunctionDeclaration (location_t location_begin,
     213              :                                     location_t location_end, const char *name,
     214              :                                     tree returntype, bool isexternal,
     215              :                                     bool isnested, bool ispublic, bool isnoreturn)
     216              : {
     217      3978877 :   tree fntype;
     218      3978877 :   tree fndecl;
     219              : 
     220      3978877 :   m2assert_AssertLocation (location_begin);
     221      3978877 :   m2assert_AssertLocation (location_end);
     222      3978877 :   ASSERT_BOOL (isexternal);
     223      3978877 :   ASSERT_BOOL (isnested);
     224      3978877 :   ASSERT_BOOL (ispublic);
     225      3978877 :   returntype = m2tree_skip_type_decl (returntype);
     226              :   /* The function type depends on the return type and type of args,
     227              :      both of which we have created in BuildParameterDeclaration */
     228      3978877 :   if (returntype == NULL_TREE)
     229      1740457 :     returntype = void_type_node;
     230      2238420 :   else if (TREE_CODE (returntype) == FUNCTION_TYPE)
     231            0 :     returntype = ptr_type_node;
     232              : 
     233      3978877 :   fntype = build_function_type (returntype, param_type_list);
     234      3978877 :   fndecl = build_decl (location_begin, FUNCTION_DECL, get_identifier (name),
     235              :                        fntype);
     236              : 
     237      3978877 :   if (isexternal)
     238      3819500 :     ASSERT_CONDITION (ispublic);
     239              : 
     240      3978877 :   DECL_EXTERNAL (fndecl) = isexternal;
     241      3978877 :   TREE_PUBLIC (fndecl) = ispublic;
     242      3978877 :   TREE_STATIC (fndecl) = (!isexternal);
     243      3978877 :   DECL_ARGUMENTS (fndecl) = param_list;
     244      7957754 :   DECL_RESULT (fndecl)
     245      3978877 :       = build_decl (location_end, RESULT_DECL, NULL_TREE, returntype);
     246      3978877 :   DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
     247      3978877 :   TREE_TYPE (fndecl) = fntype;
     248      3978877 :   TREE_THIS_VOLATILE (fndecl) = isnoreturn;
     249              : 
     250      3978877 :   DECL_SOURCE_LOCATION (fndecl) = location_begin;
     251              : 
     252              :   /* Prevent the optimizer from removing it if it is public.  */
     253      3978877 :   if (TREE_PUBLIC (fndecl))
     254      3840303 :     gm2_mark_addressable (fndecl);
     255              : 
     256      3978877 :   m2block_pushDecl (fndecl);
     257              : 
     258      3978877 :   rest_of_decl_compilation (fndecl, 1, 0);
     259      3978877 :   param_list
     260      3978877 :       = NULL_TREE; /* Ready for the next time we call/define a function.  */
     261      3978877 :   return fndecl;
     262              : }
     263              : 
     264              : /* BuildModuleCtor creates the per module constructor used as part of
     265              :    the dynamic linking scaffold.  */
     266              : 
     267              : void
     268        16208 : m2decl_BuildModuleCtor (tree module_ctor)
     269              : {
     270        16208 :   decl_init_priority_insert (module_ctor, DEFAULT_INIT_PRIORITY);
     271        16208 : }
     272              : 
     273              : /* DeclareModuleCtor configures the function to be used as a ctor.  */
     274              : 
     275              : tree
     276        16208 : m2decl_DeclareModuleCtor (tree decl)
     277              : {
     278              :   /* Declare module_ctor ().  */
     279        16208 :   TREE_PUBLIC (decl) = 1;
     280        16208 :   DECL_ARTIFICIAL (decl) = 1;
     281        16208 :   DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
     282        16208 :   DECL_VISIBILITY_SPECIFIED (decl) = 1;
     283        16208 :   DECL_STATIC_CONSTRUCTOR (decl) = 1;
     284        16208 :   return decl;
     285              : }
     286              : 
     287              : /* BuildConstLiteralNumber - returns a GCC TREE built from the
     288              :    string, str.  It assumes that, str, represents a legal number in
     289              :    Modula-2.  It always returns a positive value.  */
     290              : 
     291              : tree
     292       634174 : m2decl_BuildConstLiteralNumber (location_t location, const char *str,
     293              :                                 unsigned int base, bool issueError)
     294              : {
     295       634174 :   widest_int wval;
     296       634174 :   tree value;
     297       634174 :   bool overflow = m2expr_OverflowZType (location, str, base, issueError);
     298       634174 :   if (overflow)
     299            6 :     value = m2expr_GetIntegerZero (location);
     300              :   else
     301              :     {
     302       634168 :       overflow = m2expr_StrToWideInt (location, str, base, wval, issueError);
     303       634168 :       if (overflow)
     304            0 :         value = m2expr_GetIntegerZero (location);
     305              :       else
     306              :         {
     307       634168 :           value = wide_int_to_tree (m2type_GetM2ZType (), wval);
     308       634168 :           overflow = m2expr_TreeOverflow (value);
     309              :         }
     310              :     }
     311       634174 :   if (issueError && overflow)
     312            0 :     error_at (location, "constant %qs is too large", str);
     313       634174 :   return m2block_RememberConstant (value);
     314       634174 : }
     315              : 
     316              : /* BuildCStringConstant - creates a string constant given a, string,
     317              :    and, length.  */
     318              : 
     319              : tree
     320       257090 : m2decl_BuildCStringConstant (const char *string, int length)
     321              : {
     322       257090 :   tree elem, index, type;
     323              : 
     324              :   /* +1 ensures that we always nul terminate our strings.  */
     325       257090 :   elem = build_type_variant (char_type_node, 1, 0);
     326       257090 :   index = build_index_type (build_int_cst (integer_type_node, length + 1));
     327       257090 :   type = build_array_type (elem, index);
     328       257090 :   return m2decl_BuildStringConstantType (length + 1, string, type);
     329              : }
     330              : 
     331              : /* BuildStringConstant - creates a string constant given a, string,
     332              :    and, length.  */
     333              : 
     334              : tree
     335       239828 : m2decl_BuildStringConstant (const char *string, int length)
     336              : {
     337       239828 :   tree elem, index, type;
     338              : 
     339       239828 :   elem = build_type_variant (char_type_node, 1, 0);
     340       239828 :   index = build_index_type (build_int_cst (integer_type_node, length));
     341       239828 :   type = build_array_type (elem, index);
     342       239828 :   return m2decl_BuildStringConstantType (length, string, type);
     343              :   // maybe_wrap_with_location
     344              : }
     345              : 
     346              : 
     347              : tree
     348            0 : m2decl_BuildPtrToTypeString (location_t location, const char *string, tree type)
     349              : {
     350            0 :   if ((string == NULL) || (strlen (string) == 0))
     351            0 :     return m2convert_BuildConvert (location, type,
     352              :                                    m2decl_BuildIntegerConstant (0),
     353            0 :                                    FALSE);
     354            0 :   return build_string_literal (strlen (string), string);
     355              : }
     356              : 
     357              : 
     358              : /* BuildIntegerConstant - return a tree containing the integer value.  */
     359              : 
     360              : tree
     361      6476555 : m2decl_BuildIntegerConstant (int value)
     362              : {
     363      6476555 :   switch (value)
     364              :     {
     365              : 
     366      1228299 :     case 0:
     367      1228299 :       return integer_zero_node;
     368       633236 :     case 1:
     369       633236 :       return integer_one_node;
     370              : 
     371      4615020 :     default:
     372      4615020 :       return m2block_RememberConstant (
     373      4615020 :           build_int_cst (integer_type_node, value));
     374              :     }
     375              : }
     376              : 
     377              : /* BuildStringConstantType - builds a string constant with a type.  */
     378              : 
     379              : tree
     380       500230 : m2decl_BuildStringConstantType (int length, const char *string, tree type)
     381              : {
     382       500230 :   tree id = build_string (length, string);
     383              : 
     384       500230 :   TREE_TYPE (id) = type;
     385       500230 :   TREE_CONSTANT (id) = TRUE;
     386       500230 :   TREE_READONLY (id) = TRUE;
     387       500230 :   TREE_STATIC (id) = TRUE;
     388              : 
     389       500230 :   return m2block_RememberConstant (id);
     390              : }
     391              : 
     392              : /* GetBitsPerWord - returns the number of bits in a WORD.  */
     393              : 
     394              : int
     395            0 : m2decl_GetBitsPerWord (void)
     396              : {
     397            0 :   return BITS_PER_WORD;
     398              : }
     399              : 
     400              : /* GetBitsPerInt - returns the number of bits in a INTEGER.  */
     401              : 
     402              : int
     403        34048 : m2decl_GetBitsPerInt (void)
     404              : {
     405        34048 :   return INT_TYPE_SIZE;
     406              : }
     407              : 
     408              : /* GetBitsPerBitset - returns the number of bits in a BITSET.  */
     409              : 
     410              : int
     411       107922 : m2decl_GetBitsPerBitset (void)
     412              : {
     413       107922 :   return SET_WORD_SIZE;
     414              : }
     415              : 
     416              : /* GetBitsPerUnit - returns the number of bits in a UNIT.  */
     417              : 
     418              : int
     419         1943 : m2decl_GetBitsPerUnit (void)
     420              : {
     421         1943 :   return BITS_PER_UNIT;
     422              : }
     423              : 
     424              : /* m2decl_GetDeclContext - returns the DECL_CONTEXT of tree, t.  */
     425              : 
     426              : tree
     427            0 : m2decl_GetDeclContext (tree t)
     428              : {
     429            0 :   return DECL_CONTEXT (t);
     430              : }
     431              : 
     432              : #include "gt-m2-m2decl.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.