From c0fd3fc88ea057ea536627191da9c61690760995 Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski Date: Tue, 11 Jul 2023 09:46:51 -0400 Subject: [PATCH] feat: TArg stores types --- include/mrdox/Metadata/Specialization.hpp | 2 +- include/mrdox/Metadata/Template.hpp | 155 ++++++-- include/mrdox/Metadata/Type.hpp | 2 +- include/mrdox/MetadataFwd.hpp | 3 + src/lib/-XML/CXXTags.hpp | 21 +- src/lib/-XML/XMLWriter.cpp | 6 +- src/lib/AST/ASTVisitor.cpp | 95 ++++- src/lib/AST/AnyBlock.hpp | 102 +++++- src/lib/AST/BitcodeIDs.hpp | 5 +- src/lib/AST/BitcodeWriter.cpp | 30 +- src/lib/AST/BitcodeWriter.hpp | 2 +- src/lib/Metadata/DomMetadata.cpp | 47 ++- src/lib/Metadata/Template.cpp | 19 + src/lib/Metadata/Type.cpp | 26 +- test-files/old-tests/alias-template.xml | 6 +- .../old-tests/class-template-partial-spec.xml | 8 +- test-files/old-tests/class-template-spec.xml | 16 +- .../class-template-specializations-1.xml | 340 +++++++++--------- .../class-template-specializations-2.xml | 22 +- .../class-template-specializations-3.xml | 36 +- .../old-tests/explicit-deduct-guide.xml | 8 +- .../implicit-instantiation-member-ref.xml | 8 +- .../old-tests/nested-private-template.xml | 4 +- .../spec-mem-implicit-instantiation.xml | 14 +- test-files/old-tests/static-data-template.xml | 8 +- .../old-tests/temp/c_mct_expl_inline.xml | 2 +- .../old-tests/temp/c_mct_expl_outside.xml | 2 +- .../old-tests/temp/c_mft_expl_inline.xml | 2 +- .../old-tests/temp/c_mft_expl_outside.xml | 2 +- test-files/old-tests/temp/ct_expl.xml | 2 +- .../old-tests/temp/ct_mc_expl_outside.xml | 2 +- .../old-tests/temp/ct_mct_expl_inline.xml | 2 +- .../old-tests/temp/ct_mct_expl_outside.xml | 4 +- .../old-tests/temp/ct_mf_expl_outside.xml | 2 +- .../old-tests/temp/ct_mft_expl_inline.xml | 2 +- .../old-tests/temp/ct_mft_expl_outside.xml | 4 +- test-files/old-tests/temp/ft_expl.xml | 2 +- test-files/old-tests/type-resolution.xml | 62 ++-- test-files/old-tests/var-template.xml | 8 +- 39 files changed, 714 insertions(+), 369 deletions(-) diff --git a/include/mrdox/Metadata/Specialization.hpp b/include/mrdox/Metadata/Specialization.hpp index ef6e6c790..3783889ad 100644 --- a/include/mrdox/Metadata/Specialization.hpp +++ b/include/mrdox/Metadata/Specialization.hpp @@ -50,7 +50,7 @@ struct SpecializationInfo : IsInfo { /** The template arguments the parent template is specialized for */ - std::vector Args; + std::vector> Args; /** ID of the template to which the arguments pertain */ SymbolID Primary = SymbolID::zero; diff --git a/include/mrdox/Metadata/Template.hpp b/include/mrdox/Metadata/Template.hpp index 80aca9790..835b8a297 100644 --- a/include/mrdox/Metadata/Template.hpp +++ b/include/mrdox/Metadata/Template.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,115 @@ namespace clang { namespace mrdox { +enum class TArgKind : int +{ + // type arguments + Type = 1, // for bitstream + // non-type arguments, i.e. expressions + NonType, + // template template arguments, i.e. template names + Template +}; + +MRDOX_DECL dom::String toString(TArgKind kind) noexcept; + +struct TArg +{ + /** The kind of template argument this is. */ + TArgKind Kind; + + /** Whether this template argument is a parameter expansion. */ + bool IsPackExpansion = false; + + constexpr virtual ~TArg() = default; + + constexpr bool isType() const noexcept { return Kind == TArgKind::Type; } + constexpr bool isNonType() const noexcept { return Kind == TArgKind::NonType; } + constexpr bool isTemplate() const noexcept { return Kind == TArgKind::Template; } + +protected: + constexpr + TArg( + TArgKind kind) noexcept + : Kind(kind) + { + } +}; + +template +struct IsTArg : TArg +{ + static constexpr TArgKind kind_id = K; + + static constexpr bool isType() noexcept { return K == TArgKind::Type; } + static constexpr bool isNonType() noexcept { return K == TArgKind::NonType; } + static constexpr bool isTemplate() noexcept { return K == TArgKind::Template; } + +protected: + constexpr + IsTArg() noexcept + : TArg(K) + { + } +}; + +struct TypeTArg + : IsTArg +{ + /** Template argument type. */ + std::unique_ptr Type; +}; + +struct NonTypeTArg + : IsTArg +{ + /** Template argument expression. */ + ExprInfo Value; +}; + +struct TemplateTArg + : IsTArg +{ + /** SymbolID of the referenced template. */ + SymbolID Template; + + /** Name of the referenced template. */ + std::string Name; +}; + +template< + typename TArgTy, + typename F, + typename... Args> + requires std::derived_from +constexpr +decltype(auto) +visit( + TArgTy& A, + F&& f, + Args&&... args) +{ + switch(A.Kind) + { + case TArgKind::Type: + return f(static_cast&>(A), + std::forward(args)...); + case TArgKind::NonType: + return f(static_cast&>(A), + std::forward(args)...); + case TArgKind::Template: + return f(static_cast&>(A), + std::forward(args)...); + default: + MRDOX_UNREACHABLE(); + } +} + +// ---------------------------------------------------------------- + enum class TParamKind : int { // template type parameter, e.g. "typename T" or "class T" @@ -103,48 +213,31 @@ struct TemplateTParam Optional Default; }; -template +template< + typename TParamTy, + typename F, + typename... Args> + requires std::derived_from constexpr decltype(auto) visit( - TParam& P, + TParamTy& P, F&& f, Args&&... args) { switch(P.Kind) { case TParamKind::Type: - return f(static_cast(P), + return f(static_cast&>(P), std::forward(args)...); case TParamKind::NonType: - return f(static_cast(P), + return f(static_cast&>(P), std::forward(args)...); case TParamKind::Template: - return f(static_cast(P), - std::forward(args)...); - default: - MRDOX_UNREACHABLE(); - } -} - -template -constexpr -decltype(auto) -visit( - const TParam& P, - F&& f, - Args&&... args) -{ - switch(P.Kind) - { - case TParamKind::Type: - return f(static_cast(P), - std::forward(args)...); - case TParamKind::NonType: - return f(static_cast(P), - std::forward(args)...); - case TParamKind::Template: - return f(static_cast(P), + return f(static_cast&>(P), std::forward(args)...); default: MRDOX_UNREACHABLE(); @@ -153,6 +246,7 @@ visit( // ---------------------------------------------------------------- +#if 0 struct TArg { std::string Value; @@ -162,6 +256,7 @@ struct TArg MRDOX_DECL TArg(std::string&& value); }; +#endif // ---------------------------------------------------------------- @@ -191,7 +286,7 @@ struct TemplateInfo once in Args outside of a non-deduced context */ std::vector> Params; - std::vector Args; + std::vector> Args; /** Primary template ID for partial and explicit specializations. */ diff --git a/include/mrdox/Metadata/Type.hpp b/include/mrdox/Metadata/Type.hpp index 860ada977..ae1099b27 100644 --- a/include/mrdox/Metadata/Type.hpp +++ b/include/mrdox/Metadata/Type.hpp @@ -123,7 +123,7 @@ struct SpecializationTypeInfo std::unique_ptr ParentType; std::string Name; SymbolID id = SymbolID::zero; - std::vector TemplateArgs; + std::vector> TemplateArgs; }; struct LValueReferenceTypeInfo diff --git a/include/mrdox/MetadataFwd.hpp b/include/mrdox/MetadataFwd.hpp index 53b506571..ed2c688b5 100644 --- a/include/mrdox/MetadataFwd.hpp +++ b/include/mrdox/MetadataFwd.hpp @@ -60,6 +60,9 @@ struct ConstantExprInfo; struct TemplateInfo; struct TArg; +struct TypeTArg; +struct NonTypeTArg; +struct TemplateTArg; struct TParam; struct TypeTParam; struct NonTypeTParam; diff --git a/src/lib/-XML/CXXTags.hpp b/src/lib/-XML/CXXTags.hpp index 70b9c085f..5c623638f 100644 --- a/src/lib/-XML/CXXTags.hpp +++ b/src/lib/-XML/CXXTags.hpp @@ -262,7 +262,7 @@ writeType( if constexpr(T::isSpecialization()) { for(const auto& targ : t.TemplateArgs) - writeTemplateArg(targ, tags); + writeTemplateArg(*targ, tags); } if constexpr(requires { t.PointeeType; }) @@ -365,9 +365,22 @@ inline void writeTemplateParam(const TParam& I, XMLTags& tags) inline void writeTemplateArg(const TArg& I, XMLTags& tags) { - tags.write(targTagName, {}, { - { "value", I.Value } - }); + visit(I, [&](const T& A) + { + Attributes attrs = { + {"class", toString(T::kind_id)} + }; + + if constexpr(T::isType()) + attrs.push({"type", toString(*A.Type)}); + else if constexpr(T::isNonType()) + attrs.push({"value", A.Value.Written}); + else if constexpr(T::isTemplate()) + attrs.push({A.Template}); + + tags.write(targTagName, {}, + std::move(attrs)); + }); } /** Return the xml tag name for the Info. diff --git a/src/lib/-XML/XMLWriter.cpp b/src/lib/-XML/XMLWriter.cpp index 1a3b1656d..fe99f742a 100644 --- a/src/lib/-XML/XMLWriter.cpp +++ b/src/lib/-XML/XMLWriter.cpp @@ -493,7 +493,7 @@ openTemplate( for(const auto& tparam : I->Params) writeTemplateParam(*tparam, tags_); for(const auto& targ : I->Args) - writeTemplateArg(targ, tags_); + writeTemplateArg(*targ, tags_); } void @@ -516,8 +516,8 @@ writeSpecialization( {"primary", toString(I.Primary) } }); - for(const TArg& targ : I.Args) - writeTemplateArg(targ, tags_); + for(const auto& targ : I.Args) + writeTemplateArg(*targ, tags_); corpus_.traverse(I, *this); diff --git a/src/lib/AST/ASTVisitor.cpp b/src/lib/AST/ASTVisitor.cpp index eeff33893..8ee727efb 100644 --- a/src/lib/AST/ASTVisitor.cpp +++ b/src/lib/AST/ASTVisitor.cpp @@ -1348,7 +1348,7 @@ class ASTVisitor template void buildTemplateArgs( - std::vector& result, + std::vector>& result, Range&& range) { // TypePrinter generates an internal placeholder name (e.g. type-parameter-0-0) @@ -1363,21 +1363,92 @@ class ASTVisitor const auto& policy = context_.getPrintingPolicy(); for(const TemplateArgument& arg : range) { - std::string arg_str; - if(arg.getKind() == TemplateArgument::Type) + switch(arg.getKind()) { - QualType qt = arg.getAsType(); - // KRYSTIAN FIXME: we *really* should not be - // converting types to strings like this. - // TArg needs to be a variant type anyways. - arg_str = toString(*buildTypeInfo(qt)); + // empty template argument (e.g. not yet deduced) + case TemplateArgument::Null: + break; + + // a template argument pack (any kind) + case TemplateArgument::Pack: + { + // KRYSTIAN NOTE: is this correct? should we have a + // separate TArgKind for packs instead of "unlaminating" + // them as we are doing here? + buildTemplateArgs(result, arg.pack_elements()); + break; } - else + // type + case TemplateArgument::Type: { - llvm::raw_string_ostream stream(arg_str); - arg.print(policy, stream, false); + auto R = std::make_unique(); + QualType QT = arg.getAsType(); + MRDOX_ASSERT(! QT.isNull()); + // if the template argument is a pack expansion, + // use the expansion pattern as the type & mark + // the template argument as a pack expansion + if(const Type* T = QT.getTypePtr(); + auto* PT = dyn_cast(T)) + { + R->IsPackExpansion = true; + QT = PT->getPattern(); + } + R->Type = buildTypeInfo(QT); + + result.emplace_back(std::move(R)); + break; + } + // pack expansion of a template name + case TemplateArgument::TemplateExpansion: + // template name + case TemplateArgument::Template: + { + auto R = std::make_unique(); + R->IsPackExpansion = arg.isPackExpansion(); + TemplateName TN = arg.getAsTemplateOrTemplatePattern(); + TemplateDecl* TD = cast( + getInstantiatedFrom(TN.getAsTemplateDecl())); + MRDOX_ASSERT(TD); + if(auto* II = TD->getIdentifier()) + R->Name = II->getName(); + // do not extract a SymbolID or build Info if + // the template template parameter names a + // template template parameter or builtin template + if(! isa(TD) && + ! isa(TD)) + { + extractSymbolID(TD, R->Template); + getOrBuildInfo(TD); + } + result.emplace_back(std::move(R)); + break; + } + // nullptr value + case TemplateArgument::NullPtr: + // expression referencing a declaration + case TemplateArgument::Declaration: + // integral expression + case TemplateArgument::Integral: + // expression + case TemplateArgument::Expression: + { + auto R = std::make_unique(); + R->IsPackExpansion = arg.isPackExpansion(); + // if this is a pack expansion, use the template argument + // expansion pattern in place of the template argument pack + const TemplateArgument& adjusted = + R->IsPackExpansion ? + arg.getPackExpansionPattern() : arg; + + llvm::raw_string_ostream stream(R->Value.Written); + adjusted.print(policy, stream, false); + + result.emplace_back(std::move(R)); + break; + } + default: + MRDOX_UNREACHABLE(); } - result.emplace_back(std::move(arg_str)); } } diff --git a/src/lib/AST/AnyBlock.hpp b/src/lib/AST/AnyBlock.hpp index f3071ae8c..423b70e16 100644 --- a/src/lib/AST/AnyBlock.hpp +++ b/src/lib/AST/AnyBlock.hpp @@ -596,12 +596,15 @@ class BaseBlock class TemplateArgBlock : public BitcodeReader::AnyBlock { - TArg& I_; + BitcodeReader& br_; + std::unique_ptr& I_; public: TemplateArgBlock( - TArg& I) noexcept - : I_(I) + std::unique_ptr& I, + BitcodeReader& br) noexcept + : br_(br) + , I_(I) { } @@ -613,12 +616,77 @@ class TemplateArgBlock { switch(ID) { - case TEMPLATE_ARG_VALUE: - return decodeRecord(R, I_.Value, Blob); + case TEMPLATE_ARG_KIND: + { + TArgKind kind{}; + if(auto err = decodeRecord(R, kind, Blob)) + return err; + switch(kind) + { + case TArgKind::Type: + I_ = std::make_unique(); + break; + case TArgKind::NonType: + I_ = std::make_unique(); + break; + case TArgKind::Template: + I_= std::make_unique(); + break; + default: + return formatError("invalid template argument kind"); + } + return Error::success(); + } + case TEMPLATE_ARG_IS_PACK: + { + return decodeRecord(R, I_->IsPackExpansion, Blob); + } + case TEMPLATE_ARG_TEMPLATE: + { + if(! I_->isTemplate()) + return formatError("only TemplateTArgs may reference a template"); + return decodeRecord(R, + static_cast( + *I_.get()).Template, Blob); + } + case TEMPLATE_ARG_NAME: + { + if(! I_->isTemplate()) + return formatError("only TemplateTArgs may have a template name"); + return decodeRecord(R, + static_cast( + *I_.get()).Name, Blob); + } default: return AnyBlock::parseRecord(R, ID, Blob); } } + Error + readSubBlock( + unsigned ID) override + { + switch(ID) + { + case BI_TYPEINFO_BLOCK_ID: + { + if(! I_->isType()) + return formatError("only TypeTArgs may have types"); + TypeInfoBlock B(static_cast( + *I_.get()).Type, br_); + return br_.readBlock(B, ID); + } + case BI_EXPR_BLOCK_ID: + { + if(! I_->isNonType()) + return formatError("only NonTypeTArgs may have expressions"); + ExprBlock B(static_cast( + *I_.get()).Value, br_); + return br_.readBlock(B, ID); + } + default: + return AnyBlock::readSubBlock(ID); + } + } }; //------------------------------------------------ @@ -646,17 +714,9 @@ class TemplateParamBlock { switch(ID) { - case TEMPLATE_PARAM_NAME: - { - return decodeRecord(R, I_->Name, Blob); - } - case TEMPLATE_PARAM_IS_PACK: - { - return decodeRecord(R, I_->IsParameterPack, Blob); - } case TEMPLATE_PARAM_KIND: { - TParamKind kind; + TParamKind kind{}; if(auto err = decodeRecord(R, kind, Blob)) return err; switch(kind) @@ -675,6 +735,14 @@ class TemplateParamBlock } return Error::success(); } + case TEMPLATE_PARAM_NAME: + { + return decodeRecord(R, I_->Name, Blob); + } + case TEMPLATE_PARAM_IS_PACK: + { + return decodeRecord(R, I_->IsParameterPack, Blob); + } case TEMPLATE_PARAM_DEFAULT: { return visit(*I_, [&](T& P) @@ -769,7 +837,7 @@ class TemplateBlock case BI_TEMPLATE_ARG_BLOCK_ID: { TemplateArgBlock A( - I_.Args.emplace_back()); + I_.Args.emplace_back(), br_); return br_.readBlock(A, ID); } case BI_TEMPLATE_PARAM_BLOCK_ID: @@ -841,7 +909,7 @@ readSubBlock(unsigned ID) if(! I_->isSpecialization()) return Error("wrong TypeInfo kind"); auto& I = static_cast(*I_); - TemplateArgBlock B(I.TemplateArgs.emplace_back()); + TemplateArgBlock B(I.TemplateArgs.emplace_back(), br_); return br_.readBlock(B, ID); } case BI_EXPR_BLOCK_ID: @@ -1386,7 +1454,7 @@ class SpecializationBlock { case BI_TEMPLATE_ARG_BLOCK_ID: { - TemplateArgBlock B(I->Args.emplace_back()); + TemplateArgBlock B(I->Args.emplace_back(), br_); return br_.readBlock(B, ID); } default: diff --git a/src/lib/AST/BitcodeIDs.hpp b/src/lib/AST/BitcodeIDs.hpp index c1d71b601..1ba7401aa 100644 --- a/src/lib/AST/BitcodeIDs.hpp +++ b/src/lib/AST/BitcodeIDs.hpp @@ -128,7 +128,10 @@ enum RecordID RECORD_KEY_KIND, RECORD_MEMBERS, RECORD_SPECIALIZATIONS, - TEMPLATE_ARG_VALUE, + TEMPLATE_ARG_KIND, + TEMPLATE_ARG_IS_PACK, + TEMPLATE_ARG_TEMPLATE, + TEMPLATE_ARG_NAME, TEMPLATE_PARAM_DEFAULT, TEMPLATE_PARAM_IS_PACK, TEMPLATE_PARAM_KIND, diff --git a/src/lib/AST/BitcodeWriter.cpp b/src/lib/AST/BitcodeWriter.cpp index bc61d5642..b368a3ce5 100644 --- a/src/lib/AST/BitcodeWriter.cpp +++ b/src/lib/AST/BitcodeWriter.cpp @@ -289,7 +289,10 @@ RecordIDNameMap = []() {SOURCE_INFO_DEFLOC, {"SourceDefLoc", &LocationAbbrev}}, {SOURCE_INFO_LOC, {"SourceLoc", &LocationAbbrev}}, {TEMPLATE_PRIMARY_USR, {"Primary", &SymbolIDAbbrev}}, - {TEMPLATE_ARG_VALUE, {"Value", &StringAbbrev}}, + {TEMPLATE_ARG_KIND, {"TArgKind", &Integer32Abbrev}}, + {TEMPLATE_ARG_IS_PACK, {"IsPack", &BoolAbbrev}}, + {TEMPLATE_ARG_TEMPLATE, {"TemplateID", &SymbolIDAbbrev}}, + {TEMPLATE_ARG_NAME, {"TemplateName", &StringAbbrev}}, {TEMPLATE_PARAM_KIND, {"Kind", &Integer32Abbrev}}, {TEMPLATE_PARAM_NAME, {"Name", &StringAbbrev}}, {TEMPLATE_PARAM_IS_PACK, {"IsPack", &BoolAbbrev}}, @@ -368,7 +371,8 @@ RecordsByBlock{ RECORD_FRIENDS, RECORD_MEMBERS, RECORD_SPECIALIZATIONS}}, // TArg {BI_TEMPLATE_ARG_BLOCK_ID, - {TEMPLATE_ARG_VALUE}}, + {TEMPLATE_ARG_KIND, TEMPLATE_ARG_IS_PACK, + TEMPLATE_ARG_TEMPLATE, TEMPLATE_ARG_NAME}}, // TemplateInfo {BI_TEMPLATE_BLOCK_ID, {TEMPLATE_PRIMARY_USR}}, @@ -1079,10 +1083,28 @@ emitBlock( void BitcodeWriter:: emitBlock( - const TArg& T) + const std::unique_ptr& T) { StreamSubBlockGuard Block(Stream, BI_TEMPLATE_ARG_BLOCK_ID); - emitRecord(T.Value, TEMPLATE_ARG_VALUE); + visit(*T, [&](const T& A) + { + emitRecord(A.Kind, TEMPLATE_ARG_KIND); + emitRecord(A.IsPackExpansion, TEMPLATE_ARG_IS_PACK); + + if constexpr(T::isType()) + { + emitBlock(A.Type); + } + else if constexpr(T::isNonType()) + { + emitBlock(A.Value); + } + else if constexpr(T::isTemplate()) + { + emitRecord(A.Template, TEMPLATE_ARG_TEMPLATE); + emitRecord(A.Name, TEMPLATE_ARG_NAME); + } + }); } void diff --git a/src/lib/AST/BitcodeWriter.hpp b/src/lib/AST/BitcodeWriter.hpp index ef7df6274..180c569b7 100644 --- a/src/lib/AST/BitcodeWriter.hpp +++ b/src/lib/AST/BitcodeWriter.hpp @@ -123,7 +123,7 @@ class BitcodeWriter void emitBlock(SpecializationInfo const& T); void emitBlock(TemplateInfo const& T); void emitBlock(std::unique_ptr const& T); - void emitBlock(TArg const& T); + void emitBlock(std::unique_ptr const& T); void emitBlock(TypedefInfo const& I); void emitBlock(VariableInfo const& I); void emitBlock(FieldInfo const& I); diff --git a/src/lib/Metadata/DomMetadata.cpp b/src/lib/Metadata/DomMetadata.cpp index 48e04d1a4..4bf5f56da 100644 --- a/src/lib/Metadata/DomMetadata.cpp +++ b/src/lib/Metadata/DomMetadata.cpp @@ -198,7 +198,8 @@ class DomParamArray : public dom::ArrayImpl // //------------------------------------------------ -static dom::Value domCreate(TArg const&, DomCorpus const&); +static dom::Value domCreate( + std::unique_ptr const&, DomCorpus const&); static dom::Value domCreate( std::unique_ptr const&, DomCorpus const&); static dom::Value domCreate( @@ -210,12 +211,12 @@ static dom::Value domCreate( */ class DomTArgArray : public dom::ArrayImpl { - std::vector const& list_; + std::vector> const& list_; DomCorpus const& domCorpus_; public: DomTArgArray( - std::vector const& list, + std::vector> const& list, DomCorpus const& domCorpus) noexcept : list_(list) , domCorpus_(domCorpus) @@ -266,11 +267,39 @@ class DomTParamArray : public dom::ArrayImpl static dom::Value domCreate( - TArg const& I, DomCorpus const& domCorpus) + std::unique_ptr const& I, + DomCorpus const& domCorpus) { - return dom::Object({ - { "value", dom::stringOrNull(I.Value) } - }); + if(! I) + return nullptr; + dom::Object::storage_type entries = { + { "kind", toString(I->Kind) }, + { "is-pack", I->IsPackExpansion } + }; + visit(*I, [&](const T& t) + { + if constexpr(T::isType()) + { + entries.emplace_back("type", + domCreate(t.Type, domCorpus)); + } + else if constexpr(T::isNonType()) + { + entries.emplace_back("value", + t.Value.Written); + } + else if constexpr(T::isTemplate()) + { + entries.emplace_back("name", + t.Name); + // KRYSTIAN NOTE: hack for missing SymbolIDs + if(t.Template != SymbolID::zero && + domCorpus.corpus.find(t.Template)) + entries.emplace_back("template", + toBase16(t.Template)); + } + }); + return dom::Object(std::move(entries)); } static @@ -283,8 +312,8 @@ domCreate( return nullptr; dom::Object::storage_type entries = { { "kind", toString(I->Kind) }, - { "name", dom::stringOrNull(I->Name)}, - { "is-pack", I->IsParameterPack} + { "name", dom::stringOrNull(I->Name) }, + { "is-pack", I->IsParameterPack } }; visit(*I, [&](const T& t) { diff --git a/src/lib/Metadata/Template.cpp b/src/lib/Metadata/Template.cpp index 30ee5d7e6..c6e55ad3d 100644 --- a/src/lib/Metadata/Template.cpp +++ b/src/lib/Metadata/Template.cpp @@ -15,12 +15,31 @@ namespace clang { namespace mrdox { +#if 0 TArg:: TArg( std::string&& value) : Value(std::move(value)) { } +#endif + +dom::String +toString( + TArgKind kind) noexcept +{ + switch(kind) + { + case TArgKind::Type: + return "type"; + case TArgKind::NonType: + return "non-type"; + case TArgKind::Template: + return "template"; + default: + MRDOX_UNREACHABLE(); + } +} dom::String toString( diff --git a/src/lib/Metadata/Type.cpp b/src/lib/Metadata/Type.cpp index 705aafb4b..c4a9badb0 100644 --- a/src/lib/Metadata/Type.cpp +++ b/src/lib/Metadata/Type.cpp @@ -169,10 +169,32 @@ operator()( write('<'); if(! t.TemplateArgs.empty()) { - write(t.TemplateArgs.front().Value); + auto targ_writer = + [&](const U& u) + { + if constexpr(U::isType()) + { + if(u.Type) + writeFullType(*u.Type, write); + } + if constexpr(U::isNonType()) + { + write(u.Value.Written); + } + if constexpr(U::isTemplate()) + { + write(u.Name); + } + if(u.IsPackExpansion) + write("..."); + }; + visit(*t.TemplateArgs.front(), targ_writer); for(auto first = t.TemplateArgs.begin(); ++first != t.TemplateArgs.end();) - write(", ", first->Value); + { + write(", "); + visit(**first, targ_writer); + } } write('>'); } diff --git a/test-files/old-tests/alias-template.xml b/test-files/old-tests/alias-template.xml index 3bd27313e..ec9a9c6eb 100644 --- a/test-files/old-tests/alias-template.xml +++ b/test-files/old-tests/alias-template.xml @@ -20,7 +20,7 @@ - + @@ -33,8 +33,8 @@ - - + + diff --git a/test-files/old-tests/class-template-partial-spec.xml b/test-files/old-tests/class-template-partial-spec.xml index 96733a438..3a51c397c 100644 --- a/test-files/old-tests/class-template-partial-spec.xml +++ b/test-files/old-tests/class-template-partial-spec.xml @@ -15,15 +15,15 @@ - - + + - - + +