LCOV - code coverage report
Current view: top level - gcc/rust/ast - rust-path.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 63.8 % 149 95
Test Date: 2024-04-27 14:03:13 Functions: 64.0 % 25 16
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* General AST-related method implementations for Rust frontend.
       2                 :             :    Copyright (C) 2009-2024 Free Software Foundation, Inc.
       3                 :             : 
       4                 :             : This file is part of GCC.
       5                 :             : 
       6                 :             : GCC is free software; you can redistribute it and/or modify it under
       7                 :             : the terms of the GNU General Public License as published by the Free
       8                 :             : Software Foundation; either version 3, or (at your option) any later
       9                 :             : version.
      10                 :             : 
      11                 :             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12                 :             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13                 :             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14                 :             : for more details.
      15                 :             : 
      16                 :             : You should have received a copy of the GNU General Public License
      17                 :             : along with GCC; see the file COPYING3.  If not see
      18                 :             : <http://www.gnu.org/licenses/>.  */
      19                 :             : 
      20                 :             : #include "rust-system.h"
      21                 :             : #include "rust-ast-full.h"
      22                 :             : #include "rust-diagnostics.h"
      23                 :             : #include "rust-ast-visitor.h"
      24                 :             : #include "rust-macro.h"
      25                 :             : #include "rust-session-manager.h"
      26                 :             : #include "rust-lex.h"
      27                 :             : #include "rust-parse.h"
      28                 :             : #include "rust-operators.h"
      29                 :             : 
      30                 :             : namespace Rust {
      31                 :             : namespace AST {
      32                 :             : 
      33                 :             : std::string
      34                 :         553 : GenericArgs::as_string () const
      35                 :             : {
      36                 :         553 :   std::string args;
      37                 :             : 
      38                 :             :   // lifetime args
      39                 :         553 :   if (!lifetime_args.empty ())
      40                 :             :     {
      41                 :             :       auto i = lifetime_args.begin ();
      42                 :             :       auto e = lifetime_args.end ();
      43                 :             : 
      44                 :           8 :       for (; i != e; i++)
      45                 :             :         {
      46                 :           4 :           args += (*i).as_string ();
      47                 :           4 :           if (e != i + 1)
      48                 :           0 :             args += ", ";
      49                 :             :         }
      50                 :             :     }
      51                 :             : 
      52                 :             :   // type args
      53                 :         553 :   if (!generic_args.empty ())
      54                 :             :     {
      55                 :             :       auto i = generic_args.begin ();
      56                 :             :       auto e = generic_args.end ();
      57                 :             : 
      58                 :        1182 :       for (; i != e; i++)
      59                 :             :         {
      60                 :         632 :           args += (*i).as_string ();
      61                 :         632 :           if (e != i + 1)
      62                 :          82 :             args += ", ";
      63                 :             :         }
      64                 :             :     }
      65                 :             : 
      66                 :             :   // binding args
      67                 :         553 :   if (!binding_args.empty ())
      68                 :             :     {
      69                 :             :       auto i = binding_args.begin ();
      70                 :             :       auto e = binding_args.end ();
      71                 :             : 
      72                 :           0 :       for (; i != e; i++)
      73                 :             :         {
      74                 :           0 :           args += (*i).as_string ();
      75                 :           0 :           if (e != i + 1)
      76                 :           0 :             args += ", ";
      77                 :             :         }
      78                 :             :     }
      79                 :             : 
      80                 :         553 :   return args;
      81                 :             : }
      82                 :             : 
      83                 :             : GenericArg
      84                 :           4 : GenericArg::disambiguate_to_const () const
      85                 :             : {
      86                 :           4 :   rust_assert (get_kind () == Kind::Either);
      87                 :             : 
      88                 :             :   // FIXME: is it fine to have no outer attributes?
      89                 :           4 :   return GenericArg::create_const (
      90                 :           4 :     std::unique_ptr<Expr> (new IdentifierExpr (path, {}, locus)));
      91                 :             : }
      92                 :             : 
      93                 :             : GenericArg
      94                 :        1428 : GenericArg::disambiguate_to_type () const
      95                 :             : {
      96                 :        1428 :   rust_assert (get_kind () == Kind::Either);
      97                 :             : 
      98                 :        1428 :   auto segment = std::unique_ptr<TypePathSegment> (
      99                 :        1428 :     new TypePathSegment (path.as_string (), false, locus));
     100                 :        1428 :   auto segments = std::vector<std::unique_ptr<TypePathSegment>> ();
     101                 :        1428 :   segments.emplace_back (std::move (segment));
     102                 :             : 
     103                 :        1428 :   return GenericArg::create_type (
     104                 :        1428 :     std::unique_ptr<Type> (new TypePath (std::move (segments), locus)));
     105                 :        1428 : }
     106                 :             : 
     107                 :             : std::string
     108                 :           0 : GenericArgsBinding::as_string () const
     109                 :             : {
     110                 :             :   // TODO: rewrite to work with non-literalisable types
     111                 :           0 :   return identifier.as_string () + " = " + type->as_string ();
     112                 :             : }
     113                 :             : 
     114                 :             : std::string
     115                 :           0 : ConstGenericParam::as_string () const
     116                 :             : {
     117                 :           0 :   std::string str ("ConstGenericParam: ");
     118                 :           0 :   str += "const " + name.as_string () + ": " + type->as_string ();
     119                 :             : 
     120                 :           0 :   if (has_default_value ())
     121                 :           0 :     str += " = " + get_default_value ().as_string ();
     122                 :             : 
     123                 :           0 :   return str;
     124                 :             : }
     125                 :             : 
     126                 :             : std::string
     127                 :        4281 : PathExprSegment::as_string () const
     128                 :             : {
     129                 :             :   // TODO: rewrite dump to work with non-literalisable types
     130                 :        4281 :   std::string ident_str = segment_name.as_string ();
     131                 :        4281 :   if (has_generic_args ())
     132                 :           0 :     ident_str += "::<" + generic_args.as_string () + ">";
     133                 :             : 
     134                 :        4281 :   return ident_str;
     135                 :             : }
     136                 :             : 
     137                 :             : std::string
     138                 :           0 : PathPattern::as_string () const
     139                 :             : {
     140                 :           0 :   std::string str;
     141                 :             : 
     142                 :           0 :   for (const auto &segment : segments)
     143                 :           0 :     str += segment.as_string () + "::";
     144                 :             : 
     145                 :             :   // basically a hack - remove last two characters of string (remove final ::)
     146                 :           0 :   str.erase (str.length () - 2);
     147                 :             : 
     148                 :           0 :   return str;
     149                 :             : }
     150                 :             : 
     151                 :             : SimplePath
     152                 :        2116 : PathPattern::convert_to_simple_path (bool with_opening_scope_resolution) const
     153                 :             : {
     154                 :        2116 :   if (!has_segments ())
     155                 :           0 :     return SimplePath::create_empty ();
     156                 :             : 
     157                 :             :   // create vector of reserved size (to minimise reallocations)
     158                 :        2116 :   std::vector<SimplePathSegment> simple_segments;
     159                 :        2116 :   simple_segments.reserve (segments.size ());
     160                 :             : 
     161                 :        4255 :   for (const auto &segment : segments)
     162                 :             :     {
     163                 :             :       // return empty path if doesn't meet simple path segment requirements
     164                 :        6417 :       if (segment.is_error () || segment.has_generic_args ()
     165                 :        4278 :           || segment.as_string () == "Self")
     166                 :           0 :         return SimplePath::create_empty ();
     167                 :             : 
     168                 :             :       // create segment and add to vector
     169                 :        2139 :       std::string segment_str = segment.as_string ();
     170                 :        4278 :       simple_segments.push_back (
     171                 :        4278 :         SimplePathSegment (std::move (segment_str), segment.get_locus ()));
     172                 :        2139 :     }
     173                 :             : 
     174                 :             :   // kind of a HACK to get locus depending on opening scope resolution
     175                 :        2116 :   location_t locus = UNKNOWN_LOCATION;
     176                 :        2116 :   if (with_opening_scope_resolution)
     177                 :           0 :     locus = simple_segments[0].get_locus () - 2; // minus 2 chars for ::
     178                 :             :   else
     179                 :        2116 :     locus = simple_segments[0].get_locus ();
     180                 :             :   // FIXME: this hack probably doesn't actually work
     181                 :             : 
     182                 :        2116 :   return SimplePath (std::move (simple_segments), with_opening_scope_resolution,
     183                 :        2116 :                      locus);
     184                 :        2116 : }
     185                 :             : 
     186                 :             : void
     187                 :      102246 : PathInExpression::accept_vis (ASTVisitor &vis)
     188                 :             : {
     189                 :      102246 :   vis.visit (*this);
     190                 :      102246 : }
     191                 :             : 
     192                 :             : std::string
     193                 :           0 : PathInExpression::as_string () const
     194                 :             : {
     195                 :           0 :   std::string str;
     196                 :             : 
     197                 :           0 :   if (has_opening_scope_resolution)
     198                 :           0 :     str = "::";
     199                 :             : 
     200                 :           0 :   return str + PathPattern::as_string ();
     201                 :           0 : }
     202                 :             : 
     203                 :             : std::string
     204                 :         553 : TypePathSegmentGeneric::as_string () const
     205                 :             : {
     206                 :             :   // TODO: rewrite to work with non-linearisable types
     207                 :        1659 :   return TypePathSegment::as_string () + "<" + generic_args.as_string () + ">";
     208                 :             : }
     209                 :             : 
     210                 :             : std::string
     211                 :           0 : TypePathSegmentFunction::as_string () const
     212                 :             : {
     213                 :             :   // TODO: rewrite to work with non-linearisable types
     214                 :           0 :   return TypePathSegment::as_string () + function_path.as_string ();
     215                 :             : }
     216                 :             : 
     217                 :             : std::string
     218                 :       70351 : TypePath::as_string () const
     219                 :             : {
     220                 :             :   /* TODO: this may need to be rewritten if a segment (e.g. function) can't be
     221                 :             :    * literalised */
     222                 :       70351 :   std::string str;
     223                 :             : 
     224                 :       70351 :   if (has_opening_scope_resolution)
     225                 :           6 :     str = "::";
     226                 :             : 
     227                 :      140739 :   for (const auto &segment : segments)
     228                 :      140776 :     str += segment->as_string () + "::";
     229                 :             : 
     230                 :             :   // kinda hack - remove last 2 '::' characters
     231                 :       70351 :   str.erase (str.length () - 2);
     232                 :             : 
     233                 :       70351 :   return str;
     234                 :             : }
     235                 :             : 
     236                 :             : SimplePath
     237                 :          20 : TypePath::as_simple_path () const
     238                 :             : {
     239                 :          20 :   if (segments.empty ())
     240                 :           0 :     return SimplePath::create_empty ();
     241                 :             : 
     242                 :             :   // create vector of reserved size (to minimise reallocations)
     243                 :          20 :   std::vector<SimplePathSegment> simple_segments;
     244                 :          20 :   simple_segments.reserve (segments.size ());
     245                 :             : 
     246                 :          40 :   for (const auto &segment : segments)
     247                 :             :     {
     248                 :             :       // return empty path if doesn't meet simple path segment requirements
     249                 :          20 :       if (segment == nullptr || segment->is_error ()
     250                 :          40 :           || !segment->is_ident_only () || segment->as_string () == "Self")
     251                 :           0 :         return SimplePath::create_empty ();
     252                 :             : 
     253                 :             :       // create segment and add to vector
     254                 :          20 :       std::string segment_str = segment->as_string ();
     255                 :          40 :       simple_segments.push_back (
     256                 :          40 :         SimplePathSegment (std::move (segment_str), segment->get_locus ()));
     257                 :          20 :     }
     258                 :             : 
     259                 :          20 :   return SimplePath (std::move (simple_segments), has_opening_scope_resolution,
     260                 :          20 :                      locus);
     261                 :          20 : }
     262                 :             : 
     263                 :             : // hopefully definition here will prevent circular dependency issue
     264                 :             : TraitBound *
     265                 :           0 : TypePath::to_trait_bound (bool in_parens) const
     266                 :             : {
     267                 :           0 :   return new TraitBound (TypePath (*this), get_locus (), in_parens);
     268                 :             : }
     269                 :             : 
     270                 :             : std::string
     271                 :           0 : TypePathFunction::as_string () const
     272                 :             : {
     273                 :             :   // TODO: rewrite to work with non-linearisable types
     274                 :           0 :   std::string str ("(");
     275                 :             : 
     276                 :           0 :   if (has_inputs ())
     277                 :             :     {
     278                 :             :       auto i = inputs.begin ();
     279                 :             :       auto e = inputs.end ();
     280                 :             : 
     281                 :           0 :       for (; i != e; i++)
     282                 :             :         {
     283                 :           0 :           str += (*i)->as_string ();
     284                 :           0 :           if (e != i + 1)
     285                 :           0 :             str += ", ";
     286                 :             :         }
     287                 :             :     }
     288                 :             : 
     289                 :           0 :   str += ")";
     290                 :             : 
     291                 :           0 :   if (has_return_type ())
     292                 :           0 :     str += " -> " + return_type->as_string ();
     293                 :             : 
     294                 :           0 :   return str;
     295                 :             : }
     296                 :             : 
     297                 :             : std::string
     298                 :           0 : QualifiedPathInExpression::as_string () const
     299                 :             : {
     300                 :           0 :   return path_type.as_string () + "::" + PathPattern::as_string ();
     301                 :             : }
     302                 :             : 
     303                 :             : std::string
     304                 :           0 : QualifiedPathInType::as_string () const
     305                 :             : {
     306                 :             :   /* TODO: this may need adjusting if segments (e.g. with functions) can't be
     307                 :             :    * literalised */
     308                 :           0 :   std::string str = path_type.as_string ();
     309                 :             : 
     310                 :           0 :   str += "::" + associated_segment->as_string ();
     311                 :           0 :   for (const auto &segment : segments)
     312                 :           0 :     str += "::" + segment->as_string ();
     313                 :             : 
     314                 :           0 :   return str;
     315                 :             : }
     316                 :             : 
     317                 :             : void
     318                 :         158 : ConstGenericParam::accept_vis (ASTVisitor &vis)
     319                 :             : {
     320                 :         158 :   vis.visit (*this);
     321                 :         158 : }
     322                 :             : 
     323                 :             : void
     324                 :      193328 : TypePathSegment::accept_vis (ASTVisitor &vis)
     325                 :             : {
     326                 :      193328 :   vis.visit (*this);
     327                 :      193328 : }
     328                 :             : 
     329                 :             : void
     330                 :        8841 : TypePathSegmentGeneric::accept_vis (ASTVisitor &vis)
     331                 :             : {
     332                 :        8841 :   vis.visit (*this);
     333                 :        8841 : }
     334                 :             : 
     335                 :             : void
     336                 :          79 : TypePathSegmentFunction::accept_vis (ASTVisitor &vis)
     337                 :             : {
     338                 :          79 :   vis.visit (*this);
     339                 :          79 : }
     340                 :             : 
     341                 :             : void
     342                 :      257108 : TypePath::accept_vis (ASTVisitor &vis)
     343                 :             : {
     344                 :      257108 :   vis.visit (*this);
     345                 :      257108 : }
     346                 :             : 
     347                 :             : void
     348                 :         670 : QualifiedPathInExpression::accept_vis (ASTVisitor &vis)
     349                 :             : {
     350                 :         670 :   vis.visit (*this);
     351                 :         670 : }
     352                 :             : 
     353                 :             : void
     354                 :        1698 : QualifiedPathInType::accept_vis (ASTVisitor &vis)
     355                 :             : {
     356                 :        1698 :   vis.visit (*this);
     357                 :        1698 : }
     358                 :             : 
     359                 :             : } // namespace AST
     360                 :             : } // namespace Rust
        

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.