[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`

2020-02-24 Thread Nathan James via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6a0c066c6102: [ASTMatchers] Adds a matcher called 
`hasAnyOperatorName` (authored by njames93).

Changed prior to commit:
  https://reviews.llvm.org/D75040?vs=246335=246375#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75040/new/

https://reviews.llvm.org/D75040

Files:
  clang/docs/LibASTMatchersReference.html
  clang/docs/tools/dump_ast_matchers.py
  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/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1123,6 +1123,19 @@
   EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
 }
 
+TEST(MatchBinaryOperator, HasAnyOperatorName) {
+  StatementMatcher Matcher =
+  binaryOperator(hasAnyOperatorName("+", "-", "*", "/"));
+
+  EXPECT_TRUE(matches("int x(int I) { return I + 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I - 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I * 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I / 2; }", Matcher));
+  EXPECT_TRUE(notMatches("int x(int I) { return I % 2; }", Matcher));
+  // Ensure '+= isn't mistaken.
+  EXPECT_TRUE(notMatches("void x(int ) { I += 1; }", Matcher));
+}
+
 TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
   StatementMatcher OperatorTrueFalse =
 binaryOperator(hasLHS(cxxBoolLiteral(equals(true))),
@@ -1255,6 +1268,18 @@
   EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
 }
 
+TEST(MatchUnaryOperator, HasAnyOperatorName) {
+  StatementMatcher Matcher = unaryOperator(hasAnyOperatorName("-", "*", "++"));
+
+  EXPECT_TRUE(matches("int x(int *I) { return *I; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return -I; }", Matcher));
+  EXPECT_TRUE(matches("void x(int ) { I++; }", Matcher));
+  EXPECT_TRUE(matches("void x(int ) { ++I; }", Matcher));
+  EXPECT_TRUE(notMatches("void x(int ) { I--; }", Matcher));
+  EXPECT_TRUE(notMatches("void x(int ) { --I; }", Matcher));
+  EXPECT_TRUE(notMatches("int *x(int ) { return  }", Matcher));
+}
+
 TEST(MatchUnaryOperator, HasUnaryOperand) {
   StatementMatcher OperatorOnFalse =
 unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false;
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -243,6 +243,7 @@
   REGISTER_MATCHER(hasAnyConstructorInitializer);
   REGISTER_MATCHER(hasAnyDeclaration);
   REGISTER_MATCHER(hasAnyName);
+  REGISTER_MATCHER(hasAnyOperatorName);
   REGISTER_MATCHER(hasAnyParameter);
   REGISTER_MATCHER(hasAnyPlacementArg);
   REGISTER_MATCHER(hasAnySelector);
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -375,6 +375,10 @@
   return hasAnySelectorMatcher(vectorFromRefs(NameRefs));
 }
 
+HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef NameRefs) {
+  return HasOpNameMatcher(vectorFromRefs(NameRefs));
+}
+
 HasNameMatcher::HasNameMatcher(std::vector N)
 : UseUnqualifiedMatch(llvm::all_of(
   N, [](StringRef Name) { return Name.find("::") == Name.npos; })),
@@ -849,6 +853,10 @@
 const internal::VariadicFunction, StringRef,
  internal::hasAnyNameFunc>
 hasAnyName = {};
+
+const internal::VariadicFunction
+hasAnyOperatorName = {};
 const internal::VariadicFunction, StringRef,
  internal::hasAnySelectorFunc>
 hasAnySelector = {};
Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h
===
--- clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1858,6 +1858,47 @@
 llvm::Optional
 getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc,
const ASTContext );
+
+/// Matches overloaded operators with a specific name.
+///
+/// The type argument ArgT is not used by this matcher but is used by
+/// PolymorphicMatcherWithParam1 and should be std::vector>.
+template >
+class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface {
+  static_assert(std::is_same::value ||
+std::is_same::value,
+"Matcher only supports `BinaryOperator` and `UnaryOperator`");
+  static_assert(std::is_same>::value,
+  

[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`

2020-02-24 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 246335.
njames93 added a comment.

- Rebase with trunk


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75040/new/

https://reviews.llvm.org/D75040

Files:
  clang/docs/LibASTMatchersReference.html
  clang/docs/tools/dump_ast_matchers.py
  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/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1123,6 +1123,19 @@
   EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
 }
 
+TEST(MatchBinaryOperator, HasAnyOperatorName) {
+  StatementMatcher Matcher =
+  binaryOperator(hasAnyOperatorName("+", "-", "*", "/"));
+
+  EXPECT_TRUE(matches("int x(int I) { return I + 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I - 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I * 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I / 2; }", Matcher));
+  EXPECT_TRUE(notMatches("int x(int I) { return I % 2; }", Matcher));
+  // Ensure '+= isn't mistaken.
+  EXPECT_TRUE(notMatches("void x(int ) { I += 1; }", Matcher));
+}
+
 TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
   StatementMatcher OperatorTrueFalse =
 binaryOperator(hasLHS(cxxBoolLiteral(equals(true))),
@@ -1255,6 +1268,18 @@
   EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
 }
 
+TEST(MatchUnaryOperator, HasAnyOperatorName) {
+  StatementMatcher Matcher = unaryOperator(hasAnyOperatorName("-", "*", "++"));
+
+  EXPECT_TRUE(matches("int x(int *I) { return *I; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return -I; }", Matcher));
+  EXPECT_TRUE(matches("void x(int ) { I++; }", Matcher));
+  EXPECT_TRUE(matches("void x(int ) { ++I; }", Matcher));
+  EXPECT_TRUE(notMatches("void x(int ) { I--; }", Matcher));
+  EXPECT_TRUE(notMatches("void x(int ) { --I; }", Matcher));
+  EXPECT_TRUE(notMatches("int *x(int ) { return  }", Matcher));
+}
+
 TEST(MatchUnaryOperator, HasUnaryOperand) {
   StatementMatcher OperatorOnFalse =
 unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false;
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -243,6 +243,7 @@
   REGISTER_MATCHER(hasAnyConstructorInitializer);
   REGISTER_MATCHER(hasAnyDeclaration);
   REGISTER_MATCHER(hasAnyName);
+  REGISTER_MATCHER(hasAnyOperatorName);
   REGISTER_MATCHER(hasAnyParameter);
   REGISTER_MATCHER(hasAnyPlacementArg);
   REGISTER_MATCHER(hasAnySelector);
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -380,6 +380,10 @@
   return hasAnySelectorMatcher(vectorFromRefs(NameRefs));
 }
 
+HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef NameRefs) {
+  return HasOpNameMatcher(vectorFromRefs(NameRefs));
+}
+
 HasNameMatcher::HasNameMatcher(std::vector N)
 : UseUnqualifiedMatch(std::all_of(
   N.begin(), N.end(),
@@ -854,6 +858,10 @@
 const internal::VariadicFunction, StringRef,
  internal::hasAnyNameFunc>
 hasAnyName = {};
+
+const internal::VariadicFunction
+hasAnyOperatorName = {};
 const internal::VariadicFunction, StringRef,
  internal::hasAnySelectorFunc>
 hasAnySelector = {};
Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h
===
--- clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1858,6 +1858,47 @@
 llvm::Optional
 getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc,
const ASTContext );
+
+/// Matches overloaded operators with a specific name.
+///
+/// The type argument ArgT is not used by this matcher but is used by
+/// PolymorphicMatcherWithParam1 and should be std::vector>.
+template >
+class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface {
+  static_assert(std::is_same::value ||
+std::is_same::value,
+"Matcher only supports `BinaryOperator` and `UnaryOperator`");
+  static_assert(std::is_same>::value,
+"Matcher ArgT must be std::vector");
+
+public:
+  explicit HasAnyOperatorNameMatcher(std::vector Names)
+  : SingleNodeMatcherInterface(), Names(std::move(Names)) {}
+
+  bool matchesNode(const T ) const 

[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`

2020-02-24 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 246203.
njames93 added a comment.

- Improved docs


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75040/new/

https://reviews.llvm.org/D75040

Files:
  clang/docs/LibASTMatchersReference.html
  clang/docs/tools/dump_ast_matchers.py
  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/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1123,6 +1123,19 @@
   EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
 }
 
+TEST(MatchBinaryOperator, HasAnyOperatorName) {
+  StatementMatcher Matcher =
+  binaryOperator(hasAnyOperatorName("+", "-", "*", "/"));
+
+  EXPECT_TRUE(matches("int x(int I) { return I + 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I - 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I * 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I / 2; }", Matcher));
+  EXPECT_TRUE(notMatches("int x(int I) { return I % 2; }", Matcher));
+  // Ensure '+= isn't mistaken.
+  EXPECT_TRUE(notMatches("void x(int ) { I += 1; }", Matcher));
+}
+
 TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
   StatementMatcher OperatorTrueFalse =
 binaryOperator(hasLHS(cxxBoolLiteral(equals(true))),
@@ -1255,6 +1268,18 @@
   EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
 }
 
+TEST(MatchUnaryOperator, HasAnyOperatorName) {
+  StatementMatcher Matcher = unaryOperator(hasAnyOperatorName("-", "*", "++"));
+
+  EXPECT_TRUE(matches("int x(int *I) { return *I; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return -I; }", Matcher));
+  EXPECT_TRUE(matches("void x(int ) { I++; }", Matcher));
+  EXPECT_TRUE(matches("void x(int ) { ++I; }", Matcher));
+  EXPECT_TRUE(notMatches("void x(int ) { I--; }", Matcher));
+  EXPECT_TRUE(notMatches("void x(int ) { --I; }", Matcher));
+  EXPECT_TRUE(notMatches("int *x(int ) { return  }", Matcher));
+}
+
 TEST(MatchUnaryOperator, HasUnaryOperand) {
   StatementMatcher OperatorOnFalse =
 unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false;
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -243,6 +243,7 @@
   REGISTER_MATCHER(hasAnyConstructorInitializer);
   REGISTER_MATCHER(hasAnyDeclaration);
   REGISTER_MATCHER(hasAnyName);
+  REGISTER_MATCHER(hasAnyOperatorName);
   REGISTER_MATCHER(hasAnyParameter);
   REGISTER_MATCHER(hasAnyPlacementArg);
   REGISTER_MATCHER(hasAnySelector);
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -380,6 +380,10 @@
   return hasAnySelectorMatcher(vectorFromRefs(NameRefs));
 }
 
+HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef NameRefs) {
+  return HasOpNameMatcher(vectorFromRefs(NameRefs));
+}
+
 HasNameMatcher::HasNameMatcher(std::vector N)
 : UseUnqualifiedMatch(std::all_of(
   N.begin(), N.end(),
@@ -854,6 +858,10 @@
 const internal::VariadicFunction, StringRef,
  internal::hasAnyNameFunc>
 hasAnyName = {};
+
+const internal::VariadicFunction
+hasAnyOperatorName = {};
 const internal::VariadicFunction, StringRef,
  internal::hasAnySelectorFunc>
 hasAnySelector = {};
Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h
===
--- clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1858,6 +1858,47 @@
 llvm::Optional
 getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc,
const ASTContext );
+
+/// Matches overloaded operators with a specific name.
+///
+/// The type argument ArgT is not used by this matcher but is used by
+/// PolymorphicMatcherWithParam1 and should be std::vector>.
+template >
+class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface {
+  static_assert(std::is_same::value ||
+std::is_same::value,
+"Matcher only supports `BinaryOperator` and `UnaryOperator`");
+  static_assert(std::is_same>::value,
+"Matcher ArgT must be std::vector");
+
+public:
+  explicit HasAnyOperatorNameMatcher(std::vector Names)
+  : SingleNodeMatcherInterface(), Names(std::move(Names)) {}
+
+  bool matchesNode(const T ) const override {

[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`

2020-02-24 Thread Nathan James via Phabricator via cfe-commits
njames93 requested review of this revision.
njames93 marked 3 inline comments as done.
njames93 added a comment.

I have fixed up the docs to be more in line with other matchers


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75040/new/

https://reviews.llvm.org/D75040



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`

2020-02-24 Thread Nathan James via Phabricator via cfe-commits
njames93 marked an inline comment as done.
njames93 added inline comments.



Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:4772
+///
+/// FIXME: Tweak to improve docs generated
+extern const internal::VariadicFunction Any specific things you would like to improve? The fixme is rather vague.
This is what comes up in the ASTMatchersReference docs. 
```
Matcher hasAnyOperatorName  StringRef, ..., 
StringRef```
I would like it to have 
```
Matcher  hasAnyOperatorName StringRef, ..., StringRef
...
Matcher  hasAnyOperatorName  StringRef, ..., StringRef```
However how VariadicFunction is matched in the dumper won't support that yet. 
And If you want to support it properly regex wouldn't work, instead you'd need 
a parser


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75040/new/

https://reviews.llvm.org/D75040



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`

2020-02-24 Thread Nathan James via Phabricator via cfe-commits
njames93 marked an inline comment as done.
njames93 added inline comments.



Comment at: clang/include/clang/ASTMatchers/ASTMatchersInternal.h:1870
+std::is_same::value,
+"unsupported class for matcher");
+  static_assert(std::is_same>::value,

gribozavr2 wrote:
> Consider enhancing the message to say what the expected types are.
This is the reason c++17 removed the need for static_assert messages, the 
message isn't needed as you can figure the error from the predicate



Comment at: clang/include/clang/ASTMatchers/ASTMatchersInternal.h:1880-1884
+for (const std::string  : Names) {
+  if (Name == OpName)
+return true;
+}
+return false;

aaron.ballman wrote:
> Can we use `llvm::find()` instead of a manual loop?
`llvm::is_contained` would be better, but they involve creating temporaries, 
`llvm::any_of` does it best I think


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75040/new/

https://reviews.llvm.org/D75040



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`

2020-02-24 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 246190.
njames93 marked an inline comment as done.
njames93 edited the summary of this revision.
njames93 added a comment.

- Address nits


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75040/new/

https://reviews.llvm.org/D75040

Files:
  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/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1123,6 +1123,19 @@
   EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
 }
 
+TEST(MatchBinaryOperator, HasAnyOperatorName) {
+  StatementMatcher Matcher =
+  binaryOperator(hasAnyOperatorName("+", "-", "*", "/"));
+
+  EXPECT_TRUE(matches("int x(int I) { return I + 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I - 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I * 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I / 2; }", Matcher));
+  EXPECT_TRUE(notMatches("int x(int I) { return I % 2; }", Matcher));
+  // Ensure '+= isn't mistaken.
+  EXPECT_TRUE(notMatches("void x(int ) { I += 1; }", Matcher));
+}
+
 TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
   StatementMatcher OperatorTrueFalse =
 binaryOperator(hasLHS(cxxBoolLiteral(equals(true))),
@@ -1255,6 +1268,18 @@
   EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
 }
 
+TEST(MatchUnaryOperator, HasAnyOperatorName) {
+  StatementMatcher Matcher = unaryOperator(hasAnyOperatorName("-", "*", "++"));
+
+  EXPECT_TRUE(matches("int x(int *I) { return *I; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return -I; }", Matcher));
+  EXPECT_TRUE(matches("void x(int ) { I++; }", Matcher));
+  EXPECT_TRUE(matches("void x(int ) { ++I; }", Matcher));
+  EXPECT_TRUE(notMatches("void x(int ) { I--; }", Matcher));
+  EXPECT_TRUE(notMatches("void x(int ) { --I; }", Matcher));
+  EXPECT_TRUE(notMatches("int *x(int ) { return  }", Matcher));
+}
+
 TEST(MatchUnaryOperator, HasUnaryOperand) {
   StatementMatcher OperatorOnFalse =
 unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false;
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -243,6 +243,7 @@
   REGISTER_MATCHER(hasAnyConstructorInitializer);
   REGISTER_MATCHER(hasAnyDeclaration);
   REGISTER_MATCHER(hasAnyName);
+  REGISTER_MATCHER(hasAnyOperatorName);
   REGISTER_MATCHER(hasAnyParameter);
   REGISTER_MATCHER(hasAnyPlacementArg);
   REGISTER_MATCHER(hasAnySelector);
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -380,6 +380,10 @@
   return hasAnySelectorMatcher(vectorFromRefs(NameRefs));
 }
 
+HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef NameRefs) {
+  return HasOpNameMatcher(vectorFromRefs(NameRefs));
+}
+
 HasNameMatcher::HasNameMatcher(std::vector N)
 : UseUnqualifiedMatch(std::all_of(
   N.begin(), N.end(),
@@ -854,6 +858,10 @@
 const internal::VariadicFunction, StringRef,
  internal::hasAnyNameFunc>
 hasAnyName = {};
+
+const internal::VariadicFunction
+hasAnyOperatorName = {};
 const internal::VariadicFunction, StringRef,
  internal::hasAnySelectorFunc>
 hasAnySelector = {};
Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h
===
--- clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1858,6 +1858,47 @@
 llvm::Optional
 getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc,
const ASTContext );
+
+/// Matches overloaded operators with a specific name.
+///
+/// The type argument ArgT is not used by this matcher but is used by
+/// PolymorphicMatcherWithParam1 and should be std::vector>.
+template >
+class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface {
+  static_assert(std::is_same::value ||
+std::is_same::value,
+"Matcher only supports `BinaryOperator` and `UnaryOperator`");
+  static_assert(std::is_same>::value,
+"Matcher ArgT must be std::vector");
+
+public:
+  explicit HasAnyOperatorNameMatcher(std::vector Names)
+  : SingleNodeMatcherInterface(), Names(std::move(Names)) {}

[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`

2020-02-24 Thread Dmitri Gribenko via Phabricator via cfe-commits
gribozavr2 added inline comments.



Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:4772
+///
+/// FIXME: Tweak to improve docs generated
+extern const internal::VariadicFunctionhttps://reviews.llvm.org/D75040/new/

https://reviews.llvm.org/D75040



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`

2020-02-24 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.

LGTM




Comment at: clang/include/clang/ASTMatchers/ASTMatchersInternal.h:1880-1884
+for (const std::string  : Names) {
+  if (Name == OpName)
+return true;
+}
+return false;

Can we use `llvm::find()` instead of a manual loop?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75040/new/

https://reviews.llvm.org/D75040



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`

2020-02-24 Thread Dmitri Gribenko via Phabricator via cfe-commits
gribozavr2 accepted this revision.
gribozavr2 added inline comments.
This revision is now accepted and ready to land.



Comment at: clang/include/clang/ASTMatchers/ASTMatchersInternal.h:1870
+std::is_same::value,
+"unsupported class for matcher");
+  static_assert(std::is_same>::value,

Consider enhancing the message to say what the expected types are.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75040/new/

https://reviews.llvm.org/D75040



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`

2020-02-24 Thread Nathan James via Phabricator via cfe-commits
njames93 created this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
njames93 edited the summary of this revision.
njames93 added reviewers: aaron.ballman, gribozavr2.

Acts on `BinaryOperator` and `UnaryOperator` and functions the same as 
`anyOf(hasOperatorName(...), hasOperatorName(...), ...)`

Documentation generation isn't perfect but I feel that the python doc script 
needs updating for that


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75040

Files:
  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/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1123,6 +1123,19 @@
   EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
 }
 
+TEST(MatchBinaryOperator, HasAnyOperatorName) {
+  StatementMatcher Matcher =
+  binaryOperator(hasAnyOperatorName("+", "-", "*", "/"));
+
+  EXPECT_TRUE(matches("int x(int I) { return I + 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I - 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I * 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I / 2; }", Matcher));
+  EXPECT_TRUE(notMatches("int x(int I) { return I % 2; }", Matcher));
+  // Ensure '+= isn't mistaken.
+  EXPECT_TRUE(notMatches("void x(int ) { I += 1; }", Matcher));
+}
+
 TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
   StatementMatcher OperatorTrueFalse =
 binaryOperator(hasLHS(cxxBoolLiteral(equals(true))),
@@ -1255,6 +1268,18 @@
   EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
 }
 
+TEST(MatchUnaryOperator, HasAnyOperatorName) {
+  StatementMatcher Matcher = unaryOperator(hasAnyOperatorName("-", "*", "++"));
+
+  EXPECT_TRUE(matches("int x(int *I) { return *I; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return -I; }", Matcher));
+  EXPECT_TRUE(matches("void x(int ) { I++; }", Matcher));
+  EXPECT_TRUE(matches("void x(int ) { ++I; }", Matcher));
+  EXPECT_TRUE(notMatches("void x(int ) { I--; }", Matcher));
+  EXPECT_TRUE(notMatches("void x(int ) { --I; }", Matcher));
+  EXPECT_TRUE(notMatches("int *x(int ) { return  }", Matcher));
+}
+
 TEST(MatchUnaryOperator, HasUnaryOperand) {
   StatementMatcher OperatorOnFalse =
 unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false;
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -243,6 +243,7 @@
   REGISTER_MATCHER(hasAnyConstructorInitializer);
   REGISTER_MATCHER(hasAnyDeclaration);
   REGISTER_MATCHER(hasAnyName);
+  REGISTER_MATCHER(hasAnyOperatorName);
   REGISTER_MATCHER(hasAnyParameter);
   REGISTER_MATCHER(hasAnyPlacementArg);
   REGISTER_MATCHER(hasAnySelector);
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -380,6 +380,10 @@
   return hasAnySelectorMatcher(vectorFromRefs(NameRefs));
 }
 
+HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef NameRefs) {
+  return HasOpNameMatcher(vectorFromRefs(NameRefs));
+}
+
 HasNameMatcher::HasNameMatcher(std::vector N)
 : UseUnqualifiedMatch(std::all_of(
   N.begin(), N.end(),
@@ -854,6 +858,10 @@
 const internal::VariadicFunction, StringRef,
  internal::hasAnyNameFunc>
 hasAnyName = {};
+
+const internal::VariadicFunction
+hasAnyOperatorName = {};
 const internal::VariadicFunction, StringRef,
  internal::hasAnySelectorFunc>
 hasAnySelector = {};
Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h
===
--- clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1858,6 +1858,50 @@
 llvm::Optional
 getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc,
const ASTContext );
+
+/// Matches overloaded operators with a specific name.
+///
+/// The type argument ArgT is not used by this matcher but is used by
+/// PolymorphicMatcherWithParam1 and should be StringRef.
+template 
+class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface {
+  static_assert(std::is_same::value ||
+std::is_same::value,
+"unsupported class for matcher");
+  static_assert(std::is_same>::value,
+"Unsupported