lebedev.ri created this revision. lebedev.ri added reviewers: gribozavr, aaron.ballman, JonasToth, george.karpenkov. lebedev.ri added projects: clang, OpenMP. Herald added subscribers: jdoerfert, guansong.
Exposes the interface being added in D59214 <https://reviews.llvm.org/D59214> for ASTMatchers. Repository: rC Clang https://reviews.llvm.org/D59463 Files: docs/LibASTMatchersReference.html include/clang/ASTMatchers/ASTMatchers.h lib/ASTMatchers/Dynamic/Registry.cpp unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
Index: unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp =================================================================== --- unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -2274,6 +2274,57 @@ notMatches("int main2() {}", functionDecl(isMain()))); } +TEST(OMPExecutableDirective, isStandaloneDirective) { + auto Matcher = ompExecutableDirective(isStandaloneDirective()); + + const std::string Source0 = R"(void x() { +#pragma omp parallel +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher)); + + const std::string Source1 = R"(void x() { +#pragma omp taskyield +})"; + EXPECT_TRUE(matchesWithOpenMP(Source1, Matcher)); +} + +TEST(Stmt, isOMPStructuredBlock) { + const std::string Source0 = R"(void x() { +#pragma omp parallel +; +})"; + EXPECT_TRUE( + matchesWithOpenMP(Source0, stmt(nullStmt(), isOMPStructuredBlock()))); + + const std::string Source1 = R"(void x() { +#pragma omp parallel +{;} +})"; + EXPECT_TRUE( + notMatchesWithOpenMP(Source1, stmt(nullStmt(), isOMPStructuredBlock()))); + EXPECT_TRUE( + matchesWithOpenMP(Source1, stmt(compoundStmt(), isOMPStructuredBlock()))); +} + +TEST(OMPExecutableDirective, hasStructuredBlock) { + const std::string Source0 = R"(void x() { +#pragma omp parallel +; +})"; + EXPECT_TRUE(matchesWithOpenMP( + Source0, ompExecutableDirective(hasStructuredBlock(nullStmt())))); + + const std::string Source1 = R"(void x() { +#pragma omp parallel +{;} +})"; + EXPECT_TRUE(notMatchesWithOpenMP( + Source1, ompExecutableDirective(hasStructuredBlock(nullStmt())))); + EXPECT_TRUE(matchesWithOpenMP( + Source1, ompExecutableDirective(hasStructuredBlock(compoundStmt())))); +} + TEST(OMPExecutableDirective, hasClause) { auto Matcher = ompExecutableDirective(hasClause(anything())); Index: lib/ASTMatchers/Dynamic/Registry.cpp =================================================================== --- lib/ASTMatchers/Dynamic/Registry.cpp +++ lib/ASTMatchers/Dynamic/Registry.cpp @@ -510,6 +510,9 @@ REGISTER_MATCHER(ompDefaultClause); REGISTER_MATCHER(isNoneKind); REGISTER_MATCHER(isAllowedToContainClause); + REGISTER_MATCHER(isStandaloneDirective); + REGISTER_MATCHER(isOMPStructuredBlock); + REGISTER_MATCHER(hasStructuredBlock); } RegistryMaps::~RegistryMaps() = default; Index: include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- include/clang/ASTMatchers/ASTMatchers.h +++ include/clang/ASTMatchers/ASTMatchers.h @@ -6386,6 +6386,58 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, OMPExecutableDirective> ompExecutableDirective; +/// Given OpenMP directive, matches if it is an OpenMP standalone directive, +/// i.e. an executable directive with no structured block. +/// +/// Example: +/// +/// Given ``ompExecutableDirective(isStandaloneDirective()))``: +/// +/// \code +/// #pragma omp parallel // <- no match, not standalone +/// {} +/// #pragma omp taskyield // <- match, is standalone +/// \endcode +AST_MATCHER(OMPExecutableDirective, isStandaloneDirective) { + return Node.isStandaloneDirective(); +} + +/// Will match the Stmt AST node that is marked as being the structured block +/// of an OpenMP executable directive. +/// +/// Example: +/// +/// Given ``stmt(isOMPStructuredBlock()))``: +/// +/// \code +/// #pragma omp parallel +/// ; // <- will match `;` +/// \endcode +AST_MATCHER(Stmt, isOMPStructuredBlock) { return Node.isOMPStructuredBlock(); } + +/// Given OpenMP executable directive, matches if the InnerMatcher matches the +/// structured block of this OpenMP executable directive. +/// +/// Prerequisite: the executable directive must not be standalone directive. +/// +/// Example: +/// +/// Given ``ompExecutableDirective(hasStructuredBlock(nullStmt()))``: +/// +/// \code +/// #pragma omp parallel +/// ; // <- will match `;` +/// \endcode +/// +/// \code +/// #pragma omp parallel +/// {} // <- no match +/// \endcode +AST_MATCHER_P(OMPExecutableDirective, hasStructuredBlock, + internal::Matcher<Stmt>, InnerMatcher) { + return InnerMatcher.matches(*Node.getStructuredBlock(), Finder, Builder); +} + /// Given OpenMP directive, matches the first clause (out of all specified), /// that matches InnerMatcher. /// Index: docs/LibASTMatchersReference.html =================================================================== --- docs/LibASTMatchersReference.html +++ docs/LibASTMatchersReference.html @@ -3460,6 +3460,20 @@ </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPExecutableDirective.html">OMPExecutableDirective</a>></td><td class="name" onclick="toggle('isStandaloneDirective0')"><a name="isStandaloneDirective0Anchor">isStandaloneDirective</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isStandaloneDirective0"><pre>Given OpenMP directive, matches if it is an OpenMP standalone directive, +i.e. an executable directive with no structured block. + +Example: + +Given ``ompExecutableDirective(isStandaloneDirective()))``: + + #pragma omp parallel // <- no match, not standalone + {} + #pragma omp taskyield // <- match, is standalone +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>></td><td class="name" onclick="toggle('argumentCountIs2')"><a name="argumentCountIs2Anchor">argumentCountIs</a></td><td>unsigned N</td></tr> <tr><td colspan="4" class="doc" id="argumentCountIs2"><pre>Checks that a call expression or a constructor call expression has a specific number of arguments (including absent default arguments). @@ -3830,6 +3844,19 @@ </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('isOMPStructuredBlock0')"><a name="isOMPStructuredBlock0Anchor">isOMPStructuredBlock</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isOMPStructuredBlock0"><pre>Will match the Stmt AST node that is marked as being the structured block +of an OpenMP executable directive. + +Example: + +Given ``stmt(isOMPStructuredBlock()))``: + + #pragma omp parallel + ; // <- will match `;` +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1StringLiteral.html">StringLiteral</a>></td><td class="name" onclick="toggle('hasSize1')"><a name="hasSize1Anchor">hasSize</a></td><td>unsigned N</td></tr> <tr><td colspan="4" class="doc" id="hasSize1"><pre>Matches nodes that have the specified size. @@ -6197,6 +6224,24 @@ </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPExecutableDirective.html">OMPExecutableDirective</a>></td><td class="name" onclick="toggle('hasStructuredBlock0')"><a name="hasStructuredBlock0Anchor">hasStructuredBlock</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasStructuredBlock0"><pre>Given OpenMP executable directive, matches if the InnerMatcher matches the +structured block of this OpenMP executable directive. + +Prerequisite: the executable directive must not be standalone directive. + +Example: + +Given ``ompExecutableDirective(hasStructuredBlock(nullStmt()))``: + + #pragma omp parallel + ; // <- will match `;` + + #pragma omp parallel + {} // <- no match +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPExecutableDirective.html">OMPExecutableDirective</a>></td><td class="name" onclick="toggle('isAllowedToContainClause0')"><a name="isAllowedToContainClause0Anchor">isAllowedToContainClause</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPClause.html">OMPClause</a>> ClauseMatcher</td></tr> <tr><td colspan="4" class="doc" id="isAllowedToContainClause0"><pre>Matches if the OpenMP directive is allowed to contain the specified OpenMP clause kind.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits