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>
This commit is contained in:
commit
e76b639955
|
@ -3108,6 +3108,22 @@ EnumItem::as_string () const
|
|||
{
|
||||
std::string str = Item::as_string ();
|
||||
str += variant_name;
|
||||
str += " ";
|
||||
switch (get_enum_item_kind ())
|
||||
{
|
||||
case Named:
|
||||
str += "[Named variant]";
|
||||
break;
|
||||
case Tuple:
|
||||
str += "[Tuple variant]";
|
||||
break;
|
||||
case Struct:
|
||||
str += "[Struct variant]";
|
||||
break;
|
||||
case Discriminant:
|
||||
str += "[Discriminant variant]";
|
||||
break;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
|
|
@ -1588,7 +1588,7 @@ public:
|
|||
|
||||
std::string as_string () const;
|
||||
|
||||
Analysis::NodeMapping get_mappings () { return mappings; }
|
||||
Analysis::NodeMapping get_mappings () const { return mappings; }
|
||||
|
||||
Location get_locus () const { return locus; }
|
||||
|
||||
|
@ -1644,12 +1644,19 @@ protected:
|
|||
class EnumItem : public Item
|
||||
{
|
||||
Identifier variant_name;
|
||||
|
||||
Location locus;
|
||||
|
||||
public:
|
||||
virtual ~EnumItem () {}
|
||||
|
||||
enum EnumItemKind
|
||||
{
|
||||
Named,
|
||||
Tuple,
|
||||
Struct,
|
||||
Discriminant,
|
||||
};
|
||||
|
||||
EnumItem (Analysis::NodeMapping mappings, Identifier variant_name,
|
||||
AST::AttrVec outer_attrs, Location locus)
|
||||
: Item (std::move (mappings), std::move (outer_attrs)),
|
||||
|
@ -1663,6 +1670,7 @@ public:
|
|||
}
|
||||
|
||||
virtual std::string as_string () const override;
|
||||
virtual EnumItemKind get_enum_item_kind () const { return Named; };
|
||||
|
||||
// not pure virtual as not abstract
|
||||
void accept_vis (HIRFullVisitor &vis) override;
|
||||
|
@ -1687,6 +1695,11 @@ public:
|
|||
// Returns whether tuple enum item has tuple fields.
|
||||
bool has_tuple_fields () const { return !tuple_fields.empty (); }
|
||||
|
||||
EnumItemKind get_enum_item_kind () const override
|
||||
{
|
||||
return EnumItemKind::Tuple;
|
||||
}
|
||||
|
||||
EnumItemTuple (Analysis::NodeMapping mappings, Identifier variant_name,
|
||||
std::vector<TupleField> tuple_fields, AST::AttrVec outer_attrs,
|
||||
Location locus)
|
||||
|
@ -1720,6 +1733,11 @@ public:
|
|||
// Returns whether struct enum item has struct fields.
|
||||
bool has_struct_fields () const { return !struct_fields.empty (); }
|
||||
|
||||
EnumItemKind get_enum_item_kind () const override
|
||||
{
|
||||
return EnumItemKind::Struct;
|
||||
}
|
||||
|
||||
EnumItemStruct (Analysis::NodeMapping mappings, Identifier variant_name,
|
||||
std::vector<StructField> struct_fields,
|
||||
AST::AttrVec outer_attrs, Location locus)
|
||||
|
@ -1777,6 +1795,11 @@ public:
|
|||
EnumItemDiscriminant (EnumItemDiscriminant &&other) = default;
|
||||
EnumItemDiscriminant &operator= (EnumItemDiscriminant &&other) = default;
|
||||
|
||||
EnumItemKind get_enum_item_kind () const override
|
||||
{
|
||||
return EnumItemKind::Discriminant;
|
||||
}
|
||||
|
||||
std::string as_string () const override;
|
||||
|
||||
void accept_vis (HIRFullVisitor &vis) override;
|
||||
|
|
|
@ -69,6 +69,9 @@ ReachabilityVisitor::visit_generic_predicates (
|
|||
void
|
||||
ReachabilityVisitor::visit (HIR::Module &mod)
|
||||
{
|
||||
auto reach = get_reachability_level (mod.get_visibility ());
|
||||
reach = ctx.update_reachability (mod.get_mappings (), reach);
|
||||
|
||||
for (auto &item : mod.get_items ())
|
||||
{
|
||||
// FIXME: Is that what we want to do? Yes? Only visit the items with
|
||||
|
@ -83,11 +86,17 @@ ReachabilityVisitor::visit (HIR::Module &mod)
|
|||
|
||||
void
|
||||
ReachabilityVisitor::visit (HIR::ExternCrate &crate)
|
||||
{}
|
||||
{
|
||||
auto reach = get_reachability_level (crate.get_visibility ());
|
||||
reach = ctx.update_reachability (crate.get_mappings (), reach);
|
||||
}
|
||||
|
||||
void
|
||||
ReachabilityVisitor::visit (HIR::UseDeclaration &use_decl)
|
||||
{}
|
||||
{
|
||||
auto reach = get_reachability_level (use_decl.get_visibility ());
|
||||
reach = ctx.update_reachability (use_decl.get_mappings (), reach);
|
||||
}
|
||||
|
||||
void
|
||||
ReachabilityVisitor::visit (HIR::Function &func)
|
||||
|
@ -141,6 +150,38 @@ ReachabilityVisitor::visit (HIR::Enum &enum_item)
|
|||
|
||||
enum_reach = ctx.update_reachability (enum_item.get_mappings (), enum_reach);
|
||||
visit_generic_predicates (enum_item.get_generic_params (), enum_reach);
|
||||
|
||||
for (const auto &variant : enum_item.get_variants ())
|
||||
{
|
||||
auto variant_reach
|
||||
= ctx.update_reachability (variant->get_mappings (), enum_reach);
|
||||
|
||||
switch (variant->get_enum_item_kind ())
|
||||
{
|
||||
case HIR::EnumItem::Tuple: {
|
||||
// Should we update the fields only if they are public? Similarly to
|
||||
// what we do in the ReachabilityVisitor for HIR::TupleStruct?
|
||||
auto tuple_variant
|
||||
= static_cast<HIR::EnumItemTuple *> (variant.get ());
|
||||
for (const auto &field : tuple_variant->get_tuple_fields ())
|
||||
ctx.update_reachability (field.get_mappings (), variant_reach);
|
||||
break;
|
||||
}
|
||||
case HIR::EnumItem::Struct: {
|
||||
// Should we update the fields only if they are public? Similarly to
|
||||
// what we do in the ReachabilityVisitor for HIR::StructStruct?
|
||||
auto struct_variant
|
||||
= static_cast<HIR::EnumItemStruct *> (variant.get ());
|
||||
for (const auto &field : struct_variant->get_struct_fields ())
|
||||
ctx.update_reachability (field.get_mappings (), variant_reach);
|
||||
break;
|
||||
}
|
||||
// Nothing nested to visit in that case
|
||||
case HIR::EnumItem::Named:
|
||||
case HIR::EnumItem::Discriminant:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -155,11 +196,17 @@ ReachabilityVisitor::visit (HIR::Union &union_item)
|
|||
|
||||
void
|
||||
ReachabilityVisitor::visit (HIR::ConstantItem &const_item)
|
||||
{}
|
||||
{
|
||||
auto reach = get_reachability_level (const_item.get_visibility ());
|
||||
reach = ctx.update_reachability (const_item.get_mappings (), reach);
|
||||
}
|
||||
|
||||
void
|
||||
ReachabilityVisitor::visit (HIR::StaticItem &static_item)
|
||||
{}
|
||||
{
|
||||
auto reach = get_reachability_level (static_item.get_visibility ());
|
||||
reach = ctx.update_reachability (static_item.get_mappings (), reach);
|
||||
}
|
||||
|
||||
void
|
||||
ReachabilityVisitor::visit (HIR::Trait &trait)
|
||||
|
|
Loading…
Reference in New Issue