[cfe-commits] r131369 - in /cfe/trunk: lib/AST/ASTContext.cpp test/CodeGenObjC/encode-test.m

Argyrios Kyrtzidis akyrtzi at gmail.com
Sat May 14 17:11:35 PDT 2011


Author: akirtzidis
Date: Sat May 14 19:11:35 2011
New Revision: 131369

URL: http://llvm.org/viewvc/llvm-project?rev=131369&view=rev
Log:
Fix generation of obj-c @encoding for members with zero size.
Also follow gcc in that arrays of elements with zero size are encoded as arrays with zero elements.

Modified:
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/test/CodeGenObjC/encode-test.m

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=131369&r1=131368&r2=131369&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Sat May 14 19:11:35 2011
@@ -4248,9 +4248,12 @@
     } else {
       S += '[';
 
-      if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT))
-        S += llvm::utostr(CAT->getSize().getZExtValue());
-      else {
+      if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) {
+        if (getTypeSize(CAT->getElementType()) == 0)
+          S += '0';
+        else
+          S += llvm::utostr(CAT->getSize().getZExtValue());
+      } else {
         //Variable length arrays are encoded as a regular array with 0 elements.
         assert((isa<VariableArrayType>(AT) || isa<IncompleteArrayType>(AT)) &&
                "Unknown array type!");
@@ -4445,35 +4448,39 @@
     return;
 
   CXXRecordDecl *CXXRec = dyn_cast<CXXRecordDecl>(RDecl);
-  std::map<uint64_t, NamedDecl *> FieldOrBaseOffsets;
+  std::multimap<uint64_t, NamedDecl *> FieldOrBaseOffsets;
   const ASTRecordLayout &layout = getASTRecordLayout(RDecl);
-  
-  unsigned i = 0;
-  for (RecordDecl::field_iterator Field = RDecl->field_begin(),
-                               FieldEnd = RDecl->field_end();
-       Field != FieldEnd; ++Field, ++i) {
-    assert(!FieldOrBaseOffsets[layout.getFieldOffset(i)]);
-    FieldOrBaseOffsets[layout.getFieldOffset(i)] = *Field;
-  }
-  
+
   if (CXXRec) {
     for (CXXRecordDecl::base_class_iterator
            BI = CXXRec->bases_begin(),
            BE = CXXRec->bases_end(); BI != BE; ++BI) {
       if (!BI->isVirtual()) {
         CXXRecordDecl *base = BI->getType()->getAsCXXRecordDecl();
-        assert(!FieldOrBaseOffsets[layout.getBaseClassOffsetInBits(base)]);
-        FieldOrBaseOffsets[layout.getBaseClassOffsetInBits(base)] = base;
+        uint64_t offs = layout.getBaseClassOffsetInBits(base);
+        FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),
+                                  std::make_pair(offs, base));
       }
     }
-    if (includeVBases) {
-      for (CXXRecordDecl::base_class_iterator
-             BI = CXXRec->vbases_begin(),
-             BE = CXXRec->vbases_end(); BI != BE; ++BI) {
-        CXXRecordDecl *base = BI->getType()->getAsCXXRecordDecl();
-        assert(!FieldOrBaseOffsets[layout.getVBaseClassOffsetInBits(base)]);
-        FieldOrBaseOffsets[layout.getVBaseClassOffsetInBits(base)] = base;
-      }
+  }
+  
+  unsigned i = 0;
+  for (RecordDecl::field_iterator Field = RDecl->field_begin(),
+                               FieldEnd = RDecl->field_end();
+       Field != FieldEnd; ++Field, ++i) {
+    uint64_t offs = layout.getFieldOffset(i);
+    FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),
+                              std::make_pair(offs, *Field));
+  }
+
+  if (CXXRec && includeVBases) {
+    for (CXXRecordDecl::base_class_iterator
+           BI = CXXRec->vbases_begin(),
+           BE = CXXRec->vbases_end(); BI != BE; ++BI) {
+      CXXRecordDecl *base = BI->getType()->getAsCXXRecordDecl();
+      uint64_t offs = layout.getVBaseClassOffsetInBits(base);
+      FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),
+                                std::make_pair(offs, base));
     }
   }
 
@@ -4504,8 +4511,9 @@
 
   if (!RDecl->hasFlexibleArrayMember()) {
     // Mark the end of the structure.
-    assert(!FieldOrBaseOffsets[toBits(size)]);
-    FieldOrBaseOffsets[toBits(size)] = 0;
+    uint64_t offs = toBits(size);
+    FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),
+                              std::make_pair(offs, (NamedDecl*)0));
   }
 
   for (; CurLayObj != FieldOrBaseOffsets.end(); ++CurLayObj) {

Modified: cfe/trunk/test/CodeGenObjC/encode-test.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/encode-test.m?rev=131369&r1=131368&r2=131369&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/encode-test.m (original)
+++ cfe/trunk/test/CodeGenObjC/encode-test.m Sat May 14 19:11:35 2011
@@ -151,3 +151,13 @@
   int flex[];
 };
 const char g9[] = @encode(struct S9);
+
+struct f
+{
+  int i;
+  struct{} g[4];
+  int tt;
+};
+
+// CHECK: @g10 = constant [14 x i8] c"{f=i[0{?=}]i}\00"
+const char g10[] = @encode(struct f);





More information about the cfe-commits mailing list