diff options
author | Roman Lebedev <lebedev.ri@gmail.com> | 2019-03-21 15:33:24 +0000 |
---|---|---|
committer | Roman Lebedev <lebedev.ri@gmail.com> | 2019-03-21 15:33:24 +0000 |
commit | 33ef20ec2f1324b1fbee60f502d9a3ede550d5d8 (patch) | |
tree | adeee29f521a1605b5b695f62fffededb7c34872 | |
parent | de0e4ae024eced8fa952c4b8d9e0f0a607a0a86b (diff) | |
download | bcm5719-llvm-33ef20ec2f1324b1fbee60f502d9a3ede550d5d8.tar.gz bcm5719-llvm-33ef20ec2f1324b1fbee60f502d9a3ede550d5d8.zip |
[ASTTypeTraits][ASTMatchers][OpenMP] OMPClause handling
Summary:
`OMPClause` is the base class, it is not descendant from **any**
other class, therefore for it to work with e.g.
`VariadicDynCastAllOfMatcher<>`, it needs to be handled here.
Reviewers: sbenza, bkramer, pcc, klimek, hokein, gribozavr, aaron.ballman, george.karpenkov
Reviewed By: gribozavr, aaron.ballman
Subscribers: guansong, jdoerfert, alexfh, ABataev, cfe-commits
Tags: #openmp, #clang
Differential Revision: https://reviews.llvm.org/D57112
llvm-svn: 356675
-rw-r--r-- | clang/docs/LibASTMatchersReference.html | 71 | ||||
-rw-r--r-- | clang/include/clang/AST/ASTTypeTraits.h | 13 | ||||
-rw-r--r-- | clang/include/clang/ASTMatchers/ASTMatchers.h | 85 | ||||
-rw-r--r-- | clang/lib/AST/ASTTypeTraits.cpp | 19 | ||||
-rw-r--r-- | clang/lib/ASTMatchers/ASTMatchersInternal.cpp | 2 | ||||
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Marshallers.h | 23 | ||||
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Registry.cpp | 5 | ||||
-rw-r--r-- | clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp | 168 | ||||
-rw-r--r-- | clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp | 38 |
9 files changed, 424 insertions, 0 deletions
diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index 298faa782b1..eee51c35c5b 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -645,6 +645,19 @@ nestedNameSpecifier() </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPClause.html">OMPClause</a>></td><td class="name" onclick="toggle('ompDefaultClause0')"><a name="ompDefaultClause0Anchor">ompDefaultClause</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPDefaultClause.html">OMPDefaultClause</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="ompDefaultClause0"><pre>Matches OpenMP ``default`` clause. + +Given + + #pragma omp parallel default(none) + #pragma omp parallel default(shared) + #pragma omp parallel + +``ompDefaultClause()`` matches ``default(none)`` and ``default(shared)``. +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>></td><td class="name" onclick="toggle('qualType0')"><a name="qualType0Anchor">qualType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>...</td></tr> <tr><td colspan="4" class="doc" id="qualType0"><pre>Matches QualTypes in the clang AST. </pre></td></tr> @@ -3439,6 +3452,51 @@ namespaceDecl(isInline()) will match n::m. </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPDefaultClause.html">OMPDefaultClause</a>></td><td class="name" onclick="toggle('isNoneKind0')"><a name="isNoneKind0Anchor">isNoneKind</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isNoneKind0"><pre>Matches if the OpenMP ``default`` clause has ``none`` kind specified. + +Given + + #pragma omp parallel + #pragma omp parallel default(none) + #pragma omp parallel default(shared) + +``ompDefaultClause(isNoneKind())`` matches only ``default(none)``. +</pre></td></tr> + + +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPDefaultClause.html">OMPDefaultClause</a>></td><td class="name" onclick="toggle('isSharedKind0')"><a name="isSharedKind0Anchor">isSharedKind</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isSharedKind0"><pre>Matches if the OpenMP ``default`` clause has ``shared`` kind specified. + +Given + + #pragma omp parallel + #pragma omp parallel default(none) + #pragma omp parallel default(shared) + +``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``. +</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('isAllowedToContainClauseKind0')"><a name="isAllowedToContainClauseKind0Anchor">isAllowedToContainClauseKind</a></td><td>OpenMPClauseKind CKind</td></tr> +<tr><td colspan="4" class="doc" id="isAllowedToContainClauseKind0"><pre>Matches if the OpenMP directive is allowed to contain the specified OpenMP +clause kind. + +Given + + #pragma omp parallel + #pragma omp parallel for + #pragma omp for + +`ompExecutableDirective(isAllowedToContainClause(OMPC_default))`` matches +``omp parallel`` and ``omp parallel for``. + +If the matcher is use from clang-query, ``OpenMPClauseKind`` parameter +should be passed as a quoted string. e.g., +``isAllowedToContainClauseKind("OMPC_default").`` +</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). @@ -6163,6 +6221,19 @@ nestedNameSpecifier(specifiesType( </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('hasAnyClause0')"><a name="hasAnyClause0Anchor">hasAnyClause</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPClause.html">OMPClause</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasAnyClause0"><pre>Matches any clause in an OpenMP directive. + +Given + + #pragma omp parallel + #pragma omp parallel default(none) + +``ompExecutableDirective(hasAnyClause(anything()))`` matches +``omp parallel default(none)``. +</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. diff --git a/clang/include/clang/AST/ASTTypeTraits.h b/clang/include/clang/AST/ASTTypeTraits.h index 71c0ec4c2a8..477d94bcbd8 100644 --- a/clang/include/clang/AST/ASTTypeTraits.h +++ b/clang/include/clang/AST/ASTTypeTraits.h @@ -18,6 +18,7 @@ #include "clang/AST/ASTFwd.h" #include "clang/AST/Decl.h" #include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/OpenMPClause.h" #include "clang/AST/Stmt.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/TypeLoc.h" @@ -58,6 +59,7 @@ public: static ASTNodeKind getFromNode(const Decl &D); static ASTNodeKind getFromNode(const Stmt &S); static ASTNodeKind getFromNode(const Type &T); + static ASTNodeKind getFromNode(const OMPClause &C); /// \} /// Returns \c true if \c this and \c Other represent the same kind. @@ -136,6 +138,9 @@ private: NKI_Type, #define TYPE(DERIVED, BASE) NKI_##DERIVED##Type, #include "clang/AST/TypeNodes.def" + NKI_OMPClause, +#define OPENMP_CLAUSE(TextualSpelling, Class) NKI_##Class, +#include "clang/Basic/OpenMPKinds.def" NKI_NumberOfKinds }; @@ -183,12 +188,15 @@ KIND_TO_KIND_ID(TypeLoc) KIND_TO_KIND_ID(Decl) KIND_TO_KIND_ID(Stmt) KIND_TO_KIND_ID(Type) +KIND_TO_KIND_ID(OMPClause) #define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl) #include "clang/AST/DeclNodes.inc" #define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED) #include "clang/AST/StmtNodes.inc" #define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type) #include "clang/AST/TypeNodes.def" +#define OPENMP_CLAUSE(TextualSpelling, Class) KIND_TO_KIND_ID(Class) +#include "clang/Basic/OpenMPKinds.def" #undef KIND_TO_KIND_ID inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) { @@ -459,6 +467,11 @@ struct DynTypedNode::BaseConverter< T, typename std::enable_if<std::is_base_of<Type, T>::value>::type> : public DynCastPtrConverter<T, Type> {}; +template <typename T> +struct DynTypedNode::BaseConverter< + T, typename std::enable_if<std::is_base_of<OMPClause, T>::value>::type> + : public DynCastPtrConverter<T, OMPClause> {}; + template <> struct DynTypedNode::BaseConverter< NestedNameSpecifier, void> : public PtrConverter<NestedNameSpecifier> {}; diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 08a039e0056..c88cfc00c0c 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -56,6 +56,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/OpenMPClause.h" #include "clang/AST/OperationKinds.h" #include "clang/AST/Stmt.h" #include "clang/AST/StmtCXX.h" @@ -6389,6 +6390,90 @@ AST_MATCHER(FunctionDecl, hasTrailingReturn) { extern const internal::VariadicDynCastAllOfMatcher<Stmt, OMPExecutableDirective> ompExecutableDirective; +/// Matches any clause in an OpenMP directive. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// #pragma omp parallel default(none) +/// \endcode +/// +/// ``ompExecutableDirective(hasAnyClause(anything()))`` matches +/// ``omp parallel default(none)``. +AST_MATCHER_P(OMPExecutableDirective, hasAnyClause, + internal::Matcher<OMPClause>, InnerMatcher) { + ArrayRef<OMPClause *> Clauses = Node.clauses(); + return matchesFirstInPointerRange(InnerMatcher, Clauses.begin(), + Clauses.end(), Finder, Builder); +} + +/// Matches OpenMP ``default`` clause. +/// +/// Given +/// +/// \code +/// #pragma omp parallel default(none) +/// #pragma omp parallel default(shared) +/// #pragma omp parallel +/// \endcode +/// +/// ``ompDefaultClause()`` matches ``default(none)`` and ``default(shared)``. +extern const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPDefaultClause> + ompDefaultClause; + +/// Matches if the OpenMP ``default`` clause has ``none`` kind specified. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// #pragma omp parallel default(none) +/// #pragma omp parallel default(shared) +/// \endcode +/// +/// ``ompDefaultClause(isNoneKind())`` matches only ``default(none)``. +AST_MATCHER(OMPDefaultClause, isNoneKind) { + return Node.getDefaultKind() == OMPC_DEFAULT_none; +} + +/// Matches if the OpenMP ``default`` clause has ``shared`` kind specified. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// #pragma omp parallel default(none) +/// #pragma omp parallel default(shared) +/// \endcode +/// +/// ``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``. +AST_MATCHER(OMPDefaultClause, isSharedKind) { + return Node.getDefaultKind() == OMPC_DEFAULT_shared; +} + +/// Matches if the OpenMP directive is allowed to contain the specified OpenMP +/// clause kind. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// #pragma omp parallel for +/// #pragma omp for +/// \endcode +/// +/// `ompExecutableDirective(isAllowedToContainClause(OMPC_default))`` matches +/// ``omp parallel`` and ``omp parallel for``. +/// +/// If the matcher is use from clang-query, ``OpenMPClauseKind`` parameter +/// should be passed as a quoted string. e.g., +/// ``isAllowedToContainClauseKind("OMPC_default").`` +AST_MATCHER_P(OMPExecutableDirective, isAllowedToContainClauseKind, + OpenMPClauseKind, CKind) { + return isAllowedClauseForDirective(Node.getDirectiveKind(), CKind); +} + //----------------------------------------------------------------------------// // End OpenMP handling. //----------------------------------------------------------------------------// diff --git a/clang/lib/AST/ASTTypeTraits.cpp b/clang/lib/AST/ASTTypeTraits.cpp index 11ab94033a7..dae9ab3a289 100644 --- a/clang/lib/AST/ASTTypeTraits.cpp +++ b/clang/lib/AST/ASTTypeTraits.cpp @@ -37,6 +37,9 @@ const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = { { NKI_None, "Type" }, #define TYPE(DERIVED, BASE) { NKI_##BASE, #DERIVED "Type" }, #include "clang/AST/TypeNodes.def" + { NKI_None, "OMPClause" }, +#define OPENMP_CLAUSE(TextualSpelling, Class) {NKI_OMPClause, #Class}, +#include "clang/Basic/OpenMPKinds.def" }; bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const { @@ -103,6 +106,20 @@ ASTNodeKind ASTNodeKind::getFromNode(const Type &T) { #include "clang/AST/TypeNodes.def" } llvm_unreachable("invalid type kind"); + } + +ASTNodeKind ASTNodeKind::getFromNode(const OMPClause &C) { + switch (C.getClauseKind()) { +#define OPENMP_CLAUSE(Name, Class) \ + case OMPC_##Name: return ASTNodeKind(NKI_##Class); +#include "clang/Basic/OpenMPKinds.def" + case OMPC_allocate: + case OMPC_threadprivate: + case OMPC_uniform: + case OMPC_unknown: + llvm_unreachable("unexpected OpenMP clause kind"); + } + llvm_unreachable("invalid stmt kind"); } void DynTypedNode::print(llvm::raw_ostream &OS, @@ -151,6 +168,8 @@ SourceRange DynTypedNode::getSourceRange() const { return D->getSourceRange(); if (const Stmt *S = get<Stmt>()) return S->getSourceRange(); + if (const auto *C = get<OMPClause>()) + return SourceRange(C->getBeginLoc(), C->getEndLoc()); return SourceRange(); } diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp index 654a6c28c05..a09ae3ad2e4 100644 --- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -847,6 +847,8 @@ AST_TYPELOC_TRAVERSE_MATCHER_DEF( const internal::VariadicDynCastAllOfMatcher<Stmt, OMPExecutableDirective> ompExecutableDirective; +const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPDefaultClause> + ompDefaultClause; } // end namespace ast_matchers } // end namespace clang diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/clang/lib/ASTMatchers/Dynamic/Marshallers.h index 812e5f909e1..fac2fc98e09 100644 --- a/clang/lib/ASTMatchers/Dynamic/Marshallers.h +++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.h @@ -26,6 +26,7 @@ #include "clang/ASTMatchers/Dynamic/VariantValue.h" #include "clang/Basic/AttrKinds.h" #include "clang/Basic/LLVM.h" +#include "clang/Basic/OpenMPKinds.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/None.h" #include "llvm/ADT/STLExtras.h" @@ -165,6 +166,28 @@ public: } }; +template <> struct ArgTypeTraits<OpenMPClauseKind> { +private: + static Optional<OpenMPClauseKind> getClauseKind(llvm::StringRef ClauseKind) { + return llvm::StringSwitch<Optional<OpenMPClauseKind>>(ClauseKind) +#define OPENMP_CLAUSE(TextualSpelling, Class) \ + .Case("OMPC_" #TextualSpelling, OMPC_##TextualSpelling) +#include "clang/Basic/OpenMPKinds.def" + .Default(llvm::None); + } + +public: + static bool is(const VariantValue &Value) { + return Value.isString() && getClauseKind(Value.getString()); + } + + static OpenMPClauseKind get(const VariantValue &Value) { + return *getClauseKind(Value.getString()); + } + + static ArgKind getKind() { return ArgKind(ArgKind::AK_String); } +}; + /// Matcher descriptor interface. /// /// Provides a \c create() method that constructs the matcher from the provided diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp index 4982721b4e9..2dabd021b28 100644 --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -233,6 +233,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(has); REGISTER_MATCHER(hasAncestor); REGISTER_MATCHER(hasAnyArgument); + REGISTER_MATCHER(hasAnyClause); REGISTER_MATCHER(hasAnyConstructorInitializer); REGISTER_MATCHER(hasAnyDeclaration); REGISTER_MATCHER(hasAnyName); @@ -331,6 +332,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(injectedClassNameType); REGISTER_MATCHER(innerType); REGISTER_MATCHER(integerLiteral); + REGISTER_MATCHER(isAllowedToContainClauseKind); REGISTER_MATCHER(isAnonymous); REGISTER_MATCHER(isAnyCharacter); REGISTER_MATCHER(isAnyPointer); @@ -376,12 +378,14 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(isMoveConstructor); REGISTER_MATCHER(isNoReturn); REGISTER_MATCHER(isNoThrow); + REGISTER_MATCHER(isNoneKind); REGISTER_MATCHER(isOverride); REGISTER_MATCHER(isPrivate); REGISTER_MATCHER(isProtected); REGISTER_MATCHER(isPublic); REGISTER_MATCHER(isPure); REGISTER_MATCHER(isScoped); + REGISTER_MATCHER(isSharedKind); REGISTER_MATCHER(isSignedInteger); REGISTER_MATCHER(isStaticLocal); REGISTER_MATCHER(isStaticStorageClass); @@ -434,6 +438,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(objcThrowStmt); REGISTER_MATCHER(objcTryStmt); REGISTER_MATCHER(ofClass); + REGISTER_MATCHER(ompDefaultClause); REGISTER_MATCHER(ompExecutableDirective); REGISTER_MATCHER(on); REGISTER_MATCHER(onImplicitObjectArgument); diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp index a7e3d5082ea..1802eba2e18 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -2274,5 +2274,173 @@ TEST(Matcher, isMain) { notMatches("int main2() {}", functionDecl(isMain()))); } +TEST(OMPExecutableDirective, hasClause) { + auto Matcher = ompExecutableDirective(hasAnyClause(anything())); + + const std::string Source0 = R"( +void x() { +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher)); + + const std::string Source1 = R"( +void x() { +#pragma omp parallel +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher)); + + const std::string Source2 = R"( +void x() { +#pragma omp parallel default(none) +; +})"; + EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher)); + + const std::string Source3 = R"( +void x() { +#pragma omp parallel default(shared) +; +})"; + EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher)); + + const std::string Source4 = R"( +void x(int x) { +#pragma omp parallel num_threads(x) +; +})"; + EXPECT_TRUE(matchesWithOpenMP(Source4, Matcher)); +} + +TEST(OMPDefaultClause, isNoneKind) { + auto Matcher = + ompExecutableDirective(hasAnyClause(ompDefaultClause(isNoneKind()))); + + const std::string Source0 = R"( +void x() { +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher)); + + const std::string Source1 = R"( +void x() { +#pragma omp parallel +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher)); + + const std::string Source2 = R"( +void x() { +#pragma omp parallel default(none) +; +})"; + EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher)); + + const std::string Source3 = R"( +void x() { +#pragma omp parallel default(shared) +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher)); + + const std::string Source4 = R"( +void x(int x) { +#pragma omp parallel num_threads(x) +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source4, Matcher)); +} + +TEST(OMPDefaultClause, isSharedKind) { + auto Matcher = + ompExecutableDirective(hasAnyClause(ompDefaultClause(isSharedKind()))); + + const std::string Source0 = R"( +void x() { +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher)); + + const std::string Source1 = R"( +void x() { +#pragma omp parallel +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher)); + + const std::string Source2 = R"( +void x() { +#pragma omp parallel default(shared) +; +})"; + EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher)); + + const std::string Source3 = R"( +void x() { +#pragma omp parallel default(none) +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher)); + + const std::string Source4 = R"( +void x(int x) { +#pragma omp parallel num_threads(x) +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source4, Matcher)); +} + +TEST(OMPExecutableDirective, isAllowedToContainClauseKind) { + auto Matcher = + ompExecutableDirective(isAllowedToContainClauseKind(OMPC_default)); + + const std::string Source0 = R"( +void x() { +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher)); + + const std::string Source1 = R"( +void x() { +#pragma omp parallel +; +})"; + EXPECT_TRUE(matchesWithOpenMP(Source1, Matcher)); + + const std::string Source2 = R"( +void x() { +#pragma omp parallel default(none) +; +})"; + EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher)); + + const std::string Source3 = R"( +void x() { +#pragma omp parallel default(shared) +; +})"; + EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher)); + + const std::string Source4 = R"( +void x(int x) { +#pragma omp parallel num_threads(x) +; +})"; + EXPECT_TRUE(matchesWithOpenMP(Source4, Matcher)); + + const std::string Source5 = R"( +void x() { +#pragma omp taskyield +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source5, Matcher)); + + const std::string Source6 = R"( +void x() { +#pragma omp task +; +})"; + EXPECT_TRUE(matchesWithOpenMP(Source6, Matcher)); +} + } // namespace ast_matchers } // namespace clang diff --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp index 4bce409cab4..16e682aeff1 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp @@ -1789,5 +1789,43 @@ void x() { EXPECT_TRUE(notMatchesWithOpenMP(Source2, Matcher)); } +TEST(OMPDefaultClause, Matches) { + auto Matcher = ompExecutableDirective(hasAnyClause(ompDefaultClause())); + + const std::string Source0 = R"( +void x() { +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher)); + + const std::string Source1 = R"( +void x() { +#pragma omp parallel +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher)); + + const std::string Source2 = R"( +void x() { +#pragma omp parallel default(none) +; +})"; + EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher)); + + const std::string Source3 = R"( +void x() { +#pragma omp parallel default(shared) +; +})"; + EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher)); + + const std::string Source4 = R"( +void x(int x) { +#pragma omp parallel num_threads(x) +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source4, Matcher)); +} + } // namespace ast_matchers } // namespace clang |