diff --git a/docs/modules/ROOT/pages/generators.adoc b/docs/modules/ROOT/pages/generators.adoc index 84bce290a..ec6e78de6 100644 --- a/docs/modules/ROOT/pages/generators.adoc +++ b/docs/modules/ROOT/pages/generators.adoc @@ -189,6 +189,10 @@ The `Symbol` object represents a symbol extracted from the source code.The symbo | `Any` | The documentation for the symbol. +| `attributes` +| `string[]` +| The attributes of the symbol. + |=== Handlebars generators extend each symbol with the following fields: @@ -326,13 +330,9 @@ When the symbol kind is `function`, the symbol object has the following addition | `bool` | Whether the function is deleted as written. -| `isNoReturn` +| `isOverride` | `bool` -| Whether the function is noreturn. - -| `hasOverrideAttr` -| `bool` -| Whether the function has the override attribute. +| Whether the function is override. | `hasTrailingReturn` | `bool` @@ -350,10 +350,6 @@ When the symbol kind is `function`, the symbol object has the following addition | `bool` | Whether the function is final. -| `isNodiscard` -| `bool` -| Whether the function is nodiscard. - | `isExplicitObjectMemberFunction` | `bool` | Whether the function is an explicit object member function. @@ -401,10 +397,6 @@ When the symbol kind is `function`, the symbol object has the following addition | `requires` | `string` | The `requires` expression of the function. - -| `attributes` -| `string[]` -| The attributes of the function. |=== When the symbol kind is `typedef`, the symbol object has the following additional properties: @@ -461,10 +453,6 @@ When the symbol kind is `variable`, the symbol object has the following addition | `initializer` | `string` | The initializer of the variable. - -| `attributes` -| `string[]` -| The attributes of the variable. |=== When the symbol kind is `field` (i.e. non-static data members), the symbol object has the following additional properties: @@ -480,14 +468,6 @@ When the symbol kind is `field` (i.e. non-static data members), the symbol objec | `string` | The default value of the field. -| `isMaybeUnused` -| `bool` -| Whether the field is maybe unused. - -| `isDeprecated` -| `bool` -| Whether the field is deprecated. - | `isVariant` | `bool` | Whether the field is a variant. @@ -500,17 +480,9 @@ When the symbol kind is `field` (i.e. non-static data members), the symbol objec | `bool` | Whether the field is a bitfield. -| `hasNoUniqueAddress` -| `string` -| Whether the field has the `[[no_unique_address]]` attribute. - | `bitfieldWidth` | `string` | The width of the bitfield. - -| `attributes` -| `string[]` -| The attributes of the field. |=== When the symbol kind is `friend`, the symbol object has the following additional properties: diff --git a/include/mrdocs/Metadata/Info.hpp b/include/mrdocs/Metadata/Info.hpp index ecf56351b..964fa3ae3 100644 --- a/include/mrdocs/Metadata/Info.hpp +++ b/include/mrdocs/Metadata/Info.hpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -112,6 +113,10 @@ struct MRDOCS_VISIBLE Info */ std::optional javadoc; + /** The attributes appertaining to this declaration. + */ + std::vector Attributes; + //-------------------------------------------- ~Info() override = default; @@ -298,6 +303,8 @@ tag_invoke( { io.map("doc", *I.javadoc); } + + io.map("attributes", dom::LazyArray(I.Attributes)); io.map("loc", dynamic_cast(I)); } diff --git a/include/mrdocs/Metadata/Info/Field.hpp b/include/mrdocs/Metadata/Info/Field.hpp index 711cab72d..69746ca26 100644 --- a/include/mrdocs/Metadata/Info/Field.hpp +++ b/include/mrdocs/Metadata/Info/Field.hpp @@ -48,16 +48,6 @@ struct FieldInfo final /** The width of the bitfield */ ConstantExprInfo BitfieldWidth; - // KRYSTIAN FIXME: nodiscard cannot be applied to fields; this should - // instead be IsMaybeUnused. we should also store the spelling - bool IsMaybeUnused = false; - - bool IsDeprecated = false; - - bool HasNoUniqueAddress = false; - - std::vector Attributes; - //-------------------------------------------- explicit FieldInfo(SymbolID ID) noexcept @@ -86,17 +76,13 @@ tag_invoke( { io.map("default", I.Default.Written); } - io.map("isMaybeUnused", I.IsMaybeUnused); - io.map("isDeprecated", I.IsDeprecated); io.map("isVariant", I.IsVariant); io.map("isMutable", I.IsMutable); io.map("isBitfield", I.IsBitfield); - io.map("hasNoUniqueAddress", I.HasNoUniqueAddress); if (I.IsBitfield) { io.map("bitfieldWidth", I.BitfieldWidth.Written); } - io.map("attributes", dom::LazyArray(I.Attributes)); } /** Map the FieldInfo to a @ref dom::Value object. diff --git a/include/mrdocs/Metadata/Info/Function.hpp b/include/mrdocs/Metadata/Info/Function.hpp index 56489b23e..b655389fa 100644 --- a/include/mrdocs/Metadata/Info/Function.hpp +++ b/include/mrdocs/Metadata/Info/Function.hpp @@ -165,10 +165,7 @@ struct FunctionInfo final bool IsExplicitlyDefaulted = false; bool IsDeleted = false; bool IsDeletedAsWritten = false; - bool IsNoReturn = false; - bool HasOverrideAttr = false; bool HasTrailingReturn = false; - bool IsNodiscard = false; bool IsExplicitObjectMemberFunction = false; ConstexprKind Constexpr = ConstexprKind::None; OperatorKind OverloadedOperator = OperatorKind::None; @@ -183,6 +180,7 @@ struct FunctionInfo final bool IsConst = false; bool IsVolatile = false; bool IsFinal = false; + bool IsOverride = false; ReferenceKind RefQualifier = ReferenceKind::None; ExplicitInfo Explicit; @@ -220,13 +218,11 @@ tag_invoke( io.map("isExplicitlyDefaulted", I.IsExplicitlyDefaulted); io.map("isDeleted", I.IsDeleted); io.map("isDeletedAsWritten", I.IsDeletedAsWritten); - io.map("isNoReturn", I.IsNoReturn); - io.map("hasOverrideAttr", I.HasOverrideAttr); io.map("hasTrailingReturn", I.HasTrailingReturn); io.map("isConst", I.IsConst); io.map("isVolatile", I.IsVolatile); io.map("isFinal", I.IsFinal); - io.map("isNodiscard", I.IsNodiscard); + io.map("isOverride", I.IsOverride); io.map("isExplicitObjectMemberFunction", I.IsExplicitObjectMemberFunction); if (I.Constexpr != ConstexprKind::None) { @@ -251,7 +247,6 @@ tag_invoke( { io.map("requires", I.Requires.Written); } - io.map("attributes", dom::LazyArray(I.Attributes)); } /** Map the FunctionInfo to a @ref dom::Value object. diff --git a/include/mrdocs/Metadata/Info/Variable.hpp b/include/mrdocs/Metadata/Info/Variable.hpp index c8d8ece54..c3f7c7528 100644 --- a/include/mrdocs/Metadata/Info/Variable.hpp +++ b/include/mrdocs/Metadata/Info/Variable.hpp @@ -17,7 +17,6 @@ #include #include #include -#include #include namespace clang::mrdocs { @@ -89,7 +88,6 @@ tag_invoke( { io.map("initializer", I.Initializer.Written); } - io.map("attributes", dom::LazyArray(I.Attributes)); } /** Map the VariableInfo to a @ref dom::Value object. diff --git a/include/mrdocs/Metadata/Specifiers.hpp b/include/mrdocs/Metadata/Specifiers.hpp index b9d069da4..9296fb1bb 100644 --- a/include/mrdocs/Metadata/Specifiers.hpp +++ b/include/mrdocs/Metadata/Specifiers.hpp @@ -36,6 +36,17 @@ enum class AccessKind Private, }; +/** Attribute kinds. +*/ +enum class AttributeKind +{ + Deprecated, + MaybeUnused, + Nodiscard, + Noreturn, + NoUniqueAddress +}; + /** `constexpr`/`consteval` specifier kinds [dcl.spec.general] p2: At most one of the `constexpr`, `consteval`, @@ -209,6 +220,7 @@ enum class StorageClassKind }; MRDOCS_DECL dom::String toString(AccessKind kind) noexcept; +MRDOCS_DECL dom::String toString(AttributeKind kind) noexcept; MRDOCS_DECL dom::String toString(ConstexprKind kind) noexcept; MRDOCS_DECL dom::String toString(ExplicitKind kind) noexcept; MRDOCS_DECL dom::String toString(NoexceptKind kind) noexcept; @@ -278,6 +290,18 @@ tag_invoke( v = toString(kind); } +/** Return the AttributeKind as a @ref dom::Value string. + */ +inline +void +tag_invoke( + dom::ValueFromTag, + dom::Value& v, + AttributeKind kind) +{ + v = toString(kind); +} + /** Return the ConstexprKind as a @ref dom::Value string. */ inline diff --git a/share/mrdocs/addons/generator/common/partials/symbol/attributes.hbs b/share/mrdocs/addons/generator/common/partials/symbol/attributes.hbs new file mode 100644 index 000000000..b91c1b94c --- /dev/null +++ b/share/mrdocs/addons/generator/common/partials/symbol/attributes.hbs @@ -0,0 +1,2 @@ +{{!-- Renders the symbol attributes. --}} +{{ str "[[" }}{{join ", " attributes}}{{ str "]]" }} \ No newline at end of file diff --git a/share/mrdocs/addons/generator/common/partials/symbol/signature/concept.hbs b/share/mrdocs/addons/generator/common/partials/symbol/signature/concept.hbs index ae55eb0c2..cbdca0fa7 100644 --- a/share/mrdocs/addons/generator/common/partials/symbol/signature/concept.hbs +++ b/share/mrdocs/addons/generator/common/partials/symbol/signature/concept.hbs @@ -1,3 +1,3 @@ {{>template/head template}} -concept {{>symbol/name symbol}} = {{constraint}}; \ No newline at end of file +concept {{>symbol/name symbol}}{{#if attributes}} {{>symbol/attributes symbol}}{{/if}} = {{constraint}}; \ No newline at end of file diff --git a/share/mrdocs/addons/generator/common/partials/symbol/signature/enum.hbs b/share/mrdocs/addons/generator/common/partials/symbol/signature/enum.hbs index 202010d35..41689683f 100644 --- a/share/mrdocs/addons/generator/common/partials/symbol/signature/enum.hbs +++ b/share/mrdocs/addons/generator/common/partials/symbol/signature/enum.hbs @@ -1,2 +1,2 @@ -enum {{#if isScoped}}class {{/if}}{{>symbol/name .~}} +enum{{#if isScoped}} class{{/if}}{{#if attributes}} {{>symbol/attributes symbol}}{{/if}} {{>symbol/name .~}} {{#if type}} : {{>type/declarator type}}{{/if}}; \ No newline at end of file diff --git a/share/mrdocs/addons/generator/common/partials/symbol/signature/field.hbs b/share/mrdocs/addons/generator/common/partials/symbol/signature/field.hbs index e43274dc5..d96783fbe 100644 --- a/share/mrdocs/addons/generator/common/partials/symbol/signature/field.hbs +++ b/share/mrdocs/addons/generator/common/partials/symbol/signature/field.hbs @@ -1,5 +1,5 @@ -{{#if attributes}}{{ str "[[" }}{{join ", " attributes}}{{ str "]]" }} -{{/if}} +{{#if attributes}}{{>symbol/attributes symbol}} +{{/if~}} {{#if isMutable}}mutable {{/if~}} {{>type/declarator-prefix type}} {{>symbol/name symbol~}} 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 130a8b58d..acd79e615 100644 --- a/share/mrdocs/addons/generator/common/partials/symbol/signature/function.hbs +++ b/share/mrdocs/addons/generator/common/partials/symbol/signature/function.hbs @@ -2,7 +2,7 @@ {{/if~}} {{#if isFriend}}friend {{/if~}} -{{#if attributes}}{{#unless isFriend}}{{ str "[[" }}{{join ", " attributes}}{{ str "]]" }} +{{#if attributes}}{{#unless isFriend}}{{>symbol/attributes symbol}} {{/unless}}{{/if~}} {{#if constexprKind}}{{constexprKind}} {{/if~}} @@ -28,7 +28,7 @@ {{#if requires}} requires {{requires}}{{/if~}} -{{#if hasOverrideAttr}} override{{/if~}} +{{#if isOverride}} override{{/if~}} {{#if isFinal}} final{{/if~}} {{#if isPure}} = 0{{/if~}} {{#if isDeleted}} = delete{{/if~}} diff --git a/share/mrdocs/addons/generator/common/partials/symbol/signature/record.hbs b/share/mrdocs/addons/generator/common/partials/symbol/signature/record.hbs index 0afb25ed2..66183f1d2 100644 --- a/share/mrdocs/addons/generator/common/partials/symbol/signature/record.hbs +++ b/share/mrdocs/addons/generator/common/partials/symbol/signature/record.hbs @@ -1,6 +1,6 @@ {{#if template}}{{>template/head template}} {{/if~}} -{{#if isFriend}}friend {{/if}}{{tag}} {{>symbol/name symbol link=(select link link template.primary)~}} +{{#if isFriend}}friend {{/if}}{{tag}}{{#if attributes}} {{>symbol/attributes symbol}}{{/if}} {{>symbol/name symbol link=(select link link template.primary)~}} {{#unless bases~}} {{else if isFriend~}} {{else}} diff --git a/share/mrdocs/addons/generator/common/partials/symbol/signature/typedef.hbs b/share/mrdocs/addons/generator/common/partials/symbol/signature/typedef.hbs index 1469df45e..0b08bd4eb 100644 --- a/share/mrdocs/addons/generator/common/partials/symbol/signature/typedef.hbs +++ b/share/mrdocs/addons/generator/common/partials/symbol/signature/typedef.hbs @@ -1,7 +1,9 @@ {{#if isUsing~}} {{#if template}}{{>template/head template}} {{/if~}} - using {{name}} = {{>type/declarator type}} + using {{name}}{{#if attributes}} {{>symbol/attributes symbol}}{{/if}} = {{>type/declarator type}} {{~else~}} + {{#if attributes}}{{>symbol/attributes symbol}} + {{/if~}} typedef {{>type/declarator type decl-name=name}} {{~/if}}; \ No newline at end of file diff --git a/share/mrdocs/addons/generator/common/partials/symbol/signature/variable.hbs b/share/mrdocs/addons/generator/common/partials/symbol/signature/variable.hbs index 77caeb6a1..856bcc3df 100644 --- a/share/mrdocs/addons/generator/common/partials/symbol/signature/variable.hbs +++ b/share/mrdocs/addons/generator/common/partials/symbol/signature/variable.hbs @@ -1,5 +1,7 @@ {{#if template}}{{>template/head template}} {{/if~}} +{{#if attributes}}{{>symbol/attributes symbol}} +{{/if~}} {{#if isInline}}inline {{/if~}} {{#if isConstexpr}}constexpr {{/if~}} {{#if storageClass}}{{storageClass}} diff --git a/src/lib/AST/ASTVisitor.cpp b/src/lib/AST/ASTVisitor.cpp index 95ca28786..cf6f8fbf7 100644 --- a/src/lib/AST/ASTVisitor.cpp +++ b/src/lib/AST/ASTVisitor.cpp @@ -525,6 +525,7 @@ populate(Info& I, bool const isNew, DeclTy const* D) { populate(I.javadoc, D); populate(dynamic_cast(I), D); + populateAttributes(I, D); // All other information is redundant if the symbol is not new MRDOCS_CHECK_OR(isNew); @@ -800,8 +801,6 @@ populate( I.IsExplicitlyDefaulted |= D->isExplicitlyDefaulted(); I.IsDeleted |= D->isDeleted(); I.IsDeletedAsWritten |= D->isDeletedAsWritten(); - I.IsNoReturn |= D->isNoReturn(); - I.HasOverrideAttr |= D->hasAttr(); if (ConstexprSpecKind const CSK = D->getConstexprKind(); CSK != ConstexprSpecKind::Unspecified) @@ -814,7 +813,6 @@ populate( I.StorageClass = toStorageClassKind(SC); } - I.IsNodiscard |= D->hasAttr(); I.IsExplicitObjectMemberFunction |= D->hasCXXExplicitFunctionObjectParameter(); ArrayRef const params = D->parameters(); @@ -900,8 +898,6 @@ populate( } } } - - populateAttributes(I, D); } void @@ -927,6 +923,7 @@ populate(FunctionInfo& I, CXXMethodDecl const* D) I.IsVolatile |= D->isVolatile(); I.RefQualifier = toReferenceKind(D->getRefQualifier()); I.IsFinal |= D->hasAttr(); + I.IsOverride |= D->hasAttr(); } void @@ -1056,7 +1053,6 @@ populate( QT.removeLocalConst(); } I.Type = toTypeInfo(QT); - populateAttributes(I, D); } void @@ -1100,10 +1096,6 @@ populate( I.IsBitfield = true; populate(I.BitfieldWidth, D->getBitWidth()); } - I.HasNoUniqueAddress = D->hasAttr(); - I.IsDeprecated = D->hasAttr(); - I.IsMaybeUnused = D->hasAttr(); - populateAttributes(I, D); } void @@ -1624,11 +1616,60 @@ populate( })); } -template InfoTy> void ASTVisitor:: -populateAttributes(InfoTy& I, Decl const* D) +populateAttributes(Info& I, Decl const* D) { + if(! D->hasAttrs()) + return; + + if(const TemplateDecl* TD = D->getDescribedTemplate()) + populateAttributes(I, TD); + + for(const Attr* AT : D->getAttrs()) + { + switch(AT->getKind()) + { + case attr::Kind::Deprecated: + addAttribute(I, AttributeKind::Deprecated); + break; + case attr::Kind::Unused: + addAttribute(I, AttributeKind::MaybeUnused); + break; + case attr::Kind::WarnUnusedResult: + addAttribute(I, AttributeKind::Nodiscard); + break; + case attr::Kind::NoReturn: + case attr::Kind::CXX11NoReturn: + addAttribute(I, AttributeKind::Noreturn); + break; + case attr::Kind::NoUniqueAddress: + addAttribute(I, AttributeKind::NoUniqueAddress); + break; + default: + // KRYSTIAN TODO: handle more attributes types + break; + } + } + +#if 0 + if(D->hasAttr()) + addAttribute(I, AttributeKind::Deprecated); + + if(D->hasAttr()) + addAttribute(I, AttributeKind::MaybeUnused); + + if(D->hasAttr()) + addAttribute(I, AttributeKind::Nodiscard); + + if(D->hasAttr()) + addAttribute(I, AttributeKind::Noreturn); + + if(D->hasAttr()) + addAttribute(I, AttributeKind::NoUniqueAddress); + #endif + + #if 0 if constexpr (requires { I.Attributes; }) { MRDOCS_CHECK_OR(D->hasAttrs()); @@ -1645,6 +1686,18 @@ populateAttributes(InfoTy& I, Decl const* D) } } } + #endif +} + +void +ASTVisitor:: +addAttribute( + Info& I, + AttributeKind kind) +{ + if(std::ranges::find(I.Attributes, kind) != I.Attributes.end()) + return; + I.Attributes.emplace_back(kind); } void diff --git a/src/lib/AST/ASTVisitor.hpp b/src/lib/AST/ASTVisitor.hpp index c6f717143..b39e79021 100644 --- a/src/lib/AST/ASTVisitor.hpp +++ b/src/lib/AST/ASTVisitor.hpp @@ -708,10 +708,11 @@ class ASTVisitor std::vector>& result, ASTTemplateArgumentListInfo const* args); - template InfoTy> - static void - populateAttributes(InfoTy& I, Decl const* D); + populateAttributes(Info& I, Decl const* D); + + void + addAttribute(Info& I, AttributeKind kind); // ================================================= // Populate function helpers diff --git a/src/lib/Gen/xml/XMLWriter.cpp b/src/lib/Gen/xml/XMLWriter.cpp index df3b7c9e1..c0fb02c56 100644 --- a/src/lib/Gen/xml/XMLWriter.cpp +++ b/src/lib/Gen/xml/XMLWriter.cpp @@ -244,8 +244,8 @@ writeEnum( } writeSourceInfo(I); - writeJavadoc(I.javadoc); + writeAttributes(I); corpus_.traverse(I, *this); @@ -269,8 +269,8 @@ writeEnumConstant( }); writeSourceInfo(I); - writeJavadoc(I.javadoc); + writeAttributes(I); tags_.close(enumConstantTagName); } @@ -286,8 +286,8 @@ writeFriend( }); writeSourceInfo(I); - writeJavadoc(I.javadoc); + writeAttributes(I); Attributes attrs = {}; if(I.FriendSymbol) @@ -325,6 +325,7 @@ writeFunction( }); writeSourceInfo(I); + writeAttributes(I); writeAttr(I.IsVariadic, "is-variadic", tags_); writeAttr(I.IsVirtualAsWritten, "is-virtual-as-written", tags_); @@ -333,8 +334,7 @@ writeFunction( writeAttr(I.IsExplicitlyDefaulted, "is-explicitly-defaulted", tags_); writeAttr(I.IsDeleted, "is-deleted", tags_); writeAttr(I.IsDeletedAsWritten, "is-deleted-as-written", tags_); - writeAttr(I.IsNoReturn, "is-no-return", tags_); - writeAttr(I.HasOverrideAttr, "has-override", tags_); + writeAttr(I.IsOverride, "is-override", tags_); writeAttr(I.HasTrailingReturn, "has-trailing-return", tags_); writeAttr(I.Constexpr, "constexpr-kind", tags_); writeAttr(I.OverloadedOperator, "operator", tags_); @@ -342,7 +342,6 @@ writeFunction( writeAttr(I.IsConst, "is-const", tags_); writeAttr(I.IsVolatile, "is-volatile", tags_); writeAttr(I.RefQualifier, "ref-qualifier", tags_); - writeAttr(I.IsNodiscard, "nodiscard", tags_); writeAttr(I.IsExplicitObjectMemberFunction, "is-explicit-object-member-function", tags_); writeReturnType(*I.ReturnType, tags_); @@ -383,6 +382,7 @@ writeGuide( }); writeSourceInfo(I); + writeAttributes(I); tags_.open(deducedTagName); writeType(I.Deduced, tags_); @@ -390,7 +390,7 @@ writeGuide( for(auto const& J : I.Params) writeParam(J, tags_); - + writeJavadoc(I.javadoc); tags_.close(guideTagName); @@ -413,8 +413,8 @@ writeConcept( }); writeSourceInfo(I); - writeJavadoc(I.javadoc); + writeAttributes(I); tags_.close(conceptTagName); @@ -433,8 +433,8 @@ writeNamespaceAlias( }); writeSourceInfo(I); - writeJavadoc(I.javadoc); + writeAttributes(I); tags_.write("aliased", {}, { {"name", toString(*I.AliasedSymbol)}, @@ -477,8 +477,8 @@ XMLWriter:: }); writeSourceInfo(I); - writeJavadoc(I.javadoc); + writeAttributes(I); for (auto const& id : I.UsingSymbols) tags_.write("named", {}, { id }); @@ -502,6 +502,7 @@ writeRecord( }); writeSourceInfo(I); + writeAttributes(I); writeAttr(I.IsFinal, "is-final", tags_); writeAttr(I.IsFinalDestructor, "is-final-dtor", tags_); @@ -544,9 +545,10 @@ writeTypedef( }); writeSourceInfo(I); + writeAttributes(I); writeType(I.Type, tags_); - + writeJavadoc(I.javadoc); tags_.close(tag); @@ -578,6 +580,7 @@ writeField( }); writeSourceInfo(I); + writeAttributes(I); if(I.IsMutable) tags_.write(attributeTagName, {}, { @@ -585,9 +588,6 @@ writeField( }); writeAttr(I.IsVariant, "is-variant", tags_); - writeAttr(I.IsMaybeUnused, "maybe-unused", tags_); - writeAttr(I.IsDeprecated, "deprecated", tags_); - writeAttr(I.HasNoUniqueAddress, "no-unique-address", tags_); writeType(I.Type, tags_); @@ -610,6 +610,7 @@ writeVariable( }); writeSourceInfo(I); + writeAttributes(I); writeAttr(I.StorageClass, "storage-class", tags_); writeAttr(I.IsInline, "is-inline", tags_); @@ -628,6 +629,15 @@ writeVariable( //------------------------------------------------ +void +XMLWriter:: +writeAttributes( + const Info& I) +{ + for(auto attr : I.Attributes) + tags_.write(attributeTagName, {}, { { "id", toString(attr) } }); +} + void XMLWriter:: writeSourceInfo( diff --git a/src/lib/Gen/xml/XMLWriter.hpp b/src/lib/Gen/xml/XMLWriter.hpp index 28bd07feb..ec516d8ee 100644 --- a/src/lib/Gen/xml/XMLWriter.hpp +++ b/src/lib/Gen/xml/XMLWriter.hpp @@ -68,6 +68,7 @@ class XMLWriter void writeSourceInfo(SourceInfo const& I); void writeLocation(Location const& loc, bool def = false); void writeJavadoc(std::optional const& javadoc); + void writeAttributes(const Info& I); void openTemplate(const std::optional& I); void closeTemplate(const std::optional& I); diff --git a/src/lib/Metadata/Info.cpp b/src/lib/Metadata/Info.cpp index db2746b0f..2c03abb3d 100644 --- a/src/lib/Metadata/Info.cpp +++ b/src/lib/Metadata/Info.cpp @@ -64,6 +64,22 @@ merge(Info& I, Info&& Other) { merge(*I.javadoc, std::move(*Other.javadoc)); } + + if(I.Attributes.empty()) + { + I.Attributes = std::move(Other.Attributes); + } + else if(! Other.Attributes.empty()) + { + auto it = std::ranges::remove_if( + Other.Attributes, [&](AttributeKind k) + { + return std::ranges::find( + I.Attributes, k) != I.Attributes.end(); + }).begin(); + I.Attributes.insert(I.Attributes.end(), + Other.Attributes.begin(), it); + } } } // clang::mrdocs diff --git a/src/lib/Metadata/Info/Field.cpp b/src/lib/Metadata/Info/Field.cpp index ae31c6966..55ba56756 100644 --- a/src/lib/Metadata/Info/Field.cpp +++ b/src/lib/Metadata/Info/Field.cpp @@ -32,9 +32,6 @@ merge(FieldInfo& I, FieldInfo&& Other) merge(I.BitfieldWidth, std::move(Other.BitfieldWidth)); I.IsVariant |= Other.IsVariant; I.IsMutable |= Other.IsMutable; - I.IsMaybeUnused |= Other.IsMaybeUnused; - I.IsDeprecated |= Other.IsDeprecated; - I.HasNoUniqueAddress |= Other.HasNoUniqueAddress; } } // clang::mrdocs diff --git a/src/lib/Metadata/Info/Function.cpp b/src/lib/Metadata/Info/Function.cpp index ecd879832..a197b2ebb 100644 --- a/src/lib/Metadata/Info/Function.cpp +++ b/src/lib/Metadata/Info/Function.cpp @@ -330,13 +330,11 @@ merge(FunctionInfo& I, FunctionInfo&& Other) I.IsExplicitlyDefaulted |= Other.IsExplicitlyDefaulted; I.IsDeleted |= Other.IsDeleted; I.IsDeletedAsWritten |= Other.IsDeletedAsWritten; - I.IsNoReturn |= Other.IsNoReturn; - I.HasOverrideAttr |= Other.HasOverrideAttr; I.HasTrailingReturn |= Other.HasTrailingReturn; I.IsConst |= Other.IsConst; I.IsVolatile |= Other.IsVolatile; I.IsFinal |= Other.IsFinal; - I.IsNodiscard |= Other.IsNodiscard; + I.IsOverride |= Other.IsOverride; I.IsExplicitObjectMemberFunction |= Other.IsExplicitObjectMemberFunction; if (I.Constexpr == ConstexprKind::None) { diff --git a/src/lib/Metadata/Specifiers.cpp b/src/lib/Metadata/Specifiers.cpp index 2e3390648..8a1c68ba0 100644 --- a/src/lib/Metadata/Specifiers.cpp +++ b/src/lib/Metadata/Specifiers.cpp @@ -26,6 +26,20 @@ dom::String toString(AccessKind kind) noexcept } } +dom::String toString(AttributeKind kind) noexcept +{ + switch(kind) + { + case AttributeKind::Deprecated: return "deprecated"; + case AttributeKind::MaybeUnused: return "maybe_unused"; + case AttributeKind::Nodiscard: return "nodiscard"; + case AttributeKind::Noreturn: return "noreturn"; + case AttributeKind::NoUniqueAddress: return "no_unique_address"; + default: + MRDOCS_UNREACHABLE(); + } +} + dom::String toString(StorageClassKind kind) noexcept { switch(kind) diff --git a/test-files/golden-tests/filters/symbol-name/excluded-base-class.xml b/test-files/golden-tests/filters/symbol-name/excluded-base-class.xml index e33b54280..3c77edd6a 100644 --- a/test-files/golden-tests/filters/symbol-name/excluded-base-class.xml +++ b/test-files/golden-tests/filters/symbol-name/excluded-base-class.xml @@ -13,11 +13,11 @@ - + - + @@ -37,7 +37,7 @@ - + diff --git a/test-files/golden-tests/snippets/terminate.xml b/test-files/golden-tests/snippets/terminate.xml index a47f44fa8..aaa40702e 100644 --- a/test-files/golden-tests/snippets/terminate.xml +++ b/test-files/golden-tests/snippets/terminate.xml @@ -4,7 +4,7 @@ - + Exit the program. diff --git a/test-files/golden-tests/symbols/function/attributes-2.adoc b/test-files/golden-tests/symbols/function/attributes-2.adoc index 87af947cd..1eb417a05 100644 --- a/test-files/golden-tests/symbols/function/attributes-2.adoc +++ b/test-files/golden-tests/symbols/function/attributes-2.adoc @@ -22,7 +22,6 @@ Declared in `<attributes‐2.cpp>` [source,cpp,subs="verbatim,replacements,macros,-callouts"] ---- template<class T> -[[nodiscard]] int f(); ---- diff --git a/test-files/golden-tests/symbols/function/attributes-2.html b/test-files/golden-tests/symbols/function/attributes-2.html index 8f3f4bf24..e8de79b54 100644 --- a/test-files/golden-tests/symbols/function/attributes-2.html +++ b/test-files/golden-tests/symbols/function/attributes-2.html @@ -34,7 +34,6 @@

Synopsis

 
 template<class T>
-[[nodiscard]]
 int
 f();
 
diff --git a/test-files/golden-tests/symbols/function/mem-fn.xml b/test-files/golden-tests/symbols/function/mem-fn.xml
index 45064bb1d..301e9bbe1 100644
--- a/test-files/golden-tests/symbols/function/mem-fn.xml
+++ b/test-files/golden-tests/symbols/function/mem-fn.xml
@@ -115,7 +115,7 @@
     
     
       
-      
+      
     
   
   
@@ -163,7 +163,7 @@
     
     
       
-      
+      
       
       
       
diff --git a/test-files/golden-tests/symbols/function/noreturn.xml b/test-files/golden-tests/symbols/function/noreturn.xml
index cd7b613bb..2a4c6a2fe 100644
--- a/test-files/golden-tests/symbols/function/noreturn.xml
+++ b/test-files/golden-tests/symbols/function/noreturn.xml
@@ -6,11 +6,11 @@
     
     
       
-      
+      
     
     
       
-      
+      
       
     
     
@@ -20,7 +20,7 @@
   
   
     
-    
+    
   
 
 
diff --git a/test-files/golden-tests/symbols/variable/no_unique_address.xml b/test-files/golden-tests/symbols/variable/no_unique_address.xml
index 5172e712c..81d8cf4c4 100644
--- a/test-files/golden-tests/symbols/variable/no_unique_address.xml
+++ b/test-files/golden-tests/symbols/variable/no_unique_address.xml
@@ -9,7 +9,7 @@
     
     
       
-      
+