diff options
author | Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> | 2023-07-20 13:40:35 +0200 |
---|---|---|
committer | P-E-P <32375388+P-E-P@users.noreply.github.com> | 2023-07-27 12:24:54 +0000 |
commit | f925f2f094da19369a77ce88ffa378316d788285 (patch) | |
tree | 3bc57914efd942cb8e6e84f5f41df7197bad9efa | |
parent | 72e6a1e85d7930825cfd370104ea5adee4d082ce (diff) | |
download | gcc-f925f2f094da19369a77ce88ffa378316d788285.zip gcc-f925f2f094da19369a77ce88ffa378316d788285.tar.gz gcc-f925f2f094da19369a77ce88ffa378316d788285.tar.bz2 |
privacy: Refactor proc macro privacy check
Refactor proc macro specific privacy check in multiple shorter
functions.
gcc/rust/ChangeLog:
* checks/errors/privacy/rust-privacy-reporter.cc (find_proc_macro_attribute):
Add a new function to find a potential proc macro type
attribute on a given item.
(proc_macro_privacy_check): Move all proc macro privacy check in
their own function to avoid cluttering the usual privacy check.
(PrivacyReporter::go): Add call to newly created proc macro
privacy check function.
Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
-rw-r--r-- | gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc | 81 |
1 files changed, 47 insertions, 34 deletions
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc index c5a6681..7845962 100644 --- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc +++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc @@ -32,46 +32,59 @@ PrivacyReporter::PrivacyReporter ( current_module (tl::nullopt) {} +// Find a proc_macro, proc_macro_derive or proc_macro_attribute +// attribute in a vector of attribute +static tl::optional<std::string> +find_proc_macro_attribute (const AST::AttrVec &outer_attrs) +{ + tl::optional<std::string> result; + + for (auto &a : outer_attrs) + { + auto &segments = a.get_path ().get_segments (); + if (segments.size () != 1) + continue; + auto name = segments.at (0).get_segment_name (); + if (name == "proc_macro" || name == "proc_macro_attribute" + || name == "proc_macro_derive") + result = {name}; + } + + return result; +} + +// Common check on crate items when dealing with 'proc-macro' crate type. +static void +proc_macro_privacy_check (std::unique_ptr<HIR::Item> &item) +{ + if (item->get_hir_kind () == HIR::Node::BaseKind::VIS_ITEM) + { + auto attribute = find_proc_macro_attribute (item->get_outer_attrs ()); + + bool pub_item = static_cast<HIR::VisItem *> (item.get ()) + ->get_visibility () + .is_public (); + + if (pub_item && !attribute.has_value ()) // Public non proc-macro + rust_error_at ( + item->get_locus (), + "%<proc-macro%> crate types currently cannot export any " + "items other than functions tagged with %<#[proc_macro]%>, " + "%<#[proc_macro_derive]%> or %<#[proc_macro_attribute]%>"); + else if (!pub_item && attribute.has_value ()) // Private proc-macro + rust_error_at (item->get_locus (), + "functions tagged with %<#[%s]%> must be %<pub%>", + attribute.value ().c_str ()); + } +} + void PrivacyReporter::go (HIR::Crate &crate) { for (auto &item : crate.get_items ()) { if (Session::get_instance ().options.is_proc_macro ()) - { - if (item->get_hir_kind () == HIR::Node::BaseKind::VIS_ITEM) - { - auto &outer_attrs = item->get_outer_attrs (); - // Find a proc_macro, proc_macro_derive or proc_macro_attribute - // attribute - tl::optional<std::string> proc_macro_attribute; - for (auto &a : outer_attrs) - { - auto &segments = a.get_path ().get_segments (); - if (segments.size () != 1) - break; - auto name = segments.at (0).get_segment_name (); - if (name == "proc_macro" || name == "proc_macro_attribute" - || name == "proc_macro_derive") - proc_macro_attribute = {name}; - } - - auto vis_item = static_cast<HIR::VisItem *> (item.get ()); - if (vis_item->get_visibility ().is_public () - && !proc_macro_attribute.has_value ()) - rust_error_at ( - item->get_locus (), - "%<proc-macro%> crate types currently cannot export any " - "items other than functions tagged with %<#[proc_macro]%>, " - "%<#[proc_macro_derive]%> or %<#[proc_macro_attribute]%>"); - else if (!vis_item->get_visibility ().is_public () - && proc_macro_attribute.has_value ()) - rust_error_at ( - item->get_locus (), - "functions tagged with %<#[%s]%> must be %<pub%>", - proc_macro_attribute.value ().c_str ()); - } - } + proc_macro_privacy_check (item); item->accept_vis (*this); } } |