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:
Fariborz Jahanian 2010-04-13 18:32:24 +00:00
Родитель 8ce9e451b4
Коммит 15bd58842a
3 изменённых файлов: 32 добавлений и 8 удалений

Просмотреть файл

@ -148,6 +148,8 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
const ObjCPropertyImplDecl *PID) { const ObjCPropertyImplDecl *PID) {
ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl(); ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
const ObjCPropertyDecl *PD = PID->getPropertyDecl(); const ObjCPropertyDecl *PD = PID->getPropertyDecl();
bool IsAtomic =
!(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic);
ObjCMethodDecl *OMD = PD->getGetterMethodDecl(); ObjCMethodDecl *OMD = PD->getGetterMethodDecl();
assert(OMD && "Invalid call to generate getter (empty method)"); assert(OMD && "Invalid call to generate getter (empty method)");
// FIXME: This is rather murky, we create this here since they will not have // FIXME: This is rather murky, we create this here since they will not have
@ -160,7 +162,7 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
// atomic 'copy' and 'retain' properties are also directly // atomic 'copy' and 'retain' properties are also directly
// evaluated in gc-only mode. // evaluated in gc-only mode.
if (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly && if (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly &&
!(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic) && IsAtomic &&
(PD->getSetterKind() == ObjCPropertyDecl::Copy || (PD->getSetterKind() == ObjCPropertyDecl::Copy ||
PD->getSetterKind() == ObjCPropertyDecl::Retain)) { PD->getSetterKind() == ObjCPropertyDecl::Retain)) {
llvm::Value *GetPropertyFn = llvm::Value *GetPropertyFn =
@ -208,7 +210,8 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
StoreComplexToAddr(Pair, ReturnValue, LV.isVolatileQualified()); StoreComplexToAddr(Pair, ReturnValue, LV.isVolatileQualified());
} }
else if (hasAggregateLLVMType(Ivar->getType())) { 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 && CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect
&& CGM.getObjCRuntime().GetCopyStructFunction()) { && CGM.getObjCRuntime().GetCopyStructFunction()) {
llvm::Value *GetCopyStructFn = llvm::Value *GetCopyStructFn =
@ -232,12 +235,15 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
// FIXME. Implement when Atomic is false; But when struct has // FIXME. Implement when Atomic is false; But when struct has
// gc'able data member! // gc'able data member!
llvm::Value *isAtomic = 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), Args.push_back(std::make_pair(RValue::get(isAtomic),
getContext().BoolTy)); getContext().BoolTy));
llvm::Value *False = llvm::Value *hasStrong =
llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 0); llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy),
Args.push_back(std::make_pair(RValue::get(False), getContext().BoolTy)); IsStrong ? 1 : 0);
Args.push_back(std::make_pair(RValue::get(hasStrong),
getContext().BoolTy));
EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args, EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,
FunctionType::ExtInfo()), FunctionType::ExtInfo()),
GetCopyStructFn, ReturnValueSlot(), Args); GetCopyStructFn, ReturnValueSlot(), Args);
@ -396,6 +402,14 @@ bool CodeGenFunction::IndirectObjCSetterArg(const CGFunctionInfo &FI) {
return (AI.getKind() == ABIArgInfo::Indirect); 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() { llvm::Value *CodeGenFunction::LoadObjCSelf() {
const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
// See if we need to lazily forward self inside a block literal. // See if we need to lazily forward self inside a block literal.

Просмотреть файл

@ -480,6 +480,7 @@ public:
void GenerateObjCSetter(ObjCImplementationDecl *IMP, void GenerateObjCSetter(ObjCImplementationDecl *IMP,
const ObjCPropertyImplDecl *PID); const ObjCPropertyImplDecl *PID);
bool IndirectObjCSetterArg(const CGFunctionInfo &FI); bool IndirectObjCSetterArg(const CGFunctionInfo &FI);
bool IvarTypeWithAggrGCObjects(QualType Ty);
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Block Bits // 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 // rdar: // 7849824
struct s { struct s {
double a, b, c, d; double a, b, c, d;
}; };
struct s1 {
int i;
id j;
id k;
};
@interface A @interface A
@property (readwrite) double x; @property (readwrite) double x;
@property (readwrite) struct s y; @property (readwrite) struct s y;
@property (nonatomic, readwrite) struct s1 z;
@end @end
@implementation A @implementation A
@synthesize x; @synthesize x;
@synthesize y; @synthesize y;
@synthesize z;
@end @end
// CHECK-LP64: call void @objc_copyStruct // CHECK-LP64: call void @objc_copyStruct
// CHECK-LP64: call void @objc_copyStruct // CHECK-LP64: call void @objc_copyStruct
// CHECK-LP64: call void @objc_copyStruct