================
@@ -0,0 +1,152 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "StringViewConversionsCheck.h"
+#include "clang/AST/Expr.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::performance {
+
+static auto getStringTypeMatcher(StringRef CharType) {
+  return hasCanonicalType(hasDeclaration(cxxRecordDecl(hasName(CharType))));
+}
+
+void StringViewConversionsCheck::registerMatchers(MatchFinder *Finder) {
+  // Matchers for std::basic_[w|u8|u16|u32]string and
+  // std::basic_[w|u8|u16|u32]string_view families.
+  const auto IsStdString = getStringTypeMatcher("::std::basic_string");
+  const auto IsStdStringView = 
getStringTypeMatcher("::std::basic_string_view");
+
+  // Matches pointer to any character type (char*, const char*, wchar_t*, etc.)
+  // or array of any character type (char[], char[N], const char[N], etc.).
+  const auto IsCharPointerOrArray =
+      anyOf(hasType(pointerType(pointee(isAnyCharacter()))),
+            hasType(arrayType(hasElementType(isAnyCharacter()))));
+
+  // Matches expressions that can be implicitly converted to string_view
+  // without going through std::string:
+  //   - string_view itself (no conversion needed)
+  //   - string literals ("hello", L"wide", u8"utf8", etc.)
+  //   - character pointers (const char*, char*)
+  //   - character arrays (char arr[], char arr[N])
+  // These are the expressions we want to preserve after removing
+  // the redundant std::string conversion.
+  const auto ImplicitlyConvertibleToStringView =
+      expr(anyOf(hasType(IsStdStringView), stringLiteral(),
+                 IsCharPointerOrArray))
+          .bind("originalStringView");
+
+  // Matches direct std::string construction from a string_view-convertible
+  // expression. This handles cases like:
+  //   - Implicit construction in certain contexts
+  //   - Brace initialization: std::string{sv}
+  // Excludes copy/move constructors to avoid false positives when
+  // an existing std::string is being copied or moved.
+  const auto RedundantStringConstruction = cxxConstructExpr(
+      hasType(IsStdString),
+      hasArgument(0, ignoringImplicit(ImplicitlyConvertibleToStringView)),
+      unless(hasDeclaration(cxxConstructorDecl(isCopyConstructor()))),
+      unless(hasDeclaration(cxxConstructorDecl(isMoveConstructor()))));
----------------
localspook wrote:

If a `std::string` is being copy or move constructed, that means its first 
argument has type `std::string`, which wouldn't be matched by 
`ImplicitlyConvertibleToStringView` anyway, so is explicitly excluding copy and 
move constructors needed?
```suggestion
  const auto RedundantStringConstruction = cxxConstructExpr(
      hasType(IsStdString),
      hasArgument(0, ignoringImplicit(ImplicitlyConvertibleToStringView)));
```

https://github.com/llvm/llvm-project/pull/174288
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to