clang-tools  8.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(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
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//