Added handling of anonymous nested enums

This commit is contained in:
Bartek Kryza
2021-05-03 11:11:16 +02:00
parent ed6bcf1c71
commit cff012ab7b
3 changed files with 45 additions and 18 deletions

View File

@@ -170,6 +170,12 @@ void tu_visitor::operator()(const cppast::cpp_entity &file)
void tu_visitor::process_enum_declaration(const cppast::cpp_enum &enm) void tu_visitor::process_enum_declaration(const cppast::cpp_enum &enm)
{ {
if (enm.name().empty()) {
// Anonymous enum values should be rendered as class fields
// with type enum
return;
}
enum_ e; enum_ e;
e.name = cx::util::full_name(ctx.namespace_, enm); e.name = cx::util::full_name(ctx.namespace_, enm);
@@ -179,7 +185,7 @@ void tu_visitor::process_enum_declaration(const cppast::cpp_enum &enm)
} }
} }
// Find if class is contained in another class // Find if enum is contained in a class
for (auto cur = enm.parent(); cur; cur = cur.value().parent()) { for (auto cur = enm.parent(); cur; cur = cur.value().parent()) {
// find nearest parent class, if any // find nearest parent class, if any
if (cur.value().kind() == cppast::cpp_entity_kind::class_t) { if (cur.value().kind() == cppast::cpp_entity_kind::class_t) {
@@ -246,6 +252,14 @@ void tu_visitor::process_class_declaration(const cppast::cpp_class &cls)
auto &mc = static_cast<const cppast::cpp_destructor &>(child); auto &mc = static_cast<const cppast::cpp_destructor &>(child);
process_destructor(mc, c, last_access_specifier); process_destructor(mc, c, last_access_specifier);
} }
else if (child.kind() == cppast::cpp_entity_kind::enum_t) {
auto &en = static_cast<const cppast::cpp_enum &>(child);
if (en.name().empty()) {
// Here we only want to handle anonymous enums, regular nested
// enums are handled in the file-level visitor
process_anonymous_enum(en, c, last_access_specifier);
}
}
else if (child.kind() == cppast::cpp_entity_kind::friend_t) { else if (child.kind() == cppast::cpp_entity_kind::friend_t) {
auto &fr = static_cast<const cppast::cpp_friend &>(child); auto &fr = static_cast<const cppast::cpp_friend &>(child);
@@ -484,6 +498,21 @@ void tu_visitor::process_field(const cppast::cpp_member_variable &mv, class_ &c,
c.members.emplace_back(std::move(m)); c.members.emplace_back(std::move(m));
} }
void tu_visitor::process_anonymous_enum(
const cppast::cpp_enum &en, class_ &c, cppast::cpp_access_specifier_kind as)
{
for (const auto &ev : en) {
if (ev.kind() == cppast::cpp_entity_kind::enum_value_t) {
class_member m;
m.name = ev.name();
m.type = "enum"; // TODO: Try to figure out real enum type
m.scope = detail::cpp_access_specifier_to_scope(as);
m.is_static = false;
c.members.emplace_back(std::move(m));
}
}
}
void tu_visitor::process_static_field(const cppast::cpp_variable &mv, class_ &c, void tu_visitor::process_static_field(const cppast::cpp_variable &mv, class_ &c,
cppast::cpp_access_specifier_kind as) cppast::cpp_access_specifier_kind as)
{ {
@@ -764,7 +793,7 @@ void tu_visitor::process_friend(const cppast::cpp_friend &f, class_ &parent)
r.destination = name; r.destination = name;
} }
else if (f.entity()) { else if (f.entity()) {
std::string name {}; std::string name{};
if (f.entity().value().kind() == if (f.entity().value().kind() ==
cppast::cpp_entity_kind::class_template_t) { cppast::cpp_entity_kind::class_template_t) {

View File

@@ -153,6 +153,10 @@ public:
void process_enum_declaration(const cppast::cpp_enum &enm); void process_enum_declaration(const cppast::cpp_enum &enm);
void process_anonymous_enum(const cppast::cpp_enum &en,
clanguml::model::class_diagram::class_ &c,
cppast::cpp_access_specifier_kind as);
void process_field(const cppast::cpp_member_variable &mv, void process_field(const cppast::cpp_member_variable &mv,
clanguml::model::class_diagram::class_ &c, clanguml::model::class_diagram::class_ &c,
cppast::cpp_access_specifier_kind as); cppast::cpp_access_specifier_kind as);

View File

@@ -1,30 +1,24 @@
namespace clanguml { namespace clanguml {
namespace t00016 { namespace t00016 {
template <typename> template <typename> struct is_numeric {
struct is_numeric { enum { value = false };
enum { value = false };
}; };
template <> template <> struct is_numeric<char> {
struct is_numeric<char> { enum { value = true };
enum { value = true };
}; };
template <> template <> struct is_numeric<unsigned char> {
struct is_numeric<unsigned char> { enum { value = true };
enum { value = true };
}; };
template <> template <> struct is_numeric<int> {
struct is_numeric<int> { enum { value = true };
enum { value = true };
}; };
template <> template <> struct is_numeric<bool> {
struct is_numeric<bool> { enum { value = false };
enum { value = false };
}; };
} }
} }