]> granicus.if.org Git - clang/commitdiff
Patch to fix encoding of Enum bitfields in ObjC.
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 13 Jan 2009 01:18:13 +0000 (01:18 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 13 Jan 2009 01:18:13 +0000 (01:18 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62135 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ASTContext.cpp
test/CodeGenObjC/encode-test-1.m [new file with mode: 0644]

index 24172a5ddbda8666316658d9e7791595bdff2b73..b5487565ae76dd1e4d221bafbef2f918ec5fca8a 100644 (file)
@@ -1775,6 +1775,16 @@ void ASTContext::getObjCEncodingForType(QualType T, std::string& S,
                              true /* outermost type */);
 }
 
+static void EncodeBitField(const ASTContext *Context, std::string& S, 
+                           FieldDecl *FD) {
+  const Expr *E = FD->getBitWidth();
+  assert(E && "bitfield width not there - getObjCEncodingForTypeImpl");
+  ASTContext *Ctx = const_cast<ASTContext*>(Context);
+  unsigned N = E->getIntegerConstantExprValue(*Ctx).getZExtValue();
+  S += 'b';
+  S += llvm::utostr(N);
+}
+
 void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
                                             bool ExpandPointedToStructures,
                                             bool ExpandStructures,
@@ -1782,12 +1792,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
                                             bool OutermostType) const {
   if (const BuiltinType *BT = T->getAsBuiltinType()) {
     if (FD && FD->isBitField()) {
-      const Expr *E = FD->getBitWidth();
-      assert(E && "bitfield width not there - getObjCEncodingForTypeImpl");
-      ASTContext *Ctx = const_cast<ASTContext*>(this);
-      unsigned N = E->getIntegerConstantExprValue(*Ctx).getZExtValue();
-      S += 'b';
-      S += llvm::utostr(N);
+      EncodeBitField(this, S, FD);
     }
     else {
       char encoding;
@@ -1949,7 +1954,10 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
     }
     S += RDecl->isUnion() ? ')' : '}';
   } else if (T->isEnumeralType()) {
-    S += 'i';
+    if (FD && FD->isBitField())
+      EncodeBitField(this, S, FD);
+    else
+      S += 'i';
   } else if (T->isBlockPointerType()) {
     S += '^'; // This type string is the same as general pointers.
   } else if (T->isObjCInterfaceType()) {
diff --git a/test/CodeGenObjC/encode-test-1.m b/test/CodeGenObjC/encode-test-1.m
new file mode 100644 (file)
index 0000000..3646fef
--- /dev/null
@@ -0,0 +1,36 @@
+// RUN: clang -triple=i686-apple-darwin9 -fnext-runtime -emit-llvm -o %t %s &&
+// RUN: grep -e "{Base=b2b3b4b5}" %t | count 1 &&
+// RUN: grep -e "{Derived=b2b3b4b5b5b4b3}" %t | count 1
+
+enum Enum { one, two, three, four };
+
+@interface Base {
+  unsigned a: 2;
+  int b: 3;
+  enum Enum c: 4;
+  unsigned d: 5;
+} 
+@end
+
+@interface Derived: Base {
+  signed e: 5;
+  int f: 4;
+  enum Enum g: 3;
+} 
+@end
+
+@implementation Base @end
+
+@implementation Derived @end
+  
+int main(void)
+{
+
+  const char *en = @encode(Base);
+//  printf ("%s\n", en);
+
+  const char *ed = @encode(Derived);
+ // printf ("%s\n", ed);
+
+  return 0;
+}