diff --git a/src/cx/cursor.h b/src/cx/cursor.h index b2b48e84..b7f9d832 100644 --- a/src/cx/cursor.h +++ b/src/cx/cursor.h @@ -211,6 +211,11 @@ public: return clang_getCXXAccessSpecifier(m_cursor); } + cx::type underlying_type() const + { + return clang_getTypedefDeclUnderlyingType(m_cursor); + } + int template_argument_count() const { return clang_Cursor_getNumTemplateArguments(m_cursor); diff --git a/src/uml/class_diagram_visitor.cc b/src/uml/class_diagram_visitor.cc index bbb58a4f..6fc0770d 100644 --- a/src/uml/class_diagram_visitor.cc +++ b/src/uml/class_diagram_visitor.cc @@ -599,8 +599,11 @@ enum CXChildVisitResult process_field( m.is_static = cursor.is_static(); - spdlog::debug("Adding member {} {}::{} {}, {}, {}", m.type, parent->name, - cursor.spelling(), t, tr, tr.type_declaration()); + spdlog::debug( + "Adding member {} {}::{} " + "\n\tCURSOR={}\n\tTYPE={}\n\tTYPEDECL={}\n\tUNDERLYINGTYPE={}", + m.type, parent->name, cursor.spelling(), cursor, t, + tr.type_declaration(), tr.type_declaration().underlying_type()); if (tr.is_unexposed()) { added_relation_to_instantiation = diff --git a/src/util/util.cc b/src/util/util.cc index 3bb9cf8b..05dbe246 100644 --- a/src/util/util.cc +++ b/src/util/util.cc @@ -91,8 +91,8 @@ std::string ns_relative( std::string unqualify(const std::string &s) { auto toks = clanguml::util::split(s, " "); - const std::vector qualifiers = { - "static", "const", "volatile", "register", "mutable", "struct", "enum"}; + const std::vector qualifiers = {"static", "const", "volatile", + "register", "constexpr", "mutable", "struct", "enum"}; toks.erase(toks.begin(), std::find_if(toks.begin(), toks.end(), [&qualifiers](const auto &t) { diff --git a/tests/t00014/.clanguml b/tests/t00014/.clanguml new file mode 100644 index 00000000..b6e5b791 --- /dev/null +++ b/tests/t00014/.clanguml @@ -0,0 +1,12 @@ +compilation_database_dir: .. +output_directory: puml +diagrams: + t00014_class: + type: class + glob: + - ../../tests/t00014/t00014.cc + using_namespace: + - clanguml::t00014 + include: + namespaces: + - clanguml::t00014 diff --git a/tests/t00014/t00014.cc b/tests/t00014/t00014.cc new file mode 100644 index 00000000..403cf616 --- /dev/null +++ b/tests/t00014/t00014.cc @@ -0,0 +1,29 @@ +#include +#include +#include +#include +#include +#include +#include + +namespace clanguml { +namespace t00014 { + +template struct A { + T t; + P p; +}; + +template using AString = A; + +using AIntString = AString; +using AStringString = AString; + +class R { + A boolstring; + AString floatstring; + AIntString intstring; + AStringString stringstring; +}; +} +} diff --git a/tests/t00014/test_case.h b/tests/t00014/test_case.h new file mode 100644 index 00000000..28fa82a7 --- /dev/null +++ b/tests/t00014/test_case.h @@ -0,0 +1,66 @@ +/** + * tests/t00014/test_case.cc + * + * Copyright (c) 2021 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +TEST_CASE("t00014", "[test-case][class]") +{ + auto [config, db] = load_config("t00014"); + + auto diagram = config.diagrams["t00014_class"]; + + REQUIRE(diagram->name == "t00014_class"); + + REQUIRE_THAT(diagram->include.namespaces, + VectorContains(std::string{"clanguml::t00014"})); + + REQUIRE(diagram->exclude.namespaces.size() == 0); + + REQUIRE(diagram->should_include("clanguml::t00014::S")); + + auto model = generate_class_diagram(db, diagram); + + REQUIRE(model.name == "t00014_class"); + + auto puml = generate_class_puml(diagram, model); + AliasMatcher _A(puml); + + REQUIRE_THAT(puml, StartsWith("@startuml")); + REQUIRE_THAT(puml, EndsWith("@enduml\n")); + REQUIRE_THAT(puml, IsClass(_A("S"))); + /* + REQUIRE_THAT(puml, IsClass(_A("B"))); + REQUIRE_THAT(puml, IsClass(_A("C"))); + REQUIRE_THAT(puml, IsClass(_A("D"))); + REQUIRE_THAT(puml, !IsDependency(_A("R"), _A("R"))); + REQUIRE_THAT(puml, IsDependency(_A("R"), _A("A"))); + REQUIRE_THAT(puml, IsDependency(_A("R"), _A("B"))); + REQUIRE_THAT(puml, IsDependency(_A("R"), _A("C"))); + REQUIRE_THAT(puml, IsDependency(_A("R"), _A("D"))); + REQUIRE_THAT(puml, IsDependency(_A("D"), _A("R"))); + REQUIRE_THAT(puml, IsDependency(_A("R"), _A("E"))); + REQUIRE_THAT(puml, IsDependency(_A("R"), _A("E"))); + REQUIRE_THAT(puml, IsInstantiation(_A("E"), _A("E"))); + REQUIRE_THAT(puml, IsInstantiation(_A("E"), _A("E"))); + REQUIRE_THAT(puml, IsComposition(_A("R"), _A("E"), "estring")); + REQUIRE_THAT(puml, IsDependency(_A("R"), _A("ABCD::F"))); + REQUIRE_THAT(puml, IsInstantiation(_A("ABCD::F"), _A("ABCD::F"))); + REQUIRE_THAT(puml, IsDependency(_A("R"), _A("ABCD::F"))); + */ + + save_puml( + "./" + config.output_directory + "/" + diagram->name + ".puml", puml); +} diff --git a/tests/test_cases.cc b/tests/test_cases.cc index 5a632d91..77bf2f6a 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -129,6 +129,7 @@ using clanguml::test::matchers::Static; #include "t00011/test_case.h" #include "t00012/test_case.h" #include "t00013/test_case.h" +#include "t00014/test_case.h" // // Sequence diagram tests