[cfe-commits] r54824 - in /cfe/trunk/lib/CodeGen: CGObjC.cpp CGObjCGNU.cpp CGObjCMac.cpp CGObjCRuntime.h CodeGenModule.cpp

Daniel Dunbar daniel at zuster.org
Fri Aug 15 15:20:33 PDT 2008


Author: ddunbar
Date: Fri Aug 15 17:20:32 2008
New Revision: 54824

URL: http://llvm.org/viewvc/llvm-project?rev=54824&view=rev
Log:
Change CGObjCRuntime methods to take appropriate clang Decls.
 - This is in prep for implementation class support for the NeXT
   runtime, for which the existing methods don't provide enough
   information (and additionally make too many assumptions about how
   things should be emitted).

Modified:
    cfe/trunk/lib/CodeGen/CGObjC.cpp
    cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp
    cfe/trunk/lib/CodeGen/CGObjCRuntime.h
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Fri Aug 15 17:20:32 2008
@@ -103,33 +103,7 @@
 /// Generate an Objective-C method.  An Objective-C method is a C function with
 /// its pointer, name, and types registered in the class struture.  
 void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
-
-  llvm::SmallVector<const llvm::Type *, 16> ParamTypes;
-  for (unsigned i=0 ; i<OMD->param_size() ; i++) {
-    const llvm::Type *Ty = ConvertType(OMD->getParamDecl(i)->getType());
-    if (Ty->isFirstClassType())
-      ParamTypes.push_back(Ty);
-    else
-      ParamTypes.push_back(llvm::PointerType::getUnqual(Ty));
-  }
-  std::string CategoryName = "";
-  if (ObjCCategoryImplDecl *OCD =
-      dyn_cast<ObjCCategoryImplDecl>(OMD->getMethodContext())) {
-    CategoryName = OCD->getName();
-  }
-  const llvm::Type *ReturnTy = 
-    CGM.getTypes().ConvertReturnType(OMD->getResultType());
-  CurFn = CGM.getObjCRuntime().MethodPreamble(
-                                          OMD->getClassInterface()->getName(),
-                                              CategoryName,
-                                              OMD->getSelector().getName(),
-                                              ReturnTy,
-                                              llvm::PointerType::getUnqual(
-                                              llvm::Type::Int32Ty),
-                                              ParamTypes.begin(),
-                                              OMD->param_size(),
-                                              !OMD->isInstance(),
-                                              OMD->isVariadic());
+  CurFn = CGM.getObjCRuntime().GenerateMethod(OMD);
   llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn);
   
   // Create a marker to make it easy to insert allocas into the entryblock

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Fri Aug 15 17:20:32 2008
@@ -20,10 +20,11 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "llvm/Module.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/IRBuilder.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/IRBuilder.h"
+#include "llvm/Target/TargetData.h"
 #include <map>
 using namespace clang;
 using llvm::dyn_cast;
@@ -109,34 +110,9 @@
                                    llvm::Value *ClassName);
   virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
   
-  virtual llvm::Function *MethodPreamble(
-                                         const std::string &ClassName,
-                                         const std::string &CategoryName,
-                                         const std::string &MethodName,
-                                         const llvm::Type *ReturnTy,
-                                         const llvm::Type *SelfTy,
-                                         const llvm::Type **ArgTy,
-                                         unsigned ArgC,
-                                         bool isClassMethod,
-                                         bool isVarArg);
-  virtual void GenerateCategory(const char *ClassName, const char *CategoryName,
-           const llvm::SmallVectorImpl<Selector>  &InstanceMethodSels,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &InstanceMethodTypes,
-           const llvm::SmallVectorImpl<Selector>  &ClassMethodSels,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodTypes,
-           const llvm::SmallVectorImpl<std::string> &Protocols);
-  virtual void GenerateClass(
-           const char *ClassName,
-           const char *SuperClassName,
-           const int instanceSize,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &IvarNames,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &IvarTypes,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &IvarOffsets,
-           const llvm::SmallVectorImpl<Selector>  &InstanceMethodSels,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &InstanceMethodTypes,
-           const llvm::SmallVectorImpl<Selector>  &ClassMethodSels,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodTypes,
-           const llvm::SmallVectorImpl<std::string> &Protocols);
+  virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
+  virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
+  virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
   virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
                                            const ObjCProtocolDecl *PD);
   virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
@@ -623,14 +599,39 @@
           ".objc_protocol"), IdTy);
 }
 
-void CGObjCGNU::GenerateCategory(
-           const char *ClassName,
-           const char *CategoryName,
-           const llvm::SmallVectorImpl<Selector>  &InstanceMethodSels,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &InstanceMethodTypes,
-           const llvm::SmallVectorImpl<Selector>  &ClassMethodSels,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodTypes,
-           const llvm::SmallVectorImpl<std::string> &Protocols) {
+void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
+  const char *ClassName = OCD->getClassInterface()->getName();
+  const char *CategoryName = OCD->getName();
+  // Collect information about instance methods
+  llvm::SmallVector<Selector, 16> InstanceMethodSels;
+  llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
+  for (ObjCCategoryDecl::instmeth_iterator iter = OCD->instmeth_begin(),
+      endIter = OCD->instmeth_end() ; iter != endIter ; iter++) {
+    InstanceMethodSels.push_back((*iter)->getSelector());
+    std::string TypeStr;
+    CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr);
+    InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
+  }
+
+  // Collect information about class methods
+  llvm::SmallVector<Selector, 16> ClassMethodSels;
+  llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
+  for (ObjCCategoryDecl::classmeth_iterator iter = OCD->classmeth_begin(),
+      endIter = OCD->classmeth_end() ; iter != endIter ; iter++) {
+    ClassMethodSels.push_back((*iter)->getSelector());
+    std::string TypeStr;
+    CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr);
+    ClassMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
+  }
+
+  // Collect the names of referenced protocols
+  llvm::SmallVector<std::string, 16> Protocols;
+  const ObjCInterfaceDecl *ClassDecl = OCD->getClassInterface();
+  const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols();
+  for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(),
+       E = Protos.end(); I != E; ++I)
+    Protocols.push_back((*I)->getName());
+
   std::vector<llvm::Constant*> Elements;
   Elements.push_back(MakeConstantString(CategoryName));
   Elements.push_back(MakeConstantString(ClassName));
@@ -649,18 +650,89 @@
         MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, PtrTy,
             PtrTy, PtrTy, NULL), Elements), PtrTy));
 }
-void CGObjCGNU::GenerateClass(
-           const char *ClassName,
-           const char *SuperClassName,
-           const int instanceSize,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &IvarNames,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &IvarTypes,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &IvarOffsets,
-           const llvm::SmallVectorImpl<Selector>  &InstanceMethodSels,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &InstanceMethodTypes,
-           const llvm::SmallVectorImpl<Selector>  &ClassMethodSels,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodTypes,
-           const llvm::SmallVectorImpl<std::string> &Protocols) {
+
+void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
+  ASTContext &Context = CGM.getContext();
+
+  // Get the superclass name.
+  const ObjCInterfaceDecl * SuperClassDecl = 
+    OID->getClassInterface()->getSuperClass();
+  const char * SuperClassName = NULL;
+  if (SuperClassDecl) {
+    SuperClassName = SuperClassDecl->getName();
+  }
+
+  // Get the class name
+  ObjCInterfaceDecl * ClassDecl = (ObjCInterfaceDecl*)OID->getClassInterface();
+  const char * ClassName = ClassDecl->getName();
+
+  // Get the size of instances.  For runtimes that support late-bound instances
+  // this should probably be something different (size just of instance
+  // varaibles in this class, not superclasses?).
+  int instanceSize = 0;
+  const llvm::Type *ObjTy = 0;
+  if (!LateBoundIVars()) {
+    ObjTy = CGM.getTypes().ConvertType(Context.getObjCInterfaceType(ClassDecl));
+    instanceSize = CGM.getTargetData().getABITypeSize(ObjTy);
+  } else {
+    // This is required by newer ObjC runtimes.
+    assert(0 && "Late-bound instance variables not yet supported");
+  }
+
+  // Collect information about instance variables.
+  llvm::SmallVector<llvm::Constant*, 16> IvarNames;
+  llvm::SmallVector<llvm::Constant*, 16> IvarTypes;
+  llvm::SmallVector<llvm::Constant*, 16> IvarOffsets;
+  const llvm::StructLayout *Layout =
+    CGM.getTargetData().getStructLayout(cast<llvm::StructType>(ObjTy));
+  ObjTy = llvm::PointerType::getUnqual(ObjTy);
+  for (ObjCInterfaceDecl::ivar_iterator iter = ClassDecl->ivar_begin(),
+      endIter = ClassDecl->ivar_end() ; iter != endIter ; iter++) {
+      // Store the name
+      IvarNames.push_back(CGM.GetAddrOfConstantCString((*iter)->getName()));
+      // Get the type encoding for this ivar
+      std::string TypeStr;
+      llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
+      Context.getObjCEncodingForType((*iter)->getType(), TypeStr,
+                                     EncodingRecordTypes);
+      IvarTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
+      // Get the offset
+      int offset =
+        (int)Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(*iter));
+      IvarOffsets.push_back(
+          llvm::ConstantInt::get(llvm::Type::Int32Ty, offset));
+  }
+
+  // Collect information about instance methods
+  llvm::SmallVector<Selector, 16> InstanceMethodSels;
+  llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
+  for (ObjCImplementationDecl::instmeth_iterator iter = OID->instmeth_begin(),
+      endIter = OID->instmeth_end() ; iter != endIter ; iter++) {
+    InstanceMethodSels.push_back((*iter)->getSelector());
+    std::string TypeStr;
+    Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
+    InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
+  }
+
+  // Collect information about class methods
+  llvm::SmallVector<Selector, 16> ClassMethodSels;
+  llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
+  for (ObjCImplementationDecl::classmeth_iterator iter = OID->classmeth_begin(),
+      endIter = OID->classmeth_end() ; iter != endIter ; iter++) {
+    ClassMethodSels.push_back((*iter)->getSelector());
+    std::string TypeStr;
+    Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
+    ClassMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
+  }
+  // Collect the names of referenced protocols
+  llvm::SmallVector<std::string, 16> Protocols;
+  const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols();
+  for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(),
+       E = Protos.end(); I != E; ++I)
+    Protocols.push_back((*I)->getName());
+
+
+
   // Get the superclass pointer.
   llvm::Constant *SuperClass;
   if (SuperClassName) {
@@ -834,16 +906,30 @@
   Builder.CreateRetVoid();
   return LoadFunction;
 }
-llvm::Function *CGObjCGNU::MethodPreamble(
-                                         const std::string &ClassName,
-                                         const std::string &CategoryName,
-                                         const std::string &MethodName,
-                                         const llvm::Type *ReturnTy,
-                                         const llvm::Type *SelfTy,
-                                         const llvm::Type **ArgTy,
-                                         unsigned ArgC,
-                                         bool isClassMethod,
-                                         bool isVarArg) {
+
+llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD) {  
+  const llvm::Type *ReturnTy = 
+    CGM.getTypes().ConvertReturnType(OMD->getResultType());
+  const ObjCCategoryImplDecl *OCD = 
+    dyn_cast<ObjCCategoryImplDecl>(OMD->getMethodContext());
+  const std::string &CategoryName = OCD ? OCD->getName() : "";
+  const llvm::Type *SelfTy = llvm::PointerType::getUnqual(llvm::Type::Int32Ty);
+  const std::string &ClassName = OMD->getClassInterface()->getName();
+  const std::string &MethodName = OMD->getSelector().getName();
+  unsigned ArgC = OMD->param_size();
+  bool isClassMethod = !OMD->isInstance();
+  bool isVarArg = OMD->isVariadic();
+
+  llvm::SmallVector<const llvm::Type *, 16> ArgTy;
+  for (unsigned i=0 ; i<OMD->param_size() ; i++) {
+    const llvm::Type *Ty = 
+      CGM.getTypes().ConvertType(OMD->getParamDecl(i)->getType());
+    if (Ty->isFirstClassType())
+      ArgTy.push_back(Ty);
+    else
+      ArgTy.push_back(llvm::PointerType::getUnqual(Ty));
+  }
+
   std::vector<const llvm::Type*> Args;
   if (!ReturnTy->isSingleValueType() && ReturnTy != llvm::Type::VoidTy) {
     Args.push_back(llvm::PointerType::getUnqual(ReturnTy));
@@ -851,7 +937,7 @@
   }
   Args.push_back(SelfTy);
   Args.push_back(SelectorTy);
-  Args.insert(Args.end(), ArgTy, ArgTy+ArgC);
+  Args.insert(Args.end(), ArgTy.begin(), ArgTy.begin()+ArgC);
 
   llvm::FunctionType *MethodTy = llvm::FunctionType::get(ReturnTy,
       Args,

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Fri Aug 15 17:20:32 2008
@@ -218,35 +218,11 @@
 
   virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
   
-  virtual llvm::Function *MethodPreamble(const std::string &ClassName,
-                                         const std::string &CategoryName,
-                                         const std::string &MethodName,
-                                         const llvm::Type *ReturnTy,
-                                         const llvm::Type *SelfTy,
-                                         const llvm::Type **ArgTy,
-                                         unsigned ArgC,
-                                         bool isClassMethod,
-                                         bool isVarArg);
-
-  virtual void GenerateCategory(const char *ClassName, const char *CategoryName,
-           const llvm::SmallVectorImpl<Selector>  &InstanceMethodSels,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &InstanceMethodTypes,
-           const llvm::SmallVectorImpl<Selector>  &ClassMethodSels,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodTypes,
-           const llvm::SmallVectorImpl<std::string> &Protocols);
-
-  virtual void GenerateClass(
-           const char *ClassName,
-           const char *SuperClassName,
-           const int instanceSize,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &IvarNames,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &IvarTypes,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &IvarOffsets,
-           const llvm::SmallVectorImpl<Selector>  &InstanceMethodSels,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &InstanceMethodTypes,
-           const llvm::SmallVectorImpl<Selector>  &ClassMethodSels,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodTypes,
-           const llvm::SmallVectorImpl<std::string> &Protocols);
+  virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
+
+  virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
+
+  virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
 
   virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
                                            const ObjCProtocolDecl *PD);
@@ -370,7 +346,17 @@
   Args[0] = Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
   Args[1] = EmitSelector(Builder, Sel);
   std::copy(ArgV, ArgV+ArgC, Args+2);
-  llvm::CallInst *CI = Builder.CreateCall(F, Args, Args+ArgC+2, "tmp");
+
+  std::vector<const llvm::Type*> Params;
+  Params.push_back(ObjCTypes.ObjectPtrTy);
+  Params.push_back(ObjCTypes.SelectorPtrTy);
+  llvm::FunctionType *CallFTy = llvm::FunctionType::get(ReturnTy,
+                                                        Params,
+                                                        true);
+  llvm::Type *PCallFTy = llvm::PointerType::getUnqual(CallFTy);
+  llvm::Constant *C = llvm::ConstantExpr::getBitCast(F, PCallFTy);
+  llvm::CallInst *CI = Builder.CreateCall(C, 
+                                          Args, Args+ArgC+2, "tmp");
   delete[] Args;
   return Builder.CreateBitCast(CI, ReturnTy, "tmp");
 }
@@ -613,29 +599,11 @@
                                         ObjCTypes.MethodDescriptionListPtrTy);
 }
 
-void CGObjCMac::GenerateCategory(
-           const char *ClassName,
-           const char *CategoryName,
-           const llvm::SmallVectorImpl<Selector>  &InstanceMethodSels,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &InstanceMethodTypes,
-           const llvm::SmallVectorImpl<Selector>  &ClassMethodSels,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodTypes,
-           const llvm::SmallVectorImpl<std::string> &Protocols) {
+void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
   assert(0 && "Cannot generate category for Mac runtime.");
 }
 
-void CGObjCMac::GenerateClass(
-           const char *ClassName,
-           const char *SuperClassName,
-           const int instanceSize,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &IvarNames,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &IvarTypes,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &IvarOffsets,
-           const llvm::SmallVectorImpl<Selector>  &InstanceMethodSels,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &InstanceMethodTypes,
-           const llvm::SmallVectorImpl<Selector>  &ClassMethodSels,
-           const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodTypes,
-           const llvm::SmallVectorImpl<std::string> &Protocols) {
+void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ClassDecl) {
   assert(0 && "Cannot generate class for Mac runtime.");
 }
 
@@ -646,15 +614,7 @@
   return NULL;
 }
 
-llvm::Function *CGObjCMac::MethodPreamble(const std::string &ClassName,
-                                          const std::string &CategoryName,
-                                          const std::string &MethodName,
-                                          const llvm::Type *ReturnTy,
-                                          const llvm::Type *SelfTy,
-                                          const llvm::Type **ArgTy,
-                                          unsigned ArgC,
-                                          bool isClassMethod,
-                                          bool isVarArg) {
+llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
   assert(0 && "Cannot generate method preamble for Mac runtime.");
   return 0;
 }
@@ -724,7 +684,7 @@
   std::vector<llvm::Constant*> Values(4);
   Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
   Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
-    // FIXME: GCC just appears to make up an empty name for this? Why?
+  // This used to be the filename, now it is unused. <rdr://4327263>
   Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
   Values[3] = EmitModuleSymbols();
 

Modified: cfe/trunk/lib/CodeGen/CGObjCRuntime.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCRuntime.h?rev=54824&r1=54823&r2=54824&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCRuntime.h (original)
+++ cfe/trunk/lib/CodeGen/CGObjCRuntime.h Fri Aug 15 17:20:32 2008
@@ -29,6 +29,9 @@
 }
 
 namespace clang {
+  class ObjCCategoryImplDecl;
+  class ObjCImplementationDecl;
+  class ObjCMethodDecl;
   class ObjCProtocolDecl;
   class Selector;
 
@@ -44,49 +47,37 @@
 
 public:
   virtual ~CGObjCRuntime();
-  
-  /// Generate an Objective-C message send operation
-  virtual llvm::Value *GenerateMessageSend(BuilderType &Builder,
-                                           const llvm::Type *ReturnTy,
-                                           llvm::Value *Receiver,
-                                           Selector Sel,
-                                           llvm::Value** ArgV,
-                                           unsigned ArgC) =0;
 
   /// Generate the function required to register all Objective-C components in
   /// this compilation unit with the runtime library.
-  virtual llvm::Function *ModuleInitFunction() =0;
+  virtual llvm::Function *ModuleInitFunction() = 0;
 
-  /// Get a selector for the specified name and type values
+  /// Get a selector for the specified name and type values. The
+  /// return value should have the LLVM type for pointer-to
+  /// ASTContext::getObjCSelType().
   virtual llvm::Value *GetSelector(BuilderType &Builder,
-                                   Selector Sel) =0;
+                                   Selector Sel) = 0;
 
-  /// Generate a constant string object
+  /// Generate a constant string object.
   virtual llvm::Constant *GenerateConstantString(const std::string &String) = 0;
 
   /// Generate a category.  A category contains a list of methods (and
   /// accompanying metadata) and a list of protocols.
-  virtual void GenerateCategory(const char *ClassName, const char *CategoryName,
-             const llvm::SmallVectorImpl<Selector>  &InstanceMethodSels,
-             const llvm::SmallVectorImpl<llvm::Constant *>  &InstanceMethodTypes,
-             const llvm::SmallVectorImpl<Selector>  &ClassMethodSels,
-             const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodTypes,
-             const llvm::SmallVectorImpl<std::string> &Protocols) =0;
+  virtual void GenerateCategory(const ObjCCategoryImplDecl *OCD) = 0;
 
   /// Generate a class stucture for this class.
-  virtual void GenerateClass(
-             const char *ClassName,
-             const char *SuperClassName,
-             const int instanceSize,
-             const llvm::SmallVectorImpl<llvm::Constant *>  &IvarNames,
-             const llvm::SmallVectorImpl<llvm::Constant *>  &IvarTypes,
-             const llvm::SmallVectorImpl<llvm::Constant *>  &IvarOffsets,
-             const llvm::SmallVectorImpl<Selector>  &InstanceMethodSels,
-             const llvm::SmallVectorImpl<llvm::Constant *>  &InstanceMethodTypes,
-             const llvm::SmallVectorImpl<Selector>  &ClassMethodSels,
-             const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodTypes,
-             const llvm::SmallVectorImpl<std::string> &Protocols) =0;
+  virtual void GenerateClass(const ObjCImplementationDecl *OID) = 0;
+  
+  /// Generate an Objective-C message send operation.
+  virtual llvm::Value *GenerateMessageSend(BuilderType &Builder,
+                                           const llvm::Type *ReturnTy,
+                                           llvm::Value *Receiver,
+                                           Selector Sel,
+                                           llvm::Value** ArgV,
+                                           unsigned ArgC) = 0;
 
+  /// Generate an Objective-C message send operation to the super
+  /// class.
   virtual llvm::Value *GenerateMessageSendSuper(llvm::IRBuilder<true> &Builder,
                                                 const llvm::Type *ReturnTy,
                                                 const char *SuperClassName,
@@ -98,27 +89,24 @@
   /// Emit the code to return the named protocol as an object, as in a
   /// @protocol expression.
   virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<true> &Builder,
-                                           const ObjCProtocolDecl *PD) = 0;
+                                           const ObjCProtocolDecl *OPD) = 0;
 
   /// Generate the named protocol.  Protocols contain method metadata but no 
   /// implementations. 
-  virtual void GenerateProtocol(const ObjCProtocolDecl *PD) = 0;
+  virtual void GenerateProtocol(const ObjCProtocolDecl *OPD) = 0;
+
+  /// Generate a function preamble for a method with the specified
+  /// types.  
 
-  /// Generate a function preamble for a method with the specified types
-  virtual llvm::Function *MethodPreamble(
-                                         const std::string &ClassName,
-                                         const std::string &CategoryName,
-                                         const std::string &MethodName,
-                                         const llvm::Type *ReturnTy,
-                                         const llvm::Type *SelfTy,
-                                         const llvm::Type **ArgTy,
-                                         unsigned ArgC,
-                                         bool isClassMethod,
-                                         bool isVarArg) = 0;
+  // FIXME: Current this just generates the Function definition, but
+  // really this should also be generating the loads of the
+  // parameters, as the runtime should have full control over how
+  // parameters are passed.
+  virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD) = 0;
 
   /// Look up the class for the specified name
   virtual llvm::Value *LookupClass(BuilderType &Builder, 
-                                   llvm::Value *ClassName) =0;
+                                   llvm::Value *ClassName) = 0;
 
   /// If instance variable addresses are determined at runtime then this should
   /// return true, otherwise instance variables will be accessed directly from

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Aug 15 17:20:32 2008
@@ -252,125 +252,12 @@
 }
 
 void CodeGenModule::EmitObjCCategoryImpl(const ObjCCategoryImplDecl *OCD) {
+  Runtime->GenerateCategory(OCD);
+}
 
-  // Collect information about instance methods
-  llvm::SmallVector<Selector, 16> InstanceMethodSels;
-  llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
-  for (ObjCCategoryDecl::instmeth_iterator iter = OCD->instmeth_begin(),
-      endIter = OCD->instmeth_end() ; iter != endIter ; iter++) {
-    InstanceMethodSels.push_back((*iter)->getSelector());
-    std::string TypeStr;
-    Context.getObjCEncodingForMethodDecl(*iter,TypeStr);
-    InstanceMethodTypes.push_back(GetAddrOfConstantCString(TypeStr));
-  }
-
-  // Collect information about class methods
-  llvm::SmallVector<Selector, 16> ClassMethodSels;
-  llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
-  for (ObjCCategoryDecl::classmeth_iterator iter = OCD->classmeth_begin(),
-      endIter = OCD->classmeth_end() ; iter != endIter ; iter++) {
-    ClassMethodSels.push_back((*iter)->getSelector());
-    std::string TypeStr;
-    Context.getObjCEncodingForMethodDecl(*iter,TypeStr);
-    ClassMethodTypes.push_back(GetAddrOfConstantCString(TypeStr));
-  }
-
-  // Collect the names of referenced protocols
-  llvm::SmallVector<std::string, 16> Protocols;
-  const ObjCInterfaceDecl *ClassDecl = OCD->getClassInterface();
-  const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols();
-  for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(),
-       E = Protos.end(); I != E; ++I)
-    Protocols.push_back((*I)->getName());
-
-  // Generate the category
-  Runtime->GenerateCategory(OCD->getClassInterface()->getName(),
-      OCD->getName(), InstanceMethodSels, InstanceMethodTypes,
-      ClassMethodSels, ClassMethodTypes, Protocols);
-}
-
-void CodeGenModule::EmitObjCClassImplementation(
-    const ObjCImplementationDecl *OID) {
-  // Get the superclass name.
-  const ObjCInterfaceDecl * SCDecl = OID->getClassInterface()->getSuperClass();
-  const char * SCName = NULL;
-  if (SCDecl) {
-    SCName = SCDecl->getName();
-  }
-
-  // Get the class name
-  ObjCInterfaceDecl * ClassDecl = (ObjCInterfaceDecl*)OID->getClassInterface();
-  const char * ClassName = ClassDecl->getName();
-
-  // Get the size of instances.  For runtimes that support late-bound instances
-  // this should probably be something different (size just of instance
-  // varaibles in this class, not superclasses?).
-  int instanceSize = 0;
-  const llvm::Type *ObjTy = 0;
-  if (!Runtime->LateBoundIVars()) {
-    ObjTy = getTypes().ConvertType(Context.getObjCInterfaceType(ClassDecl));
-    instanceSize = TheTargetData.getABITypeSize(ObjTy);
-  } else {
-    // This is required by newer ObjC runtimes.
-    assert(0 && "Late-bound instance variables not yet supported");
-  }
-
-  // Collect information about instance variables.
-  llvm::SmallVector<llvm::Constant*, 16> IvarNames;
-  llvm::SmallVector<llvm::Constant*, 16> IvarTypes;
-  llvm::SmallVector<llvm::Constant*, 16> IvarOffsets;
-  const llvm::StructLayout *Layout =
-    TheTargetData.getStructLayout(cast<llvm::StructType>(ObjTy));
-  ObjTy = llvm::PointerType::getUnqual(ObjTy);
-  for (ObjCInterfaceDecl::ivar_iterator iter = ClassDecl->ivar_begin(),
-      endIter = ClassDecl->ivar_end() ; iter != endIter ; iter++) {
-      // Store the name
-      IvarNames.push_back(GetAddrOfConstantCString((*iter)->getName()));
-      // Get the type encoding for this ivar
-      std::string TypeStr;
-      llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
-      Context.getObjCEncodingForType((*iter)->getType(), TypeStr,
-                                     EncodingRecordTypes);
-      IvarTypes.push_back(GetAddrOfConstantCString(TypeStr));
-      // Get the offset
-      int offset =
-        (int)Layout->getElementOffset(getTypes().getLLVMFieldNo(*iter));
-      IvarOffsets.push_back(
-          llvm::ConstantInt::get(llvm::Type::Int32Ty, offset));
-  }
-
-  // Collect information about instance methods
-  llvm::SmallVector<Selector, 16> InstanceMethodSels;
-  llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
-  for (ObjCImplementationDecl::instmeth_iterator iter = OID->instmeth_begin(),
-      endIter = OID->instmeth_end() ; iter != endIter ; iter++) {
-    InstanceMethodSels.push_back((*iter)->getSelector());
-    std::string TypeStr;
-    Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
-    InstanceMethodTypes.push_back(GetAddrOfConstantCString(TypeStr));
-  }
-
-  // Collect information about class methods
-  llvm::SmallVector<Selector, 16> ClassMethodSels;
-  llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
-  for (ObjCImplementationDecl::classmeth_iterator iter = OID->classmeth_begin(),
-      endIter = OID->classmeth_end() ; iter != endIter ; iter++) {
-    ClassMethodSels.push_back((*iter)->getSelector());
-    std::string TypeStr;
-    Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
-    ClassMethodTypes.push_back(GetAddrOfConstantCString(TypeStr));
-  }
-  // Collect the names of referenced protocols
-  llvm::SmallVector<std::string, 16> Protocols;
-  const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols();
-  for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(),
-       E = Protos.end(); I != E; ++I)
-    Protocols.push_back((*I)->getName());
-
-  // Generate the category
-  Runtime->GenerateClass(ClassName, SCName, instanceSize, IvarNames, IvarTypes,
-                         IvarOffsets, InstanceMethodSels, InstanceMethodTypes,
-                         ClassMethodSels, ClassMethodTypes, Protocols);
+void 
+CodeGenModule::EmitObjCClassImplementation(const ObjCImplementationDecl *OID) {
+  Runtime->GenerateClass(OID);
 }
 
 void CodeGenModule::EmitStatics() {





More information about the cfe-commits mailing list