зеркало из 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,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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче