#include "RedundantStringInitCheck.h"
#include "../utils/Matchers.h"
-#include "../utils/OptionsUtils.h"
#include "clang/ASTMatchers/ASTMatchers.h"
using namespace clang::ast_matchers;
namespace tidy {
namespace readability {
-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);
-}
-
void RedundantStringInitCheck::registerMatchers(MatchFinder *Finder) {
if (!getLangOpts().CPlusPlus)
return;
- 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()));
// Match string constructor.
- 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()))));
+ const auto StringConstructorExpr = expr(anyOf(
+ cxxConstructExpr(argumentCountIs(1),
+ hasDeclaration(cxxMethodDecl(hasName("basic_string")))),
+ // If present, the second argument is the alloc object which must not
+ // be present explicitly.
+ cxxConstructExpr(argumentCountIs(2),
+ hasDeclaration(cxxMethodDecl(hasName("basic_string"))),
+ hasArgument(1, cxxDefaultArgExpr()))));
// Match a string constructor expression with an empty string literal.
const auto EmptyStringCtorExpr = cxxConstructExpr(
namedDecl(
varDecl(
hasType(hasUnqualifiedDesugaredType(recordType(
- hasDeclaration(cxxRecordDecl(hasStringTypeName))))),
+ hasDeclaration(cxxRecordDecl(hasName("basic_string")))))),
hasInitializer(expr(ignoringImplicit(anyOf(
EmptyStringCtorExpr, EmptyStringCtorExprWithTemporaries)))))
.bind("vardecl"),
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_STRING_INIT_H
#include "../ClangTidyCheck.h"
-#include <string>
-#include <vector>
namespace clang {
namespace tidy {
/// Finds unnecessary string initializations.
class RedundantStringInitCheck : public ClangTidyCheck {
public:
- RedundantStringInitCheck(StringRef Name, ClangTidyContext *Context);
- void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+ RedundantStringInitCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
-
-private:
- std::vector<std::string> StringNames;
};
} // namespace readability
Finds non-static member functions that can be made ``const``
because the functions don't use ``this`` in a non-const way.
-- The :doc:`readability-redundant-string-init
- <clang-tidy/checks/readability-redundant-string-init>` check now supports a
- `StringNames` option enabling its application to custom string classes.
-
Improvements to include-fixer
-----------------------------
Finds unnecessary string initializations.
-Examples
---------
+Examples:
.. code-block:: c++
std::string a;
std::string b;
-
-Options
--------
-
-.. option:: StringNames
-
- Default is `::std::basic_string`.
-
- Semicolon-delimited list of class names to apply this check to.
- By default `::std::basic_string` applies to ``std::string`` and
- ``std::wstring``. Set to e.g. `::std::basic_string;llvm::StringRef;QString`
- to perform this check on custom classes.
-// RUN: %check_clang_tidy -std=c++11,c++14 %s readability-redundant-string-init %t \
-// RUN: -config="{CheckOptions: \
-// RUN: [{key: readability-redundant-string-init.StringNames, \
-// RUN: value: "::std::basic_string;our::TestString"}] \
-// RUN: }"
-// FIXME: Fix the checker to work in C++17 mode.
+// RUN: %check_clang_tidy %s readability-redundant-string-init %t
namespace std {
template <typename T>
void Param3(std::string param = "") {}
void Param4(STRING param = "") {}
-namespace our {
-struct TestString {
- TestString();
- TestString(const TestString &);
- TestString(const char *);
- ~TestString();
-};
-}
-
-void ourTestStringTests() {
- our::TestString a = "";
- // CHECK-MESSAGES: [[@LINE-1]]:19: warning: redundant string initialization
- // CHECK-FIXES: our::TestString a;
- our::TestString b("");
- // CHECK-MESSAGES: [[@LINE-1]]:19: warning: redundant string initialization
- // CHECK-FIXES: our::TestString b;
- our::TestString c = R"()";
- // CHECK-MESSAGES: [[@LINE-1]]:19: warning: redundant string initialization
- // CHECK-FIXES: our::TestString c;
- our::TestString d(R"()");
- // CHECK-MESSAGES: [[@LINE-1]]:19: warning: redundant string initialization
- // CHECK-FIXES: our::TestString d;
-
- our::TestString u = "u";
- our::TestString w("w");
- our::TestString x = R"(x)";
- our::TestString y(R"(y)");
- our::TestString z;
-}
-
-namespace their {
-using TestString = our::TestString;
-}
-
-// their::TestString is the same type so should warn / fix
-void theirTestStringTests() {
- their::TestString a = "";
- // CHECK-MESSAGES: [[@LINE-1]]:21: warning: redundant string initialization
- // CHECK-FIXES: their::TestString a;
- their::TestString b("");
- // CHECK-MESSAGES: [[@LINE-1]]:21: warning: redundant string initialization
- // CHECK-FIXES: their::TestString b;
-}
-
-namespace other {
-// Identical declarations to above but different type
-struct TestString {
- TestString();
- TestString(const TestString &);
- TestString(const char *);
- ~TestString();
-};
-
-// Identical declarations to above but different type
-template <typename T>
-class allocator {};
-template <typename T>
-class char_traits {};
-template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C>>
-struct basic_string {
- basic_string();
- basic_string(const basic_string &);
- basic_string(const C *, const A &a = A());
- ~basic_string();
-};
-typedef basic_string<char> string;
-typedef basic_string<wchar_t> wstring;
-}
-
-// other::TestString, other::string, other::wstring are unrelated to the types
-// being checked. No warnings / fixes should be produced for these types.
-void otherTestStringTests() {
- other::TestString a = "";
- other::TestString b("");
- other::string c = "";
- other::string d("");
- other::wstring e = L"";
- other::wstring f(L"");
-}