[ASTMatchers] Make hasOverloadedOperatorName also match freestanding overloads.
Freestanding overloads are represented as FunctionDecls in the AST, make the matcher also match them. Differential Revision: http://reviews.llvm.org/D4493 llvm-svn: 212940
This commit is contained in:
parent
8e254166e1
commit
09514492cc
|
@ -1542,14 +1542,14 @@ AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) {
|
|||
/// line and \c recordDecl(hasMethod(hasOverloadedOperatorName("*"))) matches
|
||||
/// the declaration of \c A.
|
||||
///
|
||||
/// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<CXXMethodDecl>
|
||||
/// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl>
|
||||
inline internal::PolymorphicMatcherWithParam1<
|
||||
internal::HasOverloadedOperatorNameMatcher, StringRef,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, CXXMethodDecl)>
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, FunctionDecl)>
|
||||
hasOverloadedOperatorName(const StringRef Name) {
|
||||
return internal::PolymorphicMatcherWithParam1<
|
||||
internal::HasOverloadedOperatorNameMatcher, StringRef,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, CXXMethodDecl)>(
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, FunctionDecl)>(
|
||||
Name);
|
||||
}
|
||||
|
||||
|
|
|
@ -517,7 +517,7 @@ template <typename T> struct has_getDecl {
|
|||
template <typename T, typename ArgT>
|
||||
class HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
|
||||
static_assert(std::is_same<T, CXXOperatorCallExpr>::value ||
|
||||
std::is_same<T, CXXMethodDecl>::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");
|
||||
|
@ -541,7 +541,7 @@ private:
|
|||
|
||||
/// \brief Returns true only if CXXMethodDecl represents an overloaded
|
||||
/// operator and has the given operator name.
|
||||
bool matchesSpecialized(const CXXMethodDecl &Node) const {
|
||||
bool matchesSpecialized(const FunctionDecl &Node) const {
|
||||
return Node.isOverloadedOperator() &&
|
||||
getOperatorSpelling(Node.getOverloadedOperator()) == Name;
|
||||
}
|
||||
|
|
|
@ -1095,12 +1095,19 @@ TEST(Matcher, HasOperatorNameForOverloadedOperatorCall) {
|
|||
"bool operator&&(Y x, Y y) { return true; }; "
|
||||
"Y a; Y b; bool c = a && b;",
|
||||
OpCallLessLess));
|
||||
StatementMatcher OpStarCall =
|
||||
operatorCallExpr(hasOverloadedOperatorName("*"));
|
||||
EXPECT_TRUE(matches("class Y; int operator*(Y &); void f(Y &y) { *y; }",
|
||||
OpStarCall));
|
||||
DeclarationMatcher ClassWithOpStar =
|
||||
recordDecl(hasMethod(hasOverloadedOperatorName("*")));
|
||||
EXPECT_TRUE(matches("class Y { int operator*(); };",
|
||||
ClassWithOpStar));
|
||||
EXPECT_TRUE(notMatches("class Y { void myOperator(); };",
|
||||
ClassWithOpStar)) ;
|
||||
DeclarationMatcher AnyOpStar = functionDecl(hasOverloadedOperatorName("*"));
|
||||
EXPECT_TRUE(matches("class Y; int operator*(Y &);", AnyOpStar));
|
||||
EXPECT_TRUE(matches("class Y { int operator*(); };", AnyOpStar));
|
||||
}
|
||||
|
||||
TEST(Matcher, NestedOverloadedOperatorCalls) {
|
||||
|
|
Loading…
Reference in New Issue