[clang] 77eec38 - [ASTMatchers] Add hasAnyOverloadedOperatorName matcher
Nathan James via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 9 17:11:34 PDT 2020
Author: Nathan James
Date: 2020-03-10T00:11:27Z
New Revision: 77eec38626cb9e796f6cbb108ea9be5ee6e0ce81
URL: https://github.com/llvm/llvm-project/commit/77eec38626cb9e796f6cbb108ea9be5ee6e0ce81
DIFF: https://github.com/llvm/llvm-project/commit/77eec38626cb9e796f6cbb108ea9be5ee6e0ce81.diff
LOG: [ASTMatchers] Add hasAnyOverloadedOperatorName matcher
Reviewers: aaron.ballman
Reviewed By: aaron.ballman
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D75841
Added:
Modified:
clang/docs/LibASTMatchersReference.html
clang/include/clang/ASTMatchers/ASTMatchers.h
clang/include/clang/ASTMatchers/ASTMatchersInternal.h
clang/lib/ASTMatchers/ASTMatchersInternal.cpp
clang/lib/ASTMatchers/Dynamic/Registry.cpp
clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
Removed:
################################################################################
diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html
index f0faed7f0f8f..f5208abf44bd 100644
--- a/clang/docs/LibASTMatchersReference.html
+++ b/clang/docs/LibASTMatchersReference.html
@@ -2599,6 +2599,18 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
</pre></td></tr>
+<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html">CXXOperatorCallExpr</a>></td><td class="name" onclick="toggle('hasAnyOverloadedOperatorName0')"><a name="hasAnyOverloadedOperatorName0Anchor">hasAnyOverloadedOperatorName</a></td><td>StringRef, ..., StringRef</td></tr>
+<tr><td colspan="4" class="doc" id="hasAnyOverloadedOperatorName0"><pre>Matches overloaded operator names.
+
+Matches overloaded operator names specified in strings without the
+"operator" prefix: e.g. "<<".
+
+ hasAnyOverloadesOperatorName("+", "-")
+Is equivalent to
+ anyOf(hasOverloadedOperatorName("+"), hasOverloadedOperatorName("-"))
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html">CXXOperatorCallExpr</a>></td><td class="name" onclick="toggle('hasOverloadedOperatorName1')"><a name="hasOverloadedOperatorName1Anchor">hasOverloadedOperatorName</a></td><td>StringRef Name</td></tr>
<tr><td colspan="4" class="doc" id="hasOverloadedOperatorName1"><pre>Matches overloaded operator names.
@@ -3178,6 +3190,18 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
<tr><td colspan="4" class="doc" id="equals12"><pre></pre></td></tr>
+<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('hasAnyOverloadedOperatorName1')"><a name="hasAnyOverloadedOperatorName1Anchor">hasAnyOverloadedOperatorName</a></td><td>StringRef, ..., StringRef</td></tr>
+<tr><td colspan="4" class="doc" id="hasAnyOverloadedOperatorName1"><pre>Matches overloaded operator names.
+
+Matches overloaded operator names specified in strings without the
+"operator" prefix: e.g. "<<".
+
+ hasAnyOverloadesOperatorName("+", "-")
+Is equivalent to
+ anyOf(hasOverloadedOperatorName("+"), hasOverloadedOperatorName("-"))
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('hasDynamicExceptionSpec0')"><a name="hasDynamicExceptionSpec0Anchor">hasDynamicExceptionSpec</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="hasDynamicExceptionSpec0"><pre>Matches functions that have a dynamic exception specification.
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 31138e47750c..989932b9c119 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -2749,14 +2749,30 @@ AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) {
///
/// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl>
inline internal::PolymorphicMatcherWithParam1<
- internal::HasOverloadedOperatorNameMatcher, StringRef,
+ internal::HasOverloadedOperatorNameMatcher, std::vector<std::string>,
AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>
hasOverloadedOperatorName(StringRef Name) {
return internal::PolymorphicMatcherWithParam1<
- internal::HasOverloadedOperatorNameMatcher, StringRef,
- AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>(Name);
+ internal::HasOverloadedOperatorNameMatcher, std::vector<std::string>,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>(
+ {std::string(Name)});
}
+/// Matches overloaded operator names.
+///
+/// Matches overloaded operator names specified in strings without the
+/// "operator" prefix: e.g. "<<".
+///
+/// hasAnyOverloadesOperatorName("+", "-")
+/// Is equivalent to
+/// anyOf(hasOverloadedOperatorName("+"), hasOverloadedOperatorName("-"))
+extern const internal::VariadicFunction<
+ internal::PolymorphicMatcherWithParam1<
+ internal::HasOverloadedOperatorNameMatcher, std::vector<std::string>,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>,
+ StringRef, internal::hasAnyOverloadedOperatorNameFunc>
+ hasAnyOverloadedOperatorName;
+
/// Matches C++ classes that are directly or indirectly derived from a class
/// matching \c Base, or Objective-C classes that directly or indirectly
/// subclass a class matching \c Base.
diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
index 6e4310fa0ee8..e363bdd9ae9c 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -670,12 +670,12 @@ class HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
static_assert(std::is_same<T, CXXOperatorCallExpr>::value ||
std::is_base_of<FunctionDecl, T>::value,
"unsupported class for matcher");
- static_assert(std::is_same<ArgT, StringRef>::value,
- "argument type must be StringRef");
+ static_assert(std::is_same<ArgT, std::vector<std::string>>::value,
+ "argument type must be std::vector<std::string>");
public:
- explicit HasOverloadedOperatorNameMatcher(const StringRef Name)
- : SingleNodeMatcherInterface<T>(), Name(Name) {}
+ explicit HasOverloadedOperatorNameMatcher(std::vector<std::string> Names)
+ : SingleNodeMatcherInterface<T>(), Names(std::move(Names)) {}
bool matchesNode(const T &Node) const override {
return matchesSpecialized(Node);
@@ -687,17 +687,18 @@ class HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
/// so this function returns true if the call is to an operator of the given
/// name.
bool matchesSpecialized(const CXXOperatorCallExpr &Node) const {
- return getOperatorSpelling(Node.getOperator()) == Name;
+ return llvm::is_contained(Names, getOperatorSpelling(Node.getOperator()));
}
/// Returns true only if CXXMethodDecl represents an overloaded
/// operator and has the given operator name.
bool matchesSpecialized(const FunctionDecl &Node) const {
return Node.isOverloadedOperator() &&
- getOperatorSpelling(Node.getOverloadedOperator()) == Name;
+ llvm::is_contained(
+ Names, getOperatorSpelling(Node.getOverloadedOperator()));
}
- std::string Name;
+ const std::vector<std::string> Names;
};
/// Matches named declarations with a specific name.
@@ -1899,6 +1900,13 @@ using HasOpNameMatcher =
HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef<const StringRef *> NameRefs);
+using HasOverloadOpNameMatcher = PolymorphicMatcherWithParam1<
+ HasOverloadedOperatorNameMatcher, std::vector<std::string>,
+ void(TypeList<CXXOperatorCallExpr, FunctionDecl>)>;
+
+HasOverloadOpNameMatcher
+hasAnyOverloadedOperatorNameFunc(ArrayRef<const StringRef *> NameRefs);
+
} // namespace internal
} // namespace ast_matchers
diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
index 033a5f19fd8c..c20e8422be46 100644
--- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -378,6 +378,11 @@ HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef<const StringRef *> NameRefs) {
return HasOpNameMatcher(vectorFromRefs(NameRefs));
}
+HasOverloadOpNameMatcher
+hasAnyOverloadedOperatorNameFunc(ArrayRef<const StringRef *> NameRefs) {
+ return HasOverloadOpNameMatcher(vectorFromRefs(NameRefs));
+}
+
HasNameMatcher::HasNameMatcher(std::vector<std::string> N)
: UseUnqualifiedMatch(llvm::all_of(
N, [](StringRef Name) { return Name.find("::") == Name.npos; })),
@@ -861,6 +866,9 @@ const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef,
const internal::VariadicFunction<internal::HasOpNameMatcher, StringRef,
internal::hasAnyOperatorNameFunc>
hasAnyOperatorName = {};
+const internal::VariadicFunction<internal::HasOverloadOpNameMatcher, StringRef,
+ internal::hasAnyOverloadedOperatorNameFunc>
+ hasAnyOverloadedOperatorName = {};
const internal::VariadicFunction<internal::Matcher<ObjCMessageExpr>, StringRef,
internal::hasAnySelectorFunc>
hasAnySelector = {};
diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
index fd2b6b253c53..8ff70a4f78cf 100644
--- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -244,6 +244,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(hasAnyDeclaration);
REGISTER_MATCHER(hasAnyName);
REGISTER_MATCHER(hasAnyOperatorName);
+ REGISTER_MATCHER(hasAnyOverloadedOperatorName);
REGISTER_MATCHER(hasAnyParameter);
REGISTER_MATCHER(hasAnyPlacementArg);
REGISTER_MATCHER(hasAnySelector);
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
index 2816e216e8c4..88c55e1cb4f4 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -898,6 +898,12 @@ TEST(Matcher, HasOperatorNameForOverloadedOperatorCall) {
DeclarationMatcher AnyOpStar = functionDecl(hasOverloadedOperatorName("*"));
EXPECT_TRUE(matches("class Y; int operator*(Y &);", AnyOpStar));
EXPECT_TRUE(matches("class Y { int operator*(); };", AnyOpStar));
+ DeclarationMatcher AnyAndOp =
+ functionDecl(hasAnyOverloadedOperatorName("&", "&&"));
+ EXPECT_TRUE(matches("class Y; Y operator&(Y &, Y &);", AnyAndOp));
+ EXPECT_TRUE(matches("class Y; Y operator&&(Y &, Y &);", AnyAndOp));
+ EXPECT_TRUE(matches("class Y { Y operator&(Y &); };", AnyAndOp));
+ EXPECT_TRUE(matches("class Y { Y operator&&(Y &); };", AnyAndOp));
}
More information about the cfe-commits
mailing list