Added case handling of template argument kinds
This commit is contained in:
@@ -2370,27 +2370,48 @@ void translation_unit_visitor::
|
||||
{
|
||||
auto arg_index = 0;
|
||||
for (const auto &arg : template_args) {
|
||||
const auto argument_kind = arg.getKind();
|
||||
std::optional<template_parameter> argument;
|
||||
if (argument_kind == clang::TemplateArgument::Template) {
|
||||
argument =
|
||||
build_template_instantiation_process_template_argument(arg);
|
||||
// Argument can be a parameter pack in which case it gives multiple
|
||||
// arguments
|
||||
std::vector<template_parameter> argument;
|
||||
|
||||
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(
|
||||
parent, cls, full_template_specialization_name, template_decl,
|
||||
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());
|
||||
|
||||
if (argument.empty()) {
|
||||
arg_index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2405,18 +2426,20 @@ void translation_unit_visitor::
|
||||
if (!template_base_params.empty()) {
|
||||
variadic_params = build_template_instantiation_add_base_classes(
|
||||
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 "
|
||||
"specialization/instantiation {}",
|
||||
argument.value().to_string(config().using_namespace(), false),
|
||||
arg.to_string(config().using_namespace(), false),
|
||||
template_instantiation.name());
|
||||
|
||||
simplify_system_template(argument.value(),
|
||||
argument.value().to_string(config().using_namespace(), false));
|
||||
|
||||
template_instantiation.add_template(std::move(argument.value()));
|
||||
template_instantiation.add_template(std::move(arg));
|
||||
}
|
||||
|
||||
arg_index++;
|
||||
}
|
||||
@@ -2468,7 +2491,8 @@ translation_unit_visitor::build_template_instantiation_process_type_argument(
|
||||
|
||||
// Set function template argument 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());
|
||||
|
||||
if (maybe_arg) {
|
||||
@@ -2477,7 +2501,8 @@ translation_unit_visitor::build_template_instantiation_process_type_argument(
|
||||
}
|
||||
|
||||
if (param_type->isBuiltinType()) {
|
||||
argument.add_template_param(template_parameter::make_argument(
|
||||
argument.add_template_param(
|
||||
template_parameter::make_argument(
|
||||
param_type.getAsString()));
|
||||
continue;
|
||||
}
|
||||
@@ -2559,7 +2584,8 @@ translation_unit_visitor::build_template_instantiation_process_type_argument(
|
||||
if (nested_template_instantiation &&
|
||||
diagram().should_include(
|
||||
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(
|
||||
{relationship_t::kDependency,
|
||||
nested_template_instantiation->id()});
|
||||
@@ -2638,6 +2664,24 @@ template_parameter translation_unit_visitor::
|
||||
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::
|
||||
build_template_instantiation_process_expression_argument(
|
||||
const clang::TemplateArgument &arg) const
|
||||
@@ -2647,6 +2691,16 @@ template_parameter translation_unit_visitor::
|
||||
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::
|
||||
build_template_instantiation_process_tag_argument(
|
||||
class_ &template_instantiation,
|
||||
@@ -2668,7 +2722,8 @@ void translation_unit_visitor::
|
||||
record_type_decl != nullptr) {
|
||||
|
||||
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
|
||||
// template
|
||||
template_instantiation.add_relationship(
|
||||
@@ -2686,7 +2741,8 @@ void translation_unit_visitor::
|
||||
#if LLVM_VERSION_MAJOR >= 16
|
||||
argument.set_type(record_type_decl->getQualifiedNameAsString());
|
||||
#endif
|
||||
if (diagram().should_include(full_template_specialization_name)) {
|
||||
if (diagram().should_include(
|
||||
full_template_specialization_name)) {
|
||||
// Add dependency relationship to the parent
|
||||
// template
|
||||
template_instantiation.add_relationship(
|
||||
@@ -2830,7 +2886,8 @@ void translation_unit_visitor::process_field(
|
||||
&field_declaration, *template_field_type, {&c});
|
||||
|
||||
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
|
||||
// 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 :
|
||||
template_specialization.template_params()) {
|
||||
|
||||
LOG_DBG("Looking for nested relationships from {}::{} in "
|
||||
LOG_DBG(
|
||||
"Looking for nested relationships from {}::{} in "
|
||||
"template {}",
|
||||
c.full_name(false), field_name,
|
||||
template_argument.to_string(
|
||||
@@ -2871,7 +2929,8 @@ void translation_unit_visitor::process_field(
|
||||
[&d = diagram()](const std::string &full_name) {
|
||||
if (full_name.empty())
|
||||
return false;
|
||||
auto [ns, name] = common::split_ns(full_name);
|
||||
auto [ns, name] =
|
||||
common::split_ns(full_name);
|
||||
return d.should_include(ns, name);
|
||||
});
|
||||
}
|
||||
@@ -2897,10 +2956,10 @@ void translation_unit_visitor::process_field(
|
||||
field_type->getAsRecordDecl()->getNameAsString().empty()) {
|
||||
// Relationships to fields whose type is an anonymous nested
|
||||
// struct have to be handled separately here
|
||||
anonymous_struct_relationships_[field_type->getAsRecordDecl()
|
||||
->getID()] =
|
||||
std::make_tuple(
|
||||
field.name(), relationship_hint, field.access());
|
||||
anonymous_struct_relationships_
|
||||
[field_type->getAsRecordDecl()->getID()] =
|
||||
std::make_tuple(field.name(), relationship_hint,
|
||||
field.access());
|
||||
}
|
||||
else
|
||||
find_relationships(
|
||||
@@ -2932,7 +2991,8 @@ void translation_unit_visitor::resolve_local_to_global_ids()
|
||||
if (rel.type() == relationship_t::kInstantiation) {
|
||||
const auto maybe_id = get_ast_local_id(rel.destination());
|
||||
if (maybe_id) {
|
||||
LOG_DBG("= Resolved instantiation destination from local "
|
||||
LOG_DBG(
|
||||
"= Resolved instantiation destination from local "
|
||||
"id {} to global id {}",
|
||||
rel.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()) {
|
||||
// Handle typename constraint in requires clause
|
||||
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()) +
|
||||
cpt->getNameAsString().size() + 1);
|
||||
|
||||
|
||||
@@ -225,6 +225,15 @@ private:
|
||||
template_parameter build_template_instantiation_process_integral_argument(
|
||||
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(
|
||||
std::optional<clanguml::class_diagram::model::class_ *> &parent,
|
||||
const clang::Decl *cls,
|
||||
|
||||
Reference in New Issue
Block a user