diff --git a/src/class_diagram/visitor/translation_unit_visitor.cc b/src/class_diagram/visitor/translation_unit_visitor.cc index 47a5d8ed..c7a09737 100644 --- a/src/class_diagram/visitor/translation_unit_visitor.cc +++ b/src/class_diagram/visitor/translation_unit_visitor.cc @@ -125,33 +125,29 @@ bool translation_unit_visitor::VisitEnumDecl(clang::EnumDecl *enm) const auto *parent = enm->getParent(); - if ((parent != nullptr) && parent->isRecord()) { - // Here we have 2 options, either: - // - the parent is a regular C++ class/struct - // - the parent is a class template declaration/specialization - std::optional id_opt; + std::optional id_opt; + if (parent != nullptr) { const auto *parent_record_decl = clang::dyn_cast(parent); - int64_t local_id = parent_record_decl->getID(); + if (parent_record_decl != nullptr) { + int64_t local_id = parent_record_decl->getID(); - id_opt = get_ast_local_id(local_id); + // First check if the parent has been added to the diagram as + // regular class + id_opt = get_ast_local_id(local_id); - // If not, check if the parent template declaration is in the model - if (!id_opt) { - if (parent_record_decl->getDescribedTemplate() != nullptr) { + // If not, check if the parent template declaration is in the model + if (!id_opt) { local_id = parent_record_decl->getDescribedTemplate()->getID(); - - id_opt = get_ast_local_id(local_id); + if (parent_record_decl->getDescribedTemplate() != nullptr) + id_opt = get_ast_local_id(local_id); } } + } - if (!id_opt) { - LOG_WARN("Unknown parent for enum {}", qualified_name); - return true; - } - + if (id_opt) { auto parent_class = diagram_.get_class(*id_opt); assert(parent_class); @@ -418,30 +414,32 @@ std::unique_ptr translation_unit_visitor::create_class_declaration( const auto *parent = cls->getParent(); - if ((parent != nullptr) && parent->isRecord()) { - // Here we have 2 options, either: - // - the parent is a regular C++ class/struct - // - the parent is a class template declaration/specialization - std::optional id_opt; + std::optional id_opt; + if (parent != nullptr) { const auto *parent_record_decl = clang::dyn_cast(parent); - int64_t local_id = parent_record_decl->getID(); + if (parent_record_decl != nullptr) { + int64_t local_id = parent_record_decl->getID(); - // First check if the parent has been added to the diagram as regular - // class - id_opt = get_ast_local_id(local_id); + // First check if the parent has been added to the diagram as + // regular class + id_opt = get_ast_local_id(local_id); - // If not, check if the parent template declaration is in the model - if (!id_opt) { - local_id = parent_record_decl->getDescribedTemplate()->getID(); - if (parent_record_decl->getDescribedTemplate() != nullptr) - id_opt = get_ast_local_id(local_id); + // If not, check if the parent template declaration is in the model + if (!id_opt) { + local_id = parent_record_decl->getDescribedTemplate()->getID(); + if (parent_record_decl->getDescribedTemplate() != nullptr) + id_opt = get_ast_local_id(local_id); + } } + } - assert(id_opt); - + if (id_opt) { + // Here we have 2 options, either: + // - the parent is a regular C++ class/struct + // - the parent is a class template declaration/specialization auto parent_class = diagram_.get_class(*id_opt); assert(parent_class); diff --git a/src/sequence_diagram/visitor/translation_unit_visitor.cc b/src/sequence_diagram/visitor/translation_unit_visitor.cc index 196e68c4..ddb308f2 100644 --- a/src/sequence_diagram/visitor/translation_unit_visitor.cc +++ b/src/sequence_diagram/visitor/translation_unit_visitor.cc @@ -1038,47 +1038,25 @@ bool translation_unit_visitor::process_class_template_method_call_expression( return false; if (is_callee_valid_template_specialization(dependent_member_callee)) { - const auto *template_declaration = - dependent_member_callee->getBaseType() - ->getAs() - ->getTemplateName() - .getAsTemplateDecl(); + if (const auto *tst = dependent_member_callee->getBaseType() + ->getAs(); + tst != nullptr) { + const auto *template_declaration = + tst->getTemplateName().getAsTemplateDecl(); - std::string callee_method_full_name; + std::string callee_method_full_name; - // First check if the primary template is already in the - // participants map - if (get_participant(template_declaration).has_value()) { - callee_method_full_name = - get_participant(template_declaration).value().full_name(false) + - "::" + dependent_member_callee->getMember().getAsString(); - - for (const auto &[id, p] : diagram().participants()) { - const auto p_full_name = p->full_name(false); - - if (p_full_name.find(callee_method_full_name + "(") == 0) { - // TODO: This selects the first matching template method - // without considering arguments!!! - m.set_to(id); - break; - } - } - } - // Otherwise check if it is a smart pointer - else if (is_smart_pointer(template_declaration)) { - const auto *argument_template = - template_declaration->getTemplateParameters() - ->asArray() - .front(); - - if (get_participant(argument_template).has_value()) { - callee_method_full_name = get_participant(argument_template) + // First check if the primary template is already in the + // participants map + if (get_participant(template_declaration).has_value()) { + callee_method_full_name = get_participant(template_declaration) .value() .full_name(false) + "::" + dependent_member_callee->getMember().getAsString(); for (const auto &[id, p] : diagram().participants()) { const auto p_full_name = p->full_name(false); + if (p_full_name.find(callee_method_full_name + "(") == 0) { // TODO: This selects the first matching template method // without considering arguments!!! @@ -1087,15 +1065,43 @@ bool translation_unit_visitor::process_class_template_method_call_expression( } } } - else - return false; + // Otherwise check if it is a smart pointer + else if (is_smart_pointer(template_declaration)) { + const auto *argument_template = + template_declaration->getTemplateParameters() + ->asArray() + .front(); + + if (get_participant(argument_template).has_value()) { + callee_method_full_name = get_participant(argument_template) + .value() + .full_name(false) + + "::" + + dependent_member_callee->getMember().getAsString(); + + for (const auto &[id, p] : diagram().participants()) { + const auto p_full_name = p->full_name(false); + if (p_full_name.find(callee_method_full_name + "(") == + 0) { + // TODO: This selects the first matching template + // method + // without considering arguments!!! + m.set_to(id); + break; + } + } + } + else + return false; + } + + m.set_message_name( + dependent_member_callee->getMember().getAsString()); + + if (get_unique_id(template_declaration->getID())) + diagram().add_active_participant( + get_unique_id(template_declaration->getID()).value()); } - - m.set_message_name(dependent_member_callee->getMember().getAsString()); - - if (get_unique_id(template_declaration->getID())) - diagram().add_active_participant( - get_unique_id(template_declaration->getID()).value()); } else { LOG_DBG("Skipping call due to unresolvable " @@ -1191,9 +1197,7 @@ bool translation_unit_visitor::is_callee_valid_template_specialization( if (tst == nullptr) return false; - return !(dependent_member_expr->getBaseType() - ->getAs() - ->isPointerType()); + return !(tst->isPointerType()); } bool translation_unit_visitor::is_smart_pointer( @@ -1239,6 +1243,8 @@ translation_unit_visitor::create_class_declaration(clang::CXXRecordDecl *cls) const auto *parent_record_decl = clang::dyn_cast(parent); + assert(parent_record_decl != nullptr); + int64_t local_id = parent_record_decl->getID(); // First check if the parent has been added to the diagram as