[ASTMatchers][OpenMP] OpenMP Structured-block-related matchers
Summary: Exposes to the for ASTMatchers the interface/modelling of OpenMP structured-block. Reviewers: gribozavr, aaron.ballman, JonasToth, george.karpenkov Reviewed By: gribozavr, aaron.ballman Subscribers: guansong, jdoerfert, cfe-commits Tags: #clang, #openmp Differential Revision: https://reviews.llvm.org/D59463 llvm-svn: 356676
This commit is contained in:
parent
33ef20ec2f
commit
c816195759
|
@ -3497,6 +3497,21 @@ should be passed as a quoted string. e.g.,
|
|||
</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>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``.
|
||||
</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).
|
||||
|
@ -3867,6 +3882,19 @@ Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl
|
|||
</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>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 ``{}``.
|
||||
</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.
|
||||
|
||||
|
@ -6234,6 +6262,23 @@ Given
|
|||
</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>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 ``;``
|
||||
</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('hasAnyArgument3')"><a name="hasAnyArgument3Anchor">hasAnyArgument</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasAnyArgument3"><pre>Matches any argument of a call expression or a constructor call
|
||||
expression, or an ObjC-message-send expression.
|
||||
|
|
|
@ -6390,6 +6390,58 @@ AST_MATCHER(FunctionDecl, hasTrailingReturn) {
|
|||
extern const internal::VariadicDynCastAllOfMatcher<Stmt, OMPExecutableDirective>
|
||||
ompExecutableDirective;
|
||||
|
||||
/// 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<Stmt>, 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
|
||||
|
|
|
@ -304,6 +304,7 @@ RegistryMaps::RegistryMaps() {
|
|||
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 @@ RegistryMaps::RegistryMaps() {
|
|||
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 @@ RegistryMaps::RegistryMaps() {
|
|||
REGISTER_MATCHER(isScoped);
|
||||
REGISTER_MATCHER(isSharedKind);
|
||||
REGISTER_MATCHER(isSignedInteger);
|
||||
REGISTER_MATCHER(isStandaloneDirective);
|
||||
REGISTER_MATCHER(isStaticLocal);
|
||||
REGISTER_MATCHER(isStaticStorageClass);
|
||||
REGISTER_MATCHER(isStruct);
|
||||
|
|
|
@ -2274,6 +2274,71 @@ TEST(Matcher, isMain) {
|
|||
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()));
|
||||
|
||||
|
|
Loading…
Reference in New Issue