зеркало из https://github.com/microsoft/clang-1.git
Variation of objc_copyStruct API generation when
property (atomic/nonatomic) is of aggregate type with gc'able member objects) (NeXT runtime). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101156 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
8ce9e451b4
Коммит
15bd58842a
|
@ -148,19 +148,21 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
|
|||
const ObjCPropertyImplDecl *PID) {
|
||||
ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
|
||||
const ObjCPropertyDecl *PD = PID->getPropertyDecl();
|
||||
bool IsAtomic =
|
||||
!(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic);
|
||||
ObjCMethodDecl *OMD = PD->getGetterMethodDecl();
|
||||
assert(OMD && "Invalid call to generate getter (empty method)");
|
||||
// FIXME: This is rather murky, we create this here since they will not have
|
||||
// been created by Sema for us.
|
||||
OMD->createImplicitParams(getContext(), IMP->getClassInterface());
|
||||
StartObjCMethod(OMD, IMP->getClassInterface());
|
||||
|
||||
|
||||
// Determine if we should use an objc_getProperty call for
|
||||
// this. Non-atomic properties are directly evaluated.
|
||||
// atomic 'copy' and 'retain' properties are also directly
|
||||
// evaluated in gc-only mode.
|
||||
if (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly &&
|
||||
!(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
|
||||
IsAtomic &&
|
||||
(PD->getSetterKind() == ObjCPropertyDecl::Copy ||
|
||||
PD->getSetterKind() == ObjCPropertyDecl::Retain)) {
|
||||
llvm::Value *GetPropertyFn =
|
||||
|
@ -208,7 +210,8 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
|
|||
StoreComplexToAddr(Pair, ReturnValue, LV.isVolatileQualified());
|
||||
}
|
||||
else if (hasAggregateLLVMType(Ivar->getType())) {
|
||||
if (!(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic)
|
||||
bool IsStrong = false;
|
||||
if ((IsAtomic || (IsStrong = IvarTypeWithAggrGCObjects(Ivar->getType())))
|
||||
&& CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect
|
||||
&& CGM.getObjCRuntime().GetCopyStructFunction()) {
|
||||
llvm::Value *GetCopyStructFn =
|
||||
|
@ -232,12 +235,15 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
|
|||
// FIXME. Implement when Atomic is false; But when struct has
|
||||
// gc'able data member!
|
||||
llvm::Value *isAtomic =
|
||||
llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1);
|
||||
llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy),
|
||||
IsAtomic ? 1 : 0);
|
||||
Args.push_back(std::make_pair(RValue::get(isAtomic),
|
||||
getContext().BoolTy));
|
||||
llvm::Value *False =
|
||||
llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 0);
|
||||
Args.push_back(std::make_pair(RValue::get(False), getContext().BoolTy));
|
||||
llvm::Value *hasStrong =
|
||||
llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy),
|
||||
IsStrong ? 1 : 0);
|
||||
Args.push_back(std::make_pair(RValue::get(hasStrong),
|
||||
getContext().BoolTy));
|
||||
EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,
|
||||
FunctionType::ExtInfo()),
|
||||
GetCopyStructFn, ReturnValueSlot(), Args);
|
||||
|
@ -396,6 +402,14 @@ bool CodeGenFunction::IndirectObjCSetterArg(const CGFunctionInfo &FI) {
|
|||
return (AI.getKind() == ABIArgInfo::Indirect);
|
||||
}
|
||||
|
||||
bool CodeGenFunction::IvarTypeWithAggrGCObjects(QualType Ty) {
|
||||
if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
|
||||
return false;
|
||||
if (const RecordType *FDTTy = Ty.getTypePtr()->getAs<RecordType>())
|
||||
return FDTTy->getDecl()->hasObjectMember();
|
||||
return false;
|
||||
}
|
||||
|
||||
llvm::Value *CodeGenFunction::LoadObjCSelf() {
|
||||
const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
|
||||
// See if we need to lazily forward self inside a block literal.
|
||||
|
|
|
@ -480,6 +480,7 @@ public:
|
|||
void GenerateObjCSetter(ObjCImplementationDecl *IMP,
|
||||
const ObjCPropertyImplDecl *PID);
|
||||
bool IndirectObjCSetterArg(const CGFunctionInfo &FI);
|
||||
bool IvarTypeWithAggrGCObjects(QualType Ty);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Block Bits
|
||||
|
|
|
@ -1,19 +1,28 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -emit-llvm -o - %s | FileCheck -check-prefix LP64 %s
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fobjc-gc -emit-llvm -o - %s | FileCheck -check-prefix LP64 %s
|
||||
// rdar: // 7849824
|
||||
|
||||
struct s {
|
||||
double a, b, c, d;
|
||||
};
|
||||
|
||||
struct s1 {
|
||||
int i;
|
||||
id j;
|
||||
id k;
|
||||
};
|
||||
|
||||
@interface A
|
||||
@property (readwrite) double x;
|
||||
@property (readwrite) struct s y;
|
||||
@property (nonatomic, readwrite) struct s1 z;
|
||||
@end
|
||||
|
||||
@implementation A
|
||||
@synthesize x;
|
||||
@synthesize y;
|
||||
@synthesize z;
|
||||
@end
|
||||
|
||||
// CHECK-LP64: call void @objc_copyStruct
|
||||
// CHECK-LP64: call void @objc_copyStruct
|
||||
// CHECK-LP64: call void @objc_copyStruct
|
||||
|
|
Загрузка…
Ссылка в новой задаче