diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/StmtPrinter.cpp | 10 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGOpenMPRuntime.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Parse/ParseOpenMP.cpp | 35 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 81 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 5 |
5 files changed, 95 insertions, 37 deletions
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index ea9533ab5fe..fb63620deb9 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -873,14 +873,14 @@ void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) { } void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) { + OS << "depend("; + OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), + Node->getDependencyKind()); if (!Node->varlist_empty()) { - OS << "depend("; - OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), - Node->getDependencyKind()) - << " :"; + OS << " :"; VisitOMPClauseList(Node, ' '); - OS << ")"; } + OS << ")"; } void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) { diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 33dd853bb6d..98a83b661b5 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -2519,6 +2519,7 @@ void CGOpenMPRuntime::emitTaskCall( case OMPC_DEPEND_inout: DepKind = DepInOut; break; + case OMPC_DEPEND_source: case OMPC_DEPEND_unknown: llvm_unreachable("Unknown task dependence type"); } diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index bf190892a1d..b8948bf061e 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -215,7 +215,7 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) { case OMPD_cancel: if (!StandAloneAllowed) { Diag(Tok, diag::err_omp_immediate_directive) - << getOpenMPDirectiveName(DKind); + << getOpenMPDirectiveName(DKind) << 0; } HasAssociatedStatement = false; // Fall through for further analysis. @@ -295,6 +295,18 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) { // Consume final annot_pragma_openmp_end. ConsumeToken(); + // OpenMP [2.13.8, ordered Construct, Syntax] + // If the depend clause is specified, the ordered construct is a stand-alone + // directive. + if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) { + if (!StandAloneAllowed) { + Diag(Loc, diag::err_omp_immediate_directive) + << getOpenMPDirectiveName(DKind) << 1 + << getOpenMPClauseName(OMPC_depend); + } + HasAssociatedStatement = false; + } + StmtResult AssociatedStmt; if (HasAssociatedStatement) { // The body is a block scope like in Lambdas and Blocks. @@ -524,7 +536,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_flush: case OMPC_depend: case OMPC_map: - Clause = ParseOpenMPVarListClause(CKind); + Clause = ParseOpenMPVarListClause(DKind, CKind); break; case OMPC_unknown: Diag(Tok, diag::warn_omp_extra_tokens_at_eol) @@ -793,7 +805,7 @@ static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec, /// flush-clause: /// 'flush' '(' list ')' /// depend-clause: -/// 'depend' '(' in | out | inout : list ')' +/// 'depend' '(' in | out | inout : list | source ')' /// map-clause: /// 'map' '(' [ [ always , ] /// to | from | tofrom | alloc | release | delete ':' ] list ')'; @@ -802,7 +814,8 @@ static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec, /// list /// modifier(list) /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++). -OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) { +OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, + OpenMPClauseKind Kind) { SourceLocation Loc = Tok.getLocation(); SourceLocation LOpen = ConsumeToken(); SourceLocation ColonLoc = SourceLocation(); @@ -858,11 +871,23 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) { StopBeforeMatch); } else { ConsumeToken(); + // Special processing for depend(source) clause. + if (DKind == OMPD_ordered && DepKind == OMPC_DEPEND_source) { + // Parse ')'. + T.consumeClose(); + return Actions.ActOnOpenMPVarListClause( + Kind, llvm::None, /*TailExpr=*/nullptr, Loc, LOpen, + /*ColonLoc=*/SourceLocation(), Tok.getLocation(), + ReductionIdScopeSpec, DeclarationNameInfo(), DepKind, + LinearModifier, MapTypeModifier, MapType, DepLinMapLoc); + } } if (Tok.is(tok::colon)) { ColonLoc = ConsumeToken(); } else { - Diag(Tok, diag::warn_pragma_expected_colon) << "dependency type"; + Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren + : diag::warn_pragma_expected_colon) + << "dependency type"; } } else if (Kind == OMPC_linear) { // Try to parse modifier if any. diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 152c1183dae..83329350f28 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -4574,36 +4574,59 @@ StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - if (!AStmt) - return StmtError(); - - assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); - - getCurFunction()->setHasBranchProtectedScope(); - + OMPClause *DependFound = nullptr; + OMPClause *DependSourceClause = nullptr; + bool ErrorFound = false; OMPThreadsClause *TC = nullptr; OMPSIMDClause *SC = nullptr; - for (auto *C: Clauses) { - if (C->getClauseKind() == OMPC_threads) + for (auto *C : Clauses) { + if (auto *DC = dyn_cast<OMPDependClause>(C)) { + DependFound = C; + if (DC->getDependencyKind() == OMPC_DEPEND_source) { + if (DependSourceClause) { + Diag(C->getLocStart(), diag::err_omp_more_one_clause) + << getOpenMPDirectiveName(OMPD_ordered) + << getOpenMPClauseName(OMPC_depend) << 2; + ErrorFound = true; + } else + DependSourceClause = C; + } + } else if (C->getClauseKind() == OMPC_threads) TC = cast<OMPThreadsClause>(C); else if (C->getClauseKind() == OMPC_simd) SC = cast<OMPSIMDClause>(C); } - - // TODO: this must happen only if 'threads' clause specified or if no clauses - // is specified. - if (auto *Param = DSAStack->getParentOrderedRegionParam()) { - SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc; - Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) << (TC != nullptr); - Diag(Param->getLocStart(), diag::note_omp_ordered_param); - return StmtError(); - } - if (!SC && isOpenMPSimdDirective(DSAStack->getParentDirective())) { + if (!ErrorFound && !SC && + isOpenMPSimdDirective(DSAStack->getParentDirective())) { // OpenMP [2.8.1,simd Construct, Restrictions] // An ordered construct with the simd clause is the only OpenMP construct // that can appear in the simd region. Diag(StartLoc, diag::err_omp_prohibited_region_simd); + ErrorFound = true; + } else if (DependFound && (TC || SC)) { + Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd) + << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); + ErrorFound = true; + } else if (DependFound && !DSAStack->getParentOrderedRegionParam()) { + Diag(DependFound->getLocStart(), + diag::err_omp_ordered_directive_without_param); + ErrorFound = true; + } else if (TC || Clauses.empty()) { + if (auto *Param = DSAStack->getParentOrderedRegionParam()) { + SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc; + Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) + << (TC != nullptr); + Diag(Param->getLocStart(), diag::note_omp_ordered_param); + ErrorFound = true; + } + } + if ((!AStmt && !DependFound) || ErrorFound) return StmtError(); + + if (AStmt) { + assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); + + getCurFunction()->setHasBranchProtectedScope(); } return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); @@ -7966,18 +7989,30 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { - if (DepKind == OMPC_DEPEND_unknown) { + if (DSAStack->getCurrentDirective() == OMPD_ordered && + DepKind != OMPC_DEPEND_source) { + std::string Values = "'"; + Values += getOpenMPSimpleClauseTypeName(OMPC_depend, OMPC_DEPEND_source); + Values += "'"; + Diag(DepLoc, diag::err_omp_unexpected_clause_value) + << Values << getOpenMPClauseName(OMPC_depend); + return nullptr; + } + if (DSAStack->getCurrentDirective() != OMPD_ordered && + (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source)) { std::string Values; std::string Sep(", "); for (unsigned i = 0; i < OMPC_DEPEND_unknown; ++i) { + if (i == OMPC_DEPEND_source) + continue; Values += "'"; Values += getOpenMPSimpleClauseTypeName(OMPC_depend, i); Values += "'"; switch (i) { - case OMPC_DEPEND_unknown - 2: + case OMPC_DEPEND_unknown - 3: Values += " or "; break; - case OMPC_DEPEND_unknown - 1: + case OMPC_DEPEND_unknown - 2: break; default: Values += Sep; @@ -8018,7 +8053,7 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, Vars.push_back(RefExpr->IgnoreParenImpCasts()); } - if (Vars.empty()) + if (DepKind != OMPC_DEPEND_source && Vars.empty()) return nullptr; return OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, DepKind, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 200701e13db..f11f135d462 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -7071,10 +7071,7 @@ StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective( } } StmtResult AssociatedStmt; - if (D->hasAssociatedStmt()) { - if (!D->getAssociatedStmt()) { - return StmtError(); - } + if (D->hasAssociatedStmt() && D->getAssociatedStmt()) { getDerived().getSema().ActOnOpenMPRegionStart(D->getDirectiveKind(), /*CurScope=*/nullptr); StmtResult Body; |