From d65864adaf8295982df239fba0fd1135456ee554 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sat, 23 Jul 2022 13:48:15 +0200 Subject: [PATCH] Fixed up to t00013 --- .../plantuml/class_diagram_generator.cc | 16 +- src/class_diagram/model/diagram.cc | 8 +- src/class_diagram/model/template_parameter.h | 2 + .../visitor/translation_unit_visitor.cc | 474 ++++++++++-------- .../visitor/translation_unit_visitor.h | 16 + src/common/generators/plantuml/generator.h | 5 +- tests/t00012/t00012.cc | 11 +- tests/t00012/test_case.h | 2 +- tests/t00013/test_case.h | 6 +- tests/test_cases.cc | 4 +- 10 files changed, 318 insertions(+), 226 deletions(-) diff --git a/src/class_diagram/generators/plantuml/class_diagram_generator.cc b/src/class_diagram/generators/plantuml/class_diagram_generator.cc index 041b0ec9..afcfce52 100644 --- a/src/class_diagram/generators/plantuml/class_diagram_generator.cc +++ b/src/class_diagram/generators/plantuml/class_diagram_generator.cc @@ -246,7 +246,7 @@ void generator::generate_relationships( { namespace plantuml_common = clanguml::common::generators::plantuml; -// const auto &uns = m_config.using_namespace(); + // const auto &uns = m_config.using_namespace(); // // Process relationships @@ -270,8 +270,9 @@ void generator::generate_relationships( // TODO: Refactor destination to a namespace qualified entity // name -// if (util::starts_with(destination, std::string{"::"})) -// destination = destination.substr(2, destination.size()); + // if (util::starts_with(destination, std::string{"::"})) + // destination = destination.substr(2, + // destination.size()); LOG_DBG("=== Destination is: {}", destination); @@ -284,7 +285,14 @@ void generator::generate_relationships( if (!r.multiplicity_destination().empty()) puml_relation += " \"" + r.multiplicity_destination() + "\""; - auto target_alias = m_model.to_alias(destination); + std::string target_alias; + try { + target_alias = m_model.to_alias(destination); + } + catch (...) { + LOG_ERROR("Failed to find alias to {}", destination); + continue; + } if (m_generated_aliases.find(target_alias) == m_generated_aliases.end()) diff --git a/src/class_diagram/model/diagram.cc b/src/class_diagram/model/diagram.cc index b53d0b34..5daf3fb3 100644 --- a/src/class_diagram/model/diagram.cc +++ b/src/class_diagram/model/diagram.cc @@ -77,7 +77,13 @@ std::optional> diagram::get_class( const std::string &name) const { for (const auto &c : classes_) { - if (c.get().full_name(false) == name) { + const auto full_name = c.get().full_name(false); + if (name == + "clanguml::t00012::C>>>,3,3,3>") + LOG_ERROR("Comparing {} with {}", full_name, name); + + if (full_name == name) { return {c}; } } diff --git a/src/class_diagram/model/template_parameter.h b/src/class_diagram/model/template_parameter.h index 0599000d..eecefa3c 100644 --- a/src/class_diagram/model/template_parameter.h +++ b/src/class_diagram/model/template_parameter.h @@ -84,6 +84,8 @@ public: const std::vector &template_params() const; + void clear_params() { template_params_.clear(); } + void find_nested_relationships( std::vector> &nested_relationships, diff --git a/src/class_diagram/visitor/translation_unit_visitor.cc b/src/class_diagram/visitor/translation_unit_visitor.cc index 8c8b14fb..ba7c7c2c 100644 --- a/src/class_diagram/visitor/translation_unit_visitor.cc +++ b/src/class_diagram/visitor/translation_unit_visitor.cc @@ -20,6 +20,7 @@ #include "cx/util.h" #include +#include #include namespace clanguml::class_diagram::visitor { @@ -106,6 +107,28 @@ std::string to_string(const clang::QualType &type, const clang::ASTContext &ctx) return result; } +std::string get_source_text_raw( + clang::SourceRange range, const clang::SourceManager &sm) +{ + return clang::Lexer::getSourceText( + clang::CharSourceRange::getCharRange(range), sm, clang::LangOptions()) + .str(); +} + +std::string get_source_text( + clang::SourceRange range, const clang::SourceManager &sm) +{ + clang::LangOptions lo; + + // NOTE: sm.getSpellingLoc() used in case the range corresponds to a + // macro/preprocessed source. + auto start_loc = sm.getSpellingLoc(range.getBegin()); + auto last_token_loc = sm.getSpellingLoc(range.getEnd()); + auto end_loc = clang::Lexer::getLocForEndOfToken(last_token_loc, 0, sm, lo); + auto printable_range = clang::SourceRange{start_loc, end_loc}; + return get_source_text_raw(printable_range, sm); +} + translation_unit_visitor::translation_unit_visitor(clang::SourceManager &sm, clanguml::class_diagram::model::diagram &diagram, const clanguml::config::class_diagram &config) @@ -115,6 +138,47 @@ translation_unit_visitor::translation_unit_visitor(clang::SourceManager &sm, { } +bool translation_unit_visitor::VisitNamespaceDecl(clang::NamespaceDecl *ns) +{ + auto package_path = namespace_{ns->getQualifiedNameAsString()}; + auto package_parent = package_path; + + std::string name; + if (!package_path.is_empty()) + name = package_path.name(); + + if (!package_parent.is_empty()) + package_parent.pop_back(); + + const auto usn = config().using_namespace(); + + auto p = std::make_unique(usn); + package_path = package_path.relative_to(usn); + + p->set_name(name); + p->set_namespace(package_parent); + + if (diagram().should_include(*p)) { + process_comment(*ns, *p); + set_source_location(*ns, *p); + + p->set_style(p->style_spec()); + + for (const auto *attr : ns->attrs()) { + if (attr->getKind() == clang::attr::Kind::Deprecated) { + p->set_deprecated(true); + break; + } + } + + if (!p->skip()) { + diagram().add_package(std::move(p)); + } + } + + return true; +} + bool translation_unit_visitor::VisitEnumDecl(clang::EnumDecl *enm) { auto e_ptr = std::make_unique(config_.using_namespace()); @@ -162,9 +226,14 @@ bool translation_unit_visitor::VisitClassTemplateDecl( auto c_ptr = process_class_declaration(cls->getTemplatedDecl()); + // Override the id with the template id, for now we don't care about the + // underlying templated class id + c_ptr->set_id(cls->getID()); + process_template_parameters(*cls, *c_ptr); if (diagram_.should_include(*c_ptr)) { + LOG_DBG("Adding class {} with id {}", c_ptr->full_name(), c_ptr->id()); diagram_.add_class(std::move(c_ptr)); } @@ -177,6 +246,10 @@ bool translation_unit_visitor::VisitCXXRecordDecl(clang::CXXRecordDecl *cls) if (source_manager_.isInSystemHeader(cls->getSourceRange().getBegin())) return true; + // Templated records are handled by VisitClassTemplateDecl() + if (cls->isTemplated()) + return true; + // Skip forward declarations if (!cls->isCompleteDefinition()) return true; @@ -293,35 +366,6 @@ bool translation_unit_visitor::process_template_parameters( } } - /* - auto scope = cppast::cpp_scope_name(type_safe::ref(cls)); - // Even if this is a template the scope.is_templated() returns - // false when the template parameter list is empty - if (scope.is_templated()) { - process_scope_template_parameters(c, scope); - } - else { - LOG_DBG("Class {} is templated but it's scope {} is not - " - "probably this is a specialization", - cls.name(), scope.name()); - - // Add specialization arguments - if (tspec) { - if (!tspec.value().arguments_exposed()) { - process_unexposed_template_specialization_parameters(tspec, c); - } - else { - process_exposed_template_specialization_parameters(tspec, c); - } - } - else { - LOG_DBG("Skipping template class declaration which has only " - "unexposed arguments but no tspec provided"); - return true; - } - } - */ - return false; } @@ -376,8 +420,21 @@ void translation_unit_visitor::process_class_children( // Iterate over class methods (both regular and static) for (const auto *method : cls->methods()) { - if (method != nullptr) + if (method != nullptr) { + process_method(*method, c); + } + } + + // Iterate over class template methods + for (auto const *decl_iterator : + clang::dyn_cast_or_null(cls)->decls()) { + auto const *method_template = + llvm::dyn_cast_or_null(decl_iterator); + if (method_template == nullptr) + continue; + + process_template_method(*method_template, c); } // Iterate over regular class fields @@ -460,6 +517,40 @@ void translation_unit_visitor::process_method( c.add_method(std::move(method)); } +void translation_unit_visitor::process_template_method( + const clang::FunctionTemplateDecl &mf, class_ &c) +{ + // TODO: For now skip implicitly default methods + // in the future, add config option to choose + if (mf.getTemplatedDecl()->isDefaulted() && + !mf.getTemplatedDecl()->isExplicitlyDefaulted()) + return; + + class_method method{detail::access_specifier_to_access_t(mf.getAccess()), + util::trim(mf.getNameAsString()), + mf.getTemplatedDecl()->getReturnType().getAsString()}; + + method.is_pure_virtual(mf.getTemplatedDecl()->isPure()); + method.is_virtual(false); + method.is_const(false); + method.is_defaulted(mf.getTemplatedDecl()->isDefaulted()); + method.is_static(mf.getTemplatedDecl()->isStatic()); + + process_comment(mf, method); + + if (method.skip()) + return; + + for (const auto *param : mf.getTemplatedDecl()->parameters()) { + if (param != nullptr) + process_function_parameter(*param, method, c); + } + + LOG_DBG("Adding method: {}", method.name()); + + c.add_method(std::move(method)); +} + bool translation_unit_visitor::find_relationships(const clang::QualType &type, found_relationships_t &relationships, clanguml::common::model::relationship_t relationship_hint) @@ -505,8 +596,8 @@ bool translation_unit_visitor::find_relationships(const clang::QualType &type, } } else { - relationships.emplace_back( - type->getAsCXXRecordDecl()->getID(), relationship_hint); + const auto target_id = type->getAsCXXRecordDecl()->getID(); + relationships.emplace_back(target_id, relationship_hint); result = true; } } @@ -537,48 +628,82 @@ void translation_unit_visitor::process_function_parameter( } } - /* - if (!parameter.skip_relationship()) { - // find relationship for the type - std::vector> - relationships; + if (!parameter.skip_relationship()) { + // find relationship for the type + found_relationships_t relationships; - find_relationships(cppast::remove_cv(param.type()), - relationships, relationship_t::kDependency); + find_relationships( + p.getType(), relationships, relationship_t::kDependency); - for (const auto &[type, relationship_type] : relationships) { - if (type.empty()) - continue; + for (const auto &[type_element_id, relationship_type] : relationships) { + if (/*diagram().has_element(type_element_id) &&*/ + (relationship_type != relationship_t::kNone)) { + relationship r{relationship_t::kDependency, type_element_id}; - auto [type_ns, type_name] = cx::util::split_ns(type); - if (ctx.diagram().should_include(type_ns, type_name) && - (relationship_type != relationship_t::kNone) && - (type != c.name_and_ns())) { - relationship r{relationship_t::kDependency, type}; + LOG_DBG("Adding field relationship {} {} {} : {}", + r.destination(), + clanguml::common::model::to_string(r.type()), c.full_name(), + r.label()); - LOG_DBG("Adding field relationship {} {} {} : {}", - r.destination(), - clanguml::common::model::to_string(r.type()), - c.full_name(), r.label()); - - c.add_relationship(std::move(r)); - } - } - - // Also consider the container itself if it is a template - instantiation - // it's arguments could count as reference to relevant types - const auto &t = - cppast::remove_cv(cx::util::unreferenced(param.type())); if (t.kind() - == cppast::cpp_type_kind::template_instantiation_t) { - process_function_parameter_find_relationships_in_template( - c, template_parameter_names, t); + c.add_relationship(std::move(r)); } } - */ + + // Also consider the container itself if it is a template instantiation + // it's arguments could count as reference to relevant types + auto underlying_type = p.getType(); + if (underlying_type->isReferenceType()) + underlying_type = underlying_type.getNonReferenceType(); + if (underlying_type->isPointerType()) + underlying_type = underlying_type->getPointeeType(); + + if (underlying_type->getAs() != + nullptr) { + process_function_parameter_find_relationships_in_template(c, + template_parameter_names, + *underlying_type->getAs()); + } + } + method.add_parameter(std::move(parameter)); } +void translation_unit_visitor:: + process_function_parameter_find_relationships_in_template(class_ &c, + const std::set &template_parameter_names, + const clang::TemplateSpecializationType &template_instantiation_type) +{ + const auto template_field_decl_name = + template_instantiation_type.getTemplateName() + .getAsTemplateDecl() + ->getQualifiedNameAsString(); + + if (diagram().should_include(template_field_decl_name)) { + if (template_instantiation_type.isDependentType()) { + relationship r{relationship_t::kDependency, + template_instantiation_type.getTemplateName() + .getAsTemplateDecl() + ->getID()}; + + c.add_relationship(std::move(r)); + } + else { + auto template_specialization_ptr = + build_template_instantiation(template_instantiation_type); + + if (template_specialization_ptr) { + relationship r{relationship_t::kDependency, + template_specialization_ptr->id()}; + + if (!diagram().has_element(template_specialization_ptr->id())) + diagram().add_class(std::move(template_specialization_ptr)); + + c.add_relationship(std::move(r)); + } + } + } +} + void translation_unit_visitor::add_relationships(class_ &c, const found_relationships_t &relationships, access_t access, std::optional label) @@ -639,6 +764,8 @@ std::unique_ptr translation_unit_visitor::build_template_instantiation( const clang::TemplateSpecializationType &template_type, std::optional parent) { + // TODO: Make sure we only build instantiation once + // // Create class_ instance to hold the template instantiation // @@ -651,7 +778,9 @@ std::unique_ptr translation_unit_visitor::build_template_instantiation( const auto *template_decl{ template_type.getTemplateName().getAsTemplateDecl()}; + auto qualified_name = template_decl->getQualifiedNameAsString(); + namespace_ ns{qualified_name}; ns.pop_back(); template_instantiation.set_name(template_decl->getNameAsString()); @@ -660,20 +789,71 @@ std::unique_ptr translation_unit_visitor::build_template_instantiation( (std::hash{}(full_template_specialization_name) >> 4)); for (const auto &arg : template_type) { - auto argument_kind = arg.getKind(); + const auto argument_kind = arg.getKind(); if (argument_kind == clang::TemplateArgument::ArgKind::Type) { - // const auto *argument_record_decl = - // arg.getAsType()->getAsRecordDecl(); template_parameter argument; argument.is_template_parameter(false); - argument.set_name( - to_string(arg.getAsType(), template_decl->getASTContext())); + + // If this is a nested template type - add nested templates as + // template arguments + if (arg.getAsType()->getAs()) { + + const auto *nested_template_type = + arg.getAsType()->getAs(); + + const auto nested_template_name = + nested_template_type->getTemplateName() + .getAsTemplateDecl() + ->getQualifiedNameAsString(); + + argument.set_name(nested_template_name); + + auto nested_template_instantiation = + build_template_instantiation( + *arg.getAsType() + ->getAs(), + parent); + + for (const auto &t : nested_template_instantiation->templates()) + argument.add_template_param(t); + + // Check if this template should be simplified (e.g. system + // template aliases such as 'std:basic_string' should be + // simply 'std::string') + simplify_system_template(argument, + argument.to_string(config().using_namespace(), false)); + } + else { + argument.set_name( + to_string(arg.getAsType(), template_decl->getASTContext())); + } template_instantiation.add_template(std::move(argument)); - - template_instantiation.add_relationship( - {relationship_t::kInstantiation, template_decl->getID()}); } + else if (argument_kind == clang::TemplateArgument::ArgKind::Integral) { + template_parameter argument; + argument.is_template_parameter(false); + argument.set_type( + std::to_string(arg.getAsIntegral().getExtValue())); + template_instantiation.add_template(std::move(argument)); + } + else if (argument_kind == + clang::TemplateArgument::ArgKind::Expression) { + template_parameter argument; + argument.is_template_parameter(false); + argument.set_type(get_source_text( + arg.getAsExpr()->getSourceRange(), source_manager_)); + template_instantiation.add_template(std::move(argument)); + } + else { + LOG_ERROR("UNSUPPORTED ARGUMENT KIND FOR ARG {}", arg.getKind()); + } + } + + if (diagram().has_element( + template_type.getTemplateName().getAsTemplateDecl()->getID())) { + template_instantiation.add_relationship({relationship_t::kInstantiation, + template_type.getTemplateName().getAsTemplateDecl()->getID()}); } return template_instantiation_ptr; @@ -763,142 +943,6 @@ void translation_unit_visitor::process_field( } } - /* - if (field_type->getAsCXXRecordDecl()) { - - ElaboratedType 0x5555587d0850 'std::vector' sugar - `-TemplateSpecializationType 0x5555587d0810 'vector' sugar vector - |-TemplateArgument type 'class clanguml::t00002::A *' - | `-PointerType 0x5555587ce870 'class clanguml::t00002::A - *' | `-RecordType 0x5555587ce700 'class clanguml::t00002::A' | - `-CXXRecord 0x5555587ce668 'A' - `-RecordType 0x5555587d07f0 'class std::vector' - `-ClassTemplateSpecialization 0x5555587d06f0 'vector' - */ - // field_type->dump(); - // - // const auto *type_instantiation_decl = - // field_type->getAs(); - // //->desugar() - // //->getAs() - // //->getDecl(); - // - // std::string type_decl_str = - // field_type->getAsCXXRecordDecl()->getQualifiedNameAsString(); - // - // (void)type_decl_str; - // - // for (const auto &f : *type_instantiation_decl) { - // std::cout << " [[[===================== \n"; - // f.dump(); - // std::cout << " ]]]===================== \n"; - // if (f.getAsType()->isPointerType()) { - // f.getAsType()->getPointeeType().dump(); - // if (f.getAsType()->getPointeeType()->isClassType()) { - // const auto t = - // f.getAsType()->getPointeeType()->getAsCXXRecordDecl(); - // std::string tt = t->getQualifiedNameAsString(); - // (void)tt; - // } - // } - // } - - /* - if (clang::isTemplateInstantiation( - type_decl->getTemplateSpecializationKind())) { - for (const auto *template_param : - *type_decl->getTemplateParameterList(0)) { - template_param->getDescribedTemplate()->getCanonicalDecl()-> - } - // for(const auto* template_param : type_decl->templ - // type_decl->getTemplateInstantiationPattern() - } - */ - //} - - // if (field.isTemplated()) { - // for (const auto *param : *field.getTemplateParameterList(0)) { - // std::string param_type_str = - // param->getQualifiedNameAsString(); (void)param_type_str; - // } - // } - /* - const auto &tr = - cx::util::unreferenced(cppast::remove_cv(mv.type())); - - auto tr_declaration = cppast::to_string(tr); - - LOG_DBG("Processing field {} with unreferenced type of kind {}", - mv.name(), cppast::to_string(tr.kind())); - - if (tr.kind() == cppast::cpp_type_kind::builtin_t) { - LOG_DBG("Builtin type found for field: {}", m.name()); - } - else if (tr.kind() == cppast::cpp_type_kind::user_defined_t) { - LOG_DBG("Processing user defined type field {} {}", - cppast::to_string(tr), mv.name()); - if (resolve_alias(tr).kind() == - cppast::cpp_type_kind::template_instantiation_t) - template_instantiation_added_as_aggregation = - process_field_with_template_instantiation(mv, tr, c, m, - as); - } - else if (tr.kind() == - cppast::cpp_type_kind::template_instantiation_t) { - // This can be either template instantiation or an alias - template - // instantiation - template_instantiation_added_as_aggregation = - process_field_with_template_instantiation(mv, tr, c, m, as); - } - else if (tr.kind() == cppast::cpp_type_kind::unexposed_t) { - LOG_DBG( - "Processing field with unexposed type {}", - cppast::to_string(tr)); - // TODO - } - - // - // Try to find relationships in the type of the member, unless it - has - // been already added as part of template processing or it is marked - // to be skipped in the comment - // - if (!m.skip_relationship() && - !template_instantiation_added_as_aggregation && - (tr.kind() != cppast::cpp_type_kind::builtin_t) && - (tr.kind() != cppast::cpp_type_kind::template_parameter_t)) { - found_relationships_t relationships; - - const auto &unaliased_type = resolve_alias(mv.type()); - find_relationships(unaliased_type, relationships); - - for (const auto &[type, relationship_type] : relationships) { - if (relationship_type != relationship_t::kNone) { - relationship r{relationship_type, type, m.access(), - m.name()}; r.set_style(m.style_spec()); - - auto [decorator_rtype, decorator_rmult] = - m.get_relationship(); if (decorator_rtype != relationship_t::kNone) { - r.set_type(decorator_rtype); - auto mult = util::split(decorator_rmult, ":", - false); if (mult.size() == 2) { r.set_multiplicity_source(mult[0]); - r.set_multiplicity_destination(mult[1]); - } - } - - LOG_DBG("Adding field relationship {} {} {} : {}", - r.destination(), - clanguml::common::model::to_string(r.type()), - c.full_name(), r.label()); - - c.add_relationship(std::move(r)); - } - } - } - */ c.add_member(std::move(field)); } @@ -911,4 +955,16 @@ void translation_unit_visitor::set_source_location( source_manager_.getSpellingLineNumber(decl.getLocation())); } } + +bool translation_unit_visitor::simplify_system_template( + template_parameter &ct, const std::string &full_name) +{ + if (config().template_aliases().count(full_name) > 0) { + ct.set_name(config().template_aliases().at(full_name)); + ct.clear_params(); + return true; + } + else + return false; +} } diff --git a/src/class_diagram/visitor/translation_unit_visitor.h b/src/class_diagram/visitor/translation_unit_visitor.h index f9187fe9..023abf5d 100644 --- a/src/class_diagram/visitor/translation_unit_visitor.h +++ b/src/class_diagram/visitor/translation_unit_visitor.h @@ -44,6 +44,8 @@ public: clanguml::class_diagram::model::diagram &diagram, const clanguml::config::class_diagram &config); + virtual bool VisitNamespaceDecl(clang::NamespaceDecl *ns); + virtual bool VisitCXXRecordDecl(clang::CXXRecordDecl *d); virtual bool VisitEnumDecl(clang::EnumDecl *e); @@ -53,6 +55,9 @@ public: // virtual bool VisitVarDecl(clang::VarDecl *variable_declaration); clanguml::class_diagram::model::diagram &diagram() { return diagram_; } + + const clanguml::config::class_diagram &config() const { return config_; } + // void operator()(); private: @@ -75,6 +80,9 @@ private: void process_method(const clang::CXXMethodDecl &mf, clanguml::class_diagram::model::class_ &c); + void process_template_method(const clang::FunctionTemplateDecl &mf, + clanguml::class_diagram::model::class_ &c); + void process_static_field(const clang::VarDecl &field_declaration, clanguml::class_diagram::model::class_ &c); @@ -106,6 +114,11 @@ private: const clang::TemplateSpecializationType &template_type, std::optional parent = {}); + void process_function_parameter_find_relationships_in_template( + clanguml::class_diagram::model::class_ &c, + const std::set &template_parameter_names, + const clang::TemplateSpecializationType &template_instantiation_type); + template void process_comment( const ClangDecl &decl, clanguml::common::model::decorated_element &e) @@ -125,6 +138,9 @@ private: } } + bool simplify_system_template( + model::template_parameter &ct, const std::string &full_name); + clang::SourceManager &source_manager_; // Reference to the output diagram model diff --git a/src/common/generators/plantuml/generator.h b/src/common/generators/plantuml/generator.h index 04b2ff43..79f64a82 100644 --- a/src/common/generators/plantuml/generator.h +++ b/src/common/generators/plantuml/generator.h @@ -194,9 +194,12 @@ void generator::generate_plantuml_directives( directive.replace(std::get<1>(alias_match), std::get<2>(alias_match), element_opt.value().get().alias()); - else + else { + LOG_ERROR( + "CANNOT FIND ALIAS TO ELEMENT {}", full_name.to_string()); directive.replace(std::get<1>(alias_match), std::get<2>(alias_match), "UNKNOWN_ALIAS"); + } } ostr << directive << '\n'; } diff --git a/tests/t00012/t00012.cc b/tests/t00012/t00012.cc index 82f292a0..7f4d335d 100644 --- a/tests/t00012/t00012.cc +++ b/tests/t00012/t00012.cc @@ -22,13 +22,14 @@ template class C { }; class R { - A a1; - A a2; + [[maybe_unused]] A a1; + [[maybe_unused]] A a2; - B<3, 2, 1> b1; - B<1, 1, 1, 1> b2; + [[maybe_unused]] B<3, 2, 1> b1; + [[maybe_unused]] B<1, 1, 1, 1> b2; - C>>>, 3, 3, + [[maybe_unused]] C< + std::map>>>, 3, 3, 3> c1; }; diff --git a/tests/t00012/test_case.h b/tests/t00012/test_case.h index 1a8dd1cd..1d1033fe 100644 --- a/tests/t00012/test_case.h +++ b/tests/t00012/test_case.h @@ -24,7 +24,7 @@ TEST_CASE("t00012", "[test-case][class]") REQUIRE(diagram->name == "t00012_class"); - auto model = generate_class_diagram(db, diagram); + auto model = generate_class_diagram(*db, diagram); REQUIRE(model->name() == "t00012_class"); diff --git a/tests/t00013/test_case.h b/tests/t00013/test_case.h index 28f672b1..3b0375f0 100644 --- a/tests/t00013/test_case.h +++ b/tests/t00013/test_case.h @@ -24,7 +24,7 @@ TEST_CASE("t00013", "[test-case][class]") REQUIRE(diagram->name == "t00013_class"); - auto model = generate_class_diagram(db, diagram); + auto model = generate_class_diagram(*db, diagram); REQUIRE(model->name() == "t00013_class"); REQUIRE(model->should_include("clanguml::t00013::A")); @@ -56,8 +56,8 @@ TEST_CASE("t00013", "[test-case][class]") REQUIRE_THAT( puml, IsAggregation(_A("R"), _A("E"), "-estring")); REQUIRE_THAT(puml, IsDependency(_A("R"), _A("ABCD::F"))); - REQUIRE_THAT(puml, IsInstantiation(_A("ABCD::F"), _A("F"))); - REQUIRE_THAT(puml, IsDependency(_A("R"), _A("F"))); + REQUIRE_THAT(puml, IsInstantiation(_A("ABCD::F"), _A("ABCD::F"))); + REQUIRE_THAT(puml, IsDependency(_A("R"), _A("ABCD::F"))); REQUIRE_THAT(puml, IsInstantiation(_A("G"), _A("G"))); diff --git a/tests/test_cases.cc b/tests/test_cases.cc index 4aeae84e..9674f0e6 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -200,8 +200,8 @@ using namespace clanguml::test::matchers; #include "t00009/test_case.h" #include "t00010/test_case.h" #include "t00011/test_case.h" -//#include "t00012/test_case.h" -//#include "t00013/test_case.h" +#include "t00012/test_case.h" +#include "t00013/test_case.h" //#include "t00014/test_case.h" //#include "t00015/test_case.h" //#include "t00016/test_case.h"