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
45 changes: 44 additions & 1 deletion src/mrdocs/AST/ASTVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<clang::UsingShadowDecl>(target))
{
target = USD->getTargetDecl();
}
else if (clang::UsingDecl const* UD = dyn_cast<clang::UsingDecl>(target);
UD && UD->shadow_size() != 0)
{
target = (*UD->shadow_begin())->getTargetDecl();
}
if (clang::FunctionTemplateDecl const* FTD =
dyn_cast<clang::FunctionTemplateDecl>(target))
{
target = FTD->getTemplatedDecl();
}
return dyn_cast<clang::CXXConversionDecl>(target);
}

} // unnamed namespace

void
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions src/mrdocs/AST/ASTVisitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
46 changes: 46 additions & 0 deletions tests/golden/fixtures/symbols/function/conv-operator-names.cpp
Original file line number Diff line number Diff line change
@@ -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 <typename T>
struct IsArray
{
/// Whether the type is an array.
static constexpr bool value = false;
};

/// A class template with conversion functions.
template <typename T>
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 <class CArray>
explicit operator CArray&();

/// Convert to a function template parameter.
template <class Range>
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<Range>::value)
constexpr
explicit
operator Range() const;
};
Loading
Loading