Fixed compilation with some failing test cases on LLVM 16
This commit is contained in:
@@ -25,11 +25,6 @@ set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
if(APPLE)
|
||||
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES
|
||||
${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
|
||||
endif(APPLE)
|
||||
|
||||
#
|
||||
# clang-uml custom defines
|
||||
#
|
||||
@@ -124,6 +119,11 @@ else()
|
||||
message(STATUS "Found LibTooling libraries: ${LIBTOOLING_LIBS}")
|
||||
endif()
|
||||
|
||||
if(APPLE OR (LLVM_VERSION_MAJOR GREATER_EQUAL 16))
|
||||
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES
|
||||
${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
|
||||
endif()
|
||||
|
||||
#
|
||||
# Setup threads library
|
||||
#
|
||||
|
||||
@@ -1488,7 +1488,8 @@ bool translation_unit_visitor::find_relationships(const clang::QualType &type,
|
||||
->getID(),
|
||||
relationship_hint);
|
||||
}
|
||||
for (const auto &template_argument : *type_instantiation_decl) {
|
||||
for (const auto &template_argument :
|
||||
type_instantiation_decl->template_arguments()) {
|
||||
const auto template_argument_kind = template_argument.getKind();
|
||||
if (template_argument_kind ==
|
||||
clang::TemplateArgument::ArgKind::Integral) {
|
||||
@@ -2520,12 +2521,29 @@ void translation_unit_visitor::
|
||||
argument.set_type(
|
||||
common::to_string(arg.getAsType(), template_decl->getASTContext()));
|
||||
|
||||
if (const auto *record_type = arg.getAsType()->getAs<clang::RecordType>();
|
||||
record_type != nullptr) {
|
||||
if (const auto *tsp =
|
||||
arg.getAsType()->getAs<clang::TemplateSpecializationType>();
|
||||
tsp != nullptr) {
|
||||
if (const auto *record_type_decl = tsp->getAsRecordDecl();
|
||||
record_type_decl != nullptr) {
|
||||
|
||||
argument.set_id(common::to_id(arg));
|
||||
if (diagram().should_include(full_template_specialization_name)) {
|
||||
// Add dependency relationship to the parent
|
||||
// template
|
||||
template_instantiation.add_relationship(
|
||||
{relationship_t::kDependency, common::to_id(arg)});
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (const auto *record_type =
|
||||
arg.getAsType()->getAs<clang::RecordType>();
|
||||
record_type != nullptr) {
|
||||
if (const auto *record_type_decl = record_type->getAsRecordDecl();
|
||||
record_type_decl != nullptr) {
|
||||
argument.set_id(common::to_id(arg));
|
||||
|
||||
argument.set_id(common::to_id(arg));
|
||||
argument.set_type(record_type_decl->getQualifiedNameAsString());
|
||||
if (diagram().should_include(full_template_specialization_name)) {
|
||||
// Add dependency relationship to the parent
|
||||
// template
|
||||
@@ -2635,11 +2653,10 @@ void translation_unit_visitor::process_field(
|
||||
if (type_name.find("std::weak_ptr") == 0)
|
||||
relationship_hint = relationship_t::kAssociation;
|
||||
|
||||
const auto *template_field_type =
|
||||
field_type->getAs<clang::TemplateSpecializationType>();
|
||||
|
||||
found_relationships_t relationships;
|
||||
|
||||
const auto *template_field_type =
|
||||
field_type->getAs<clang::TemplateSpecializationType>();
|
||||
// TODO: Refactor to an unalias_type() method
|
||||
if (template_field_type != nullptr)
|
||||
if (template_field_type->isTypeAlias())
|
||||
|
||||
@@ -268,13 +268,10 @@ cli_flow_t cli_handler::handle_post_config_options()
|
||||
|
||||
cli_flow_t cli_handler::print_version()
|
||||
{
|
||||
constexpr auto kLLVMBackendPackageStringLength{5};
|
||||
ostr_ << "clang-uml " << clanguml::version::CLANG_UML_VERSION << '\n';
|
||||
ostr_ << "Copyright (C) 2021-2023 Bartek Kryza <bkryza@gmail.com>" << '\n';
|
||||
ostr_ << "Built against LLVM/Clang libraries version: "
|
||||
<< std::string{BACKEND_PACKAGE_STRING}.substr(
|
||||
kLLVMBackendPackageStringLength)
|
||||
<< std::endl;
|
||||
<< LLVM_VERSION_STRING << std::endl;
|
||||
ostr_ << "Using LLVM/Clang libraries version: "
|
||||
<< clang::getClangFullVersion() << std::endl;
|
||||
|
||||
|
||||
@@ -115,9 +115,32 @@ std::string get_tag_name(const clang::TagDecl &declaration)
|
||||
std::string to_string(const clang::QualType &type, const clang::ASTContext &ctx,
|
||||
bool try_canonical)
|
||||
{
|
||||
const clang::PrintingPolicy print_policy(ctx.getLangOpts());
|
||||
clang::PrintingPolicy print_policy(ctx.getLangOpts());
|
||||
print_policy.SuppressScope = false;
|
||||
print_policy.PrintCanonicalTypes = false;
|
||||
// print_policy.FullyQualifiedName = true;
|
||||
|
||||
auto result{type.getAsString(print_policy)};
|
||||
#if LLVM_VERSION_MAJOR >= 16
|
||||
print_policy.AlwaysIncludeTypeForTemplateArgument = true;
|
||||
print_policy.SplitTemplateClosers = false;
|
||||
print_policy.SuppressDefaultTemplateArgs = false;
|
||||
print_policy.SuppressInlineNamespace = false;
|
||||
#endif
|
||||
|
||||
std::string result;
|
||||
|
||||
result = type.getAsString(print_policy);
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 16
|
||||
// Why do I have to this LLVM16?
|
||||
if (const auto *decl = type->getAsCXXRecordDecl();
|
||||
decl && !decl->isTemplated() && result.find('<') == std::string::npos) {
|
||||
// This is a workaround for LLVM >= 16
|
||||
const auto tag_namespace = get_tag_namespace(*decl).to_string();
|
||||
if (result.find(tag_namespace) != 0)
|
||||
result = fmt::format("{}::{}", tag_namespace, result);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (try_canonical && result.find('<') != std::string::npos) {
|
||||
auto canonical_type_name =
|
||||
|
||||
@@ -176,6 +176,12 @@ std::optional<std::string> diagram::get_together_group(
|
||||
|
||||
void diagram::initialize_type_aliases()
|
||||
{
|
||||
if (type_aliases().count("std::__cxx11::basic_string<char,std::char_traits<"
|
||||
"char>,std::allocator<char>>") == 0U) {
|
||||
type_aliases().insert({"std::__cxx11::basic_string<char,std::char_"
|
||||
"traits<char>,std::allocator<char>>",
|
||||
"std::string"});
|
||||
}
|
||||
if (type_aliases().count("std::basic_string<char>") == 0U) {
|
||||
type_aliases().insert({"std::basic_string<char>", "std::string"});
|
||||
}
|
||||
@@ -204,6 +210,11 @@ void diagram::initialize_type_aliases()
|
||||
type_aliases().insert(
|
||||
{"std::integral_constant<bool,false>", "std::false_type"});
|
||||
}
|
||||
// #if LLVM_VERSION_MAJOR >= 16
|
||||
// if (type_aliases().count("std::basic_string") == 0U) {
|
||||
// type_aliases().insert({"std::basic_string", "std::string"});
|
||||
// }
|
||||
// #endif
|
||||
}
|
||||
|
||||
common::model::diagram_t class_diagram::type() const
|
||||
|
||||
@@ -43,7 +43,15 @@ translation_unit_visitor::include_visitor::include_visitor(
|
||||
{
|
||||
}
|
||||
|
||||
#if LLVM_VERSION_MAJOR > 14
|
||||
#if LLVM_VERSION_MAJOR >= 16
|
||||
void translation_unit_visitor::include_visitor::InclusionDirective(
|
||||
clang::SourceLocation hash_loc, const clang::Token & /*include_tok*/,
|
||||
clang::StringRef /*file_name*/, bool is_angled,
|
||||
clang::CharSourceRange /*filename_range*/, clang::OptionalFileEntryRef file,
|
||||
clang::StringRef /*search_path*/, clang::StringRef relative_path,
|
||||
const clang::Module * /*imported*/,
|
||||
clang::SrcMgr::CharacteristicKind file_type)
|
||||
#elif LLVM_VERSION_MAJOR > 14
|
||||
void translation_unit_visitor::include_visitor::InclusionDirective(
|
||||
clang::SourceLocation hash_loc, const clang::Token & /*include_tok*/,
|
||||
clang::StringRef /*file_name*/, bool is_angled,
|
||||
|
||||
@@ -49,7 +49,14 @@ public:
|
||||
|
||||
~include_visitor() override = default;
|
||||
|
||||
#if LLVM_VERSION_MAJOR > 14
|
||||
#if LLVM_VERSION_MAJOR >= 16
|
||||
void InclusionDirective(clang::SourceLocation HashLoc,
|
||||
const clang::Token &IncludeTok, clang::StringRef FileName,
|
||||
bool IsAngled, clang::CharSourceRange FilenameRange,
|
||||
clang::OptionalFileEntryRef File, clang::StringRef SearchPath,
|
||||
clang::StringRef RelativePath, const clang::Module *Imported,
|
||||
clang::SrcMgr::CharacteristicKind FileType) override;
|
||||
#elif LLVM_VERSION_MAJOR > 14
|
||||
void InclusionDirective(clang::SourceLocation hash_loc,
|
||||
const clang::Token &include_tok, clang::StringRef file_name,
|
||||
bool is_angled, clang::CharSourceRange filename_range,
|
||||
|
||||
@@ -344,7 +344,7 @@ bool translation_unit_visitor::find_relationships(const clang::QualType &type,
|
||||
type->getAs<clang::TemplateSpecializationType>()) {
|
||||
if (template_specialization_type != nullptr) {
|
||||
for (const auto &template_argument :
|
||||
*template_specialization_type) {
|
||||
template_specialization_type->template_arguments()) {
|
||||
const auto template_argument_kind = template_argument.getKind();
|
||||
if (template_argument_kind ==
|
||||
clang::TemplateArgument::ArgKind::Integral) {
|
||||
|
||||
@@ -620,6 +620,26 @@ struct File {
|
||||
const std::string file;
|
||||
};
|
||||
|
||||
std::optional<nlohmann::json> get_element_by_id(
|
||||
const nlohmann::json &j, const std::string &id)
|
||||
{
|
||||
if (!j.contains("elements"))
|
||||
return {};
|
||||
|
||||
for (const nlohmann::json &e : j["elements"]) {
|
||||
if (e["id"] == id)
|
||||
return {e};
|
||||
|
||||
if (e["type"] == "namespace" || e["type"] == "folder") {
|
||||
auto maybe_e = get_element_by_id(e, id);
|
||||
if (maybe_e)
|
||||
return maybe_e;
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<nlohmann::json> get_element(
|
||||
const nlohmann::json &j, const std::string &name)
|
||||
{
|
||||
@@ -744,15 +764,16 @@ bool IsDeprecated(const nlohmann::json &j, const std::string &name)
|
||||
bool IsBaseClass(const nlohmann::json &j, const std::string &base,
|
||||
const std::string &subclass)
|
||||
{
|
||||
auto sc = get_element(j, expand_name(j, subclass));
|
||||
auto base_el = get_element(j, expand_name(j, base));
|
||||
auto subclass_el = get_element(j, expand_name(j, subclass));
|
||||
|
||||
if (!sc)
|
||||
if (!base_el || !subclass_el)
|
||||
return false;
|
||||
|
||||
const nlohmann::json &bases = (*sc)["bases"];
|
||||
const nlohmann::json &bases = (*subclass_el)["bases"];
|
||||
|
||||
return std::find_if(bases.begin(), bases.end(), [&](const auto &it) {
|
||||
return it["name"] == expand_name(j, base);
|
||||
return it["id"] == base_el.value()["id"];
|
||||
}) != bases.end();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user