59 Result.Nodes.getNodeAs<ClassTemplateSpecializationDecl>(ID);
62 auto DeleterArgument = Class->getTemplateArgs()[1];
63 if (DeleterArgument.getKind() != TemplateArgument::Type)
65 return DeleterArgument.getAsType().getTypePtr();
72 if (LeftDeleterType->getUnqualifiedDesugaredType() ==
73 RightDeleterType->getUnqualifiedDesugaredType()) {
79 const CXXRecordDecl *LeftDeleter = LeftDeleterType->getAsCXXRecordDecl();
80 const CXXRecordDecl *RightDeleter = RightDeleterType->getAsCXXRecordDecl();
81 if (!LeftDeleter || !RightDeleter)
84 if (LeftDeleter->getCanonicalDecl() == RightDeleter->getCanonicalDecl()) {
89 const auto *LeftAsTemplate =
90 dyn_cast<ClassTemplateSpecializationDecl>(LeftDeleter);
91 const auto *RightAsTemplate =
92 dyn_cast<ClassTemplateSpecializationDecl>(RightDeleter);
93 if (LeftAsTemplate && RightAsTemplate &&
94 LeftAsTemplate->getSpecializedTemplate() ==
95 RightAsTemplate->getSpecializedTemplate()) {
109 const auto *ResetMember = Result.Nodes.getNodeAs<MemberExpr>(
"reset_member");
110 const auto *ReleaseMember =
111 Result.Nodes.getNodeAs<MemberExpr>(
"release_member");
112 const auto *Right = Result.Nodes.getNodeAs<Expr>(
"right");
113 const auto *ResetCall =
114 Result.Nodes.getNodeAs<CXXMemberCallExpr>(
"reset_call");
116 StringRef AssignmentText =
" = ";
117 StringRef TrailingText =
"";
118 bool NeedsUtilityInclude =
false;
119 if (ReleaseMember->isArrow()) {
120 AssignmentText =
" = std::move(*";
122 NeedsUtilityInclude =
true;
123 }
else if (!Right->isPRValue()) {
124 AssignmentText =
" = std::move(";
126 NeedsUtilityInclude =
true;
129 auto D = diag(ResetMember->getExprLoc(),
130 "prefer 'unique_ptr<>' assignment over 'release' and 'reset'");
131 if (ResetMember->isArrow())
132 D << FixItHint::CreateInsertion(ResetMember->getBeginLoc(),
"*");
133 D << FixItHint::CreateReplacement(
134 CharSourceRange::getCharRange(ResetMember->getOperatorLoc(),
135 Right->getBeginLoc()),
137 << FixItHint::CreateReplacement(
138 CharSourceRange::getTokenRange(ReleaseMember->getOperatorLoc(),
139 ResetCall->getEndLoc()),
141 if (NeedsUtilityInclude)
142 D << Inserter.createIncludeInsertion(
143 Result.SourceManager->getFileID(ResetMember->getBeginLoc()),
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.