[OPENMP] Initial support for 'depend' clause (4.0).
Parsing and sema analysis (without support for array sections in arguments) for 'depend' clause (used in 'task' directive, OpenMP 4.0).
llvm-svn: 240409
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 4e45705..7c1746f 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -4248,6 +4248,7 @@
case OMPC_update:
case OMPC_capture:
case OMPC_seq_cst:
+ case OMPC_depend:
case OMPC_unknown:
llvm_unreachable("Clause is not allowed.");
}
@@ -4462,6 +4463,7 @@
case OMPC_update:
case OMPC_capture:
case OMPC_seq_cst:
+ case OMPC_depend:
case OMPC_unknown:
llvm_unreachable("Clause is not allowed.");
}
@@ -4582,6 +4584,7 @@
case OMPC_update:
case OMPC_capture:
case OMPC_seq_cst:
+ case OMPC_depend:
case OMPC_unknown:
llvm_unreachable("Clause is not allowed.");
}
@@ -4704,6 +4707,7 @@
case OMPC_proc_bind:
case OMPC_threadprivate:
case OMPC_flush:
+ case OMPC_depend:
case OMPC_unknown:
llvm_unreachable("Clause is not allowed.");
}
@@ -4760,7 +4764,8 @@
OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
- const DeclarationNameInfo &ReductionId) {
+ const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
+ SourceLocation DepLoc) {
OMPClause *Res = nullptr;
switch (Kind) {
case OMPC_private:
@@ -4796,6 +4801,10 @@
case OMPC_flush:
Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
break;
+ case OMPC_depend:
+ Res = ActOnOpenMPDependClause(DepKind, DepLoc, ColonLoc, VarList, StartLoc,
+ LParenLoc, EndLoc);
+ break;
case OMPC_if:
case OMPC_final:
case OMPC_num_threads:
@@ -6346,3 +6355,66 @@
return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
}
+OMPClause *
+Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,
+ SourceLocation DepLoc, SourceLocation ColonLoc,
+ ArrayRef<Expr *> VarList, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc) {
+ if (DepKind == OMPC_DEPEND_unknown) {
+ std::string Values;
+ std::string Sep(", ");
+ for (unsigned i = 0; i < OMPC_DEPEND_unknown; ++i) {
+ Values += "'";
+ Values += getOpenMPSimpleClauseTypeName(OMPC_depend, i);
+ Values += "'";
+ switch (i) {
+ case OMPC_DEPEND_unknown - 2:
+ Values += " or ";
+ break;
+ case OMPC_DEPEND_unknown - 1:
+ break;
+ default:
+ Values += Sep;
+ break;
+ }
+ }
+ Diag(DepLoc, diag::err_omp_unexpected_clause_value)
+ << Values << getOpenMPClauseName(OMPC_depend);
+ return nullptr;
+ }
+ SmallVector<Expr *, 8> Vars;
+ for (auto &RefExpr : VarList) {
+ assert(RefExpr && "NULL expr in OpenMP shared clause.");
+ if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
+ // It will be analyzed later.
+ Vars.push_back(RefExpr);
+ continue;
+ }
+
+ SourceLocation ELoc = RefExpr->getExprLoc();
+ // OpenMP [2.11.1.1, Restrictions, p.3]
+ // A variable that is part of another variable (such as a field of a
+ // structure) but is not an array element or an array section cannot appear
+ // in a depend clause.
+ auto *SimpleExpr = RefExpr->IgnoreParenCasts();
+ DeclRefExpr *DE = dyn_cast<DeclRefExpr>(SimpleExpr);
+ ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
+ if (!RefExpr->IgnoreParenImpCasts()->isLValue() || (!ASE && !DE) ||
+ (DE && !isa<VarDecl>(DE->getDecl())) ||
+ (ASE && !ASE->getBase()->getType()->isAnyPointerType() &&
+ !ASE->getBase()->getType()->isArrayType())) {
+ Diag(ELoc, diag::err_omp_expected_var_name_or_array_item)
+ << RefExpr->getSourceRange();
+ continue;
+ }
+
+ Vars.push_back(RefExpr->IgnoreParenImpCasts());
+ }
+
+ if (Vars.empty())
+ return nullptr;
+
+ return OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, DepKind,
+ DepLoc, ColonLoc, Vars);
+}
+