30#include <clang/AST/RecursiveASTVisitor.h>
31#include <clang/Basic/SourceManager.h>
70 std::map<eid_t, std::unique_ptr<T>>
values;
72 std::map<eid_t, std::unique_ptr<T>> &
get() {
return values; }
74 const std::map<eid_t, std::unique_ptr<T>> &
get()
const {
return values; }
77template <
typename... Ts>
90 :
public clang::RecursiveASTVisitor<translation_unit_visitor>,
128 clang::ClassTemplateDecl *class_template_declaration);
131 clang::ClassTemplateSpecializationDecl *cls);
159 void add_class(std::unique_ptr<class_> &&c);
166 void add_enum(std::unique_ptr<enum_> &&e);
178 std::unique_ptr<common::model::template_element> element)
override;
180 std::unique_ptr<class_>
create_element(
const clang::NamedDecl *decl)
const;
184 const std::string &full_name,
eid_t templated_decl_id);
194 clang::CXXRecordDecl *cls);
206 template <
typename T,
typename ElementT>
207 bool add_or_update(
const T *cls, std::unique_ptr<ElementT> &&c_ptr);
216 const clang::EnumDecl *enm,
const clang::TypedefDecl *typedef_decl);
226 clang::RecordDecl *rec);
234 std::unique_ptr<clanguml::class_diagram::model::objc_interface>
243 std::unique_ptr<clanguml::class_diagram::model::objc_interface>
252 std::unique_ptr<clanguml::class_diagram::model::objc_interface>
260 std::unique_ptr<clanguml::class_diagram::model::concept_>
342 std::unique_ptr<clanguml::class_diagram::model::class_>
344 clang::ClassTemplateSpecializationDecl *cls);
352 const clang::ClassTemplateSpecializationDecl *cls,
class_ &c);
380 const class_ &c,
const std::string &method_name,
407 void process_field(
const clang::FieldDecl &field_declaration,
437 const std::set<std::string> &template_parameter_names = {});
469 const clang::QualType &type, found_relationships_t & ,
487 const found_relationships_t &relationships,
488 bool break_on_first_aggregation =
false);
498 const std::string &type_name,
int index, relationship_t hint);
510 clang::RecordDecl *cls,
class_ &c,
const namespace_ &ns);
562 const clang::ConceptSpecializationExpr *concept_specialization);
575 const clang::ConceptSpecializationExpr *concept_specialization,
576 const clang::ConceptDecl *cpt,
577 std::vector<std::string> &constrained_template_params,
578 size_t argument_index, std::string &type_name)
const;
602 template <
typename T>
604 namespace_ parent_ns,
const clang::RecordDecl *decl);
607 std::optional<eid_t> &parent_id_opt, namespace_ &parent_ns)
const;
616 std::optional<size_t> >>
619 std::map<const clang::EnumDecl *, const clang::TypedefDecl *>
634 class_ &c, namespace_ parent_ns,
const clang::RecordDecl *decl)
639 auto parent_class =
diagram().find<T>(parent_id);
642 const auto cls_name = decl->getNameAsString();
643 if (cls_name.empty()) {
646 const auto &[label, hint, access, destination_multiplicity] =
649 c.
set_name(parent_class.value().name() +
"##" +
650 fmt::format(
"({})", label));
652 std::string destination_multiplicity_str{};
653 if (destination_multiplicity.has_value()) {
654 destination_multiplicity_str =
655 std::to_string(*destination_multiplicity);
658 parent_class.value().add_relationship(
660 destination_multiplicity_str});
663 c.
set_name(parent_class.value().name() +
"##" +
664 fmt::format(
"(anonymous_{})", std::to_string(decl->getID())));
668 parent_class.value().name() +
"##" + decl->getNameAsString());
673 if (!(decl->getNameAsString().empty())) {
682template <
typename T,
typename ElementT>
684 const T *cls, std::unique_ptr<ElementT> &&c_ptr)
687 std::is_same_v<ElementT, class_> || std::is_same_v<ElementT, enum_>);
689 const auto cls_id = c_ptr->id();
693 auto maybe_existing_model =
diagram().find<ElementT>(cls_id);
695 ElementT &class_model =
696 maybe_existing_model.has_value() ? *maybe_existing_model.get() : *c_ptr;
698 auto id = class_model.id();
700 if (cls->isCompleteDefinition() && !class_model.complete()) {
709 if (cls->isCompleteDefinition()) {
710 if (maybe_existing_model &&
715 const auto file =
config().make_path_relative(class_model.file());
719 diagram().move<ElementT>(id, p);
729 if constexpr (std::is_same_v<T, clang::ClassTemplateSpecializationDecl>) {
730 if (!class_model.template_specialization_found()) {
733 const eid_t ast_id{cls->getSpecializedTemplate()->getID()};
735 if (maybe_id.has_value())
736 class_model.add_relationship(
737 {relationship_t::kInstantiation, maybe_id.value()});
741 if (maybe_existing_model)
745 LOG_DBG(
"Adding {} {} with id {}", class_model.type_name(), class_model,
747 if constexpr (std::is_same_v<ElementT, class_>)
753 LOG_DBG(
"Skipping {} {} with id {}", class_model.type_name(),
754 class_model, class_model.id());