Repository: llvm/llvm-project
File: clang-tools-extra/clang-tidy/performance/UseStdMoveCheck.cpp (C++)

Code before:
//
//===----------------------------------------------------------------------===//

#include "UseStdMoveCheck.h"

#include "../utils/DeclRefExprUtils.h"

#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/STLExtras.h"

using namespace clang::ast_matchers;

namespace clang::tidy::performance {

namespace {
AST_MATCHER(CXXRecordDecl, hasTrivialMoveAssignment) {
  return Node.hasTrivialMoveAssignment();
}

AST_MATCHER(VarDecl, isMovableAndProfitable) {
  const QualType NodeQual = Node.getType();

  // Not profitable.
  if (NodeQual->isScalarType())
    return false;

  // Not valid.
  if (NodeQual->isLValueReferenceType() || NodeQual.isConstQualified())
    return false;

  return true;
}

// Ignore nodes inside macros.
AST_POLYMORPHIC_MATCHER(isInMacro,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(Stmt, Decl)) {
  return Node.getBeginLoc().isMacroID() || Node.getEndLoc().isMacroID();
}
} // namespace

using utils::decl_ref_expr::allDeclRefExprs;

void UseStdMoveCheck::registerMatchers(MatchFinder *Finder) {
  auto AssignOperatorExpr =
      cxxOperatorCallExpr(
          hasOperatorName("="),
          hasArgument(

Review comment (suggestion):
We should be able to do something like:

```cpp
AST_MATCHER(QualType, isScalarType) {
  return Node.isScalarType();
}
AST_MATCHER(QualType, isLValueReferenceType) {
  return Node.isLValueReferenceType();
}

// registerMatchers

varDecl(hasLocalStorage(),
  hasType(qualType(
    unless(anyOf(
      isScalarType(), // Not profitable.
      isLValueReferenceType(), isConstQualified()
    ))  
  )))
```

Eventually we should transfer all custom `AST_MATCHER` to main library as building blocks. (But it's out of scope for this PR ofc)

Code after:
//
//===----------------------------------------------------------------------===//

#include "UseStdMoveCheck.h"

#include "../utils/DeclRefExprUtils.h"

#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/STLExtras.h"

using namespace clang::ast_matchers;

namespace clang::tidy::performance {

namespace {
AST_MATCHER(CXXRecordDecl, hasNonTrivialMoveAssignment) {
  return Node.hasNonTrivialMoveAssignment();
}

AST_MATCHER(QualType, isLValueReferenceType) {
  return Node->isLValueReferenceType();
}

AST_MATCHER(DeclRefExpr, refersToEnclosingVariableOrCapture) {
  return Node.refersToEnclosingVariableOrCapture();
}

AST_MATCHER(CXXOperatorCallExpr, isCopyAssignmentOperator) {
  if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(Node.getDirectCallee()))
    return MD->isCopyAssignmentOperator();
  return false;
}

// Ignore nodes inside macros.
AST_POLYMORPHIC_MATCHER(isInMacro,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(Stmt, Decl)) {
  return Node.getBeginLoc().isMacroID() || Node.getEndLoc().isMacroID();
}
} // namespace

using utils::decl_ref_expr::allDeclRefExprs;

void UseStdMoveCheck::registerMatchers(MatchFinder *Finder) {
  auto AssignOperatorExpr =
      cxxOperatorCallExpr(
          isCopyAssignmentOperator(),
          hasArgument(0, hasType(cxxRecordDecl(hasNonTrivialMoveAssignment()))),