diff --git a/src/lib/AST/ASTVisitor.cpp b/src/lib/AST/ASTVisitor.cpp index 508f77b81..303a8e12c 100644 --- a/src/lib/AST/ASTVisitor.cpp +++ b/src/lib/AST/ASTVisitor.cpp @@ -2382,26 +2382,16 @@ getSFINAEControlParams( // template argument in a list of template arguments. It is used // to find the index of the controlling parameter in the list of // template arguments of the template declaration. - auto FindParam = [this]( - llvm::ArrayRef Arguments, - clang::TemplateArgument const& Arg) -> std::size_t - { - if (Arg.getKind() != clang::TemplateArgument::Type) - { - return -1; - } - auto const It = std::ranges::find_if( - Arguments, - [&](clang::TemplateArgument const& Other) - { - if (Other.getKind() != clang::TemplateArgument::Type) - { - return false; - } - return context_.hasSameType(Other.getAsType(), Arg.getAsType()); - }); + auto FindParam = + [this]( + llvm::ArrayRef Arguments, + clang::TemplateArgument const& Arg) -> std::size_t { + auto const It = std::ranges:: + find_if(Arguments, [&](clang::TemplateArgument const& Other) { + return context_.isSameTemplateArgument(Arg, Other); + }); bool const found = It != Arguments.end(); - return found ? It - Arguments.data() : static_cast(-1); + return found ? It - Arguments.begin() : static_cast(-1); }; if(auto* ATD = dyn_cast(TD)) @@ -2441,9 +2431,40 @@ getSFINAEControlParams( // the primary template arguments clang::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(-1)) + { + continue; + } + + primaryControllingParams.set(ParamIdx); + } + } + return SFINAEControlParams( primaryTemplParams, - std::move(sfinaeControl->ControllingParams), + std::move(primaryControllingParams), ParamIdx); } diff --git a/test-files/golden-tests/config/sfinae/alias.adoc b/test-files/golden-tests/config/sfinae/alias.adoc new file mode 100644 index 000000000..e054a5b6e --- /dev/null +++ b/test-files/golden-tests/config/sfinae/alias.adoc @@ -0,0 +1,86 @@ += Reference +:mrdocs: + +[#index] +== Global namespace + +=== Types + +[cols=1] +|=== +| Name +| link:#enable_if_t[`enable_if_t`] +| link:#if_enable_t[`if_enable_t`] +|=== + +=== Functions + +[cols=1] +|=== +| Name +| link:#f1[`f1`] +| link:#f2[`f2`] +|=== + +[#enable_if_t] +== enable_if_t + +=== Synopsis + +Declared in `<alias.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +template< + bool C, + typename T> +using enable_if_t = T; +---- + +[#if_enable_t] +== if_enable_t + +=== Synopsis + +Declared in `<alias.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +template< + typename T, + bool C> +using if_enable_t = T; +---- + +[#f1] +== f1 + +=== Synopsis + +Declared in `<alias.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +template<typename T> +T +f1() +requires std::is_class_v<T>; +---- + +[#f2] +== f2 + +=== Synopsis + +Declared in `<alias.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +template<typename T> +T +f2() +requires std::is_class_v<T>; +---- + + +[.small]#Created with https://www.mrdocs.com[MrDocs]# diff --git a/test-files/golden-tests/config/sfinae/alias.cpp b/test-files/golden-tests/config/sfinae/alias.cpp new file mode 100644 index 000000000..8aa619178 --- /dev/null +++ b/test-files/golden-tests/config/sfinae/alias.cpp @@ -0,0 +1,17 @@ +#include + +// just like std::enable_if_t +template +using enable_if_t = typename std::enable_if::type; + +template +enable_if_t, T> +f1(); + +// reversed param order +template +using if_enable_t = typename std::enable_if::type; + +template +if_enable_t> +f2(); diff --git a/test-files/golden-tests/config/sfinae/alias.html b/test-files/golden-tests/config/sfinae/alias.html new file mode 100644 index 000000000..186e44474 --- /dev/null +++ b/test-files/golden-tests/config/sfinae/alias.html @@ -0,0 +1,111 @@ + + +Reference + + +
+

Reference

+
+
+

+
+

Types

+ + + + + + + + + + + +
Name
enable_if_t
if_enable_t
+ +

Functions

+ + + + + + + + + + + +
Name
f1
f2
+ +
+
+
+

enable_if_t

+
+
+

Synopsis

+
+Declared in <alias.cpp>
+
+template<
+    bool C,
+    typename T>
+using enable_if_t = T;
+
+
+
+
+
+

if_enable_t

+
+
+

Synopsis

+
+Declared in <alias.cpp>
+
+template<
+    typename T,
+    bool C>
+using if_enable_t = T;
+
+
+
+
+
+

f1

+
+
+

Synopsis

+
+Declared in <alias.cpp>
+
+template<typename T>
+T
+f1()
+requires std::is_class_v<T>;
+
+
+
+
+
+

f2

+
+
+

Synopsis

+
+Declared in <alias.cpp>
+
+template<typename T>
+T
+f2()
+requires std::is_class_v<T>;
+
+
+
+ +
+
+

Created with MrDocs

+
+ + \ No newline at end of file diff --git a/test-files/golden-tests/config/sfinae/alias.xml b/test-files/golden-tests/config/sfinae/alias.xml new file mode 100644 index 000000000..779e498a8 --- /dev/null +++ b/test-files/golden-tests/config/sfinae/alias.xml @@ -0,0 +1,40 @@ + + + + + + + + + diff --git a/test-files/golden-tests/regression/1057.adoc b/test-files/golden-tests/regression/1057.adoc new file mode 100644 index 000000000..6aa15593b --- /dev/null +++ b/test-files/golden-tests/regression/1057.adoc @@ -0,0 +1,140 @@ += Reference +:mrdocs: + +[#index] +== Global namespace + +=== Types + +[cols=1] +|=== +| Name +| link:#enable_if-03[`enable_if`] +| link:#enable_if-0e[`enable_if<false, T>`] +| link:#is_match[`is_match`] +| link:#_UniqAssignable[`_UniqAssignable`] +| link:#_UniqCompatible[`_UniqCompatible`] +|=== + +[#_UniqAssignable] +== _UniqAssignable + +=== Synopsis + +Declared in `<1057.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +template< + typename _Yp, + typename _Del> +using _UniqAssignable = int; +---- + +[#_UniqCompatible] +== _UniqCompatible + +=== Synopsis + +Declared in `<1057.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +template< + typename _Yp, + typename _Del, + typename _Res> +using _UniqCompatible = _Res; +---- + +[#enable_if-03] +== enable_if + +=== Synopsis + +Declared in `<1057.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +template< + bool C, + typename T> +struct enable_if; +---- + +=== Types + +[cols=1] +|=== +| Name +| link:#enable_if-03-type[`type`] +|=== + +[#enable_if-03-type] +== link:#enable_if-03[enable_if]::type + +=== Synopsis + +Declared in `<1057.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +using type = T; +---- + +[#enable_if-0e] +== link:#enable_if-03[enable_if]<false, T> + +=== Synopsis + +Declared in `<1057.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +template<typename T> +struct link:#enable_if-03[enable_if]<false, T>; +---- + +[#is_match] +== is_match + +=== Synopsis + +Declared in `<1057.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +template<typename T> +struct is_match; +---- + +=== Enums + +[cols=1] +|=== +| Name +| link:#is_match-_04enum[`Unnamed enum`] +|=== + +[#is_match-_04enum] +== link:#is_match[is_match]::Unnamed enum + +=== Synopsis + +Declared in `<1057.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +enum Unnamed enum; +---- + +=== Members + +[cols=1] +|=== +| Name +| `value` +|=== + + +[.small]#Created with https://www.mrdocs.com[MrDocs]# diff --git a/test-files/golden-tests/regression/1057.cpp b/test-files/golden-tests/regression/1057.cpp new file mode 100644 index 000000000..3953f87c5 --- /dev/null +++ b/test-files/golden-tests/regression/1057.cpp @@ -0,0 +1,21 @@ + +template +struct enable_if { + using type = T; +}; + +template +struct enable_if {}; + +template +struct is_match { + enum { + value = false + }; +}; + +template +using _UniqCompatible = typename enable_if::value, _Res>::type; + +template +using _UniqAssignable = _UniqCompatible<_Yp, _Del, int>; diff --git a/test-files/golden-tests/regression/1057.html b/test-files/golden-tests/regression/1057.html new file mode 100644 index 000000000..58aafa11a --- /dev/null +++ b/test-files/golden-tests/regression/1057.html @@ -0,0 +1,184 @@ + + +Reference + + +
+

Reference

+
+
+

+
+

Types

+ + + + + + + + + + + + + + +
Name
enable_if
enable_if<false, T>
is_match
_UniqAssignable
_UniqCompatible
+ +
+
+
+

_UniqAssignable

+
+
+

Synopsis

+
+Declared in <1057.cpp>
+
+template<
+    typename _Yp,
+    typename _Del>
+using _UniqAssignable = int;
+
+
+
+
+
+

_UniqCompatible

+
+
+

Synopsis

+
+Declared in <1057.cpp>
+
+template<
+    typename _Yp,
+    typename _Del,
+    typename _Res>
+using _UniqCompatible = _Res;
+
+
+
+
+
+

enable_if

+
+
+

Synopsis

+
+Declared in <1057.cpp>
+
+template<
+    bool C,
+    typename T>
+struct enable_if;
+
+
+

Types

+ + + + + + + + + + +
Name
type
+ + + +
+
+
+

enable_if::type

+
+
+

Synopsis

+
+Declared in <1057.cpp>
+
+using type = T;
+
+
+
+
+
+

enable_if<false, T>

+
+
+

Synopsis

+
+Declared in <1057.cpp>
+
+template<typename T>
+struct enable_if<false, T>;
+
+
+ + +
+
+
+

is_match

+
+
+

Synopsis

+
+Declared in <1057.cpp>
+
+template<typename T>
+struct is_match;
+
+
+

Enums

+ + + + + + + + + + +
Name
Unnamed enum
+ + + +
+
+
+

is_match::

+
+
+

Synopsis

+
+Declared in <1057.cpp>
+
+enum Unnamed enum;
+
+
+

Members

+ + + + + + + + + + +
Name
value
+ +
+ +
+
+

Created with MrDocs

+
+ + \ No newline at end of file diff --git a/test-files/golden-tests/regression/1057.xml b/test-files/golden-tests/regression/1057.xml new file mode 100644 index 000000000..1be4e5cdd --- /dev/null +++ b/test-files/golden-tests/regression/1057.xml @@ -0,0 +1,54 @@ + + + + + + + + + +