[cfe-commits] r61268 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/CodeGen/CGObjCMac.cpp test/CodeGenObjC/encode-test.m
Fariborz Jahanian
fjahanian at apple.com
Fri Dec 19 15:34:54 PST 2008
Author: fjahanian
Date: Fri Dec 19 17:34:38 2008
New Revision: 61268
URL: http://llvm.org/viewvc/llvm-project?rev=61268&view=rev
Log:
More encoding support. This time for
@encode of classes and bitfields.
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
cfe/trunk/test/CodeGenObjC/encode-test.m
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=61268&r1=61267&r2=61268&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Fri Dec 19 17:34:38 2008
@@ -299,7 +299,7 @@
/// given type into \arg S. If \arg NameFields is specified then
/// record field names are also encoded.
void getObjCEncodingForType(QualType t, std::string &S,
- bool NameFields=false) const;
+ FieldDecl *Field=NULL) const;
// Put the string version of type qualifiers into S.
void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,
@@ -542,7 +542,7 @@
void getObjCEncodingForTypeImpl(QualType t, std::string &S,
bool ExpandPointedToStructures,
bool ExpandStructures,
- bool NameFields) const;
+ FieldDecl *Field) const;
};
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=61268&r1=61267&r2=61268&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Dec 19 17:34:38 2008
@@ -1734,48 +1734,58 @@
}
void ASTContext::getObjCEncodingForType(QualType T, std::string& S,
- bool NameFields) const {
+ FieldDecl *Field) const {
// We follow the behavior of gcc, expanding structures which are
// directly pointed to, and expanding embedded structures. Note that
// these rules are sufficient to prevent recursive encoding of the
// same type.
- getObjCEncodingForTypeImpl(T, S, true, true, NameFields);
+ getObjCEncodingForTypeImpl(T, S, true, true, Field);
}
void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
bool ExpandPointedToStructures,
bool ExpandStructures,
- bool NameFields) const {
+ FieldDecl *FD) const {
if (const BuiltinType *BT = T->getAsBuiltinType()) {
- char encoding;
- switch (BT->getKind()) {
- default: assert(0 && "Unhandled builtin type kind");
- case BuiltinType::Void: encoding = 'v'; break;
- case BuiltinType::Bool: encoding = 'B'; break;
- case BuiltinType::Char_U:
- case BuiltinType::UChar: encoding = 'C'; break;
- case BuiltinType::UShort: encoding = 'S'; break;
- case BuiltinType::UInt: encoding = 'I'; break;
- case BuiltinType::ULong: encoding = 'L'; break;
- case BuiltinType::ULongLong: encoding = 'Q'; break;
- case BuiltinType::Char_S:
- case BuiltinType::SChar: encoding = 'c'; break;
- case BuiltinType::Short: encoding = 's'; break;
- case BuiltinType::Int: encoding = 'i'; break;
- case BuiltinType::Long: encoding = 'l'; break;
- case BuiltinType::LongLong: encoding = 'q'; break;
- case BuiltinType::Float: encoding = 'f'; break;
- case BuiltinType::Double: encoding = 'd'; break;
- case BuiltinType::LongDouble: encoding = 'd'; break;
- }
+ 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);
+ }
+ else {
+ char encoding;
+ switch (BT->getKind()) {
+ default: assert(0 && "Unhandled builtin type kind");
+ case BuiltinType::Void: encoding = 'v'; break;
+ case BuiltinType::Bool: encoding = 'B'; break;
+ case BuiltinType::Char_U:
+ case BuiltinType::UChar: encoding = 'C'; break;
+ case BuiltinType::UShort: encoding = 'S'; break;
+ case BuiltinType::UInt: encoding = 'I'; break;
+ case BuiltinType::ULong: encoding = 'L'; break;
+ case BuiltinType::ULongLong: encoding = 'Q'; break;
+ case BuiltinType::Char_S:
+ case BuiltinType::SChar: encoding = 'c'; break;
+ case BuiltinType::Short: encoding = 's'; break;
+ case BuiltinType::Int: encoding = 'i'; break;
+ case BuiltinType::Long: encoding = 'l'; break;
+ case BuiltinType::LongLong: encoding = 'q'; break;
+ case BuiltinType::Float: encoding = 'f'; break;
+ case BuiltinType::Double: encoding = 'd'; break;
+ case BuiltinType::LongDouble: encoding = 'd'; break;
+ }
- S += encoding;
+ S += encoding;
+ }
}
else if (T->isObjCQualifiedIdType()) {
// Treat id<P...> same as 'id' for encoding purposes.
return getObjCEncodingForTypeImpl(getObjCIdType(), S,
ExpandPointedToStructures,
- ExpandStructures, NameFields);
+ ExpandStructures, FD);
}
else if (const PointerType *PT = T->getAsPointerType()) {
QualType PointeeTy = PT->getPointeeType();
@@ -1810,7 +1820,7 @@
S += '^';
getObjCEncodingForTypeImpl(PT->getPointeeType(), S,
false, ExpandPointedToStructures,
- false);
+ NULL);
} else if (const ArrayType *AT =
// Ignore type qualifiers etc.
dyn_cast<ArrayType>(T->getCanonicalTypeInternal())) {
@@ -1822,7 +1832,7 @@
assert(0 && "Unhandled array type!");
getObjCEncodingForTypeImpl(AT->getElementType(), S,
- false, ExpandStructures, NameFields);
+ false, ExpandStructures, FD);
S += ']';
} else if (T->getAsFunctionType()) {
S += '?';
@@ -1840,24 +1850,19 @@
for (RecordDecl::field_iterator Field = RDecl->field_begin(),
FieldEnd = RDecl->field_end();
Field != FieldEnd; ++Field) {
- if (NameFields) {
+ if (FD) {
S += '"';
S += Field->getNameAsString();
S += '"';
}
// Special case bit-fields.
- if (const Expr *E = Field->getBitWidth()) {
- // FIXME: Fix constness.
- ASTContext *Ctx = const_cast<ASTContext*>(this);
- unsigned N = E->getIntegerConstantExprValue(*Ctx).getZExtValue();
- // FIXME: Obj-C is losing information about the type size
- // here. Investigate if this is a problem.
- S += 'b';
- S += llvm::utostr(N);
+ if (Field->isBitField()) {
+ getObjCEncodingForTypeImpl(Field->getType(), S, false, true,
+ (*Field));
} else {
getObjCEncodingForTypeImpl(Field->getType(), S, false, true,
- NameFields);
+ FD);
}
}
}
@@ -1866,7 +1871,26 @@
S += 'i';
} else if (T->isBlockPointerType()) {
S += '^'; // This type string is the same as general pointers.
- } else
+ } else if (T->isObjCInterfaceType()) {
+ // @encode(class_name)
+ ObjCInterfaceDecl *OI = T->getAsObjCInterfaceType()->getDecl();
+ S += '{';
+ const IdentifierInfo *II = OI->getIdentifier();
+ S += II->getName();
+ S += '=';
+ std::vector<FieldDecl*> RecFields;
+ CollectObjCIvars(OI, RecFields);
+ for (unsigned int i = 0; i != RecFields.size(); i++) {
+ if (RecFields[i]->isBitField())
+ getObjCEncodingForTypeImpl(RecFields[i]->getType(), S, false, true,
+ RecFields[i]);
+ else
+ getObjCEncodingForTypeImpl(RecFields[i]->getType(), S, false, true,
+ FD);
+ }
+ S += '}';
+ }
+ else
assert(0 && "@encode for type not implemented!");
}
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=61268&r1=61267&r2=61268&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Fri Dec 19 17:34:38 2008
@@ -1336,7 +1336,7 @@
Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field));
std::string TypeStr;
Ivar[0] = GetMethodVarName(V->getIdentifier());
- CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr, true);
+ CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr, Field);
Ivar[1] = GetMethodVarType(TypeStr);
Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));
Modified: cfe/trunk/test/CodeGenObjC/encode-test.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/encode-test.m?rev=61268&r1=61267&r2=61268&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/encode-test.m (original)
+++ cfe/trunk/test/CodeGenObjC/encode-test.m Fri Dec 19 17:34:38 2008
@@ -1,5 +1,6 @@
// RUN: clang -fnext-runtime -emit-llvm -o %t %s &&
-// RUN: grep -e "\^{Innermost=CC}" %t | count 1
+// RUN: grep -e "\^{Innermost=CC}" %t | count 1 &&
+// RUN: grep -e "{Derived=#ib32b8b3b8sb16b8b8b2b8ccb6}" %t | count 1
@class Int1;
@@ -15,3 +16,40 @@
@implementation Int1
@end
+
+ at interface Base
+{
+ struct objc_class *isa;
+ int full;
+ int full2: 32;
+ int _refs: 8;
+ int field2: 3;
+ unsigned f3: 8;
+ short cc;
+ unsigned g: 16;
+ int r2: 8;
+ int r3: 8;
+ int r4: 2;
+ int r5: 8;
+ char c;
+}
+ at end
+
+ at interface Derived: Base
+{
+ char d;
+ int _field3: 6;
+}
+ at end
+
+ at implementation Base
+ at end
+
+ at implementation Derived
+ at end
+
+int main()
+{
+ const char *en = @encode(Derived);
+}
+
More information about the cfe-commits
mailing list