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: 2026-02-28 14:20:25 Functions: 68.0 % 25 17
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* m2linemap.cc provides an interface to GCC linemaps.
       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              : #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       292144 : m2linemap_StartFile (void *filename, unsigned int linebegin)
      54              : {
      55       292144 :   if (inFile)
      56       277193 :     m2linemap_EndFile ();
      57       292144 :   linemap_add (line_table, LC_ENTER, false,
      58       292144 :                xstrdup (reinterpret_cast<char *> (filename)), linebegin);
      59       292144 :   inFile = TRUE;
      60       292144 : }
      61              : 
      62              : /* Tell the line table the file has ended.  */
      63              : 
      64              : EXTERN
      65              : void
      66       277193 : m2linemap_EndFile (void)
      67              : {
      68       277193 :   linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
      69       277193 :   inFile = FALSE;
      70       277193 : }
      71              : 
      72              : /* Indicate that there is a new source file line number with a
      73              :    maximum width.  */
      74              : 
      75              : EXTERN
      76              : void
      77     65921892 : m2linemap_StartLine (unsigned int linenumber, unsigned int linesize)
      78              : {
      79     65921892 :   linemap_line_start (line_table, linenumber, linesize);
      80     65921892 : }
      81              : 
      82              : /* GetLocationColumn, returns a location_t based on the current line
      83              :    number and column.  */
      84              : 
      85              : EXTERN
      86              : location_t
      87   1878223628 : m2linemap_GetLocationColumn (unsigned int column)
      88              : {
      89   1878223628 :   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   1878223628 : m2linemap_GetLocationRange (unsigned int start, unsigned int end)
      98              : {
      99   1878223628 :   location_t caret = m2linemap_GetLocationColumn (start);
     100              : 
     101   1878223628 :   source_range where;
     102   1878223628 :   where.m_start = linemap_position_for_column (line_table, start);
     103   1878223628 :   where.m_finish = linemap_position_for_column (line_table, end);
     104   1878223628 :   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     12291885 : m2linemap_GetLocationBinary (location_t caret, location_t start, location_t finish)
     122              : {
     123     12291885 :   if (isSrcLocation (start) && isSrcLocation (finish) && isSrcLocation (caret)
     124     24583770 :     && (m2linemap_GetFilenameFromLocation (start) != NULL))
     125              :     {
     126     12147093 :       linemap_add (line_table, LC_ENTER, false, xstrdup (m2linemap_GetFilenameFromLocation (start)), 1);
     127     12147093 :       gcc_assert (inFile);
     128     12147093 :       location_t location = make_location (caret, start, finish);
     129     12147093 :       linemap_add (line_table, LC_LEAVE, false, NULL, 0);
     130     12147093 :       return location;
     131              :     }
     132              :   return caret;
     133              : }
     134              : 
     135              : /* GetLineNoFromLocation - returns the lineno given a location.  */
     136              : 
     137              : EXTERN
     138              : int
     139         3868 : m2linemap_GetLineNoFromLocation (location_t location)
     140              : {
     141         3868 :   if (isSrcLocation (location) && (!M2Options_GetCpp ()))
     142              :     {
     143         3256 :       expanded_location xl = expand_location (location);
     144         3256 :       return xl.line;
     145              :     }
     146              :   return 0;
     147              : }
     148              : 
     149              : /* GetColumnNoFromLocation - returns the columnno given a location.  */
     150              : 
     151              : EXTERN
     152              : int
     153         3868 : m2linemap_GetColumnNoFromLocation (location_t location)
     154              : {
     155         3868 :   if (isSrcLocation (location) && (!M2Options_GetCpp ()))
     156              :     {
     157         3256 :       expanded_location xl = expand_location (location);
     158         3256 :       return xl.column;
     159              :     }
     160              :   return 0;
     161              : }
     162              : 
     163              : /* GetFilenameFromLocation - returns the filename given a location.  */
     164              : 
     165              : EXTERN
     166              : const char *
     167     24442846 : m2linemap_GetFilenameFromLocation (location_t location)
     168              : {
     169     24442846 :   if (isSrcLocation (location) && (!M2Options_GetCpp ()))
     170              :     {
     171     24297442 :       expanded_location xl = expand_location (location);
     172     24297442 :       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         3196 : m2linemap_ErrorAtf_1 (location_t location, const char *message, ...)
     190              : {
     191         3196 :   diagnostics::diagnostic_info diagnostic;
     192         3196 :   va_list ap;
     193         3196 :   rich_location richloc (line_table, location);
     194              : 
     195         3196 :   va_start (ap, message);
     196         3196 :   diagnostic_set_info (&diagnostic, message, &ap, &richloc,
     197              :                        diagnostics::kind::error);
     198         3196 :   diagnostic_report_diagnostic (global_dc, &diagnostic);
     199         3196 :   va_end (ap);
     200         3196 : }
     201              : 
     202              : void
     203         3196 : m2linemap_ErrorAtf (location_t location, const char *message)
     204              : {
     205         3196 :   m2linemap_ErrorAtf_1 (location, "%s", message);
     206         3196 : }
     207              : 
     208              : /* m2linemap_WarningAtf - wraps up a warning message.  */
     209              : 
     210              : static void
     211          600 : m2linemap_WarningAtf_1 (location_t location, const char *message, ...)
     212              : {
     213          600 :   diagnostics::diagnostic_info diagnostic;
     214          600 :   va_list ap;
     215          600 :   rich_location richloc (line_table, location);
     216              : 
     217          600 :   va_start (ap, message);
     218          600 :   diagnostic_set_info (&diagnostic, message, &ap, &richloc,
     219              :                        diagnostics::kind::warning);
     220          600 :   diagnostic_report_diagnostic (global_dc, &diagnostic);
     221          600 :   va_end (ap);
     222          600 : }
     223              : 
     224              : void
     225          600 : m2linemap_WarningAtf (location_t location, const char *message)
     226              : {
     227          600 :   m2linemap_WarningAtf_1 (location, "%s", message);
     228          600 : }
     229              : 
     230              : /* m2linemap_NoteAtf - wraps up a note message.  */
     231              : 
     232              : static void
     233           31 : m2linemap_NoteAtf_1 (location_t location, const char *message, ...)
     234              : {
     235           31 :   diagnostics::diagnostic_info diagnostic;
     236           31 :   va_list ap;
     237           31 :   rich_location richloc (line_table, location);
     238              : 
     239           31 :   va_start (ap, message);
     240           31 :   diagnostic_set_info (&diagnostic, message, &ap, &richloc,
     241              :                        diagnostics::kind::note);
     242           31 :   diagnostic_report_diagnostic (global_dc, &diagnostic);
     243           31 :   va_end (ap);
     244           31 : }
     245              : 
     246              : void
     247           31 : m2linemap_NoteAtf (location_t location, const char *message)
     248              : {
     249           31 :   m2linemap_NoteAtf_1 (location, "%s", message);
     250           31 : }
     251              : 
     252              : /* m2linemap_internal_error - allow Modula-2 to use the GCC internal error.  */
     253              : 
     254              : void
     255            0 : m2linemap_internal_error (const char *message)
     256              : {
     257            0 :   internal_error ("%s", message);
     258              : }
     259              : 
     260              : 
     261              : /* Code derived from rust.  */
     262              : 
     263              : static std::string
     264            0 : mformat_value ()
     265              : {
     266            0 :   return std::string (xstrerror (errno));
     267              : }
     268              : 
     269              : 
     270              : static std::string
     271            0 : expand_format (const char *fmt)
     272              : {
     273            0 :   std::string result;
     274            0 :   for (const char *c = fmt; *c; ++c)
     275              :     {
     276            0 :       if (*c != '%')
     277              :         {
     278            0 :           result += *c;
     279            0 :           continue;
     280              :         }
     281            0 :       c++;
     282            0 :       switch (*c)
     283              :         {
     284            0 :           case '\0': {
     285              :             // malformed format string
     286            0 :             gcc_unreachable ();
     287              :           }
     288            0 :           case '%': {
     289            0 :             result += '%';
     290            0 :             break;
     291              :           }
     292            0 :           case 'm': {
     293            0 :             result += mformat_value ();
     294            0 :             break;
     295              :           }
     296            0 :           case '<': {
     297            0 :             result += m2color_open_quote ();
     298            0 :             break;
     299              :           }
     300            0 :           case '>': {
     301            0 :             result += m2color_close_quote ();
     302            0 :             break;
     303              :           }
     304            0 :           case 'q': {
     305            0 :             result += m2color_open_quote ();
     306            0 :             c++;
     307            0 :             if (*c == 'm')
     308            0 :               result += mformat_value ();
     309              :             else
     310              :               {
     311            0 :                 result += '%';
     312            0 :                 result += *c;
     313              :               }
     314            0 :             result += m2color_close_quote ();
     315            0 :             break;
     316              :           }
     317            0 :           default: {
     318            0 :             result += '%';
     319            0 :             result += *c;
     320              :           }
     321              :         }
     322              :     }
     323            0 :   return result;
     324              : }
     325              : 
     326              : static std::string
     327            0 : expand_message (const char *fmt, va_list ap)
     328              : {
     329            0 :   char *mbuf = 0;
     330            0 :   std::string expanded_fmt = expand_format (fmt);
     331            0 :   int nwr = vasprintf (&mbuf, expanded_fmt.c_str (), ap);
     332            0 :   if (nwr == -1)
     333              :     {
     334              :       // memory allocation failed
     335            0 :       error_at (UNKNOWN_LOCATION,
     336              :                 "memory allocation failed in vasprintf");
     337            0 :       gcc_assert (0);
     338              :     }
     339            0 :   std::string rval = std::string (mbuf);
     340            0 :   free (mbuf);
     341            0 :   return rval;
     342            0 : }
     343              : 
     344              : 
     345              : static void
     346            0 : gm2_internal_error_at (location_t location, const std::string &errmsg)
     347              : {
     348            0 :   expanded_location exp_loc = expand_location (location);
     349            0 :   std::string loc_str;
     350            0 :   std::string file_str;
     351              : 
     352            0 :   if (exp_loc.file == NULL)
     353              :     file_str.clear ();
     354              :   else
     355            0 :     file_str = std::string (exp_loc.file);
     356              : 
     357            0 :   if (! file_str.empty ())
     358              :     {
     359            0 :       loc_str += file_str;
     360            0 :       loc_str += ':';
     361            0 :       loc_str += std::to_string (exp_loc.line);
     362            0 :       loc_str += ':';
     363            0 :       loc_str += std::to_string (exp_loc.column);
     364              :     }
     365            0 :   if (loc_str.empty ())
     366            0 :     internal_error ("%s", errmsg.c_str ());
     367              :   else
     368            0 :     internal_error ("at %s, %s", loc_str.c_str (), errmsg.c_str ());
     369              : }
     370              : 
     371              : 
     372              : void
     373            0 : m2linemap_internal_error_at (location_t location, const char *fmt, ...)
     374              : {
     375            0 :   va_list ap;
     376              : 
     377            0 :   va_start (ap, fmt);
     378            0 :   gm2_internal_error_at (location, expand_message (fmt, ap));
     379              :   va_end (ap);
     380              : }
     381              : 
     382              : /* UnknownLocation - return the predefined location representing an
     383              :    unknown location.  */
     384              : 
     385              : EXTERN
     386              : location_t
     387    158405477 : m2linemap_UnknownLocation (void)
     388              : {
     389    158405477 :   return UNKNOWN_LOCATION;
     390              : }
     391              : 
     392              : /* BuiltinsLocation - return the predefined location representing a
     393              :    builtin.  */
     394              : 
     395              : EXTERN
     396              : location_t
     397      3748375 : m2linemap_BuiltinsLocation (void)
     398              : {
     399      3748375 :   return BUILTINS_LOCATION;
     400              : }
        

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.