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
23 changes: 7 additions & 16 deletions include/mrdocs/Metadata/Specifiers/ExplicitInfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <mrdocs/Platform.hpp>
#include <mrdocs/Metadata/Specifiers/ExplicitKind.hpp>
#include <mrdocs/Support/Describe.hpp>
#include <string>

namespace mrdocs {
Expand All @@ -27,7 +28,7 @@ struct ExplicitInfo
{
/** Whether an explicit-specifier was user-written.
*/
bool Implicit = true;
bool IsUserWritten = false;

/** The evaluated exception specification.
*/
Expand All @@ -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.
Expand All @@ -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
9 changes: 2 additions & 7 deletions include/mrdocs/Metadata/Specifiers/ExplicitKind.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
#define MRDOCS_API_METADATA_SPECIFIERS_EXPLICITKIND_HPP

#include <mrdocs/Platform.hpp>
#include <mrdocs/Dom/String.hpp>
#include <string>
#include <mrdocs/Support/Describe.hpp>

namespace mrdocs {

Expand All @@ -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

Expand Down
26 changes: 13 additions & 13 deletions include/mrdocs/Metadata/Specifiers/NoexceptInfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <mrdocs/Metadata/Specifiers/ExplicitInfo.hpp>
#include <mrdocs/Metadata/Specifiers/ExplicitKind.hpp>
#include <mrdocs/Metadata/Specifiers/NoexceptKind.hpp>
#include <mrdocs/Support/Describe.hpp>
#include <string>

namespace mrdocs {
Expand All @@ -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.
*/
Expand All @@ -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.
Expand All @@ -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
9 changes: 2 additions & 7 deletions include/mrdocs/Metadata/Specifiers/NoexceptKind.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
#define MRDOCS_API_METADATA_SPECIFIERS_NOEXCEPTKIND_HPP

#include <mrdocs/Platform.hpp>
#include <mrdocs/Dom/String.hpp>
#include <string>
#include <mrdocs/Support/Describe.hpp>

namespace mrdocs {

Expand All @@ -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

Expand Down
21 changes: 5 additions & 16 deletions include/mrdocs/Support/MergeReflectedType.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,12 @@ isPlaceholderType(Polymorphic<Type> const& t);
4. `Polymorphic<Type>` — take if placeholder (AutoType or blank
NamedType)
5. `Polymorphic<Name>` — take if Identifier is empty
6. `.Implicit` types — take if dst is implicit
7. `Optional<T>` — take if disengaged; recursive merge
6. `Optional<T>` — 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<T>` with `==` — dedup-append
11. `vector<T>` fallback — take if dst is empty
7. `enum` — take if zero-initialized
8. `string` — take if empty
9. `vector<T>` with `==` — dedup-append
10. `vector<T>` fallback — take if dst is empty

Returns `false` only for types none of the above handles.
*/
Expand Down Expand Up @@ -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<bool>; })
{
if (dst.Implicit)
{
dst = std::move(src);
}
return true;
}
// Optional<T>: take if disengaged; recursive merge if both
// engaged and the value type has a merge() function.
else if constexpr (is_optional_v<T>)
Expand Down
44 changes: 40 additions & 4 deletions mrdocs.rnc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
#---------------------------------------------
Expand Down Expand Up @@ -187,7 +223,7 @@ grammar
TypeBase,
AnyType*,
element ref-qualifier { text }?,
element exception-spec { text }?,
NoexceptSpec?,
element is-variadic { Bool }?
}

Expand Down Expand Up @@ -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 }?,
Expand All @@ -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 }?
}
Expand All @@ -457,7 +493,7 @@ grammar
AnyType?,
TemplateInfo?,
Param*,
element explicit { text }?
ExplicitSpec?
}

#---------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pass:q[_see-below_]
8 changes: 8 additions & 0 deletions share/mrdocs/addons/generator/adoc/partials/symbol.adoc.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -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}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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~}}
Expand All @@ -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}}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<em>see-below</em>
9 changes: 9 additions & 0 deletions share/mrdocs/addons/generator/html/partials/symbol.html.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,15 @@
{{/if}}
</div>

{{/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}}
<div>
{{#> markup/dynamic-level-h level=2 }}noexcept Specification{{/markup/dynamic-level-h~}}
<p><code>noexcept</code> when <code>{{symbol.noexcept.operand}}</code>.</p>
</div>
{{/if}}
{{! Exceptions }}
{{#if symbol.doc.exceptions}}
Expand Down
10 changes: 8 additions & 2 deletions src/lib/AST/ASTVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1453,15 +1453,21 @@ 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
if (clang::Expr const* NoexceptExpr = FPT->getNoexceptExpr())
{
I.Operand = toString(NoexceptExpr);
}
I.OperandIsLong = I.Operand.size() > noexceptOperandLongThreshold;
}

void
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/lib/AST/ExtractDocComment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions src/lib/AST/ParseRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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("(", ")"))
Expand Down Expand Up @@ -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;
}
Expand Down
Loading
Loading