LCOV - code coverage report
Current view: top level - gcc/rust/parse - rust-parse-impl-ttree.hxx (source / functions) Coverage Total Hit
Test: gcc.info Lines: 100.0 % 60 60
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 4 4
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              : #include "rust-parse-error.h"
      25              : #include "expected.h"
      26              : 
      27              : namespace Rust {
      28              : 
      29              : /* Parses a TokenTree syntactical production. This is either a delimited token
      30              :  * tree or a non-delimiter token. */
      31              : template <typename ManagedTokenSource>
      32              : tl::expected<std::unique_ptr<AST::TokenTree>, Parse::Error::Node>
      33        66514 : Parser<ManagedTokenSource>::parse_token_tree ()
      34              : {
      35        66514 :   const_TokenPtr t = lexer.peek_token ();
      36              : 
      37        66514 :   switch (t->get_id ())
      38              :     {
      39         5510 :     case LEFT_PAREN:
      40              :     case LEFT_SQUARE:
      41              :     case LEFT_CURLY:
      42              :       {
      43              :         // Parse delimited token tree
      44         5510 :         auto delim_token_tree = parse_delim_token_tree ();
      45         5510 :         if (!delim_token_tree)
      46              :           return tl::unexpected<Parse::Error::Node> (
      47            2 :             Parse::Error::Node::CHILD_ERROR);
      48              : 
      49              :         // TODO: use move rather than copy constructor
      50         5508 :         return std::unique_ptr<AST::DelimTokenTree> (
      51         5508 :           new AST::DelimTokenTree (delim_token_tree.value ()));
      52         5510 :       }
      53            2 :     case RIGHT_PAREN:
      54              :     case RIGHT_SQUARE:
      55              :     case RIGHT_CURLY:
      56              :       // error - should not be called when this a token
      57            2 :       add_error (Error (t->get_locus (), "unexpected closing delimiter %qs",
      58              :                         t->get_token_description ()));
      59              : 
      60            4 :       add_error (Error (Error::Kind::Hint, t->get_locus (),
      61            2 :                         "token tree requires either paired delimiters or "
      62              :                         "non-delimiter tokens"));
      63              : 
      64            2 :       lexer.skip_token ();
      65            2 :       return tl::unexpected<Parse::Error::Node> (Parse::Error::Node::MALFORMED);
      66        61002 :     default:
      67              :       // parse token itself as TokenTree
      68        61002 :       lexer.skip_token ();
      69        61002 :       return std::unique_ptr<AST::Token> (new AST::Token (std::move (t)));
      70              :     }
      71        66514 : }
      72              : 
      73              : // Parses a delimited token tree
      74              : template <typename ManagedTokenSource>
      75              : tl::expected<AST::DelimTokenTree, Parse::Error::Node>
      76        19736 : Parser<ManagedTokenSource>::parse_delim_token_tree ()
      77              : {
      78        19736 :   const_TokenPtr t = lexer.peek_token ();
      79        19736 :   lexer.skip_token ();
      80        19736 :   location_t initial_loc = t->get_locus ();
      81              : 
      82              :   // save delim type to ensure it is reused later
      83        19736 :   AST::DelimType delim_type = AST::PARENS;
      84              : 
      85              :   // Map tokens to DelimType
      86        19736 :   switch (t->get_id ())
      87              :     {
      88              :     case LEFT_PAREN:
      89              :       delim_type = AST::PARENS;
      90              :       break;
      91          499 :     case LEFT_SQUARE:
      92          499 :       delim_type = AST::SQUARE;
      93          499 :       break;
      94         2685 :     case LEFT_CURLY:
      95         2685 :       delim_type = AST::CURLY;
      96         2685 :       break;
      97            2 :     default:
      98            2 :       add_error (Error (t->get_locus (),
      99              :                         "unexpected token %qs - expecting delimiters (for a "
     100              :                         "delimited token tree)",
     101              :                         t->get_token_description ()));
     102              : 
     103            2 :       return tl::unexpected<Parse::Error::Node> (Parse::Error::Node::MALFORMED);
     104              :     }
     105              : 
     106              :   // parse actual token tree vector - 0 or more
     107        19734 :   std::vector<std::unique_ptr<AST::TokenTree>> token_trees_in_tree;
     108        19734 :   auto delim_open
     109        19734 :     = std::unique_ptr<AST::Token> (new AST::Token (std::move (t)));
     110        19734 :   token_trees_in_tree.push_back (std::move (delim_open));
     111              : 
     112              :   // repeat loop until finding the matching delimiter
     113        19734 :   t = lexer.peek_token ();
     114        82261 :   while (!Parse::Utils::token_id_matches_delims (t->get_id (), delim_type)
     115        82259 :          && t->get_id () != END_OF_FILE)
     116              :     {
     117        62527 :       auto tok_tree = parse_token_tree ();
     118        62527 :       if (!tok_tree)
     119              :         return tl::unexpected<Parse::Error::Node> (
     120            2 :           Parse::Error::Node::CHILD_ERROR);
     121              : 
     122        62525 :       token_trees_in_tree.push_back (std::move (tok_tree.value ()));
     123              : 
     124              :       // lexer.skip_token();
     125        62525 :       t = lexer.peek_token ();
     126              :     }
     127        19732 :   auto delim_close
     128        19732 :     = std::unique_ptr<AST::Token> (new AST::Token (std::move (t)));
     129        19732 :   token_trees_in_tree.push_back (std::move (delim_close));
     130              : 
     131        19732 :   AST::DelimTokenTree token_tree (delim_type, std::move (token_trees_in_tree),
     132              :                                   initial_loc);
     133              : 
     134              :   // parse end delimiters
     135        19732 :   t = lexer.peek_token ();
     136              : 
     137        19732 :   if (Parse::Utils::token_id_matches_delims (t->get_id (), delim_type))
     138              :     {
     139              :       // tokens match opening delimiter, so skip.
     140        19725 :       lexer.skip_token ();
     141        19725 :       return token_tree;
     142              :     }
     143              :   else
     144              :     {
     145              :       // tokens don't match opening delimiters, so produce error
     146            7 :       Error error (t->get_locus (),
     147              :                    "unexpected token %qs - expecting closing delimiter %qs "
     148              :                    "(for a delimited token tree)",
     149              :                    t->get_token_description (),
     150              :                    (delim_type == AST::PARENS
     151              :                       ? ")"
     152              :                       : (delim_type == AST::SQUARE ? "]" : "}")));
     153            7 :       add_error (std::move (error));
     154              : 
     155            7 :       return tl::unexpected<Parse::Error::Node> (Parse::Error::Node::MALFORMED);
     156            7 :     }
     157        19734 : }
     158              : 
     159              : } // 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.