LCOV - code coverage report
Current view: top level - gcc/m2/gm2-gcc - m2linemap.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 52.6 % 156 82
Test Date: 2025-03-08 13:07:09 Functions: 68.0 % 25 17
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* m2linemap.cc provides an interface to GCC linemaps.
       2                 :             : 
       3                 :             : Copyright (C) 2012-2025 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                 :             : #define INCLUDE_STRING
      23                 :             : #include "gcc-consolidation.h"
      24                 :             : 
      25                 :             : /* Utilize some of the C build routines */
      26                 :             : 
      27                 :             : #include "../gm2-lang.h"
      28                 :             : #include "../m2-tree.h"
      29                 :             : 
      30                 :             : #include "m2assert.h"
      31                 :             : #include "m2block.h"
      32                 :             : #include "m2decl.h"
      33                 :             : #include "m2expr.h"
      34                 :             : #include "m2options.h"
      35                 :             : #include "m2tree.h"
      36                 :             : #include "m2type.h"
      37                 :             : #define m2linemap_c
      38                 :             : #include "m2linemap.h"
      39                 :             : #include "m2color.h"
      40                 :             : 
      41                 :             : static int inFile = FALSE;
      42                 :             : 
      43                 :             : #if defined(__cplusplus)
      44                 :             : #define EXTERN extern "C"
      45                 :             : #else
      46                 :             : #define EXTERN
      47                 :             : #endif
      48                 :             : 
      49                 :             : /* Start getting locations from a new file.  */
      50                 :             : 
      51                 :             : EXTERN
      52                 :             : void
      53                 :      232996 : m2linemap_StartFile (void *filename, unsigned int linebegin)
      54                 :             : {
      55                 :      232996 :   if (inFile)
      56                 :      217112 :     m2linemap_EndFile ();
      57                 :      232996 :   linemap_add (line_table, LC_ENTER, false,
      58                 :      232996 :                xstrdup (reinterpret_cast<char *> (filename)), linebegin);
      59                 :      232996 :   inFile = TRUE;
      60                 :      232996 : }
      61                 :             : 
      62                 :             : /* Tell the line table the file has ended.  */
      63                 :             : 
      64                 :             : EXTERN
      65                 :             : void
      66                 :      217112 : m2linemap_EndFile (void)
      67                 :             : {
      68                 :      217112 :   linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
      69                 :      217112 :   inFile = FALSE;
      70                 :      217112 : }
      71                 :             : 
      72                 :             : /* Indicate that there is a new source file line number with a
      73                 :             :    maximum width.  */
      74                 :             : 
      75                 :             : EXTERN
      76                 :             : void
      77                 :    42938021 : m2linemap_StartLine (unsigned int linenumber, unsigned int linesize)
      78                 :             : {
      79                 :    42938021 :   linemap_line_start (line_table, linenumber, linesize);
      80                 :    42938021 : }
      81                 :             : 
      82                 :             : /* GetLocationColumn, returns a location_t based on the current line
      83                 :             :    number and column.  */
      84                 :             : 
      85                 :             : EXTERN
      86                 :             : location_t
      87                 :  1340193332 : m2linemap_GetLocationColumn (unsigned int column)
      88                 :             : {
      89                 :  1340193332 :   return linemap_position_for_column (line_table, column);
      90                 :             : }
      91                 :             : 
      92                 :             : /* GetLocationRange, returns a location based on the start column
      93                 :             :    and end column.  */
      94                 :             : 
      95                 :             : EXTERN
      96                 :             : location_t
      97                 :  1340193332 : m2linemap_GetLocationRange (unsigned int start, unsigned int end)
      98                 :             : {
      99                 :  1340193332 :   location_t caret = m2linemap_GetLocationColumn (start);
     100                 :             : 
     101                 :  1340193332 :   source_range where;
     102                 :  1340193332 :   where.m_start = linemap_position_for_column (line_table, start);
     103                 :  1340193332 :   where.m_finish = linemap_position_for_column (line_table, end);
     104                 :  1340193332 :   return make_location (caret, where);
     105                 :             : }
     106                 :             : 
     107                 :             : 
     108                 :             : static
     109                 :             : int
     110                 :           0 : isSrcLocation (location_t location)
     111                 :             : {
     112                 :           0 :   return (location != BUILTINS_LOCATION) && (location != UNKNOWN_LOCATION);
     113                 :             : }
     114                 :             : 
     115                 :             : 
     116                 :             : /* GetLocationBinary, returns a location based on the expression
     117                 :             :    start caret finish locations.  */
     118                 :             : 
     119                 :             : EXTERN
     120                 :             : location_t
     121                 :     1843986 : m2linemap_GetLocationBinary (location_t caret, location_t start, location_t finish)
     122                 :             : {
     123                 :     1843986 :   if (isSrcLocation (start) && isSrcLocation (finish) && isSrcLocation (caret)
     124                 :     3687972 :     && (m2linemap_GetFilenameFromLocation (start) != NULL))
     125                 :             :     {
     126                 :     1831506 :       linemap_add (line_table, LC_ENTER, false, xstrdup (m2linemap_GetFilenameFromLocation (start)), 1);
     127                 :     1831506 :       gcc_assert (inFile);
     128                 :     1831506 :       location_t location = make_location (caret, start, finish);
     129                 :     1831506 :       linemap_add (line_table, LC_LEAVE, false, NULL, 0);
     130                 :     1831506 :       return location;
     131                 :             :     }
     132                 :             :   return caret;
     133                 :             : }
     134                 :             : 
     135                 :             : /* GetLineNoFromLocation - returns the lineno given a location.  */
     136                 :             : 
     137                 :             : EXTERN
     138                 :             : int
     139                 :        3712 : m2linemap_GetLineNoFromLocation (location_t location)
     140                 :             : {
     141                 :        3712 :   if (isSrcLocation (location) && (!M2Options_GetCpp ()))
     142                 :             :     {
     143                 :        3100 :       expanded_location xl = expand_location (location);
     144                 :        3100 :       return xl.line;
     145                 :             :     }
     146                 :             :   return 0;
     147                 :             : }
     148                 :             : 
     149                 :             : /* GetColumnNoFromLocation - returns the columnno given a location.  */
     150                 :             : 
     151                 :             : EXTERN
     152                 :             : int
     153                 :        3712 : m2linemap_GetColumnNoFromLocation (location_t location)
     154                 :             : {
     155                 :        3712 :   if (isSrcLocation (location) && (!M2Options_GetCpp ()))
     156                 :             :     {
     157                 :        3100 :       expanded_location xl = expand_location (location);
     158                 :        3100 :       return xl.column;
     159                 :             :     }
     160                 :             :   return 0;
     161                 :             : }
     162                 :             : 
     163                 :             : /* GetFilenameFromLocation - returns the filename given a location.  */
     164                 :             : 
     165                 :             : EXTERN
     166                 :             : const char *
     167                 :     3679204 : m2linemap_GetFilenameFromLocation (location_t location)
     168                 :             : {
     169                 :     3679204 :   if (isSrcLocation (location) && (!M2Options_GetCpp ()))
     170                 :             :     {
     171                 :     3666112 :       expanded_location xl = expand_location (location);
     172                 :     3666112 :       return xl.file;
     173                 :             :     }
     174                 :             :   return NULL;
     175                 :             : }
     176                 :             : 
     177                 :             : /* ErrorAt - issue an error message.  */
     178                 :             : 
     179                 :             : EXTERN
     180                 :             : void
     181                 :           0 : m2linemap_ErrorAt (location_t location, char *message)
     182                 :             : {
     183                 :           0 :   error_at (location, "%s", message);
     184                 :           0 : }
     185                 :             : 
     186                 :             : /* m2linemap_ErrorAtf - wraps up an error message.  */
     187                 :             : 
     188                 :             : static void
     189                 :        3216 : m2linemap_ErrorAtf_1 (location_t location, const char *message, ...)
     190                 :             : {
     191                 :        3216 :   diagnostic_info diagnostic;
     192                 :        3216 :   va_list ap;
     193                 :        3216 :   rich_location richloc (line_table, location);
     194                 :             : 
     195                 :        3216 :   va_start (ap, message);
     196                 :        3216 :   diagnostic_set_info (&diagnostic, message, &ap, &richloc, DK_ERROR);
     197                 :        3216 :   diagnostic_report_diagnostic (global_dc, &diagnostic);
     198                 :        3216 :   va_end (ap);
     199                 :        3216 : }
     200                 :             : 
     201                 :             : void
     202                 :        3216 : m2linemap_ErrorAtf (location_t location, const char *message)
     203                 :             : {
     204                 :        3216 :   m2linemap_ErrorAtf_1 (location, "%s", message);
     205                 :        3216 : }
     206                 :             : 
     207                 :             : /* m2linemap_WarningAtf - wraps up a warning message.  */
     208                 :             : 
     209                 :             : static void
     210                 :         594 : m2linemap_WarningAtf_1 (location_t location, const char *message, ...)
     211                 :             : {
     212                 :         594 :   diagnostic_info diagnostic;
     213                 :         594 :   va_list ap;
     214                 :         594 :   rich_location richloc (line_table, location);
     215                 :             : 
     216                 :         594 :   va_start (ap, message);
     217                 :         594 :   diagnostic_set_info (&diagnostic, message, &ap, &richloc, DK_WARNING);
     218                 :         594 :   diagnostic_report_diagnostic (global_dc, &diagnostic);
     219                 :         594 :   va_end (ap);
     220                 :         594 : }
     221                 :             : 
     222                 :             : void
     223                 :         594 : m2linemap_WarningAtf (location_t location, const char *message)
     224                 :             : {
     225                 :         594 :   m2linemap_WarningAtf_1 (location, "%s", message);
     226                 :         594 : }
     227                 :             : 
     228                 :             : /* m2linemap_NoteAtf - wraps up a note message.  */
     229                 :             : 
     230                 :             : static void
     231                 :          16 : m2linemap_NoteAtf_1 (location_t location, const char *message, ...)
     232                 :             : {
     233                 :          16 :   diagnostic_info diagnostic;
     234                 :          16 :   va_list ap;
     235                 :          16 :   rich_location richloc (line_table, location);
     236                 :             : 
     237                 :          16 :   va_start (ap, message);
     238                 :          16 :   diagnostic_set_info (&diagnostic, message, &ap, &richloc, DK_NOTE);
     239                 :          16 :   diagnostic_report_diagnostic (global_dc, &diagnostic);
     240                 :          16 :   va_end (ap);
     241                 :          16 : }
     242                 :             : 
     243                 :             : void
     244                 :          16 : m2linemap_NoteAtf (location_t location, const char *message)
     245                 :             : {
     246                 :          16 :   m2linemap_NoteAtf_1 (location, "%s", message);
     247                 :          16 : }
     248                 :             : 
     249                 :             : /* m2linemap_internal_error - allow Modula-2 to use the GCC internal error.  */
     250                 :             : 
     251                 :             : void
     252                 :           0 : m2linemap_internal_error (const char *message)
     253                 :             : {
     254                 :           0 :   internal_error ("%s", message);
     255                 :             : }
     256                 :             : 
     257                 :             : 
     258                 :             : /* Code derived from rust.  */
     259                 :             : 
     260                 :             : static std::string
     261                 :           0 : mformat_value ()
     262                 :             : {
     263                 :           0 :   return std::string (xstrerror (errno));
     264                 :             : }
     265                 :             : 
     266                 :             : 
     267                 :             : static std::string
     268                 :           0 : expand_format (const char *fmt)
     269                 :             : {
     270                 :           0 :   std::string result;
     271                 :           0 :   for (const char *c = fmt; *c; ++c)
     272                 :             :     {
     273                 :           0 :       if (*c != '%')
     274                 :             :         {
     275                 :           0 :           result += *c;
     276                 :           0 :           continue;
     277                 :             :         }
     278                 :           0 :       c++;
     279                 :           0 :       switch (*c)
     280                 :             :         {
     281                 :           0 :           case '\0': {
     282                 :             :             // malformed format string
     283                 :           0 :             gcc_unreachable ();
     284                 :             :           }
     285                 :           0 :           case '%': {
     286                 :           0 :             result += '%';
     287                 :           0 :             break;
     288                 :             :           }
     289                 :           0 :           case 'm': {
     290                 :           0 :             result += mformat_value ();
     291                 :           0 :             break;
     292                 :             :           }
     293                 :           0 :           case '<': {
     294                 :           0 :             result += m2color_open_quote ();
     295                 :           0 :             break;
     296                 :             :           }
     297                 :           0 :           case '>': {
     298                 :           0 :             result += m2color_close_quote ();
     299                 :           0 :             break;
     300                 :             :           }
     301                 :           0 :           case 'q': {
     302                 :           0 :             result += m2color_open_quote ();
     303                 :           0 :             c++;
     304                 :           0 :             if (*c == 'm')
     305                 :           0 :               result += mformat_value ();
     306                 :             :             else
     307                 :             :               {
     308                 :           0 :                 result += '%';
     309                 :           0 :                 result += *c;
     310                 :             :               }
     311                 :           0 :             result += m2color_close_quote ();
     312                 :           0 :             break;
     313                 :             :           }
     314                 :           0 :           default: {
     315                 :           0 :             result += '%';
     316                 :           0 :             result += *c;
     317                 :             :           }
     318                 :             :         }
     319                 :             :     }
     320                 :           0 :   return result;
     321                 :             : }
     322                 :             : 
     323                 :             : static std::string
     324                 :           0 : expand_message (const char *fmt, va_list ap)
     325                 :             : {
     326                 :           0 :   char *mbuf = 0;
     327                 :           0 :   std::string expanded_fmt = expand_format (fmt);
     328                 :           0 :   int nwr = vasprintf (&mbuf, expanded_fmt.c_str (), ap);
     329                 :           0 :   if (nwr == -1)
     330                 :             :     {
     331                 :             :       // memory allocation failed
     332                 :           0 :       error_at (UNKNOWN_LOCATION,
     333                 :             :                 "memory allocation failed in vasprintf");
     334                 :           0 :       gcc_assert (0);
     335                 :             :     }
     336                 :           0 :   std::string rval = std::string (mbuf);
     337                 :           0 :   free (mbuf);
     338                 :           0 :   return rval;
     339                 :           0 : }
     340                 :             : 
     341                 :             : 
     342                 :             : static void
     343                 :           0 : gm2_internal_error_at (location_t location, const std::string &errmsg)
     344                 :             : {
     345                 :           0 :   expanded_location exp_loc = expand_location (location);
     346                 :           0 :   std::string loc_str;
     347                 :           0 :   std::string file_str;
     348                 :             : 
     349                 :           0 :   if (exp_loc.file == NULL)
     350                 :             :     file_str.clear ();
     351                 :             :   else
     352                 :           0 :     file_str = std::string (exp_loc.file);
     353                 :             : 
     354                 :           0 :   if (! file_str.empty ())
     355                 :             :     {
     356                 :           0 :       loc_str += file_str;
     357                 :           0 :       loc_str += ':';
     358                 :           0 :       loc_str += std::to_string (exp_loc.line);
     359                 :           0 :       loc_str += ':';
     360                 :           0 :       loc_str += std::to_string (exp_loc.column);
     361                 :             :     }
     362                 :           0 :   if (loc_str.empty ())
     363                 :           0 :     internal_error ("%s", errmsg.c_str ());
     364                 :             :   else
     365                 :           0 :     internal_error ("at %s, %s", loc_str.c_str (), errmsg.c_str ());
     366                 :             : }
     367                 :             : 
     368                 :             : 
     369                 :             : void
     370                 :           0 : m2linemap_internal_error_at (location_t location, const char *fmt, ...)
     371                 :             : {
     372                 :           0 :   va_list ap;
     373                 :             : 
     374                 :           0 :   va_start (ap, fmt);
     375                 :           0 :   gm2_internal_error_at (location, expand_message (fmt, ap));
     376                 :             :   va_end (ap);
     377                 :             : }
     378                 :             : 
     379                 :             : /* UnknownLocation - return the predefined location representing an
     380                 :             :    unknown location.  */
     381                 :             : 
     382                 :             : EXTERN
     383                 :             : location_t
     384                 :   111229756 : m2linemap_UnknownLocation (void)
     385                 :             : {
     386                 :   111229756 :   return UNKNOWN_LOCATION;
     387                 :             : }
     388                 :             : 
     389                 :             : /* BuiltinsLocation - return the predefined location representing a
     390                 :             :    builtin.  */
     391                 :             : 
     392                 :             : EXTERN
     393                 :             : location_t
     394                 :     3643132 : m2linemap_BuiltinsLocation (void)
     395                 :             : {
     396                 :     3643132 :   return BUILTINS_LOCATION;
     397                 :             : }
        

Generated by: LCOV version 2.1-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.