[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`
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&id=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) { 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) { I++; }", Matcher)); + EXPECT_TRUE(matches("void x(int &I) { ++I; }", Matcher)); + EXPECT_TRUE(notMatches("void x(int &I) { I--; }", Matcher)); + EXPECT_TRUE(notMatches("void x(int &I) { --I; }", Matcher)); + EXPECT_TRUE(notMatches("int *x(int &I) { return &I; }", 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 &Context); + +/// 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
[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`
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) { 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) { I++; }", Matcher)); + EXPECT_TRUE(matches("void x(int &I) { ++I; }", Matcher)); + EXPECT_TRUE(notMatches("void x(int &I) { I--; }", Matcher)); + EXPECT_TRUE(notMatches("void x(int &I) { --I; }", Matcher)); + EXPECT_TRUE(notMatches("int *x(int &I) { return &I; }", 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 &Context); + +/// 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(
[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`
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) { 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) { I++; }", Matcher)); + EXPECT_TRUE(matches("void x(int &I) { ++I; }", Matcher)); + EXPECT_TRUE(notMatches("void x(int &I) { I--; }", Matcher)); + EXPECT_TRUE(notMatches("void x(int &I) { --I; }", Matcher)); + EXPECT_TRUE(notMatches("int *x(int &I) { return &I; }", 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 &Context); + +/// 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(cons
[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`
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`
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`
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 &Name : 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`
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) { 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) { I++; }", Matcher)); + EXPECT_TRUE(matches("void x(int &I) { ++I; }", Matcher)); + EXPECT_TRUE(notMatches("void x(int &I) { I--; }", Matcher)); + EXPECT_TRUE(notMatches("void x(int &I) { --I; }", Matcher)); + EXPECT_TRUE(notMatches("int *x(int &I) { return &I; }", 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 &Context); + +/// 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
[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`
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`
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 &Name : 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`
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`
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) { 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) { I++; }", Matcher)); + EXPECT_TRUE(matches("void x(int &I) { ++I; }", Matcher)); + EXPECT_TRUE(notMatches("void x(int &I) { I--; }", Matcher)); + EXPECT_TRUE(notMatches("void x(int &I) { --I; }", Matcher)); + EXPECT_TRUE(notMatches("int *x(int &I) { return &I; }", 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 &Context); + +/// 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, +