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<const StringRef *> NameRefs) { + return HasOpNameMatcher(vectorFromRefs(NameRefs)); +} + HasNameMatcher::HasNameMatcher(std::vector<std::string> N) : UseUnqualifiedMatch(std::all_of( N.begin(), N.end(), @@ -854,6 +858,10 @@ const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef, internal::hasAnyNameFunc> hasAnyName = {}; + +const internal::VariadicFunction<internal::HasOpNameMatcher, StringRef, + internal::hasAnyOperatorNameFunc> + hasAnyOperatorName = {}; const internal::VariadicFunction<internal::Matcher<ObjCMessageExpr>, 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<SourceLocation> 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<std::string>>. +template <typename T, typename ArgT = std::vector<std::string>> +class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface<T> { + static_assert(std::is_same<T, BinaryOperator>::value || + std::is_same<T, UnaryOperator>::value, + "Matcher only supports `BinaryOperator` and `UnaryOperator`"); + static_assert(std::is_same<ArgT, std::vector<std::string>>::value, + "Matcher ArgT must be std::vector<std::string>"); + +public: + explicit HasAnyOperatorNameMatcher(std::vector<std::string> Names) + : SingleNodeMatcherInterface<T>(), Names(std::move(Names)) {} + + bool matchesNode(const T &Node) const override { + StringRef OpName = getOpName(Node); + return llvm::any_of( + Names, [&](const std::string &Name) { return Name == OpName; }); + } + +private: + static StringRef getOpName(const UnaryOperator &Node) { + return Node.getOpcodeStr(Node.getOpcode()); + } + static StringRef getOpName(const BinaryOperator &Node) { + return Node.getOpcodeStr(); + } + + const std::vector<std::string> Names; +}; + +using HasOpNameMatcher = + PolymorphicMatcherWithParam1<HasAnyOperatorNameMatcher, + std::vector<std::string>, + void(TypeList<BinaryOperator, UnaryOperator>)>; + +HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef<const StringRef *> NameRefs); + } // namespace internal } // namespace ast_matchers Index: clang/include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchers.h +++ clang/include/clang/ASTMatchers/ASTMatchers.h @@ -4762,6 +4762,18 @@ return Name == Node.getOpcodeStr(Node.getOpcode()); } +/// Matches operator expressions (binary or unary) that have any of the +/// specified names. +/// +/// hasAnyOperatorName("+", "-") +/// Is equivalent to +/// anyOf(hasOperatorName("+"), hasOperatorName("-")) +/// +/// FIXME: Tweak to improve docs generated +extern const internal::VariadicFunction<internal::HasOpNameMatcher, StringRef, + internal::hasAnyOperatorNameFunc> + hasAnyOperatorName; + /// Matches all kinds of assignment operators. /// /// Example 1: matches a += b (matcher = binaryOperator(isAssignmentOperator())) Index: clang/docs/LibASTMatchersReference.html =================================================================== --- clang/docs/LibASTMatchersReference.html +++ clang/docs/LibASTMatchersReference.html @@ -4552,6 +4552,29 @@ </pre></td></tr> +<tr><td>Matcher<clang::Stmt></td><td class="name" onclick="toggle('isExpandedFromMacro0')"><a name="isExpandedFromMacro0Anchor">isExpandedFromMacro</a></td><td>llvm::StringRef MacroName</td></tr> +<tr><td colspan="4" class="doc" id="isExpandedFromMacro0"><pre>Matches statements that are (transitively) expanded from the named macro. +Does not match if only part of the statement is expanded from that macro or +if different parts of the the statement are expanded from different +appearances of the macro. + +FIXME: Change to be a polymorphic matcher that works on any syntactic +node. There's nothing `Stmt`-specific about it. +</pre></td></tr> + + +<tr><td>Matcher<internal::HasOpNameMatcher></td><td class="name" onclick="toggle('hasAnyOperatorName0')"><a name="hasAnyOperatorName0Anchor">hasAnyOperatorName</a></td><td>StringRef, ..., StringRef</td></tr> +<tr><td colspan="4" class="doc" id="hasAnyOperatorName0"><pre>Matches operator expressions (binary or unary) that have any of the +specified names. + + hasAnyOperatorName("+", "-") + Is equivalent to + anyOf(hasOperatorName("+"), hasOperatorName("-")) + +FIXME: Tweak to improve docs generated +</pre></td></tr> + + <tr><td>Matcher<internal::Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>>></td><td class="name" onclick="toggle('isInstantiated0')"><a name="isInstantiated0Anchor">isInstantiated</a></td><td></td></tr> <tr><td colspan="4" class="doc" id="isInstantiated0"><pre>Matches declarations that are template instantiations or are inside template instantiations.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits