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@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}} // expected-note@+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; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits