]> granicus.if.org Git - clang/commitdiff
Finishing up block variable layout API by supporting
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 6 Aug 2010 16:28:55 +0000 (16:28 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Fri, 6 Aug 2010 16:28:55 +0000 (16:28 +0000)
union type variables and their nesting inside other
aggregate types.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110448 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGObjCMac.cpp
test/CodeGenObjC/block-var-layout.m

index b3921a4816541500759a9ecbecb00aa09c5a2a98..d9d79e1587526e0b1185bdeee920c3c319fbb282 100644 (file)
@@ -1714,6 +1714,7 @@ llvm::Constant *CGObjCCommonMac::GCBlockLayout(CodeGen::CodeGenFunction &CGF,
   if ((CGM.getLangOptions().getGCMode() == LangOptions::NonGC) ||
       DeclRefs.empty())
     return NullPtr;
+  bool hasUnion = false;
   SkipIvars.clear();
   IvarsInfo.clear();
   unsigned WordSizeInBits = CGM.getContext().Target.getPointerWidth(0);
@@ -1727,19 +1728,14 @@ llvm::Constant *CGObjCCommonMac::GCBlockLayout(CodeGen::CodeGenFunction &CGF,
     QualType Ty = VD->getType();
     assert(!Ty->isArrayType() && 
            "Array block variable should have been caught");
-    if (Ty->isRecordType() && !BDRE->isByRef()) {
-      bool HasUnion = false;
+    if ((Ty->isRecordType() || Ty->isUnionType()) && !BDRE->isByRef()) {
       BuildAggrIvarRecordLayout(Ty->getAs<RecordType>(),
                                 FieldOffset,
                                 true,
-                                HasUnion);
+                                hasUnion);
       continue;
     }
-    // FIXME. Handle none __block Aggregate variables
-#if 0
-    if (Ty->isUnionType() && !BDRE->isByRef())
-      assert(false && "union block variable layout NYI");
-#endif
+      
     Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), Ty);
     unsigned FieldSize = CGM.getContext().getTypeSize(Ty);
     // __block variables are passed by their descriptior address. So, size
@@ -1756,6 +1752,12 @@ llvm::Constant *CGObjCCommonMac::GCBlockLayout(CodeGen::CodeGenFunction &CGF,
   
   if (IvarsInfo.empty())
     return NullPtr;
+  // Sort on byte position in case we encounterred a union nested in
+  // block variable type's aggregate type.
+  if (hasUnion && !IvarsInfo.empty())
+    std::sort(IvarsInfo.begin(), IvarsInfo.end());
+  if (hasUnion && !SkipIvars.empty())
+    std::sort(SkipIvars.begin(), SkipIvars.end());
   
   std::string BitMap;
   llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
index f00b44fdd553dcb5074c91493cd6898f759b272b..bf9ba8df75e253c900ebc29c4e8d6fea2469bbf9 100644 (file)
@@ -72,6 +72,41 @@ void (^d)() = ^{
     e();
 }
 
+// Test 5 (unions/structs and their nesting):
+void Test5() {
+struct S5 {
+    int i1;
+    id o1;
+    struct V {
+     int i2;
+     id o2;
+    } v1;
+    int i3;
+    union UI {
+        void * i1;
+        id o1;
+        int i3;
+        id o3;
+    }ui;
+};
+
+union U {
+        void * i1;
+        id o1;
+        int i3;
+        id o3;
+}ui;
+
+struct S5 s2;
+union U u2;
+void (^c)() = ^{
+    x(s2.ui.o1);
+    x(u2.o1);
+};
+c();
+
+}
+
 // CHECK-LP64: L_OBJC_CLASS_NAME_:
 // CHECK-LP64-NEXT: .asciz      "A\024"
 
@@ -83,3 +118,6 @@ void (^d)() = ^{
 
 // CHECK-LP64: L_OBJC_CLASS_NAME_11:
 // CHECK-LP64-NEXT: .asciz   "Q\021\021"
+
+// CHECK-LP64: L_OBJC_CLASS_NAME_14:
+// CHECK-LP64-NEXT: .asciz   "Q\021\022p"