diff options
| author | Alexey Bataev <a.bataev@hotmail.com> | 2016-02-16 12:13:49 +0000 |
|---|---|---|
| committer | Alexey Bataev <a.bataev@hotmail.com> | 2016-02-16 12:13:49 +0000 |
| commit | c0214e0e87a147be4a204d4355b8d8c023861760 (patch) | |
| tree | 2eaa29dae117fdbea5cf046085d0f1aab19f481e /clang/lib/Sema/SemaOpenMP.cpp | |
| parent | 6a7c3e4bac78bc796b722f07dc336be8186fd535 (diff) | |
| download | bcm5719-llvm-c0214e0e87a147be4a204d4355b8d8c023861760.tar.gz bcm5719-llvm-c0214e0e87a147be4a204d4355b8d8c023861760.zip | |
[OPENMP] Allow to use compound assignment operators.
Loop-based directives allow to use iterators as loop counters. Iterators are allowed to define their own operators. This patch allows to use compound assignment operators for iterators.
llvm-svn: 260957
Diffstat (limited to 'clang/lib/Sema/SemaOpenMP.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 47 |
1 files changed, 37 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 33f809b5d7b..e63b40b80d0 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -4072,7 +4072,8 @@ static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, if (!Update.isUsable()) return ExprError(); - // Build 'VarRef = Start + Iter * Step'. + // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or + // 'VarRef = Start (+|-) Iter * Step'. auto NewStart = Transform.TransformExpr(Start.get()->IgnoreImplicit()); if (NewStart.isInvalid()) return ExprError(); @@ -4082,17 +4083,43 @@ static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, /*AllowExplicit=*/true); if (NewStart.isInvalid()) return ExprError(); - Update = SemaRef.BuildBinOp(S, Loc, (Subtract ? BO_Sub : BO_Add), - NewStart.get(), Update.get()); - if (!Update.isUsable()) - return ExprError(); - Update = SemaRef.PerformImplicitConversion( - Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); - if (!Update.isUsable()) - return ExprError(); + // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. + ExprResult SavedUpdate = Update; + ExprResult UpdateVal; + if (VarRef.get()->getType()->isOverloadableType() || + NewStart.get()->getType()->isOverloadableType() || + Update.get()->getType()->isOverloadableType()) { + bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); + SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); + Update = + SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); + if (Update.isUsable()) { + UpdateVal = + SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, + VarRef.get(), SavedUpdate.get()); + if (UpdateVal.isUsable()) { + Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), + UpdateVal.get()); + } + } + SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); + } + + // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. + if (!Update.isUsable() || !UpdateVal.isUsable()) { + Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, + NewStart.get(), SavedUpdate.get()); + if (!Update.isUsable()) + return ExprError(); - Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); + Update = SemaRef.PerformImplicitConversion( + Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); + if (!Update.isUsable()) + return ExprError(); + + Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); + } return Update; } |

