11 #include "../utils/OptionsUtils.h"
12 using namespace clang::ast_matchers;
19 "::std::vector; ::std::list; ::std::deque";
21 "::std::shared_ptr; ::std::unique_ptr; ::std::auto_ptr; ::std::weak_ptr";
43 auto callPushBack = cxxMemberCallExpr(
44 hasDeclaration(functionDecl(hasName(
"push_back"))),
45 on(hasType(cxxRecordDecl(hasAnyName(SmallVector<StringRef, 5>(
46 ContainersWithPushBack.begin(), ContainersWithPushBack.end()))))));
52 auto isCtorOfSmartPtr = hasDeclaration(cxxConstructorDecl(ofClass(hasAnyName(
53 SmallVector<StringRef, 5>(SmartPointers.begin(), SmartPointers.end())))));
56 auto bitFieldAsArgument = hasAnyArgument(
57 ignoringImplicit(memberExpr(hasDeclaration(fieldDecl(isBitField())))));
60 auto initializerListAsArgument = hasAnyArgument(
61 ignoringImplicit(cxxConstructExpr(isListInitialization())));
64 auto newExprAsArgument = hasAnyArgument(ignoringImplicit(cxxNewExpr()));
66 auto constructingDerived =
67 hasParent(implicitCastExpr(hasCastKind(CastKind::CK_DerivedToBase)));
70 auto isPrivateCtor = hasDeclaration(cxxConstructorDecl(isPrivate()));
72 auto hasInitList = has(ignoringImplicit(initListExpr()));
75 auto soughtConstructExpr =
77 unless(anyOf(isCtorOfSmartPtr, hasInitList, bitFieldAsArgument,
78 initializerListAsArgument, newExprAsArgument,
79 constructingDerived, isPrivateCtor)))
81 auto hasConstructExpr = has(ignoringImplicit(soughtConstructExpr));
83 auto ctorAsArgument = materializeTemporaryExpr(
84 anyOf(hasConstructExpr, has(cxxFunctionalCastExpr(hasConstructExpr))));
86 Finder->addMatcher(cxxMemberCallExpr(callPushBack, has(ctorAsArgument),
87 unless(isInTemplateInstantiation()))
93 const auto *Call = Result.Nodes.getNodeAs<CXXMemberCallExpr>(
"call");
94 const auto *InnerCtorCall = Result.Nodes.getNodeAs<CXXConstructExpr>(
"ctor");
96 auto FunctionNameSourceRange = CharSourceRange::getCharRange(
97 Call->getExprLoc(), Call->getArg(0)->getExprLoc());
99 auto Diag =
diag(Call->getExprLoc(),
"use emplace_back instead of push_back");
101 if (FunctionNameSourceRange.getBegin().isMacroID())
104 Diag << FixItHint::CreateReplacement(FunctionNameSourceRange,
107 auto CallParensRange = InnerCtorCall->getParenOrBraceRange();
110 if (CallParensRange.getBegin().isInvalid())
114 auto CtorCallSourceRange = CharSourceRange::getTokenRange(
115 InnerCtorCall->getExprLoc(), CallParensRange.getBegin());
117 Diag << FixItHint::CreateRemoval(CtorCallSourceRange)
118 << FixItHint::CreateRemoval(CharSourceRange::getTokenRange(
119 CallParensRange.getEnd(), CallParensRange.getEnd()));
LangOptions getLangOpts() const
Returns the language options from the context.
std::string serializeStringList(ArrayRef< std::string > Strings)
Serialize a sequence of names that can be parsed by parseStringList.
void storeOptions(ClangTidyOptions::OptionMap &Opts) override
Should store all options supported by this check with their current values or default values for opti...
std::unique_ptr< ast_matchers::MatchFinder > Finder
Base class for all clang-tidy checks.
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
static const auto DefaultContainersWithPushBack
std::vector< std::string > parseStringList(StringRef Option)
Parse a semicolon separated list of strings.
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register AST matchers with Finder.
void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, StringRef Value) const
Stores an option with the check-local name LocalName with string value Value to Options.
std::map< std::string, std::string > OptionMap
ClangTidyContext & Context
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
static const auto DefaultSmartPointers