Added case handling of template argument kinds
This commit is contained in:
@@ -2370,27 +2370,48 @@ void translation_unit_visitor::
|
|||||||
{
|
{
|
||||||
auto arg_index = 0;
|
auto arg_index = 0;
|
||||||
for (const auto &arg : template_args) {
|
for (const auto &arg : template_args) {
|
||||||
const auto argument_kind = arg.getKind();
|
// Argument can be a parameter pack in which case it gives multiple
|
||||||
std::optional<template_parameter> argument;
|
// arguments
|
||||||
if (argument_kind == clang::TemplateArgument::Template) {
|
std::vector<template_parameter> argument;
|
||||||
argument =
|
|
||||||
build_template_instantiation_process_template_argument(arg);
|
switch (arg.getKind()) {
|
||||||
|
case clang::TemplateArgument::Null:
|
||||||
|
argument.push_back(
|
||||||
|
build_template_instantiation_process_null_argument(arg));
|
||||||
|
break;
|
||||||
|
case clang::TemplateArgument::Type:
|
||||||
|
argument.push_back(
|
||||||
|
build_template_instantiation_process_type_argument(parent, cls,
|
||||||
|
full_template_specialization_name, template_decl, arg,
|
||||||
|
template_instantiation));
|
||||||
|
break;
|
||||||
|
case clang::TemplateArgument::Declaration:
|
||||||
|
break;
|
||||||
|
case clang::TemplateArgument::NullPtr:
|
||||||
|
argument.push_back(
|
||||||
|
build_template_instantiation_process_nullptr_argument(arg));
|
||||||
|
break;
|
||||||
|
case clang::TemplateArgument::Integral:
|
||||||
|
argument.push_back(
|
||||||
|
build_template_instantiation_process_integral_argument(arg));
|
||||||
|
break;
|
||||||
|
case clang::TemplateArgument::Template:
|
||||||
|
argument.push_back(
|
||||||
|
build_template_instantiation_process_template_argument(arg));
|
||||||
|
break;
|
||||||
|
case clang::TemplateArgument::TemplateExpansion:
|
||||||
|
break;
|
||||||
|
case clang::TemplateArgument::Expression:
|
||||||
|
argument.push_back(
|
||||||
|
build_template_instantiation_process_expression_argument(arg));
|
||||||
|
break;
|
||||||
|
case clang::TemplateArgument::Pack:
|
||||||
|
build_template_instantiation_process_pack_argument(arg, argument));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (argument_kind == clang::TemplateArgument::Type) {
|
|
||||||
argument = build_template_instantiation_process_type_argument(
|
if (argument.empty()) {
|
||||||
parent, cls, full_template_specialization_name, template_decl,
|
arg_index++;
|
||||||
arg, template_instantiation);
|
|
||||||
}
|
|
||||||
else if (argument_kind == clang::TemplateArgument::Integral) {
|
|
||||||
argument =
|
|
||||||
build_template_instantiation_process_integral_argument(arg);
|
|
||||||
}
|
|
||||||
else if (argument_kind == clang::TemplateArgument::Expression) {
|
|
||||||
argument =
|
|
||||||
build_template_instantiation_process_expression_argument(arg);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LOG_ERROR("Unsupported argument type {}", arg.getKind());
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2405,18 +2426,20 @@ void translation_unit_visitor::
|
|||||||
if (!template_base_params.empty()) {
|
if (!template_base_params.empty()) {
|
||||||
variadic_params = build_template_instantiation_add_base_classes(
|
variadic_params = build_template_instantiation_add_base_classes(
|
||||||
template_instantiation, template_base_params, arg_index,
|
template_instantiation, template_base_params, arg_index,
|
||||||
variadic_params, argument.value());
|
variadic_params, argument.front());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto &arg : argument) {
|
||||||
|
simplify_system_template(
|
||||||
|
arg, arg.to_string(config().using_namespace(), false));
|
||||||
|
|
||||||
LOG_DBG("Adding template argument {} to template "
|
LOG_DBG("Adding template argument {} to template "
|
||||||
"specialization/instantiation {}",
|
"specialization/instantiation {}",
|
||||||
argument.value().to_string(config().using_namespace(), false),
|
arg.to_string(config().using_namespace(), false),
|
||||||
template_instantiation.name());
|
template_instantiation.name());
|
||||||
|
|
||||||
simplify_system_template(argument.value(),
|
template_instantiation.add_template(std::move(arg));
|
||||||
argument.value().to_string(config().using_namespace(), false));
|
}
|
||||||
|
|
||||||
template_instantiation.add_template(std::move(argument.value()));
|
|
||||||
|
|
||||||
arg_index++;
|
arg_index++;
|
||||||
}
|
}
|
||||||
@@ -2468,7 +2491,8 @@ translation_unit_visitor::build_template_instantiation_process_type_argument(
|
|||||||
|
|
||||||
// Set function template argument types
|
// Set function template argument types
|
||||||
for (const auto ¶m_type : function_type->param_types()) {
|
for (const auto ¶m_type : function_type->param_types()) {
|
||||||
auto maybe_arg = get_template_argument_from_type_parameter_string(
|
auto maybe_arg =
|
||||||
|
get_template_argument_from_type_parameter_string(
|
||||||
cls, param_type.getAsString());
|
cls, param_type.getAsString());
|
||||||
|
|
||||||
if (maybe_arg) {
|
if (maybe_arg) {
|
||||||
@@ -2477,7 +2501,8 @@ translation_unit_visitor::build_template_instantiation_process_type_argument(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (param_type->isBuiltinType()) {
|
if (param_type->isBuiltinType()) {
|
||||||
argument.add_template_param(template_parameter::make_argument(
|
argument.add_template_param(
|
||||||
|
template_parameter::make_argument(
|
||||||
param_type.getAsString()));
|
param_type.getAsString()));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -2559,7 +2584,8 @@ translation_unit_visitor::build_template_instantiation_process_type_argument(
|
|||||||
if (nested_template_instantiation &&
|
if (nested_template_instantiation &&
|
||||||
diagram().should_include(
|
diagram().should_include(
|
||||||
nested_template_instantiation->full_name(false))) {
|
nested_template_instantiation->full_name(false))) {
|
||||||
if (diagram().should_include(full_template_specialization_name)) {
|
if (diagram().should_include(
|
||||||
|
full_template_specialization_name)) {
|
||||||
template_instantiation.add_relationship(
|
template_instantiation.add_relationship(
|
||||||
{relationship_t::kDependency,
|
{relationship_t::kDependency,
|
||||||
nested_template_instantiation->id()});
|
nested_template_instantiation->id()});
|
||||||
@@ -2638,6 +2664,24 @@ template_parameter translation_unit_visitor::
|
|||||||
std::to_string(arg.getAsIntegral().getExtValue()));
|
std::to_string(arg.getAsIntegral().getExtValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template_parameter
|
||||||
|
translation_unit_visitor::build_template_instantiation_process_null_argument(
|
||||||
|
const clang::TemplateArgument &arg) const
|
||||||
|
{
|
||||||
|
assert(arg.getKind() == clang::TemplateArgument::Null);
|
||||||
|
|
||||||
|
return template_parameter::make_argument("");
|
||||||
|
}
|
||||||
|
|
||||||
|
template_parameter
|
||||||
|
translation_unit_visitor::build_template_instantiation_process_nullptr_argument(
|
||||||
|
const clang::TemplateArgument &arg) const
|
||||||
|
{
|
||||||
|
assert(arg.getKind() == clang::TemplateArgument::NullPtr);
|
||||||
|
|
||||||
|
return template_parameter::make_argument("nullptr");
|
||||||
|
}
|
||||||
|
|
||||||
template_parameter translation_unit_visitor::
|
template_parameter translation_unit_visitor::
|
||||||
build_template_instantiation_process_expression_argument(
|
build_template_instantiation_process_expression_argument(
|
||||||
const clang::TemplateArgument &arg) const
|
const clang::TemplateArgument &arg) const
|
||||||
@@ -2647,6 +2691,16 @@ template_parameter translation_unit_visitor::
|
|||||||
arg.getAsExpr()->getSourceRange(), source_manager()));
|
arg.getAsExpr()->getSourceRange(), source_manager()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template_parameter
|
||||||
|
translation_unit_visitor::build_template_instantiation_process_pack_argument(
|
||||||
|
const clang::TemplateArgument &arg) const
|
||||||
|
{
|
||||||
|
assert(arg.getKind() == clang::TemplateArgument::Pack);
|
||||||
|
|
||||||
|
arg.getPackAsArray().front().return template_parameter::make_argument(
|
||||||
|
std::to_string(arg.get));
|
||||||
|
}
|
||||||
|
|
||||||
void translation_unit_visitor::
|
void translation_unit_visitor::
|
||||||
build_template_instantiation_process_tag_argument(
|
build_template_instantiation_process_tag_argument(
|
||||||
class_ &template_instantiation,
|
class_ &template_instantiation,
|
||||||
@@ -2668,7 +2722,8 @@ void translation_unit_visitor::
|
|||||||
record_type_decl != nullptr) {
|
record_type_decl != nullptr) {
|
||||||
|
|
||||||
argument.set_id(common::to_id(arg));
|
argument.set_id(common::to_id(arg));
|
||||||
if (diagram().should_include(full_template_specialization_name)) {
|
if (diagram().should_include(
|
||||||
|
full_template_specialization_name)) {
|
||||||
// Add dependency relationship to the parent
|
// Add dependency relationship to the parent
|
||||||
// template
|
// template
|
||||||
template_instantiation.add_relationship(
|
template_instantiation.add_relationship(
|
||||||
@@ -2686,7 +2741,8 @@ void translation_unit_visitor::
|
|||||||
#if LLVM_VERSION_MAJOR >= 16
|
#if LLVM_VERSION_MAJOR >= 16
|
||||||
argument.set_type(record_type_decl->getQualifiedNameAsString());
|
argument.set_type(record_type_decl->getQualifiedNameAsString());
|
||||||
#endif
|
#endif
|
||||||
if (diagram().should_include(full_template_specialization_name)) {
|
if (diagram().should_include(
|
||||||
|
full_template_specialization_name)) {
|
||||||
// Add dependency relationship to the parent
|
// Add dependency relationship to the parent
|
||||||
// template
|
// template
|
||||||
template_instantiation.add_relationship(
|
template_instantiation.add_relationship(
|
||||||
@@ -2830,7 +2886,8 @@ void translation_unit_visitor::process_field(
|
|||||||
&field_declaration, *template_field_type, {&c});
|
&field_declaration, *template_field_type, {&c});
|
||||||
|
|
||||||
if (!field.skip_relationship() && template_specialization_ptr) {
|
if (!field.skip_relationship() && template_specialization_ptr) {
|
||||||
const auto &template_specialization = *template_specialization_ptr;
|
const auto &template_specialization =
|
||||||
|
*template_specialization_ptr;
|
||||||
|
|
||||||
// Check if this template instantiation should be added to the
|
// Check if this template instantiation should be added to the
|
||||||
// current diagram. Even if the top level template type for
|
// current diagram. Even if the top level template type for
|
||||||
@@ -2859,7 +2916,8 @@ void translation_unit_visitor::process_field(
|
|||||||
for (const auto &template_argument :
|
for (const auto &template_argument :
|
||||||
template_specialization.template_params()) {
|
template_specialization.template_params()) {
|
||||||
|
|
||||||
LOG_DBG("Looking for nested relationships from {}::{} in "
|
LOG_DBG(
|
||||||
|
"Looking for nested relationships from {}::{} in "
|
||||||
"template {}",
|
"template {}",
|
||||||
c.full_name(false), field_name,
|
c.full_name(false), field_name,
|
||||||
template_argument.to_string(
|
template_argument.to_string(
|
||||||
@@ -2871,7 +2929,8 @@ void translation_unit_visitor::process_field(
|
|||||||
[&d = diagram()](const std::string &full_name) {
|
[&d = diagram()](const std::string &full_name) {
|
||||||
if (full_name.empty())
|
if (full_name.empty())
|
||||||
return false;
|
return false;
|
||||||
auto [ns, name] = common::split_ns(full_name);
|
auto [ns, name] =
|
||||||
|
common::split_ns(full_name);
|
||||||
return d.should_include(ns, name);
|
return d.should_include(ns, name);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -2897,10 +2956,10 @@ void translation_unit_visitor::process_field(
|
|||||||
field_type->getAsRecordDecl()->getNameAsString().empty()) {
|
field_type->getAsRecordDecl()->getNameAsString().empty()) {
|
||||||
// Relationships to fields whose type is an anonymous nested
|
// Relationships to fields whose type is an anonymous nested
|
||||||
// struct have to be handled separately here
|
// struct have to be handled separately here
|
||||||
anonymous_struct_relationships_[field_type->getAsRecordDecl()
|
anonymous_struct_relationships_
|
||||||
->getID()] =
|
[field_type->getAsRecordDecl()->getID()] =
|
||||||
std::make_tuple(
|
std::make_tuple(field.name(), relationship_hint,
|
||||||
field.name(), relationship_hint, field.access());
|
field.access());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
find_relationships(
|
find_relationships(
|
||||||
@@ -2932,7 +2991,8 @@ void translation_unit_visitor::resolve_local_to_global_ids()
|
|||||||
if (rel.type() == relationship_t::kInstantiation) {
|
if (rel.type() == relationship_t::kInstantiation) {
|
||||||
const auto maybe_id = get_ast_local_id(rel.destination());
|
const auto maybe_id = get_ast_local_id(rel.destination());
|
||||||
if (maybe_id) {
|
if (maybe_id) {
|
||||||
LOG_DBG("= Resolved instantiation destination from local "
|
LOG_DBG(
|
||||||
|
"= Resolved instantiation destination from local "
|
||||||
"id {} to global id {}",
|
"id {} to global id {}",
|
||||||
rel.destination(), *maybe_id);
|
rel.destination(), *maybe_id);
|
||||||
rel.set_destination(*maybe_id);
|
rel.set_destination(*maybe_id);
|
||||||
@@ -3002,7 +3062,8 @@ void translation_unit_visitor::extract_constrained_template_param_name(
|
|||||||
if (!full_declaration_text.empty()) {
|
if (!full_declaration_text.empty()) {
|
||||||
// Handle typename constraint in requires clause
|
// Handle typename constraint in requires clause
|
||||||
if (type_name.find("type-parameter-") == 0) {
|
if (type_name.find("type-parameter-") == 0) {
|
||||||
const auto concept_declaration_text = full_declaration_text.substr(
|
const auto concept_declaration_text =
|
||||||
|
full_declaration_text.substr(
|
||||||
full_declaration_text.find(cpt->getNameAsString()) +
|
full_declaration_text.find(cpt->getNameAsString()) +
|
||||||
cpt->getNameAsString().size() + 1);
|
cpt->getNameAsString().size() + 1);
|
||||||
|
|
||||||
|
|||||||
@@ -225,6 +225,15 @@ private:
|
|||||||
template_parameter build_template_instantiation_process_integral_argument(
|
template_parameter build_template_instantiation_process_integral_argument(
|
||||||
const clang::TemplateArgument &arg) const;
|
const clang::TemplateArgument &arg) const;
|
||||||
|
|
||||||
|
template_parameter build_template_instantiation_process_nullptr_argument(
|
||||||
|
const clang::TemplateArgument &arg) const;
|
||||||
|
|
||||||
|
template_parameter build_template_instantiation_process_null_argument(
|
||||||
|
const clang::TemplateArgument &arg) const;
|
||||||
|
|
||||||
|
template_parameter build_template_instantiation_process_pack_argument(
|
||||||
|
const clang::TemplateArgument &arg) const;
|
||||||
|
|
||||||
template_parameter build_template_instantiation_process_type_argument(
|
template_parameter build_template_instantiation_process_type_argument(
|
||||||
std::optional<clanguml::class_diagram::model::class_ *> &parent,
|
std::optional<clanguml::class_diagram::model::class_ *> &parent,
|
||||||
const clang::Decl *cls,
|
const clang::Decl *cls,
|
||||||
|
|||||||
Reference in New Issue
Block a user