LCOV - code coverage report
Current view: top level - gcc/rust/parse - rust-parse-impl-utils.hxx (source / functions) Coverage Total Hit
Test: gcc.info Lines: 67.4 % 89 60
Test Date: 2026-02-28 14:20:25 Functions: 46.4 % 28 13
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Copyright (C) 2025-2026 Free Software Foundation, Inc.
       2              : 
       3              : // This file is part of GCC.
       4              : 
       5              : // GCC is free software; you can redistribute it and/or modify it under
       6              : // the terms of the GNU General Public License as published by the Free
       7              : // Software Foundation; either version 3, or (at your option) any later
       8              : // version.
       9              : 
      10              : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11              : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12              : // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13              : // for more details.
      14              : 
      15              : // You should have received a copy of the GNU General Public License
      16              : // along with GCC; see the file COPYING3.  If not see
      17              : // <http://www.gnu.org/licenses/>.
      18              : 
      19              : /* DO NOT INCLUDE ANYWHERE - this is automatically included
      20              :  *   by rust-parse-impl.h
      21              :  * This is also the reason why there are no include guards. */
      22              : 
      23              : #include "rust-parse.h"
      24              : 
      25              : namespace Rust {
      26              : 
      27              : // "Unexpected token" panic mode - flags gcc error at unexpected token
      28              : // TODO: seems to be unused, remove?
      29              : template <typename ManagedTokenSource>
      30              : void
      31            0 : Parser<ManagedTokenSource>::unexpected_token (const_TokenPtr t)
      32              : {
      33            0 :   Error error (t->get_locus (), "unexpected token %qs",
      34              :                t->get_token_description ());
      35            0 :   add_error (std::move (error));
      36            0 : }
      37              : 
      38              : /* Crappy "error recovery" performed after error by skipping tokens until a
      39              :  * semi-colon is found */
      40              : template <typename ManagedTokenSource>
      41              : void
      42           25 : Parser<ManagedTokenSource>::skip_after_semicolon ()
      43              : {
      44           25 :   const_TokenPtr t = lexer.peek_token ();
      45              : 
      46           34 :   while (t->get_id () != END_OF_FILE && t->get_id () != SEMICOLON)
      47              :     {
      48            9 :       lexer.skip_token ();
      49            9 :       t = lexer.peek_token ();
      50              :     }
      51              : 
      52           25 :   if (t->get_id () == SEMICOLON)
      53            4 :     lexer.skip_token ();
      54           25 : }
      55              : 
      56              : /* Skips the current token */
      57              : template <typename ManagedTokenSource>
      58              : void
      59         5562 : Parser<ManagedTokenSource>::skip_token ()
      60              : {
      61         1534 :   lexer.skip_token ();
      62         1369 : }
      63              : 
      64              : /* Checks if current token has inputted id - skips it and returns true if so,
      65              :  * diagnoses an error and returns false otherwise. */
      66              : template <typename ManagedTokenSource>
      67              : bool
      68       296567 : Parser<ManagedTokenSource>::skip_token (TokenId token_id)
      69              : {
      70       296567 :   return expect_token (token_id) != const_TokenPtr ();
      71              : }
      72              : 
      73              : /* Checks if current token is similar to inputted token - skips it and returns
      74              :  * true if so, diagnoses an error and returns false otherwise. */
      75              : template <typename ManagedTokenSource>
      76              : bool
      77         2692 : Parser<ManagedTokenSource>::skip_token (const_TokenPtr token)
      78              : {
      79         8019 :   return expect_token (token) != const_TokenPtr ();
      80              : }
      81              : 
      82              : /* Checks if current token has inputted id - skips it and returns true if so,
      83              :  * returns false otherwise without diagnosing an error */
      84              : template <typename ManagedTokenSource>
      85              : bool
      86        47112 : Parser<ManagedTokenSource>::maybe_skip_token (TokenId token_id)
      87              : {
      88        94224 :   if (lexer.peek_token ()->get_id () != token_id)
      89              :     return false;
      90              :   else
      91         1101 :     return skip_token (token_id);
      92              : }
      93              : 
      94              : /* Checks the current token - if id is same as expected, skips and returns it,
      95              :  * otherwise diagnoses error and returns null. */
      96              : template <typename ManagedTokenSource>
      97              : const_TokenPtr
      98       334794 : Parser<ManagedTokenSource>::expect_token (TokenId token_id)
      99              : {
     100       334794 :   const_TokenPtr t = lexer.peek_token ();
     101       334794 :   if (t->get_id () == token_id)
     102              :     {
     103       333108 :       lexer.skip_token ();
     104       333108 :       return t;
     105              :     }
     106              :   else
     107              :     {
     108         1686 :       Error error (t->get_locus (), "expecting %qs but %qs found",
     109              :                    get_token_description (token_id),
     110              :                    t->get_token_description ());
     111         1686 :       add_error (std::move (error));
     112              : 
     113         1686 :       return const_TokenPtr ();
     114         1686 :     }
     115       334794 : }
     116              : 
     117              : /* Checks the current token - if same as expected, skips and returns it,
     118              :  * otherwise diagnoses error and returns null. */
     119              : template <typename ManagedTokenSource>
     120              : const_TokenPtr
     121         2692 : Parser<ManagedTokenSource>::expect_token (const_TokenPtr token_expect)
     122              : {
     123         2692 :   const_TokenPtr t = lexer.peek_token ();
     124         2692 :   if (t->get_id () == token_expect->get_id ()
     125         2692 :       && (!t->should_have_str () || t->get_str () == token_expect->get_str ()))
     126              :     {
     127         2635 :       lexer.skip_token ();
     128         2635 :       return t;
     129              :     }
     130              :   else
     131              :     {
     132           57 :       Error error (t->get_locus (), "expecting %qs but %qs found",
     133              :                    token_expect->get_token_description (),
     134              :                    t->get_token_description ());
     135           57 :       add_error (std::move (error));
     136              : 
     137           57 :       return const_TokenPtr ();
     138           57 :     }
     139         2692 : }
     140              : 
     141              : // Skips all tokens until EOF or }. Don't use.
     142              : template <typename ManagedTokenSource>
     143              : void
     144            0 : Parser<ManagedTokenSource>::skip_after_end ()
     145              : {
     146            0 :   const_TokenPtr t = lexer.peek_token ();
     147              : 
     148            0 :   while (t->get_id () != END_OF_FILE && t->get_id () != RIGHT_CURLY)
     149              :     {
     150            0 :       lexer.skip_token ();
     151            0 :       t = lexer.peek_token ();
     152              :     }
     153              : 
     154            0 :   if (t->get_id () == RIGHT_CURLY)
     155              :     {
     156            0 :       lexer.skip_token ();
     157              :     }
     158            0 : }
     159              : 
     160              : /* A slightly more aware error-handler that skips all tokens until it reaches
     161              :  * the end of the block scope (i.e. when left curly brackets = right curly
     162              :  * brackets). Note: assumes currently in the middle of a block. Use
     163              :  * skip_after_next_block to skip based on the assumption that the block
     164              :  * has not been entered yet. */
     165              : template <typename ManagedTokenSource>
     166              : void
     167           34 : Parser<ManagedTokenSource>::skip_after_end_block ()
     168              : {
     169           34 :   const_TokenPtr t = lexer.peek_token ();
     170           34 :   int curly_count = 1;
     171              : 
     172          112 :   while (curly_count > 0 && t->get_id () != END_OF_FILE)
     173              :     {
     174           78 :       switch (t->get_id ())
     175              :         {
     176            6 :         case LEFT_CURLY:
     177            6 :           curly_count++;
     178            6 :           break;
     179           18 :         case RIGHT_CURLY:
     180           18 :           curly_count--;
     181           18 :           break;
     182              :         default:
     183              :           break;
     184              :         }
     185           78 :       lexer.skip_token ();
     186           78 :       t = lexer.peek_token ();
     187              :     }
     188           34 : }
     189              : 
     190              : /* Skips tokens until the end of the next block. i.e. assumes that the block
     191              :  * has not been entered yet. */
     192              : template <typename ManagedTokenSource>
     193              : void
     194            1 : Parser<ManagedTokenSource>::skip_after_next_block ()
     195              : {
     196            1 :   const_TokenPtr t = lexer.peek_token ();
     197              : 
     198              :   // initial loop - skip until EOF if no left curlies encountered
     199            1 :   while (t->get_id () != END_OF_FILE && t->get_id () != LEFT_CURLY)
     200              :     {
     201            0 :       lexer.skip_token ();
     202              : 
     203            0 :       t = lexer.peek_token ();
     204              :     }
     205              : 
     206              :   // if next token is left, skip it and then skip after the block ends
     207            1 :   if (t->get_id () == LEFT_CURLY)
     208              :     {
     209            1 :       lexer.skip_token ();
     210              : 
     211            1 :       skip_after_end_block ();
     212              :     }
     213              :   // otherwise, do nothing as EOF
     214            1 : }
     215              : 
     216              : /* Skips all tokens until ] (the end of an attribute) - does not skip the ]
     217              :  * (as designed for attribute body use) */
     218              : template <typename ManagedTokenSource>
     219              : void
     220            0 : Parser<ManagedTokenSource>::skip_after_end_attribute ()
     221              : {
     222            0 :   const_TokenPtr t = lexer.peek_token ();
     223              : 
     224            0 :   while (t->get_id () != RIGHT_SQUARE && t->get_id () != END_OF_FILE)
     225              :     {
     226            0 :       lexer.skip_token ();
     227            0 :       t = lexer.peek_token ();
     228              :     }
     229              : 
     230              :   // Don't skip the RIGHT_SQUARE token
     231            0 : }
     232              : 
     233              : // Returns true if the next token is END, ELSE, or EOF;
     234              : template <typename ManagedTokenSource>
     235              : bool
     236            0 : Parser<ManagedTokenSource>::done_end_or_else ()
     237              : {
     238            0 :   const_TokenPtr t = lexer.peek_token ();
     239            0 :   return (t->get_id () == RIGHT_CURLY || t->get_id () == ELSE
     240            0 :           || t->get_id () == END_OF_FILE);
     241            0 : }
     242              : 
     243              : // Returns true if the next token is END or EOF.
     244              : template <typename ManagedTokenSource>
     245              : bool
     246            0 : Parser<ManagedTokenSource>::done_end ()
     247              : {
     248            0 :   const_TokenPtr t = lexer.peek_token ();
     249            0 :   return (t->get_id () == RIGHT_CURLY || t->get_id () == END_OF_FILE);
     250            0 : }
     251              : 
     252              : } // namespace Rust
        

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.