Skip to content

Commit e76b639

Browse files
Merge #1118
1118: Add reachability visitor to Enum variants r=CohenArthur a=CohenArthur This visits all of an enum's variants and their fields if present. To do that properly, this adds a new `EnumItemKind` enum which allows static casting when visiting each variant of the enum (kept as an `EnumItem` class which is derived three times) Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2 parents 042c875 + c4443ca commit e76b639

File tree

3 files changed

+92
-6
lines changed

3 files changed

+92
-6
lines changed

gcc/rust/hir/tree/rust-hir-full-test.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3108,6 +3108,22 @@ EnumItem::as_string () const
31083108
{
31093109
std::string str = Item::as_string ();
31103110
str += variant_name;
3111+
str += " ";
3112+
switch (get_enum_item_kind ())
3113+
{
3114+
case Named:
3115+
str += "[Named variant]";
3116+
break;
3117+
case Tuple:
3118+
str += "[Tuple variant]";
3119+
break;
3120+
case Struct:
3121+
str += "[Struct variant]";
3122+
break;
3123+
case Discriminant:
3124+
str += "[Discriminant variant]";
3125+
break;
3126+
}
31113127

31123128
return str;
31133129
}

gcc/rust/hir/tree/rust-hir-item.h

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,7 +1588,7 @@ struct TupleField
15881588

15891589
std::string as_string () const;
15901590

1591-
Analysis::NodeMapping get_mappings () { return mappings; }
1591+
Analysis::NodeMapping get_mappings () const { return mappings; }
15921592

15931593
Location get_locus () const { return locus; }
15941594

@@ -1644,12 +1644,19 @@ class TupleStruct : public Struct
16441644
class EnumItem : public Item
16451645
{
16461646
Identifier variant_name;
1647-
16481647
Location locus;
16491648

16501649
public:
16511650
virtual ~EnumItem () {}
16521651

1652+
enum EnumItemKind
1653+
{
1654+
Named,
1655+
Tuple,
1656+
Struct,
1657+
Discriminant,
1658+
};
1659+
16531660
EnumItem (Analysis::NodeMapping mappings, Identifier variant_name,
16541661
AST::AttrVec outer_attrs, Location locus)
16551662
: Item (std::move (mappings), std::move (outer_attrs)),
@@ -1663,6 +1670,7 @@ class EnumItem : public Item
16631670
}
16641671

16651672
virtual std::string as_string () const override;
1673+
virtual EnumItemKind get_enum_item_kind () const { return Named; };
16661674

16671675
// not pure virtual as not abstract
16681676
void accept_vis (HIRFullVisitor &vis) override;
@@ -1687,6 +1695,11 @@ class EnumItemTuple : public EnumItem
16871695
// Returns whether tuple enum item has tuple fields.
16881696
bool has_tuple_fields () const { return !tuple_fields.empty (); }
16891697

1698+
EnumItemKind get_enum_item_kind () const override
1699+
{
1700+
return EnumItemKind::Tuple;
1701+
}
1702+
16901703
EnumItemTuple (Analysis::NodeMapping mappings, Identifier variant_name,
16911704
std::vector<TupleField> tuple_fields, AST::AttrVec outer_attrs,
16921705
Location locus)
@@ -1720,6 +1733,11 @@ class EnumItemStruct : public EnumItem
17201733
// Returns whether struct enum item has struct fields.
17211734
bool has_struct_fields () const { return !struct_fields.empty (); }
17221735

1736+
EnumItemKind get_enum_item_kind () const override
1737+
{
1738+
return EnumItemKind::Struct;
1739+
}
1740+
17231741
EnumItemStruct (Analysis::NodeMapping mappings, Identifier variant_name,
17241742
std::vector<StructField> struct_fields,
17251743
AST::AttrVec outer_attrs, Location locus)
@@ -1777,6 +1795,11 @@ class EnumItemDiscriminant : public EnumItem
17771795
EnumItemDiscriminant (EnumItemDiscriminant &&other) = default;
17781796
EnumItemDiscriminant &operator= (EnumItemDiscriminant &&other) = default;
17791797

1798+
EnumItemKind get_enum_item_kind () const override
1799+
{
1800+
return EnumItemKind::Discriminant;
1801+
}
1802+
17801803
std::string as_string () const override;
17811804

17821805
void accept_vis (HIRFullVisitor &vis) override;

gcc/rust/privacy/rust-reachability.cc

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ ReachabilityVisitor::visit_generic_predicates (
6969
void
7070
ReachabilityVisitor::visit (HIR::Module &mod)
7171
{
72+
auto reach = get_reachability_level (mod.get_visibility ());
73+
reach = ctx.update_reachability (mod.get_mappings (), reach);
74+
7275
for (auto &item : mod.get_items ())
7376
{
7477
// FIXME: Is that what we want to do? Yes? Only visit the items with
@@ -83,11 +86,17 @@ ReachabilityVisitor::visit (HIR::Module &mod)
8386

8487
void
8588
ReachabilityVisitor::visit (HIR::ExternCrate &crate)
86-
{}
89+
{
90+
auto reach = get_reachability_level (crate.get_visibility ());
91+
reach = ctx.update_reachability (crate.get_mappings (), reach);
92+
}
8793

8894
void
8995
ReachabilityVisitor::visit (HIR::UseDeclaration &use_decl)
90-
{}
96+
{
97+
auto reach = get_reachability_level (use_decl.get_visibility ());
98+
reach = ctx.update_reachability (use_decl.get_mappings (), reach);
99+
}
91100

92101
void
93102
ReachabilityVisitor::visit (HIR::Function &func)
@@ -141,6 +150,38 @@ ReachabilityVisitor::visit (HIR::Enum &enum_item)
141150

142151
enum_reach = ctx.update_reachability (enum_item.get_mappings (), enum_reach);
143152
visit_generic_predicates (enum_item.get_generic_params (), enum_reach);
153+
154+
for (const auto &variant : enum_item.get_variants ())
155+
{
156+
auto variant_reach
157+
= ctx.update_reachability (variant->get_mappings (), enum_reach);
158+
159+
switch (variant->get_enum_item_kind ())
160+
{
161+
case HIR::EnumItem::Tuple: {
162+
// Should we update the fields only if they are public? Similarly to
163+
// what we do in the ReachabilityVisitor for HIR::TupleStruct?
164+
auto tuple_variant
165+
= static_cast<HIR::EnumItemTuple *> (variant.get ());
166+
for (const auto &field : tuple_variant->get_tuple_fields ())
167+
ctx.update_reachability (field.get_mappings (), variant_reach);
168+
break;
169+
}
170+
case HIR::EnumItem::Struct: {
171+
// Should we update the fields only if they are public? Similarly to
172+
// what we do in the ReachabilityVisitor for HIR::StructStruct?
173+
auto struct_variant
174+
= static_cast<HIR::EnumItemStruct *> (variant.get ());
175+
for (const auto &field : struct_variant->get_struct_fields ())
176+
ctx.update_reachability (field.get_mappings (), variant_reach);
177+
break;
178+
}
179+
// Nothing nested to visit in that case
180+
case HIR::EnumItem::Named:
181+
case HIR::EnumItem::Discriminant:
182+
break;
183+
}
184+
}
144185
}
145186

146187
void
@@ -155,11 +196,17 @@ ReachabilityVisitor::visit (HIR::Union &union_item)
155196

156197
void
157198
ReachabilityVisitor::visit (HIR::ConstantItem &const_item)
158-
{}
199+
{
200+
auto reach = get_reachability_level (const_item.get_visibility ());
201+
reach = ctx.update_reachability (const_item.get_mappings (), reach);
202+
}
159203

160204
void
161205
ReachabilityVisitor::visit (HIR::StaticItem &static_item)
162-
{}
206+
{
207+
auto reach = get_reachability_level (static_item.get_visibility ());
208+
reach = ctx.update_reachability (static_item.get_mappings (), reach);
209+
}
163210

164211
void
165212
ReachabilityVisitor::visit (HIR::Trait &trait)

0 commit comments

Comments
 (0)