[cfe-commits] r55461 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/CodeGen/CGObjCMac.cpp

Daniel Dunbar daniel at zuster.org
Wed Aug 27 21:38:11 PDT 2008


Author: ddunbar
Date: Wed Aug 27 23:38:10 2008
New Revision: 55461

URL: http://llvm.org/viewvc/llvm-project?rev=55461&view=rev
Log:
NeXT: Emit mostly-correct property type encoding.
 - Added ASTContext::getObjCEncodingForPropertyDecl.

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=55461&r1=55460&r2=55461&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Wed Aug 27 23:38:10 2008
@@ -38,6 +38,7 @@
   class SourceManager;
   // Decls
   class Decl;
+  class ObjCPropertyDecl;
   class RecordDecl;
   class TagDecl;
   class TranslationUnitDecl;
@@ -277,7 +278,15 @@
   
   /// getObjCEncodingForMethodDecl - Return the encoded type for this method
   /// declaration.
-  void getObjCEncodingForMethodDecl(ObjCMethodDecl *Decl, std::string &S);
+  void getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S);
+  
+  /// getObjCEncodingForPropertyDecl - Return the encoded type for
+  /// this method declaration. If non-NULL, Container must be either
+  /// an ObjCCategoryImplDecl or ObjCImplementationDecl; it should
+  /// only be NULL when getting encodings for protocol properties.
+  void getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *Decl, 
+                                      const Decl *Container,
+                                      std::string &S);
   
   /// getObjCEncodingTypeSize returns size of type for objective-c encoding
   /// purpose.

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=55461&r1=55460&r2=55461&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Aug 27 23:38:10 2008
@@ -1396,9 +1396,10 @@
 
 /// getObjCEncodingForMethodDecl - Return the encoded type for this method
 /// declaration.
-void ASTContext::getObjCEncodingForMethodDecl(ObjCMethodDecl *Decl, 
+void ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, 
                                               std::string& S)
 {
+  // FIXME: This is not very efficient.
   // Encode type qualifer, 'in', 'inout', etc. for the return type.
   getObjCEncodingForTypeQualifier(Decl->getObjCDeclQualifier(), S);
   // Encode result type.
@@ -1436,6 +1437,91 @@
   }
 }
 
+/// getObjCEncodingForPropertyDecl - Return the encoded type for this
+/// method declaration. If non-NULL, Container must be either an
+/// ObjCCategoryImplDecl or ObjCImplementationDecl; it should only be
+/// NULL when getting encodings for protocol properties.
+void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, 
+                                                const Decl *Container,
+                                                std::string& S)
+{
+  // Collect information from the property implementation decl(s).
+  bool Dynamic = false;
+  ObjCPropertyImplDecl *SynthesizePID = 0;
+
+  // FIXME: Duplicated code due to poor abstraction.
+  if (Container) {
+    if (const ObjCCategoryImplDecl *CID = 
+        dyn_cast<ObjCCategoryImplDecl>(Container)) {
+      for (ObjCCategoryImplDecl::propimpl_iterator
+             i = CID->propimpl_begin(), e = CID->propimpl_end(); i != e; ++i) {
+        ObjCPropertyImplDecl *PID = *i;
+        if (PID->getPropertyDecl() == PD) {
+          if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
+            Dynamic = true;
+          } else {
+            SynthesizePID = PID;
+          }
+        }
+      }
+    } else {
+      const ObjCImplementationDecl *OID = cast<ObjCImplementationDecl>(Container);
+      for (ObjCCategoryImplDecl::propimpl_iterator
+             i = OID->propimpl_begin(), e = OID->propimpl_end(); i != e; ++i) {
+        ObjCPropertyImplDecl *PID = *i;
+        if (PID->getPropertyDecl() == PD) {
+          if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
+            Dynamic = true;
+          } else {
+            SynthesizePID = PID;
+          }
+        }
+      }      
+    }
+  }
+
+  // FIXME: This is not very efficient.
+  S = "T";
+
+  // Encode result type.
+  // FIXME: GCC uses a generating_property_type_encoding mode during
+  // this part. Investigate.
+  getObjCEncodingForType(PD->getType(), S, EncodingRecordTypes);
+
+  if (PD->isReadOnly()) {
+    S += ",R";
+  } else {
+    switch (PD->getSetterKind()) {
+    case ObjCPropertyDecl::Assign: break;
+    case ObjCPropertyDecl::Copy:   S += ",C"; break;
+    case ObjCPropertyDecl::Retain: S += ",&"; break;      
+    }
+  }
+
+  // It really isn't clear at all what this means, since properties
+  // are "dynamic by default".
+  if (Dynamic)
+    S += ",D";
+
+  if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) {
+    S += ",G";
+    S += PD->getGetterName().getName();
+  }
+
+  if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) {
+    S += ",S";
+    S += PD->getSetterName().getName();
+  }
+
+  if (SynthesizePID) {
+    const ObjCIvarDecl *OID = SynthesizePID->getPropertyIvarDecl();
+    S += ",V";
+    S += OID->getName();
+  }
+
+  // FIXME: OBJCGC: weak & strong
+}
+
 void ASTContext::getObjCEncodingForType(QualType T, std::string& S,
        llvm::SmallVector<const RecordType *, 8> &ERType) const {
   // FIXME: This currently doesn't encode:

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=55461&r1=55460&r2=55461&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Wed Aug 27 23:38:10 2008
@@ -267,6 +267,7 @@
   /// EmitPropertyList - Emit the given property list. The return
   /// value has type PropertyListPtrTy.
   llvm::Constant *EmitPropertyList(const std::string &Name,
+                                   const Decl *Container,
                                    ObjCPropertyDecl * const *begin,
                                    ObjCPropertyDecl * const *end);
 
@@ -315,8 +316,9 @@
   /// name. The return value has type char *.
   llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
 
-  // FIXME: This is a horrible name too.
-  llvm::Constant *GetPropertyType(const ObjCPropertyDecl *PD);
+  // FIXME: This can be dropped once string functions are unified.
+  llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
+                                        const Decl *Container);
 
   /// GetNameForMethod - Return a name for the given method.
   /// \param[out] NameOut - The return value.
@@ -623,6 +625,7 @@
                        OptClassMethods);
   Values[3] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_PROTO_LIST_") + 
                                PD->getName(),
+                               0,
                                PD->classprop_begin(),
                                PD->classprop_end());
 
@@ -702,13 +705,14 @@
   };
 */
 llvm::Constant *CGObjCMac::EmitPropertyList(const std::string &Name,
+                                            const Decl *Container,
                                             ObjCPropertyDecl * const *begin,
                                             ObjCPropertyDecl * const *end) {
   std::vector<llvm::Constant*> Properties, Prop(2);
   for (; begin != end; ++begin) {
     const ObjCPropertyDecl *PD = *begin;
     Prop[0] = GetPropertyName(PD->getIdentifier());
-    Prop[1] = GetPropertyType(PD);
+    Prop[1] = GetPropertyTypeString(PD, Container);
     Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
                                                    Prop));
   }
@@ -843,6 +847,7 @@
   // If there is no category @interface then there can be no properties.
   if (Category) {
     Values[6] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + ExtName,
+                                 OCD,
                                  Category->classprop_begin(),
                                  Category->classprop_end());
   } else {
@@ -1120,6 +1125,7 @@
   Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
   Values[2] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + 
                                ID->getName(),
+                               ID,
                                ID->getClassInterface()->classprop_begin(),
                                ID->getClassInterface()->classprop_end());
 
@@ -1599,9 +1605,11 @@
 }
 
 // FIXME: Merge into a single cstring creation function.
-llvm::Constant *CGObjCMac::GetPropertyType(const ObjCPropertyDecl *PD) {
-  std::string TypeStr("MOOO!");
-  //CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
+// FIXME: This Decl should be more precise.
+llvm::Constant *CGObjCMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
+                                                 const Decl *Container) {
+  std::string TypeStr;
+  CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
   return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
 }
 
@@ -1650,7 +1658,7 @@
   }
   for (std::set<IdentifierInfo*>::iterator i = DefinedSymbols.begin(),
          e = DefinedSymbols.end(); i != e; ++i) {
-    s << "\t.objc_class_name_" << (*i)->getName() << " = 0\n"
+    s << "\t.objc_class_name_" << (*i)->getName() << "=0\n"
       << "\t.globl .objc_class_name_" << (*i)->getName() << "\n";
   }  
   CGM.getModule().appendModuleInlineAsm(s.str());





More information about the cfe-commits mailing list