From cc901137a12cf2d4fc468e5aeff19b82e0a232e8 Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Wed, 22 Apr 2026 16:55:47 +0200 Subject: [PATCH] feat: render long noexcept specifications as noexcept(see-below) MrDocs used to render the full `noexcept` operand inline, so a declaration like void swap(reference, reference) noexcept( std::is_nothrow_move_constructible::value && std::is_nothrow_move_assignable::value && std::is_nothrow_move_constructible::value && std::is_nothrow_move_assignable::value); buried the `noexcept` condition in a mostly-unreadable slop. This replaces operands longer than 40 characters with an italic "see-below" placeholder in the declaration, and moves the actual condition to a dedicated "noexcept Specification" section of the exposition: void swap(reference, reference) noexcept(see-below); === noexcept Specification noexcept when `...long condition...`. The section is intentionally separate from the existing "Exceptions" section, which continues to cover `@throws` documentation. Closes issue #1103. --- .../Metadata/Specifiers/ExplicitInfo.hpp | 23 +- .../Metadata/Specifiers/ExplicitKind.hpp | 9 +- .../Metadata/Specifiers/NoexceptInfo.hpp | 26 +- .../Metadata/Specifiers/NoexceptKind.hpp | 9 +- include/mrdocs/Support/MergeReflectedType.hpp | 21 +- mrdocs.rnc | 44 ++- .../adoc/partials/markup/see-below.adoc.hbs | 1 + .../generator/adoc/partials/symbol.adoc.hbs | 8 + .../partials/symbol/signature/function.hbs | 7 +- .../partials/type/declarator-suffix.hbs | 6 +- .../html/partials/markup/see-below.html.hbs | 1 + .../generator/html/partials/symbol.html.hbs | 9 + src/lib/AST/ASTVisitor.cpp | 10 +- src/lib/AST/ExtractDocComment.cpp | 2 +- src/lib/AST/ParseRef.cpp | 4 +- src/lib/CorpusImpl.cpp | 2 +- src/lib/Gen/xml/XMLWriter.cpp | 5 + src/lib/Metadata/Specifiers.cpp | 28 +- src/test/lib/Metadata/Merge.cpp | 12 +- src/test/lib/Metadata/Specifiers.cpp | 203 ++++++++++ .../extract-friends/extract-friends.xml | 4 + .../extract-friends/no-extract-friends.xml | 4 + .../javadoc/copydoc/operator-param.xml | 8 + .../golden-tests/javadoc/inline/styled.xml | 4 + .../golden-tests/snippets/function_object.xml | 8 + test-files/golden-tests/snippets/is_prime.xml | 4 + .../golden-tests/snippets/terminate.xml | 4 + .../function/explicit-conv-operator.xml | 19 + .../symbols/function/explicit-ctor.xml | 92 +++++ .../golden-tests/symbols/function/mem-fn.xml | 28 ++ .../symbols/function/noexcept.adoc | 159 ++++++++ .../symbols/function/noexcept.cpp | 38 ++ .../symbols/function/noexcept.html | 194 ++++++++++ .../symbols/function/noexcept.xml | 346 ++++++++++++++++++ .../symbols/guide/explicit-deduct-guide.xml | 19 + .../symbols/record/conditional-explicit.xml | 28 ++ .../symbols/variable/function-objects.xml | 4 + 37 files changed, 1288 insertions(+), 105 deletions(-) create mode 100644 share/mrdocs/addons/generator/adoc/partials/markup/see-below.adoc.hbs create mode 100644 share/mrdocs/addons/generator/html/partials/markup/see-below.html.hbs create mode 100644 src/test/lib/Metadata/Specifiers.cpp create mode 100644 test-files/golden-tests/symbols/function/noexcept.adoc create mode 100644 test-files/golden-tests/symbols/function/noexcept.cpp create mode 100644 test-files/golden-tests/symbols/function/noexcept.html create mode 100644 test-files/golden-tests/symbols/function/noexcept.xml diff --git a/include/mrdocs/Metadata/Specifiers/ExplicitInfo.hpp b/include/mrdocs/Metadata/Specifiers/ExplicitInfo.hpp index 8b5fdf7fe4..45ba0675d4 100644 --- a/include/mrdocs/Metadata/Specifiers/ExplicitInfo.hpp +++ b/include/mrdocs/Metadata/Specifiers/ExplicitInfo.hpp @@ -14,6 +14,7 @@ #include #include +#include #include namespace mrdocs { @@ -27,7 +28,7 @@ struct ExplicitInfo { /** Whether an explicit-specifier was user-written. */ - bool Implicit = true; + bool IsUserWritten = false; /** The evaluated exception specification. */ @@ -42,6 +43,11 @@ struct ExplicitInfo auto operator<=>(ExplicitInfo const&) const = default; }; +MRDOCS_DESCRIBE_STRUCT( + ExplicitInfo, + (), + (IsUserWritten, Kind, Operand)) + /** Convert ExplicitInfo to a string. @param info The explicit-specifier information. @@ -57,21 +63,6 @@ toString( bool resolved = false, bool implicit = false); -/** Return the ExplicitInfo as a @ref dom::Value string. - - @param v The output parameter to receive the dom::Value. - @param I The ExplicitInfo to convert. -*/ -inline -void -tag_invoke( - dom::ValueFromTag, - dom::Value& v, - ExplicitInfo const& I) -{ - v = toString(I); -} - } // mrdocs #endif diff --git a/include/mrdocs/Metadata/Specifiers/ExplicitKind.hpp b/include/mrdocs/Metadata/Specifiers/ExplicitKind.hpp index 8df1d9e63d..2654ccbcf8 100644 --- a/include/mrdocs/Metadata/Specifiers/ExplicitKind.hpp +++ b/include/mrdocs/Metadata/Specifiers/ExplicitKind.hpp @@ -13,8 +13,7 @@ #define MRDOCS_API_METADATA_SPECIFIERS_EXPLICITKIND_HPP #include -#include -#include +#include namespace mrdocs { @@ -33,11 +32,7 @@ enum class ExplicitKind Dependent }; -/** Convert an explicit kind to its string form. -*/ -MRDOCS_DECL -dom::String -toString(ExplicitKind kind) noexcept; +MRDOCS_DESCRIBE_ENUM(ExplicitKind, False, True, Dependent) } // mrdocs diff --git a/include/mrdocs/Metadata/Specifiers/NoexceptInfo.hpp b/include/mrdocs/Metadata/Specifiers/NoexceptInfo.hpp index e2512d9ed5..17c1c37a98 100644 --- a/include/mrdocs/Metadata/Specifiers/NoexceptInfo.hpp +++ b/include/mrdocs/Metadata/Specifiers/NoexceptInfo.hpp @@ -18,6 +18,7 @@ #include #include #include +#include #include namespace mrdocs { @@ -28,7 +29,13 @@ struct NoexceptInfo { /** Whether a noexcept-specifier was user-written. */ - bool Implicit = true; + bool IsUserWritten = false; + + /** Whether the operand is long enough to warrant rendering as + `noexcept(see-below)` plus a separate specification section, + instead of inline in the signature. + */ + bool OperandIsLong = false; /** The evaluated exception specification. */ @@ -43,6 +50,11 @@ struct NoexceptInfo auto operator<=>(NoexceptInfo const&) const = default; }; +MRDOCS_DESCRIBE_STRUCT( + NoexceptInfo, + (), + (IsUserWritten, OperandIsLong, Kind, Operand)) + /** Convert NoexceptInfo to a string. @param info The noexcept-specifier information. @@ -62,18 +74,6 @@ toString( bool resolved = false, bool implicit = false); -/** Convert a NoexceptInfo to a DOM value. -*/ -inline -void -tag_invoke( - dom::ValueFromTag tag, - dom::Value& v, - NoexceptInfo const& info) -{ - v = toString(info, false, false); -} - } // mrdocs #endif diff --git a/include/mrdocs/Metadata/Specifiers/NoexceptKind.hpp b/include/mrdocs/Metadata/Specifiers/NoexceptKind.hpp index 0125f3b4a5..741427b297 100644 --- a/include/mrdocs/Metadata/Specifiers/NoexceptKind.hpp +++ b/include/mrdocs/Metadata/Specifiers/NoexceptKind.hpp @@ -13,8 +13,7 @@ #define MRDOCS_API_METADATA_SPECIFIERS_NOEXCEPTKIND_HPP #include -#include -#include +#include namespace mrdocs { @@ -33,11 +32,7 @@ enum class NoexceptKind Dependent }; -/** Convert a noexcept kind to its string form. -*/ -MRDOCS_DECL -dom::String -toString(NoexceptKind kind) noexcept; +MRDOCS_DESCRIBE_ENUM(NoexceptKind, False, True, Dependent) } // mrdocs diff --git a/include/mrdocs/Support/MergeReflectedType.hpp b/include/mrdocs/Support/MergeReflectedType.hpp index e8f8712df7..26f5a55132 100644 --- a/include/mrdocs/Support/MergeReflectedType.hpp +++ b/include/mrdocs/Support/MergeReflectedType.hpp @@ -95,13 +95,12 @@ isPlaceholderType(Polymorphic const& t); 4. `Polymorphic` — take if placeholder (AutoType or blank NamedType) 5. `Polymorphic` — take if Identifier is empty - 6. `.Implicit` types — take if dst is implicit - 7. `Optional` — take if disengaged; recursive merge + 6. `Optional` — take if disengaged; recursive merge if both engaged and T has `merge()` - 8. `enum` — take if zero-initialized - 9. `string` — take if empty - 10. `vector` with `==` — dedup-append - 11. `vector` fallback — take if dst is empty + 7. `enum` — take if zero-initialized + 8. `string` — take if empty + 9. `vector` with `==` — dedup-append + 10. `vector` fallback — take if dst is empty Returns `false` only for types none of the above handles. */ @@ -152,16 +151,6 @@ mergeByType(T& dst, T&& src) } return true; } - // Types with .Implicit flag (NoexceptInfo, ExplicitInfo): - // take src if dst is still implicit (compiler-generated). - else if constexpr (requires(T const& t) { { t.Implicit } -> std::convertible_to; }) - { - if (dst.Implicit) - { - dst = std::move(src); - } - return true; - } // Optional: take if disengaged; recursive merge if both // engaged and the value type has a merge() function. else if constexpr (is_optional_v) diff --git a/mrdocs.rnc b/mrdocs.rnc index 75c69b3477..0b01014877 100644 --- a/mrdocs.rnc +++ b/mrdocs.rnc @@ -95,6 +95,42 @@ grammar TableAlignmentKind = "left" | "center" | "right" + NoexceptKind = "false" | "true" | "dependent" + + ExplicitKind = "false" | "true" | "dependent" + + #--------------------------------------------- + # noexcept specification + # + # Emitted only when a noexcept-specifier is user-written + # (implicit specifications are skipped). The operand holds + # the expression as written, when present. + #--------------------------------------------- + + NoexceptSpec = + element noexcept + { + element is-user-written { Bool }, + element operand-is-long { Bool }?, + element kind { NoexceptKind }?, + element operand { text }? + } + + #--------------------------------------------- + # explicit specification + # + # Emitted only when an explicit-specifier is user-written. + # The operand holds the expression as written, when present. + #--------------------------------------------- + + ExplicitSpec = + element explicit + { + element is-user-written { Bool }, + element kind { ExplicitKind }?, + element operand { text }? + } + #--------------------------------------------- # Name (used inside types, not for symbol names) #--------------------------------------------- @@ -187,7 +223,7 @@ grammar TypeBase, AnyType*, element ref-qualifier { text }?, - element exception-spec { text }?, + NoexceptSpec?, element is-variadic { Bool }? } @@ -420,7 +456,7 @@ grammar Param*, TemplateInfo?, element func-class { FunctionClass }?, - element noexcept { text }?, + NoexceptSpec?, element requires { text }?, element is-variadic { Bool }?, element is-defaulted { Bool }?, @@ -443,7 +479,7 @@ grammar element is-volatile { Bool }?, element is-final { Bool }?, element ref-qualifier { text }?, - element explicit { text }?, + ExplicitSpec?, element attributes { text }*, element function-object-impl { SymbolID }? } @@ -457,7 +493,7 @@ grammar AnyType?, TemplateInfo?, Param*, - element explicit { text }? + ExplicitSpec? } #--------------------------------------------- diff --git a/share/mrdocs/addons/generator/adoc/partials/markup/see-below.adoc.hbs b/share/mrdocs/addons/generator/adoc/partials/markup/see-below.adoc.hbs new file mode 100644 index 0000000000..7b86521a56 --- /dev/null +++ b/share/mrdocs/addons/generator/adoc/partials/markup/see-below.adoc.hbs @@ -0,0 +1 @@ +pass:q[_see-below_] \ No newline at end of file diff --git a/share/mrdocs/addons/generator/adoc/partials/symbol.adoc.hbs b/share/mrdocs/addons/generator/adoc/partials/symbol.adoc.hbs index 1f3290f23f..897c702175 100644 --- a/share/mrdocs/addons/generator/adoc/partials/symbol.adoc.hbs +++ b/share/mrdocs/addons/generator/adoc/partials/symbol.adoc.hbs @@ -168,6 +168,14 @@ {{/each}} |=== {{/if}} +{{/if}} +{{! noexcept specification — only when the operand is long enough to + be rendered as noexcept(see-below) in the signature. Short + operands are shown inline and need no separate section. }} +{{#if symbol.noexcept.operandIsLong}} +{{#> markup/dynamic-level-h }}noexcept Specification{{/markup/dynamic-level-h~}} +`noexcept` when `{{symbol.noexcept.operand}}`. + {{/if}} {{! Exceptions }} {{#if symbol.doc.exceptions}} diff --git a/share/mrdocs/addons/generator/common/partials/symbol/signature/function.hbs b/share/mrdocs/addons/generator/common/partials/symbol/signature/function.hbs index 4ffab163fa..b582b12b3c 100644 --- a/share/mrdocs/addons/generator/common/partials/symbol/signature/function.hbs +++ b/share/mrdocs/addons/generator/common/partials/symbol/signature/function.hbs @@ -10,7 +10,8 @@ {{/if~}} {{#if isVirtual}}virtual {{/if~}} -{{#if explicit}}{{explicit}} +{{#if explicit.isUserWritten}} + {{~#if explicit.operand}}explicit({{explicit.operand}}){{else if (eq explicit.kind "true")}}explicit{{/if}} {{/if~}} {{#if (eq funcClass "normal")}}{{>type/declarator-prefix returnType}} {{/if~}} @@ -31,7 +32,9 @@ {{~#if isConst}} const{{/if~}} {{#if isVolatile}} volatile{{/if~}} {{#if refQualifier}} {{refQualifier}}{{/if~}} -{{#if noexcept}} {{noexcept}}{{/if~}} +{{~#if noexcept.isUserWritten~}} + {{~#if noexcept.operandIsLong}} noexcept({{> markup/see-below }}){{else if noexcept.operand}} noexcept({{noexcept.operand}}){{else if (eq noexcept.kind "true")}} noexcept{{/if~}} +{{~/if~}} {{#if (eq funcClass "normal")}}{{>type/declarator-suffix returnType}}{{/if~}} {{#if requires}} diff --git a/share/mrdocs/addons/generator/common/partials/type/declarator-suffix.hbs b/share/mrdocs/addons/generator/common/partials/type/declarator-suffix.hbs index b09e8be0e1..1105582340 100644 --- a/share/mrdocs/addons/generator/common/partials/type/declarator-suffix.hbs +++ b/share/mrdocs/addons/generator/common/partials/type/declarator-suffix.hbs @@ -37,8 +37,10 @@ {{~#if cv-qualifiers}} {{cv-qualifiers}}{{/if~}} {{! Refqualifiers as "&" or "&&" ~}} {{#if (eq refQualifier "lvalue")}} &{{else if (eq refQualifier "rvalue")}} &&{{/if~}} - {{! Exception spec as literal string ~}} - {{#if exceptionSpec}} {{exceptionSpec}}{{/if~}} + {{! noexcept specification with "see-below" placeholder for long operands ~}} + {{~#if exceptionSpec.isUserWritten~}} + {{~#if exceptionSpec.operandIsLong}} noexcept({{> markup/see-below }}){{else if exceptionSpec.operand}} noexcept({{exceptionSpec.operand}}){{else if (eq exceptionSpec.kind "true")}} noexcept{{/if~}} + {{~/if~}} {{! Declarator suffix of the return type ~}} {{~>type/declarator-suffix returnType link-components-impl=link-components-impl~}} {{/if}} \ No newline at end of file diff --git a/share/mrdocs/addons/generator/html/partials/markup/see-below.html.hbs b/share/mrdocs/addons/generator/html/partials/markup/see-below.html.hbs new file mode 100644 index 0000000000..d33ac68728 --- /dev/null +++ b/share/mrdocs/addons/generator/html/partials/markup/see-below.html.hbs @@ -0,0 +1 @@ +see-below \ No newline at end of file diff --git a/share/mrdocs/addons/generator/html/partials/symbol.html.hbs b/share/mrdocs/addons/generator/html/partials/symbol.html.hbs index acab90eb12..e1f6d53ec8 100644 --- a/share/mrdocs/addons/generator/html/partials/symbol.html.hbs +++ b/share/mrdocs/addons/generator/html/partials/symbol.html.hbs @@ -231,6 +231,15 @@ {{/if}} +{{/if}} +{{! noexcept specification - only when the operand is long enough to + be rendered as noexcept(see-below) in the signature. Short + operands are shown inline and need no separate section. }} +{{#if symbol.noexcept.operandIsLong}} +
+{{#> markup/dynamic-level-h level=2 }}noexcept Specification{{/markup/dynamic-level-h~}} +

noexcept when {{symbol.noexcept.operand}}.

+
{{/if}} {{! Exceptions }} {{#if symbol.doc.exceptions}} diff --git a/src/lib/AST/ASTVisitor.cpp b/src/lib/AST/ASTVisitor.cpp index 4b935943f7..04ed09ab30 100644 --- a/src/lib/AST/ASTVisitor.cpp +++ b/src/lib/AST/ASTVisitor.cpp @@ -1453,8 +1453,13 @@ populate( NoexceptInfo& I, clang::FunctionProtoType const* FPT) { + // noexcept operands longer than this many characters are rendered + // as `noexcept(see-below)` plus a dedicated specification section, + // instead of inline in the signature. + constexpr std::size_t noexceptOperandLongThreshold = 40; + MRDOCS_ASSERT(FPT); - I.Implicit = ! FPT->hasNoexceptExceptionSpec(); + I.IsUserWritten = FPT->hasNoexceptExceptionSpec(); I.Kind = toNoexceptKind( FPT->getExceptionSpecType()); // store the operand, if any @@ -1462,6 +1467,7 @@ populate( { I.Operand = toString(NoexceptExpr); } + I.OperandIsLong = I.Operand.size() > noexceptOperandLongThreshold; } void @@ -1470,7 +1476,7 @@ populate( ExplicitInfo& I, clang::ExplicitSpecifier const& ES) { - I.Implicit = ! ES.isSpecified(); + I.IsUserWritten = ES.isSpecified(); I.Kind = toExplicitKind(ES); // store the operand, if any diff --git a/src/lib/AST/ExtractDocComment.cpp b/src/lib/AST/ExtractDocComment.cpp index 7c48621500..f4fd95c764 100644 --- a/src/lib/AST/ExtractDocComment.cpp +++ b/src/lib/AST/ExtractDocComment.cpp @@ -382,7 +382,7 @@ class DocCommentVisitor } bool const mightHaveMoreQualifiers - = v.HasFunctionParameters && v.ExceptionSpec.Implicit + = v.HasFunctionParameters && !v.ExceptionSpec.IsUserWritten && v.ExceptionSpec.Operand.empty(); if (mightHaveMoreQualifiers) diff --git a/src/lib/AST/ParseRef.cpp b/src/lib/AST/ParseRef.cpp index 541bff34ec..3de4f81fe0 100644 --- a/src/lib/AST/ParseRef.cpp +++ b/src/lib/AST/ParseRef.cpp @@ -2183,7 +2183,7 @@ class RefParser // https://en.cppreference.com/w/cpp/language/noexcept_spec if (parseKeyword("noexcept")) { - dest.ExceptionSpec.Implicit = false; + dest.ExceptionSpec.IsUserWritten = true; skipWhitespace(); char const *noexceptStart = ptr_; if (parseBalanced("(", ")")) @@ -2217,7 +2217,7 @@ class RefParser ptr_ = start; return false; } - dest.ExceptionSpec.Implicit = false; + dest.ExceptionSpec.IsUserWritten = true; dest.ExceptionSpec.Operand = "true"; dest.ExceptionSpec.Kind = NoexceptKind::True; } diff --git a/src/lib/CorpusImpl.cpp b/src/lib/CorpusImpl.cpp index 559362e8cb..b91d0ff99f 100644 --- a/src/lib/CorpusImpl.cpp +++ b/src/lib/CorpusImpl.cpp @@ -668,7 +668,7 @@ lookupImpl( matchRes = MatchLevel::Qualifiers; // Noexcept match - MRDOCS_CHECK_OR(F.Noexcept.Implicit == ref.ExceptionSpec.Implicit, matchRes); + MRDOCS_CHECK_OR(F.Noexcept.IsUserWritten == ref.ExceptionSpec.IsUserWritten, matchRes); matchRes = MatchLevel::NoExceptDefinition; MRDOCS_CHECK_OR(F.Noexcept.Kind == ref.ExceptionSpec.Kind, matchRes); matchRes = MatchLevel::NoExceptKind; diff --git a/src/lib/Gen/xml/XMLWriter.cpp b/src/lib/Gen/xml/XMLWriter.cpp index de1e2c7e4a..35b1db5e41 100644 --- a/src/lib/Gen/xml/XMLWriter.cpp +++ b/src/lib/Gen/xml/XMLWriter.cpp @@ -14,6 +14,8 @@ #include "XMLWriter.hpp" #include +#include +#include #include #include #include @@ -180,6 +182,9 @@ XMLWriter::writeElement(std::string_view tag, T const& value) { if (value.empty()) return; } else if constexpr (std::is_base_of_v) { if (value.Written.empty()) return; } + else if constexpr (std::is_same_v + || std::is_same_v) + { if (!value.IsUserWritten) return; } // Primitives inline, compounds wrapped. if constexpr (std::is_base_of_v) diff --git a/src/lib/Metadata/Specifiers.cpp b/src/lib/Metadata/Specifiers.cpp index 9f8b458487..1292d96f6e 100644 --- a/src/lib/Metadata/Specifiers.cpp +++ b/src/lib/Metadata/Specifiers.cpp @@ -54,37 +54,13 @@ dom::String toString(ConstexprKind kind) noexcept } } -dom::String toString(ExplicitKind kind) noexcept -{ - switch(kind) - { - case ExplicitKind::False: return ""; - case ExplicitKind::True: return "explicit"; - case ExplicitKind::Dependent: return "explicit(...)"; - default: - MRDOCS_UNREACHABLE(); - } -} - -dom::String toString(NoexceptKind kind) noexcept -{ - switch(kind) - { - case NoexceptKind::False: return ""; - case NoexceptKind::True: return "noexcept"; - case NoexceptKind::Dependent: return "noexcept(...)"; - default: - MRDOCS_UNREACHABLE(); - } -} - dom::String toString( NoexceptInfo const& info, bool resolved, bool implicit) { - if(! implicit && info.Implicit) + if(! implicit && ! info.IsUserWritten) return ""; if(info.Kind == NoexceptKind::Dependent && info.Operand.empty()) @@ -104,7 +80,7 @@ toString( bool resolved, bool implicit) { - if(! implicit && info.Implicit) + if(! implicit && ! info.IsUserWritten) return ""; if(info.Kind == ExplicitKind::Dependent && info.Operand.empty()) diff --git a/src/test/lib/Metadata/Merge.cpp b/src/test/lib/Metadata/Merge.cpp index 0a48bbfbbe..33636abe50 100644 --- a/src/test/lib/Metadata/Merge.cpp +++ b/src/test/lib/Metadata/Merge.cpp @@ -293,21 +293,21 @@ struct MergeTest { auto dst = makeFunc(); auto src = makeFunc(); - src.Noexcept.Implicit = false; + src.Noexcept.IsUserWritten = true; src.Noexcept.Kind = NoexceptKind::True; merge(dst, std::move(src)); - BOOST_TEST(!dst.Noexcept.Implicit); + BOOST_TEST(dst.Noexcept.IsUserWritten); BOOST_TEST(dst.Noexcept.Kind == NoexceptKind::True); } void test_func_noexcept_explicit_keeps_dst() { auto dst = makeFunc(); - dst.Noexcept.Implicit = false; + dst.Noexcept.IsUserWritten = true; dst.Noexcept.Kind = NoexceptKind::True; auto src = makeFunc(); - src.Noexcept.Implicit = false; + src.Noexcept.IsUserWritten = true; src.Noexcept.Kind = NoexceptKind::False; merge(dst, std::move(src)); @@ -318,11 +318,11 @@ struct MergeTest { auto dst = makeFunc(); auto src = makeFunc(); - src.Explicit.Implicit = false; + src.Explicit.IsUserWritten = true; src.Explicit.Kind = ExplicitKind::True; merge(dst, std::move(src)); - BOOST_TEST(!dst.Explicit.Implicit); + BOOST_TEST(dst.Explicit.IsUserWritten); } void test_func_attributes_dedup() diff --git a/src/test/lib/Metadata/Specifiers.cpp b/src/test/lib/Metadata/Specifiers.cpp new file mode 100644 index 0000000000..d2776a53ae --- /dev/null +++ b/src/test/lib/Metadata/Specifiers.cpp @@ -0,0 +1,203 @@ +// +// Licensed under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// Copyright (c) 2026 Gennaro Prota (gennaro.prota@gmail.com) +// +// Official repository: https://github.com/cppalliance/mrdocs +// + +#include +#include +#include +#include + +namespace mrdocs { +namespace { + +// Helpers to build the specs in one line per test. + +NoexceptInfo +makeNoexcept( + bool const userWritten, + NoexceptKind const kind, + std::string operand = {}) +{ + NoexceptInfo info; + info.IsUserWritten = userWritten; + info.Kind = kind; + info.Operand = std::move(operand); + return info; +} + +ExplicitInfo +makeExplicit( + bool const userWritten, + ExplicitKind const kind, + std::string operand = {}) +{ + ExplicitInfo info; + info.IsUserWritten = userWritten; + info.Kind = kind; + info.Operand = std::move(operand); + return info; +} + +// ------------------------------------------------------------------ + +struct SpecifiersTest +{ + // -- toString(NoexceptInfo) ---------------------------------- + + void test_noexcept_implicit_is_skipped() + { + NoexceptInfo const info = makeNoexcept(false, NoexceptKind::True); + BOOST_TEST(toString(info).get() == ""); + } + + void test_noexcept_implicit_shown_when_requested() + { + NoexceptInfo const info = makeNoexcept(false, NoexceptKind::True); + BOOST_TEST(toString(info, false, true).get() == "noexcept"); + } + + void test_noexcept_dependent_empty_operand() + { + NoexceptInfo const info = makeNoexcept(true, NoexceptKind::Dependent); + BOOST_TEST(toString(info).get() == ""); + } + + void test_noexcept_dependent_with_operand() + { + NoexceptInfo const info = makeNoexcept( + true, NoexceptKind::Dependent, "sizeof(T) > 4"); + BOOST_TEST(toString(info).get() == "noexcept(sizeof(T) > 4)"); + } + + void test_noexcept_false_resolved_drops_operand() + { + NoexceptInfo const info = makeNoexcept( + true, NoexceptKind::False, "false"); + BOOST_TEST(toString(info, true).get() == ""); + } + + void test_noexcept_false_with_operand() + { + NoexceptInfo const info = makeNoexcept( + true, NoexceptKind::False, "false"); + BOOST_TEST(toString(info).get() == "noexcept(false)"); + } + + void test_noexcept_true_resolved_drops_operand() + { + NoexceptInfo const info = makeNoexcept( + true, NoexceptKind::True, "true"); + BOOST_TEST(toString(info, true).get() == "noexcept"); + } + + void test_noexcept_true_empty_operand() + { + NoexceptInfo const info = makeNoexcept(true, NoexceptKind::True); + BOOST_TEST(toString(info).get() == "noexcept"); + } + + void test_noexcept_true_with_operand() + { + NoexceptInfo const info = makeNoexcept( + true, NoexceptKind::True, "true"); + BOOST_TEST(toString(info).get() == "noexcept(true)"); + } + + // -- toString(ExplicitInfo) ---------------------------------- + + void test_explicit_implicit_is_skipped() + { + ExplicitInfo const info = makeExplicit(false, ExplicitKind::True); + BOOST_TEST(toString(info).get() == ""); + } + + void test_explicit_implicit_shown_when_requested() + { + ExplicitInfo const info = makeExplicit(false, ExplicitKind::True); + BOOST_TEST(toString(info, false, true).get() == "explicit"); + } + + void test_explicit_dependent_empty_operand() + { + ExplicitInfo const info = makeExplicit(true, ExplicitKind::Dependent); + BOOST_TEST(toString(info).get() == ""); + } + + void test_explicit_dependent_with_operand() + { + ExplicitInfo const info = makeExplicit( + true, ExplicitKind::Dependent, "sizeof(T) > 4"); + BOOST_TEST(toString(info).get() == "explicit(sizeof(T) > 4)"); + } + + void test_explicit_false_resolved_drops_operand() + { + ExplicitInfo const info = makeExplicit( + true, ExplicitKind::False, "false"); + BOOST_TEST(toString(info, true).get() == ""); + } + + void test_explicit_false_with_operand() + { + ExplicitInfo const info = makeExplicit( + true, ExplicitKind::False, "false"); + BOOST_TEST(toString(info).get() == "explicit(false)"); + } + + void test_explicit_true_resolved_drops_operand() + { + ExplicitInfo const info = makeExplicit( + true, ExplicitKind::True, "true"); + BOOST_TEST(toString(info, true).get() == "explicit"); + } + + void test_explicit_true_empty_operand() + { + ExplicitInfo const info = makeExplicit(true, ExplicitKind::True); + BOOST_TEST(toString(info).get() == "explicit"); + } + + void test_explicit_true_with_operand() + { + ExplicitInfo const info = makeExplicit( + true, ExplicitKind::True, "true"); + BOOST_TEST(toString(info).get() == "explicit(true)"); + } + + // -- runner -------------------------------------------------- + + void run() + { + test_noexcept_implicit_is_skipped(); + test_noexcept_implicit_shown_when_requested(); + test_noexcept_dependent_empty_operand(); + test_noexcept_dependent_with_operand(); + test_noexcept_false_resolved_drops_operand(); + test_noexcept_false_with_operand(); + test_noexcept_true_resolved_drops_operand(); + test_noexcept_true_empty_operand(); + test_noexcept_true_with_operand(); + + test_explicit_implicit_is_skipped(); + test_explicit_implicit_shown_when_requested(); + test_explicit_dependent_empty_operand(); + test_explicit_dependent_with_operand(); + test_explicit_false_resolved_drops_operand(); + test_explicit_false_with_operand(); + test_explicit_true_resolved_drops_operand(); + test_explicit_true_empty_operand(); + test_explicit_true_with_operand(); + } +}; + +} // (unnamed) + +TEST_SUITE(SpecifiersTest, "clang.mrdocs.Metadata.Specifiers"); + +} // mrdocs diff --git a/test-files/golden-tests/config/extract-friends/extract-friends.xml b/test-files/golden-tests/config/extract-friends/extract-friends.xml index d10d24ae21..9d22580491 100644 --- a/test-files/golden-tests/config/extract-friends/extract-friends.xml +++ b/test-files/golden-tests/config/extract-friends/extract-friends.xml @@ -140,6 +140,10 @@ rhs normal + + 1 + true + 1 1 diff --git a/test-files/golden-tests/config/extract-friends/no-extract-friends.xml b/test-files/golden-tests/config/extract-friends/no-extract-friends.xml index d6632f40c4..1411b7850e 100644 --- a/test-files/golden-tests/config/extract-friends/no-extract-friends.xml +++ b/test-files/golden-tests/config/extract-friends/no-extract-friends.xml @@ -140,6 +140,10 @@ rhs normal + + 1 + true + 1 1 diff --git a/test-files/golden-tests/javadoc/copydoc/operator-param.xml b/test-files/golden-tests/javadoc/copydoc/operator-param.xml index eab467ca8a..ba1b83848b 100644 --- a/test-files/golden-tests/javadoc/copydoc/operator-param.xml +++ b/test-files/golden-tests/javadoc/copydoc/operator-param.xml @@ -156,6 +156,10 @@ ch normal + + 1 + true + 1 1 @@ -221,6 +225,10 @@ ch normal + + 1 + true + 1 1 diff --git a/test-files/golden-tests/javadoc/inline/styled.xml b/test-files/golden-tests/javadoc/inline/styled.xml index 5bcbba48f2..c9e2f537be 100644 --- a/test-files/golden-tests/javadoc/inline/styled.xml +++ b/test-files/golden-tests/javadoc/inline/styled.xml @@ -203,6 +203,10 @@ other normal + + 1 + true + 1 1 diff --git a/test-files/golden-tests/snippets/function_object.xml b/test-files/golden-tests/snippets/function_object.xml index 0372d4af92..5abf8cfb06 100644 --- a/test-files/golden-tests/snippets/function_object.xml +++ b/test-files/golden-tests/snippets/function_object.xml @@ -92,6 +92,10 @@ x normal + + 1 + true + 1 1 @@ -150,6 +154,10 @@ x normal + + 1 + true + 7X78dvKaHCvXfNokuB9sZf6Fq4o= diff --git a/test-files/golden-tests/snippets/is_prime.xml b/test-files/golden-tests/snippets/is_prime.xml index 654fb8203b..29a4488d24 100644 --- a/test-files/golden-tests/snippets/is_prime.xml +++ b/test-files/golden-tests/snippets/is_prime.xml @@ -92,5 +92,9 @@ n normal + + 1 + true + diff --git a/test-files/golden-tests/snippets/terminate.xml b/test-files/golden-tests/snippets/terminate.xml index f4aae36fae..51bd4d33f1 100644 --- a/test-files/golden-tests/snippets/terminate.xml +++ b/test-files/golden-tests/snippets/terminate.xml @@ -60,6 +60,10 @@
normal + + 1 + true + 1 noreturn diff --git a/test-files/golden-tests/symbols/function/explicit-conv-operator.xml b/test-files/golden-tests/symbols/function/explicit-conv-operator.xml index 35c1e9fbd9..25e1b49323 100644 --- a/test-files/golden-tests/symbols/function/explicit-conv-operator.xml +++ b/test-files/golden-tests/symbols/function/explicit-conv-operator.xml @@ -91,6 +91,10 @@ conversion 1 + + 1 + true + ExplicitExpression @@ -181,6 +185,11 @@ conversion 1 + + 1 + dependent + B + ExplicitFalse @@ -259,6 +268,11 @@ conversion 1 + + 1 + false + false + ExplicitTrue @@ -337,5 +351,10 @@ conversion 1 + + 1 + true + true +
diff --git a/test-files/golden-tests/symbols/function/explicit-ctor.xml b/test-files/golden-tests/symbols/function/explicit-ctor.xml index 2e8c1a432a..ab22743f8c 100644 --- a/test-files/golden-tests/symbols/function/explicit-ctor.xml +++ b/test-files/golden-tests/symbols/function/explicit-ctor.xml @@ -123,6 +123,10 @@ constructor 1 + + 1 + true + Explicit @@ -176,6 +180,10 @@ constructor 1 + + 1 + true + Explicit @@ -227,7 +235,15 @@ other constructor + + 1 + true + 1 + + 1 + true + Explicit @@ -276,6 +292,10 @@ constructor 1 + + 1 + true + ExplicitExpression @@ -398,6 +418,11 @@ constructor 1 + + 1 + dependent + B + ExplicitExpression @@ -451,6 +476,11 @@ constructor 1 + + 1 + dependent + B + ExplicitExpression @@ -502,7 +532,16 @@ other constructor + + 1 + true + 1 + + 1 + dependent + B + ExplicitExpression @@ -551,6 +590,11 @@ constructor 1 + + 1 + dependent + B + ExplicitFalse @@ -661,6 +705,11 @@ constructor 1 + + 1 + false + false + ExplicitFalse @@ -714,6 +763,11 @@ constructor 1 + + 1 + false + false + ExplicitFalse @@ -765,7 +819,16 @@ other constructor + + 1 + true + 1 + + 1 + false + false + ExplicitFalse @@ -814,6 +877,11 @@ constructor 1 + + 1 + false + false + ExplicitTrue @@ -924,6 +992,11 @@ constructor 1 + + 1 + true + true + ExplicitTrue @@ -977,6 +1050,11 @@ constructor 1 + + 1 + true + true + ExplicitTrue @@ -1028,7 +1106,16 @@ other constructor + + 1 + true + 1 + + 1 + true + true + ExplicitTrue @@ -1077,5 +1164,10 @@ constructor 1 + + 1 + true + true +
diff --git a/test-files/golden-tests/symbols/function/mem-fn.xml b/test-files/golden-tests/symbols/function/mem-fn.xml index cd386b9270..9360995e84 100644 --- a/test-files/golden-tests/symbols/function/mem-fn.xml +++ b/test-files/golden-tests/symbols/function/mem-fn.xml @@ -411,6 +411,10 @@ normal + + 1 + true + 1 @@ -867,6 +871,10 @@ normal + + 1 + true + 1 1 1 @@ -894,6 +902,10 @@ normal + + 1 + true + 1 1 1 @@ -922,6 +934,10 @@ normal + + 1 + true + 1 1 @@ -982,6 +998,10 @@ normal + + 1 + true + 1 1 1 @@ -1009,6 +1029,10 @@ normal + + 1 + true + 1 1 1 @@ -1036,6 +1060,10 @@ normal + + 1 + true + 1 1 diff --git a/test-files/golden-tests/symbols/function/noexcept.adoc b/test-files/golden-tests/symbols/function/noexcept.adoc new file mode 100644 index 0000000000..0d9cf70fde --- /dev/null +++ b/test-files/golden-tests/symbols/function/noexcept.adoc @@ -0,0 +1,159 @@ += Reference +:mrdocs: + +[#index] +== Global namespace + +=== Functions + +[cols=1] +|=== +| Name +| link:#f1[`f1`] +| link:#f2[`f2`] +| link:#f3[`f3`] +| link:#f4[`f4`] +| link:#f5[`f5`] +| link:#f6[`f6`] +|=== + +=== Variables + +[cols=1] +|=== +| Name +| link:#is_nothrow_move_assignable_v[`is_nothrow_move_assignable_v`] +| link:#is_nothrow_move_constructible_v[`is_nothrow_move_constructible_v`] +| link:#is_nothrow_swappable_v[`is_nothrow_swappable_v`] +|=== + +[#f1] +== f1 + +=== Synopsis + +Declared in `<noexcept.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +f1() noexcept; +---- + +[#f2] +== f2 + +=== Synopsis + +Declared in `<noexcept.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +f2() noexcept(true); +---- + +[#f3] +== f3 + +=== Synopsis + +Declared in `<noexcept.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +f3() noexcept(false); +---- + +[#f4] +== f4 + +=== Synopsis + +Declared in `<noexcept.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +template<typename T> +void +f4(T&) noexcept(is_nothrow_swappable_v<T>); +---- + +[#f5] +== f5 + +=== Synopsis + +Declared in `<noexcept.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +template<typename T> +void +f5( + T a, + T b) noexcept(noexcept(a + b)); +---- + +[#f6] +== f6 + +=== Synopsis + +Declared in `<noexcept.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +template<typename T> +void +f6( + T&, + T&) noexcept(pass:q[_see-below_]); +---- + +=== noexcept Specification + +`noexcept` when `is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<T>`. + +[#is_nothrow_move_assignable_v] +== is_nothrow_move_assignable_v + +=== Synopsis + +Declared in `<noexcept.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +template<typename T> +inline constexpr bool is_nothrow_move_assignable_v = false; +---- + +[#is_nothrow_move_constructible_v] +== is_nothrow_move_constructible_v + +=== Synopsis + +Declared in `<noexcept.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +template<typename T> +inline constexpr bool is_nothrow_move_constructible_v = false; +---- + +[#is_nothrow_swappable_v] +== is_nothrow_swappable_v + +=== Synopsis + +Declared in `<noexcept.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +template<typename T> +inline constexpr bool is_nothrow_swappable_v = false; +---- + + +[.small]#Created with https://www.mrdocs.com[MrDocs]# diff --git a/test-files/golden-tests/symbols/function/noexcept.cpp b/test-files/golden-tests/symbols/function/noexcept.cpp new file mode 100644 index 0000000000..a3aae89704 --- /dev/null +++ b/test-files/golden-tests/symbols/function/noexcept.cpp @@ -0,0 +1,38 @@ +// A function with an unconditional noexcept-specifier. +void f1() noexcept; + +// A function with noexcept(true). +void f2() noexcept(true); + +// A function with noexcept(false). +void f3() noexcept(false); + +// Traits declared locally, so the fixture does not depend on +// . +template +inline constexpr bool is_nothrow_swappable_v = false; +template +inline constexpr bool is_nothrow_move_constructible_v = false; +template +inline constexpr bool is_nothrow_move_assignable_v = false; + +// A function template with a short conditional noexcept whose +// operand depends on a type trait. The operand is short enough +// to be rendered inline in the signature. +template +void f4(T&) noexcept(is_nothrow_swappable_v); + +// A function template with a simpler conditional noexcept: a +// dependent expression that is not a type trait. Also short +// enough to be inlined. +template +void f5(T a, T b) noexcept(noexcept(a + b)); + +// A function template whose noexcept operand is long enough to +// be rendered as `noexcept(see-below)` in the signature, with +// the actual condition shown in a dedicated "noexcept +// Specification" section. See issue #1103. +template +void f6(T&, T&) noexcept( + is_nothrow_move_constructible_v && + is_nothrow_move_assignable_v); diff --git a/test-files/golden-tests/symbols/function/noexcept.html b/test-files/golden-tests/symbols/function/noexcept.html new file mode 100644 index 0000000000..a6ce519d5f --- /dev/null +++ b/test-files/golden-tests/symbols/function/noexcept.html @@ -0,0 +1,194 @@ + + +Reference + + + +
+

Reference

+
+
+

+Global Namespace

+
+

+Functions

+ + + + + + + + + + + + + + + +
Name
f1
f2
f3
f4
f5
f6
+ +

+Variables

+ + + + + + + + + + + + +
Name
is_nothrow_move_assignable_v
is_nothrow_move_constructible_v
is_nothrow_swappable_v
+ +
+
+
+

+f1

+
+
+

+Synopsis

+
+Declared in <noexcept.cpp>
+
void
+f1() noexcept;
+
+
+
+
+

+f2

+
+
+

+Synopsis

+
+Declared in <noexcept.cpp>
+
void
+f2() noexcept(true);
+
+
+
+
+

+f3

+
+
+

+Synopsis

+
+Declared in <noexcept.cpp>
+
void
+f3() noexcept(false);
+
+
+
+
+

+f4

+
+
+

+Synopsis

+
+Declared in <noexcept.cpp>
+
template<typename T>
+void
+f4(T&) noexcept(is_nothrow_swappable_v<T>);
+
+
+
+
+

+f5

+
+
+

+Synopsis

+
+Declared in <noexcept.cpp>
+
template<typename T>
+void
+f5(
+    T a,
+    T b) noexcept(noexcept(a + b));
+
+
+
+
+

+f6

+
+
+

+Synopsis

+
+Declared in <noexcept.cpp>
+
template<typename T>
+void
+f6(
+    T&,
+    T&) noexcept(see-below);
+
+
+

+noexcept Specification

+

noexcept when is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<T>.

+
+
+
+
+

+is_nothrow_move_assignable_v

+
+
+

+Synopsis

+
+Declared in <noexcept.cpp>
+
template<typename T>
+inline constexpr bool is_nothrow_move_assignable_v = false;
+
+
+
+
+

+is_nothrow_move_constructible_v

+
+
+

+Synopsis

+
+Declared in <noexcept.cpp>
+
template<typename T>
+inline constexpr bool is_nothrow_move_constructible_v = false;
+
+
+
+
+

+is_nothrow_swappable_v

+
+
+

+Synopsis

+
+Declared in <noexcept.cpp>
+
template<typename T>
+inline constexpr bool is_nothrow_swappable_v = false;
+
+
+ +
+ + + \ No newline at end of file diff --git a/test-files/golden-tests/symbols/function/noexcept.xml b/test-files/golden-tests/symbols/function/noexcept.xml new file mode 100644 index 0000000000..4eaa93afa1 --- /dev/null +++ b/test-files/golden-tests/symbols/function/noexcept.xml @@ -0,0 +1,346 @@ + + + + + + namespace + //////////////////////////8= + regular + + CnO51rIKTzfiVKHkR3TdPa0eo+8= + 0MJUv5yGFR9nXWFLeYc+rjOY+iM= + khwJweIqd5FuWAg8T+l+GEljQVc= + YLQQaYyVExJgVdKmDUI8g3kUSe4= + 8UyaUNUP7e7Lw8EqXP3My1yLQ6U= + NubFG5T9/Beym2c/ShoR//0YUyU= + Tc9ci3FD59/jcGuSU0poHg/W/gY= + PUuglSr4gxhfPzz7VJftFjC3IXc= + wGin1cWt/dOHtf7KP/24V/5GKec= + + + + f1 + + + noexcept.cpp + noexcept.cpp + 2 + 1 + + + function + CnO51rIKTzfiVKHkR3TdPa0eo+8= + regular + //////////////////////////8= + + + identifier + void + + + normal + + 1 + true + + + + f2 + + + noexcept.cpp + noexcept.cpp + 5 + 1 + + + function + 0MJUv5yGFR9nXWFLeYc+rjOY+iM= + regular + //////////////////////////8= + + + identifier + void + + + normal + + 1 + true + true + + + + f3 + + + noexcept.cpp + noexcept.cpp + 8 + 1 + + + function + khwJweIqd5FuWAg8T+l+GEljQVc= + regular + //////////////////////////8= + + + identifier + void + + + normal + + 1 + false + false + + + + f4 + + + noexcept.cpp + noexcept.cpp + 22 + 1 + + + function + YLQQaYyVExJgVdKmDUI8g3kUSe4= + regular + //////////////////////////8= + + + identifier + void + + + + + + + identifier + T + + + + + + normal + + 1 + dependent + is_nothrow_swappable_v<T> + + + + f5 + + + noexcept.cpp + noexcept.cpp + 28 + 1 + + + function + 8UyaUNUP7e7Lw8EqXP3My1yLQ6U= + regular + //////////////////////////8= + + + identifier + void + + + + + + identifier + T + + + a + + + + + identifier + T + + + b + + + normal + + 1 + dependent + noexcept(a + b) + + + + f6 + + + noexcept.cpp + noexcept.cpp + 35 + 1 + + + function + NubFG5T9/Beym2c/ShoR//0YUyU= + regular + //////////////////////////8= + + + identifier + void + + + + + + + identifier + T + + + + + + + + + identifier + T + + + + + + normal + + 1 + 1 + dependent + is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<T> + + + + is_nothrow_move_assignable_v + + + noexcept.cpp + noexcept.cpp + 16 + 1 + + + variable + Tc9ci3FD59/jcGuSU0poHg/W/gY= + regular + //////////////////////////8= + + + identifier + bool + + + + false + 1 + 1 + + + is_nothrow_move_constructible_v + + + noexcept.cpp + noexcept.cpp + 14 + 1 + + + variable + PUuglSr4gxhfPzz7VJftFjC3IXc= + regular + //////////////////////////8= + + + identifier + bool + + + + false + 1 + 1 + + + is_nothrow_swappable_v + + + noexcept.cpp + noexcept.cpp + 12 + 1 + + + variable + wGin1cWt/dOHtf7KP/24V/5GKec= + regular + //////////////////////////8= + + + identifier + bool + + + + false + 1 + 1 + + diff --git a/test-files/golden-tests/symbols/guide/explicit-deduct-guide.xml b/test-files/golden-tests/symbols/guide/explicit-deduct-guide.xml index d314a0d2a3..3ed976f96b 100644 --- a/test-files/golden-tests/symbols/guide/explicit-deduct-guide.xml +++ b/test-files/golden-tests/symbols/guide/explicit-deduct-guide.xml @@ -79,6 +79,10 @@ + + 1 + true + X @@ -109,6 +113,11 @@ + + 1 + true + true + X @@ -139,6 +148,11 @@ + + 1 + false + false + X @@ -185,5 +199,10 @@ + + 1 + dependent + B +
diff --git a/test-files/golden-tests/symbols/record/conditional-explicit.xml b/test-files/golden-tests/symbols/record/conditional-explicit.xml index a74cffd24a..d7dd1be703 100644 --- a/test-files/golden-tests/symbols/record/conditional-explicit.xml +++ b/test-files/golden-tests/symbols/record/conditional-explicit.xml @@ -153,6 +153,11 @@ constructor 1 + + 1 + dependent + sizeof(T) > 4 + A @@ -253,6 +258,10 @@ constructor 1 + + 1 + true + A @@ -310,6 +319,11 @@ constructor 1 + + 1 + dependent + sizeof(U) > 4 + operator @@ -365,6 +379,11 @@ conversion 1 1 + + 1 + dependent + sizeof(U) > 1 + operator bool @@ -413,6 +432,10 @@ conversion 1 1 + + 1 + true + operator char @@ -461,6 +484,11 @@ conversion 1 1 + + 1 + dependent + sizeof(T) > 4 + operator double diff --git a/test-files/golden-tests/symbols/variable/function-objects.xml b/test-files/golden-tests/symbols/variable/function-objects.xml index a7bacedfb2..4248d056ac 100644 --- a/test-files/golden-tests/symbols/variable/function-objects.xml +++ b/test-files/golden-tests/symbols/variable/function-objects.xml @@ -3095,6 +3095,10 @@ constructor 1 + + 1 + true + operator()