objective-C mrr block. Block variable layout metadata in

mrr mode.

llvm-svn: 167331
This commit is contained in:
Fariborz Jahanian 2012-11-02 22:51:18 +00:00
parent 3b0af848d3
commit 2dd7819267
2 changed files with 85 additions and 5 deletions

View File

@ -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);
}

View File

@ -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;
};
}