summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaOpenMP.cpp
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2016-02-16 12:13:49 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2016-02-16 12:13:49 +0000
commitc0214e0e87a147be4a204d4355b8d8c023861760 (patch)
tree2eaa29dae117fdbea5cf046085d0f1aab19f481e /clang/lib/Sema/SemaOpenMP.cpp
parent6a7c3e4bac78bc796b722f07dc336be8186fd535 (diff)
downloadbcm5719-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.cpp47
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;
}
OpenPOWER on IntegriCloud