LCOV - code coverage report
Current view: top level - gcc/rust/util - rust-attributes.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 65.6 % 620 407
Test Date: 2026-02-28 14:20:25 Functions: 54.7 % 170 93
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Copyright (C) 2020-2026 Free Software Foundation, Inc.
       2              : 
       3              : // This file is part of GCC.
       4              : 
       5              : // GCC is free software; you can redistribute it and/or modify it under
       6              : // the terms of the GNU General Public License as published by the Free
       7              : // Software Foundation; either version 3, or (at your option) any later
       8              : // version.
       9              : 
      10              : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11              : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12              : // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13              : // for more details.
      14              : 
      15              : // You should have received a copy of the GNU General Public License
      16              : // along with GCC; see the file COPYING3.  If not see
      17              : // <http://www.gnu.org/licenses/>.
      18              : 
      19              : #include "rust-ast-visitor.h"
      20              : #include "rust-system.h"
      21              : #include "rust-session-manager.h"
      22              : #include "rust-attributes.h"
      23              : #include "rust-ast.h"
      24              : #include "rust-ast-full.h"
      25              : #include "rust-diagnostics.h"
      26              : #include "rust-unicode.h"
      27              : #include "rust-attribute-values.h"
      28              : 
      29              : namespace Rust {
      30              : namespace Analysis {
      31              : 
      32              : bool
      33        28990 : Attributes::is_known (const std::string &attribute_path)
      34              : {
      35        28990 :   const auto &lookup
      36        28990 :     = BuiltinAttributeMappings::get ()->lookup_builtin (attribute_path);
      37              : 
      38        28990 :   return !lookup.is_error ();
      39              : }
      40              : 
      41              : tl::optional<std::string>
      42         6460 : Attributes::extract_string_literal (const AST::Attribute &attr)
      43              : {
      44         6460 :   if (!attr.has_attr_input ())
      45            0 :     return tl::nullopt;
      46              : 
      47         6460 :   auto &attr_input = attr.get_attr_input ();
      48              : 
      49         6460 :   if (attr_input.get_attr_input_type ()
      50              :       != AST::AttrInput::AttrInputType::LITERAL)
      51            2 :     return tl::nullopt;
      52              : 
      53         6458 :   auto &literal_expr
      54         6458 :     = static_cast<AST::AttrInputLiteral &> (attr_input).get_literal ();
      55              : 
      56         6458 :   auto lit_type = literal_expr.get_lit_type ();
      57              : 
      58              :   // TODO: bring escape sequence handling out of lexing?
      59         6458 :   if (lit_type != AST::Literal::LitType::STRING
      60         6458 :       && lit_type != AST::Literal::LitType::RAW_STRING)
      61            2 :     return tl::nullopt;
      62              : 
      63         6456 :   return literal_expr.as_string ();
      64              : }
      65              : 
      66              : using Attrs = Values::Attributes;
      67              : 
      68              : // https://doc.rust-lang.org/stable/nightly-rustc/src/rustc_feature/builtin_attrs.rs.html#248
      69              : static const BuiltinAttrDefinition __definitions[]
      70              :   = {{Attrs::INLINE, CODE_GENERATION},
      71              :      {Attrs::COLD, CODE_GENERATION},
      72              :      {Attrs::CFG, EXPANSION},
      73              :      {Attrs::CFG_ATTR, EXPANSION},
      74              :      {Attrs::DERIVE_ATTR, EXPANSION},
      75              :      {Attrs::DEPRECATED, STATIC_ANALYSIS},
      76              :      {Attrs::ALLOW, STATIC_ANALYSIS},
      77              :      {Attrs::ALLOW_INTERNAL_UNSTABLE, STATIC_ANALYSIS},
      78              :      {Attrs::DOC, HIR_LOWERING},
      79              :      {Attrs::MUST_USE, STATIC_ANALYSIS},
      80              :      {Attrs::LANG, HIR_LOWERING},
      81              :      {Attrs::LINK_NAME, CODE_GENERATION},
      82              :      {Attrs::LINK_SECTION, CODE_GENERATION},
      83              :      {Attrs::NO_MANGLE, CODE_GENERATION},
      84              :      {Attrs::EXPORT_NAME, CODE_GENERATION},
      85              :      {Attrs::REPR, CODE_GENERATION},
      86              :      {Attrs::RUSTC_BUILTIN_MACRO, EXPANSION},
      87              :      {Attrs::RUSTC_MACRO_TRANSPARENCY, EXPANSION},
      88              :      {Attrs::PATH, EXPANSION},
      89              :      {Attrs::MACRO_USE, NAME_RESOLUTION},
      90              :      {Attrs::MACRO_EXPORT, NAME_RESOLUTION},
      91              :      {Attrs::PROC_MACRO, EXPANSION},
      92              :      {Attrs::PROC_MACRO_DERIVE, EXPANSION},
      93              :      {Attrs::PROC_MACRO_ATTRIBUTE, EXPANSION},
      94              :      // FIXME: This is not implemented yet, see
      95              :      // https://github.com/Rust-GCC/gccrs/issues/1475
      96              :      {Attrs::TARGET_FEATURE, CODE_GENERATION},
      97              :      // From now on, these are reserved by the compiler and gated through
      98              :      // #![feature(rustc_attrs)]
      99              :      {Attrs::RUSTC_DEPRECATED, STATIC_ANALYSIS},
     100              :      {Attrs::RUSTC_INHERIT_OVERFLOW_CHECKS, CODE_GENERATION},
     101              :      {Attrs::STABLE, STATIC_ANALYSIS},
     102              :      {Attrs::UNSTABLE, STATIC_ANALYSIS},
     103              :      // assuming we keep these for static analysis
     104              :      {Attrs::RUSTC_PROMOTABLE, CODE_GENERATION},
     105              :      {Attrs::RUSTC_CONST_STABLE, STATIC_ANALYSIS},
     106              :      {Attrs::RUSTC_CONST_UNSTABLE, STATIC_ANALYSIS},
     107              :      {Attrs::RUSTC_ALLOW_CONST_FN_UNSTABLE, STATIC_ANALYSIS},
     108              :      {Attrs::PRELUDE_IMPORT, NAME_RESOLUTION},
     109              :      {Attrs::TRACK_CALLER, CODE_GENERATION},
     110              :      {Attrs::RUSTC_SPECIALIZATION_TRAIT, TYPE_CHECK},
     111              :      {Attrs::RUSTC_UNSAFE_SPECIALIZATION_MARKER, TYPE_CHECK},
     112              :      {Attrs::RUSTC_RESERVATION_IMPL, TYPE_CHECK},
     113              :      {Attrs::RUSTC_PAREN_SUGAR, TYPE_CHECK},
     114              :      {Attrs::RUSTC_NONNULL_OPTIMIZATION_GUARANTEED, TYPE_CHECK},
     115              :      {Attrs::RUSTC_LAYOUT_SCALAR_VALID_RANGE_START, CODE_GENERATION},
     116              :      // TODO: be careful about calling functions marked with this?
     117              :      {Attrs::RUSTC_ARGS_REQUIRED_CONST, CODE_GENERATION},
     118              :      {Attrs::PRELUDE_IMPORT, NAME_RESOLUTION},
     119              :      {Attrs::RUSTC_DIAGNOSTIC_ITEM, STATIC_ANALYSIS},
     120              :      {Attrs::RUSTC_ON_UNIMPLEMENTED, STATIC_ANALYSIS},
     121              :      {Attrs::FUNDAMENTAL, TYPE_CHECK},
     122              :      {Attrs::NON_EXHAUSTIVE, TYPE_CHECK},
     123              :      {Attrs::RUSTFMT, EXTERNAL},
     124              :      {Attrs::TEST, CODE_GENERATION}};
     125              : 
     126              : static const std::set<std::string> __outer_attributes
     127              :   = {Attrs::INLINE,
     128              :      Attrs::DERIVE_ATTR,
     129              :      Attrs::ALLOW_INTERNAL_UNSTABLE,
     130              :      Attrs::LANG,
     131              :      Attrs::REPR,
     132              :      Attrs::PATH,
     133              :      Attrs::TARGET_FEATURE,
     134              :      Attrs::TEST,
     135              :      Attrs::COLD,
     136              :      Attrs::MACRO_USE,
     137              :      Attrs::MACRO_EXPORT,
     138              :      Attrs::PROC_MACRO_ATTRIBUTE,
     139              :      Attrs::PROC_MACRO_DERIVE,
     140              :      Attrs::DEPRECATED,
     141              :      Attrs::MUST_USE,
     142              :      Attrs::LINK_NAME,
     143              :      Attrs::LINK_SECTION};
     144              : 
     145              : BuiltinAttributeMappings *
     146       487782 : BuiltinAttributeMappings::get ()
     147              : {
     148       487782 :   static BuiltinAttributeMappings *instance = nullptr;
     149       487782 :   if (instance == nullptr)
     150         4510 :     instance = new BuiltinAttributeMappings ();
     151              : 
     152       487782 :   return instance;
     153              : }
     154              : 
     155              : const BuiltinAttrDefinition &
     156       107073 : BuiltinAttributeMappings::lookup_builtin (const std::string &attr_name) const
     157              : {
     158       107073 :   auto it = mappings.find (attr_name);
     159       107073 :   if (it == mappings.end ())
     160        22228 :     return BuiltinAttrDefinition::error_node ();
     161              : 
     162        84845 :   return it->second;
     163              : }
     164              : 
     165         4510 : BuiltinAttributeMappings::BuiltinAttributeMappings ()
     166              : {
     167         4510 :   size_t ndefinitions = sizeof (__definitions) / sizeof (BuiltinAttrDefinition);
     168       225500 :   for (size_t i = 0; i < ndefinitions; i++)
     169              :     {
     170       220990 :       const BuiltinAttrDefinition &def = __definitions[i];
     171       441980 :       mappings.insert ({def.name, def});
     172              :     }
     173         4510 : }
     174              : 
     175         4510 : AttributeChecker::AttributeChecker () {}
     176              : 
     177              : void
     178         4510 : AttributeChecker::go (AST::Crate &crate)
     179              : {
     180         4510 :   visit (crate);
     181         4510 : }
     182              : 
     183              : void
     184         4510 : AttributeChecker::visit (AST::Crate &crate)
     185              : {
     186        15737 :   for (auto &attr : crate.get_inner_attrs ())
     187              :     {
     188        11227 :       check_inner_attribute (attr);
     189        11227 :       check_attribute (attr);
     190              :     }
     191              : 
     192        22786 :   for (auto &item : crate.items)
     193        18276 :     item->accept_vis (*this);
     194         4510 : }
     195              : 
     196              : static bool
     197        33899 : is_builtin (const AST::Attribute &attribute, BuiltinAttrDefinition &builtin)
     198              : {
     199        33899 :   auto &segments = attribute.get_path ().get_segments ();
     200              : 
     201              :   // Builtin attributes always have a single segment. This avoids us creating
     202              :   // strings all over the place and performing a linear search in the builtins
     203              :   // map
     204        33899 :   if (segments.size () != 1)
     205              :     return false;
     206              : 
     207        33899 :   builtin = BuiltinAttributeMappings::get ()->lookup_builtin (
     208        33899 :     segments.at (0).get_segment_name ());
     209              : 
     210        33899 :   return !builtin.is_error ();
     211              : }
     212              : 
     213              : /**
     214              :  * Check that the string given to #[doc(alias = ...)] or #[doc(alias(...))] is
     215              :  * valid.
     216              :  *
     217              :  * This means no whitespace characters other than spaces and no quoting
     218              :  * characters.
     219              :  */
     220              : static void
     221          700 : check_doc_alias (const std::string &alias_input, const location_t locus)
     222              : {
     223              :   // FIXME: The locus here is for the whole attribute. Can we get the locus
     224              :   // of the alias input instead?
     225         1872 :   for (auto c : alias_input)
     226         1172 :     if ((ISSPACE (c) && c != ' ') || c == '\'' || c == '\"')
     227              :       {
     228            7 :         auto to_print = std::string (1, c);
     229            7 :         switch (c)
     230              :           {
     231            7 :           case '\n':
     232            7 :             to_print = "\\n";
     233            7 :             break;
     234            0 :           case '\t':
     235            0 :             to_print = "\\t";
     236            0 :             break;
     237              :           default:
     238              :             break;
     239              :           }
     240            7 :         rust_error_at (locus,
     241              :                        "invalid character used in %<#[doc(alias)]%> input: %qs",
     242              :                        to_print.c_str ());
     243            7 :       }
     244              : 
     245          700 :   if (alias_input.empty ())
     246              :     return;
     247              : 
     248         1400 :   if (alias_input.front () == ' ' || alias_input.back () == ' ')
     249            0 :     rust_error_at (locus,
     250              :                    "%<#[doc(alias)]%> input cannot start or end with a space");
     251              : }
     252              : 
     253              : static void
     254          877 : check_doc_attribute (const AST::Attribute &attribute)
     255              : {
     256          877 :   if (!attribute.has_attr_input ())
     257              :     {
     258            1 :       rust_error_at (
     259              :         attribute.get_locus (),
     260              :         "valid forms for the attribute are "
     261              :         "%<#[doc(hidden|inline|...)]%> and %<#[doc = \" string \"]%>");
     262            1 :       return;
     263              :     }
     264              : 
     265          876 :   switch (attribute.get_attr_input ().get_attr_input_type ())
     266              :     {
     267              :     case AST::AttrInput::LITERAL:
     268              :     case AST::AttrInput::MACRO:
     269              :     case AST::AttrInput::META_ITEM:
     270              :       break;
     271              :       // FIXME: Handle them as well
     272              : 
     273          742 :     case AST::AttrInput::TOKEN_TREE:
     274          742 :       {
     275              :         // FIXME: This doesn't check for #[doc(alias(...))]
     276          742 :         const auto &option = static_cast<const AST::DelimTokenTree &> (
     277          742 :           attribute.get_attr_input ());
     278          742 :         auto *meta_item = option.parse_to_meta_item ();
     279              : 
     280         1491 :         for (auto &item : meta_item->get_items ())
     281              :           {
     282          749 :             if (item->is_key_value_pair ())
     283              :               {
     284          707 :                 auto name_value
     285          707 :                   = static_cast<AST::MetaNameValueStr *> (item.get ())
     286          707 :                       ->get_name_value_pair ();
     287              : 
     288              :                 // FIXME: Check for other stuff than #[doc(alias = ...)]
     289          707 :                 if (name_value.first.as_string () == "alias")
     290          700 :                   check_doc_alias (name_value.second, attribute.get_locus ());
     291          707 :               }
     292              :           }
     293              :         break;
     294              :       }
     295              :     }
     296              : }
     297              : 
     298              : static void
     299            1 : check_deprecated_attribute (const AST::Attribute &attribute)
     300              : {
     301            1 :   if (!attribute.has_attr_input ())
     302              :     return;
     303              : 
     304            0 :   const auto &input = attribute.get_attr_input ();
     305              : 
     306            0 :   if (input.get_attr_input_type () != AST::AttrInput::META_ITEM)
     307              :     return;
     308              : 
     309            0 :   auto &meta = static_cast<const AST::AttrInputMetaItemContainer &> (input);
     310              : 
     311            0 :   for (auto &current : meta.get_items ())
     312              :     {
     313            0 :       switch (current->get_kind ())
     314              :         {
     315            0 :         case AST::MetaItemInner::Kind::MetaItem:
     316            0 :           {
     317            0 :             auto *meta_item = static_cast<AST::MetaItem *> (current.get ());
     318              : 
     319            0 :             switch (meta_item->get_item_kind ())
     320              :               {
     321            0 :               case AST::MetaItem::ItemKind::NameValueStr:
     322            0 :                 {
     323            0 :                   auto *nv = static_cast<AST::MetaNameValueStr *> (meta_item);
     324              : 
     325            0 :                   const std::string key = nv->get_name ().as_string ();
     326              : 
     327            0 :                   if (key != "since" && key != "note")
     328              :                     {
     329            0 :                       rust_error_at (nv->get_locus (), "unknown meta item %qs",
     330              :                                      key.c_str ());
     331            0 :                       rust_inform (nv->get_locus (),
     332              :                                    "expected one of %<since%>, %<note%>");
     333              :                     }
     334            0 :                 }
     335            0 :                 break;
     336              : 
     337            0 :               case AST::MetaItem::ItemKind::Path:
     338            0 :                 {
     339              :                   // #[deprecated(a,a)]
     340            0 :                   auto *p = static_cast<AST::MetaItemPath *> (meta_item);
     341              : 
     342            0 :                   std::string ident = p->get_path ().as_string ();
     343              : 
     344            0 :                   rust_error_at (p->get_locus (), "unknown meta item %qs",
     345              :                                  ident.c_str ());
     346            0 :                   rust_inform (p->get_locus (),
     347              :                                "expected one of %<since%>, %<note%>");
     348            0 :                 }
     349            0 :                 break;
     350              : 
     351            0 :               case AST::MetaItem::ItemKind::Word:
     352            0 :                 {
     353              :                   // #[deprecated("a")]
     354            0 :                   auto *w = static_cast<AST::MetaWord *> (meta_item);
     355              : 
     356            0 :                   rust_error_at (
     357            0 :                     w->get_locus (),
     358              :                     "item in %<deprecated%> must be a key/value pair");
     359              :                 }
     360            0 :                 break;
     361              : 
     362            0 :               case AST::MetaItem::ItemKind::PathExpr:
     363            0 :                 {
     364              :                   // #[deprecated(since=a)]
     365            0 :                   auto *px = static_cast<AST::MetaItemPathExpr *> (meta_item);
     366              : 
     367            0 :                   rust_error_at (
     368            0 :                     px->get_locus (),
     369              :                     "expected unsuffixed literal or identifier, found %qs",
     370            0 :                     px->get_expr ().as_string ().c_str ());
     371              :                 }
     372            0 :                 break;
     373              : 
     374            0 :               case AST::MetaItem::ItemKind::Seq:
     375            0 :               case AST::MetaItem::ItemKind::ListPaths:
     376            0 :               case AST::MetaItem::ItemKind::ListNameValueStr:
     377            0 :               default:
     378            0 :                 gcc_unreachable ();
     379            0 :                 break;
     380              :               }
     381              :           }
     382            0 :           break;
     383              : 
     384            0 :         case AST::MetaItemInner::Kind::LitExpr:
     385            0 :         default:
     386            0 :           gcc_unreachable ();
     387            0 :           break;
     388              :         }
     389              :     }
     390              : }
     391              : 
     392              : /**
     393              :  * Emit an error when an attribute is attached
     394              :  * to an incompatable item type. e.g.:
     395              :  *
     396              :  * #[cold]
     397              :  * struct A(u8, u8);
     398              :  *
     399              :  * Note that "#[derive]" is handled
     400              :  * explicitly in rust-derive.cc
     401              :  */
     402              : static void
     403         5064 : check_valid_attribute_for_item (const AST::Attribute &attr,
     404              :                                 const AST::Item &item)
     405              : {
     406        10128 :   if (item.get_item_kind () != AST::Item::Kind::Function
     407        14870 :       && (attr.get_path () == Values::Attributes::TARGET_FEATURE
     408        14546 :           || attr.get_path () == Values::Attributes::COLD
     409         9805 :           || attr.get_path () == Values::Attributes::INLINE))
     410              :     {
     411            1 :       rust_error_at (attr.get_locus (),
     412              :                      "the %<#[%s]%> attribute may only be applied to functions",
     413            2 :                      attr.get_path ().as_string ().c_str ());
     414              :     }
     415        10126 :   else if (attr.get_path () == Values::Attributes::REPR
     416           39 :            && item.get_item_kind () != AST::Item::Kind::Enum
     417           37 :            && item.get_item_kind () != AST::Item::Kind::Union
     418         5092 :            && item.get_item_kind () != AST::Item::Kind::Struct)
     419              :     {
     420            1 :       rust_error_at (attr.get_locus (),
     421              :                      "the %<#[%s]%> attribute may only be applied "
     422              :                      "to structs, enums and unions",
     423            2 :                      attr.get_path ().as_string ().c_str ());
     424              :     }
     425         5064 : }
     426              : 
     427              : static bool
     428         6750 : is_proc_macro_type (const AST::Attribute &attribute)
     429              : {
     430         6750 :   BuiltinAttrDefinition result;
     431         6750 :   if (!is_builtin (attribute, result))
     432              :     return false;
     433              : 
     434         6750 :   auto name = result.name;
     435         6732 :   return name == Attrs::PROC_MACRO || name == Attrs::PROC_MACRO_DERIVE
     436        13482 :          || name == Attrs::PROC_MACRO_ATTRIBUTE;
     437         6750 : }
     438              : 
     439              : // Emit an error when one encountered attribute is either #[proc_macro],
     440              : // #[proc_macro_attribute] or #[proc_macro_derive]
     441              : static void
     442         4742 : check_proc_macro_non_function (const AST::Attribute &attr)
     443              : {
     444         4742 :   if (is_proc_macro_type (attr))
     445           45 :     rust_error_at (attr.get_locus (),
     446              :                    "the %<#[%s]%> attribute may only be used on bare functions",
     447           90 :                    attr.get_path ().get_segments ()[0].as_string ().c_str ());
     448         4742 : }
     449              : 
     450              : // Emit an error when one attribute is either proc_macro, proc_macro_attribute
     451              : // or proc_macro_derive
     452              : static void
     453         2008 : check_proc_macro_non_root (const AST::Attribute &attr, location_t loc)
     454              : {
     455         2008 :   if (is_proc_macro_type (attr))
     456              :     {
     457            9 :       rust_error_at (
     458              :         loc,
     459              :         "functions tagged with %<#[%s]%> must currently "
     460              :         "reside in the root of the crate",
     461           18 :         attr.get_path ().get_segments ().at (0).as_string ().c_str ());
     462              :     }
     463         2008 : }
     464              : 
     465              : void
     466        11227 : AttributeChecker::check_inner_attribute (const AST::Attribute &attribute)
     467              : {
     468        11227 :   BuiltinAttrDefinition result;
     469              : 
     470        11227 :   if (!is_builtin (attribute, result))
     471        11113 :     return;
     472              : 
     473          114 :   if (__outer_attributes.find (result.name) != __outer_attributes.end ())
     474            3 :     rust_error_at (attribute.get_locus (),
     475              :                    "attribute cannot be used at crate level");
     476        11227 : }
     477              : 
     478              : static void
     479            2 : check_link_section_attribute (const AST::Attribute &attribute)
     480              : {
     481            2 :   if (!attribute.has_attr_input ())
     482              :     {
     483            1 :       rust_error_at (attribute.get_locus (),
     484              :                      "malformed %<link_section%> attribute input");
     485            1 :       rust_inform (attribute.get_locus (),
     486              :                    "must be of the form: %<#[link_section = \"name\"]%>");
     487              :     }
     488            2 : }
     489              : 
     490              : static void
     491            9 : check_export_name_attribute (const AST::Attribute &attribute)
     492              : {
     493            9 :   if (!attribute.has_attr_input ())
     494              :     {
     495            2 :       rust_error_at (attribute.get_locus (),
     496              :                      "malformed %<export_name%> attribute input");
     497            2 :       rust_inform (attribute.get_locus (),
     498              :                    "must be of the form: %<#[export_name = \"name\"]%>");
     499            2 :       return;
     500              :     }
     501              : 
     502           10 :   if (!Attributes::extract_string_literal (attribute))
     503              :     {
     504            4 :       rust_error_at (attribute.get_locus (),
     505              :                      "attribute must be a string literal");
     506              :     }
     507              : }
     508              : 
     509              : static void
     510           10 : check_lint_attribute (const AST::Attribute &attribute, const char *name)
     511              : {
     512           10 :   if (!attribute.has_attr_input ())
     513              :     {
     514            1 :       rust_error_at (attribute.get_locus (), "malformed %qs attribute input",
     515              :                      name);
     516            1 :       rust_inform (attribute.get_locus (),
     517              :                    "must be of the form: %<#[%s(lint1, lint2, ...)]%>", name);
     518              :     }
     519           10 : }
     520              : 
     521              : void
     522        15592 : AttributeChecker::check_attribute (const AST::Attribute &attribute)
     523              : {
     524        15592 :   if (!attribute.empty_input ())
     525              :     {
     526        11043 :       const auto &attr_input = attribute.get_attr_input ();
     527        11043 :       auto type = attr_input.get_attr_input_type ();
     528        11043 :       if (type == AST::AttrInput::AttrInputType::TOKEN_TREE)
     529              :         {
     530         8036 :           const auto &option = static_cast<const AST::DelimTokenTree &> (
     531         8036 :             attribute.get_attr_input ());
     532         8036 :           std::unique_ptr<AST::AttrInputMetaItemContainer> meta_item (
     533         8036 :             option.parse_to_meta_item ());
     534         8036 :           AST::DefaultASTVisitor::visit (meta_item);
     535         8036 :         }
     536              :     }
     537              : 
     538        15592 :   BuiltinAttrDefinition result;
     539              : 
     540              :   // This checker does not check non-builtin attributes
     541        15592 :   if (!is_builtin (attribute, result))
     542        11113 :     return;
     543              : 
     544              :   // TODO: Add checks here for each builtin attribute
     545              :   // TODO: Have an enum of builtins as well, switching on strings is annoying
     546              :   // and costly
     547         4479 :   if (result.name == Attrs::DOC)
     548          877 :     check_doc_attribute (attribute);
     549         3602 :   else if (result.name == Attrs::DEPRECATED)
     550            1 :     check_deprecated_attribute (attribute);
     551        15592 : }
     552              : 
     553              : void
     554            0 : AttributeChecker::visit (AST::Token &)
     555            0 : {}
     556              : 
     557              : void
     558            0 : AttributeChecker::visit (AST::DelimTokenTree &)
     559            0 : {}
     560              : 
     561              : void
     562          519 : AttributeChecker::visit (AST::IdentifierExpr &)
     563          519 : {}
     564              : 
     565              : void
     566            0 : AttributeChecker::visit (AST::Lifetime &)
     567            0 : {}
     568              : 
     569              : void
     570           33 : AttributeChecker::visit (AST::LifetimeParam &)
     571           33 : {}
     572              : 
     573              : void
     574           23 : AttributeChecker::visit (AST::ConstGenericParam &)
     575           23 : {}
     576              : 
     577              : // rust-path.h
     578              : void
     579           38 : AttributeChecker::visit (AST::PathInExpression &)
     580           38 : {}
     581              : 
     582              : void
     583            0 : AttributeChecker::visit (AST::TypePathSegment &)
     584            0 : {}
     585              : 
     586              : void
     587            0 : AttributeChecker::visit (AST::TypePathSegmentGeneric &)
     588            0 : {}
     589              : 
     590              : void
     591            0 : AttributeChecker::visit (AST::TypePathSegmentFunction &)
     592            0 : {}
     593              : 
     594              : void
     595         4366 : AttributeChecker::visit (AST::TypePath &)
     596         4366 : {}
     597              : 
     598              : void
     599            0 : AttributeChecker::visit (AST::QualifiedPathInExpression &)
     600            0 : {}
     601              : 
     602              : void
     603            0 : AttributeChecker::visit (AST::QualifiedPathInType &)
     604            0 : {}
     605              : 
     606              : // rust-expr.h
     607              : void
     608         1418 : AttributeChecker::visit (AST::LiteralExpr &)
     609         1418 : {}
     610              : 
     611              : void
     612            0 : AttributeChecker::visit (AST::AttrInputLiteral &)
     613            0 : {}
     614              : 
     615              : void
     616            0 : AttributeChecker::visit (AST::AttrInputMacro &)
     617            0 : {}
     618              : 
     619              : void
     620           26 : AttributeChecker::visit (AST::MetaItemLitExpr &)
     621           26 : {}
     622              : 
     623              : void
     624            2 : AttributeChecker::visit (AST::MetaItemPathExpr &attribute)
     625              : {
     626            2 :   if (!attribute.get_expr ().is_literal ())
     627              :     {
     628            1 :       rust_error_at (attribute.get_expr ().get_locus (),
     629              :                      "malformed %<path%> attribute input");
     630            1 :       rust_inform (attribute.get_expr ().get_locus (),
     631              :                    "must be of the form: %<#[path = \"file\"]%>");
     632              :     }
     633            2 : }
     634              : 
     635              : void
     636          143 : AttributeChecker::visit (AST::BorrowExpr &)
     637          143 : {}
     638              : 
     639              : void
     640          228 : AttributeChecker::visit (AST::DereferenceExpr &)
     641          228 : {}
     642              : 
     643              : void
     644            0 : AttributeChecker::visit (AST::ErrorPropagationExpr &)
     645            0 : {}
     646              : 
     647              : void
     648           15 : AttributeChecker::visit (AST::NegationExpr &)
     649           15 : {}
     650              : 
     651              : void
     652          776 : AttributeChecker::visit (AST::ArithmeticOrLogicalExpr &)
     653          776 : {}
     654              : 
     655              : void
     656          743 : AttributeChecker::visit (AST::ComparisonExpr &)
     657          743 : {}
     658              : 
     659              : void
     660           28 : AttributeChecker::visit (AST::LazyBooleanExpr &)
     661           28 : {}
     662              : 
     663              : void
     664          158 : AttributeChecker::visit (AST::TypeCastExpr &)
     665          158 : {}
     666              : 
     667              : void
     668            1 : AttributeChecker::visit (AST::AssignmentExpr &)
     669            1 : {}
     670              : 
     671              : void
     672            7 : AttributeChecker::visit (AST::CompoundAssignmentExpr &)
     673            7 : {}
     674              : 
     675              : void
     676           12 : AttributeChecker::visit (AST::GroupedExpr &)
     677           12 : {}
     678              : 
     679              : void
     680            0 : AttributeChecker::visit (AST::ArrayElemsValues &)
     681            0 : {}
     682              : 
     683              : void
     684            0 : AttributeChecker::visit (AST::ArrayElemsCopied &)
     685            0 : {}
     686              : 
     687              : void
     688           15 : AttributeChecker::visit (AST::ArrayExpr &)
     689           15 : {}
     690              : 
     691              : void
     692            0 : AttributeChecker::visit (AST::ArrayIndexExpr &)
     693            0 : {}
     694              : 
     695              : void
     696           53 : AttributeChecker::visit (AST::TupleExpr &)
     697           53 : {}
     698              : 
     699              : void
     700          187 : AttributeChecker::visit (AST::TupleIndexExpr &)
     701          187 : {}
     702              : 
     703              : void
     704            7 : AttributeChecker::visit (AST::StructExprStruct &)
     705            7 : {}
     706              : 
     707              : void
     708            0 : AttributeChecker::visit (AST::StructExprFieldIdentifier &)
     709            0 : {}
     710              : 
     711              : void
     712            0 : AttributeChecker::visit (AST::StructExprFieldIdentifierValue &)
     713            0 : {}
     714              : 
     715              : void
     716            0 : AttributeChecker::visit (AST::StructExprFieldIndexValue &)
     717            0 : {}
     718              : 
     719              : void
     720          155 : AttributeChecker::visit (AST::StructExprStructFields &)
     721          155 : {}
     722              : 
     723              : void
     724            0 : AttributeChecker::visit (AST::StructExprStructBase &)
     725            0 : {}
     726              : 
     727              : void
     728          646 : AttributeChecker::visit (AST::CallExpr &)
     729          646 : {}
     730              : 
     731              : void
     732          276 : AttributeChecker::visit (AST::MethodCallExpr &)
     733          276 : {}
     734              : 
     735              : void
     736          171 : AttributeChecker::visit (AST::FieldAccessExpr &)
     737          171 : {}
     738              : 
     739              : void
     740            1 : AttributeChecker::visit (AST::ClosureExprInner &)
     741            1 : {}
     742              : 
     743              : void
     744        11152 : AttributeChecker::visit (AST::BlockExpr &expr)
     745              : {
     746        26812 :   for (auto &stmt : expr.get_statements ())
     747              :     {
     748        15660 :       if (stmt->get_stmt_kind () == AST::Stmt::Kind::Item)
     749              :         {
     750              :           // Non owning pointer, let it go out of scope
     751          718 :           auto item = static_cast<AST::Item *> (stmt.get ());
     752          728 :           for (auto &attr : item->get_outer_attrs ())
     753           10 :             check_proc_macro_non_root (attr, item->get_locus ());
     754              :         }
     755              :     }
     756        11152 :   AST::DefaultASTVisitor::visit (expr);
     757        11152 : }
     758              : 
     759              : void
     760            0 : AttributeChecker::visit (AST::ClosureExprInnerTyped &)
     761            0 : {}
     762              : 
     763              : void
     764            0 : AttributeChecker::visit (AST::ContinueExpr &)
     765            0 : {}
     766              : 
     767              : void
     768            0 : AttributeChecker::visit (AST::BreakExpr &)
     769            0 : {}
     770              : 
     771              : void
     772            0 : AttributeChecker::visit (AST::RangeFromToExpr &)
     773            0 : {}
     774              : 
     775              : void
     776            0 : AttributeChecker::visit (AST::RangeFromExpr &)
     777            0 : {}
     778              : 
     779              : void
     780            0 : AttributeChecker::visit (AST::RangeToExpr &)
     781            0 : {}
     782              : 
     783              : void
     784            0 : AttributeChecker::visit (AST::RangeFullExpr &)
     785            0 : {}
     786              : 
     787              : void
     788            0 : AttributeChecker::visit (AST::RangeFromToInclExpr &)
     789            0 : {}
     790              : 
     791              : void
     792            0 : AttributeChecker::visit (AST::RangeToInclExpr &)
     793            0 : {}
     794              : 
     795              : void
     796            3 : AttributeChecker::visit (AST::ReturnExpr &)
     797            3 : {}
     798              : 
     799              : void
     800           52 : AttributeChecker::visit (AST::LoopExpr &)
     801           52 : {}
     802              : 
     803              : void
     804           18 : AttributeChecker::visit (AST::WhileLoopExpr &)
     805           18 : {}
     806              : 
     807              : void
     808            2 : AttributeChecker::visit (AST::WhileLetLoopExpr &)
     809            2 : {}
     810              : 
     811              : void
     812            1 : AttributeChecker::visit (AST::ForLoopExpr &)
     813            1 : {}
     814              : 
     815              : void
     816           66 : AttributeChecker::visit (AST::IfExpr &)
     817           66 : {}
     818              : 
     819              : void
     820          460 : AttributeChecker::visit (AST::IfExprConseqElse &)
     821          460 : {}
     822              : 
     823              : void
     824            0 : AttributeChecker::visit (AST::IfLetExpr &)
     825            0 : {}
     826              : 
     827              : void
     828            9 : AttributeChecker::visit (AST::IfLetExprConseqElse &)
     829            9 : {}
     830              : 
     831              : void
     832          225 : AttributeChecker::visit (AST::MatchExpr &)
     833          225 : {}
     834              : 
     835              : void
     836            0 : AttributeChecker::visit (AST::AwaitExpr &)
     837            0 : {}
     838              : 
     839              : void
     840            0 : AttributeChecker::visit (AST::AsyncBlockExpr &)
     841            0 : {}
     842              : 
     843              : // rust-item.h
     844              : void
     845          965 : AttributeChecker::visit (AST::TypeParam &)
     846          965 : {}
     847              : 
     848              : void
     849            0 : AttributeChecker::visit (AST::LifetimeWhereClauseItem &)
     850            0 : {}
     851              : 
     852              : void
     853           85 : AttributeChecker::visit (AST::TypeBoundWhereClauseItem &)
     854           85 : {}
     855              : 
     856              : void
     857         1303 : AttributeChecker::visit (AST::Module &module)
     858              : {
     859         1470 :   for (auto &attr : module.get_outer_attrs ())
     860              :     {
     861          167 :       check_valid_attribute_for_item (attr, module);
     862          167 :       check_attribute (attr);
     863          167 :       check_proc_macro_non_function (attr);
     864              :     }
     865              : 
     866         4135 :   for (auto &item : module.get_items ())
     867         4830 :     for (auto &attr : item->get_outer_attrs ())
     868         1998 :       check_proc_macro_non_root (attr, item->get_locus ());
     869              : 
     870         1303 :   AST::DefaultASTVisitor::visit (module);
     871         1303 : }
     872              : 
     873              : void
     874           27 : AttributeChecker::visit (AST::ExternCrate &crate)
     875              : {
     876           30 :   for (auto &attr : crate.get_outer_attrs ())
     877              :     {
     878            3 :       check_valid_attribute_for_item (attr, crate);
     879            3 :       check_proc_macro_non_function (attr);
     880              :     }
     881           27 : }
     882              : 
     883              : void
     884            0 : AttributeChecker::visit (AST::UseTreeGlob &)
     885            0 : {}
     886              : 
     887              : void
     888            0 : AttributeChecker::visit (AST::UseTreeList &)
     889            0 : {}
     890              : 
     891              : void
     892            0 : AttributeChecker::visit (AST::UseTreeRebind &)
     893            0 : {}
     894              : 
     895              : void
     896          676 : AttributeChecker::visit (AST::UseDeclaration &declaration)
     897              : {
     898          680 :   for (auto &attr : declaration.get_outer_attrs ())
     899              :     {
     900            4 :       check_valid_attribute_for_item (attr, declaration);
     901            4 :       check_proc_macro_non_function (attr);
     902              :     }
     903          676 : }
     904              : 
     905              : static void
     906            1 : check_no_mangle_function (const AST::Attribute &attribute,
     907              :                           const AST::Function &fun)
     908              : {
     909            1 :   if (attribute.has_attr_input ())
     910              :     {
     911            0 :       rust_error_at (attribute.get_locus (), ErrorCode::E0754,
     912              :                      "malformed %<no_mangle%> attribute input");
     913            0 :       rust_inform (attribute.get_locus (),
     914              :                    "must be of the form: %<#[no_mangle]%>");
     915              :     }
     916            1 :   if (!is_ascii_only (fun.get_function_name ().as_string ()))
     917            0 :     rust_error_at (fun.get_function_name ().get_locus (),
     918              :                    "the %<#[no_mangle]%> attribute requires ASCII identifier");
     919            1 : }
     920              : 
     921              : void
     922        10032 : AttributeChecker::visit (AST::Function &fun)
     923              : {
     924        10354 :   for (auto &attr : fun.get_outer_attrs ())
     925          322 :     check_valid_attribute_for_item (attr, fun);
     926              : 
     927        10048 :   auto check_crate_type = [] (const char *name, AST::Attribute &attribute) {
     928           16 :     if (!Session::get_instance ().options.is_proc_macro ())
     929            3 :       rust_error_at (attribute.get_locus (),
     930              :                      "the %<#[%s]%> attribute is only usable with crates of "
     931              :                      "the %<proc-macro%> crate type",
     932              :                      name);
     933           16 :   };
     934              : 
     935        10032 :   BuiltinAttrDefinition result;
     936        10354 :   for (auto &attribute : fun.get_outer_attrs ())
     937              :     {
     938          322 :       if (!is_builtin (attribute, result))
     939            0 :         return;
     940              : 
     941          322 :       auto name = result.name.c_str ();
     942              : 
     943          322 :       if (result.name == Attrs::PROC_MACRO_DERIVE)
     944              :         {
     945            6 :           if (!attribute.has_attr_input ())
     946              :             {
     947            1 :               rust_error_at (attribute.get_locus (),
     948              :                              "malformed %qs attribute input", name);
     949            1 :               rust_inform (
     950              :                 attribute.get_locus (),
     951              :                 "must be of the form: %<#[proc_macro_derive(TraitName, "
     952              :                 "/*opt*/ attributes(name1, name2, ...))]%>");
     953              :             }
     954            6 :           check_crate_type (name, attribute);
     955              :         }
     956          316 :       else if (result.name == Attrs::PROC_MACRO
     957          316 :                || result.name == Attrs::PROC_MACRO_ATTRIBUTE)
     958              :         {
     959           10 :           check_crate_type (name, attribute);
     960              :         }
     961          306 :       else if (result.name == Attrs::TARGET_FEATURE)
     962              :         {
     963            3 :           if (!attribute.has_attr_input ())
     964              :             {
     965            1 :               rust_error_at (attribute.get_locus (),
     966              :                              "malformed %<target_feature%> attribute input");
     967            1 :               rust_inform (attribute.get_locus (),
     968              :                            "must be of the form: %<#[target_feature(enable = "
     969              :                            "\"name\")]%>");
     970              :             }
     971            2 :           else if (!fun.get_qualifiers ().is_unsafe ())
     972              :             {
     973            1 :               rust_error_at (
     974              :                 attribute.get_locus (),
     975              :                 "the %<#[target_feature]%> attribute can only be applied "
     976              :                 "to %<unsafe%> functions");
     977              :             }
     978              :         }
     979          303 :       else if (result.name == Attrs::NO_MANGLE)
     980              :         {
     981            2 :           if (attribute.has_attr_input ())
     982              :             {
     983            1 :               rust_error_at (attribute.get_locus (),
     984              :                              "malformed %<no_mangle%> attribute input");
     985            1 :               rust_inform (attribute.get_locus (),
     986              :                            "must be of the form: %<#[no_mangle]%>");
     987              :             }
     988              :           else
     989            1 :             check_no_mangle_function (attribute, fun);
     990              :         }
     991          301 :       else if (result.name == Attrs::EXPORT_NAME)
     992              :         {
     993            5 :           check_export_name_attribute (attribute);
     994              :         }
     995          286 :       else if (result.name == Attrs::ALLOW || result.name == "deny"
     996          582 :                || result.name == "warn" || result.name == "forbid")
     997              :         {
     998           10 :           check_lint_attribute (attribute, name);
     999              :         }
    1000          286 :       else if (result.name == Attrs::LINK_NAME)
    1001              :         {
    1002            1 :           if (!attribute.has_attr_input ())
    1003              :             {
    1004            1 :               rust_error_at (attribute.get_locus (),
    1005              :                              "malformed %<link_name%> attribute input");
    1006            1 :               rust_inform (attribute.get_locus (),
    1007              :                            "must be of the form: %<#[link_name = \"name\"]%>");
    1008              :             }
    1009              :         }
    1010          285 :       else if (result.name == Attrs::LINK_SECTION)
    1011              :         {
    1012            1 :           check_link_section_attribute (attribute);
    1013              :         }
    1014              :     }
    1015              : 
    1016        10032 :   if (fun.has_body ())
    1017        10025 :     fun.get_definition ().value ()->accept_vis (*this);
    1018        10032 : }
    1019              : 
    1020              : void
    1021          736 : AttributeChecker::visit (AST::TypeAlias &alias)
    1022              : {
    1023          739 :   for (auto &attr : alias.get_outer_attrs ())
    1024              :     {
    1025            3 :       check_valid_attribute_for_item (attr, alias);
    1026            3 :       check_proc_macro_non_function (attr);
    1027              :     }
    1028          736 : }
    1029              : 
    1030              : void
    1031         1492 : AttributeChecker::visit (AST::StructStruct &struct_item)
    1032              : {
    1033         1961 :   for (auto &attr : struct_item.get_outer_attrs ())
    1034              :     {
    1035          469 :       check_valid_attribute_for_item (attr, struct_item);
    1036          469 :       check_attribute (attr);
    1037          469 :       check_proc_macro_non_function (attr);
    1038              :     }
    1039         1492 : }
    1040              : 
    1041              : void
    1042          963 : AttributeChecker::visit (AST::TupleStruct &tuplestruct)
    1043              : {
    1044          995 :   for (auto &attr : tuplestruct.get_outer_attrs ())
    1045              :     {
    1046           32 :       check_valid_attribute_for_item (attr, tuplestruct);
    1047           32 :       check_proc_macro_non_function (attr);
    1048              :     }
    1049          963 : }
    1050              : 
    1051              : void
    1052            0 : AttributeChecker::visit (AST::EnumItem &)
    1053            0 : {}
    1054              : 
    1055              : void
    1056            0 : AttributeChecker::visit (AST::EnumItemTuple &)
    1057            0 : {}
    1058              : 
    1059              : void
    1060            0 : AttributeChecker::visit (AST::EnumItemStruct &)
    1061            0 : {}
    1062              : 
    1063              : void
    1064            0 : AttributeChecker::visit (AST::EnumItemDiscriminant &)
    1065            0 : {}
    1066              : 
    1067              : void
    1068          544 : AttributeChecker::visit (AST::Enum &enumeration)
    1069              : {
    1070          697 :   for (auto &attr : enumeration.get_outer_attrs ())
    1071              :     {
    1072          153 :       check_valid_attribute_for_item (attr, enumeration);
    1073          153 :       check_proc_macro_non_function (attr);
    1074              :     }
    1075          544 : }
    1076              : 
    1077              : void
    1078          107 : AttributeChecker::visit (AST::Union &u)
    1079              : {
    1080          120 :   for (auto &attr : u.get_outer_attrs ())
    1081              :     {
    1082           13 :       check_valid_attribute_for_item (attr, u);
    1083           13 :       check_proc_macro_non_function (attr);
    1084              :     }
    1085          107 : }
    1086              : 
    1087              : void
    1088          524 : AttributeChecker::visit (AST::ConstantItem &item)
    1089              : {
    1090          527 :   for (auto &attr : item.get_outer_attrs ())
    1091              :     {
    1092            3 :       check_valid_attribute_for_item (attr, item);
    1093            3 :       check_proc_macro_non_function (attr);
    1094              :     }
    1095          524 : }
    1096              : 
    1097              : void
    1098           64 : AttributeChecker::visit (AST::StaticItem &item)
    1099              : {
    1100           64 :   BuiltinAttrDefinition result;
    1101           72 :   for (auto &attr : item.get_outer_attrs ())
    1102              :     {
    1103            8 :       check_valid_attribute_for_item (attr, item);
    1104            8 :       check_proc_macro_non_function (attr);
    1105            8 :       if (is_builtin (attr, result))
    1106              :         {
    1107            8 :           if (result.name == Attrs::LINK_SECTION)
    1108              :             {
    1109            1 :               check_link_section_attribute (attr);
    1110              :             }
    1111            7 :           else if (result.name == Attrs::EXPORT_NAME)
    1112              :             {
    1113            4 :               check_export_name_attribute (attr);
    1114              :             }
    1115              :         }
    1116              :     }
    1117           64 : }
    1118              : 
    1119              : void
    1120            0 : AttributeChecker::visit (AST::TraitItemType &)
    1121            0 : {}
    1122              : 
    1123              : void
    1124         3737 : AttributeChecker::visit (AST::Trait &trait)
    1125              : {
    1126         7466 :   for (auto &attr : trait.get_outer_attrs ())
    1127              :     {
    1128         3729 :       check_valid_attribute_for_item (attr, trait);
    1129         3729 :       check_proc_macro_non_function (attr);
    1130         3729 :       check_attribute (attr);
    1131              :     }
    1132         3737 : }
    1133              : 
    1134              : void
    1135          760 : AttributeChecker::visit (AST::InherentImpl &impl)
    1136              : {
    1137          906 :   for (auto &attr : impl.get_outer_attrs ())
    1138              :     {
    1139          146 :       check_valid_attribute_for_item (attr, impl);
    1140          146 :       check_proc_macro_non_function (attr);
    1141              :     }
    1142              : 
    1143          760 :   AST::DefaultASTVisitor::visit (impl);
    1144          760 : }
    1145              : 
    1146              : void
    1147         2010 : AttributeChecker::visit (AST::TraitImpl &impl)
    1148              : {
    1149         2018 :   for (auto &attr : impl.get_outer_attrs ())
    1150              :     {
    1151            8 :       check_valid_attribute_for_item (attr, impl);
    1152            8 :       check_proc_macro_non_function (attr);
    1153              :     }
    1154         2010 :   AST::DefaultASTVisitor::visit (impl);
    1155         2010 : }
    1156              : 
    1157              : void
    1158            0 : AttributeChecker::visit (AST::ExternalTypeItem &)
    1159            0 : {}
    1160              : 
    1161              : void
    1162            0 : AttributeChecker::visit (AST::ExternalStaticItem &)
    1163            0 : {}
    1164              : 
    1165              : void
    1166         1464 : AttributeChecker::visit (AST::ExternBlock &block)
    1167              : {
    1168         1468 :   for (auto &attr : block.get_outer_attrs ())
    1169              :     {
    1170            4 :       check_valid_attribute_for_item (attr, block);
    1171            4 :       check_proc_macro_non_function (attr);
    1172              :     }
    1173         1464 : }
    1174              : 
    1175              : // rust-macro.h
    1176              : void
    1177            0 : AttributeChecker::visit (AST::MacroMatchFragment &)
    1178            0 : {}
    1179              : 
    1180              : void
    1181            0 : AttributeChecker::visit (AST::MacroMatchRepetition &)
    1182            0 : {}
    1183              : 
    1184              : void
    1185            0 : AttributeChecker::visit (AST::MacroMatcher &)
    1186            0 : {}
    1187              : 
    1188              : void
    1189          962 : AttributeChecker::visit (AST::MacroRulesDefinition &)
    1190          962 : {}
    1191              : 
    1192              : void
    1193          710 : AttributeChecker::visit (AST::MacroInvocation &)
    1194          710 : {}
    1195              : 
    1196              : void
    1197            0 : AttributeChecker::visit (AST::MetaItemPath &)
    1198            0 : {}
    1199              : 
    1200              : void
    1201         7094 : AttributeChecker::visit (AST::MetaWord &)
    1202         7094 : {}
    1203              : 
    1204              : void
    1205         1699 : AttributeChecker::visit (AST::MetaNameValueStr &)
    1206         1699 : {}
    1207              : 
    1208              : void
    1209            0 : AttributeChecker::visit (AST::MetaListPaths &)
    1210            0 : {}
    1211              : 
    1212              : void
    1213            0 : AttributeChecker::visit (AST::MetaListNameValueStr &)
    1214            0 : {}
    1215              : 
    1216              : // rust-pattern.h
    1217              : void
    1218            0 : AttributeChecker::visit (AST::LiteralPattern &)
    1219            0 : {}
    1220              : 
    1221              : void
    1222            0 : AttributeChecker::visit (AST::IdentifierPattern &)
    1223            0 : {}
    1224              : 
    1225              : void
    1226            0 : AttributeChecker::visit (AST::WildcardPattern &)
    1227            0 : {}
    1228              : 
    1229              : void
    1230            0 : AttributeChecker::visit (AST::RestPattern &)
    1231            0 : {}
    1232              : 
    1233              : // void AttributeChecker::visit(RangePatternBound& ){}
    1234              : 
    1235              : void
    1236            0 : AttributeChecker::visit (AST::RangePatternBoundLiteral &)
    1237            0 : {}
    1238              : 
    1239              : void
    1240            0 : AttributeChecker::visit (AST::RangePatternBoundPath &)
    1241            0 : {}
    1242              : 
    1243              : void
    1244            0 : AttributeChecker::visit (AST::RangePatternBoundQualPath &)
    1245            0 : {}
    1246              : 
    1247              : void
    1248            0 : AttributeChecker::visit (AST::RangePattern &)
    1249            0 : {}
    1250              : 
    1251              : void
    1252            0 : AttributeChecker::visit (AST::ReferencePattern &)
    1253            0 : {}
    1254              : 
    1255              : // void AttributeChecker::visit(StructPatternField& ){}
    1256              : 
    1257              : void
    1258            0 : AttributeChecker::visit (AST::StructPatternFieldTuplePat &)
    1259            0 : {}
    1260              : 
    1261              : void
    1262            0 : AttributeChecker::visit (AST::StructPatternFieldIdentPat &)
    1263            0 : {}
    1264              : 
    1265              : void
    1266            0 : AttributeChecker::visit (AST::StructPatternFieldIdent &)
    1267            0 : {}
    1268              : 
    1269              : void
    1270            0 : AttributeChecker::visit (AST::StructPattern &)
    1271            0 : {}
    1272              : 
    1273              : // void AttributeChecker::visit(TupleStructItems& ){}
    1274              : 
    1275              : void
    1276            0 : AttributeChecker::visit (AST::TupleStructItemsNoRest &)
    1277            0 : {}
    1278              : 
    1279              : void
    1280            0 : AttributeChecker::visit (AST::TupleStructItemsHasRest &)
    1281            0 : {}
    1282              : 
    1283              : void
    1284            0 : AttributeChecker::visit (AST::TupleStructPattern &)
    1285            0 : {}
    1286              : 
    1287              : // void AttributeChecker::visit(TuplePatternItems& ){}
    1288              : 
    1289              : void
    1290            0 : AttributeChecker::visit (AST::TuplePatternItemsNoRest &)
    1291            0 : {}
    1292              : 
    1293              : void
    1294            0 : AttributeChecker::visit (AST::TuplePatternItemsHasRest &)
    1295            0 : {}
    1296              : 
    1297              : void
    1298            0 : AttributeChecker::visit (AST::TuplePattern &)
    1299            0 : {}
    1300              : 
    1301              : void
    1302            0 : AttributeChecker::visit (AST::GroupedPattern &)
    1303            0 : {}
    1304              : 
    1305              : void
    1306            0 : AttributeChecker::visit (AST::SlicePattern &)
    1307            0 : {}
    1308              : 
    1309              : void
    1310            0 : AttributeChecker::visit (AST::AltPattern &)
    1311            0 : {}
    1312              : 
    1313              : // rust-stmt.h
    1314              : void
    1315           18 : AttributeChecker::visit (AST::EmptyStmt &)
    1316           18 : {}
    1317              : 
    1318              : void
    1319         9571 : AttributeChecker::visit (AST::LetStmt &)
    1320         9571 : {}
    1321              : 
    1322              : void
    1323         5353 : AttributeChecker::visit (AST::ExprStmt &)
    1324         5353 : {}
    1325              : 
    1326              : // rust-type.h
    1327              : void
    1328            0 : AttributeChecker::visit (AST::TraitBound &)
    1329            0 : {}
    1330              : 
    1331              : void
    1332            0 : AttributeChecker::visit (AST::ImplTraitType &)
    1333            0 : {}
    1334              : 
    1335              : void
    1336            4 : AttributeChecker::visit (AST::TraitObjectType &)
    1337            4 : {}
    1338              : 
    1339              : void
    1340            2 : AttributeChecker::visit (AST::ParenthesisedType &)
    1341            2 : {}
    1342              : 
    1343              : void
    1344            0 : AttributeChecker::visit (AST::ImplTraitTypeOneBound &)
    1345            0 : {}
    1346              : 
    1347              : void
    1348            7 : AttributeChecker::visit (AST::TraitObjectTypeOneBound &)
    1349            7 : {}
    1350              : 
    1351              : void
    1352            2 : AttributeChecker::visit (AST::TupleType &)
    1353            2 : {}
    1354              : 
    1355              : void
    1356            2 : AttributeChecker::visit (AST::NeverType &)
    1357            2 : {}
    1358              : 
    1359              : void
    1360          164 : AttributeChecker::visit (AST::RawPointerType &)
    1361          164 : {}
    1362              : 
    1363              : void
    1364          166 : AttributeChecker::visit (AST::ReferenceType &)
    1365          166 : {}
    1366              : 
    1367              : void
    1368            0 : AttributeChecker::visit (AST::ArrayType &)
    1369            0 : {}
    1370              : 
    1371              : void
    1372           66 : AttributeChecker::visit (AST::SliceType &)
    1373           66 : {}
    1374              : 
    1375              : void
    1376            0 : AttributeChecker::visit (AST::InferredType &)
    1377            0 : {}
    1378              : 
    1379              : void
    1380            1 : AttributeChecker::visit (AST::BareFunctionType &)
    1381            1 : {}
    1382              : 
    1383              : void
    1384            0 : AttributeChecker::visit (AST::SelfParam &)
    1385            0 : {}
    1386              : 
    1387              : void
    1388            0 : AttributeChecker::visit (AST::VariadicParam &)
    1389            0 : {}
    1390              : 
    1391              : void
    1392            0 : AttributeChecker::visit (AST::FunctionParam &)
    1393            0 : {}
    1394              : 
    1395              : } // namespace Analysis
    1396              : } // namespace Rust
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.