r260957 - [OPENMP] Allow to use compound assignment operators.
Alexey Bataev via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 16 04:13:50 PST 2016
Author: abataev
Date: Tue Feb 16 06:13:49 2016
New Revision: 260957
URL: http://llvm.org/viewvc/llvm-project?rev=260957&view=rev
Log:
[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.
Modified:
cfe/trunk/lib/Sema/SemaOpenMP.cpp
cfe/trunk/test/OpenMP/for_loop_messages.cpp
Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=260957&r1=260956&r2=260957&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Tue Feb 16 06:13:49 2016
@@ -4072,7 +4072,8 @@ static ExprResult BuildCounterUpdate(Sem
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(Sem
/*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.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());
+ Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
+ }
return Update;
}
Modified: cfe/trunk/test/OpenMP/for_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_loop_messages.cpp?rev=260957&r1=260956&r2=260957&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/for_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/for_loop_messages.cpp Tue Feb 16 06:13:49 2016
@@ -426,6 +426,19 @@ public:
typedef int difference_type;
typedef std::random_access_iterator_tag iterator_category;
};
+class GoodIter1 {
+public:
+ GoodIter1() {}
+ GoodIter1(const GoodIter1 &) {}
+ GoodIter1 &operator++(int) { return *this; }
+ GoodIter1 &operator=(const GoodIter1 &that) { return *this; }
+ GoodIter1 &operator+=(int x) { return *this; }
+ friend long operator-(const GoodIter1 &, const GoodIter1 &);
+ GoodIter1 &operator-(int) { return *this; }
+ bool operator<(GoodIter1 a) { return true; }
+ typedef int difference_type;
+ typedef std::random_access_iterator_tag iterator_category;
+};
// expected-note at +2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}}
// expected-note at +1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
int operator-(GoodIter a, GoodIter b) { return 0; }
@@ -572,6 +585,10 @@ int test_with_random_access_iterator() {
#pragma omp for
for (Iter1 I; I < end1; ++I) {
}
+ GoodIter1 I1, E1;
+#pragma omp for
+ for (GoodIter1 I = I1; I < E1; I++)
+ ;
return 0;
}
More information about the cfe-commits
mailing list