From 5c76772f49f7a42db66b96f4d1e8d1d0e47fae8c Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Tue, 13 Jan 2009 01:18:13 +0000 Subject: [PATCH] Patch to fix encoding of Enum bitfields in ObjC. llvm-svn: 62135 --- clang/lib/AST/ASTContext.cpp | 22 +++++++++++----- clang/test/CodeGenObjC/encode-test-1.m | 36 ++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 clang/test/CodeGenObjC/encode-test-1.m diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 24172a5ddbda..b5487565ae76 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -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(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(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/clang/test/CodeGenObjC/encode-test-1.m b/clang/test/CodeGenObjC/encode-test-1.m new file mode 100644 index 000000000000..3646fef23b3e --- /dev/null +++ b/clang/test/CodeGenObjC/encode-test-1.m @@ -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; +}