From fd889403c76825796df640bf35e6f0cca67710b7 Mon Sep 17 00:00:00 2001 From: Agustin Berge Date: Wed, 8 Oct 2025 15:29:29 +0200 Subject: [PATCH 1/7] remap controlling params --- src/lib/AST/ASTVisitor.cpp | 41 +++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/src/lib/AST/ASTVisitor.cpp b/src/lib/AST/ASTVisitor.cpp index a33826061..4a8e79b3a 100644 --- a/src/lib/AST/ASTVisitor.cpp +++ b/src/lib/AST/ASTVisitor.cpp @@ -2362,19 +2362,23 @@ getSFINAEControlParams( ArrayRef 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) + if (Arg.getKind() != Other.getKind()) { return false; } - return context_.hasSameType(Other.getAsType(), Arg.getAsType()); + if (Arg.getKind() == TemplateArgument::Type) + { + return context_.hasSameType(Other.getAsType(), Arg.getAsType()); + } + if (Arg.getKind() == TemplateArgument::Expression) + { + return context_.hasSameExpr(Other.getAsExpr(), Arg.getAsExpr()); + } + return false; }); bool const found = It != Arguments.end(); return found ? It - Arguments.data() : static_cast(-1); @@ -2417,9 +2421,32 @@ 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 + unsigned ParamIdx = FindParam(ATD->getInjectedTemplateArgs(context_), *resultType); + + primaryControllingParams.set(ParamIdx); + } + } + return SFINAEControlParams( primaryTemplParams, - std::move(sfinaeControl->ControllingParams), + std::move(primaryControllingParams), ParamIdx); } From 00d826e062ef4364ed796e2dbd6f37f80b17d6c0 Mon Sep 17 00:00:00 2001 From: Agustin Berge Date: Wed, 8 Oct 2025 16:00:18 +0200 Subject: [PATCH 2/7] test --- .../golden-tests/config/sfinae/alias.adoc | 86 +++++++++++++ .../golden-tests/config/sfinae/alias.cpp | 15 +++ .../golden-tests/config/sfinae/alias.html | 119 ++++++++++++++++++ .../golden-tests/config/sfinae/alias.xml | 40 ++++++ 4 files changed, 260 insertions(+) create mode 100644 test-files/golden-tests/config/sfinae/alias.adoc create mode 100644 test-files/golden-tests/config/sfinae/alias.cpp create mode 100644 test-files/golden-tests/config/sfinae/alias.html create mode 100644 test-files/golden-tests/config/sfinae/alias.xml 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..14a90db1b --- /dev/null +++ b/test-files/golden-tests/config/sfinae/alias.cpp @@ -0,0 +1,15 @@ +#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..4e1f96e22 --- /dev/null +++ b/test-files/golden-tests/config/sfinae/alias.html @@ -0,0 +1,119 @@ + + +Reference + + +
+

Reference

+
+
+

+
+

Types

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

Functions

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

Synopsis

+
+Declared in <alias.cpp>
+
+template<
+    bool C,
+    typename T>
+using enable_if_t = 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..b70d6508d --- /dev/null +++ b/test-files/golden-tests/config/sfinae/alias.xml @@ -0,0 +1,40 @@ + + + + + + + + + From 401d63e4f3ae657c03545f8c496f7452a00b7fd5 Mon Sep 17 00:00:00 2001 From: Agustin Berge Date: Wed, 8 Oct 2025 17:31:21 +0200 Subject: [PATCH 3/7] skip not found --- src/lib/AST/ASTVisitor.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/AST/ASTVisitor.cpp b/src/lib/AST/ASTVisitor.cpp index 4a8e79b3a..cfb0d5518 100644 --- a/src/lib/AST/ASTVisitor.cpp +++ b/src/lib/AST/ASTVisitor.cpp @@ -2381,7 +2381,7 @@ getSFINAEControlParams( return false; }); 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)) @@ -2439,6 +2439,7 @@ getSFINAEControlParams( // Find the index of the parameter that represents the param // in the primary template arguments unsigned ParamIdx = FindParam(ATD->getInjectedTemplateArgs(context_), *resultType); + if (ParamIdx == -1) continue; primaryControllingParams.set(ParamIdx); } From 4ba3e6b817f5222908c4cfe707896ba6f5d2a7f7 Mon Sep 17 00:00:00 2001 From: Agustin Berge Date: Thu, 9 Oct 2025 09:33:08 +0200 Subject: [PATCH 4/7] warn --- src/lib/AST/ASTVisitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/AST/ASTVisitor.cpp b/src/lib/AST/ASTVisitor.cpp index cfb0d5518..a1e0556eb 100644 --- a/src/lib/AST/ASTVisitor.cpp +++ b/src/lib/AST/ASTVisitor.cpp @@ -2439,7 +2439,7 @@ getSFINAEControlParams( // Find the index of the parameter that represents the param // in the primary template arguments unsigned ParamIdx = FindParam(ATD->getInjectedTemplateArgs(context_), *resultType); - if (ParamIdx == -1) continue; + if (ParamIdx == static_cast(-1)) continue; primaryControllingParams.set(ParamIdx); } From 1a7a89a7681b0c7c35901fe9570a4f05cb3ed320 Mon Sep 17 00:00:00 2001 From: Agustin Berge Date: Thu, 9 Oct 2025 09:35:04 +0200 Subject: [PATCH 5/7] warn --- src/lib/AST/ASTVisitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/AST/ASTVisitor.cpp b/src/lib/AST/ASTVisitor.cpp index a1e0556eb..da7c82582 100644 --- a/src/lib/AST/ASTVisitor.cpp +++ b/src/lib/AST/ASTVisitor.cpp @@ -2438,7 +2438,7 @@ getSFINAEControlParams( // Find the index of the parameter that represents the param // in the primary template arguments - unsigned ParamIdx = FindParam(ATD->getInjectedTemplateArgs(context_), *resultType); + auto ParamIdx = FindParam(ATD->getInjectedTemplateArgs(context_), *resultType); if (ParamIdx == static_cast(-1)) continue; primaryControllingParams.set(ParamIdx); From 28fdec0baeb6faedad0377fc5da621b7ce019420 Mon Sep 17 00:00:00 2001 From: Agustin Berge Date: Thu, 9 Oct 2025 09:56:12 +0200 Subject: [PATCH 6/7] regression test --- test-files/golden-tests/regression/1057.adoc | 143 +++++++++++++ test-files/golden-tests/regression/1057.cpp | 15 ++ test-files/golden-tests/regression/1057.html | 202 +++++++++++++++++++ test-files/golden-tests/regression/1057.xml | 54 +++++ 4 files changed, 414 insertions(+) create mode 100644 test-files/golden-tests/regression/1057.adoc create mode 100644 test-files/golden-tests/regression/1057.cpp create mode 100644 test-files/golden-tests/regression/1057.html create mode 100644 test-files/golden-tests/regression/1057.xml diff --git a/test-files/golden-tests/regression/1057.adoc b/test-files/golden-tests/regression/1057.adoc new file mode 100644 index 000000000..f46ae62da --- /dev/null +++ b/test-files/golden-tests/regression/1057.adoc @@ -0,0 +1,143 @@ += 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=2] +|=== +| Name +| Description +|`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..cdd42866d --- /dev/null +++ b/test-files/golden-tests/regression/1057.cpp @@ -0,0 +1,15 @@ + +template +struct enable_if { using type = T; }; + +template < typename T> +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..9ade92b8b --- /dev/null +++ b/test-files/golden-tests/regression/1057.html @@ -0,0 +1,202 @@ + + +Reference + + +
+

Reference

+
+
+

+
+

Types

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

Synopsis

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

Synopsis

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

Synopsis

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

Types

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

Synopsis

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

Synopsis

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

Synopsis

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

Enums

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

Synopsis

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

Members

+ + + + + + + + + + + + + +
NameDescription
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..2b860ddfb --- /dev/null +++ b/test-files/golden-tests/regression/1057.xml @@ -0,0 +1,54 @@ + + + + + + + + + + From 4e99ce92ddaf69d6af3391b618e10a86f08ac571 Mon Sep 17 00:00:00 2001 From: Agustin Berge Date: Fri, 10 Oct 2025 08:46:25 +0200 Subject: [PATCH 7/7] isSameTemplateArgument --- src/lib/AST/ASTVisitor.cpp | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/lib/AST/ASTVisitor.cpp b/src/lib/AST/ASTVisitor.cpp index da7c82582..c32ca1e00 100644 --- a/src/lib/AST/ASTVisitor.cpp +++ b/src/lib/AST/ASTVisitor.cpp @@ -2366,19 +2366,7 @@ getSFINAEControlParams( Arguments, [&](TemplateArgument const& Other) { - if (Arg.getKind() != Other.getKind()) - { - return false; - } - if (Arg.getKind() == TemplateArgument::Type) - { - return context_.hasSameType(Other.getAsType(), Arg.getAsType()); - } - if (Arg.getKind() == TemplateArgument::Expression) - { - return context_.hasSameExpr(Other.getAsExpr(), Arg.getAsExpr()); - } - return false; + return context_.isSameTemplateArgument(Arg, Other); }); bool const found = It != Arguments.end(); return found ? It - Arguments.begin() : static_cast(-1);