[AMDGPU] Infer amdgpu-no-flat-scratch-init attribute in AMDGPUAttributor (#94647)
[llvm-project.git] / clang-tools-extra / clang-tidy / utils / Matchers.h
blob451c4ce92585b9b8df4e28cc756ba89de40fbeee
1 //===--- Matchers.h - clang-tidy-------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_MATCHERS_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_MATCHERS_H
12 #include "TypeTraits.h"
13 #include "clang/AST/ExprConcepts.h"
14 #include "clang/ASTMatchers/ASTMatchers.h"
15 #include <optional>
17 namespace clang::tidy::matchers {
19 AST_MATCHER(BinaryOperator, isRelationalOperator) {
20 return Node.isRelationalOp();
23 AST_MATCHER(BinaryOperator, isEqualityOperator) { return Node.isEqualityOp(); }
25 AST_MATCHER(QualType, isExpensiveToCopy) {
26 std::optional<bool> IsExpensive =
27 utils::type_traits::isExpensiveToCopy(Node, Finder->getASTContext());
28 return IsExpensive && *IsExpensive;
31 AST_MATCHER(RecordDecl, isTriviallyDefaultConstructible) {
32 return utils::type_traits::recordIsTriviallyDefaultConstructible(
33 Node, Finder->getASTContext());
36 AST_MATCHER(QualType, isTriviallyDestructible) {
37 return utils::type_traits::isTriviallyDestructible(Node);
40 // Returns QualType matcher for references to const.
41 AST_MATCHER_FUNCTION(ast_matchers::TypeMatcher, isReferenceToConst) {
42 using namespace ast_matchers;
43 return referenceType(pointee(qualType(isConstQualified())));
46 // Returns QualType matcher for pointers to const.
47 AST_MATCHER_FUNCTION(ast_matchers::TypeMatcher, isPointerToConst) {
48 using namespace ast_matchers;
49 return pointerType(pointee(qualType(isConstQualified())));
52 // Returns QualType matcher for target char type only.
53 AST_MATCHER(QualType, isSimpleChar) {
54 const auto ActualType = Node.getTypePtr();
55 return ActualType &&
56 (ActualType->isSpecificBuiltinType(BuiltinType::Char_S) ||
57 ActualType->isSpecificBuiltinType(BuiltinType::Char_U));
60 AST_MATCHER(Expr, hasUnevaluatedContext) {
61 if (isa<CXXNoexceptExpr>(Node) || isa<RequiresExpr>(Node))
62 return true;
63 if (const auto *UnaryExpr = dyn_cast<UnaryExprOrTypeTraitExpr>(&Node)) {
64 switch (UnaryExpr->getKind()) {
65 case UETT_SizeOf:
66 case UETT_AlignOf:
67 return true;
68 default:
69 return false;
72 if (const auto *TypeIDExpr = dyn_cast<CXXTypeidExpr>(&Node))
73 return !TypeIDExpr->isPotentiallyEvaluated();
74 return false;
77 // A matcher implementation that matches a list of type name regular expressions
78 // against a NamedDecl. If a regular expression contains the substring "::"
79 // matching will occur against the qualified name, otherwise only the typename.
80 class MatchesAnyListedNameMatcher
81 : public ast_matchers::internal::MatcherInterface<NamedDecl> {
82 public:
83 explicit MatchesAnyListedNameMatcher(llvm::ArrayRef<StringRef> NameList) {
84 std::transform(
85 NameList.begin(), NameList.end(), std::back_inserter(NameMatchers),
86 [](const llvm::StringRef Name) { return NameMatcher(Name); });
89 class NameMatcher {
90 llvm::Regex Regex;
91 enum class MatchMode {
92 // Match against the unqualified name because the regular expression
93 // does not contain ":".
94 MatchUnqualified,
95 // Match against the qualified name because the regular expression
96 // contains ":" suggesting name and namespace should be matched.
97 MatchQualified,
98 // Match against the fully qualified name because the regular expression
99 // starts with ":".
100 MatchFullyQualified,
102 MatchMode Mode;
104 public:
105 NameMatcher(const llvm::StringRef Regex)
106 : Regex(Regex), Mode(determineMatchMode(Regex)) {}
108 bool match(const NamedDecl &ND) const {
109 switch (Mode) {
110 case MatchMode::MatchQualified:
111 return Regex.match(ND.getQualifiedNameAsString());
112 case MatchMode::MatchFullyQualified:
113 return Regex.match("::" + ND.getQualifiedNameAsString());
114 default:
115 if (const IdentifierInfo *II = ND.getIdentifier())
116 return Regex.match(II->getName());
117 return false;
121 private:
122 MatchMode determineMatchMode(llvm::StringRef Regex) {
123 if (Regex.starts_with(":") || Regex.starts_with("^:")) {
124 return MatchMode::MatchFullyQualified;
126 return Regex.contains(":") ? MatchMode::MatchQualified
127 : MatchMode::MatchUnqualified;
131 bool matches(
132 const NamedDecl &Node, ast_matchers::internal::ASTMatchFinder *Finder,
133 ast_matchers::internal::BoundNodesTreeBuilder *Builder) const override {
134 return llvm::any_of(NameMatchers, [&Node](const NameMatcher &NM) {
135 return NM.match(Node);
139 private:
140 std::vector<NameMatcher> NameMatchers;
143 // Returns a matcher that matches NamedDecl's against a list of provided regular
144 // expressions. If a regular expression contains starts ':' the NamedDecl's
145 // qualified name will be used for matching, otherwise its name will be used.
146 inline ::clang::ast_matchers::internal::Matcher<NamedDecl>
147 matchesAnyListedName(llvm::ArrayRef<StringRef> NameList) {
148 return ::clang::ast_matchers::internal::makeMatcher(
149 new MatchesAnyListedNameMatcher(NameList));
152 // Predicate that verify if statement is not identical to one bound to ID node.
153 struct NotIdenticalStatementsPredicate {
154 bool
155 operator()(const clang::ast_matchers::internal::BoundNodesMap &Nodes) const;
157 std::string ID;
158 ::clang::DynTypedNode Node;
159 ASTContext *Context;
162 // Checks if statement is identical (utils::areStatementsIdentical) to one bound
163 // to ID node.
164 AST_MATCHER_P(Stmt, isStatementIdenticalToBoundNode, std::string, ID) {
165 NotIdenticalStatementsPredicate Predicate{
166 ID, ::clang::DynTypedNode::create(Node), &(Finder->getASTContext())};
167 return Builder->removeBindings(Predicate);
170 // A matcher implementation that matches a list of type name regular expressions
171 // against a QualType.
172 class MatchesAnyListedTypeNameMatcher
173 : public ast_matchers::internal::MatcherInterface<QualType> {
174 public:
175 explicit MatchesAnyListedTypeNameMatcher(llvm::ArrayRef<StringRef> NameList);
176 ~MatchesAnyListedTypeNameMatcher() override;
177 bool matches(
178 const QualType &Node, ast_matchers::internal::ASTMatchFinder *Finder,
179 ast_matchers::internal::BoundNodesTreeBuilder *Builder) const override;
181 private:
182 std::vector<llvm::Regex> NameMatchers;
185 // Returns a matcher that matches QualType against a list of provided regular.
186 inline ::clang::ast_matchers::internal::Matcher<QualType>
187 matchesAnyListedTypeName(llvm::ArrayRef<StringRef> NameList) {
188 return ::clang::ast_matchers::internal::makeMatcher(
189 new MatchesAnyListedTypeNameMatcher(NameList));
192 } // namespace clang::tidy::matchers
194 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_MATCHERS_H