blob: ad6c2cdd4167712270e35bcd73c0c90211385c04 [file] [log] [blame]
Alexander Kornienko1612fa02016-02-25 23:57:23 +00001//===- 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
10#include "RedundantStringInitCheck.h"
11#include "clang/ASTMatchers/ASTMatchers.h"
12
13using namespace clang::ast_matchers;
14
15namespace clang {
16namespace tidy {
17namespace readability {
18
19namespace {
20
21AST_MATCHER(StringLiteral, lengthIsZero) { return Node.getLength() == 0; }
22
23} // namespace
24
25void RedundantStringInitCheck::registerMatchers(MatchFinder *Finder) {
26 if (!getLangOpts().CPlusPlus)
27 return;
28
29 const auto StringCtorExpr = cxxConstructExpr(
30 hasDeclaration(cxxMethodDecl(hasName("basic_string"))),
31 argumentCountIs(2),
32 hasArgument(0, ignoringParenImpCasts(stringLiteral(lengthIsZero()))),
33 hasArgument(1, cxxDefaultArgExpr()));
34
35 // string foo = "";
36 // OR
37 // string bar("");
38 Finder->addMatcher(
39 namedDecl(varDecl(hasType(cxxRecordDecl(hasName("basic_string"))),
40 hasInitializer(
41 expr(anyOf(StringCtorExpr,
42 exprWithCleanups(has(expr(anyOf(
43 StringCtorExpr,
44 cxxConstructExpr(hasArgument(
45 0, cxxBindTemporaryExpr(has(
46 StringCtorExpr))))))))))
47 .bind("expr"))))
48 .bind("decl"),
49 this);
50}
51
52void RedundantStringInitCheck::check(const MatchFinder::MatchResult &Result) {
53 const auto *CtorExpr = Result.Nodes.getNodeAs<Expr>("expr");
54 const auto *Decl = Result.Nodes.getNodeAs<NamedDecl>("decl");
55 diag(CtorExpr->getExprLoc(), "redundant string initialization")
56 << FixItHint::CreateReplacement(CtorExpr->getSourceRange(),
57 Decl->getName());
58}
59
60} // namespace readability
61} // namespace tidy
62} // namespace clang