From b4c79e027fdcc752b5a377611fd4cfbb21611a05 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 4 May 2009 21:26:30 +0000 Subject: [PATCH] Compute interface instanceStart and instanceSize using the record layout. - This is much simpler / more efficient. - This also properly computes the size in the presence of bit-fields. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70916 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGObjCMac.cpp | 31 +++++--------------------- test/CodeGenObjC/interface-layout-64.m | 23 +++++++++++++++++++ 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index e735efb490..1a1ef83123 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -4219,35 +4219,16 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData( void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID, uint32_t &InstanceStart, uint32_t &InstanceSize) { - // Find first and last (non-padding) ivars in this interface. - - // FIXME: Use iterator. - llvm::SmallVector OIvars; - GetNamedIvarList(OID->getClassInterface(), OIvars); - - if (OIvars.empty()) { + const ASTRecordLayout &RL = + CGM.getContext().getASTObjCImplementationLayout(OID); + + if (!RL.getFieldCount()) { InstanceStart = InstanceSize = 0; return; } - const ObjCIvarDecl *First = OIvars.front(); - const ObjCIvarDecl *Last = OIvars.back(); - - InstanceStart = ComputeIvarBaseOffset(CGM, OID, First); - const llvm::Type *FieldTy = - CGM.getTypes().ConvertTypeForMem(Last->getType()); - unsigned Size = CGM.getTargetData().getTypePaddedSize(FieldTy); -// FIXME. This breaks compatibility with llvm-gcc-4.2 (but makes it compatible -// with gcc-4.2). We postpone this for now. -#if 0 - if (Last->isBitField()) { - Expr *BitWidth = Last->getBitWidth(); - uint64_t BitFieldSize = - BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue(); - Size = (BitFieldSize / 8) + ((BitFieldSize % 8) != 0); - } -#endif - InstanceSize = ComputeIvarBaseOffset(CGM, OID, Last) + Size; + InstanceStart = RL.getFieldOffset(0) / 8; + InstanceSize = llvm::RoundUpToAlignment(RL.getNextOffset(), 8) / 8; } void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { diff --git a/test/CodeGenObjC/interface-layout-64.m b/test/CodeGenObjC/interface-layout-64.m index 57f89b4787..ee01ac6bb6 100644 --- a/test/CodeGenObjC/interface-layout-64.m +++ b/test/CodeGenObjC/interface-layout-64.m @@ -7,6 +7,8 @@ // RUN: grep '@"OBJC_IVAR_$_I5._iv5" = global i64 24, section "__DATA, __objc_const", align 8' %t && // RUN: grep '@"OBJC_IVAR_$_I5._iv6_synth" = global i64 28, section "__DATA, __objc_const", align 8' %t && // RUN: grep '@"OBJC_IVAR_$_I5._iv7_synth" = global i64 32, section "__DATA, __objc_const", align 8' %t && +// RUN: grep '_OBJC_CLASS_RO_$_I6" = internal global .* { i32 2, i32 0, i32 1, .*' %t && +// RUN: grep '_OBJC_CLASS_RO_$_I8" = internal global .* { i32 0, i32 8, i32 16, .*' %t && // RUN: true @@ -54,3 +56,24 @@ struct s0 { @synthesize prop1 = _iv7_synth; @synthesize prop2 = _iv5; @end + +// The size rounds up to the next available byte. +@interface I6 { + unsigned iv0 : 2; +} +@end +@implementation I6 +@end + +// The start of the subclass includes padding for its own alignment. +@interface I7 { + char a; +} +@end +@interface I8 : I7 { + double b; +} +@end +@implementation I8 +@end + -- 2.40.0