10 #include "clang/AST/ASTContext.h" 11 #include "clang/ASTMatchers/ASTMatchFinder.h" 17 namespace performance {
19 void InefficientStringConcatenationCheck::storeOptions(
21 Options.store(Opts,
"StrictMode", StrictMode);
24 InefficientStringConcatenationCheck::InefficientStringConcatenationCheck(
27 StrictMode(Options.getLocalOrGlobal(
"StrictMode", 0)) {}
30 MatchFinder *Finder) {
34 const auto BasicStringType =
35 hasType(qualType(hasUnqualifiedDesugaredType(recordType(
36 hasDeclaration(cxxRecordDecl(hasName(
"::std::basic_string")))))));
38 const auto BasicStringPlusOperator = cxxOperatorCallExpr(
39 hasOverloadedOperatorName(
"+"),
40 hasAnyArgument(ignoringImpCasts(declRefExpr(BasicStringType))));
42 const auto PlusOperator =
44 hasOverloadedOperatorName(
"+"),
45 hasAnyArgument(ignoringImpCasts(declRefExpr(BasicStringType))),
46 hasDescendant(BasicStringPlusOperator))
47 .bind(
"plusOperator");
49 const auto AssignOperator = cxxOperatorCallExpr(
50 hasOverloadedOperatorName(
"="),
51 hasArgument(0, declRefExpr(BasicStringType,
52 hasDeclaration(decl().bind(
"lhsStrT")))
54 hasArgument(1, stmt(hasDescendant(declRefExpr(
55 hasDeclaration(decl(equalsBoundNode(
"lhsStrT"))))))),
56 hasDescendant(BasicStringPlusOperator));
59 Finder->addMatcher(cxxOperatorCallExpr(anyOf(AssignOperator, PlusOperator)),
63 cxxOperatorCallExpr(anyOf(AssignOperator, PlusOperator),
64 hasAncestor(stmt(anyOf(cxxForRangeStmt(),
65 whileStmt(), forStmt())))),
71 const MatchFinder::MatchResult &
Result) {
72 const auto *LhsStr = Result.Nodes.getNodeAs<DeclRefExpr>(
"lhsStr");
73 const auto *PlusOperator =
74 Result.Nodes.getNodeAs<CXXOperatorCallExpr>(
"plusOperator");
76 "string concatenation results in allocation of unnecessary temporary " 77 "strings; consider using 'operator+=' or 'string::append()' instead";
80 diag(LhsStr->getExprLoc(), DiagMsg);
81 else if (PlusOperator)
82 diag(PlusOperator->getExprLoc(), DiagMsg);
Base class for all clang-tidy checks.
const LangOptions & getLangOpts() const
Returns the language options from the context.
static constexpr llvm::StringLiteral Name
std::map< std::string, std::string > OptionMap
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.