]> granicus.if.org Git - clang/commitdiff
Improving on encoding of objective-c's property types. More to come.
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 20 Jan 2009 19:14:18 +0000 (19:14 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 20 Jan 2009 19:14:18 +0000 (19:14 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62601 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ASTContext.h
lib/AST/ASTContext.cpp
test/CodeGenObjC/encode-test-2.m [new file with mode: 0644]

index 7707b1d21582b569b00456d13c6ae94682bf973a..32aa9157aabe348d934009679043e1f980f1baf6 100644 (file)
@@ -548,7 +548,8 @@ private:
                                   bool ExpandPointedToStructures,
                                   bool ExpandStructures,
                                   FieldDecl *Field,
-                                  bool OutermostType = false) const;
+                                  bool OutermostType = false,
+                                  bool EncodingProperty = false) const;
   
 };
   
index 057dfb7bcf170338b983d1f5a847daf6be052fa3..bdcb7af9c03a309c0f3dda41511dca724510f448 100644 (file)
@@ -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<P...> 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 (file)
index 0000000..0df54ca
--- /dev/null
@@ -0,0 +1,29 @@
+// RUN: clang -triple=i686-apple-darwin9 -fnext-runtime -emit-llvm -o %t %s &&
+// RUN: grep -e "@\\\22<X>\\\22" %t  &&
+// RUN: grep -e "@\\\22<X><Y>\\\22" %t  &&
+// RUN: grep -e "@\\\22<X><Y><Z>\\\22" %t  &&
+// RUN: grep -e "@\\\22Foo<X><Y><Z>\\\22" %t  &&
+// RUN: grep -e "{Intf=@@@@}" %t  
+
+@protocol X, Y, Z;
+@class Foo;
+
+@protocol Proto
+@end
+
+@interface Intf <Proto>
+{
+id <X> IVAR_x;
+id <X, Y> IVAR_xy;
+id <X, Y, Z> IVAR_xyz;
+Foo <X, Y, Z> *IVAR_Fooxyz;
+}
+@end
+
+@implementation Intf 
+@end
+
+int main()
+{
+       const char * en = @encode(Intf);
+}