Skip to content

Commit

Permalink
[ASTTypeTraits][ASTMatchers][OpenMP] OMPClause handling
Browse files Browse the repository at this point in the history
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
  • Loading branch information
LebedevRI committed Mar 21, 2019
1 parent de0e4ae commit 33ef20e
Show file tree
Hide file tree
Showing 9 changed files with 424 additions and 0 deletions.
71 changes: 71 additions & 0 deletions clang/docs/LibASTMatchersReference.html
Expand Up @@ -645,6 +645,19 @@ <h2 id="decl-matchers">Node Matchers</h2>
</pre></td></tr>


<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPClause.html">OMPClause</a>&gt;</td><td class="name" onclick="toggle('ompDefaultClause0')"><a name="ompDefaultClause0Anchor">ompDefaultClause</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPDefaultClause.html">OMPDefaultClause</a>&gt;...</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&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;</td><td class="name" onclick="toggle('qualType0')"><a name="qualType0Anchor">qualType</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="qualType0"><pre>Matches QualTypes in the clang AST.
</pre></td></tr>
Expand Down Expand Up @@ -3439,6 +3452,51 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
</pre></td></tr>


<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPDefaultClause.html">OMPDefaultClause</a>&gt;</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&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPDefaultClause.html">OMPDefaultClause</a>&gt;</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&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPExecutableDirective.html">OMPExecutableDirective</a>&gt;</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&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>&gt;</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).
Expand Down Expand Up @@ -6163,6 +6221,19 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
</pre></td></tr>


<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPExecutableDirective.html">OMPExecutableDirective</a>&gt;</td><td class="name" onclick="toggle('hasAnyClause0')"><a name="hasAnyClause0Anchor">hasAnyClause</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPClause.html">OMPClause</a>&gt; 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&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>&gt;</td><td class="name" onclick="toggle('hasAnyArgument3')"><a name="hasAnyArgument3Anchor">hasAnyArgument</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; 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.
Expand Down
13 changes: 13 additions & 0 deletions clang/include/clang/AST/ASTTypeTraits.h
Expand Up @@ -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"
Expand Down Expand Up @@ -58,6 +59,7 @@ class ASTNodeKind {
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.
Expand Down Expand Up @@ -136,6 +138,9 @@ class ASTNodeKind {
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
};

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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> {};
Expand Down
85 changes: 85 additions & 0 deletions clang/include/clang/ASTMatchers/ASTMatchers.h
Expand Up @@ -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"
Expand Down Expand Up @@ -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.
//----------------------------------------------------------------------------//
Expand Down
19 changes: 19 additions & 0 deletions clang/lib/AST/ASTTypeTraits.cpp
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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();
}

Expand Down
2 changes: 2 additions & 0 deletions clang/lib/ASTMatchers/ASTMatchersInternal.cpp
Expand Up @@ -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
23 changes: 23 additions & 0 deletions clang/lib/ASTMatchers/Dynamic/Marshallers.h
Expand Up @@ -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"
Expand Down Expand Up @@ -165,6 +166,28 @@ template <> struct ArgTypeTraits<CastKind> {
}
};

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
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/ASTMatchers/Dynamic/Registry.cpp
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 33ef20e

Please sign in to comment.