clang-tools  9.0.0
RedundantStringInitCheck.cpp
Go to the documentation of this file.
1 //===- RedundantStringInitCheck.cpp - clang-tidy ----------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "../utils/Matchers.h"
11 #include "clang/ASTMatchers/ASTMatchers.h"
12 
13 using namespace clang::ast_matchers;
14 using namespace clang::tidy::matchers;
15 
16 namespace clang {
17 namespace tidy {
18 namespace readability {
19 
20 void RedundantStringInitCheck::registerMatchers(MatchFinder *Finder) {
21  if (!getLangOpts().CPlusPlus)
22  return;
23 
24  // Match string constructor.
25  const auto StringConstructorExpr = expr(anyOf(
26  cxxConstructExpr(argumentCountIs(1),
27  hasDeclaration(cxxMethodDecl(hasName("basic_string")))),
28  // If present, the second argument is the alloc object which must not
29  // be present explicitly.
30  cxxConstructExpr(argumentCountIs(2),
31  hasDeclaration(cxxMethodDecl(hasName("basic_string"))),
32  hasArgument(1, cxxDefaultArgExpr()))));
33 
34  // Match a string constructor expression with an empty string literal.
35  const auto EmptyStringCtorExpr = cxxConstructExpr(
36  StringConstructorExpr,
37  hasArgument(0, ignoringParenImpCasts(stringLiteral(hasSize(0)))));
38 
39  const auto EmptyStringCtorExprWithTemporaries =
40  cxxConstructExpr(StringConstructorExpr,
41  hasArgument(0, ignoringImplicit(EmptyStringCtorExpr)));
42 
43  // Match a variable declaration with an empty string literal as initializer.
44  // Examples:
45  // string foo = "";
46  // string bar("");
47  Finder->addMatcher(
48  namedDecl(
49  varDecl(hasType(hasUnqualifiedDesugaredType(recordType(
50  hasDeclaration(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
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
Definition: Rename.cpp:36