Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 27 additions & 11 deletions src/lib/AST/ASTVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2362,22 +2362,14 @@ getSFINAEControlParams(
ArrayRef<TemplateArgument> Arguments,
TemplateArgument const& Arg) -> std::size_t
{
if (Arg.getKind() != TemplateArgument::Type)
{
return -1;
}
auto const It = std::ranges::find_if(
Arguments,
[&](TemplateArgument const& Other)
{
if (Other.getKind() != TemplateArgument::Type)
{
return false;
}
return context_.hasSameType(Other.getAsType(), Arg.getAsType());
return context_.isSameTemplateArgument(Arg, Other);
});
bool const found = It != Arguments.end();
return found ? It - Arguments.data() : static_cast<std::size_t>(-1);
return found ? It - Arguments.begin() : static_cast<std::size_t>(-1);
};

if(auto* ATD = dyn_cast<TypeAliasTemplateDecl>(TD))
Expand Down Expand Up @@ -2417,9 +2409,33 @@ getSFINAEControlParams(
// the primary template arguments
TemplateParameterList* primaryTemplParams = ATD->getTemplateParameters();
MRDOCS_SYMBOL_TRACE(primaryTemplParams, context_);

llvm::SmallBitVector primaryControllingParams(primaryTemplParams->size());
for (std::size_t i = 0; i < sfinaeControl->ControllingParams.size(); ++i)
{
if (sfinaeControl->ControllingParams[i])
{
// Find the index of the parameter that represents the SFINAE result
// in the underlying template arguments
auto resultType = tryGetTemplateArgument(
sfinaeControl->Parameters,
underlyingTemplateInfo->Arguments,
i);
MRDOCS_CHECK_OR_CONTINUE(resultType);
MRDOCS_SYMBOL_TRACE(*resultType, context_);

// Find the index of the parameter that represents the param
// in the primary template arguments
auto ParamIdx = FindParam(ATD->getInjectedTemplateArgs(context_), *resultType);
if (ParamIdx == static_cast<std::size_t>(-1)) continue;

primaryControllingParams.set(ParamIdx);
}
}

return SFINAEControlParams(
primaryTemplParams,
std::move(sfinaeControl->ControllingParams),
std::move(primaryControllingParams),
ParamIdx);
}

Expand Down
86 changes: 86 additions & 0 deletions test-files/golden-tests/config/sfinae/alias.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
= Reference
:mrdocs:

[#index]
== Global namespace

=== Types

[cols=1]
|===
| Name
| link:#enable_if_t[`enable&lowbar;if&lowbar;t`]
| link:#if_enable_t[`if&lowbar;enable&lowbar;t`]
|===

=== Functions

[cols=1]
|===
| Name
| link:#f1[`f1`]
| link:#f2[`f2`]
|===

[#enable_if_t]
== enable&lowbar;if&lowbar;t

=== Synopsis

Declared in `&lt;alias&period;cpp&gt;`

[source,cpp,subs="verbatim,replacements,macros,-callouts"]
----
template&lt;
bool C,
typename T&gt;
using enable&lowbar;if&lowbar;t = T;
----

[#if_enable_t]
== if&lowbar;enable&lowbar;t

=== Synopsis

Declared in `&lt;alias&period;cpp&gt;`

[source,cpp,subs="verbatim,replacements,macros,-callouts"]
----
template&lt;
typename T,
bool C&gt;
using if&lowbar;enable&lowbar;t = T;
----

[#f1]
== f1

=== Synopsis

Declared in `&lt;alias&period;cpp&gt;`

[source,cpp,subs="verbatim,replacements,macros,-callouts"]
----
template&lt;typename T&gt;
T
f1()
requires std&colon;&colon;is&lowbar;class&lowbar;v&lt;T&gt;;
----

[#f2]
== f2

=== Synopsis

Declared in `&lt;alias&period;cpp&gt;`

[source,cpp,subs="verbatim,replacements,macros,-callouts"]
----
template&lt;typename T&gt;
T
f2()
requires std&colon;&colon;is&lowbar;class&lowbar;v&lt;T&gt;;
----


[.small]#Created with https://www.mrdocs.com[MrDocs]#
15 changes: 15 additions & 0 deletions test-files/golden-tests/config/sfinae/alias.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include <type_traits>

// just like std::enable_if_t
template <bool C, typename T>
using enable_if_t = typename std::enable_if<C, T>::type;

template <typename T>
enable_if_t<std::is_class_v<T>, T> f1();

// reversed param order
template <typename T, bool C>
using if_enable_t = typename std::enable_if<C, T>::type;

template <typename T>
if_enable_t<T, std::is_class_v<T>> f2();
119 changes: 119 additions & 0 deletions test-files/golden-tests/config/sfinae/alias.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<html lang="en">
<head>
<title>Reference</title>
</head>
<body>
<div>
<h1>Reference</h1>
<div>
<div>
<h2 id="index"><a href="#index"></a></h2>
</div>
<h2>Types</h2>
<table style="table-layout: fixed; width: 100%;">
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="#enable_if_t"><code>enable_if_t</code></a> </td></tr><tr>
<td><a href="#if_enable_t"><code>if_enable_t</code></a> </td></tr>
</tbody>
</table>

<h2>Functions</h2>
<table style="table-layout: fixed; width: 100%;">
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="#f1"><code>f1</code></a> </td></tr><tr>
<td><a href="#f2"><code>f2</code></a> </td></tr>
</tbody>
</table>

</div>
<div>
<div>
<h2 id="enable_if_t"><a href="#enable_if_t">enable_if_t</a></h2>
</div>
<div>
<h3>Synopsis</h3>
<div>
Declared in <code>&lt;alias.cpp&gt;</code></div>
<pre>
<code class="source-code cpp">template&lt;
bool C,
typename T&gt;
using enable_if_t = T;

</code>
</pre>
</div>
</div>
<div>
<div>
<h2 id="if_enable_t"><a href="#if_enable_t">if_enable_t</a></h2>
</div>
<div>
<h3>Synopsis</h3>
<div>
Declared in <code>&lt;alias.cpp&gt;</code></div>
<pre>
<code class="source-code cpp">template&lt;
typename T,
bool C&gt;
using if_enable_t = T;

</code>
</pre>
</div>
</div>
<div>
<div>
<h2 id="f1"><a href="#f1">f1</a></h2>
</div>
<div>
<h3>Synopsis</h3>
<div>
Declared in <code>&lt;alias.cpp&gt;</code></div>
<pre>
<code class="source-code cpp">template&lt;typename T&gt;
T
f1()
requires std::is_class_v&lt;T&gt;;

</code>
</pre>
</div>
</div>
<div>
<div>
<h2 id="f2"><a href="#f2">f2</a></h2>
</div>
<div>
<h3>Synopsis</h3>
<div>
Declared in <code>&lt;alias.cpp&gt;</code></div>
<pre>
<code class="source-code cpp">template&lt;typename T&gt;
T
f2()
requires std::is_class_v&lt;T&gt;;

</code>
</pre>
</div>
</div>

</div>
<div>
<h4>Created with <a href="https://www.mrdocs.com">MrDocs</a></h4>
</div>
</body>
</html>
40 changes: 40 additions & 0 deletions test-files/golden-tests/config/sfinae/alias.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<mrdocs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://github.com/cppalliance/mrdocs/raw/develop/mrdocs.rnc">
<namespace id="//////////////////////////8=">
<template>
<tparam name="C" class="non-type" type="bool"/>
<tparam name="T" class="type"/>
<namespace-alias name="enable_if_t" id="G6KvcosPT2J4Mp72/Jj/t+hpu7w=">
<file short-path="alias.cpp" source-path="alias.cpp" line="4"/>
<type name="T"/>
</namespace-alias>
</template>
<template>
<tparam name="T" class="type"/>
<tparam name="C" class="non-type" type="bool"/>
<namespace-alias name="if_enable_t" id="3mL2o5cGgdygMfQf6RJVMv4YrLg=">
<file short-path="alias.cpp" source-path="alias.cpp" line="11"/>
<type name="T"/>
</namespace-alias>
</template>
<template>
<tparam name="T" class="type"/>
<function name="f1" requires="std::is_class_v&lt;T&gt;" id="wxSwXFUt9arsW/YBeWhVf1gINhw=">
<file short-path="alias.cpp" source-path="alias.cpp" line="7"/>
<return>
<type name="T"/>
</return>
</function>
</template>
<template>
<tparam name="T" class="type"/>
<function name="f2" requires="std::is_class_v&lt;T&gt;" id="koj7SBKjX4SV47aOs0homZpcPWQ=">
<file short-path="alias.cpp" source-path="alias.cpp" line="14"/>
<return>
<type name="T"/>
</return>
</function>
</template>
</namespace>
</mrdocs>
Loading
Loading