clang-tools 6.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
10 #include "RedundantStringInitCheck.h"
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(hasUnqualifiedDesugaredType(recordType(
51 hasDeclaration(cxxRecordDecl(hasName("basic_string")))))),
52 hasInitializer(expr(ignoringImplicit(anyOf(
53 EmptyStringCtorExpr,
54 EmptyStringCtorExprWithTemporaries)))
55 .bind("expr"))),
56 unless(parmVarDecl()))
57 .bind("decl"),
58 this);
59 }
60
61 void RedundantStringInitCheck::check(const MatchFinder::MatchResult &Result) {
62 const auto *CtorExpr = Result.Nodes.getNodeAs<Expr>("expr");
63 const auto *Decl = Result.Nodes.getNodeAs<NamedDecl>("decl");
64 diag(CtorExpr->getExprLoc(), "redundant string initialization")
65 << FixItHint::CreateReplacement(CtorExpr->getSourceRange(),
66 Decl->getName());
67 }
68
69 } // namespace readability
70 } // namespace tidy
71 } // namespace clang
clang::ast_matchers
Definition: ClangTidyDiagnosticConsumer.h:27
clang::tidy::matchers
Definition: Matchers.h:18
clang
Definition: AndroidTidyModule.cpp:28
RedundantStringInitCheck.h