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

Reply via email to