//===--- PassByValueCheck.cpp - clang-tidy---------------------------------===// // // 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 "PassByValueCheck.h" #include "clang/AST/ASTContext.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/Preprocessor.h" usingnamespaceclang::ast_matchers; usingnamespacellvm; namespace clang::tidy::modernize { namespace { /// Matches move-constructible classes. /// /// Given /// \code /// // POD types are trivially move constructible. /// struct Foo { int a; }; /// /// struct Bar { /// Bar(Bar &&) = deleted; /// int a; /// }; /// \endcode /// recordDecl(isMoveConstructible()) /// matches "Foo". AST_MATCHER(CXXRecordDecl, isMoveConstructible) { … } } // namespace static TypeMatcher notTemplateSpecConstRefType() { … } static TypeMatcher nonConstValueType() { … } /// Whether or not \p ParamDecl is used exactly one time in \p Ctor. /// /// Checks both in the init-list and the body of the constructor. static bool paramReferredExactlyOnce(const CXXConstructorDecl *Ctor, const ParmVarDecl *ParamDecl) { … } /// Returns true if the given constructor is part of a lvalue/rvalue reference /// pair, i.e. `Param` is of lvalue reference type, and there exists another /// constructor such that: /// - it has the same number of parameters as `Ctor`. /// - the parameter at the same index as `Param` is an rvalue reference /// of the same pointee type /// - all other parameters have the same type as the corresponding parameter in /// `Ctor` or are rvalue references with the same pointee type. /// Examples: /// A::A(const B& Param) /// A::A(B&&) /// /// A::A(const B& Param, const C&) /// A::A(B&& Param, C&&) /// /// A::A(const B&, const C& Param) /// A::A(B&&, C&& Param) /// /// A::A(const B&, const C& Param) /// A::A(const B&, C&& Param) /// /// A::A(const B& Param, int) /// A::A(B&& Param, int) static bool hasRValueOverload(const CXXConstructorDecl *Ctor, const ParmVarDecl *Param) { … } /// Find all references to \p ParamDecl across all of the /// redeclarations of \p Ctor. static SmallVector<const ParmVarDecl *, 2> collectParamDecls(const CXXConstructorDecl *Ctor, const ParmVarDecl *ParamDecl) { … } PassByValueCheck::PassByValueCheck(StringRef Name, ClangTidyContext *Context) : … { … } void PassByValueCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { … } void PassByValueCheck::registerMatchers(MatchFinder *Finder) { … } void PassByValueCheck::registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { … } void PassByValueCheck::check(const MatchFinder::MatchResult &Result) { … } } // namespace clang::tidy::modernize