Added support for template type aliases only available as unexposed arguments
This commit is contained in:
@@ -175,12 +175,21 @@ void translation_unit_visitor::operator()(const cppast::cpp_entity &file)
|
|||||||
|
|
||||||
auto &at = static_cast<const cppast::cpp_alias_template &>(e);
|
auto &at = static_cast<const cppast::cpp_alias_template &>(e);
|
||||||
|
|
||||||
|
if (at.type_alias().underlying_type().kind() ==
|
||||||
|
cppast::cpp_type_kind::unexposed_t) {
|
||||||
|
LOG_WARN("Template alias has unexposed underlying type: {}",
|
||||||
|
static_cast<const cppast::cpp_unexposed_type &>(
|
||||||
|
at.type_alias().underlying_type())
|
||||||
|
.name());
|
||||||
|
}
|
||||||
|
else {
|
||||||
class_ tinst = build_template_instantiation(static_cast<
|
class_ tinst = build_template_instantiation(static_cast<
|
||||||
const cppast::cpp_template_instantiation_type &>(
|
const cppast::cpp_template_instantiation_type &>(
|
||||||
at.type_alias().underlying_type()));
|
at.type_alias().underlying_type()));
|
||||||
|
|
||||||
ctx.diagram().add_class(std::move(tinst));
|
ctx.diagram().add_class(std::move(tinst));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,6 +417,18 @@ void translation_unit_visitor::process_class_declaration(
|
|||||||
for (const auto &t : toks) {
|
for (const auto &t : toks) {
|
||||||
c.add_template({t});
|
c.add_template({t});
|
||||||
|
|
||||||
|
if (!tspec.value().primary_template().is_overloaded()) {
|
||||||
|
if (tspec.value()
|
||||||
|
.primary_template()
|
||||||
|
.get(ctx.entity_index())
|
||||||
|
.size() == 0) {
|
||||||
|
LOG_WARN("Template {} has no exposed arguments",
|
||||||
|
tspec.value().name());
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const auto &primary_template_ref =
|
const auto &primary_template_ref =
|
||||||
static_cast<const cppast::cpp_class_template &>(
|
static_cast<const cppast::cpp_class_template &>(
|
||||||
tspec.value()
|
tspec.value()
|
||||||
@@ -886,16 +907,28 @@ void translation_unit_visitor::process_function_parameter(
|
|||||||
// not an instantiation but just a reference to an existing
|
// not an instantiation but just a reference to an existing
|
||||||
// template
|
// template
|
||||||
bool template_is_not_instantiation{false};
|
bool template_is_not_instantiation{false};
|
||||||
|
if (template_instantiation_type.arguments_exposed()) {
|
||||||
|
LOG_DBG("Processing template method argument exposed "
|
||||||
|
"parameters...");
|
||||||
|
|
||||||
for (const auto &template_argument :
|
for (const auto &template_argument :
|
||||||
template_instantiation_type.arguments().value()) {
|
template_instantiation_type.arguments().value()) {
|
||||||
const auto template_argument_name =
|
const auto template_argument_name =
|
||||||
cppast::to_string(template_argument.type().value());
|
cppast::to_string(template_argument.type().value());
|
||||||
if (template_parameter_names.count(template_argument_name) >
|
if (template_parameter_names.count(
|
||||||
0) {
|
template_argument_name) > 0) {
|
||||||
template_is_not_instantiation = true;
|
template_is_not_instantiation = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG_DBG("Processing template method argument unexposed "
|
||||||
|
"parameters: ",
|
||||||
|
template_instantiation_type.unexposed_arguments());
|
||||||
|
// TODO: Process unexposed arguments by manually parsing the
|
||||||
|
// arguments string
|
||||||
|
}
|
||||||
|
|
||||||
LOG_DBG("Maybe building instantiation for: {}",
|
LOG_DBG("Maybe building instantiation for: {}",
|
||||||
primary_template_name);
|
primary_template_name);
|
||||||
@@ -1177,7 +1210,6 @@ class_ translation_unit_visitor::build_template_instantiation(
|
|||||||
|
|
||||||
std::deque<std::tuple<std::string, int, bool>> template_base_params{};
|
std::deque<std::tuple<std::string, int, bool>> template_base_params{};
|
||||||
|
|
||||||
// Determine the full template name
|
|
||||||
if (t.primary_template().get(ctx.entity_index()).size()) {
|
if (t.primary_template().get(ctx.entity_index()).size()) {
|
||||||
const auto &primary_template_ref =
|
const auto &primary_template_ref =
|
||||||
static_cast<const cppast::cpp_class_template &>(
|
static_cast<const cppast::cpp_class_template &>(
|
||||||
@@ -1293,6 +1325,7 @@ class_ translation_unit_visitor::build_template_instantiation(
|
|||||||
// Process template argumetns
|
// Process template argumetns
|
||||||
int arg_index{0};
|
int arg_index{0};
|
||||||
bool variadic_params{false};
|
bool variadic_params{false};
|
||||||
|
if (t.arguments_exposed()) {
|
||||||
for (const auto &targ : t.arguments().value()) {
|
for (const auto &targ : t.arguments().value()) {
|
||||||
bool add_template_argument_as_base_class{false};
|
bool add_template_argument_as_base_class{false};
|
||||||
class_template ct;
|
class_template ct;
|
||||||
@@ -1301,7 +1334,8 @@ class_ translation_unit_visitor::build_template_instantiation(
|
|||||||
|
|
||||||
LOG_DBG("Template argument is a type {}", ct.type());
|
LOG_DBG("Template argument is a type {}", ct.type());
|
||||||
auto fn = cx::util::full_name(
|
auto fn = cx::util::full_name(
|
||||||
cppast::remove_cv(cx::util::unreferenced(targ.type().value())),
|
cppast::remove_cv(
|
||||||
|
cx::util::unreferenced(targ.type().value())),
|
||||||
ctx.entity_index(), false);
|
ctx.entity_index(), false);
|
||||||
|
|
||||||
if (targ.type().value().kind() ==
|
if (targ.type().value().kind() ==
|
||||||
@@ -1331,9 +1365,11 @@ class_ translation_unit_visitor::build_template_instantiation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.config().should_include(tinst.full_name(false))) {
|
if (ctx.config().should_include(tinst.full_name(false))) {
|
||||||
LOG_DBG("Creating nested template dependency to template "
|
LOG_DBG(
|
||||||
|
"Creating nested template dependency to template "
|
||||||
"instantiation {}, {} -> {}",
|
"instantiation {}, {} -> {}",
|
||||||
fn, tinst.full_name(), tinst_dependency.destination());
|
fn, tinst.full_name(),
|
||||||
|
tinst_dependency.destination());
|
||||||
|
|
||||||
tinst.add_relationship(std::move(tinst_dependency));
|
tinst.add_relationship(std::move(tinst_dependency));
|
||||||
}
|
}
|
||||||
@@ -1344,23 +1380,27 @@ class_ translation_unit_visitor::build_template_instantiation(
|
|||||||
fn, (*parent)->full_name(),
|
fn, (*parent)->full_name(),
|
||||||
tinst_dependency.destination());
|
tinst_dependency.destination());
|
||||||
|
|
||||||
(*parent)->add_relationship(std::move(tinst_dependency));
|
(*parent)->add_relationship(
|
||||||
|
std::move(tinst_dependency));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG_DBG("No nested template dependency to template "
|
LOG_DBG("No nested template dependency to template "
|
||||||
"instantiation: {}, {} -> {}",
|
"instantiation: {}, {} -> {}",
|
||||||
fn, tinst.full_name(), tinst_dependency.destination());
|
fn, tinst.full_name(),
|
||||||
|
tinst_dependency.destination());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (targ.type().value().kind() ==
|
else if (targ.type().value().kind() ==
|
||||||
cppast::cpp_type_kind::user_defined_t) {
|
cppast::cpp_type_kind::user_defined_t) {
|
||||||
class_relationship tinst_dependency{relationship_t::kDependency,
|
class_relationship tinst_dependency{
|
||||||
|
relationship_t::kDependency,
|
||||||
cx::util::full_name(
|
cx::util::full_name(
|
||||||
cppast::remove_cv(
|
cppast::remove_cv(
|
||||||
cx::util::unreferenced(targ.type().value())),
|
cx::util::unreferenced(targ.type().value())),
|
||||||
ctx.entity_index(), false)};
|
ctx.entity_index(), false)};
|
||||||
|
|
||||||
LOG_DBG("Creating nested template dependency to user defined "
|
LOG_DBG(
|
||||||
|
"Creating nested template dependency to user defined "
|
||||||
"type {} -> {}",
|
"type {} -> {}",
|
||||||
tinst.full_name(), tinst_dependency.destination());
|
tinst.full_name(), tinst_dependency.destination());
|
||||||
|
|
||||||
@@ -1368,7 +1408,8 @@ class_ translation_unit_visitor::build_template_instantiation(
|
|||||||
tinst.add_relationship(std::move(tinst_dependency));
|
tinst.add_relationship(std::move(tinst_dependency));
|
||||||
}
|
}
|
||||||
else if (parent) {
|
else if (parent) {
|
||||||
(*parent)->add_relationship(std::move(tinst_dependency));
|
(*parent)->add_relationship(
|
||||||
|
std::move(tinst_dependency));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1380,7 +1421,8 @@ class_ translation_unit_visitor::build_template_instantiation(
|
|||||||
.value());
|
.value());
|
||||||
else if (exp.kind() == cppast::cpp_expression_kind::unexposed_t)
|
else if (exp.kind() == cppast::cpp_expression_kind::unexposed_t)
|
||||||
ct.set_type(
|
ct.set_type(
|
||||||
static_cast<const cppast::cpp_unexposed_expression &>(exp)
|
static_cast<const cppast::cpp_unexposed_expression &>(
|
||||||
|
exp)
|
||||||
.expression()
|
.expression()
|
||||||
.as_string());
|
.as_string());
|
||||||
|
|
||||||
@@ -1390,7 +1432,8 @@ class_ translation_unit_visitor::build_template_instantiation(
|
|||||||
// In case any of the template arguments are base classes, add
|
// In case any of the template arguments are base classes, add
|
||||||
// them as parents of the current template instantiation class
|
// them as parents of the current template instantiation class
|
||||||
if (template_base_params.size() > 0) {
|
if (template_base_params.size() > 0) {
|
||||||
auto [arg_name, is_variadic, index] = template_base_params.front();
|
auto [arg_name, is_variadic, index] =
|
||||||
|
template_base_params.front();
|
||||||
if (variadic_params)
|
if (variadic_params)
|
||||||
add_template_argument_as_base_class = true;
|
add_template_argument_as_base_class = true;
|
||||||
else {
|
else {
|
||||||
@@ -1402,8 +1445,8 @@ class_ translation_unit_visitor::build_template_instantiation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (add_template_argument_as_base_class) {
|
if (add_template_argument_as_base_class) {
|
||||||
LOG_DBG(
|
LOG_DBG("Adding template argument '{}' as base class",
|
||||||
"Adding template argument '{}' as base class", ct.type());
|
ct.type());
|
||||||
|
|
||||||
class_parent cp;
|
class_parent cp;
|
||||||
cp.set_access(access_t::kPublic);
|
cp.set_access(access_t::kPublic);
|
||||||
@@ -1417,6 +1460,7 @@ class_ translation_unit_visitor::build_template_instantiation(
|
|||||||
|
|
||||||
tinst.add_template(std::move(ct));
|
tinst.add_template(std::move(ct));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add instantiation relationship to primary template of this
|
// Add instantiation relationship to primary template of this
|
||||||
// instantiation
|
// instantiation
|
||||||
@@ -1452,5 +1496,4 @@ const cppast::cpp_type &translation_unit_visitor::resolve_alias(
|
|||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,10 +150,15 @@ std::string ns(const cppast::cpp_type &t, const cppast::cpp_entity_index &idx)
|
|||||||
else {
|
else {
|
||||||
// This is a bug/feature in libclang, where canonical representation
|
// This is a bug/feature in libclang, where canonical representation
|
||||||
// of a template type with incomplete specialization doesn't have a
|
// of a template type with incomplete specialization doesn't have a
|
||||||
// full namespace. We have to extract it from te primary template
|
// full namespace. We have to extract it from the primary template
|
||||||
const auto &primary_template =
|
const auto &primary_template =
|
||||||
static_cast<const cppast::cpp_template_instantiation_type &>(t)
|
static_cast<const cppast::cpp_template_instantiation_type &>(t)
|
||||||
.primary_template();
|
.primary_template();
|
||||||
|
if (!primary_template.is_overloaded()) {
|
||||||
|
LOG_WARN(
|
||||||
|
"Cannot establish namespace for ", cppast::to_string(t));
|
||||||
|
return "";
|
||||||
|
}
|
||||||
return ns(primary_template.get(idx)[0].get());
|
return ns(primary_template.get(idx)[0].get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user