clang-tools  4.0.0
RedundantStringInitCheck.cpp
Go to the documentation of this file.
1 //===- RedundantStringInitCheck.cpp - clang-tidy ----------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
11 #include "../utils/Matchers.h"
12 #include "clang/ASTMatchers/ASTMatchers.h"
13 
14 using namespace clang::ast_matchers;
15 using namespace clang::tidy::matchers;
16 
17 namespace clang {
18 namespace tidy {
19 namespace readability {
20 
21 void RedundantStringInitCheck::registerMatchers(MatchFinder *Finder) {
22  if (!getLangOpts().CPlusPlus)
23  return;
24 
25  // Match string constructor.
26  const auto StringConstructorExpr = expr(anyOf(
27  cxxConstructExpr(argumentCountIs(1),
28  hasDeclaration(cxxMethodDecl(hasName("basic_string")))),
29  // If present, the second argument is the alloc object which must not
30  // be present explicitly.
31  cxxConstructExpr(argumentCountIs(2),
32  hasDeclaration(cxxMethodDecl(hasName("basic_string"))),
33  hasArgument(1, cxxDefaultArgExpr()))));
34 
35  // Match a string constructor expression with an empty string literal.
36  const auto EmptyStringCtorExpr = cxxConstructExpr(
37  StringConstructorExpr,
38  hasArgument(0, ignoringParenImpCasts(stringLiteral(hasSize(0)))));
39 
40  const auto EmptyStringCtorExprWithTemporaries =
41  cxxConstructExpr(StringConstructorExpr,
42  hasArgument(0, ignoringImplicit(EmptyStringCtorExpr)));
43 
44  // Match a variable declaration with an empty string literal as initializer.
45  // Examples:
46  // string foo = "";
47  // string bar("");
48  Finder->addMatcher(
49  namedDecl(
50  varDecl(hasType(cxxRecordDecl(hasName("basic_string"))),
51  hasInitializer(expr(ignoringImplicit(anyOf(
52  EmptyStringCtorExpr,
53  EmptyStringCtorExprWithTemporaries)))
54  .bind("expr"))),
55  unless(parmVarDecl()))
56  .bind("decl"),
57  this);
58 }
59 
60 void RedundantStringInitCheck::check(const MatchFinder::MatchResult &Result) {
61  const auto *CtorExpr = Result.Nodes.getNodeAs<Expr>("expr");
62  const auto *Decl = Result.Nodes.getNodeAs<NamedDecl>("decl");
63  diag(CtorExpr->getExprLoc(), "redundant string initialization")
64  << FixItHint::CreateReplacement(CtorExpr->getSourceRange(),
65  Decl->getName());
66 }
67 
68 } // namespace readability
69 } // namespace tidy
70 } // namespace clang
std::unique_ptr< ast_matchers::MatchFinder > Finder
Definition: ClangTidy.cpp:262
const NamedDecl * Result
Definition: USRFinder.cpp:162