Branch data Line data Source code
1 : : // Copyright (C) 2020-2024 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 : : using Attrs = Values::Attributes;
33 : :
34 : : // https://doc.rust-lang.org/stable/nightly-rustc/src/rustc_feature/builtin_attrs.rs.html#248
35 : : static const BuiltinAttrDefinition __definitions[]
36 : : = {{Attrs::INLINE, CODE_GENERATION},
37 : : {Attrs::COLD, CODE_GENERATION},
38 : : {Attrs::CFG, EXPANSION},
39 : : {Attrs::CFG_ATTR, EXPANSION},
40 : : {Attrs::DEPRECATED, STATIC_ANALYSIS},
41 : : {Attrs::ALLOW, STATIC_ANALYSIS},
42 : : {Attrs::ALLOW_INTERNAL_UNSTABLE, STATIC_ANALYSIS},
43 : : {Attrs::DOC, HIR_LOWERING},
44 : : {Attrs::MUST_USE, STATIC_ANALYSIS},
45 : : {Attrs::LANG, HIR_LOWERING},
46 : : {Attrs::LINK_SECTION, CODE_GENERATION},
47 : : {Attrs::NO_MANGLE, CODE_GENERATION},
48 : : {Attrs::REPR, CODE_GENERATION},
49 : : {Attrs::RUSTC_BUILTIN_MACRO, EXPANSION},
50 : : {Attrs::PATH, EXPANSION},
51 : : {Attrs::MACRO_USE, NAME_RESOLUTION},
52 : : {Attrs::MACRO_EXPORT, NAME_RESOLUTION},
53 : : {Attrs::PROC_MACRO, EXPANSION},
54 : : {Attrs::PROC_MACRO_DERIVE, EXPANSION},
55 : : {Attrs::PROC_MACRO_ATTRIBUTE, EXPANSION},
56 : : // FIXME: This is not implemented yet, see
57 : : // https://github.com/Rust-GCC/gccrs/issues/1475
58 : : {Attrs::TARGET_FEATURE, CODE_GENERATION},
59 : : // From now on, these are reserved by the compiler and gated through
60 : : // #![feature(rustc_attrs)]
61 : : {Attrs::RUSTC_INHERIT_OVERFLOW_CHECKS, CODE_GENERATION},
62 : : {Attrs::STABLE, STATIC_ANALYSIS}};
63 : :
64 : : BuiltinAttributeMappings *
65 : 224304 : BuiltinAttributeMappings::get ()
66 : : {
67 : 224304 : static BuiltinAttributeMappings *instance = nullptr;
68 : 224304 : if (instance == nullptr)
69 : 3514 : instance = new BuiltinAttributeMappings ();
70 : :
71 : 224304 : return instance;
72 : : }
73 : :
74 : : const BuiltinAttrDefinition &
75 : 8198 : BuiltinAttributeMappings::lookup_builtin (const std::string &attr_name) const
76 : : {
77 : 8198 : auto it = mappings.find (attr_name);
78 : 8198 : if (it == mappings.end ())
79 : 413 : return BuiltinAttrDefinition::error_node ();
80 : :
81 : 7785 : return it->second;
82 : : }
83 : :
84 : 3514 : BuiltinAttributeMappings::BuiltinAttributeMappings ()
85 : : {
86 : 3514 : size_t ndefinitions = sizeof (__definitions) / sizeof (BuiltinAttrDefinition);
87 : 84336 : for (size_t i = 0; i < ndefinitions; i++)
88 : : {
89 : 80822 : const BuiltinAttrDefinition &def = __definitions[i];
90 : 161644 : mappings.insert ({def.name, def});
91 : : }
92 : 3514 : }
93 : :
94 : 3600 : AttributeChecker::AttributeChecker () {}
95 : :
96 : : void
97 : 3600 : AttributeChecker::go (AST::Crate &crate)
98 : : {
99 : 3600 : visit (crate);
100 : 3600 : }
101 : :
102 : : void
103 : 3600 : AttributeChecker::visit (AST::Crate &crate)
104 : : {
105 : 3600 : check_attributes (crate.get_inner_attrs ());
106 : :
107 : 16426 : for (auto &item : crate.items)
108 : 12826 : item->accept_vis (*this);
109 : 3600 : }
110 : :
111 : : static bool
112 : 2957 : is_builtin (const AST::Attribute &attribute, BuiltinAttrDefinition &builtin)
113 : : {
114 : 2957 : auto &segments = attribute.get_path ().get_segments ();
115 : :
116 : : // Builtin attributes always have a single segment. This avoids us creating
117 : : // strings all over the place and performing a linear search in the builtins
118 : : // map
119 : 2957 : if (segments.size () != 1)
120 : : return false;
121 : :
122 : 2957 : builtin = BuiltinAttributeMappings::get ()->lookup_builtin (
123 : 2957 : segments.at (0).get_segment_name ());
124 : :
125 : 2957 : return !builtin.is_error ();
126 : : }
127 : :
128 : : /**
129 : : * Check that the string given to #[doc(alias = ...)] or #[doc(alias(...))] is
130 : : * valid.
131 : : *
132 : : * This means no whitespace characters other than spaces and no quoting
133 : : * characters.
134 : : */
135 : : static void
136 : 14 : check_doc_alias (const std::string &alias_input, const location_t locus)
137 : : {
138 : : // FIXME: The locus here is for the whole attribute. Can we get the locus
139 : : // of the alias input instead?
140 : 42 : for (auto c : alias_input)
141 : 28 : if ((ISSPACE (c) && c != ' ') || c == '\'' || c == '\"')
142 : : {
143 : 7 : auto to_print = std::string (1, c);
144 : 7 : switch (c)
145 : : {
146 : 7 : case '\n':
147 : 7 : to_print = "\\n";
148 : 7 : break;
149 : 0 : case '\t':
150 : 0 : to_print = "\\t";
151 : 0 : break;
152 : : default:
153 : : break;
154 : : }
155 : 7 : rust_error_at (locus,
156 : : "invalid character used in %<#[doc(alias)]%> input: %qs",
157 : : to_print.c_str ());
158 : 7 : }
159 : :
160 : 14 : if (alias_input.empty ())
161 : : return;
162 : :
163 : 14 : if (alias_input.front () == ' ' || alias_input.back () == ' ')
164 : 0 : rust_error_at (locus,
165 : : "%<#[doc(alias)]%> input cannot start or end with a space");
166 : : }
167 : :
168 : : static void
169 : 99 : check_doc_attribute (const AST::Attribute &attribute)
170 : : {
171 : 99 : if (!attribute.has_attr_input ())
172 : : {
173 : 0 : rust_error_at (
174 : : attribute.get_locus (),
175 : : // FIXME: Improve error message here. Rustc has a very good one
176 : : "%<#[doc]%> cannot be an empty attribute");
177 : 0 : return;
178 : : }
179 : :
180 : 99 : switch (attribute.get_attr_input ().get_attr_input_type ())
181 : : {
182 : : case AST::AttrInput::LITERAL:
183 : : case AST::AttrInput::MACRO:
184 : : case AST::AttrInput::META_ITEM:
185 : : break;
186 : : // FIXME: Handle them as well
187 : :
188 : 49 : case AST::AttrInput::TOKEN_TREE: {
189 : : // FIXME: This doesn't check for #[doc(alias(...))]
190 : 49 : const auto &option = static_cast<const AST::DelimTokenTree &> (
191 : 49 : attribute.get_attr_input ());
192 : 49 : auto *meta_item = option.parse_to_meta_item ();
193 : :
194 : 105 : for (auto &item : meta_item->get_items ())
195 : : {
196 : 56 : if (item->is_key_value_pair ())
197 : : {
198 : 21 : auto name_value
199 : 21 : = static_cast<AST::MetaNameValueStr *> (item.get ())
200 : 21 : ->get_name_value_pair ();
201 : :
202 : : // FIXME: Check for other stuff than #[doc(alias = ...)]
203 : 21 : if (name_value.first.as_string () == "alias")
204 : 14 : check_doc_alias (name_value.second, attribute.get_locus ());
205 : 21 : }
206 : : }
207 : : break;
208 : : }
209 : : }
210 : : }
211 : :
212 : : static bool
213 : 2165 : is_proc_macro_type (const AST::Attribute &attribute)
214 : : {
215 : 2165 : BuiltinAttrDefinition result;
216 : 2165 : if (!is_builtin (attribute, result))
217 : : return false;
218 : :
219 : 2140 : auto name = result.name;
220 : 2122 : return name == Attrs::PROC_MACRO || name == Attrs::PROC_MACRO_DERIVE
221 : 4262 : || name == Attrs::PROC_MACRO_ATTRIBUTE;
222 : 2140 : }
223 : :
224 : : // Emit an error when one encountered attribute is either #[proc_macro],
225 : : // #[proc_macro_attribute] or #[proc_macro_derive]
226 : : static void
227 : 8500 : check_proc_macro_non_function (const AST::AttrVec &attributes)
228 : : {
229 : 10539 : for (auto &attr : attributes)
230 : : {
231 : 2039 : if (is_proc_macro_type (attr))
232 : 45 : rust_error_at (
233 : : attr.get_locus (),
234 : : "the %<#[%s]%> attribute may only be used on bare functions",
235 : 90 : attr.get_path ().get_segments ()[0].as_string ().c_str ());
236 : : }
237 : 8500 : }
238 : :
239 : : // Emit an error when one attribute is either proc_macro, proc_macro_attribute
240 : : // or proc_macro_derive
241 : : static void
242 : 1366 : check_proc_macro_non_root (AST::AttrVec attributes, location_t loc)
243 : : {
244 : 1492 : for (auto &attr : attributes)
245 : : {
246 : 126 : if (is_proc_macro_type (attr))
247 : : {
248 : 18 : rust_error_at (
249 : : loc,
250 : : "functions tagged with %<#[%s]%> must currently "
251 : : "reside in the root of the crate",
252 : 18 : attr.get_path ().get_segments ().at (0).as_string ().c_str ());
253 : : }
254 : : }
255 : 1366 : }
256 : :
257 : : void
258 : 669 : AttributeChecker::check_attribute (const AST::Attribute &attribute)
259 : : {
260 : 669 : BuiltinAttrDefinition result;
261 : :
262 : : // This checker does not check non-builtin attributes
263 : 669 : if (!is_builtin (attribute, result))
264 : 386 : return;
265 : :
266 : : // TODO: Add checks here for each builtin attribute
267 : : // TODO: Have an enum of builtins as well, switching on strings is annoying
268 : : // and costly
269 : 283 : if (result.name == Attrs::DOC)
270 : 99 : check_doc_attribute (attribute);
271 : 669 : }
272 : :
273 : : void
274 : 4531 : AttributeChecker::check_attributes (const AST::AttrVec &attributes)
275 : : {
276 : 5200 : for (auto &attr : attributes)
277 : 669 : check_attribute (attr);
278 : 4531 : }
279 : :
280 : : void
281 : 0 : AttributeChecker::visit (AST::Token &)
282 : 0 : {}
283 : :
284 : : void
285 : 0 : AttributeChecker::visit (AST::DelimTokenTree &)
286 : 0 : {}
287 : :
288 : : void
289 : 0 : AttributeChecker::visit (AST::AttrInputMetaItemContainer &)
290 : 0 : {}
291 : :
292 : : void
293 : 304 : AttributeChecker::visit (AST::IdentifierExpr &)
294 : 304 : {}
295 : :
296 : : void
297 : 0 : AttributeChecker::visit (AST::Lifetime &)
298 : 0 : {}
299 : :
300 : : void
301 : 22 : AttributeChecker::visit (AST::LifetimeParam &)
302 : 22 : {}
303 : :
304 : : void
305 : 2 : AttributeChecker::visit (AST::ConstGenericParam &)
306 : 2 : {}
307 : :
308 : : // rust-path.h
309 : : void
310 : 13 : AttributeChecker::visit (AST::PathInExpression &)
311 : 13 : {}
312 : :
313 : : void
314 : 0 : AttributeChecker::visit (AST::TypePathSegment &)
315 : 0 : {}
316 : :
317 : : void
318 : 0 : AttributeChecker::visit (AST::TypePathSegmentGeneric &)
319 : 0 : {}
320 : :
321 : : void
322 : 0 : AttributeChecker::visit (AST::TypePathSegmentFunction &)
323 : 0 : {}
324 : :
325 : : void
326 : 1182 : AttributeChecker::visit (AST::TypePath &)
327 : 1182 : {}
328 : :
329 : : void
330 : 0 : AttributeChecker::visit (AST::QualifiedPathInExpression &)
331 : 0 : {}
332 : :
333 : : void
334 : 0 : AttributeChecker::visit (AST::QualifiedPathInType &)
335 : 0 : {}
336 : :
337 : : // rust-expr.h
338 : : void
339 : 1063 : AttributeChecker::visit (AST::LiteralExpr &)
340 : 1063 : {}
341 : :
342 : : void
343 : 0 : AttributeChecker::visit (AST::AttrInputLiteral &)
344 : 0 : {}
345 : :
346 : : void
347 : 0 : AttributeChecker::visit (AST::AttrInputMacro &)
348 : 0 : {}
349 : :
350 : : void
351 : 0 : AttributeChecker::visit (AST::MetaItemLitExpr &)
352 : 0 : {}
353 : :
354 : : void
355 : 0 : AttributeChecker::visit (AST::MetaItemPathLit &)
356 : 0 : {}
357 : :
358 : : void
359 : 135 : AttributeChecker::visit (AST::BorrowExpr &)
360 : 135 : {}
361 : :
362 : : void
363 : 202 : AttributeChecker::visit (AST::DereferenceExpr &)
364 : 202 : {}
365 : :
366 : : void
367 : 0 : AttributeChecker::visit (AST::ErrorPropagationExpr &)
368 : 0 : {}
369 : :
370 : : void
371 : 14 : AttributeChecker::visit (AST::NegationExpr &)
372 : 14 : {}
373 : :
374 : : void
375 : 582 : AttributeChecker::visit (AST::ArithmeticOrLogicalExpr &)
376 : 582 : {}
377 : :
378 : : void
379 : 52 : AttributeChecker::visit (AST::ComparisonExpr &)
380 : 52 : {}
381 : :
382 : : void
383 : 0 : AttributeChecker::visit (AST::LazyBooleanExpr &)
384 : 0 : {}
385 : :
386 : : void
387 : 125 : AttributeChecker::visit (AST::TypeCastExpr &)
388 : 125 : {}
389 : :
390 : : void
391 : 1 : AttributeChecker::visit (AST::AssignmentExpr &)
392 : 1 : {}
393 : :
394 : : void
395 : 7 : AttributeChecker::visit (AST::CompoundAssignmentExpr &)
396 : 7 : {}
397 : :
398 : : void
399 : 8 : AttributeChecker::visit (AST::GroupedExpr &)
400 : 8 : {}
401 : :
402 : : void
403 : 0 : AttributeChecker::visit (AST::ArrayElemsValues &)
404 : 0 : {}
405 : :
406 : : void
407 : 0 : AttributeChecker::visit (AST::ArrayElemsCopied &)
408 : 0 : {}
409 : :
410 : : void
411 : 14 : AttributeChecker::visit (AST::ArrayExpr &)
412 : 14 : {}
413 : :
414 : : void
415 : 0 : AttributeChecker::visit (AST::ArrayIndexExpr &)
416 : 0 : {}
417 : :
418 : : void
419 : 50 : AttributeChecker::visit (AST::TupleExpr &)
420 : 50 : {}
421 : :
422 : : void
423 : 117 : AttributeChecker::visit (AST::TupleIndexExpr &)
424 : 117 : {}
425 : :
426 : : void
427 : 7 : AttributeChecker::visit (AST::StructExprStruct &)
428 : 7 : {}
429 : :
430 : : void
431 : 0 : AttributeChecker::visit (AST::StructExprFieldIdentifier &)
432 : 0 : {}
433 : :
434 : : void
435 : 0 : AttributeChecker::visit (AST::StructExprFieldIdentifierValue &)
436 : 0 : {}
437 : :
438 : : void
439 : 0 : AttributeChecker::visit (AST::StructExprFieldIndexValue &)
440 : 0 : {}
441 : :
442 : : void
443 : 140 : AttributeChecker::visit (AST::StructExprStructFields &)
444 : 140 : {}
445 : :
446 : : void
447 : 0 : AttributeChecker::visit (AST::StructExprStructBase &)
448 : 0 : {}
449 : :
450 : : void
451 : 453 : AttributeChecker::visit (AST::CallExpr &)
452 : 453 : {}
453 : :
454 : : void
455 : 167 : AttributeChecker::visit (AST::MethodCallExpr &)
456 : 167 : {}
457 : :
458 : : void
459 : 160 : AttributeChecker::visit (AST::FieldAccessExpr &)
460 : 160 : {}
461 : :
462 : : void
463 : 0 : AttributeChecker::visit (AST::ClosureExprInner &)
464 : 0 : {}
465 : :
466 : : void
467 : 7842 : AttributeChecker::visit (AST::BlockExpr &expr)
468 : : {
469 : 19910 : for (auto &stmt : expr.get_statements ())
470 : : {
471 : 12068 : if (stmt->get_stmt_kind () == AST::Stmt::Kind::Item)
472 : : {
473 : : // Non owning pointer, let it go out of scope
474 : 526 : auto item = static_cast<AST::Item *> (stmt.get ());
475 : 526 : check_proc_macro_non_root (item->get_outer_attrs (),
476 : 526 : item->get_locus ());
477 : : }
478 : : }
479 : 7842 : AST::DefaultASTVisitor::visit (expr);
480 : 7842 : }
481 : :
482 : : void
483 : 0 : AttributeChecker::visit (AST::ClosureExprInnerTyped &)
484 : 0 : {}
485 : :
486 : : void
487 : 0 : AttributeChecker::visit (AST::ContinueExpr &)
488 : 0 : {}
489 : :
490 : : void
491 : 0 : AttributeChecker::visit (AST::BreakExpr &)
492 : 0 : {}
493 : :
494 : : void
495 : 0 : AttributeChecker::visit (AST::RangeFromToExpr &)
496 : 0 : {}
497 : :
498 : : void
499 : 0 : AttributeChecker::visit (AST::RangeFromExpr &)
500 : 0 : {}
501 : :
502 : : void
503 : 0 : AttributeChecker::visit (AST::RangeToExpr &)
504 : 0 : {}
505 : :
506 : : void
507 : 0 : AttributeChecker::visit (AST::RangeFullExpr &)
508 : 0 : {}
509 : :
510 : : void
511 : 0 : AttributeChecker::visit (AST::RangeFromToInclExpr &)
512 : 0 : {}
513 : :
514 : : void
515 : 0 : AttributeChecker::visit (AST::RangeToInclExpr &)
516 : 0 : {}
517 : :
518 : : void
519 : 0 : AttributeChecker::visit (AST::ReturnExpr &)
520 : 0 : {}
521 : :
522 : : void
523 : 39 : AttributeChecker::visit (AST::LoopExpr &)
524 : 39 : {}
525 : :
526 : : void
527 : 16 : AttributeChecker::visit (AST::WhileLoopExpr &)
528 : 16 : {}
529 : :
530 : : void
531 : 0 : AttributeChecker::visit (AST::WhileLetLoopExpr &)
532 : 0 : {}
533 : :
534 : : void
535 : 0 : AttributeChecker::visit (AST::ForLoopExpr &)
536 : 0 : {}
537 : :
538 : : void
539 : 46 : AttributeChecker::visit (AST::IfExpr &)
540 : 46 : {}
541 : :
542 : : void
543 : 168 : AttributeChecker::visit (AST::IfExprConseqElse &)
544 : 168 : {}
545 : :
546 : : void
547 : 0 : AttributeChecker::visit (AST::IfLetExpr &)
548 : 0 : {}
549 : :
550 : : void
551 : 0 : AttributeChecker::visit (AST::IfLetExprConseqElse &)
552 : 0 : {}
553 : :
554 : : void
555 : 120 : AttributeChecker::visit (AST::MatchExpr &)
556 : 120 : {}
557 : :
558 : : void
559 : 0 : AttributeChecker::visit (AST::AwaitExpr &)
560 : 0 : {}
561 : :
562 : : void
563 : 0 : AttributeChecker::visit (AST::AsyncBlockExpr &)
564 : 0 : {}
565 : :
566 : : // rust-item.h
567 : : void
568 : 706 : AttributeChecker::visit (AST::TypeParam &)
569 : 706 : {}
570 : :
571 : : void
572 : 0 : AttributeChecker::visit (AST::LifetimeWhereClauseItem &)
573 : 0 : {}
574 : :
575 : : void
576 : 61 : AttributeChecker::visit (AST::TypeBoundWhereClauseItem &)
577 : 61 : {}
578 : :
579 : : void
580 : 600 : AttributeChecker::visit (AST::Module &module)
581 : : {
582 : 600 : check_proc_macro_non_function (module.get_outer_attrs ());
583 : 1440 : for (auto &item : module.get_items ())
584 : : {
585 : 840 : check_proc_macro_non_root (item->get_outer_attrs (), item->get_locus ());
586 : : }
587 : 600 : AST::DefaultASTVisitor::visit (module);
588 : 600 : }
589 : :
590 : : void
591 : 27 : AttributeChecker::visit (AST::ExternCrate &crate)
592 : : {
593 : 27 : check_proc_macro_non_function (crate.get_outer_attrs ());
594 : 27 : }
595 : :
596 : : void
597 : 0 : AttributeChecker::visit (AST::UseTreeGlob &)
598 : 0 : {}
599 : :
600 : : void
601 : 0 : AttributeChecker::visit (AST::UseTreeList &)
602 : 0 : {}
603 : :
604 : : void
605 : 0 : AttributeChecker::visit (AST::UseTreeRebind &)
606 : 0 : {}
607 : :
608 : : void
609 : 144 : AttributeChecker::visit (AST::UseDeclaration &declaration)
610 : : {
611 : 144 : check_proc_macro_non_function (declaration.get_outer_attrs ());
612 : 144 : }
613 : :
614 : : static void
615 : 1 : check_no_mangle_function (const AST::Attribute &attribute,
616 : : const AST::Function &fun)
617 : : {
618 : 1 : if (attribute.has_attr_input ())
619 : : {
620 : 0 : rust_error_at (attribute.get_locus (), ErrorCode::E0754,
621 : : "malformed %<no_mangle%> attribute input");
622 : 0 : rust_inform (attribute.get_locus (),
623 : : "must be of the form: %<#[no_mangle]%>");
624 : : }
625 : 1 : if (!is_ascii_only (fun.get_function_name ().as_string ()))
626 : 0 : rust_error_at (fun.get_function_name ().get_locus (),
627 : : "the %<#[no_mangle]%> attribute requires ASCII identifier");
628 : 1 : }
629 : :
630 : : void
631 : 7004 : AttributeChecker::visit (AST::Function &fun)
632 : : {
633 : 7020 : auto check_crate_type = [] (const char *name, AST::Attribute &attribute) {
634 : 16 : if (!Session::get_instance ().options.is_proc_macro ())
635 : 3 : rust_error_at (attribute.get_locus (),
636 : : "the %<#[%s]%> attribute is only usable with crates of "
637 : : "the %<proc-macro%> crate type",
638 : : name);
639 : 16 : };
640 : :
641 : 7004 : BuiltinAttrDefinition result;
642 : 7126 : for (auto &attribute : fun.get_outer_attrs ())
643 : : {
644 : 123 : if (!is_builtin (attribute, result))
645 : 1 : return;
646 : :
647 : 122 : auto name = result.name.c_str ();
648 : :
649 : 122 : if (result.name == Attrs::PROC_MACRO_DERIVE)
650 : : {
651 : 6 : if (!attribute.has_attr_input ())
652 : : {
653 : 1 : rust_error_at (attribute.get_locus (),
654 : : "malformed %<%s%> attribute input", name);
655 : 1 : rust_inform (
656 : : attribute.get_locus (),
657 : : "must be of the form: %<#[proc_macro_derive(TraitName, "
658 : : "/*opt*/ attributes(name1, name2, ...))]%>");
659 : : }
660 : 6 : check_crate_type (name, attribute);
661 : : }
662 : 116 : else if (result.name == Attrs::PROC_MACRO
663 : 116 : || result.name == Attrs::PROC_MACRO_ATTRIBUTE)
664 : : {
665 : 10 : check_crate_type (name, attribute);
666 : : }
667 : 106 : else if (result.name == "no_mangle")
668 : 1 : check_no_mangle_function (attribute, fun);
669 : : }
670 : 7003 : if (fun.has_body ())
671 : 6996 : fun.get_definition ().value ()->accept_vis (*this);
672 : 7004 : }
673 : :
674 : : void
675 : 596 : AttributeChecker::visit (AST::TypeAlias &alias)
676 : : {
677 : 596 : check_proc_macro_non_function (alias.get_outer_attrs ());
678 : 596 : }
679 : :
680 : : void
681 : 931 : AttributeChecker::visit (AST::StructStruct &struct_item)
682 : : {
683 : 931 : check_attributes (struct_item.get_outer_attrs ());
684 : 931 : check_proc_macro_non_function (struct_item.get_outer_attrs ());
685 : 931 : }
686 : :
687 : : void
688 : 767 : AttributeChecker::visit (AST::TupleStruct &tuplestruct)
689 : : {
690 : 767 : check_proc_macro_non_function (tuplestruct.get_outer_attrs ());
691 : 767 : }
692 : :
693 : : void
694 : 0 : AttributeChecker::visit (AST::EnumItem &)
695 : 0 : {}
696 : :
697 : : void
698 : 0 : AttributeChecker::visit (AST::EnumItemTuple &)
699 : 0 : {}
700 : :
701 : : void
702 : 0 : AttributeChecker::visit (AST::EnumItemStruct &)
703 : 0 : {}
704 : :
705 : : void
706 : 0 : AttributeChecker::visit (AST::EnumItemDiscriminant &)
707 : 0 : {}
708 : :
709 : : void
710 : 187 : AttributeChecker::visit (AST::Enum &enumeration)
711 : : {
712 : 187 : check_proc_macro_non_function (enumeration.get_outer_attrs ());
713 : 187 : }
714 : :
715 : : void
716 : 97 : AttributeChecker::visit (AST::Union &u)
717 : : {
718 : 97 : check_proc_macro_non_function (u.get_outer_attrs ());
719 : 97 : }
720 : :
721 : : void
722 : 460 : AttributeChecker::visit (AST::ConstantItem &item)
723 : : {
724 : 460 : check_proc_macro_non_function (item.get_outer_attrs ());
725 : 460 : }
726 : :
727 : : void
728 : 44 : AttributeChecker::visit (AST::StaticItem &item)
729 : : {
730 : 44 : check_proc_macro_non_function (item.get_outer_attrs ());
731 : 44 : }
732 : :
733 : : void
734 : 0 : AttributeChecker::visit (AST::TraitItemConst &)
735 : 0 : {}
736 : :
737 : : void
738 : 0 : AttributeChecker::visit (AST::TraitItemType &)
739 : 0 : {}
740 : :
741 : : void
742 : 2107 : AttributeChecker::visit (AST::Trait &trait)
743 : : {
744 : 2107 : check_proc_macro_non_function (trait.get_outer_attrs ());
745 : 2107 : }
746 : :
747 : : void
748 : 620 : AttributeChecker::visit (AST::InherentImpl &impl)
749 : : {
750 : 620 : check_proc_macro_non_function (impl.get_outer_attrs ());
751 : 620 : AST::DefaultASTVisitor::visit (impl);
752 : 620 : }
753 : :
754 : : void
755 : 903 : AttributeChecker::visit (AST::TraitImpl &impl)
756 : : {
757 : 903 : check_proc_macro_non_function (impl.get_outer_attrs ());
758 : 903 : AST::DefaultASTVisitor::visit (impl);
759 : 903 : }
760 : :
761 : : void
762 : 0 : AttributeChecker::visit (AST::ExternalTypeItem &)
763 : 0 : {}
764 : :
765 : : void
766 : 0 : AttributeChecker::visit (AST::ExternalStaticItem &)
767 : 0 : {}
768 : :
769 : : void
770 : 0 : AttributeChecker::visit (AST::ExternalFunctionItem &)
771 : 0 : {}
772 : :
773 : : void
774 : 1017 : AttributeChecker::visit (AST::ExternBlock &block)
775 : : {
776 : 1017 : check_proc_macro_non_function (block.get_outer_attrs ());
777 : 1017 : }
778 : :
779 : : // rust-macro.h
780 : : void
781 : 0 : AttributeChecker::visit (AST::MacroMatchFragment &)
782 : 0 : {}
783 : :
784 : : void
785 : 0 : AttributeChecker::visit (AST::MacroMatchRepetition &)
786 : 0 : {}
787 : :
788 : : void
789 : 0 : AttributeChecker::visit (AST::MacroMatcher &)
790 : 0 : {}
791 : :
792 : : void
793 : 675 : AttributeChecker::visit (AST::MacroRulesDefinition &)
794 : 675 : {}
795 : :
796 : : void
797 : 482 : AttributeChecker::visit (AST::MacroInvocation &)
798 : 482 : {}
799 : :
800 : : void
801 : 0 : AttributeChecker::visit (AST::MetaItemPath &)
802 : 0 : {}
803 : :
804 : : void
805 : 0 : AttributeChecker::visit (AST::MetaItemSeq &)
806 : 0 : {}
807 : :
808 : : void
809 : 0 : AttributeChecker::visit (AST::MetaWord &)
810 : 0 : {}
811 : :
812 : : void
813 : 0 : AttributeChecker::visit (AST::MetaNameValueStr &)
814 : 0 : {}
815 : :
816 : : void
817 : 0 : AttributeChecker::visit (AST::MetaListPaths &)
818 : 0 : {}
819 : :
820 : : void
821 : 0 : AttributeChecker::visit (AST::MetaListNameValueStr &)
822 : 0 : {}
823 : :
824 : : // rust-pattern.h
825 : : void
826 : 0 : AttributeChecker::visit (AST::LiteralPattern &)
827 : 0 : {}
828 : :
829 : : void
830 : 0 : AttributeChecker::visit (AST::IdentifierPattern &)
831 : 0 : {}
832 : :
833 : : void
834 : 0 : AttributeChecker::visit (AST::WildcardPattern &)
835 : 0 : {}
836 : :
837 : : void
838 : 0 : AttributeChecker::visit (AST::RestPattern &)
839 : 0 : {}
840 : :
841 : : // void AttributeChecker::visit(RangePatternBound& ){}
842 : :
843 : : void
844 : 0 : AttributeChecker::visit (AST::RangePatternBoundLiteral &)
845 : 0 : {}
846 : :
847 : : void
848 : 0 : AttributeChecker::visit (AST::RangePatternBoundPath &)
849 : 0 : {}
850 : :
851 : : void
852 : 0 : AttributeChecker::visit (AST::RangePatternBoundQualPath &)
853 : 0 : {}
854 : :
855 : : void
856 : 0 : AttributeChecker::visit (AST::RangePattern &)
857 : 0 : {}
858 : :
859 : : void
860 : 0 : AttributeChecker::visit (AST::ReferencePattern &)
861 : 0 : {}
862 : :
863 : : // void AttributeChecker::visit(StructPatternField& ){}
864 : :
865 : : void
866 : 0 : AttributeChecker::visit (AST::StructPatternFieldTuplePat &)
867 : 0 : {}
868 : :
869 : : void
870 : 0 : AttributeChecker::visit (AST::StructPatternFieldIdentPat &)
871 : 0 : {}
872 : :
873 : : void
874 : 0 : AttributeChecker::visit (AST::StructPatternFieldIdent &)
875 : 0 : {}
876 : :
877 : : void
878 : 0 : AttributeChecker::visit (AST::StructPattern &)
879 : 0 : {}
880 : :
881 : : // void AttributeChecker::visit(TupleStructItems& ){}
882 : :
883 : : void
884 : 0 : AttributeChecker::visit (AST::TupleStructItemsNoRange &)
885 : 0 : {}
886 : :
887 : : void
888 : 0 : AttributeChecker::visit (AST::TupleStructItemsRange &)
889 : 0 : {}
890 : :
891 : : void
892 : 0 : AttributeChecker::visit (AST::TupleStructPattern &)
893 : 0 : {}
894 : :
895 : : // void AttributeChecker::visit(TuplePatternItems& ){}
896 : :
897 : : void
898 : 0 : AttributeChecker::visit (AST::TuplePatternItemsMultiple &)
899 : 0 : {}
900 : :
901 : : void
902 : 0 : AttributeChecker::visit (AST::TuplePatternItemsRanged &)
903 : 0 : {}
904 : :
905 : : void
906 : 0 : AttributeChecker::visit (AST::TuplePattern &)
907 : 0 : {}
908 : :
909 : : void
910 : 0 : AttributeChecker::visit (AST::GroupedPattern &)
911 : 0 : {}
912 : :
913 : : void
914 : 0 : AttributeChecker::visit (AST::SlicePattern &)
915 : 0 : {}
916 : :
917 : : void
918 : 0 : AttributeChecker::visit (AST::AltPattern &)
919 : 0 : {}
920 : :
921 : : // rust-stmt.h
922 : : void
923 : 17 : AttributeChecker::visit (AST::EmptyStmt &)
924 : 17 : {}
925 : :
926 : : void
927 : 7522 : AttributeChecker::visit (AST::LetStmt &)
928 : 7522 : {}
929 : :
930 : : void
931 : 4003 : AttributeChecker::visit (AST::ExprStmt &)
932 : 4003 : {}
933 : :
934 : : // rust-type.h
935 : : void
936 : 0 : AttributeChecker::visit (AST::TraitBound &)
937 : 0 : {}
938 : :
939 : : void
940 : 0 : AttributeChecker::visit (AST::ImplTraitType &)
941 : 0 : {}
942 : :
943 : : void
944 : 0 : AttributeChecker::visit (AST::TraitObjectType &)
945 : 0 : {}
946 : :
947 : : void
948 : 0 : AttributeChecker::visit (AST::ParenthesisedType &)
949 : 0 : {}
950 : :
951 : : void
952 : 0 : AttributeChecker::visit (AST::ImplTraitTypeOneBound &)
953 : 0 : {}
954 : :
955 : : void
956 : 7 : AttributeChecker::visit (AST::TraitObjectTypeOneBound &)
957 : 7 : {}
958 : :
959 : : void
960 : 0 : AttributeChecker::visit (AST::TupleType &)
961 : 0 : {}
962 : :
963 : : void
964 : 0 : AttributeChecker::visit (AST::NeverType &)
965 : 0 : {}
966 : :
967 : : void
968 : 125 : AttributeChecker::visit (AST::RawPointerType &)
969 : 125 : {}
970 : :
971 : : void
972 : 151 : AttributeChecker::visit (AST::ReferenceType &)
973 : 151 : {}
974 : :
975 : : void
976 : 0 : AttributeChecker::visit (AST::ArrayType &)
977 : 0 : {}
978 : :
979 : : void
980 : 58 : AttributeChecker::visit (AST::SliceType &)
981 : 58 : {}
982 : :
983 : : void
984 : 0 : AttributeChecker::visit (AST::InferredType &)
985 : 0 : {}
986 : :
987 : : void
988 : 0 : AttributeChecker::visit (AST::BareFunctionType &)
989 : 0 : {}
990 : :
991 : : void
992 : 0 : AttributeChecker::visit (AST::SelfParam &)
993 : 0 : {}
994 : :
995 : : void
996 : 0 : AttributeChecker::visit (AST::VariadicParam &)
997 : 0 : {}
998 : :
999 : : void
1000 : 0 : AttributeChecker::visit (AST::FunctionParam &)
1001 : 0 : {}
1002 : :
1003 : : } // namespace Analysis
1004 : : } // namespace Rust
|