summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/StmtPrinter.cpp10
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.cpp1
-rw-r--r--clang/lib/Parse/ParseOpenMP.cpp35
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp81
-rw-r--r--clang/lib/Sema/TreeTransform.h5
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;
OpenPOWER on IntegriCloud