11 #include "clang/Lex/Lexer.h"
13 using namespace clang::ast_matchers;
19 const char MakeSmartPtrCheck::PointerType[] =
"pointerType";
20 const char MakeSmartPtrCheck::ConstructorCall[] =
"constructorCall";
21 const char MakeSmartPtrCheck::NewExpression[] =
"newExpression";
24 std::string makeSmartPtrFunctionName)
26 makeSmartPtrFunctionName(std::move(makeSmartPtrFunctionName)) {}
33 cxxBindTemporaryExpr(has(ignoringParenImpCasts(
37 cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType(
49 SourceManager &
SM = *Result.SourceManager;
50 const auto *Construct =
52 const auto *Type = Result.Nodes.getNodeAs<QualType>(
PointerType);
53 const auto *New = Result.Nodes.getNodeAs<CXXNewExpr>(
NewExpression);
55 if (New->getNumPlacementArgs() != 0)
58 SourceLocation ConstructCallStart = Construct->getExprLoc();
61 StringRef ExprStr = Lexer::getSourceText(
62 CharSourceRange::getCharRange(
63 ConstructCallStart, Construct->getParenOrBraceRange().getBegin()),
64 SM, LangOptions(), &Invalid);
68 auto Diag =
diag(ConstructCallStart,
"use %0 instead")
69 << makeSmartPtrFunctionName;
72 size_t LAngle = ExprStr.find(
"<");
73 SourceLocation ConstructCallEnd;
74 if (LAngle == StringRef::npos) {
77 ConstructCallEnd = ConstructCallStart.getLocWithOffset(ExprStr.size());
78 Diag << FixItHint::CreateInsertion(
79 ConstructCallEnd,
"<" + Type->getAsString(
getLangOpts()) +
">");
81 ConstructCallEnd = ConstructCallStart.getLocWithOffset(LAngle);
84 Diag << FixItHint::CreateReplacement(
85 CharSourceRange::getCharRange(ConstructCallStart, ConstructCallEnd),
86 makeSmartPtrFunctionName);
90 if (Construct->isListInitialization()) {
91 SourceRange BraceRange = Construct->getParenOrBraceRange();
92 Diag << FixItHint::CreateReplacement(
93 CharSourceRange::getCharRange(
94 BraceRange.getBegin(), BraceRange.getBegin().getLocWithOffset(1)),
96 Diag << FixItHint::CreateReplacement(
97 CharSourceRange::getCharRange(BraceRange.getEnd(),
98 BraceRange.getEnd().getLocWithOffset(1)),
102 SourceLocation NewStart = New->getSourceRange().getBegin();
103 SourceLocation NewEnd = New->getSourceRange().getEnd();
104 switch (New->getInitializationStyle()) {
105 case CXXNewExpr::NoInit: {
106 Diag << FixItHint::CreateRemoval(SourceRange(NewStart, NewEnd));
109 case CXXNewExpr::CallInit: {
110 SourceRange InitRange = New->getDirectInitRange();
111 Diag << FixItHint::CreateRemoval(
112 SourceRange(NewStart, InitRange.getBegin()));
113 Diag << FixItHint::CreateRemoval(SourceRange(InitRange.getEnd(), NewEnd));
116 case CXXNewExpr::ListInit: {
118 SourceRange InitRange;
119 if (
const auto *NewConstruct = New->getConstructExpr()) {
127 InitRange = SourceRange(
128 NewConstruct->getParenOrBraceRange().getBegin().getLocWithOffset(1),
129 NewConstruct->getParenOrBraceRange().getEnd().getLocWithOffset(-1));
135 InitRange = SourceRange(
136 New->getAllocatedTypeSourceInfo()->getTypeLoc().getLocStart(),
137 New->getInitializer()->getSourceRange().getEnd());
139 Diag << FixItHint::CreateRemoval(
140 CharSourceRange::getCharRange(NewStart, InitRange.getBegin()));
141 Diag << FixItHint::CreateRemoval(
142 SourceRange(InitRange.getEnd().getLocWithOffset(1), NewEnd));
LangOptions getLangOpts() const
Returns the language options from the context.
std::unique_ptr< ast_matchers::MatchFinder > Finder
void registerMatchers(ast_matchers::MatchFinder *Finder) final
Override this to register AST matchers with Finder.
Base class for all clang-tidy checks.
virtual SmartPtrTypeMatcher getSmartPointerTypeMatcher() const =0
Returns matcher that match with different smart pointer types.
static const char ConstructorCall[]
void check(const ast_matchers::MatchFinder::MatchResult &Result) final
ClangTidyChecks that register ASTMatchers should do the actual work in here.
static const char PointerType[]
ClangTidyContext & Context
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
static const char NewExpression[]
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.