diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2015-09-03 07:23:48 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2015-09-03 07:23:48 +0000 |
commit | 6b8046addfce08aa075f0db860f8a5a29fd6e45f (patch) | |
tree | 0590b52d3fa9f08eb5fe3b86828cbcd3931a1bcd /clang/lib/Sema/SemaOpenMP.cpp | |
parent | 49948af9cd20eea2b9a504dbb25b2779e507c57f (diff) | |
download | bcm5719-llvm-6b8046addfce08aa075f0db860f8a5a29fd6e45f.tar.gz bcm5719-llvm-6b8046addfce08aa075f0db860f8a5a29fd6e45f.zip |
[OPENMP 4.1] Parsing/sema analysis for extended format of 'if' clause.
OpenMP 4.1 added special 'directive-name-modifier' to the 'if' clause.
Format of 'if' clause is as follows:
```
if([ directive-name-modifier :] scalar-logical-expression)
```
The restriction rules are also changed.
1. If any 'if' clause on the directive includes a 'directive-name-modifier' then all 'if' clauses on the directive must include a 'directive-name-modifier'.
2. At most one 'if' clause without a 'directive-name-modifier' can appear on the directive.
3. At most one 'if' clause with some particular 'directive-name-modifier' can appear on the directive.
'directive-name-modifier' is important for combined directives and allows to separate conditions in 'if' clause for simple sub-directives in combined directive. This 'directive-name-modifier' identifies the sub-directive to which this 'if' clause must be applied.
llvm-svn: 246747
Diffstat (limited to 'clang/lib/Sema/SemaOpenMP.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 208 |
1 files changed, 179 insertions, 29 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index ea31260cc7a..b4a6768394b 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -1985,6 +1985,82 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, return false; } +static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, + ArrayRef<OMPClause *> Clauses, + ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { + bool ErrorFound = false; + unsigned NamedModifiersNumber = 0; + SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( + OMPD_unknown + 1); + for (const auto *C : Clauses) { + if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { + // At most one if clause without a directive-name-modifier can appear on + // the directive. + OpenMPDirectiveKind CurNM = IC->getNameModifier(); + if (FoundNameModifiers[CurNM]) { + S.Diag(C->getLocStart(), diag::err_omp_more_one_clause) + << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) + << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); + ErrorFound = true; + } else if (CurNM != OMPD_unknown) + ++NamedModifiersNumber; + FoundNameModifiers[CurNM] = IC; + if (CurNM == OMPD_unknown) + continue; + // Check if the specified name modifier is allowed for the current + // directive. + // At most one if clause with the particular directive-name-modifier can + // appear on the directive. + bool MatchFound = false; + for (auto NM : AllowedNameModifiers) { + if (CurNM == NM) { + MatchFound = true; + break; + } + } + if (!MatchFound) { + S.Diag(IC->getNameModifierLoc(), + diag::err_omp_wrong_if_directive_name_modifier) + << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); + ErrorFound = true; + } + } + } + // If any if clause on the directive includes a directive-name-modifier then + // all if clauses on the directive must include a directive-name-modifier. + if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { + if (NamedModifiersNumber == AllowedNameModifiers.size()) { + S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(), + diag::err_omp_no_more_if_clause); + } else { + std::string Values; + std::string Sep(", "); + unsigned AllowedCnt = 0; + unsigned TotalAllowedNum = + AllowedNameModifiers.size() - NamedModifiersNumber; + for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; + ++Cnt) { + OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; + if (!FoundNameModifiers[NM]) { + Values += "'"; + Values += getOpenMPDirectiveName(NM); + Values += "'"; + if (AllowedCnt + 2 == TotalAllowedNum) + Values += " or "; + else if (AllowedCnt + 1 != TotalAllowedNum) + Values += Sep; + ++AllowedCnt; + } + } + S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(), + diag::err_omp_unnamed_if_clause) + << (TotalAllowedNum > 1) << Values; + } + ErrorFound = true; + } + return ErrorFound; +} + StmtResult Sema::ActOnOpenMPExecutableDirective( OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, @@ -2021,10 +2097,12 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( } } + llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; switch (Kind) { case OMPD_parallel: Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); + AllowedNameModifiers.push_back(OMPD_parallel); break; case OMPD_simd: Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, @@ -2064,18 +2142,22 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( case OMPD_parallel_for: Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); + AllowedNameModifiers.push_back(OMPD_parallel); break; case OMPD_parallel_for_simd: Res = ActOnOpenMPParallelForSimdDirective( ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); + AllowedNameModifiers.push_back(OMPD_parallel); break; case OMPD_parallel_sections: Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); + AllowedNameModifiers.push_back(OMPD_parallel); break; case OMPD_task: Res = ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); + AllowedNameModifiers.push_back(OMPD_task); break; case OMPD_taskyield: assert(ClausesWithImplicit.empty() && @@ -2124,6 +2206,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( case OMPD_target: Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); + AllowedNameModifiers.push_back(OMPD_target); break; case OMPD_cancellation_point: assert(ClausesWithImplicit.empty() && @@ -2142,6 +2225,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( case OMPD_target_data: Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); + AllowedNameModifiers.push_back(OMPD_target_data); break; case OMPD_threadprivate: llvm_unreachable("OpenMP Directive is not allowed"); @@ -2153,8 +2237,11 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) << P.first << P.second->getSourceRange(); } - if (!VarsWithInheritedDSA.empty()) - return StmtError(); + ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; + + if (!AllowedNameModifiers.empty()) + ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || + ErrorFound; if (ErrorFound) return StmtError(); @@ -2165,7 +2252,9 @@ StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + CapturedStmt *CS = cast<CapturedStmt>(AStmt); // 1.2.2 OpenMP Language Terminology // Structured block - An executable statement with a single entry at the @@ -3557,6 +3646,10 @@ StmtResult Sema::ActOnOpenMPSimdDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { + if (!AStmt) + return StmtError(); + + assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); OMPLoopDirective::HelperExprs B; // In presence of clause 'collapse' or 'ordered' with number of loops, it will // define the nested loops number. @@ -3606,6 +3699,10 @@ StmtResult Sema::ActOnOpenMPForDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { + if (!AStmt) + return StmtError(); + + assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); OMPLoopDirective::HelperExprs B; // In presence of clause 'collapse' or 'ordered' with number of loops, it will // define the nested loops number. @@ -3637,6 +3734,10 @@ StmtResult Sema::ActOnOpenMPForSimdDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { + if (!AStmt) + return StmtError(); + + assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); OMPLoopDirective::HelperExprs B; // In presence of clause 'collapse' or 'ordered' with number of loops, it will // define the nested loops number. @@ -3687,7 +3788,10 @@ StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + + assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); auto BaseStmt = AStmt; while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) BaseStmt = CS->getCapturedStmt(); @@ -3719,7 +3823,10 @@ StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + + assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); getCurFunction()->setHasBranchProtectedScope(); @@ -3730,7 +3837,10 @@ StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + + assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); getCurFunction()->setHasBranchProtectedScope(); @@ -3757,7 +3867,10 @@ StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + + assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); getCurFunction()->setHasBranchProtectedScope(); @@ -3768,7 +3881,10 @@ StmtResult Sema::ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + + assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); getCurFunction()->setHasBranchProtectedScope(); @@ -3780,7 +3896,9 @@ StmtResult Sema::ActOnOpenMPParallelForDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { - assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + CapturedStmt *CS = cast<CapturedStmt>(AStmt); // 1.2.2 OpenMP Language Terminology // Structured block - An executable statement with a single entry at the @@ -3821,7 +3939,9 @@ StmtResult Sema::ActOnOpenMPParallelForSimdDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { - assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + CapturedStmt *CS = cast<CapturedStmt>(AStmt); // 1.2.2 OpenMP Language Terminology // Structured block - An executable statement with a single entry at the @@ -3877,7 +3997,10 @@ StmtResult Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + + assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); auto BaseStmt = AStmt; while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) BaseStmt = CS->getCapturedStmt(); @@ -3910,7 +4033,9 @@ Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + CapturedStmt *CS = cast<CapturedStmt>(AStmt); // 1.2.2 OpenMP Language Terminology // Structured block - An executable statement with a single entry at the @@ -3942,7 +4067,10 @@ StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, StmtResult Sema::ActOnOpenMPTaskgroupDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + + assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); getCurFunction()->setHasBranchProtectedScope(); @@ -3959,7 +4087,10 @@ StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, StmtResult Sema::ActOnOpenMPOrderedDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + + assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); getCurFunction()->setHasBranchProtectedScope(); @@ -4210,7 +4341,9 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + auto CS = cast<CapturedStmt>(AStmt); // 1.2.2 OpenMP Language Terminology // Structured block - An executable statement with a single entry at the @@ -4631,7 +4764,10 @@ StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + + assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); // OpenMP [2.16, Nesting of Regions] // If specified, a teams construct must be contained within a target @@ -4672,6 +4808,11 @@ StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { + if (!AStmt) + return StmtError(); + + assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); + getCurFunction()->setHasBranchProtectedScope(); return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, @@ -4681,7 +4822,9 @@ StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { - assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); + if (!AStmt) + return StmtError(); + CapturedStmt *CS = cast<CapturedStmt>(AStmt); // 1.2.2 OpenMP Language Terminology // Structured block - An executable statement with a single entry at the @@ -4743,9 +4886,6 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation EndLoc) { OMPClause *Res = nullptr; switch (Kind) { - case OMPC_if: - Res = ActOnOpenMPIfClause(Expr, StartLoc, LParenLoc, EndLoc); - break; case OMPC_final: Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); break; @@ -4767,6 +4907,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, case OMPC_device: Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); break; + case OMPC_if: case OMPC_default: case OMPC_proc_bind: case OMPC_schedule: @@ -4796,8 +4937,11 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, return Res; } -OMPClause *Sema::ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc, +OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, + Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation NameModifierLoc, + SourceLocation ColonLoc, SourceLocation EndLoc) { Expr *ValExpr = Condition; if (!Condition->isValueDependent() && !Condition->isTypeDependent() && @@ -4811,7 +4955,8 @@ OMPClause *Sema::ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc, ValExpr = Val.get(); } - return new (Context) OMPIfClause(ValExpr, StartLoc, LParenLoc, EndLoc); + return new (Context) OMPIfClause(NameModifier, ValExpr, StartLoc, LParenLoc, + NameModifierLoc, ColonLoc, EndLoc); } OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, @@ -5129,16 +5274,20 @@ OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( OpenMPClauseKind Kind, unsigned Argument, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation ArgumentLoc, SourceLocation CommaLoc, + SourceLocation ArgumentLoc, SourceLocation DelimLoc, SourceLocation EndLoc) { OMPClause *Res = nullptr; switch (Kind) { case OMPC_schedule: Res = ActOnOpenMPScheduleClause( static_cast<OpenMPScheduleClauseKind>(Argument), Expr, StartLoc, - LParenLoc, ArgumentLoc, CommaLoc, EndLoc); + LParenLoc, ArgumentLoc, DelimLoc, EndLoc); break; case OMPC_if: + Res = + ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument), Expr, + StartLoc, LParenLoc, ArgumentLoc, DelimLoc, EndLoc); + break; case OMPC_final: case OMPC_num_threads: case OMPC_safelen: @@ -6382,9 +6531,7 @@ OMPClause *Sema::ActOnOpenMPReductionClause( BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), BO_Assign, LHSDRE, ConditionalOp); } - if (ReductionOp.isUsable()) { - ReductionOp = ActOnFinishFullExpr(ReductionOp.get()); - } + ReductionOp = ActOnFinishFullExpr(ReductionOp.get()); } if (ReductionOp.isInvalid()) continue; @@ -6551,6 +6698,7 @@ OMPClause *Sema::ActOnOpenMPLinearClause( buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); ExprResult CalcStep = BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); + CalcStep = ActOnFinishFullExpr(CalcStep.get()); // Warn about zero linear step (it would be probably better specified as // making corresponding variables 'const'). @@ -6607,13 +6755,15 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, ExprResult Update = BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, /* Subtract */ false); - Update = SemaRef.ActOnFinishFullExpr(Update.get()); + Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(), + /*DiscardedValue=*/true); // Build final: Var = InitExpr + NumIterations * Step ExprResult Final = BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, InitExpr, NumIterations, Step, /* Subtract */ false); - Final = SemaRef.ActOnFinishFullExpr(Final.get()); + Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(), + /*DiscardedValue=*/true); if (!Update.isUsable() || !Final.isUsable()) { Updates.push_back(nullptr); Finals.push_back(nullptr); |