LCOV - code coverage report
Current view: top level - gcc/rust/ast - rust-macro.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 73.1 % 327 239
Test Date: 2025-08-30 13:27:53 Functions: 64.2 % 81 52
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // Copyright (C) 2020-2025 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                 :             : #ifndef RUST_AST_MACRO_H
      20                 :             : #define RUST_AST_MACRO_H
      21                 :             : 
      22                 :             : #include "rust-system.h"
      23                 :             : #include "rust-ast.h"
      24                 :             : #include "rust-ast-fragment.h"
      25                 :             : #include "rust-location.h"
      26                 :             : #include "rust-item.h"
      27                 :             : #include "rust-macro-builtins.h"
      28                 :             : 
      29                 :             : namespace Rust {
      30                 :             : 
      31                 :             : // forward declarations for AttributeParser
      32                 :             : class MacroInvocLexer;
      33                 :             : template <typename ManagedTokenSource> class Parser;
      34                 :             : 
      35                 :             : namespace AST {
      36                 :             : 
      37                 :             : class MacroFragSpec
      38                 :             : {
      39                 :             : public:
      40                 :             :   enum Kind
      41                 :             :   {
      42                 :             :     BLOCK,
      43                 :             :     EXPR,
      44                 :             :     IDENT,
      45                 :             :     ITEM,
      46                 :             :     LIFETIME,
      47                 :             :     LITERAL,
      48                 :             :     META,
      49                 :             :     PAT,
      50                 :             :     PATH,
      51                 :             :     STMT,
      52                 :             :     TT,
      53                 :             :     TY,
      54                 :             :     VIS,
      55                 :             :     INVALID // not really a specifier, but used to mark invalid one passed in
      56                 :             :   };
      57                 :             : 
      58                 :         934 :   MacroFragSpec (Kind kind) : kind (kind) {}
      59                 :             : 
      60                 :         934 :   static MacroFragSpec get_frag_spec_from_str (const std::string &str)
      61                 :             :   {
      62                 :         934 :     if (str == "block")
      63                 :           4 :       return MacroFragSpec (BLOCK);
      64                 :         930 :     else if (str == "expr")
      65                 :         300 :       return MacroFragSpec (EXPR);
      66                 :         630 :     else if (str == "ident")
      67                 :         103 :       return MacroFragSpec (IDENT);
      68                 :         527 :     else if (str == "item")
      69                 :           3 :       return MacroFragSpec (ITEM);
      70                 :         524 :     else if (str == "lifetime")
      71                 :           2 :       return MacroFragSpec (LIFETIME);
      72                 :         522 :     else if (str == "literal")
      73                 :         111 :       return MacroFragSpec (LITERAL);
      74                 :         411 :     else if (str == "meta")
      75                 :          14 :       return MacroFragSpec (META);
      76                 :         397 :     else if (str == "pat" || str == "pat_param")
      77                 :           7 :       return MacroFragSpec (PAT);
      78                 :         390 :     else if (str == "path")
      79                 :           1 :       return MacroFragSpec (PATH);
      80                 :         389 :     else if (str == "stmt")
      81                 :          52 :       return MacroFragSpec (STMT);
      82                 :         337 :     else if (str == "tt")
      83                 :          34 :       return MacroFragSpec (TT);
      84                 :         303 :     else if (str == "ty")
      85                 :         300 :       return MacroFragSpec (TY);
      86                 :           3 :     else if (str == "vis")
      87                 :           3 :       return MacroFragSpec (VIS);
      88                 :             :     else
      89                 :             :       {
      90                 :             :         // error_at("invalid string '%s' used as fragment specifier",
      91                 :             :         // str->c_str()));
      92                 :           0 :         return MacroFragSpec (INVALID);
      93                 :             :       }
      94                 :             :   }
      95                 :             : 
      96                 :        8302 :   Kind get_kind () const { return kind; }
      97                 :         934 :   bool is_error () const { return kind == Kind::INVALID; }
      98                 :             : 
      99                 :             :   // Converts a frag spec enum item to a string form.
     100                 :          13 :   std::string as_string () const
     101                 :             :   {
     102                 :          13 :     switch (kind)
     103                 :             :       {
     104                 :           0 :       case BLOCK:
     105                 :           0 :         return "block";
     106                 :          10 :       case EXPR:
     107                 :          10 :         return "expr";
     108                 :           1 :       case IDENT:
     109                 :           1 :         return "ident";
     110                 :           0 :       case ITEM:
     111                 :           0 :         return "item";
     112                 :           0 :       case LIFETIME:
     113                 :           0 :         return "lifetime";
     114                 :           0 :       case LITERAL:
     115                 :           0 :         return "literal";
     116                 :           0 :       case META:
     117                 :           0 :         return "meta";
     118                 :           0 :       case PAT:
     119                 :           0 :         return "pat";
     120                 :           0 :       case PATH:
     121                 :           0 :         return "path";
     122                 :           0 :       case STMT:
     123                 :           0 :         return "stmt";
     124                 :           0 :       case TT:
     125                 :           0 :         return "tt";
     126                 :           1 :       case TY:
     127                 :           1 :         return "ty";
     128                 :           1 :       case VIS:
     129                 :           1 :         return "vis";
     130                 :           0 :       case INVALID:
     131                 :           0 :         return "INVALID_FRAG_SPEC";
     132                 :           0 :       default:
     133                 :           0 :         return "ERROR_MARK_STRING - unknown frag spec";
     134                 :             :       }
     135                 :             :   }
     136                 :             : 
     137                 :         226 :   bool has_follow_set_restrictions () const
     138                 :             :   {
     139                 :         226 :     switch (kind)
     140                 :             :       {
     141                 :             :       case EXPR:
     142                 :             :       case STMT:
     143                 :             :       case PAT:
     144                 :             :       case PATH:
     145                 :             :       case TY:
     146                 :             :       case VIS:
     147                 :             :         return true;
     148                 :             :       default:
     149                 :             :         return false;
     150                 :             :       }
     151                 :             :   }
     152                 :             : 
     153                 :           6 :   bool has_follow_set_fragment_restrictions () const
     154                 :             :   {
     155                 :           6 :     switch (kind)
     156                 :             :       {
     157                 :             :       case PATH:
     158                 :             :       case PAT:
     159                 :             :       case TY:
     160                 :             :       case VIS:
     161                 :             :         return true;
     162                 :           2 :       default:
     163                 :           2 :         return false;
     164                 :             :       }
     165                 :             :   }
     166                 :             : 
     167                 :             : private:
     168                 :             :   Kind kind;
     169                 :             : };
     170                 :             : 
     171                 :             : // A macro match that has an identifier and fragment spec
     172                 :        2006 : class MacroMatchFragment : public MacroMatch
     173                 :             : {
     174                 :             :   Identifier ident;
     175                 :             :   MacroFragSpec frag_spec;
     176                 :             :   location_t locus;
     177                 :             : 
     178                 :             : public:
     179                 :         934 :   MacroMatchFragment (Identifier ident, MacroFragSpec frag_spec,
     180                 :             :                       location_t locus)
     181                 :         934 :     : ident (std::move (ident)), frag_spec (frag_spec), locus (locus)
     182                 :             :   {}
     183                 :             : 
     184                 :             :   // Returns whether macro match fragment is in an error state.
     185                 :             :   bool is_error () const
     186                 :             :   {
     187                 :             :     return frag_spec.get_kind () == MacroFragSpec::INVALID;
     188                 :             :   }
     189                 :             : 
     190                 :             :   // Creates an error state macro match fragment.
     191                 :             :   static MacroMatchFragment create_error (location_t locus)
     192                 :             :   {
     193                 :             :     return MacroMatchFragment (std::string (""),
     194                 :             :                                MacroFragSpec (MacroFragSpec::Kind::INVALID),
     195                 :             :                                locus);
     196                 :             :   }
     197                 :             : 
     198                 :             :   std::string as_string () const override;
     199                 :          12 :   location_t get_match_locus () const override { return locus; };
     200                 :             : 
     201                 :             :   void accept_vis (ASTVisitor &vis) override;
     202                 :             : 
     203                 :       10308 :   MacroMatchType get_macro_match_type () const override
     204                 :             :   {
     205                 :       10308 :     return MacroMatchType::Fragment;
     206                 :             :   }
     207                 :             : 
     208                 :        9918 :   Identifier get_ident () const { return ident; }
     209                 :          15 :   const MacroFragSpec &get_frag_spec () const { return frag_spec; }
     210                 :             : 
     211                 :             : protected:
     212                 :             :   /* Use covariance to implement clone function as returning this object rather
     213                 :             :    * than base */
     214                 :        1003 :   MacroMatchFragment *clone_macro_match_impl () const override
     215                 :             :   {
     216                 :        1003 :     return new MacroMatchFragment (*this);
     217                 :             :   }
     218                 :             : };
     219                 :             : 
     220                 :             : // A repetition macro match
     221                 :             : class MacroMatchRepetition : public MacroMatch
     222                 :             : {
     223                 :             : public:
     224                 :             :   enum MacroRepOp
     225                 :             :   {
     226                 :             :     NONE,
     227                 :             :     ANY,
     228                 :             :     ONE_OR_MORE,
     229                 :             :     ZERO_OR_ONE,
     230                 :             :   };
     231                 :             : 
     232                 :             : private:
     233                 :             :   std::vector<std::unique_ptr<MacroMatch>> matches;
     234                 :             :   MacroRepOp op;
     235                 :             : 
     236                 :             :   // bool has_sep;
     237                 :             :   typedef Token MacroRepSep;
     238                 :             :   // any token except delimiters and repetition operators
     239                 :             :   std::unique_ptr<MacroRepSep> sep;
     240                 :             :   location_t locus;
     241                 :             : 
     242                 :             : public:
     243                 :             :   // Returns whether macro match repetition has separator token.
     244                 :        4235 :   bool has_sep () const { return sep != nullptr; }
     245                 :             : 
     246                 :         506 :   MacroMatchRepetition (std::vector<std::unique_ptr<MacroMatch>> matches,
     247                 :             :                         MacroRepOp op, std::unique_ptr<MacroRepSep> sep,
     248                 :             :                         location_t locus)
     249                 :         506 :     : matches (std::move (matches)), op (op), sep (std::move (sep)),
     250                 :         506 :       locus (locus)
     251                 :             :   {}
     252                 :             : 
     253                 :             :   // Copy constructor with clone
     254                 :         511 :   MacroMatchRepetition (MacroMatchRepetition const &other)
     255                 :         511 :     : op (other.op), locus (other.locus)
     256                 :             :   {
     257                 :             :     // guard to protect from null pointer dereference
     258                 :         511 :     if (other.sep != nullptr)
     259                 :         139 :       sep = other.sep->clone_token ();
     260                 :             : 
     261                 :         511 :     matches.reserve (other.matches.size ());
     262                 :        1175 :     for (const auto &e : other.matches)
     263                 :         664 :       matches.push_back (e->clone_macro_match ());
     264                 :         511 :   }
     265                 :             : 
     266                 :             :   // Overloaded assignment operator to clone
     267                 :             :   MacroMatchRepetition &operator= (MacroMatchRepetition const &other)
     268                 :             :   {
     269                 :             :     op = other.op;
     270                 :             :     locus = other.locus;
     271                 :             : 
     272                 :             :     // guard to protect from null pointer dereference
     273                 :             :     if (other.sep != nullptr)
     274                 :             :       sep = other.sep->clone_token ();
     275                 :             :     else
     276                 :             :       sep = nullptr;
     277                 :             : 
     278                 :             :     matches.reserve (other.matches.size ());
     279                 :             :     for (const auto &e : other.matches)
     280                 :             :       matches.push_back (e->clone_macro_match ());
     281                 :             : 
     282                 :             :     return *this;
     283                 :             :   }
     284                 :             : 
     285                 :             :   // move constructors
     286                 :             :   MacroMatchRepetition (MacroMatchRepetition &&other) = default;
     287                 :             :   MacroMatchRepetition &operator= (MacroMatchRepetition &&other) = default;
     288                 :             : 
     289                 :             :   std::string as_string () const override;
     290                 :        1726 :   location_t get_match_locus () const override { return locus; };
     291                 :             : 
     292                 :             :   void accept_vis (ASTVisitor &vis) override;
     293                 :             : 
     294                 :        1780 :   MacroMatchType get_macro_match_type () const override
     295                 :             :   {
     296                 :        1780 :     return MacroMatchType::Repetition;
     297                 :             :   }
     298                 :             : 
     299                 :        1731 :   MacroRepOp get_op () const { return op; }
     300                 :         357 :   const std::unique_ptr<MacroRepSep> &get_sep () const { return sep; }
     301                 :        8603 :   std::vector<std::unique_ptr<MacroMatch>> &get_matches () { return matches; }
     302                 :             :   const std::vector<std::unique_ptr<MacroMatch>> &get_matches () const
     303                 :             :   {
     304                 :          37 :     return matches;
     305                 :             :   }
     306                 :             : 
     307                 :             : protected:
     308                 :             :   /* Use covariance to implement clone function as returning this object rather
     309                 :             :    * than base */
     310                 :         511 :   MacroMatchRepetition *clone_macro_match_impl () const override
     311                 :             :   {
     312                 :         511 :     return new MacroMatchRepetition (*this);
     313                 :             :   }
     314                 :             : };
     315                 :             : 
     316                 :             : // can't inline due to polymorphism
     317                 :        2258 : class MacroMatcher : public MacroMatch
     318                 :             : {
     319                 :             :   DelimType delim_type;
     320                 :             :   std::vector<std::unique_ptr<MacroMatch>> matches;
     321                 :             :   location_t locus;
     322                 :             : 
     323                 :             :   // TODO: think of way to mark invalid that doesn't take up more space
     324                 :             :   bool is_invalid;
     325                 :             : 
     326                 :             : public:
     327                 :        1149 :   MacroMatcher (DelimType delim_type,
     328                 :             :                 std::vector<std::unique_ptr<MacroMatch>> matches,
     329                 :             :                 location_t locus)
     330                 :        1149 :     : delim_type (delim_type), matches (std::move (matches)), locus (locus),
     331                 :        1149 :       is_invalid (false)
     332                 :             :   {}
     333                 :             : 
     334                 :             :   // copy constructor with vector clone
     335                 :        1224 :   MacroMatcher (MacroMatcher const &other)
     336                 :        1224 :     : delim_type (other.delim_type), locus (other.locus)
     337                 :             :   {
     338                 :        1224 :     matches.reserve (other.matches.size ());
     339                 :        2661 :     for (const auto &e : other.matches)
     340                 :        1437 :       matches.push_back (e->clone_macro_match ());
     341                 :        1224 :   }
     342                 :             : 
     343                 :             :   // overloaded assignment operator with vector clone
     344                 :             :   MacroMatcher &operator= (MacroMatcher const &other)
     345                 :             :   {
     346                 :             :     delim_type = other.delim_type;
     347                 :             :     locus = other.locus;
     348                 :             : 
     349                 :             :     matches.reserve (other.matches.size ());
     350                 :             :     for (const auto &e : other.matches)
     351                 :             :       matches.push_back (e->clone_macro_match ());
     352                 :             : 
     353                 :             :     return *this;
     354                 :             :   }
     355                 :             : 
     356                 :             :   // move constructors
     357                 :        1148 :   MacroMatcher (MacroMatcher &&other) = default;
     358                 :             :   MacroMatcher &operator= (MacroMatcher &&other) = default;
     359                 :             : 
     360                 :             :   // Creates an error state macro matcher.
     361                 :          27 :   static MacroMatcher create_error (location_t locus)
     362                 :             :   {
     363                 :          27 :     return MacroMatcher (true, locus);
     364                 :             :   }
     365                 :             : 
     366                 :             :   // Returns whether MacroMatcher is in an error state.
     367                 :        1163 :   bool is_error () const { return is_invalid; }
     368                 :           3 :   location_t get_match_locus () const override { return locus; }
     369                 :             : 
     370                 :             :   std::string as_string () const override;
     371                 :             : 
     372                 :             :   void accept_vis (ASTVisitor &vis) override;
     373                 :             : 
     374                 :         145 :   MacroMatchType get_macro_match_type () const override
     375                 :             :   {
     376                 :         145 :     return MacroMatchType::Matcher;
     377                 :             :   }
     378                 :             : 
     379                 :         114 :   DelimType get_delim_type () const { return delim_type; }
     380                 :       14936 :   std::vector<std::unique_ptr<MacroMatch>> &get_matches () { return matches; }
     381                 :             :   const std::vector<std::unique_ptr<MacroMatch>> &get_matches () const
     382                 :             :   {
     383                 :             :     return matches;
     384                 :             :   }
     385                 :             : 
     386                 :             : protected:
     387                 :             :   /* Use covariance to implement clone function as returning this object rather
     388                 :             :    * than base */
     389                 :          65 :   MacroMatcher *clone_macro_match_impl () const override
     390                 :             :   {
     391                 :          65 :     return new MacroMatcher (*this);
     392                 :             :   }
     393                 :             : 
     394                 :             :   // constructor only used to create error matcher
     395                 :          27 :   MacroMatcher (bool is_invalid, location_t locus)
     396                 :          14 :     : delim_type (PARENS), locus (locus), is_invalid (is_invalid)
     397                 :             :   {}
     398                 :             : };
     399                 :             : 
     400                 :             : // TODO: inline?
     401                 :        2184 : struct MacroTranscriber
     402                 :             : {
     403                 :             : private:
     404                 :             :   DelimTokenTree token_tree;
     405                 :             :   location_t locus;
     406                 :             : 
     407                 :             : public:
     408                 :        1096 :   MacroTranscriber (DelimTokenTree token_tree, location_t locus)
     409                 :        1083 :     : token_tree (std::move (token_tree)), locus (locus)
     410                 :             :   {}
     411                 :             : 
     412                 :           0 :   std::string as_string () const { return token_tree.as_string (); }
     413                 :             : 
     414                 :             :   location_t get_locus () const { return locus; }
     415                 :             : 
     416                 :       12928 :   DelimTokenTree &get_token_tree () { return token_tree; }
     417                 :             :   const DelimTokenTree &get_token_tree () const { return token_tree; }
     418                 :             : };
     419                 :             : 
     420                 :             : // A macro rule? Matcher and transcriber pair?
     421                 :             : struct MacroRule
     422                 :             : {
     423                 :             : private:
     424                 :             :   MacroMatcher matcher;
     425                 :             :   MacroTranscriber transcriber;
     426                 :             :   location_t locus;
     427                 :             : 
     428                 :             : public:
     429                 :        1095 :   MacroRule (MacroMatcher matcher, MacroTranscriber transcriber,
     430                 :             :              location_t locus)
     431                 :        1095 :     : matcher (std::move (matcher)), transcriber (std::move (transcriber)),
     432                 :        1095 :       locus (locus)
     433                 :        1095 :   {}
     434                 :             : 
     435                 :             :   // Returns whether macro rule is in error state.
     436                 :        1076 :   bool is_error () const { return matcher.is_error (); }
     437                 :             : 
     438                 :             :   // Creates an error state macro rule.
     439                 :          13 :   static MacroRule create_error (location_t locus)
     440                 :             :   {
     441                 :          13 :     return MacroRule (MacroMatcher::create_error (locus),
     442                 :          26 :                       MacroTranscriber (DelimTokenTree::create_empty (),
     443                 :          13 :                                         UNDEF_LOCATION),
     444                 :          13 :                       locus);
     445                 :             :   }
     446                 :             : 
     447                 :           2 :   location_t get_locus () const { return locus; }
     448                 :             : 
     449                 :             :   std::string as_string () const;
     450                 :             : 
     451                 :       14321 :   MacroMatcher &get_matcher () { return matcher; }
     452                 :       12926 :   MacroTranscriber &get_transcriber () { return transcriber; }
     453                 :             : };
     454                 :             : 
     455                 :             : // A macro rules definition item AST node
     456                 :             : class MacroRulesDefinition : public VisItem
     457                 :             : {
     458                 :             : public:
     459                 :             :   enum MacroKind
     460                 :             :   {
     461                 :             :     // Macro by Example (legacy macro rules)
     462                 :             :     MBE,
     463                 :             :     // Declarative macros 2.0
     464                 :             :     DeclMacro,
     465                 :             :   };
     466                 :             : 
     467                 :             : private:
     468                 :             :   std::vector<Attribute> outer_attrs;
     469                 :             :   Identifier rule_name;
     470                 :             :   // MacroRulesDef rules_def;
     471                 :             :   // only curly without required semicolon at end
     472                 :             :   DelimType delim_type;
     473                 :             :   // MacroRules rules;
     474                 :             :   std::vector<MacroRule> rules; // inlined form
     475                 :             :   location_t locus;
     476                 :             : 
     477                 :             :   MacroTranscriberFunc associated_transcriber;
     478                 :             : 
     479                 :             :   // Since we can't compare std::functions, we need to use an extra boolean
     480                 :             :   bool is_builtin_rule;
     481                 :             :   MacroKind kind;
     482                 :             : 
     483                 :             :   /**
     484                 :             :    * Default function to use as an associated transcriber. This function should
     485                 :             :    * never be called, hence the rust_unreachable().
     486                 :             :    * If this function is used, then the macro is not builtin and the compiler
     487                 :             :    * should make use of the actual rules. If the macro is builtin, then another
     488                 :             :    * associated transcriber should be used
     489                 :             :    */
     490                 :           0 :   static Fragment dummy_builtin (location_t, MacroInvocData &, AST::InvocKind)
     491                 :             :   {
     492                 :           0 :     rust_unreachable ();
     493                 :             :     return Fragment::create_error ();
     494                 :             :   }
     495                 :             : 
     496                 :             :   /* NOTE: in rustc, macro definitions are considered (and parsed as) a type
     497                 :             :    * of macro, whereas here they are considered part of the language itself.
     498                 :             :    * I am not aware of the implications of this decision. The rustc spec does
     499                 :             :    * mention that using the same parser for macro definitions and invocations
     500                 :             :    * is "extremely self-referential and non-intuitive". */
     501                 :         943 :   MacroRulesDefinition (Identifier rule_name, DelimType delim_type,
     502                 :             :                         std::vector<MacroRule> rules,
     503                 :             :                         std::vector<Attribute> outer_attrs, location_t locus,
     504                 :             :                         MacroKind kind, Visibility vis)
     505                 :         943 :     : VisItem (std::move (vis), outer_attrs),
     506                 :        1886 :       outer_attrs (std::move (outer_attrs)), rule_name (std::move (rule_name)),
     507                 :         943 :       delim_type (delim_type), rules (std::move (rules)), locus (locus),
     508                 :         943 :       associated_transcriber (dummy_builtin), is_builtin_rule (false),
     509                 :         943 :       kind (kind)
     510                 :         943 :   {}
     511                 :             : 
     512                 :             :   MacroRulesDefinition (Identifier builtin_name, DelimType delim_type,
     513                 :             :                         MacroTranscriberFunc associated_transcriber,
     514                 :             :                         MacroKind kind, Visibility vis)
     515                 :             :     : VisItem (std::move (vis), std::vector<Attribute> ()),
     516                 :             :       outer_attrs (std::vector<Attribute> ()), rule_name (builtin_name),
     517                 :             :       delim_type (delim_type), rules (std::vector<MacroRule> ()),
     518                 :             :       locus (UNDEF_LOCATION), associated_transcriber (associated_transcriber),
     519                 :             :       is_builtin_rule (true), kind (kind)
     520                 :             :   {}
     521                 :             : 
     522                 :             : public:
     523                 :             :   std::string as_string () const override;
     524                 :             : 
     525                 :             :   static std::unique_ptr<MacroRulesDefinition>
     526                 :         900 :   mbe (Identifier rule_name, DelimType delim_type, std::vector<MacroRule> rules,
     527                 :             :        std::vector<Attribute> outer_attrs, location_t locus)
     528                 :             :   {
     529                 :         900 :     return std::make_unique<MacroRulesDefinition> (
     530                 :         900 :       MacroRulesDefinition (rule_name, delim_type, rules, outer_attrs, locus,
     531                 :             :                             AST::MacroRulesDefinition::MacroKind::MBE,
     532                 :        1800 :                             AST::Visibility::create_error ()));
     533                 :             :   }
     534                 :             : 
     535                 :             :   static std::unique_ptr<MacroRulesDefinition>
     536                 :          43 :   decl_macro (Identifier rule_name, std::vector<MacroRule> rules,
     537                 :             :               std::vector<Attribute> outer_attrs, location_t locus,
     538                 :             :               Visibility vis)
     539                 :             :   {
     540                 :          43 :     return std::make_unique<MacroRulesDefinition> (MacroRulesDefinition (
     541                 :             :       rule_name, AST::DelimType::CURLY, rules, outer_attrs, locus,
     542                 :          86 :       AST::MacroRulesDefinition::MacroKind::DeclMacro, vis));
     543                 :             :   }
     544                 :             : 
     545                 :             :   void accept_vis (ASTVisitor &vis) override;
     546                 :             : 
     547                 :             :   // Invalid if rule name is empty, so base stripping on that.
     548                 :           0 :   void mark_for_strip () override { rule_name = {""}; }
     549                 :        6126 :   bool is_marked_for_strip () const override { return rule_name.empty (); }
     550                 :             : 
     551                 :             :   // TODO: this mutable getter seems really dodgy. Think up better way.
     552                 :       23665 :   std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
     553                 :        3723 :   const std::vector<Attribute> &get_outer_attrs () const override
     554                 :             :   {
     555                 :        3723 :     return outer_attrs;
     556                 :             :   }
     557                 :             : 
     558                 :        8326 :   std::vector<MacroRule> &get_macro_rules () { return rules; }
     559                 :             :   const std::vector<MacroRule> &get_macro_rules () const { return rules; }
     560                 :             : 
     561                 :         654 :   location_t get_locus () const override final { return locus; }
     562                 :             : 
     563                 :        4177 :   Identifier get_rule_name () const { return rule_name; }
     564                 :             : 
     565                 :        2400 :   std::vector<MacroRule> &get_rules () { return rules; }
     566                 :             :   const std::vector<MacroRule> &get_rules () const { return rules; }
     567                 :             : 
     568                 :        2751 :   bool is_builtin () const { return is_builtin_rule; }
     569                 :         353 :   const MacroTranscriberFunc &get_builtin_transcriber () const
     570                 :             :   {
     571                 :         353 :     rust_assert (is_builtin ());
     572                 :         353 :     return associated_transcriber;
     573                 :             :   }
     574                 :         143 :   void set_builtin_transcriber (MacroTranscriberFunc transcriber)
     575                 :             :   {
     576                 :         143 :     associated_transcriber = transcriber;
     577                 :         143 :     is_builtin_rule = true;
     578                 :             :   }
     579                 :             : 
     580                 :        4619 :   MacroKind get_kind () const { return kind; }
     581                 :             : 
     582                 :           0 :   Item::Kind get_item_kind () const override
     583                 :             :   {
     584                 :           0 :     return Item::Kind::MacroRulesDefinition;
     585                 :             :   }
     586                 :             : 
     587                 :             : protected:
     588                 :             :   /* Use covariance to implement clone function as returning this object rather
     589                 :             :    * than base */
     590                 :          32 :   MacroRulesDefinition *clone_item_impl () const override
     591                 :             :   {
     592                 :          32 :     return new MacroRulesDefinition (*this);
     593                 :             :   }
     594                 :             : };
     595                 :             : 
     596                 :             : /* AST node of a macro invocation, which is replaced by the macro result at
     597                 :             :  * compile time. This is technically a sum-type/tagged-union, which represents
     598                 :             :  * both classic macro invocations and builtin macro invocations. Regular macro
     599                 :             :  * invocations are expanded lazily, but builtin macro invocations need to be
     600                 :             :  * expanded eagerly, hence the differentiation.
     601                 :             :  */
     602                 :             : class MacroInvocation : public TypeNoBounds,
     603                 :             :                         public Pattern,
     604                 :             :                         public Item,
     605                 :             :                         public TraitItem,
     606                 :             :                         public ExternalItem,
     607                 :             :                         public ExprWithoutBlock
     608                 :             : {
     609                 :             : public:
     610                 :             :   enum class InvocKind
     611                 :             :   {
     612                 :             :     Regular,
     613                 :             :     Builtin,
     614                 :             :   };
     615                 :             : 
     616                 :             :   std::string as_string () const override;
     617                 :             : 
     618                 :             :   /**
     619                 :             :    * The default constructor you should use. Whenever we parse a macro call, we
     620                 :             :    * cannot possibly know whether or not this call refers to a builtin macro or
     621                 :             :    * a regular macro. With name resolution and scopes and nested macro calls,
     622                 :             :    * this is literally impossible. Hence, always start by creating a `Regular`
     623                 :             :    * MacroInvocation which will then (maybe!) become a `Builtin` macro
     624                 :             :    * invocation in the expander.
     625                 :             :    */
     626                 :             :   static std::unique_ptr<MacroInvocation>
     627                 :        2901 :   Regular (MacroInvocData invoc_data, std::vector<Attribute> outer_attrs,
     628                 :             :            location_t locus, bool is_semi_coloned = false)
     629                 :             :   {
     630                 :        2901 :     return std::unique_ptr<MacroInvocation> (
     631                 :             :       new MacroInvocation (InvocKind::Regular, tl::nullopt, invoc_data,
     632                 :        2901 :                            outer_attrs, locus, is_semi_coloned, {}));
     633                 :             :   }
     634                 :             : 
     635                 :             :   /**
     636                 :             :    * Create a builtin macro invocation. This can only be done after macro
     637                 :             :    * name-resolution and within the macro expander, so unless you're modifying
     638                 :             :    * these visitors, you probably do not want to use this function.
     639                 :             :    */
     640                 :          50 :   static std::unique_ptr<MacroInvocation> Builtin (
     641                 :             :     BuiltinMacro kind, MacroInvocData invoc_data,
     642                 :             :     std::vector<Attribute> outer_attrs, location_t locus,
     643                 :             :     std::vector<std::unique_ptr<MacroInvocation>> &&pending_eager_invocations
     644                 :             :     = {},
     645                 :             :     bool is_semi_coloned = false)
     646                 :             :   {
     647                 :          50 :     return std::unique_ptr<MacroInvocation> (
     648                 :          50 :       new MacroInvocation (InvocKind::Builtin, kind, invoc_data, outer_attrs,
     649                 :             :                            locus, is_semi_coloned,
     650                 :          50 :                            std::move (pending_eager_invocations)));
     651                 :             :   }
     652                 :             : 
     653                 :        3391 :   location_t get_locus () const override final { return locus; }
     654                 :             : 
     655                 :             :   void accept_vis (ASTVisitor &vis) override;
     656                 :             : 
     657                 :             :   // Invalid if path is empty, so base stripping on that.
     658                 :           0 :   void mark_for_strip () override { invoc_data.mark_for_strip (); }
     659                 :        3722 :   bool is_marked_for_strip () const override
     660                 :             :   {
     661                 :        3722 :     return invoc_data.is_marked_for_strip ();
     662                 :             :   }
     663                 :             : 
     664                 :         806 :   const std::vector<Attribute> &get_outer_attrs () const override
     665                 :             :   {
     666                 :         806 :     return outer_attrs;
     667                 :             :   }
     668                 :       13575 :   std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
     669                 :             : 
     670                 :           0 :   void set_outer_attrs (std::vector<Attribute> new_attrs) override
     671                 :             :   {
     672                 :           0 :     outer_attrs = std::move (new_attrs);
     673                 :           0 :   }
     674                 :             : 
     675                 :           0 :   NodeId get_node_id () const override final
     676                 :             :   {
     677                 :           0 :     return ExprWithoutBlock::get_node_id ();
     678                 :             :   }
     679                 :             : 
     680                 :       11041 :   NodeId get_macro_node_id () const { return node_id; }
     681                 :             : 
     682                 :        6962 :   MacroInvocData &get_invoc_data () { return invoc_data; }
     683                 :             : 
     684                 :        2743 :   bool has_semicolon () const { return is_semi_coloned; }
     685                 :             : 
     686                 :        5579 :   InvocKind get_kind () const { return kind; }
     687                 :             :   tl::optional<BuiltinMacro> get_builtin_kind () const { return builtin_kind; }
     688                 :             : 
     689                 :             :   /**
     690                 :             :    * Turn the current MacroInvocation into a builtin macro invocation
     691                 :             :    */
     692                 :           0 :   void map_to_builtin (BuiltinMacro macro)
     693                 :             :   {
     694                 :           0 :     kind = InvocKind::Builtin;
     695                 :           0 :     builtin_kind = macro;
     696                 :             :   }
     697                 :             : 
     698                 :             :   /**
     699                 :             :    * Get the list of pending macro invcations within the builtin macro
     700                 :             :    * invocation that should get expanded eagerly.
     701                 :             :    */
     702                 :             :   std::vector<std::unique_ptr<MacroInvocation>> &
     703                 :         171 :   get_pending_eager_invocations ()
     704                 :             :   {
     705                 :         171 :     rust_assert (kind == InvocKind::Builtin);
     706                 :             : 
     707                 :         171 :     return pending_eager_invocs;
     708                 :             :   }
     709                 :             : 
     710                 :             : private:
     711                 :             :   /* Full constructor */
     712                 :        2951 :   MacroInvocation (
     713                 :             :     InvocKind kind, tl::optional<BuiltinMacro> builtin_kind,
     714                 :             :     MacroInvocData invoc_data, std::vector<Attribute> outer_attrs,
     715                 :             :     location_t locus, bool is_semi_coloned,
     716                 :             :     std::vector<std::unique_ptr<MacroInvocation>> &&pending_eager_invocs)
     717                 :        5902 :     : TraitItem (locus), outer_attrs (std::move (outer_attrs)), locus (locus),
     718                 :        2951 :       node_id (Analysis::Mappings::get ().get_next_node_id ()),
     719                 :        2951 :       invoc_data (std::move (invoc_data)), is_semi_coloned (is_semi_coloned),
     720                 :        2951 :       kind (kind), builtin_kind (builtin_kind),
     721                 :        2951 :       pending_eager_invocs (std::move (pending_eager_invocs))
     722                 :        2951 :   {}
     723                 :             : 
     724                 :       10535 :   MacroInvocation (const MacroInvocation &other)
     725                 :       31605 :     : TraitItem (other.locus), ExternalItem (other.node_id),
     726                 :       21070 :       outer_attrs (other.outer_attrs), locus (other.locus),
     727                 :       10535 :       node_id (other.node_id), invoc_data (other.invoc_data),
     728                 :       10535 :       is_semi_coloned (other.is_semi_coloned), kind (other.kind),
     729                 :       21070 :       builtin_kind (other.builtin_kind)
     730                 :             :   {
     731                 :       10535 :     if (other.kind == InvocKind::Builtin)
     732                 :         666 :       for (auto &pending : other.pending_eager_invocs)
     733                 :         324 :         pending_eager_invocs.emplace_back (
     734                 :         324 :           pending->clone_macro_invocation_impl ());
     735                 :       10535 :   }
     736                 :             : 
     737                 :             :   std::vector<Attribute> outer_attrs;
     738                 :             :   location_t locus;
     739                 :             :   NodeId node_id;
     740                 :             : 
     741                 :             :   /* The data given to the macro invocation */
     742                 :             :   MacroInvocData invoc_data;
     743                 :             : 
     744                 :             :   /* Important for when we actually expand the macro */
     745                 :             :   bool is_semi_coloned;
     746                 :             : 
     747                 :             :   /* Is this a builtin macro or a regular macro */
     748                 :             :   InvocKind kind;
     749                 :             : 
     750                 :             :   /* If it is a builtin macro, which one */
     751                 :             :   tl::optional<BuiltinMacro> builtin_kind = tl::nullopt;
     752                 :             : 
     753                 :             :   /**
     754                 :             :    * Pending invocations within a builtin macro invocation. This vector is empty
     755                 :             :    * and should not be accessed for a regular macro invocation. The macro
     756                 :             :    * invocations within should be name resolved and expanded before the builtin
     757                 :             :    * macro invocation get expanded again. It is then the role of the expander to
     758                 :             :    * insert these new tokens properly in the delimited token tree and try the
     759                 :             :    * builtin transcriber once again.
     760                 :             :    */
     761                 :             :   std::vector<std::unique_ptr<MacroInvocation>> pending_eager_invocs;
     762                 :             : 
     763                 :             : protected:
     764                 :           0 :   MacroInvocation *clone_pattern_impl () const final override
     765                 :             :   {
     766                 :           0 :     return clone_macro_invocation_impl ();
     767                 :             :   }
     768                 :             : 
     769                 :           0 :   MacroInvocation *clone_expr_without_block_impl () const final override
     770                 :             :   {
     771                 :           0 :     return clone_macro_invocation_impl ();
     772                 :             :   }
     773                 :             : 
     774                 :           0 :   MacroInvocation *clone_type_no_bounds_impl () const final override
     775                 :             :   {
     776                 :           0 :     return clone_macro_invocation_impl ();
     777                 :             :   }
     778                 :             : 
     779                 :           0 :   MacroInvocation *clone_external_item_impl () const final override
     780                 :             :   {
     781                 :           0 :     return clone_macro_invocation_impl ();
     782                 :             :   }
     783                 :             : 
     784                 :             : public:
     785                 :       10535 :   /*virtual*/ MacroInvocation *clone_macro_invocation_impl () const
     786                 :             :   {
     787                 :       10535 :     return new MacroInvocation (*this);
     788                 :             :   }
     789                 :             : 
     790                 :             :   std::unique_ptr<MacroInvocation> reconstruct_macro_invocation () const
     791                 :             :   {
     792                 :             :     return nullptr;
     793                 :             :     //  return reconstruct (this,
     794                 :             :     // &MacroInvocation::reconstruct_macro_invocation_impl);
     795                 :             :   }
     796                 :             : 
     797                 :           0 :   MacroInvocation *reconstruct_impl () const override
     798                 :             :   {
     799                 :           0 :     return new MacroInvocation (kind, builtin_kind, invoc_data, outer_attrs,
     800                 :           0 :                                 locus, is_semi_coloned,
     801                 :           0 :                                 reconstruct_vec (pending_eager_invocs));
     802                 :             :   }
     803                 :             : 
     804                 :         512 :   void add_semicolon () override { is_semi_coloned = true; }
     805                 :             : 
     806                 :           0 :   Pattern::Kind get_pattern_kind () override
     807                 :             :   {
     808                 :           0 :     return Pattern::Kind::MacroInvocation;
     809                 :             :   }
     810                 :             : 
     811                 :          17 :   Expr::Kind get_expr_kind () const override
     812                 :             :   {
     813                 :          17 :     return Expr::Kind::MacroInvocation;
     814                 :             :   }
     815                 :             : 
     816                 :           0 :   Item::Kind get_item_kind () const override
     817                 :             :   {
     818                 :           0 :     return Item::Kind::MacroInvocation;
     819                 :             :   }
     820                 :             : 
     821                 :             : protected:
     822                 :         482 :   Item *clone_item_impl () const override
     823                 :             :   {
     824                 :         482 :     return clone_macro_invocation_impl ();
     825                 :             :   }
     826                 :             : 
     827                 :           0 :   bool is_item () const override { return !has_semicolon (); }
     828                 :             : 
     829                 :           0 :   MacroInvocation *clone_associated_item_impl () const override
     830                 :             :   {
     831                 :           0 :     return clone_macro_invocation_impl ();
     832                 :             :   };
     833                 :             : };
     834                 :             : 
     835                 :             : // more generic meta item path-only form
     836                 :         286 : class MetaItemPath : public MetaItem
     837                 :             : {
     838                 :             :   SimplePath path;
     839                 :             : 
     840                 :             : public:
     841                 :         286 :   MetaItemPath (SimplePath path) : path (std::move (path)) {}
     842                 :             : 
     843                 :           0 :   std::string as_string () const override { return path.as_string (); }
     844                 :             : 
     845                 :             :   void accept_vis (ASTVisitor &vis) override;
     846                 :             : 
     847                 :             :   // HACK: used to simplify parsing - returns non-empty only in this case
     848                 :           0 :   SimplePath to_path_item () const override
     849                 :             :   {
     850                 :             :     // this should copy construct - TODO ensure it does
     851                 :           0 :     return path;
     852                 :             :   }
     853                 :             : 
     854                 :         481 :   SimplePath &get_path () { return path; }
     855                 :             : 
     856                 :           0 :   location_t get_locus () const override { return path.get_locus (); }
     857                 :             : 
     858                 :             :   bool check_cfg_predicate (const Session &session) const override;
     859                 :             : 
     860                 :             :   Attribute to_attribute () const override;
     861                 :             : 
     862                 :         195 :   MetaItem::ItemKind get_item_kind () const override
     863                 :             :   {
     864                 :         195 :     return MetaItem::ItemKind::Path;
     865                 :             :   }
     866                 :             : 
     867                 :             : protected:
     868                 :             :   // Use covariance to implement clone function as returning this type
     869                 :         195 :   MetaItemPath *clone_meta_item_inner_impl () const override
     870                 :             :   {
     871                 :         195 :     return new MetaItemPath (*this);
     872                 :             :   }
     873                 :             : };
     874                 :             : 
     875                 :             : // more generic meta item sequence form
     876                 :             : class MetaItemSeq : public MetaItem
     877                 :             : {
     878                 :             :   SimplePath path;
     879                 :             :   std::vector<std::unique_ptr<MetaItemInner>> seq;
     880                 :             : 
     881                 :             : public:
     882                 :         108 :   MetaItemSeq (SimplePath path, std::vector<std::unique_ptr<MetaItemInner>> seq)
     883                 :         108 :     : path (std::move (path)), seq (std::move (seq))
     884                 :         108 :   {}
     885                 :             : 
     886                 :             :   // copy constructor with vector clone
     887                 :          16 :   MetaItemSeq (const MetaItemSeq &other) : path (other.path)
     888                 :             :   {
     889                 :          16 :     seq.reserve (other.seq.size ());
     890                 :          39 :     for (const auto &e : other.seq)
     891                 :          23 :       seq.push_back (e->clone_meta_item_inner ());
     892                 :          16 :   }
     893                 :             : 
     894                 :             :   // overloaded assignment operator with vector clone
     895                 :             :   MetaItemSeq &operator= (const MetaItemSeq &other)
     896                 :             :   {
     897                 :             :     MetaItem::operator= (other);
     898                 :             :     path = other.path;
     899                 :             : 
     900                 :             :     seq.reserve (other.seq.size ());
     901                 :             :     for (const auto &e : other.seq)
     902                 :             :       seq.push_back (e->clone_meta_item_inner ());
     903                 :             : 
     904                 :             :     return *this;
     905                 :             :   }
     906                 :             : 
     907                 :             :   // default move constructors
     908                 :             :   MetaItemSeq (MetaItemSeq &&other) = default;
     909                 :             :   MetaItemSeq &operator= (MetaItemSeq &&other) = default;
     910                 :             : 
     911                 :             :   std::string as_string () const override;
     912                 :             : 
     913                 :           2 :   SimplePath &get_path () { return path; }
     914                 :             : 
     915                 :           2 :   std::vector<std::unique_ptr<MetaItemInner>> &get_seq () { return seq; }
     916                 :             : 
     917                 :             :   void accept_vis (ASTVisitor &vis) override;
     918                 :             : 
     919                 :           0 :   location_t get_locus () const override { return path.get_locus (); }
     920                 :             : 
     921                 :             :   bool check_cfg_predicate (const Session &session) const override;
     922                 :             : 
     923                 :             :   Attribute to_attribute () const override;
     924                 :             : 
     925                 :           0 :   MetaItem::ItemKind get_item_kind () const override
     926                 :             :   {
     927                 :           0 :     return MetaItem::ItemKind::Seq;
     928                 :             :   }
     929                 :             : 
     930                 :             : protected:
     931                 :             :   // Use covariance to implement clone function as returning this type
     932                 :          16 :   MetaItemSeq *clone_meta_item_inner_impl () const override
     933                 :             :   {
     934                 :          16 :     return new MetaItemSeq (*this);
     935                 :             :   }
     936                 :             : };
     937                 :             : 
     938                 :             : // Preferred specialisation for single-identifier meta items.
     939                 :         234 : class MetaWord : public MetaItem
     940                 :             : {
     941                 :             :   Identifier ident;
     942                 :             :   location_t ident_locus;
     943                 :             : 
     944                 :             : public:
     945                 :        1211 :   MetaWord (Identifier ident, location_t ident_locus)
     946                 :        1211 :     : ident (std::move (ident)), ident_locus (ident_locus)
     947                 :             :   {}
     948                 :             : 
     949                 :         908 :   std::string as_string () const override { return ident.as_string (); }
     950                 :             : 
     951                 :             :   void accept_vis (ASTVisitor &vis) override;
     952                 :             : 
     953                 :         286 :   Identifier &get_ident () { return ident; }
     954                 :             : 
     955                 :           3 :   location_t get_locus () const override { return ident_locus; }
     956                 :             : 
     957                 :             :   bool check_cfg_predicate (const Session &session) const override;
     958                 :             : 
     959                 :             :   Attribute to_attribute () const override;
     960                 :             : 
     961                 :         286 :   MetaItem::ItemKind get_item_kind () const override
     962                 :             :   {
     963                 :         286 :     return MetaItem::ItemKind::Word;
     964                 :             :   }
     965                 :             : 
     966                 :             : protected:
     967                 :             :   // Use covariance to implement clone function as returning this type
     968                 :         117 :   MetaWord *clone_meta_item_inner_impl () const override
     969                 :             :   {
     970                 :         117 :     return new MetaWord (*this);
     971                 :             :   }
     972                 :             : };
     973                 :             : 
     974                 :             : // Preferred specialisation for "identifier '=' string literal" meta items.
     975                 :             : class MetaNameValueStr : public MetaItem
     976                 :             : {
     977                 :             :   Identifier ident;
     978                 :             :   location_t ident_locus;
     979                 :             : 
     980                 :             :   // NOTE: str stored without quotes
     981                 :             :   std::string str;
     982                 :             :   location_t str_locus;
     983                 :             : 
     984                 :             : public:
     985                 :        1093 :   MetaNameValueStr (Identifier ident, location_t ident_locus, std::string str,
     986                 :             :                     location_t str_locus)
     987                 :        2186 :     : ident (std::move (ident)), ident_locus (ident_locus),
     988                 :        1093 :       str (std::move (str)), str_locus (str_locus)
     989                 :        1093 :   {}
     990                 :             : 
     991                 :        1867 :   std::string as_string () const override
     992                 :             :   {
     993                 :        3734 :     return ident.as_string () + " = \"" + str + "\"";
     994                 :             :   }
     995                 :             : 
     996                 :             :   void accept_vis (ASTVisitor &vis) override;
     997                 :             : 
     998                 :             :   // HACK: used to simplify parsing - creates a copy of this
     999                 :           4 :   std::unique_ptr<MetaNameValueStr> to_meta_name_value_str () const override
    1000                 :             :   {
    1001                 :           4 :     return std::unique_ptr<MetaNameValueStr> (clone_meta_item_inner_impl ());
    1002                 :             :   }
    1003                 :             : 
    1004                 :          15 :   location_t get_locus () const override { return ident_locus; }
    1005                 :             : 
    1006                 :             :   bool check_cfg_predicate (const Session &session) const override;
    1007                 :             : 
    1008                 :             :   Attribute to_attribute () const override;
    1009                 :             : 
    1010                 :          30 :   inline std::pair<Identifier, std::string> get_name_value_pair () const
    1011                 :             :   {
    1012                 :          30 :     return std::pair<Identifier, std::string> (ident, str);
    1013                 :             :   }
    1014                 :             : 
    1015                 :          21 :   bool is_key_value_pair () const override { return true; }
    1016                 :             : 
    1017                 :           0 :   MetaItem::ItemKind get_item_kind () const override
    1018                 :             :   {
    1019                 :           0 :     return MetaItem::ItemKind::NameValueStr;
    1020                 :             :   }
    1021                 :             : 
    1022                 :             : protected:
    1023                 :             :   // Use covariance to implement clone function as returning this type
    1024                 :        2124 :   MetaNameValueStr *clone_meta_item_inner_impl () const override
    1025                 :             :   {
    1026                 :        2124 :     return new MetaNameValueStr (*this);
    1027                 :             :   }
    1028                 :             : };
    1029                 :             : 
    1030                 :             : // doubles up as MetaListIdents - determine via iterating through each path?
    1031                 :             : // Preferred specialisation for "identifier '(' SimplePath, SimplePath, ... ')'"
    1032                 :             : class MetaListPaths : public MetaItem
    1033                 :             : {
    1034                 :             :   Identifier ident;
    1035                 :             :   location_t ident_locus;
    1036                 :             :   std::vector<SimplePath> paths;
    1037                 :             : 
    1038                 :             : public:
    1039                 :           0 :   MetaListPaths (Identifier ident, location_t ident_locus,
    1040                 :             :                  std::vector<SimplePath> paths)
    1041                 :           0 :     : ident (std::move (ident)), ident_locus (ident_locus),
    1042                 :           0 :       paths (std::move (paths))
    1043                 :           0 :   {}
    1044                 :             : 
    1045                 :             :   std::string as_string () const override;
    1046                 :             : 
    1047                 :             :   void accept_vis (ASTVisitor &vis) override;
    1048                 :             : 
    1049                 :           0 :   Identifier get_ident () const { return ident; }
    1050                 :             : 
    1051                 :           0 :   std::vector<SimplePath> &get_paths () { return paths; };
    1052                 :             : 
    1053                 :           0 :   location_t get_locus () const override { return ident_locus; }
    1054                 :             : 
    1055                 :             :   bool check_cfg_predicate (const Session &session) const override;
    1056                 :             : 
    1057                 :             :   Attribute to_attribute () const override;
    1058                 :             : 
    1059                 :           0 :   MetaItem::ItemKind get_item_kind () const override
    1060                 :             :   {
    1061                 :           0 :     return MetaItem::ItemKind::ListPaths;
    1062                 :             :   }
    1063                 :             : 
    1064                 :             : private:
    1065                 :             :   bool check_path_exists_in_cfg (const Session &session,
    1066                 :             :                                  const SimplePath &path) const;
    1067                 :             : 
    1068                 :             : protected:
    1069                 :             :   // Use covariance to implement clone function as returning this type
    1070                 :           0 :   MetaListPaths *clone_meta_item_inner_impl () const override
    1071                 :             :   {
    1072                 :           0 :     return new MetaListPaths (*this);
    1073                 :             :   }
    1074                 :             : };
    1075                 :             : 
    1076                 :             : // Preferred specialisation for "identifier '(' MetaNameValueStr, ... ')'"
    1077                 :             : class MetaListNameValueStr : public MetaItem
    1078                 :             : {
    1079                 :             :   Identifier ident;
    1080                 :             :   location_t ident_locus;
    1081                 :             :   std::vector<MetaNameValueStr> strs;
    1082                 :             : 
    1083                 :             : public:
    1084                 :           0 :   MetaListNameValueStr (Identifier ident, location_t ident_locus,
    1085                 :             :                         std::vector<MetaNameValueStr> strs)
    1086                 :           0 :     : ident (std::move (ident)), ident_locus (ident_locus),
    1087                 :           0 :       strs (std::move (strs))
    1088                 :           0 :   {}
    1089                 :             : 
    1090                 :             :   std::string as_string () const override;
    1091                 :             : 
    1092                 :             :   void accept_vis (ASTVisitor &vis) override;
    1093                 :             : 
    1094                 :           0 :   Identifier get_ident () { return ident; }
    1095                 :             : 
    1096                 :           0 :   std::vector<MetaNameValueStr> &get_values () { return strs; }
    1097                 :             : 
    1098                 :           0 :   location_t get_locus () const override { return ident_locus; }
    1099                 :             : 
    1100                 :             :   bool check_cfg_predicate (const Session &session) const override;
    1101                 :             : 
    1102                 :             :   Attribute to_attribute () const override;
    1103                 :             : 
    1104                 :           0 :   MetaItem::ItemKind get_item_kind () const override
    1105                 :             :   {
    1106                 :           0 :     return MetaItem::ItemKind::ListNameValueStr;
    1107                 :             :   }
    1108                 :             : 
    1109                 :             : protected:
    1110                 :             :   // Use covariance to implement clone function as returning this type
    1111                 :           0 :   MetaListNameValueStr *clone_meta_item_inner_impl () const override
    1112                 :             :   {
    1113                 :           0 :     return new MetaListNameValueStr (*this);
    1114                 :             :   }
    1115                 :             : };
    1116                 :             : 
    1117                 :             : // Object that parses macros from a token stream.
    1118                 :             : /* TODO: would "AttributeParser" be a better name? MetaItems are only for
    1119                 :             :  * attributes, I believe */
    1120                 :             : struct AttributeParser
    1121                 :             : {
    1122                 :             : private:
    1123                 :             :   // TODO: might as well rewrite to use lexer tokens
    1124                 :             :   std::unique_ptr<MacroInvocLexer> lexer;
    1125                 :             :   std::unique_ptr<Parser<MacroInvocLexer>> parser;
    1126                 :             : 
    1127                 :             : public:
    1128                 :             :   AttributeParser (std::vector<std::unique_ptr<Token>> token_stream,
    1129                 :             :                    int stream_start_pos = 0);
    1130                 :             : 
    1131                 :             :   ~AttributeParser ();
    1132                 :             : 
    1133                 :             :   std::vector<std::unique_ptr<MetaItemInner>> parse_meta_item_seq ();
    1134                 :             : 
    1135                 :             : private:
    1136                 :             :   // Parses a MetaItemInner.
    1137                 :             :   std::unique_ptr<MetaItemInner> parse_meta_item_inner ();
    1138                 :             :   // Returns whether token can end a meta item.
    1139                 :             :   bool is_end_meta_item_tok (TokenId id) const;
    1140                 :             :   // Parses a MetaItemLitExpr.
    1141                 :             :   std::unique_ptr<MetaItemLitExpr> parse_meta_item_lit ();
    1142                 :             :   // Parses a meta item that begins with a simple path.
    1143                 :             :   std::unique_ptr<MetaItem> parse_path_meta_item ();
    1144                 :             : };
    1145                 :             : } // namespace AST
    1146                 :             : } // namespace Rust
    1147                 :             : 
    1148                 :             : /* <https://stackoverflow.com/a/35304501> */
    1149                 :             : namespace std {
    1150                 :             : template <> struct hash<Rust::AST::MacroFragSpec::Kind>
    1151                 :             : {
    1152                 :        1631 :   size_t operator() (const Rust::AST::MacroFragSpec::Kind &t) const noexcept
    1153                 :             :   {
    1154                 :        1631 :     return size_t (t);
    1155                 :             :   }
    1156                 :             : };
    1157                 :             : } // namespace std
    1158                 :             : 
    1159                 :             : #endif
        

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.