jansvoboda11 updated this revision to Diff 435108. jansvoboda11 added a comment. Herald added a project: clang.
Add operators for atomic types Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D125349/new/ https://reviews.llvm.org/D125349 Files: clang/lib/Sema/SemaOverload.cpp clang/test/CodeGenCXX/atomic-builtin-compound-assignment-overload.cpp clang/test/SemaCXX/atomic-builtin-compound-assignment-overload.cpp
Index: clang/test/SemaCXX/atomic-builtin-compound-assignment-overload.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/atomic-builtin-compound-assignment-overload.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -std=gnu++98 -fsyntax-only -verify %s +// expected-no-diagnostics + +_Atomic unsigned an_atomic_uint; + +enum { an_enum_value = 1 }; + +void enum1() { an_atomic_uint += an_enum_value; } + +void enum2() { an_atomic_uint |= an_enum_value; } Index: clang/test/CodeGenCXX/atomic-builtin-compound-assignment-overload.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/atomic-builtin-compound-assignment-overload.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -std=gnu++11 -emit-llvm -triple=x86_64-linux-gnu -o - %s | FileCheck %s + +_Atomic unsigned an_atomic_uint; + +enum { an_enum_value = 1 }; + +// CHECK-LABEL: define {{.*}}void @_Z5enum1v() +void enum1() { + an_atomic_uint += an_enum_value; + // CHECK: atomicrmw add ptr +} + +// CHECK-LABEL: define {{.*}}void @_Z5enum2v() +void enum2() { + an_atomic_uint |= an_enum_value; + // CHECK: atomicrmw or ptr +} + +// CHECK-LABEL: define {{.*}}void @_Z5enum3RU7_Atomicj({{.*}}) +void enum3(_Atomic unsigned &an_atomic_uint_param) { + an_atomic_uint_param += an_enum_value; + // CHECK: atomicrmw add ptr +} + +// CHECK-LABEL: define {{.*}}void @_Z5enum4RU7_Atomicj({{.*}}) +void enum4(_Atomic unsigned &an_atomic_uint_param) { + an_atomic_uint_param |= an_enum_value; + // CHECK: atomicrmw or ptr +} Index: clang/lib/Sema/SemaOverload.cpp =================================================================== --- clang/lib/Sema/SemaOverload.cpp +++ clang/lib/Sema/SemaOverload.cpp @@ -8202,6 +8202,7 @@ Sema &S; ArrayRef<Expr *> Args; Qualifiers VisibleTypeConversionsQuals; + bool VisibleTypeIsAtomic; bool HasArithmeticOrEnumeralCandidateType; SmallVectorImpl<BuiltinCandidateTypeSet> &CandidateTypes; OverloadCandidateSet &CandidateSet; @@ -8326,11 +8327,13 @@ BuiltinOperatorOverloadBuilder( Sema &S, ArrayRef<Expr *> Args, Qualifiers VisibleTypeConversionsQuals, + bool VisibleTypeIsAtomic, bool HasArithmeticOrEnumeralCandidateType, SmallVectorImpl<BuiltinCandidateTypeSet> &CandidateTypes, OverloadCandidateSet &CandidateSet) : S(S), Args(Args), VisibleTypeConversionsQuals(VisibleTypeConversionsQuals), + VisibleTypeIsAtomic(VisibleTypeIsAtomic), HasArithmeticOrEnumeralCandidateType( HasArithmeticOrEnumeralCandidateType), CandidateTypes(CandidateTypes), @@ -8951,6 +8954,13 @@ S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/isEqualOp); + if (VisibleTypeIsAtomic) { + ParamTypes[0] = S.Context.getAtomicType(LeftBaseTy); + ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); + S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, + /*IsAssignmentOperator=*/isEqualOp); + } + // Add this built-in operator as a candidate (VQ is 'volatile'). if (VisibleTypeConversionsQuals.hasVolatile()) { ParamTypes[0] = S.Context.getVolatileType(LeftBaseTy); @@ -9007,6 +9017,13 @@ // Add this built-in operator as a candidate (VQ is empty). ParamTypes[0] = S.Context.getLValueReferenceType(LeftBaseTy); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); + + if (VisibleTypeIsAtomic) { + ParamTypes[0] = S.Context.getAtomicType(LeftBaseTy); + ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); + S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); + } + if (VisibleTypeConversionsQuals.hasVolatile()) { // Add this built-in operator as a candidate (VQ is 'volatile'). ParamTypes[0] = LeftBaseTy; @@ -9179,8 +9196,11 @@ // candidate types or either arithmetic or enumeral candidate types. Qualifiers VisibleTypeConversionsQuals; VisibleTypeConversionsQuals.addConst(); - for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) + bool VisibleTypeIsAtomic = false; + for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { VisibleTypeConversionsQuals += CollectVRQualifiers(Context, Args[ArgIdx]); + VisibleTypeIsAtomic |= Args[ArgIdx]->getType()->isAtomicType(); + } bool HasNonRecordCandidateType = false; bool HasArithmeticOrEnumeralCandidateType = false; @@ -9213,6 +9233,7 @@ // Setup an object to manage the common state for building overloads. BuiltinOperatorOverloadBuilder OpBuilder(*this, Args, VisibleTypeConversionsQuals, + VisibleTypeIsAtomic, HasArithmeticOrEnumeralCandidateType, CandidateTypes, CandidateSet);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits