61 auto ForwardingRefParm =
63 hasType(qualType(rValueReferenceType(),
64 references(templateTypeParmType(hasDeclaration(
65 templateTypeParmDecl().bind(
"type-parm-decl")))),
66 unless(references(isConstQualified())))))
69 const DeclarationMatcher FindOverload =
71 hasParameter(0, ForwardingRefParm), unless(isDeleted()),
72 unless(hasAnyParameter(
74 parmVarDecl(hasType(isEnableIf())))),
75 unless(hasParent(functionTemplateDecl(anyOf(
78 hasAssociatedConstraints(),
80 has(templateTypeParmDecl(hasDefaultArgument(isEnableIf()))),
82 has(nonTypeTemplateParmDecl(
83 hasType(isEnableIf()),
84 anyOf(hasDescendant(cxxBoolLiteral()),
85 hasDescendant(cxxNullPtrLiteralExpr()),
86 hasDescendant(integerLiteral())))))))))
88 Finder->addMatcher(FindOverload,
this);
92 const MatchFinder::MatchResult &Result) {
93 const auto *ParmVar = Result.Nodes.getNodeAs<ParmVarDecl>(
"parm-var");
94 const auto *TypeParmDecl =
95 Result.Nodes.getNodeAs<TemplateTypeParmDecl>(
"type-parm-decl");
99 const auto *FuncForParam = dyn_cast<FunctionDecl>(ParmVar->getDeclContext());
102 const FunctionTemplateDecl *FuncTemplate =
103 FuncForParam->getDescribedFunctionTemplate();
110 const TemplateParameterList *Params = FuncTemplate->getTemplateParameters();
111 if (!llvm::is_contained(*Params, TypeParmDecl))
115 const auto *Ctor = Result.Nodes.getNodeAs<CXXConstructorDecl>(
"ctor");
116 for (
const auto *Param : llvm::drop_begin(Ctor->parameters()))
117 if (!Param->hasDefaultArg())
119 bool EnabledCopy =
false, DisabledCopy =
false, EnabledMove =
false,
120 DisabledMove =
false;
121 for (
const auto *OtherCtor : Ctor->getParent()->ctors()) {
122 if (OtherCtor->isCopyOrMoveConstructor()) {
123 if (OtherCtor->isDeleted() || OtherCtor->getAccess() == AS_private)
124 (OtherCtor->isCopyConstructor() ? DisabledCopy : DisabledMove) =
true;
126 (OtherCtor->isCopyConstructor() ? EnabledCopy : EnabledMove) =
true;
130 (!EnabledMove && !DisabledMove && !DisabledCopy) || EnabledCopy;
131 const bool Move = !DisabledMove || EnabledMove;
134 diag(Ctor->getLocation(),
135 "constructor accepting a forwarding reference can "
136 "hide the %select{copy|move|copy and move}0 constructor%s1")
137 << (Copy &&
Move ? 2 : (Copy ? 0 : 1)) << Copy +
Move;
138 for (
const auto *OtherCtor : Ctor->getParent()->ctors()) {
139 if (OtherCtor->isCopyOrMoveConstructor() && !OtherCtor->isDeleted() &&
140 OtherCtor->getAccess() != AS_private) {
141 diag(OtherCtor->getLocation(),
142 "%select{copy|move}0 constructor declared here", DiagnosticIDs::Note)
143 << OtherCtor->isMoveConstructor();