Index: cfe/trunk/docs/LibASTMatchersReference.html =================================================================== --- cfe/trunk/docs/LibASTMatchersReference.html +++ cfe/trunk/docs/LibASTMatchersReference.html @@ -3497,6 +3497,21 @@ +
Matches standalone OpenMP directives, +i.e., directives that can't have a structured block. + +Given + + #pragma omp parallel + {} + #pragma omp taskyield + +``ompExecutableDirective(isStandaloneDirective()))`` matches +``omp taskyield``. +
Checks that a call expression or a constructor call expression has a specific number of arguments (including absent default arguments). @@ -3867,6 +3882,19 @@
Matches the Stmt AST node that is marked as being the structured-block +of an OpenMP executable directive. + +Given + + #pragma omp parallel + {} + +``stmt(isOMPStructuredBlock()))`` matches ``{}``. +
Matches nodes that have the specified size. @@ -6234,6 +6262,23 @@
Matches the structured-block of the OpenMP executable directive + +Prerequisite: the executable directive must not be standalone directive. +If it is, it will never match. + +Given + + #pragma omp parallel + ; + #pragma omp parallel + {} + +``ompExecutableDirective(hasStructuredBlock(nullStmt()))`` will match ``;`` +
Matches any argument of a call expression or a constructor call expression, or an ObjC-message-send expression. Index: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h @@ -6390,6 +6390,58 @@ extern const internal::VariadicDynCastAllOfMatcherompExecutableDirective; +/// Matches standalone OpenMP directives, +/// i.e., directives that can't have a structured block. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// {} +/// #pragma omp taskyield +/// \endcode +/// +/// ``ompExecutableDirective(isStandaloneDirective()))`` matches +/// ``omp taskyield``. +AST_MATCHER(OMPExecutableDirective, isStandaloneDirective) { + return Node.isStandaloneDirective(); +} + +/// Matches the Stmt AST node that is marked as being the structured-block +/// of an OpenMP executable directive. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// {} +/// \endcode +/// +/// ``stmt(isOMPStructuredBlock()))`` matches ``{}``. +AST_MATCHER(Stmt, isOMPStructuredBlock) { return Node.isOMPStructuredBlock(); } + +/// Matches the structured-block of the OpenMP executable directive +/// +/// Prerequisite: the executable directive must not be standalone directive. +/// If it is, it will never match. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// ; +/// #pragma omp parallel +/// {} +/// \endcode +/// +/// ``ompExecutableDirective(hasStructuredBlock(nullStmt()))`` will match ``;`` +AST_MATCHER_P(OMPExecutableDirective, hasStructuredBlock, + internal::Matcher , InnerMatcher) { + if (Node.isStandaloneDirective()) + return false; // Standalone directives have no structured blocks. + return InnerMatcher.matches(*Node.getStructuredBlock(), Finder, Builder); +} + /// Matches any clause in an OpenMP directive. /// /// Given Index: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp =================================================================== --- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp +++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp @@ -304,6 +304,7 @@ REGISTER_MATCHER(hasSourceExpression); REGISTER_MATCHER(hasSpecializedTemplate); REGISTER_MATCHER(hasStaticStorageDuration); + REGISTER_MATCHER(hasStructuredBlock); REGISTER_MATCHER(hasSyntacticForm); REGISTER_MATCHER(hasTargetDecl); REGISTER_MATCHER(hasTemplateArgument); @@ -379,6 +380,7 @@ REGISTER_MATCHER(isNoReturn); REGISTER_MATCHER(isNoThrow); REGISTER_MATCHER(isNoneKind); + REGISTER_MATCHER(isOMPStructuredBlock); REGISTER_MATCHER(isOverride); REGISTER_MATCHER(isPrivate); REGISTER_MATCHER(isProtected); @@ -387,6 +389,7 @@ REGISTER_MATCHER(isScoped); REGISTER_MATCHER(isSharedKind); REGISTER_MATCHER(isSignedInteger); + REGISTER_MATCHER(isStandaloneDirective); REGISTER_MATCHER(isStaticLocal); REGISTER_MATCHER(isStaticStorageClass); REGISTER_MATCHER(isStruct); Index: cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp =================================================================== --- cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -2274,6 +2274,71 @@ 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())))); + + const std::string Source2 = R"( +void x() { +#pragma omp taskyield +{;} +})"; + EXPECT_TRUE(notMatchesWithOpenMP( + Source2, ompExecutableDirective(hasStructuredBlock(anything())))); +} + TEST(OMPExecutableDirective, hasClause) { auto Matcher = ompExecutableDirective(hasAnyClause(anything()));