RequiresDecls.push_back(RD);
}
+ /// Checks if the defined 'requires' directive has specified type of clause.
+ template <typename ClauseType>
+ bool hasRequiresDeclWithClause() {
+ return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
+ return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
+ return isa<ClauseType>(C);
+ });
+ });
+ }
+
/// Checks for a duplicate clause amongst previously declared requires
/// directives
bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
assert(Clauses.size() <= 1 && "Expected at most one clause.");
Expr *Allocator = nullptr;
if (Clauses.empty()) {
- if (LangOpts.OpenMPIsDevice)
+ if (LangOpts.OpenMPIsDevice &&
+ !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
targetDiag(Loc, diag::err_expected_allocator_clause);
} else {
Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
// RUN: %clang_cc1 -verify -fopenmp -triple x86_64-apple-darwin10.6.0 -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc -o %t-host.bc %s
// RUN: %clang_cc1 -verify -DDEVICE -fopenmp -triple nvptx64-nvidia-cuda -fopenmp-targets=nvptx64-nvidia-cuda -fsyntax-only %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc
-#ifndef DEVICE
+// RUN: %clang_cc1 -verify -DDEVICE -DREQUIRES -fopenmp -triple nvptx64-nvidia-cuda -fopenmp-targets=nvptx64-nvidia-cuda -fsyntax-only %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc
+#if !defined(DEVICE) || defined(REQUIRES)
// expected-no-diagnostics
#endif // DEVICE
#ifndef HEADER
#define HEADER
+#if defined(REQUIRES) && defined(DEVICE)
+#pragma omp requires dynamic_allocators
+#endif // REQUIRES && DEVICE
+
int bar() {
int res = 0;
-#ifdef DEVICE
+#if defined(DEVICE) && !defined(REQUIRES)
// expected-error@+2 {{expected an 'allocator' clause inside of the target region; provide an 'allocator' clause or use 'requires' directive with the 'dynamic_allocators' clause}}
-#endif // DEVICE
+#endif // DEVICE && !REQUIRES
#pragma omp allocate(res)
return 0;
}
#pragma omp allocate(a) allocator(omp_thread_mem_alloc)
a=2;
double b = 3;
-#ifdef DEVICE
+#if defined(DEVICE) && !defined(REQUIRES)
// expected-error@+2 {{expected an 'allocator' clause inside of the target region; provide an 'allocator' clause or use 'requires' directive with the 'dynamic_allocators' clause}}
-#endif // DEVICE
+#endif // DEVICE && !REQUIRES
#pragma omp allocate(b)
-#ifdef DEVICE
+#if defined(DEVICE) && !defined(REQUIRES)
// expected-note@+2 {{called by 'main'}}
-#endif // DEVICE
+#endif // DEVICE && !REQUIRES
return (foo<int>() + bar());
}