2016-02-26 07:57:23 +08:00
|
|
|
//===- RedundantStringInitCheck.cpp - clang-tidy ----------------*- C++ -*-===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2016-02-26 07:57:23 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "RedundantStringInitCheck.h"
|
2016-05-18 03:36:09 +08:00
|
|
|
#include "../utils/Matchers.h"
|
[clang-tidy] Give readability-redundant-string-init a customizable list of string types to fix
Summary:
This patch adds a feature requested in https://reviews.llvm.org/D69238 to enable `readability-redundant-string-init` to take a list of strings to apply the fix to rather than hard-coding `basic_string`. It adds a `StringNames` option of semicolon-delimited names of string classes to which to apply this fix. Tests ensure this works with test class out::TestString as well as std::string and std::wstring as before. It should be applicable to llvm::StringRef, QString, etc.
Note: This commit was previously reverted due to a failing unit test. That test has been fixed in this version.
Reviewers: MyDeveloperDay, aaron.ballman, hokein, alexfh, JonasToth, gribozavr2
Patch by: poelmanc
Subscribers: gribozavr2, xazax.hun, Eugene.Zelenko, cfe-commits
Tags: #clang-tools-extra, #clang
Differential Revision: https://reviews.llvm.org/D69548
2019-11-16 07:09:27 +08:00
|
|
|
#include "../utils/OptionsUtils.h"
|
2016-02-26 07:57:23 +08:00
|
|
|
#include "clang/ASTMatchers/ASTMatchers.h"
|
|
|
|
|
|
|
|
using namespace clang::ast_matchers;
|
2016-05-18 03:36:09 +08:00
|
|
|
using namespace clang::tidy::matchers;
|
2016-02-26 07:57:23 +08:00
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
namespace tidy {
|
|
|
|
namespace readability {
|
|
|
|
|
[clang-tidy] Give readability-redundant-string-init a customizable list of string types to fix
Summary:
This patch adds a feature requested in https://reviews.llvm.org/D69238 to enable `readability-redundant-string-init` to take a list of strings to apply the fix to rather than hard-coding `basic_string`. It adds a `StringNames` option of semicolon-delimited names of string classes to which to apply this fix. Tests ensure this works with test class out::TestString as well as std::string and std::wstring as before. It should be applicable to llvm::StringRef, QString, etc.
Note: This commit was previously reverted due to a failing unit test. That test has been fixed in this version.
Reviewers: MyDeveloperDay, aaron.ballman, hokein, alexfh, JonasToth, gribozavr2
Patch by: poelmanc
Subscribers: gribozavr2, xazax.hun, Eugene.Zelenko, cfe-commits
Tags: #clang-tools-extra, #clang
Differential Revision: https://reviews.llvm.org/D69548
2019-11-16 07:09:27 +08:00
|
|
|
const char DefaultStringNames[] = "::std::basic_string";
|
|
|
|
|
|
|
|
RedundantStringInitCheck::RedundantStringInitCheck(StringRef Name,
|
|
|
|
ClangTidyContext *Context)
|
|
|
|
: ClangTidyCheck(Name, Context),
|
|
|
|
StringNames(utils::options::parseStringList(
|
|
|
|
Options.get("StringNames", DefaultStringNames))) {}
|
|
|
|
|
|
|
|
void RedundantStringInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
|
|
|
|
Options.store(Opts, "StringNames", DefaultStringNames);
|
|
|
|
}
|
|
|
|
|
2016-02-26 07:57:23 +08:00
|
|
|
void RedundantStringInitCheck::registerMatchers(MatchFinder *Finder) {
|
|
|
|
if (!getLangOpts().CPlusPlus)
|
|
|
|
return;
|
[clang-tidy] Give readability-redundant-string-init a customizable list of string types to fix
Summary:
This patch adds a feature requested in https://reviews.llvm.org/D69238 to enable `readability-redundant-string-init` to take a list of strings to apply the fix to rather than hard-coding `basic_string`. It adds a `StringNames` option of semicolon-delimited names of string classes to which to apply this fix. Tests ensure this works with test class out::TestString as well as std::string and std::wstring as before. It should be applicable to llvm::StringRef, QString, etc.
Note: This commit was previously reverted due to a failing unit test. That test has been fixed in this version.
Reviewers: MyDeveloperDay, aaron.ballman, hokein, alexfh, JonasToth, gribozavr2
Patch by: poelmanc
Subscribers: gribozavr2, xazax.hun, Eugene.Zelenko, cfe-commits
Tags: #clang-tools-extra, #clang
Differential Revision: https://reviews.llvm.org/D69548
2019-11-16 07:09:27 +08:00
|
|
|
const auto hasStringTypeName = hasAnyName(
|
|
|
|
SmallVector<StringRef, 3>(StringNames.begin(), StringNames.end()));
|
|
|
|
|
|
|
|
// Version of StringNames with namespaces removed
|
|
|
|
std::vector<std::string> stringNamesNoNamespace;
|
|
|
|
for (const std::string &name : StringNames) {
|
|
|
|
std::string::size_type colonPos = name.rfind(':');
|
|
|
|
stringNamesNoNamespace.push_back(
|
|
|
|
name.substr(colonPos == std::string::npos ? 0 : colonPos + 1));
|
|
|
|
}
|
|
|
|
const auto hasStringCtorName = hasAnyName(SmallVector<StringRef, 3>(
|
|
|
|
stringNamesNoNamespace.begin(), stringNamesNoNamespace.end()));
|
2016-02-26 07:57:23 +08:00
|
|
|
|
2016-03-23 01:39:36 +08:00
|
|
|
// Match string constructor.
|
[clang-tidy] Give readability-redundant-string-init a customizable list of string types to fix
Summary:
This patch adds a feature requested in https://reviews.llvm.org/D69238 to enable `readability-redundant-string-init` to take a list of strings to apply the fix to rather than hard-coding `basic_string`. It adds a `StringNames` option of semicolon-delimited names of string classes to which to apply this fix. Tests ensure this works with test class out::TestString as well as std::string and std::wstring as before. It should be applicable to llvm::StringRef, QString, etc.
Note: This commit was previously reverted due to a failing unit test. That test has been fixed in this version.
Reviewers: MyDeveloperDay, aaron.ballman, hokein, alexfh, JonasToth, gribozavr2
Patch by: poelmanc
Subscribers: gribozavr2, xazax.hun, Eugene.Zelenko, cfe-commits
Tags: #clang-tools-extra, #clang
Differential Revision: https://reviews.llvm.org/D69548
2019-11-16 07:09:27 +08:00
|
|
|
const auto StringConstructorExpr = expr(
|
|
|
|
anyOf(cxxConstructExpr(argumentCountIs(1),
|
|
|
|
hasDeclaration(cxxMethodDecl(hasStringCtorName))),
|
|
|
|
// If present, the second argument is the alloc object which must
|
|
|
|
// not be present explicitly.
|
|
|
|
cxxConstructExpr(argumentCountIs(2),
|
|
|
|
hasDeclaration(cxxMethodDecl(hasStringCtorName)),
|
|
|
|
hasArgument(1, cxxDefaultArgExpr()))));
|
2016-03-23 01:39:36 +08:00
|
|
|
|
|
|
|
// Match a string constructor expression with an empty string literal.
|
2016-11-08 15:50:19 +08:00
|
|
|
const auto EmptyStringCtorExpr = cxxConstructExpr(
|
|
|
|
StringConstructorExpr,
|
|
|
|
hasArgument(0, ignoringParenImpCasts(stringLiteral(hasSize(0)))));
|
2016-03-23 01:39:36 +08:00
|
|
|
|
|
|
|
const auto EmptyStringCtorExprWithTemporaries =
|
2016-06-22 04:11:20 +08:00
|
|
|
cxxConstructExpr(StringConstructorExpr,
|
|
|
|
hasArgument(0, ignoringImplicit(EmptyStringCtorExpr)));
|
2016-02-26 07:57:23 +08:00
|
|
|
|
2016-03-23 01:39:36 +08:00
|
|
|
// Match a variable declaration with an empty string literal as initializer.
|
|
|
|
// Examples:
|
|
|
|
// string foo = "";
|
|
|
|
// string bar("");
|
2016-02-26 07:57:23 +08:00
|
|
|
Finder->addMatcher(
|
2016-06-22 04:11:20 +08:00
|
|
|
namedDecl(
|
2019-11-16 05:13:48 +08:00
|
|
|
varDecl(
|
|
|
|
hasType(hasUnqualifiedDesugaredType(recordType(
|
[clang-tidy] Fix readability-redundant-string-init for c++17/c++2a
Summary:
`readability-redundant-string-init` was one of several clang-tidy checks documented as failing for C++17. (The failure mode in C++17 is that it changes `std::string Name = ""`; to `std::string Name = Name;`, which actually compiles but crashes at run-time.)
Analyzing the AST with `clang -Xclang -ast-dump` showed that the outer `CXXConstructExprs` that previously held the correct SourceRange were being elided in C++17/2a, but the containing `VarDecl` expressions still had all the relevant information. So this patch changes the fix to get its source ranges from `VarDecl`.
It adds one test `std::string g = "u", h = "", i = "uuu", j = "", k;` to confirm proper warnings and fixit replacements in a single `DeclStmt` where some strings require replacement and others don't. The readability-redundant-string-init.cpp and readability-redundant-string-init-msvc.cpp tests now pass for C++11/14/17/2a.
Reviewers: gribozavr, etienneb, alexfh, hokein, aaron.ballman, gribozavr2
Patch by: poelmanc
Subscribers: NoQ, MyDeveloperDay, Eugene.Zelenko, dylanmckay, cfe-commits
Tags: #clang, #clang-tools-extra
Differential Revision: https://reviews.llvm.org/D69238
2019-11-19 20:45:53 +08:00
|
|
|
hasDeclaration(cxxRecordDecl(hasStringTypeName))))),
|
2019-11-16 05:13:48 +08:00
|
|
|
hasInitializer(expr(ignoringImplicit(anyOf(
|
|
|
|
EmptyStringCtorExpr, EmptyStringCtorExprWithTemporaries)))))
|
|
|
|
.bind("vardecl"),
|
|
|
|
unless(parmVarDecl())),
|
2016-02-26 07:57:23 +08:00
|
|
|
this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RedundantStringInitCheck::check(const MatchFinder::MatchResult &Result) {
|
[clang-tidy] Fix readability-redundant-string-init for c++17/c++2a
Summary:
`readability-redundant-string-init` was one of several clang-tidy checks documented as failing for C++17. (The failure mode in C++17 is that it changes `std::string Name = ""`; to `std::string Name = Name;`, which actually compiles but crashes at run-time.)
Analyzing the AST with `clang -Xclang -ast-dump` showed that the outer `CXXConstructExprs` that previously held the correct SourceRange were being elided in C++17/2a, but the containing `VarDecl` expressions still had all the relevant information. So this patch changes the fix to get its source ranges from `VarDecl`.
It adds one test `std::string g = "u", h = "", i = "uuu", j = "", k;` to confirm proper warnings and fixit replacements in a single `DeclStmt` where some strings require replacement and others don't. The readability-redundant-string-init.cpp and readability-redundant-string-init-msvc.cpp tests now pass for C++11/14/17/2a.
Reviewers: gribozavr, etienneb, alexfh, hokein, aaron.ballman, gribozavr2
Patch by: poelmanc
Subscribers: NoQ, MyDeveloperDay, Eugene.Zelenko, dylanmckay, cfe-commits
Tags: #clang, #clang-tools-extra
Differential Revision: https://reviews.llvm.org/D69238
2019-11-19 20:45:53 +08:00
|
|
|
const auto *VDecl = Result.Nodes.getNodeAs<VarDecl>("vardecl");
|
|
|
|
// VarDecl's getSourceRange() spans 'string foo = ""' or 'string bar("")'.
|
|
|
|
// So start at getLocation() to span just 'foo = ""' or 'bar("")'.
|
|
|
|
SourceRange ReplaceRange(VDecl->getLocation(), VDecl->getEndLoc());
|
|
|
|
diag(VDecl->getLocation(), "redundant string initialization")
|
|
|
|
<< FixItHint::CreateReplacement(ReplaceRange, VDecl->getName());
|
2016-02-26 07:57:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace readability
|
|
|
|
} // namespace tidy
|
|
|
|
} // namespace clang
|