diff --git a/src/mrdocs/AST/ASTVisitor.cpp b/src/mrdocs/AST/ASTVisitor.cpp index 3b42726e13..0ba5fffe79 100644 --- a/src/mrdocs/AST/ASTVisitor.cpp +++ b/src/mrdocs/AST/ASTVisitor.cpp @@ -115,6 +115,29 @@ gatherMacroParameters(clang::MacroInfo const* MI) return result; } +// The conversion function a declaration names, if it names one. +clang::CXXConversionDecl const* +underlyingConversion(clang::NamedDecl const* D) +{ + clang::NamedDecl const* target = D; + if (clang::UsingShadowDecl const* USD = + dyn_cast(target)) + { + target = USD->getTargetDecl(); + } + else if (clang::UsingDecl const* UD = dyn_cast(target); + UD && UD->shadow_size() != 0) + { + target = (*UD->shadow_begin())->getTargetDecl(); + } + if (clang::FunctionTemplateDecl const* FTD = + dyn_cast(target)) + { + target = FTD->getTemplatedDecl(); + } + return dyn_cast(target); +} + } // unnamed namespace void @@ -1278,6 +1301,10 @@ populate( auto INI = toName(Name, {}, NNS); MRDOCS_CHECK_OR(INI); I.IntroducedName = *INI; + if (clang::CXXConversionDecl const* CD = underlyingConversion(D)) + { + I.IntroducedName->Identifier = conversionNameAsWritten(CD); + } for (clang::UsingShadowDecl const* UDS: D->shadows()) { ScopeExitRestore s(mode_, Dependency); @@ -2216,11 +2243,27 @@ extractName(DeclTy const* D) return {}; } +std::string +ASTVisitor:: +conversionNameAsWritten(clang::CXXConversionDecl const* D) +{ + return "operator " + mrdocs::toString(*toType(D->getConversionType())); +} + std::string ASTVisitor:: extractName(clang::NamedDecl const* D) { - return extractName(D->getDeclName()); + std::string result; + if (clang::CXXConversionDecl const* CD = underlyingConversion(D)) + { + result = conversionNameAsWritten(CD); + } + else + { + result = extractName(D->getDeclName()); + } + return result; } std::string diff --git a/src/mrdocs/AST/ASTVisitor.hpp b/src/mrdocs/AST/ASTVisitor.hpp index 7d964fb881..aa41b10c8a 100644 --- a/src/mrdocs/AST/ASTVisitor.hpp +++ b/src/mrdocs/AST/ASTVisitor.hpp @@ -785,6 +785,10 @@ class ASTVisitor std::string extractName(clang::DeclarationName N); + // Name a conversion function after the type it converts to + std::string + conversionNameAsWritten(clang::CXXConversionDecl const* D); + llvm::SmallString<256> qualifiedName(clang::Decl const* D) const; diff --git a/tests/golden/fixtures/symbols/function/conv-operator-names.cpp b/tests/golden/fixtures/symbols/function/conv-operator-names.cpp new file mode 100644 index 0000000000..d84c478b28 --- /dev/null +++ b/tests/golden/fixtures/symbols/function/conv-operator-names.cpp @@ -0,0 +1,46 @@ +// Test that a conversion function is named with the type as written. + +/// An alias for a builtin. +using MyAlias = short; + +/// A trait stand-in for a constrained conversion. +template +struct IsArray +{ + /// Whether the type is an array. + static constexpr bool value = false; +}; + +/// A class template with conversion functions. +template +struct Holder +{ + /// Convert to the class template parameter. + explicit operator T(); + + /// Convert to a reference to the class template parameter. + explicit operator T&(); + + /// Convert to a dependent type. + explicit operator typename T::type(); + + /// Convert to a reference to a function template parameter. + template + explicit operator CArray&(); + + /// Convert to a function template parameter. + template + explicit operator Range() const; + + /// Convert through an alias. + explicit operator MyAlias(); + + /// Convert through a constrained template with a defaulted parameter. + template < + class Range, + class = decltype(Range(0))> + requires (!IsArray::value) + constexpr + explicit + operator Range() const; +}; diff --git a/tests/golden/fixtures/symbols/function/conv-operator-names.xml b/tests/golden/fixtures/symbols/function/conv-operator-names.xml new file mode 100644 index 0000000000..5eb83a63a3 --- /dev/null +++ b/tests/golden/fixtures/symbols/function/conv-operator-names.xml @@ -0,0 +1,740 @@ + + + + index + namespace + 4ZrjxJnU1LA5xSyrWMNuXTvSYKwt + regular + + 3VVDSy7yZT495J3sEQdZCm7VwFpU + 21Yh5PF5ewVmWeNR3NwSbcFHNTrQ 3qE7vj8ikuTMaJ3EwgcSEYoctGdA + + + + MyAlias + MyAlias + + + + conv-operator-names.cpp + conv-operator-names.cpp + 4 + 1 + + + + + typedef + 3VVDSy7yZT495J3sEQdZCm7VwFpU + regular + 4ZrjxJnU1LA5xSyrWMNuXTvSYKwt + + + brief + + + text + An alias for a builtin. + + + + + + + named + + + identifier + short + + + short + + + + + + Holder + Holder + + + conv-operator-names.cpp + conv-operator-names.cpp + 15 + 1 + + + + record + 21Yh5PF5ewVmWeNR3NwSbcFHNTrQ + regular + 4ZrjxJnU1LA5xSyrWMNuXTvSYKwt + + + brief + + + text + A class template with conversion functions. + + + + + struct + + + + Wz8WnbsdYDNstS7zo3xjvsp7SHi X1r857ZAaiGe53FPYsSZA2cLu2A 2BfAehCDBNckkTsVTfwiappi4aS8 74Ttqv4qsiQE26MzTuCihvtSjzJ 2v2EJK7VsLBqJ3p6mZrmi9QffkDM 2evy2c2rVeQCkuczHBzjW213BbcE + + + + + operator CArray& + 2conversion-0251 + + + + conv-operator-names.cpp + conv-operator-names.cpp + 28 + 5 + + + + + function + Wz8WnbsdYDNstS7zo3xjvsp7SHi + public + regular + 21Yh5PF5ewVmWeNR3NwSbcFHNTrQ + + + brief + + + text + Convert to a reference to a function template parameter. + + + + + + returns + + + text + The object converted to + + + code + + + text + CArray + + + + + + + + + + lvalue-reference + + + named + + + identifier + CArray + + + + + + + + conversion + + + + operator MyAlias + 2conversion-0252 + + + + conv-operator-names.cpp + conv-operator-names.cpp + 36 + 5 + + + + + function + X1r857ZAaiGe53FPYsSZA2cLu2A + public + regular + 21Yh5PF5ewVmWeNR3NwSbcFHNTrQ + + + brief + + + text + Convert through an alias. + + + + + + returns + + + text + An alias for a builtin. + + + + + + + + named + + + identifier + 3VVDSy7yZT495J3sEQdZCm7VwFpU + MyAlias + + + + + conversion + + + + operator Range + 2conversion-05 + + + + conv-operator-names.cpp + conv-operator-names.cpp + 32 + 5 + + + + conv-operator-names.cpp + conv-operator-names.cpp + 39 + 5 + + + + + overloads + 2BfAehCDBNckkTsVTfwiappi4aS8 + public + regular + 21Yh5PF5ewVmWeNR3NwSbcFHNTrQ + + + brief + + + text + Conversion operators + + + + + conversion + SBdHXNBiYNpbF4in7ivtCDTtidY axvfPKXMx2E2n6kATF3vWBZkdgS + + + named + + + identifier + Range + + + + + + + operator Range + 2conversion-01 + + + + conv-operator-names.cpp + conv-operator-names.cpp + 32 + 5 + + + + + function + SBdHXNBiYNpbF4in7ivtCDTtidY + public + regular + 21Yh5PF5ewVmWeNR3NwSbcFHNTrQ + + + brief + + + text + Convert to a function template parameter. + + + + + + returns + + + text + The object converted to + + + code + + + text + Range + + + + + + + + + + named + + + identifier + Range + + + + + + conversion + + + + + operator Range + 2conversion-02a + + + + conv-operator-names.cpp + conv-operator-names.cpp + 39 + 5 + + + + + function + axvfPKXMx2E2n6kATF3vWBZkdgS + public + regular + 21Yh5PF5ewVmWeNR3NwSbcFHNTrQ + + + brief + + + text + Convert through a constrained template with a defaulted parameter. + + + + + + returns + + + text + The object converted to + + + code + + + text + Range + + + + + + + + + + named + + + identifier + Range + + + + + + conversion + constexpr + + + + + operator T + 2conversion-00 + + + + conv-operator-names.cpp + conv-operator-names.cpp + 19 + 5 + + + + + function + 74Ttqv4qsiQE26MzTuCihvtSjzJ + public + regular + 21Yh5PF5ewVmWeNR3NwSbcFHNTrQ + + + brief + + + text + Convert to the class template parameter. + + + + + + returns + + + text + The object converted to + + + code + + + text + T + + + + + + + + + + named + + + identifier + T + + + + + conversion + + + + operator T& + 2conversion-08 + + + + conv-operator-names.cpp + conv-operator-names.cpp + 22 + 5 + + + + + function + 2v2EJK7VsLBqJ3p6mZrmi9QffkDM + public + regular + 21Yh5PF5ewVmWeNR3NwSbcFHNTrQ + + + brief + + + text + Convert to a reference to the class template parameter. + + + + + + returns + + + text + The object converted to + + + code + + + text + T + + + + + + + + + + lvalue-reference + + + named + + + identifier + T + + + + + + + conversion + + + + operator T::type + 2conversion-07 + + + + conv-operator-names.cpp + conv-operator-names.cpp + 25 + 5 + + + + + function + 2evy2c2rVeQCkuczHBzjW213BbcE + public + regular + 21Yh5PF5ewVmWeNR3NwSbcFHNTrQ + + + brief + + + text + Convert to a dependent type. + + + + + + returns + + + text + The object converted to + + + code + + + text + type + + + + + + + + + + named + + + identifier + type + + + identifier + T + + + + + + + conversion + + + + IsArray + IsArray + + + conv-operator-names.cpp + conv-operator-names.cpp + 7 + 1 + + + + record + 3qE7vj8ikuTMaJ3EwgcSEYoctGdA + regular + 4ZrjxJnU1LA5xSyrWMNuXTvSYKwt + + + brief + + + text + A trait stand-in for a constrained conversion. + + + + + struct + + + + 2oAft8pXGAX5XrRrPLNFiuLd38fm + + + + + value + value + + + conv-operator-names.cpp + conv-operator-names.cpp + 11 + 5 + + + + variable + 2oAft8pXGAX5XrRrPLNFiuLd38fm + public + regular + 3qE7vj8ikuTMaJ3EwgcSEYoctGdA + + + brief + + + text + Whether the type is an array. + + + + + + + named + + + identifier + bool + + + bool + + + false + static + + + + diff --git a/tests/golden/fixtures/symbols/record/conditional-explicit.xml b/tests/golden/fixtures/symbols/record/conditional-explicit.xml index 7c8b27c745..eba39e8865 100644 --- a/tests/golden/fixtures/symbols/record/conditional-explicit.xml +++ b/tests/golden/fixtures/symbols/record/conditional-explicit.xml @@ -411,7 +411,7 @@ - operator + operator U 2conversion-0f diff --git a/tests/golden/fixtures/symbols/using/using-member-conversion.xml b/tests/golden/fixtures/symbols/using/using-member-conversion.xml index 8ecb0cadd8..e8b07001dc 100644 --- a/tests/golden/fixtures/symbols/using/using-member-conversion.xml +++ b/tests/golden/fixtures/symbols/using/using-member-conversion.xml @@ -99,7 +99,7 @@ - operator void(*)() + operator fun_ptr 2conversion @@ -208,7 +208,7 @@ - operator void(*)() + operator fun_ptr 2conversion @@ -265,7 +265,7 @@ - operator void(*)() + operator fun_ptr 2conversion @@ -298,7 +298,7 @@ identifier - operator void(*)() + operator fun_ptr identifier @@ -311,7 +311,7 @@ 2P8vEavoPWWGcmU7e6hJUuaJQJcj - operator void(*)() + operator fun_ptr 2conversion