forked from OSchip/llvm-project
objective-C mrr block. Block variable layout metadata in
mrr mode. llvm-svn: 167331
This commit is contained in:
parent
3b0af848d3
commit
2dd7819267
|
@ -942,6 +942,8 @@ protected:
|
|||
unsigned int BytePos, bool ForStrongLayout,
|
||||
bool &HasUnion);
|
||||
|
||||
Qualifiers::ObjCLifetime GetObjCLifeTime(QualType QT);
|
||||
|
||||
void UpdateRunSkipBlockVars(bool IsByref,
|
||||
Qualifiers::ObjCLifetime LifeTime,
|
||||
unsigned FieldOffset,
|
||||
|
@ -1962,6 +1964,25 @@ llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
|
|||
return C;
|
||||
}
|
||||
|
||||
Qualifiers::ObjCLifetime CGObjCCommonMac::GetObjCLifeTime(QualType FQT) {
|
||||
if (CGM.getLangOpts().ObjCAutoRefCount)
|
||||
return FQT.getObjCLifetime();
|
||||
|
||||
// MRR, is more ad hoc.
|
||||
if (FQT.isObjCGCStrong())
|
||||
return Qualifiers::OCL_Strong;
|
||||
if (FQT.isObjCGCWeak())
|
||||
return Qualifiers::OCL_Weak;
|
||||
|
||||
if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
|
||||
return Qualifiers::OCL_Strong;
|
||||
|
||||
if (const PointerType *PT = FQT->getAs<PointerType>())
|
||||
return (GetObjCLifeTime(PT->getPointeeType()));
|
||||
|
||||
return Qualifiers::OCL_None;
|
||||
}
|
||||
|
||||
void CGObjCCommonMac::UpdateRunSkipBlockVars(bool IsByref,
|
||||
Qualifiers::ObjCLifetime LifeTime,
|
||||
unsigned FieldOffset,
|
||||
|
@ -2074,7 +2095,7 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
|
|||
}
|
||||
} else {
|
||||
UpdateRunSkipBlockVars(false,
|
||||
Field->getType().getObjCLifetime(),
|
||||
GetObjCLifeTime(FQT),
|
||||
BytePos + FieldOffset,
|
||||
FieldSize);
|
||||
}
|
||||
|
@ -2089,7 +2110,7 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
|
|||
((BitFieldSize % ByteSizeInBits) != 0);
|
||||
Size += LastBitfieldOrUnnamedOffset;
|
||||
UpdateRunSkipBlockVars(false,
|
||||
LastFieldBitfieldOrUnnamed->getType().getObjCLifetime(),
|
||||
GetObjCLifeTime(LastFieldBitfieldOrUnnamed->getType()),
|
||||
BytePos + LastBitfieldOrUnnamedOffset,
|
||||
Size*ByteSizeInBits);
|
||||
} else {
|
||||
|
@ -2098,7 +2119,7 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
|
|||
unsigned FieldSize
|
||||
= CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType());
|
||||
UpdateRunSkipBlockVars(false,
|
||||
LastFieldBitfieldOrUnnamed->getType().getObjCLifetime(),
|
||||
GetObjCLifeTime(LastFieldBitfieldOrUnnamed->getType()),
|
||||
BytePos + LastBitfieldOrUnnamedOffset,
|
||||
FieldSize);
|
||||
}
|
||||
|
@ -2106,7 +2127,7 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
|
|||
|
||||
if (MaxField)
|
||||
UpdateRunSkipBlockVars(false,
|
||||
MaxField->getType().getObjCLifetime(),
|
||||
GetObjCLifeTime(MaxField->getType()),
|
||||
BytePos + MaxFieldOffset,
|
||||
MaxUnionSize);
|
||||
}
|
||||
|
@ -2274,7 +2295,7 @@ llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
|
|||
}
|
||||
unsigned fieldSize = ci->isByRef() ? WordSizeInBits
|
||||
: CGM.getContext().getTypeSize(type);
|
||||
UpdateRunSkipBlockVars(ci->isByRef(), type.getObjCLifetime(),
|
||||
UpdateRunSkipBlockVars(ci->isByRef(), GetObjCLifeTime(type),
|
||||
fieldOffset, fieldSize);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin -O0 -emit-llvm %s -o %t-64.s
|
||||
// rdar://12184410
|
||||
|
||||
void x(id y) {}
|
||||
void y(int a) {}
|
||||
|
||||
extern id opaque_id();
|
||||
__weak id wid;
|
||||
|
||||
void f() {
|
||||
__block int byref_int = 0;
|
||||
const id bar = (id) opaque_id();
|
||||
id baz = 0;
|
||||
__strong id strong_void_sta;
|
||||
__block id byref_bab = (id)0;
|
||||
__block id bl_var1;
|
||||
|
||||
// Inline instruction for block variable layout: 0x0100
|
||||
// CKECK-LP64: i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0), i64 256 }
|
||||
void (^b)() = ^{
|
||||
x(bar);
|
||||
};
|
||||
|
||||
// Inline instruction for block variable layout: 0x0210
|
||||
// CKECK-LP64: i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0), i64 528 }
|
||||
void (^c)() = ^{
|
||||
x(bar);
|
||||
x(baz);
|
||||
byref_int = 1;
|
||||
};
|
||||
|
||||
// Inline instruction for block variable layout: 0x0230
|
||||
// CKECK-LP64: i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0), i64 560 }
|
||||
void (^d)() = ^{
|
||||
x(bar);
|
||||
x(baz);
|
||||
byref_int = 1;
|
||||
bl_var1 = 0;
|
||||
byref_bab = 0;
|
||||
};
|
||||
|
||||
// Inline instruction for block variable layout: 0x0230
|
||||
// CKECK-LP64: i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0), i64 560 }
|
||||
id (^e)() = ^{
|
||||
x(bar);
|
||||
x(baz);
|
||||
byref_int = 1;
|
||||
bl_var1 = 0;
|
||||
byref_bab = 0;
|
||||
return wid;
|
||||
};
|
||||
|
||||
// Inline instruction for block variable layout: 0x020
|
||||
// CKECK-LP64: i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0), i64 32 }
|
||||
void (^ii)() = ^{
|
||||
byref_int = 1;
|
||||
byref_bab = 0;
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue