diff --git a/src/config/config.cc b/src/config/config.cc index ed727822..caa189fb 100644 --- a/src/config/config.cc +++ b/src/config/config.cc @@ -94,6 +94,7 @@ void inheritable_diagram_options::inherit( puml.override(parent.puml); generate_method_arguments.override(parent.generate_method_arguments); generate_links.override(parent.generate_links); + generate_system_headers.override(parent.generate_system_headers); git.override(parent.git); base_directory.override(parent.base_directory); relative_to.override(parent.relative_to); @@ -527,6 +528,7 @@ template <> struct convert { get_option(node, rhs.layout); get_option(node, rhs.relative_to); + get_option(node, rhs.generate_system_headers); // Convert the path in relative_to to an absolute path, with respect // to the directory where the `.clang-uml` configuration file is located @@ -588,6 +590,7 @@ template <> struct convert { get_option(node, rhs.generate_method_arguments); get_option(node, rhs.generate_packages); get_option(node, rhs.generate_links); + get_option(node, rhs.generate_system_headers); get_option(node, rhs.git); rhs.base_directory.set(node["__parent_path"].as()); get_option(node, rhs.relative_to); diff --git a/src/config/config.h b/src/config/config.h index 6e454eae..c663f88d 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -112,6 +112,7 @@ struct inheritable_diagram_options { option git{"git"}; option base_directory{"__parent_path"}; option relative_to{"relative_to"}; + option generate_system_headers{"generate_system_headers", false}; void inherit(const inheritable_diagram_options &parent); }; diff --git a/src/include_diagram/visitor/translation_unit_visitor.cc b/src/include_diagram/visitor/translation_unit_visitor.cc index 6b42082d..ac47cd58 100644 --- a/src/include_diagram/visitor/translation_unit_visitor.cc +++ b/src/include_diagram/visitor/translation_unit_visitor.cc @@ -109,6 +109,20 @@ void translation_unit_visitor::process_include_directive( .string()); include_file.set_line(0); } + else if (ctx.config().generate_system_headers() && + include_directive.include_kind() == cppast::cpp_include_kind::system) { + auto directive_target = include_directive.name(); + auto f = std::make_unique(); + f->set_name(include_directive.name()); + f->set_type(source_file_t::kHeader); + ctx.diagram().add_element(std::move(f)); + + ctx.get_current_file().value().add_relationship( + relationship{common::model::relationship_t::kDependency, + ctx.diagram().get_element(directive_target).value().alias()}); + + return; + } else { LOG_DBG("Skipping include directive to file {}", include_path.string()); } diff --git a/tests/t40001/.clang-uml b/tests/t40001/.clang-uml index 660a1e13..dc6d2596 100644 --- a/tests/t40001/.clang-uml +++ b/tests/t40001/.clang-uml @@ -10,6 +10,8 @@ diagrams: - ../../tests/t40001/**/*.h # Render the paths relative to this directory relative_to: ../../tests/t40001 + # Include also external system headers + generate_system_headers: true include: # Include only headers belonging to these paths paths: diff --git a/tests/t40001/include/t40001_include1.h b/tests/t40001/include/t40001_include1.h index 734f33d2..f43f00eb 100644 --- a/tests/t40001/include/t40001_include1.h +++ b/tests/t40001/include/t40001_include1.h @@ -2,6 +2,10 @@ #include "lib1/lib1.h" +#include + +#include + namespace clanguml::t40001 { int foo() { return lib1::foo2(); } diff --git a/tests/t40001/test_case.h b/tests/t40001/test_case.h index e2bf65ae..5f476c27 100644 --- a/tests/t40001/test_case.h +++ b/tests/t40001/test_case.h @@ -40,9 +40,14 @@ TEST_CASE("t40001", "[test-case][package]") REQUIRE_THAT(puml, IsFile("t40001.cc")); REQUIRE_THAT(puml, IsFile("t40001_include1.h")); + REQUIRE_THAT(puml, IsFile("string")); + REQUIRE_THAT(puml, IsFile("cppast/cpp_preprocessor.hpp")); + REQUIRE_THAT(puml, IsAssociation(_A("t40001.cc"), _A("t40001_include1.h"))); REQUIRE_THAT(puml, IsAssociation(_A("t40001_include1.h"), _A("lib1.h"))); + REQUIRE_THAT(puml, IsDependency(_A("t40001_include1.h"), _A("string"))); + save_puml( "./" + config.output_directory() + "/" + diagram->name + ".puml", puml); } diff --git a/tests/t40002/src/lib1/lib1.cc b/tests/t40002/src/lib1/lib1.cc index de88c7b5..f043ae1d 100644 --- a/tests/t40002/src/lib1/lib1.cc +++ b/tests/t40002/src/lib1/lib1.cc @@ -1,5 +1,7 @@ #include "../../include/lib1/lib1.h" +#include + namespace clanguml::t40002::lib1 { int foo0() { return 0; } diff --git a/tests/t40002/test_case.h b/tests/t40002/test_case.h index f261d755..1baefec5 100644 --- a/tests/t40002/test_case.h +++ b/tests/t40002/test_case.h @@ -44,6 +44,8 @@ TEST_CASE("t40002", "[test-case][package]") REQUIRE_THAT(puml, IsFile("lib1.cc")); REQUIRE_THAT(puml, IsFile("lib2.cc")); + REQUIRE_THAT(puml, !IsFile("string")); + REQUIRE_THAT(puml, IsAssociation(_A("t40002.cc"), _A("lib1.h"))); REQUIRE_THAT(puml, IsAssociation(_A("lib1.h"), _A("lib2.h"))); REQUIRE_THAT(puml, IsAssociation(_A("lib1.cc"), _A("lib1.h")));