]> granicus.if.org Git - clang/commitdiff
Fix generation of obj-c @encoding for members with zero size.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sun, 15 May 2011 00:11:35 +0000 (00:11 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sun, 15 May 2011 00:11:35 +0000 (00:11 +0000)
Also follow gcc in that arrays of elements with zero size are encoded as arrays with zero elements.

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

lib/AST/ASTContext.cpp
test/CodeGenObjC/encode-test.m

index 2272bdae13eba365be5e67c564bf4ab78b3be348..2a0eac80fa493dfaf4b44e6379b55010f1ed28d7 100644 (file)
@@ -4248,9 +4248,12 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
     } 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 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
     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 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
 
   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) {
index 580b32cd0a11c5b408d29f09dfb5e1bf0ebf30c7..ade0c618225f758c31eabd36d07fbe82a6d3194d 100644 (file)
@@ -151,3 +151,13 @@ struct S9 {
   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);