[cfe-commits] r55390 - /cfe/trunk/lib/CodeGen/CGObjCMac.cpp

Daniel Dunbar daniel at zuster.org
Tue Aug 26 14:51:14 PDT 2008


Author: ddunbar
Date: Tue Aug 26 16:51:14 2008
New Revision: 55390

URL: http://llvm.org/viewvc/llvm-project?rev=55390&view=rev
Log:
NeXT: Emit metadata for synthetsized properties.

Also, fix method lookup to not use LLVM module symbol table.

Modified:
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Tue Aug 26 16:51:14 2008
@@ -157,6 +157,10 @@
   /// a StringMap here because have no other unique reference.
   llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
 
+  /// MethodDefinitions - map of methods which have been defined in
+  /// this translation unit.
+  llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
+
   /// PropertyNames - uniqued method variable names.
   llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
 
@@ -230,14 +234,16 @@
   /// given implementation. The return value has type ClassPtrTy.
   llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
                                 llvm::Constant *Protocols,
-                                const llvm::Type *InterfaceTy);
+                                const llvm::Type *InterfaceTy,
+                                const std::vector<llvm::Constant*> &Methods);
 
   /// EmitMethodList - Emit the method list for the given
   /// implementation. The return value has type MethodListPtrTy.
   llvm::Constant *EmitMethodList(const std::string &Name,
                                  const char *Section,
-                   llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator begin,
-                   llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator end);
+                                 const std::vector<llvm::Constant*> &Methods);
+
+  llvm::Constant *GetMethodConstant(ObjCMethodDecl *MD);
 
   /// EmitMethodDescList - Emit a method description list for a list of
   /// method declarations. 
@@ -298,7 +304,7 @@
   /// selector's name. The return value has type char *.
 
   // FIXME: This is a horrible name.
-  llvm::Constant *GetMethodVarType(ObjCMethodDecl *D);
+  llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D);
   llvm::Constant *GetMethodVarType(const std::string &Name);
 
   /// GetPropertyName - Return a unique constant for the given
@@ -786,6 +792,18 @@
                       "_" +
                       OCD->getName());
 
+  std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
+  for (ObjCCategoryImplDecl::instmeth_iterator i = OCD->instmeth_begin(),
+         e = OCD->instmeth_end(); i != e; ++i) {
+    // Instance methods should always be defined.
+    InstanceMethods.push_back(GetMethodConstant(*i));
+  }
+  for (ObjCCategoryImplDecl::classmeth_iterator i = OCD->classmeth_begin(),
+         e = OCD->classmeth_end(); i != e; ++i) {
+    // Class methods should always be defined.
+    ClassMethods.push_back(GetMethodConstant(*i));
+  }
+
   std::vector<llvm::Constant*> Values(7);
   Values[0] = GetClassName(OCD->getIdentifier());
   Values[1] = GetClassName(Interface->getIdentifier());
@@ -793,13 +811,11 @@
     EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") + 
                    ExtName,
                    "__OBJC,__cat_inst_meth,regular,no_dead_strip",
-                   OCD->instmeth_begin(),
-                   OCD->instmeth_end());
+                   InstanceMethods);
   Values[3] = 
     EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName,
                    "__OBJC,__cat_class_meth,regular,no_dead_strip",
-                   OCD->classmeth_begin(),
-                   OCD->classmeth_end());
+                   ClassMethods);
   Values[4] = 
     EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName,
                      Interface->protocol_begin(),
@@ -892,8 +908,36 @@
   if (IsClassHidden(ID->getClassInterface()))
     Flags |= eClassFlags_Hidden;
 
+  std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
+  for (ObjCImplementationDecl::instmeth_iterator i = ID->instmeth_begin(),
+         e = ID->instmeth_end(); i != e; ++i) {
+    // Instance methods should always be defined.
+    InstanceMethods.push_back(GetMethodConstant(*i));
+  }
+  for (ObjCImplementationDecl::classmeth_iterator i = ID->classmeth_begin(),
+         e = ID->classmeth_end(); i != e; ++i) {
+    // Class methods should always be defined.
+    ClassMethods.push_back(GetMethodConstant(*i));
+  }
+
+  for (ObjCImplementationDecl::propimpl_iterator i = ID->propimpl_begin(),
+         e = ID->propimpl_end(); i != e; ++i) {
+    ObjCPropertyImplDecl *PID = *i;
+
+    if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
+      ObjCPropertyDecl *PD = PID->getPropertyDecl();
+
+      if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
+        if (llvm::Constant *C = GetMethodConstant(MD))
+          InstanceMethods.push_back(C);
+      if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
+        if (llvm::Constant *C = GetMethodConstant(MD))
+          InstanceMethods.push_back(C);
+    }
+  }
+
   std::vector<llvm::Constant*> Values(12);
-  Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy);
+  Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy, ClassMethods);
   if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
     // Record a reference to the super class.
     LazySymbols.insert(Super->getIdentifier());
@@ -913,8 +957,7 @@
   Values[ 7] = 
     EmitMethodList(std::string("\01L_OBJC_INSTANCE_METHODS_") + ID->getName(),
                    "__OBJC,__inst_meth,regular,no_dead_strip",
-                   ID->instmeth_begin(),
-                   ID->instmeth_end());
+                   InstanceMethods);
   // cache is always NULL.
   Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
   Values[ 9] = Protocols;
@@ -939,7 +982,8 @@
 
 llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
                                          llvm::Constant *Protocols,
-                                         const llvm::Type *InterfaceTy) {
+                                         const llvm::Type *InterfaceTy,
+                                  const std::vector<llvm::Constant*> &Methods) {
   const char *ClassName = ID->getName();
   unsigned Flags = eClassFlags_Meta;
   unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy);
@@ -974,8 +1018,7 @@
   Values[ 7] = 
     EmitMethodList(std::string("\01L_OBJC_CLASS_METHODS_") + ID->getName(),
                    "__OBJC,__inst_meth,regular,no_dead_strip",
-                   ID->classmeth_begin(),
-                   ID->classmeth_end());
+                   Methods);
   // cache is always NULL.
   Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
   Values[ 9] = Protocols;
@@ -1163,30 +1206,29 @@
     struct objc_method methods_list[count];
   };
 */
-llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name,
-                                          const char *Section,
-                   llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator begin,
-                   llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator end) {
-  std::vector<llvm::Constant*> Methods, Method(3);
 
-  for (; begin != end; ++begin) {
-    ObjCMethodDecl *MD = *begin;
-
-    Method[0] = 
-      llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
-                                     ObjCTypes.SelectorPtrTy);
-    Method[1] = GetMethodVarType(MD);
-
-    // FIXME: This is gross, we shouldn't be looking up by name.
-    std::string Name;
-    GetNameForMethod(MD, Name);
-    Method[2] = 
-      llvm::ConstantExpr::getBitCast(CGM.getModule().getFunction(Name),
-                                     ObjCTypes.Int8PtrTy);
-    Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodTy,
-                                                Method));
-  }
+/// GetMethodConstant - Return a struct objc_method constant for the
+/// given method if it has been defined. The result is null if the
+/// method has not been defined. The return value has type MethodPtrTy.
+llvm::Constant *CGObjCMac::GetMethodConstant(ObjCMethodDecl *MD) {
+  // FIXME: Use DenseMap::lookup
+  llvm::Function *Fn = MethodDefinitions[MD];
+  if (!Fn)
+    return 0;
+  
+  std::vector<llvm::Constant*> Method(3);
+  Method[0] = 
+    llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
+                                   ObjCTypes.SelectorPtrTy);
+  Method[1] = GetMethodVarType(MD);
+  Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy);
+  return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
+}
 
+llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name,
+                                          const char *Section,
+                                          const std::vector<llvm::Constant*> 
+                                            &Methods) {
   // Return null for empty list.
   if (Methods.empty())
     return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
@@ -1254,6 +1296,7 @@
                            llvm::GlobalValue::InternalLinkage,
                            Name,
                            &CGM.getModule());
+  MethodDefinitions.insert(std::make_pair(OMD, Method));
 
   unsigned Offset = 3; // Return plus self and selector implicit args.
   if (useStructRet) {
@@ -1507,9 +1550,10 @@
 }
 
 // FIXME: Merge into a single cstring creation function.
-llvm::Constant *CGObjCMac::GetMethodVarType(ObjCMethodDecl *D) {
+llvm::Constant *CGObjCMac::GetMethodVarType(const ObjCMethodDecl *D) {
   std::string TypeStr;
-  CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
+  CGM.getContext().getObjCEncodingForMethodDecl(const_cast<ObjCMethodDecl*>(D),
+                                                TypeStr);
   return GetMethodVarType(TypeStr);
 }
 





More information about the cfe-commits mailing list