[cfe-commits] r57685 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/CodeGen/CGObjCMac.cpp
Daniel Dunbar
daniel at zuster.org
Fri Oct 17 09:17:38 PDT 2008
Author: ddunbar
Date: Fri Oct 17 11:17:37 2008
New Revision: 57685
URL: http://llvm.org/viewvc/llvm-project?rev=57685&view=rev
Log:
More Obj-C type encoding improvements.
- Encode unions and bit-fields correctly.
- Accept option to name record fields (used for NeXT runtime).
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=57685&r1=57684&r2=57685&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Fri Oct 17 11:17:37 2008
@@ -273,9 +273,12 @@
//// 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 @@
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;
};
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=57685&r1=57684&r2=57685&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Oct 17 11:17:37 2008
@@ -1594,26 +1594,20 @@
}
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 @@
// 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 @@
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 @@
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 @@
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()) {
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=57685&r1=57684&r2=57685&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Fri Oct 17 11:17:37 2008
@@ -1271,7 +1271,8 @@
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,
More information about the cfe-commits
mailing list