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,
|
unsigned int BytePos, bool ForStrongLayout,
|
||||||
bool &HasUnion);
|
bool &HasUnion);
|
||||||
|
|
||||||
|
Qualifiers::ObjCLifetime GetObjCLifeTime(QualType QT);
|
||||||
|
|
||||||
void UpdateRunSkipBlockVars(bool IsByref,
|
void UpdateRunSkipBlockVars(bool IsByref,
|
||||||
Qualifiers::ObjCLifetime LifeTime,
|
Qualifiers::ObjCLifetime LifeTime,
|
||||||
unsigned FieldOffset,
|
unsigned FieldOffset,
|
||||||
|
@ -1962,6 +1964,25 @@ llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
|
||||||
return C;
|
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,
|
void CGObjCCommonMac::UpdateRunSkipBlockVars(bool IsByref,
|
||||||
Qualifiers::ObjCLifetime LifeTime,
|
Qualifiers::ObjCLifetime LifeTime,
|
||||||
unsigned FieldOffset,
|
unsigned FieldOffset,
|
||||||
|
@ -2074,7 +2095,7 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
UpdateRunSkipBlockVars(false,
|
UpdateRunSkipBlockVars(false,
|
||||||
Field->getType().getObjCLifetime(),
|
GetObjCLifeTime(FQT),
|
||||||
BytePos + FieldOffset,
|
BytePos + FieldOffset,
|
||||||
FieldSize);
|
FieldSize);
|
||||||
}
|
}
|
||||||
|
@ -2089,7 +2110,7 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
|
||||||
((BitFieldSize % ByteSizeInBits) != 0);
|
((BitFieldSize % ByteSizeInBits) != 0);
|
||||||
Size += LastBitfieldOrUnnamedOffset;
|
Size += LastBitfieldOrUnnamedOffset;
|
||||||
UpdateRunSkipBlockVars(false,
|
UpdateRunSkipBlockVars(false,
|
||||||
LastFieldBitfieldOrUnnamed->getType().getObjCLifetime(),
|
GetObjCLifeTime(LastFieldBitfieldOrUnnamed->getType()),
|
||||||
BytePos + LastBitfieldOrUnnamedOffset,
|
BytePos + LastBitfieldOrUnnamedOffset,
|
||||||
Size*ByteSizeInBits);
|
Size*ByteSizeInBits);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2098,7 +2119,7 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
|
||||||
unsigned FieldSize
|
unsigned FieldSize
|
||||||
= CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType());
|
= CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType());
|
||||||
UpdateRunSkipBlockVars(false,
|
UpdateRunSkipBlockVars(false,
|
||||||
LastFieldBitfieldOrUnnamed->getType().getObjCLifetime(),
|
GetObjCLifeTime(LastFieldBitfieldOrUnnamed->getType()),
|
||||||
BytePos + LastBitfieldOrUnnamedOffset,
|
BytePos + LastBitfieldOrUnnamedOffset,
|
||||||
FieldSize);
|
FieldSize);
|
||||||
}
|
}
|
||||||
|
@ -2106,7 +2127,7 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
|
||||||
|
|
||||||
if (MaxField)
|
if (MaxField)
|
||||||
UpdateRunSkipBlockVars(false,
|
UpdateRunSkipBlockVars(false,
|
||||||
MaxField->getType().getObjCLifetime(),
|
GetObjCLifeTime(MaxField->getType()),
|
||||||
BytePos + MaxFieldOffset,
|
BytePos + MaxFieldOffset,
|
||||||
MaxUnionSize);
|
MaxUnionSize);
|
||||||
}
|
}
|
||||||
|
@ -2274,7 +2295,7 @@ llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
|
||||||
}
|
}
|
||||||
unsigned fieldSize = ci->isByRef() ? WordSizeInBits
|
unsigned fieldSize = ci->isByRef() ? WordSizeInBits
|
||||||
: CGM.getContext().getTypeSize(type);
|
: CGM.getContext().getTypeSize(type);
|
||||||
UpdateRunSkipBlockVars(ci->isByRef(), type.getObjCLifetime(),
|
UpdateRunSkipBlockVars(ci->isByRef(), GetObjCLifeTime(type),
|
||||||
fieldOffset, fieldSize);
|
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