From: Fariborz Jahanian Date: Tue, 20 Jan 2009 19:14:18 +0000 (+0000) Subject: Improving on encoding of objective-c's property types. More to come. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=090b3f71702c5626d8520f9608d77c6f26dcfa15;p=clang Improving on encoding of objective-c's property types. More to come. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62601 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 7707b1d215..32aa9157aa 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -548,7 +548,8 @@ private: bool ExpandPointedToStructures, bool ExpandStructures, FieldDecl *Field, - bool OutermostType = false) const; + bool OutermostType = false, + bool EncodingProperty = false) const; }; diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 057dfb7bcf..bdcb7af9c0 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1744,9 +1744,11 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, S = "T"; // Encode result type. - // FIXME: GCC uses a generating_property_type_encoding mode during - // this part. Investigate. - getObjCEncodingForType(PD->getType(), S); + // GCC has some special rules regarding encoding of properties which + // closely resembles encoding of ivars. + getObjCEncodingForTypeImpl(PD->getType(), S, true, true, NULL, + true /* outermost type */, + true /* encoding for property */); if (PD->isReadOnly()) { S += ",R"; @@ -1763,6 +1765,9 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, if (Dynamic) S += ",D"; + if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic) + S += ",N"; + if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) { S += ",G"; S += PD->getGetterName().getAsString(); @@ -1822,7 +1827,8 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, bool ExpandPointedToStructures, bool ExpandStructures, FieldDecl *FD, - bool OutermostType) const { + bool OutermostType, + bool EncodingProperty) const { if (const BuiltinType *BT = T->getAsBuiltinType()) { if (FD && FD->isBitField()) { EncodeBitField(this, S, FD); @@ -1854,10 +1860,23 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, } } else if (T->isObjCQualifiedIdType()) { - // Treat id same as 'id' for encoding purposes. - return getObjCEncodingForTypeImpl(getObjCIdType(), S, - ExpandPointedToStructures, - ExpandStructures, FD); + getObjCEncodingForTypeImpl(getObjCIdType(), S, + ExpandPointedToStructures, + ExpandStructures, FD); + if (FD || EncodingProperty) { + // Note that we do extended encoding of protocol qualifer list + // Only when doing ivar or property encoding. + const ObjCQualifiedIdType *QIDT = T->getAsObjCQualifiedIdType(); + S += '"'; + for (unsigned i =0; i < QIDT->getNumProtocols(); i++) { + ObjCProtocolDecl *Proto = QIDT->getProtocols(i); + S += '<'; + S += Proto->getNameAsString(); + S += '>'; + } + S += '"'; + } + return; } else if (const PointerType *PT = T->getAsPointerType()) { QualType PointeeTy = PT->getPointeeType(); @@ -1908,10 +1927,17 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, return; } S += '@'; - if (FD) { - ObjCInterfaceDecl *OI = PointeeTy->getAsObjCInterfaceType()->getDecl(); + if (FD || EncodingProperty) { + const ObjCInterfaceType *OIT = PointeeTy->getAsObjCInterfaceType(); + ObjCInterfaceDecl *OI = OIT->getDecl(); S += '"'; S += OI->getNameAsCString(); + for (unsigned i =0; i < OIT->getNumProtocols(); i++) { + ObjCProtocolDecl *Proto = OIT->getProtocol(i); + S += '<'; + S += Proto->getNameAsString(); + S += '>'; + } S += '"'; } return; diff --git a/test/CodeGenObjC/encode-test-2.m b/test/CodeGenObjC/encode-test-2.m new file mode 100644 index 0000000000..0df54ca0ba --- /dev/null +++ b/test/CodeGenObjC/encode-test-2.m @@ -0,0 +1,29 @@ +// RUN: clang -triple=i686-apple-darwin9 -fnext-runtime -emit-llvm -o %t %s && +// RUN: grep -e "@\\\22\\\22" %t && +// RUN: grep -e "@\\\22\\\22" %t && +// RUN: grep -e "@\\\22\\\22" %t && +// RUN: grep -e "@\\\22Foo\\\22" %t && +// RUN: grep -e "{Intf=@@@@}" %t + +@protocol X, Y, Z; +@class Foo; + +@protocol Proto +@end + +@interface Intf +{ +id IVAR_x; +id IVAR_xy; +id IVAR_xyz; +Foo *IVAR_Fooxyz; +} +@end + +@implementation Intf +@end + +int main() +{ + const char * en = @encode(Intf); +}