22
22
#include " clang/AST/StmtObjC.h"
23
23
#include " clang/Basic/Diagnostic.h"
24
24
#include " clang/CodeGen/CGFunctionInfo.h"
25
+ #include " clang/CodeGen/CodeGenABITypes.h"
25
26
#include " llvm/ADT/STLExtras.h"
26
27
#include " llvm/Analysis/ObjCARCUtil.h"
27
28
#include " llvm/BinaryFormat/MachO.h"
@@ -1136,6 +1137,23 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl,
1136
1137
const ObjCPropertyImplDecl *propImpl,
1137
1138
const ObjCMethodDecl *GetterMethodDecl,
1138
1139
llvm::Constant *AtomicHelperFn) {
1140
+
1141
+ ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl ();
1142
+
1143
+ if (ivar->getType ().isNonTrivialToPrimitiveCopy () == QualType::PCK_Struct) {
1144
+ if (!AtomicHelperFn) {
1145
+ LValue Src =
1146
+ EmitLValueForIvar (TypeOfSelfObject (), LoadObjCSelf (), ivar, 0 );
1147
+ LValue Dst = MakeAddrLValue (ReturnValue, ivar->getType ());
1148
+ callCStructCopyConstructor (Dst, Src);
1149
+ } else {
1150
+ ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl ();
1151
+ emitCPPObjectAtomicGetterCall (*this , ReturnValue.getPointer (), ivar,
1152
+ AtomicHelperFn);
1153
+ }
1154
+ return ;
1155
+ }
1156
+
1139
1157
// If there's a non-trivial 'get' expression, we just have to emit that.
1140
1158
if (!hasTrivialGetExpr (propImpl)) {
1141
1159
if (!AtomicHelperFn) {
@@ -1156,8 +1174,6 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl,
1156
1174
QualType propType = prop->getType ();
1157
1175
ObjCMethodDecl *getterMethod = propImpl->getGetterMethodDecl ();
1158
1176
1159
- ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl ();
1160
-
1161
1177
// Pick an implementation strategy.
1162
1178
PropertyImplStrategy strategy (CGM, propImpl);
1163
1179
switch (strategy.getKind ()) {
@@ -1424,6 +1440,24 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
1424
1440
ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl ();
1425
1441
ObjCMethodDecl *setterMethod = propImpl->getSetterMethodDecl ();
1426
1442
1443
+ if (ivar->getType ().isNonTrivialToPrimitiveCopy () == QualType::PCK_Struct) {
1444
+ ParmVarDecl *PVD = *setterMethod->param_begin ();
1445
+ if (!AtomicHelperFn) {
1446
+ // Call the move assignment operator instead of calling the copy
1447
+ // assignment operator and destructor.
1448
+ LValue Dst = EmitLValueForIvar (TypeOfSelfObject (), LoadObjCSelf (), ivar,
1449
+ /* quals*/ 0 );
1450
+ LValue Src = MakeAddrLValue (GetAddrOfLocalVar (PVD), ivar->getType ());
1451
+ callCStructMoveAssignmentOperator (Dst, Src);
1452
+ } else {
1453
+ // If atomic, assignment is called via a locking api.
1454
+ emitCPPObjectAtomicSetterCall (*this , setterMethod, ivar, AtomicHelperFn);
1455
+ }
1456
+ // Decativate the destructor for the setter parameter.
1457
+ DeactivateCleanupBlock (CalleeDestructedParamCleanups[PVD], AllocaInsertPt);
1458
+ return ;
1459
+ }
1460
+
1427
1461
// Just use the setter expression if Sema gave us one and it's
1428
1462
// non-trivial.
1429
1463
if (!hasTrivialSetExpr (propImpl)) {
@@ -3680,23 +3714,34 @@ void CodeGenFunction::EmitExtendGCLifetime(llvm::Value *object) {
3680
3714
llvm::Constant *
3681
3715
CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction (
3682
3716
const ObjCPropertyImplDecl *PID) {
3717
+ const ObjCPropertyDecl *PD = PID->getPropertyDecl ();
3718
+ if ((!(PD->getPropertyAttributes () & ObjCPropertyAttribute::kind_atomic)))
3719
+ return nullptr ;
3720
+
3721
+ QualType Ty = PID->getPropertyIvarDecl ()->getType ();
3722
+ ASTContext &C = getContext ();
3723
+
3724
+ if (Ty.isNonTrivialToPrimitiveCopy () == QualType::PCK_Struct) {
3725
+ // Call the move assignment operator instead of calling the copy assignment
3726
+ // operator and destructor.
3727
+ CharUnits Alignment = C.getTypeAlignInChars (Ty);
3728
+ llvm::Constant *Fn = getNonTrivialCStructMoveAssignmentOperator (
3729
+ CGM, Alignment, Alignment, Ty.isVolatileQualified (), Ty);
3730
+ return llvm::ConstantExpr::getBitCast (Fn, VoidPtrTy);
3731
+ }
3732
+
3683
3733
if (!getLangOpts ().CPlusPlus ||
3684
3734
!getLangOpts ().ObjCRuntime .hasAtomicCopyHelper ())
3685
3735
return nullptr ;
3686
- QualType Ty = PID->getPropertyIvarDecl ()->getType ();
3687
3736
if (!Ty->isRecordType ())
3688
3737
return nullptr ;
3689
- const ObjCPropertyDecl *PD = PID->getPropertyDecl ();
3690
- if ((!(PD->getPropertyAttributes () & ObjCPropertyAttribute::kind_atomic)))
3691
- return nullptr ;
3692
3738
llvm::Constant *HelperFn = nullptr ;
3693
3739
if (hasTrivialSetExpr (PID))
3694
3740
return nullptr ;
3695
3741
assert (PID->getSetterCXXAssignment () && " SetterCXXAssignment - null" );
3696
3742
if ((HelperFn = CGM.getAtomicSetterHelperFnMap (Ty)))
3697
3743
return HelperFn;
3698
3744
3699
- ASTContext &C = getContext ();
3700
3745
IdentifierInfo *II
3701
3746
= &CGM.getContext ().Idents .get (" __assign_helper_atomic_property_" );
3702
3747
@@ -3767,26 +3812,34 @@ CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction(
3767
3812
return HelperFn;
3768
3813
}
3769
3814
3770
- llvm::Constant *
3771
- CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction (
3772
- const ObjCPropertyImplDecl *PID) {
3815
+ llvm::Constant *CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction (
3816
+ const ObjCPropertyImplDecl *PID) {
3817
+ const ObjCPropertyDecl *PD = PID->getPropertyDecl ();
3818
+ if ((!(PD->getPropertyAttributes () & ObjCPropertyAttribute::kind_atomic)))
3819
+ return nullptr ;
3820
+
3821
+ QualType Ty = PD->getType ();
3822
+ ASTContext &C = getContext ();
3823
+
3824
+ if (Ty.isNonTrivialToPrimitiveCopy () == QualType::PCK_Struct) {
3825
+ CharUnits Alignment = C.getTypeAlignInChars (Ty);
3826
+ llvm::Constant *Fn = getNonTrivialCStructCopyConstructor (
3827
+ CGM, Alignment, Alignment, Ty.isVolatileQualified (), Ty);
3828
+ return llvm::ConstantExpr::getBitCast (Fn, VoidPtrTy);
3829
+ }
3830
+
3773
3831
if (!getLangOpts ().CPlusPlus ||
3774
3832
!getLangOpts ().ObjCRuntime .hasAtomicCopyHelper ())
3775
3833
return nullptr ;
3776
- const ObjCPropertyDecl *PD = PID->getPropertyDecl ();
3777
- QualType Ty = PD->getType ();
3778
3834
if (!Ty->isRecordType ())
3779
3835
return nullptr ;
3780
- if ((!(PD->getPropertyAttributes () & ObjCPropertyAttribute::kind_atomic)))
3781
- return nullptr ;
3782
3836
llvm::Constant *HelperFn = nullptr ;
3783
3837
if (hasTrivialGetExpr (PID))
3784
3838
return nullptr ;
3785
3839
assert (PID->getGetterCXXConstructor () && " getGetterCXXConstructor - null" );
3786
3840
if ((HelperFn = CGM.getAtomicGetterHelperFnMap (Ty)))
3787
3841
return HelperFn;
3788
3842
3789
- ASTContext &C = getContext ();
3790
3843
IdentifierInfo *II =
3791
3844
&CGM.getContext ().Idents .get (" __copy_helper_atomic_property_" );
3792
3845
0 commit comments