unsigned int BytePos, bool ForStrongLayout,
bool &HasUnion);
+ Qualifiers::ObjCLifetime GetObjCLifeTime(QualType QT);
+
void UpdateRunSkipBlockVars(bool IsByref,
Qualifiers::ObjCLifetime LifeTime,
unsigned FieldOffset,
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,
}
} else {
UpdateRunSkipBlockVars(false,
- Field->getType().getObjCLifetime(),
+ GetObjCLifeTime(FQT),
BytePos + FieldOffset,
FieldSize);
}
((BitFieldSize % ByteSizeInBits) != 0);
Size += LastBitfieldOrUnnamedOffset;
UpdateRunSkipBlockVars(false,
- LastFieldBitfieldOrUnnamed->getType().getObjCLifetime(),
+ GetObjCLifeTime(LastFieldBitfieldOrUnnamed->getType()),
BytePos + LastBitfieldOrUnnamedOffset,
Size*ByteSizeInBits);
} else {
unsigned FieldSize
= CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType());
UpdateRunSkipBlockVars(false,
- LastFieldBitfieldOrUnnamed->getType().getObjCLifetime(),
+ GetObjCLifeTime(LastFieldBitfieldOrUnnamed->getType()),
BytePos + LastBitfieldOrUnnamedOffset,
FieldSize);
}
if (MaxField)
UpdateRunSkipBlockVars(false,
- MaxField->getType().getObjCLifetime(),
+ GetObjCLifeTime(MaxField->getType()),
BytePos + MaxFieldOffset,
MaxUnionSize);
}
}
unsigned fieldSize = ci->isByRef() ? WordSizeInBits
: CGM.getContext().getTypeSize(type);
- UpdateRunSkipBlockVars(ci->isByRef(), type.getObjCLifetime(),
+ UpdateRunSkipBlockVars(ci->isByRef(), GetObjCLifeTime(type),
fieldOffset, fieldSize);
}
--- /dev/null
+// 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;
+ };
+}