Patch to fix encoding of Enum bitfields in ObjC.

llvm-svn: 62135
This commit is contained in:
Fariborz Jahanian 2009-01-13 01:18:13 +00:00
parent 75c4d57b9c
commit 5c76772f49
2 changed files with 51 additions and 7 deletions

View 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()) {

View File

@ -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;
}