diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2015-06-23 14:25:19 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2015-06-23 14:25:19 +0000 |
commit | 1c2cfbc3eac44ab3ec79bcdae56a23a17e5c9693 (patch) | |
tree | 2158e97e424dd441a8db2fcd5704f1d3ddec7fca /clang/lib/Sema | |
parent | 8c5f537f184a1e78d9a734cef3202382946a0108 (diff) | |
download | bcm5719-llvm-1c2cfbc3eac44ab3ec79bcdae56a23a17e5c9693.tar.gz bcm5719-llvm-1c2cfbc3eac44ab3ec79bcdae56a23a17e5c9693.zip |
[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
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 74 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 29 |
2 files changed, 102 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 4e45705ca1d..7c1746f90e2 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -4248,6 +4248,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 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 @@ OMPClause *Sema::ActOnOpenMPSimpleClause( 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 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 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 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 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 @@ OMPClause *Sema::ActOnOpenMPVarListClause( 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 @@ OMPClause *Sema::ActOnOpenMPVarListClause( 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 @@ OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 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); +} + diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 322cb6ccb58..996dd2b0783 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1551,6 +1551,19 @@ public: EndLoc); } + /// \brief Build a new OpenMP 'depend' pseudo clause. + /// + /// By default, performs semantic analysis to build the new OpenMP clause. + /// Subclasses may override this routine to provide different behavior. + OMPClause * + RebuildOMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, + SourceLocation ColonLoc, ArrayRef<Expr *> VarList, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) { + return getSema().ActOnOpenMPDependClause(DepKind, DepLoc, ColonLoc, VarList, + StartLoc, LParenLoc, EndLoc); + } + /// \brief Rebuild the operand to an Objective-C \@synchronized statement. /// /// By default, performs semantic analysis to build the new statement. @@ -7255,6 +7268,22 @@ OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) { C->getLParenLoc(), C->getLocEnd()); } +template <typename Derived> +OMPClause * +TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) { + llvm::SmallVector<Expr *, 16> Vars; + Vars.reserve(C->varlist_size()); + for (auto *VE : C->varlists()) { + ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); + if (EVar.isInvalid()) + return nullptr; + Vars.push_back(EVar.get()); + } + return getDerived().RebuildOMPDependClause( + C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(), Vars, + C->getLocStart(), C->getLParenLoc(), C->getLocEnd()); +} + //===----------------------------------------------------------------------===// // Expression transformation //===----------------------------------------------------------------------===// |