aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2008-10-17 16:17:37 +0000
committerDaniel Dunbar <daniel@zuster.org>2008-10-17 16:17:37 +0000
commitd96b35bc6becf8db00d140c11e3d0e53f27567a1 (patch)
tree0bd124ea4cf5ee89e1d1f72e9caadcf6cf999f17
parent66031a5594bc9a7dc0dc5137c3e7955f835e4639 (diff)
More Obj-C type encoding improvements.
- Encode unions and bit-fields correctly. - Accept option to name record fields (used for NeXT runtime). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57685 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/ASTContext.h10
-rw-r--r--lib/AST/ASTContext.cpp49
-rw-r--r--lib/CodeGen/CGObjCMac.cpp3
3 files changed, 40 insertions, 22 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index b071255c57..e0ffcf4c92 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -273,9 +273,12 @@ public:
//// This gets the struct used to keep track of fast enumerations.
QualType getObjCFastEnumerationStateType();
- // Return the ObjC type encoding for a given type.
+ /// getObjCEncodingForType - Emit the ObjC type encoding for the
+ /// given type into \arg S. If \arg NameFields is specified then
+ /// record field names are also encoded.
void getObjCEncodingForType(QualType t, std::string &S,
- llvm::SmallVector<const RecordType*,8> &RT) const;
+ llvm::SmallVector<const RecordType*,8> &RT,
+ bool NameFields=false) const;
// Put the string version of type qualifiers into S.
void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,
@@ -478,7 +481,8 @@ private:
void getObjCEncodingForTypeImpl(QualType t, std::string &S,
bool ExpandPointedToStructures,
bool ExpandStructures,
- llvm::SmallVector<const RecordType*,8> &RT) const;
+ llvm::SmallVector<const RecordType*,8> &RT,
+ bool NameFields) const;
};
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 578b0ddfb3..292d5a9482 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1594,26 +1594,20 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
}
void ASTContext::getObjCEncodingForType(QualType T, std::string& S,
- llvm::SmallVector<const RecordType*,8> &ERType) const {
+ llvm::SmallVector<const RecordType*,8> &ERType,
+ bool NameFields) 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, ERType);
+ getObjCEncodingForTypeImpl(T, S, true, true, ERType, NameFields);
}
void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
bool ExpandPointedToStructures,
bool ExpandStructures,
- llvm::SmallVector<const RecordType*,8> &ERType) const {
- // FIXME: This currently doesn't encode:
- // @ An object (whether statically typed or typed id)
- // # A class object (Class)
- // : A method selector (SEL)
- // {name=type...} A structure
- // (name=type...) A union
- // bnum A bit field of num bits
-
+ llvm::SmallVector<const RecordType*,8> &ERType,
+ bool NameFields) const {
if (const BuiltinType *BT = T->getAsBuiltinType()) {
char encoding;
switch (BT->getKind()) {
@@ -1643,7 +1637,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
// Treat id<P...> same as 'id' for encoding purposes.
return getObjCEncodingForTypeImpl(getObjCIdType(), S,
ExpandPointedToStructures,
- ExpandStructures, ERType);
+ ExpandStructures, ERType, NameFields);
}
else if (const PointerType *PT = T->getAsPointerType()) {
QualType PointeeTy = PT->getPointeeType();
@@ -1669,7 +1663,8 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
S += '^';
getObjCEncodingForTypeImpl(PT->getPointeeType(), S,
- false, ExpandPointedToStructures, ERType);
+ false, ExpandPointedToStructures,
+ ERType, NameFields);
} else if (const ArrayType *AT =
// Ignore type qualifiers etc.
dyn_cast<ArrayType>(T->getCanonicalTypeInternal())) {
@@ -1681,13 +1676,13 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
assert(0 && "Unhandled array type!");
getObjCEncodingForTypeImpl(AT->getElementType(), S,
- false, ExpandStructures, ERType);
+ false, ExpandStructures, ERType, NameFields);
S += ']';
} else if (T->getAsFunctionType()) {
S += '?';
} else if (const RecordType *RTy = T->getAsRecordType()) {
RecordDecl *RDecl = RTy->getDecl();
- S += '{';
+ S += RDecl->isUnion() ? '(' : '{';
// Anonymous structures print as '?'
if (const IdentifierInfo *II = RDecl->getIdentifier()) {
S += II->getName();
@@ -1704,13 +1699,31 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
ERType.push_back(RTy);
S += '=';
for (int i = 0; i < RDecl->getNumMembers(); i++) {
- FieldDecl *field = RDecl->getMember(i);
- getObjCEncodingForTypeImpl(field->getType(), S, false, true, ERType);
+ FieldDecl *FD = RDecl->getMember(i);
+ if (NameFields) {
+ S += '"';
+ S += FD->getName();
+ S += '"';
+ }
+
+ // Special case bit-fields.
+ if (const Expr *E = FD->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);
+ } else {
+ getObjCEncodingForTypeImpl(FD->getType(), S, false, true,
+ ERType, NameFields);
+ }
}
assert(ERType.back() == RTy && "Record Type stack mismatch.");
ERType.pop_back();
}
- S += '}';
+ S += RDecl->isUnion() ? ')' : '}';
} else if (T->isEnumeralType()) {
S += 'i';
} else if (T->isBlockPointerType()) {
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 682515180d..2b1ffc0d8e 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -1271,7 +1271,8 @@ llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
Ivar[0] = GetMethodVarName(V->getIdentifier());
CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr,
- EncodingRecordTypes);
+ EncodingRecordTypes,
+ true);
Ivar[1] = GetMethodVarType(TypeStr);
Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy,