[Clang][Unittest] Support for target update directive and from clause in clang unittests (#150580)
Added support for detecting `OMPTargetUpdateDirective` , `OMPFromClause` and `OMPToClause` in Clang Unit Test Framework
This commit is contained in:
parent
324888bdb6
commit
f369d23cea
@ -8766,6 +8766,21 @@ AST_MATCHER_P(OMPExecutableDirective, hasAnyClause,
|
||||
Builder) != Clauses.end();
|
||||
}
|
||||
|
||||
/// Matches any ``#pragma omp target update`` executable directive.
|
||||
///
|
||||
/// Given
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp target update from(a)
|
||||
/// #pragma omp target update to(b)
|
||||
/// \endcode
|
||||
///
|
||||
/// ``ompTargetUpdateDirective()`` matches both ``omp target update from(a)``
|
||||
/// and ``omp target update to(b)``.
|
||||
extern const internal::VariadicDynCastAllOfMatcher<Stmt,
|
||||
OMPTargetUpdateDirective>
|
||||
ompTargetUpdateDirective;
|
||||
|
||||
/// Matches OpenMP ``default`` clause.
|
||||
///
|
||||
/// Given
|
||||
@ -8879,6 +8894,30 @@ AST_MATCHER_P(OMPExecutableDirective, isAllowedToContainClauseKind,
|
||||
Finder->getASTContext().getLangOpts().OpenMP);
|
||||
}
|
||||
|
||||
/// Matches OpenMP ``from`` clause.
|
||||
///
|
||||
/// Given
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp target update from(a)
|
||||
/// \endcode
|
||||
///
|
||||
/// ``ompFromClause()`` matches ``from(a)``.
|
||||
extern const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPFromClause>
|
||||
ompFromClause;
|
||||
|
||||
/// Matches OpenMP ``to`` clause.
|
||||
///
|
||||
/// Given
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp target update to(a)
|
||||
/// \endcode
|
||||
///
|
||||
/// ``ompToClause()`` matches ``to(a)``.
|
||||
extern const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPToClause>
|
||||
ompToClause;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// End OpenMP handling.
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
@ -1136,8 +1136,13 @@ AST_TYPELOC_TRAVERSE_MATCHER_DEF(
|
||||
|
||||
const internal::VariadicDynCastAllOfMatcher<Stmt, OMPExecutableDirective>
|
||||
ompExecutableDirective;
|
||||
const internal::VariadicDynCastAllOfMatcher<Stmt, OMPTargetUpdateDirective>
|
||||
ompTargetUpdateDirective;
|
||||
const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPDefaultClause>
|
||||
ompDefaultClause;
|
||||
const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPFromClause>
|
||||
ompFromClause;
|
||||
const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPToClause> ompToClause;
|
||||
const internal::VariadicDynCastAllOfMatcher<Decl, CXXDeductionGuideDecl>
|
||||
cxxDeductionGuideDecl;
|
||||
|
||||
|
||||
@ -530,7 +530,10 @@ RegistryMaps::RegistryMaps() {
|
||||
REGISTER_MATCHER(ofClass);
|
||||
REGISTER_MATCHER(ofKind);
|
||||
REGISTER_MATCHER(ompDefaultClause);
|
||||
REGISTER_MATCHER(ompFromClause);
|
||||
REGISTER_MATCHER(ompToClause);
|
||||
REGISTER_MATCHER(ompExecutableDirective);
|
||||
REGISTER_MATCHER(ompTargetUpdateDirective);
|
||||
REGISTER_MATCHER(on);
|
||||
REGISTER_MATCHER(onImplicitObjectArgument);
|
||||
REGISTER_MATCHER(opaqueValueExpr);
|
||||
|
||||
@ -4770,6 +4770,400 @@ void x() {
|
||||
EXPECT_TRUE(matchesWithOpenMP(Source8, Matcher));
|
||||
}
|
||||
|
||||
TEST_P(ASTMatchersTest, OMPTargetUpdateDirective_From_IsStandaloneDirective) {
|
||||
auto Matcher = ompTargetUpdateDirective(isStandaloneDirective());
|
||||
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target update from(arr[0:8:2])
|
||||
;
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(matchesWithOpenMP(Source0, Matcher));
|
||||
}
|
||||
|
||||
TEST_P(ASTMatchersTest, OMPTargetUpdateDirective_To_IsStandaloneDirective) {
|
||||
auto Matcher = ompTargetUpdateDirective(isStandaloneDirective());
|
||||
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target update to(arr[0:8:2])
|
||||
;
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(matchesWithOpenMP(Source0, Matcher));
|
||||
}
|
||||
|
||||
TEST_P(ASTMatchersTest, OMPTargetUpdateDirective_From_HasStructuredBlock) {
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target update from(arr[0:8:2])
|
||||
;
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(notMatchesWithOpenMP(
|
||||
Source0, ompTargetUpdateDirective(hasStructuredBlock(nullStmt()))));
|
||||
}
|
||||
|
||||
TEST_P(ASTMatchersTest, OMPTargetUpdateDirective_To_HasStructuredBlock) {
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target update to(arr[0:8:2])
|
||||
;
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(notMatchesWithOpenMP(
|
||||
Source0, ompTargetUpdateDirective(hasStructuredBlock(nullStmt()))));
|
||||
}
|
||||
|
||||
TEST_P(ASTMatchersTest, OMPTargetUpdateDirective_From_HasClause) {
|
||||
auto Matcher = ompTargetUpdateDirective(hasAnyClause(ompFromClause()));
|
||||
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target update from(arr[0:8:2])
|
||||
;
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(matchesWithOpenMP(Source0, Matcher));
|
||||
|
||||
auto astUnit = tooling::buildASTFromCodeWithArgs(Source0, {"-fopenmp"});
|
||||
ASSERT_TRUE(astUnit);
|
||||
|
||||
auto Results = match(ompTargetUpdateDirective().bind("directive"),
|
||||
astUnit->getASTContext());
|
||||
ASSERT_FALSE(Results.empty());
|
||||
|
||||
const auto *Directive =
|
||||
Results[0].getNodeAs<OMPTargetUpdateDirective>("directive");
|
||||
ASSERT_TRUE(Directive);
|
||||
|
||||
OMPFromClause *FromClause = nullptr;
|
||||
for (auto *Clause : Directive->clauses()) {
|
||||
if ((FromClause = dyn_cast<OMPFromClause>(Clause))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_TRUE(FromClause);
|
||||
|
||||
for (const auto *VarExpr : FromClause->varlist()) {
|
||||
const auto *ArraySection = dyn_cast<ArraySectionExpr>(VarExpr);
|
||||
if (!ArraySection)
|
||||
continue;
|
||||
// base (arr)
|
||||
const Expr *Base = ArraySection->getBase();
|
||||
ASSERT_TRUE(Base);
|
||||
|
||||
// lower bound (0)
|
||||
const Expr *LowerBound = ArraySection->getLowerBound();
|
||||
ASSERT_TRUE(LowerBound);
|
||||
const auto *LowerBoundLiteral = dyn_cast<IntegerLiteral>(LowerBound);
|
||||
ASSERT_TRUE(LowerBoundLiteral)
|
||||
<< "Expected lower bound to be an integer literal";
|
||||
EXPECT_EQ(LowerBoundLiteral->getValue().getZExtValue(), 0u);
|
||||
|
||||
// length (8)
|
||||
const Expr *Length = ArraySection->getLength();
|
||||
ASSERT_TRUE(Length);
|
||||
const auto *LengthLiteral = dyn_cast<IntegerLiteral>(Length);
|
||||
ASSERT_TRUE(LengthLiteral) << "Expected length to be an integer literal";
|
||||
EXPECT_EQ(LengthLiteral->getValue().getZExtValue(), 8u);
|
||||
|
||||
// stride (2)
|
||||
const Expr *Stride = ArraySection->getStride();
|
||||
ASSERT_TRUE(Stride);
|
||||
const auto *StrideLiteral = dyn_cast<IntegerLiteral>(Stride);
|
||||
ASSERT_TRUE(StrideLiteral) << "Expected stride to be an integer literal";
|
||||
EXPECT_EQ(StrideLiteral->getValue().getZExtValue(), 2u);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(ASTMatchersTest, OMPTargetUpdateDirective_From_ArraySection_NoStride) {
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[20];
|
||||
#pragma omp target update from(arr[2:10])
|
||||
;
|
||||
}
|
||||
)";
|
||||
|
||||
auto astUnit = tooling::buildASTFromCodeWithArgs(Source0, {"-fopenmp"});
|
||||
ASSERT_TRUE(astUnit);
|
||||
|
||||
auto Results = match(ompTargetUpdateDirective().bind("directive"),
|
||||
astUnit->getASTContext());
|
||||
ASSERT_FALSE(Results.empty());
|
||||
|
||||
const auto *Directive =
|
||||
Results[0].getNodeAs<OMPTargetUpdateDirective>("directive");
|
||||
ASSERT_TRUE(Directive);
|
||||
|
||||
OMPFromClause *FromClause = nullptr;
|
||||
for (auto *Clause : Directive->clauses()) {
|
||||
if ((FromClause = dyn_cast<OMPFromClause>(Clause))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_TRUE(FromClause);
|
||||
|
||||
for (const auto *VarExpr : FromClause->varlist()) {
|
||||
const auto *ArraySection = dyn_cast<ArraySectionExpr>(VarExpr);
|
||||
if (!ArraySection)
|
||||
continue;
|
||||
|
||||
const Expr *LowerBound = ArraySection->getLowerBound();
|
||||
ASSERT_TRUE(LowerBound);
|
||||
const auto *LowerBoundLiteral = dyn_cast<IntegerLiteral>(LowerBound);
|
||||
ASSERT_TRUE(LowerBoundLiteral)
|
||||
<< "Expected lower bound to be an integer literal";
|
||||
EXPECT_EQ(LowerBoundLiteral->getValue().getZExtValue(), 2u);
|
||||
|
||||
const Expr *Length = ArraySection->getLength();
|
||||
ASSERT_TRUE(Length);
|
||||
const auto *LengthLiteral = dyn_cast<IntegerLiteral>(Length);
|
||||
ASSERT_TRUE(LengthLiteral) << "Expected length to be an integer literal";
|
||||
EXPECT_EQ(LengthLiteral->getValue().getZExtValue(), 10u);
|
||||
|
||||
// Stride is optional (defaults to 1 when omitted)
|
||||
const Expr *Stride = ArraySection->getStride();
|
||||
if (Stride) {
|
||||
const auto *StrideLiteral = dyn_cast<IntegerLiteral>(Stride);
|
||||
ASSERT_TRUE(StrideLiteral) << "Expected stride to be an integer literal";
|
||||
EXPECT_EQ(StrideLiteral->getValue().getZExtValue(), 1u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(ASTMatchersTest, OMPTargetUpdateDirective_To_HasClause) {
|
||||
auto Matcher = ompTargetUpdateDirective(hasAnyClause(ompToClause()));
|
||||
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target update to(arr[0:8:2])
|
||||
;
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(matchesWithOpenMP(Source0, Matcher));
|
||||
|
||||
auto astUnit = tooling::buildASTFromCodeWithArgs(Source0, {"-fopenmp"});
|
||||
ASSERT_TRUE(astUnit);
|
||||
|
||||
auto Results = match(ompTargetUpdateDirective().bind("directive"),
|
||||
astUnit->getASTContext());
|
||||
ASSERT_FALSE(Results.empty());
|
||||
|
||||
const auto *Directive =
|
||||
Results[0].getNodeAs<OMPTargetUpdateDirective>("directive");
|
||||
ASSERT_TRUE(Directive);
|
||||
|
||||
OMPToClause *ToClause = nullptr;
|
||||
for (auto *Clause : Directive->clauses()) {
|
||||
if ((ToClause = dyn_cast<OMPToClause>(Clause))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_TRUE(ToClause);
|
||||
|
||||
for (const auto *VarExpr : ToClause->varlist()) {
|
||||
const auto *ArraySection = dyn_cast<ArraySectionExpr>(VarExpr);
|
||||
if (!ArraySection)
|
||||
continue;
|
||||
|
||||
const Expr *Base = ArraySection->getBase();
|
||||
ASSERT_TRUE(Base);
|
||||
|
||||
const Expr *LowerBound = ArraySection->getLowerBound();
|
||||
ASSERT_TRUE(LowerBound);
|
||||
const auto *LowerBoundLiteral = dyn_cast<IntegerLiteral>(LowerBound);
|
||||
ASSERT_TRUE(LowerBoundLiteral)
|
||||
<< "Expected lower bound to be an integer literal";
|
||||
EXPECT_EQ(LowerBoundLiteral->getValue().getZExtValue(), 0u);
|
||||
|
||||
const Expr *Length = ArraySection->getLength();
|
||||
ASSERT_TRUE(Length);
|
||||
const auto *LengthLiteral = dyn_cast<IntegerLiteral>(Length);
|
||||
ASSERT_TRUE(LengthLiteral) << "Expected length to be an integer literal";
|
||||
EXPECT_EQ(LengthLiteral->getValue().getZExtValue(), 8u);
|
||||
|
||||
const Expr *Stride = ArraySection->getStride();
|
||||
ASSERT_TRUE(Stride);
|
||||
const auto *StrideLiteral = dyn_cast<IntegerLiteral>(Stride);
|
||||
ASSERT_TRUE(StrideLiteral) << "Expected stride to be an integer literal";
|
||||
EXPECT_EQ(StrideLiteral->getValue().getZExtValue(), 2u);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(ASTMatchersTest, OMPTargetUpdateDirective_To_ArraySection_NoStride) {
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[20];
|
||||
#pragma omp target update to(arr[1:15])
|
||||
;
|
||||
}
|
||||
)";
|
||||
|
||||
auto astUnit = tooling::buildASTFromCodeWithArgs(Source0, {"-fopenmp"});
|
||||
ASSERT_TRUE(astUnit);
|
||||
|
||||
auto Results = match(ompTargetUpdateDirective().bind("directive"),
|
||||
astUnit->getASTContext());
|
||||
ASSERT_FALSE(Results.empty());
|
||||
|
||||
const auto *Directive =
|
||||
Results[0].getNodeAs<OMPTargetUpdateDirective>("directive");
|
||||
ASSERT_TRUE(Directive);
|
||||
|
||||
OMPToClause *ToClause = nullptr;
|
||||
for (auto *Clause : Directive->clauses()) {
|
||||
if ((ToClause = dyn_cast<OMPToClause>(Clause))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_TRUE(ToClause);
|
||||
|
||||
for (const auto *VarExpr : ToClause->varlist()) {
|
||||
const auto *ArraySection = dyn_cast<ArraySectionExpr>(VarExpr);
|
||||
if (!ArraySection)
|
||||
continue;
|
||||
|
||||
const Expr *LowerBound = ArraySection->getLowerBound();
|
||||
ASSERT_TRUE(LowerBound);
|
||||
const auto *LowerBoundLiteral = dyn_cast<IntegerLiteral>(LowerBound);
|
||||
ASSERT_TRUE(LowerBoundLiteral)
|
||||
<< "Expected lower bound to be an integer literal";
|
||||
EXPECT_EQ(LowerBoundLiteral->getValue().getZExtValue(), 1u);
|
||||
|
||||
const Expr *Length = ArraySection->getLength();
|
||||
ASSERT_TRUE(Length);
|
||||
const auto *LengthLiteral = dyn_cast<IntegerLiteral>(Length);
|
||||
ASSERT_TRUE(LengthLiteral) << "Expected length to be an integer literal";
|
||||
EXPECT_EQ(LengthLiteral->getValue().getZExtValue(), 15u);
|
||||
|
||||
// Stride is optional (defaults to 1 when omitted)
|
||||
const Expr *Stride = ArraySection->getStride();
|
||||
if (Stride) {
|
||||
const auto *StrideLiteral = dyn_cast<IntegerLiteral>(Stride);
|
||||
ASSERT_TRUE(StrideLiteral) << "Expected stride to be an integer literal";
|
||||
EXPECT_EQ(StrideLiteral->getValue().getZExtValue(), 1u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(ASTMatchersTest,
|
||||
OMPTargetUpdateDirective_IsAllowedToContainClauseKind_From) {
|
||||
auto Matcher = ompTargetUpdateDirective(
|
||||
isAllowedToContainClauseKind(llvm::omp::OMPC_from));
|
||||
|
||||
StringRef Source0 = R"(
|
||||
void x() {
|
||||
;
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
|
||||
|
||||
StringRef Source1 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target update from(arr[0:8:2])
|
||||
;
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(matchesWithOpenMP(Source1, Matcher));
|
||||
}
|
||||
|
||||
TEST_P(ASTMatchersTest,
|
||||
OMPTargetUpdateDirective_IsAllowedToContainClauseKind_To) {
|
||||
auto Matcher = ompTargetUpdateDirective(
|
||||
isAllowedToContainClauseKind(llvm::omp::OMPC_to));
|
||||
|
||||
StringRef Source0 = R"(
|
||||
void x() {
|
||||
;
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
|
||||
|
||||
StringRef Source1 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target update to(arr[0:8:2])
|
||||
;
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(matchesWithOpenMP(Source1, Matcher));
|
||||
}
|
||||
|
||||
TEST_P(ASTMatchersTest, OMPFromClause_DoesNotMatchToClause) {
|
||||
auto Matcher = ompTargetUpdateDirective(hasAnyClause(ompFromClause()));
|
||||
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target update to(arr[0:8:2])
|
||||
;
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
|
||||
}
|
||||
|
||||
TEST_P(ASTMatchersTest, OMPToClause_DoesNotMatchFromClause) {
|
||||
auto Matcher = ompTargetUpdateDirective(hasAnyClause(ompToClause()));
|
||||
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target update from(arr[0:8:2])
|
||||
;
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
|
||||
}
|
||||
|
||||
TEST_P(ASTMatchersTest, OMPTargetUpdateDirective_DoesNotMatchTarget) {
|
||||
auto Matcher = ompTargetUpdateDirective();
|
||||
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target map(tofrom:arr)
|
||||
{ arr[0] = 1; }
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
|
||||
}
|
||||
|
||||
TEST_P(ASTMatchersTest, OMPTargetUpdateDirective_DoesNotMatchTargetData) {
|
||||
auto Matcher = ompTargetUpdateDirective();
|
||||
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target data map(to:arr)
|
||||
{ }
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
|
||||
}
|
||||
|
||||
TEST_P(ASTMatchersTest, OMPFromClause_DoesNotMatchMapClause) {
|
||||
auto Matcher = ompExecutableDirective(hasAnyClause(ompFromClause()));
|
||||
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target map(from:arr)
|
||||
{ }
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
|
||||
}
|
||||
|
||||
TEST_P(ASTMatchersTest, HasAnyBase_DirectBase) {
|
||||
if (!GetParam().isCXX()) {
|
||||
return;
|
||||
|
||||
@ -2791,6 +2791,225 @@ void x() {
|
||||
EXPECT_TRUE(notMatchesWithOpenMP(Source2, Matcher));
|
||||
}
|
||||
|
||||
TEST(ASTMatchersTestOpenMP, OMPTargetUpdateDirective_From) {
|
||||
auto Matcher = stmt(ompTargetUpdateDirective());
|
||||
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target update from(arr[0:8:2])
|
||||
;
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(matchesWithOpenMP(Source0, Matcher));
|
||||
}
|
||||
|
||||
TEST(ASTMatchersTestOpenMP, OMPTargetUpdateDirective_To) {
|
||||
auto Matcher = stmt(ompTargetUpdateDirective());
|
||||
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target update to(arr[0:8:2])
|
||||
;
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(matchesWithOpenMP(Source0, Matcher));
|
||||
}
|
||||
|
||||
TEST(ASTMatchersTestOpenMP, OMPFromClause) {
|
||||
auto Matcher = ompTargetUpdateDirective(hasAnyClause(ompFromClause()));
|
||||
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target update from(arr[0:8:2])
|
||||
;
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(matchesWithOpenMP(Source0, Matcher));
|
||||
|
||||
auto astUnit = tooling::buildASTFromCodeWithArgs(Source0, {"-fopenmp"});
|
||||
ASSERT_TRUE(astUnit);
|
||||
|
||||
auto Results = match(ompTargetUpdateDirective().bind("directive"),
|
||||
astUnit->getASTContext());
|
||||
ASSERT_FALSE(Results.empty());
|
||||
|
||||
const auto *Directive =
|
||||
Results[0].getNodeAs<OMPTargetUpdateDirective>("directive");
|
||||
ASSERT_TRUE(Directive);
|
||||
|
||||
OMPFromClause *FromClause = nullptr;
|
||||
for (auto *Clause : Directive->clauses()) {
|
||||
if ((FromClause = dyn_cast<OMPFromClause>(Clause))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_TRUE(FromClause);
|
||||
|
||||
for (const auto *VarExpr : FromClause->varlist()) {
|
||||
const auto *ArraySection = dyn_cast<ArraySectionExpr>(VarExpr);
|
||||
if (!ArraySection)
|
||||
continue;
|
||||
|
||||
// base (arr)
|
||||
const Expr *Base = ArraySection->getBase();
|
||||
ASSERT_TRUE(Base);
|
||||
|
||||
// lower bound (0)
|
||||
const Expr *LowerBound = ArraySection->getLowerBound();
|
||||
ASSERT_TRUE(LowerBound);
|
||||
const auto *LowerBoundLiteral = dyn_cast<IntegerLiteral>(LowerBound);
|
||||
ASSERT_TRUE(LowerBoundLiteral)
|
||||
<< "Expected lower bound to be an integer literal";
|
||||
EXPECT_EQ(LowerBoundLiteral->getValue().getZExtValue(), 0u);
|
||||
|
||||
// length (8)
|
||||
const Expr *Length = ArraySection->getLength();
|
||||
ASSERT_TRUE(Length);
|
||||
const auto *LengthLiteral = dyn_cast<IntegerLiteral>(Length);
|
||||
ASSERT_TRUE(LengthLiteral) << "Expected length to be an integer literal";
|
||||
EXPECT_EQ(LengthLiteral->getValue().getZExtValue(), 8u);
|
||||
|
||||
// stride (2)
|
||||
const Expr *Stride = ArraySection->getStride();
|
||||
ASSERT_TRUE(Stride);
|
||||
const auto *StrideLiteral = dyn_cast<IntegerLiteral>(Stride);
|
||||
ASSERT_TRUE(StrideLiteral) << "Expected stride to be an integer literal";
|
||||
EXPECT_EQ(StrideLiteral->getValue().getZExtValue(), 2u);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ASTMatchersTestOpenMP, OMPToClause) {
|
||||
auto Matcher = ompTargetUpdateDirective(hasAnyClause(ompToClause()));
|
||||
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target update to(arr[0:8:2])
|
||||
;
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(matchesWithOpenMP(Source0, Matcher));
|
||||
|
||||
auto astUnit = tooling::buildASTFromCodeWithArgs(Source0, {"-fopenmp"});
|
||||
ASSERT_TRUE(astUnit);
|
||||
|
||||
auto Results = match(ompTargetUpdateDirective().bind("directive"),
|
||||
astUnit->getASTContext());
|
||||
ASSERT_FALSE(Results.empty());
|
||||
|
||||
const auto *Directive =
|
||||
Results[0].getNodeAs<OMPTargetUpdateDirective>("directive");
|
||||
ASSERT_TRUE(Directive);
|
||||
|
||||
OMPToClause *ToClause = nullptr;
|
||||
for (auto *Clause : Directive->clauses()) {
|
||||
if ((ToClause = dyn_cast<OMPToClause>(Clause))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_TRUE(ToClause);
|
||||
|
||||
for (const auto *VarExpr : ToClause->varlist()) {
|
||||
const auto *ArraySection = dyn_cast<ArraySectionExpr>(VarExpr);
|
||||
if (!ArraySection)
|
||||
continue;
|
||||
|
||||
// base (arr)
|
||||
const Expr *Base = ArraySection->getBase();
|
||||
ASSERT_TRUE(Base);
|
||||
|
||||
// lower bound (0)
|
||||
const Expr *LowerBound = ArraySection->getLowerBound();
|
||||
ASSERT_TRUE(LowerBound);
|
||||
const auto *LowerBoundLiteral = dyn_cast<IntegerLiteral>(LowerBound);
|
||||
ASSERT_TRUE(LowerBoundLiteral)
|
||||
<< "Expected lower bound to be an integer literal";
|
||||
EXPECT_EQ(LowerBoundLiteral->getValue().getZExtValue(), 0u);
|
||||
|
||||
// length (8)
|
||||
const Expr *Length = ArraySection->getLength();
|
||||
ASSERT_TRUE(Length);
|
||||
const auto *LengthLiteral = dyn_cast<IntegerLiteral>(Length);
|
||||
ASSERT_TRUE(LengthLiteral) << "Expected length to be an integer literal";
|
||||
EXPECT_EQ(LengthLiteral->getValue().getZExtValue(), 8u);
|
||||
|
||||
// stride (2)
|
||||
const Expr *Stride = ArraySection->getStride();
|
||||
ASSERT_TRUE(Stride);
|
||||
const auto *StrideLiteral = dyn_cast<IntegerLiteral>(Stride);
|
||||
ASSERT_TRUE(StrideLiteral) << "Expected stride to be an integer literal";
|
||||
EXPECT_EQ(StrideLiteral->getValue().getZExtValue(), 2u);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ASTMatchersTestOpenMP, OMPFromClause_DoesNotMatchToClause) {
|
||||
auto Matcher = ompTargetUpdateDirective(hasAnyClause(ompFromClause()));
|
||||
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target update to(arr[0:8:2])
|
||||
;
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
|
||||
}
|
||||
|
||||
TEST(ASTMatchersTestOpenMP, OMPToClause_DoesNotMatchFromClause) {
|
||||
auto Matcher = ompTargetUpdateDirective(hasAnyClause(ompToClause()));
|
||||
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target update from(arr[0:8:2])
|
||||
;
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
|
||||
}
|
||||
|
||||
TEST(ASTMatchersTestOpenMP, OMPTargetUpdateDirective_DoesNotMatchTarget) {
|
||||
auto Matcher = ompTargetUpdateDirective();
|
||||
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target map(tofrom:arr)
|
||||
{ arr[0] = 1; }
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
|
||||
}
|
||||
|
||||
TEST(ASTMatchersTestOpenMP, OMPTargetUpdateDirective_DoesNotMatchTargetData) {
|
||||
auto Matcher = ompTargetUpdateDirective();
|
||||
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target data map(to:arr)
|
||||
{ }
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
|
||||
}
|
||||
|
||||
TEST(ASTMatchersTestOpenMP, OMPFromClause_DoesNotMatchMapClause) {
|
||||
auto Matcher = ompExecutableDirective(hasAnyClause(ompFromClause()));
|
||||
|
||||
StringRef Source0 = R"(
|
||||
void foo() {
|
||||
int arr[8];
|
||||
#pragma omp target map(from:arr)
|
||||
{ }
|
||||
}
|
||||
)";
|
||||
EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
|
||||
}
|
||||
|
||||
TEST(ASTMatchersTestOpenMP, OMPDefaultClause) {
|
||||
auto Matcher = ompExecutableDirective(hasAnyClause(ompDefaultClause()));
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user